scan rework, process errors, other fixes

This commit is contained in:
spaced4ndy
2023-11-30 13:41:44 +04:00
parent 661b5db9e9
commit a1e91d79dd
6 changed files with 100 additions and 98 deletions
@@ -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 {
@@ -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()
//}
+54 -72
View File
@@ -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 {
+8 -4
View File
@@ -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 */,
);