mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-11 06:17:08 +00:00
scan rework, process errors, other fixes
This commit is contained in:
@@ -39,7 +39,7 @@ struct ChatHelp: View {
|
||||
|
||||
HStack(spacing: 8) {
|
||||
Text("Tap button ")
|
||||
NewChatSheetButton(showNewChatSheet: $showNewChatSheet)
|
||||
NewChatInviteButton(showNewChatSheet: $showNewChatSheet)
|
||||
Text("above, then choose:")
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ struct ChatListView: View {
|
||||
case .some(true):
|
||||
HStack {
|
||||
createGroupButton()
|
||||
NewChatSheetButton(showNewChatSheet: $showNewChatSheet)
|
||||
NewChatInviteButton(showNewChatSheet: $showNewChatSheet)
|
||||
}
|
||||
case .some(false): chatStoppedIcon()
|
||||
case .none: EmptyView()
|
||||
@@ -307,28 +307,13 @@ struct ChatListSearchBar: View {
|
||||
.transition(.identity)
|
||||
}
|
||||
|
||||
scanCodeButton()
|
||||
NewChatScanButton()
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
.padding(.horizontal, 18)
|
||||
.padding(.vertical, 2)
|
||||
}
|
||||
|
||||
private func scanCodeButton() -> some View {
|
||||
Button {
|
||||
showScanCodeSheet = true
|
||||
} label: {
|
||||
Image(systemName: "qrcode")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.foregroundColor(.accentColor)
|
||||
.frame(width: 20, height: 20)
|
||||
}
|
||||
.sheet(isPresented: $showScanCodeSheet) {
|
||||
NewChatView(selection: .connect, showScanQRCodeSheet: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func chatStoppedIcon() -> some View {
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// NewChatSheetButton.swift
|
||||
// NewChatInviteButton.swift
|
||||
// SimpleX (iOS)
|
||||
//
|
||||
// Created by spaced4ndy on 28.11.2023.
|
||||
@@ -7,9 +7,8 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
struct NewChatSheetButton: View {
|
||||
struct NewChatInviteButton: View {
|
||||
@Binding var showNewChatSheet: Bool
|
||||
|
||||
var body: some View {
|
||||
@@ -28,5 +27,5 @@ struct NewChatSheetButton: View {
|
||||
}
|
||||
|
||||
//#Preview {
|
||||
// NewChatSheetButton()
|
||||
// NewChatInviteButton()
|
||||
//}
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// NewChatScanButton.swift
|
||||
// SimpleX (iOS)
|
||||
//
|
||||
// Created by spaced4ndy on 30.11.2023.
|
||||
// Copyright © 2023 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct NewChatScanButton: View {
|
||||
@State private var showNewChatSheet = false
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
showNewChatSheet = true
|
||||
} label: {
|
||||
Image(systemName: "qrcode")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 20, height: 20)
|
||||
}
|
||||
.sheet(isPresented: $showNewChatSheet) {
|
||||
NewChatView(selection: .connect, showQRCodeScanner: true)
|
||||
.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil) // fixes .refreshable in ChatListView affecting nested view
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#Preview {
|
||||
// NewChatScanButton()
|
||||
//}
|
||||
@@ -30,7 +30,7 @@ enum NewChatOption: Identifiable {
|
||||
struct NewChatView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@State var selection: NewChatOption
|
||||
@State var showScanQRCodeSheet = false
|
||||
@State var showQRCodeScanner = false
|
||||
@State private var connReqInvitation: String = ""
|
||||
@State private var contactConnection: PendingContactConnection? = nil
|
||||
@State private var creatingConnReq = false
|
||||
@@ -73,7 +73,7 @@ struct NewChatView: View {
|
||||
retryButton()
|
||||
}
|
||||
case .connect:
|
||||
ConnectView(showScanQRCodeSheet: showScanQRCodeSheet)
|
||||
ConnectView(showQRCodeScanner: showQRCodeScanner)
|
||||
}
|
||||
}
|
||||
.onChange(of: selection) { sel in
|
||||
@@ -193,7 +193,7 @@ private struct InviteView: View {
|
||||
.padding()
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 12, style: .continuous)
|
||||
.fill(Color(uiColor: .systemBackground))
|
||||
.fill(Color(uiColor: .secondarySystemGroupedBackground))
|
||||
)
|
||||
.padding(.horizontal)
|
||||
.listRowBackground(Color.clear)
|
||||
@@ -217,11 +217,10 @@ private enum ConnectAlert: Identifiable {
|
||||
|
||||
private struct ConnectView: View {
|
||||
@Environment(\.dismiss) var dismiss: DismissAction
|
||||
@State var showScanQRCodeSheet = false
|
||||
@State private var connectionLink: String = ""
|
||||
@State var showQRCodeScanner = false
|
||||
@State private var pastedLink: String = ""
|
||||
@State private var alert: ConnectAlert?
|
||||
@State private var sheet: PlanAndConnectActionSheet?
|
||||
@State private var scannedLink: String = ""
|
||||
|
||||
var body: some View {
|
||||
viewBody()
|
||||
@@ -232,17 +231,6 @@ private struct ConnectView: View {
|
||||
}
|
||||
}
|
||||
.actionSheet(item: $sheet) { s in planAndConnectActionSheet(s, dismiss: true) }
|
||||
.sheet(isPresented: $showScanQRCodeSheet) {
|
||||
if #available(iOS 16.0, *) {
|
||||
ScanConnectionCodeView(scannedLink: $scannedLink)
|
||||
.presentationDetents([.fraction(0.8)])
|
||||
} else {
|
||||
ScanConnectionCodeView(scannedLink: $scannedLink)
|
||||
}
|
||||
}
|
||||
.onChange(of: scannedLink) { link in
|
||||
connect(link)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func viewBody() -> some View {
|
||||
@@ -250,19 +238,17 @@ private struct ConnectView: View {
|
||||
pasteLinkView()
|
||||
}
|
||||
|
||||
Section("Or scan QR code") {
|
||||
scanQRCodeButton()
|
||||
}
|
||||
scanCodeView()
|
||||
}
|
||||
|
||||
@ViewBuilder private func pasteLinkView() -> some View {
|
||||
if connectionLink == "" {
|
||||
if pastedLink == "" {
|
||||
Button {
|
||||
if let str = UIPasteboard.general.string {
|
||||
let link = str.trimmingCharacters(in: .whitespaces)
|
||||
if checkParsedLink(link) {
|
||||
connectionLink = link
|
||||
connect(connectionLink)
|
||||
pastedLink = link
|
||||
connect(pastedLink)
|
||||
} else {
|
||||
alert = .connectSomeAlert(alert: .someAlert(
|
||||
alert: mkAlert(title: "Invalid link", message: "The text you pasted is not a SimpleX link."),
|
||||
@@ -276,9 +262,9 @@ private struct ConnectView: View {
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
} else {
|
||||
HStack {
|
||||
linkTextView(connectionLink)
|
||||
linkTextView(pastedLink)
|
||||
Button {
|
||||
connectionLink = ""
|
||||
pastedLink = ""
|
||||
} label: {
|
||||
Image(systemName: "xmark.circle")
|
||||
}
|
||||
@@ -296,6 +282,49 @@ private struct ConnectView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func scanCodeView() -> some View {
|
||||
Section("Or scan QR code") {
|
||||
if showQRCodeScanner {
|
||||
CodeScannerView(codeTypes: [.qr], completion: processQRCode)
|
||||
.aspectRatio(1, contentMode: .fit)
|
||||
.cornerRadius(12)
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||
.padding(.horizontal)
|
||||
} else {
|
||||
Button {
|
||||
showQRCodeScanner = true
|
||||
} label: {
|
||||
Text("Tap to scan")
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO scan is only attempted once
|
||||
private func processQRCode(_ resp: Result<ScanResult, ScanError>) {
|
||||
switch resp {
|
||||
case let .success(r):
|
||||
let link = r.string
|
||||
if checkParsedLink(link) {
|
||||
connect(link)
|
||||
} else {
|
||||
alert = .connectSomeAlert(alert: .someAlert(
|
||||
alert: mkAlert(title: "Invalid QR code", message: "The code you scanned is not a SimpleX link QR code."),
|
||||
id: "pasteLinkView checkParsedLink error"
|
||||
))
|
||||
}
|
||||
case let .failure(e):
|
||||
logger.error("processQRCode QR code error: \(e.localizedDescription)")
|
||||
alert = .connectSomeAlert(alert: .someAlert(
|
||||
alert: mkAlert(title: "Invalid QR code", message: "Error scanning code: \(e.localizedDescription)"),
|
||||
id: "processQRCode failure"
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
private func connect(_ link: String) {
|
||||
planAndConnect(
|
||||
link,
|
||||
@@ -305,53 +334,6 @@ private struct ConnectView: View {
|
||||
incognito: nil
|
||||
)
|
||||
}
|
||||
|
||||
private func scanQRCodeButton() -> some View {
|
||||
Button {
|
||||
showScanQRCodeSheet = true
|
||||
} label: {
|
||||
settingsRow("qrcode") {
|
||||
Text("Scan code")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct ScanConnectionCodeView: View {
|
||||
@Environment(\.dismiss) var dismiss: DismissAction
|
||||
@Binding var scannedLink: String
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
Text("Scan QR code")
|
||||
.font(.largeTitle)
|
||||
.bold()
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.padding(.vertical)
|
||||
|
||||
CodeScannerView(codeTypes: [.qr], completion: processQRCode)
|
||||
.aspectRatio(1, contentMode: .fit)
|
||||
.cornerRadius(12)
|
||||
.padding(.top)
|
||||
|
||||
Text("If you cannot meet in person, you can **scan QR code in the video call**, or your contact can share an invitation link.")
|
||||
.padding(.top)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||
.padding()
|
||||
}
|
||||
|
||||
private func processQRCode(_ resp: Result<ScanResult, ScanError>) {
|
||||
switch resp {
|
||||
case let .success(r):
|
||||
scannedLink = r.string
|
||||
dismiss()
|
||||
case let .failure(e):
|
||||
logger.error("ConnectContactView.processQRCode QR code error: \(e.localizedDescription)")
|
||||
// TODO alert
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InfoSheetButton<Content: View>: View {
|
||||
|
||||
@@ -179,7 +179,8 @@
|
||||
64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; };
|
||||
64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */; };
|
||||
64AEA4ED2B15D2A400334292 /* NewChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AEA4EC2B15D2A400334292 /* NewChatView.swift */; };
|
||||
64AEA4EF2B15FEE100334292 /* NewChatSheetButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AEA4EE2B15FEE100334292 /* NewChatSheetButton.swift */; };
|
||||
64AEA4EF2B15FEE100334292 /* NewChatInviteButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AEA4EE2B15FEE100334292 /* NewChatInviteButton.swift */; };
|
||||
64AEA4F12B18896400334292 /* NewChatScanButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AEA4F02B18896400334292 /* NewChatScanButton.swift */; };
|
||||
64C06EB52A0A4A7C00792D4D /* ChatItemInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */; };
|
||||
64C3B0212A0D359700E19930 /* CustomTimePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C3B0202A0D359700E19930 /* CustomTimePicker.swift */; };
|
||||
64D0C2C029F9688300B38D5F /* UserAddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2BF29F9688300B38D5F /* UserAddressView.swift */; };
|
||||
@@ -465,7 +466,8 @@
|
||||
64AA1C6827EE10C800AC7277 /* ContextItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextItemView.swift; sourceTree = "<group>"; };
|
||||
64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedItemView.swift; sourceTree = "<group>"; };
|
||||
64AEA4EC2B15D2A400334292 /* NewChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewChatView.swift; sourceTree = "<group>"; };
|
||||
64AEA4EE2B15FEE100334292 /* NewChatSheetButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewChatSheetButton.swift; sourceTree = "<group>"; };
|
||||
64AEA4EE2B15FEE100334292 /* NewChatInviteButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewChatInviteButton.swift; sourceTree = "<group>"; };
|
||||
64AEA4F02B18896400334292 /* NewChatScanButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewChatScanButton.swift; sourceTree = "<group>"; };
|
||||
64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemInfoView.swift; sourceTree = "<group>"; };
|
||||
64C3B0202A0D359700E19930 /* CustomTimePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTimePicker.swift; sourceTree = "<group>"; };
|
||||
64D0C2BF29F9688300B38D5F /* UserAddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressView.swift; sourceTree = "<group>"; };
|
||||
@@ -741,7 +743,8 @@
|
||||
5CB2085228DB7CAF00D024EC /* ConnectViaLinkView.swift */,
|
||||
64D0C2C529FAC1EC00B38D5F /* AddContactLearnMore.swift */,
|
||||
64AEA4EC2B15D2A400334292 /* NewChatView.swift */,
|
||||
64AEA4EE2B15FEE100334292 /* NewChatSheetButton.swift */,
|
||||
64AEA4EE2B15FEE100334292 /* NewChatInviteButton.swift */,
|
||||
64AEA4F02B18896400334292 /* NewChatScanButton.swift */,
|
||||
);
|
||||
path = NewChat;
|
||||
sourceTree = "<group>";
|
||||
@@ -1121,7 +1124,7 @@
|
||||
5C13730B28156D2700F43030 /* ContactConnectionView.swift in Sources */,
|
||||
644EFFE0292CFD7F00525D5B /* CIVoiceView.swift in Sources */,
|
||||
6432857C2925443C00FBE5C8 /* GroupPreferencesView.swift in Sources */,
|
||||
64AEA4EF2B15FEE100334292 /* NewChatSheetButton.swift in Sources */,
|
||||
64AEA4EF2B15FEE100334292 /* NewChatInviteButton.swift in Sources */,
|
||||
5C93293129239BED0090FFF9 /* ProtocolServerView.swift in Sources */,
|
||||
5C9CC7AD28C55D7800BEF955 /* DatabaseEncryptionView.swift in Sources */,
|
||||
5CBD285A295711D700EC2CF4 /* ImageUtils.swift in Sources */,
|
||||
@@ -1247,6 +1250,7 @@
|
||||
184152CEF68D2336FC2EBCB0 /* CallViewRenderers.swift in Sources */,
|
||||
5CB634AD29E46CF70066AD6B /* LocalAuthView.swift in Sources */,
|
||||
18415FEFE153C5920BFB7828 /* GroupWelcomeView.swift in Sources */,
|
||||
64AEA4F12B18896400334292 /* NewChatScanButton.swift in Sources */,
|
||||
18415F9A2D551F9757DA4654 /* CIVideoView.swift in Sources */,
|
||||
184158C131FDB829D8A117EA /* VideoPlayerView.swift in Sources */,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user