diff --git a/PayForMe.xcworkspace/xcshareddata/swiftpm/Package.resolved b/PayForMe.xcworkspace/xcshareddata/swiftpm/Package.resolved index 929c44d..654223f 100644 --- a/PayForMe.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/PayForMe.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/groue/GRDB.swift.git", "state" : { - "revision" : "fead2ea634c1bf7dd81a3e02f796154992165ffd", - "version" : "5.24.0" + "revision" : "dd7e7f39e8e4d7a22d258d9809a882f914690b01", + "version" : "5.26.1" } }, { diff --git a/PayForMe/Services/StorageService.swift b/PayForMe/Services/StorageService.swift index bc33691..2bdbb97 100644 --- a/PayForMe/Services/StorageService.swift +++ b/PayForMe/Services/StorageService.swift @@ -107,7 +107,7 @@ class StorageService { func removeProject(project: Project) { let storedProject = StoredProject(project: project) do { - try dbQueue.write { db in + try _ = dbQueue.write { db in try storedProject.delete(db) } } catch { diff --git a/PayForMe/Strings/cs.lproj/Localizable.strings b/PayForMe/Strings/cs.lproj/Localizable.strings index 356d180..f85bc99 100644 --- a/PayForMe/Strings/cs.lproj/Localizable.strings +++ b/PayForMe/Strings/cs.lproj/Localizable.strings @@ -89,6 +89,10 @@ "Paste Link" = "Vložit odkaz"; + +"Copy Link" = "Kopírovat odkaz"; + + /* BillDetail.swift */ "Payer" = "Plátce"; @@ -104,6 +108,8 @@ /* AddProjectQRView.swift */ "Scan the Cospend QR code to proceed" = "Pokud chcete pokračovat, naskenujte QR kód z Cospend"; +"Scan the QR code to proceed" = "Naskenujte kód QR a pokračujte"; + /* AddProjectManualView.swift */ "Server Address" = "Adresa serveru"; diff --git a/PayForMe/Strings/de.lproj/Localizable.strings b/PayForMe/Strings/de.lproj/Localizable.strings index 9e670a4..121e8e8 100644 --- a/PayForMe/Strings/de.lproj/Localizable.strings +++ b/PayForMe/Strings/de.lproj/Localizable.strings @@ -87,6 +87,9 @@ "Paste Link" = "Link einsetzen"; +"Copy Link" = "Link kopieren"; + + "Payer" = "Zahler"; /* ProjectQRPermissionCheckerView.swift */ @@ -101,6 +104,8 @@ /* AddProjectQRView.swift */ "Scan the Cospend QR code to proceed" = "Scanne den Cospend QR-Code um fortzufahren"; +"Scan the QR code to proceed" = "Scannen Sie den QR-Code, um fortzufahren"; + /* AddProjectManualView.swift */ "Server Address" = "Server URL"; diff --git a/PayForMe/Strings/en.lproj/Localizable.strings b/PayForMe/Strings/en.lproj/Localizable.strings index 37bb86d..ea406dc 100644 --- a/PayForMe/Strings/en.lproj/Localizable.strings +++ b/PayForMe/Strings/en.lproj/Localizable.strings @@ -89,6 +89,9 @@ "Paste Link" = "Paste Link"; + +"Copy Link" = "Copy Link"; + /* BillDetail.swift */ "Payer" = "Payer"; @@ -104,6 +107,8 @@ /* AddProjectQRView.swift */ "Scan the Cospend QR code to proceed" = "Scan the Cospend QR code to proceed"; +"Scan the QR code to proceed" = "Scan the QR code to proceed"; + /* AddProjectManualView.swift */ "Server Address" = "Server Address"; diff --git a/PayForMe/Strings/es.lproj/Localizable.strings b/PayForMe/Strings/es.lproj/Localizable.strings index 6fcdf6d..7616743 100644 --- a/PayForMe/Strings/es.lproj/Localizable.strings +++ b/PayForMe/Strings/es.lproj/Localizable.strings @@ -87,6 +87,9 @@ "Paste Link" = "Pegar enlace"; +"Copy Link" = "Copiar enlace"; + + "Payer" = "Pagador"; /* */ @@ -101,6 +104,8 @@ /* */ "Scan the Cospend QR code to proceed" = "Escanee el código QR de Cospend para continuar"; +"Scan the QR code to proceed" = "Escanee el código QR para continuar"; + /* Localizable.strings PayForMe diff --git a/PayForMe/Strings/fr.lproj/Localizable.strings b/PayForMe/Strings/fr.lproj/Localizable.strings index d306df8..4335107 100644 --- a/PayForMe/Strings/fr.lproj/Localizable.strings +++ b/PayForMe/Strings/fr.lproj/Localizable.strings @@ -87,6 +87,9 @@ "Paste Link" = "Lien de collage"; +"Copy Link" = "Copier le lien"; + + "Payer" = "Prêteur"; /* */ @@ -101,6 +104,8 @@ /* */ "Scan the Cospend QR code to proceed" = "Scannez le code QR de Cospend pour continuer"; +"Scan the QR code to proceed" = "Scannez le code QR pour continuer"; + /* Localizable.strings PayForMe diff --git a/PayForMe/Strings/ru.lproj/Localizable.strings b/PayForMe/Strings/ru.lproj/Localizable.strings index 6813389..a1c51b5 100644 --- a/PayForMe/Strings/ru.lproj/Localizable.strings +++ b/PayForMe/Strings/ru.lproj/Localizable.strings @@ -87,6 +87,9 @@ "Paste Link" = "Вставить ссылку"; +"Copy Link" = "Копировать ссылку"; + + "Payer" = "Кто платил"; /* */ @@ -101,6 +104,8 @@ /* */ "Scan the Cospend QR code to proceed" = "Сканирование QR-кода Cospend для продолжения работы"; +"Scan the QR code to proceed" = "Сканируйте QR-код, чтобы продолжить"; + /* diff --git a/PayForMe/Util/FloatingAddButtonViewModifier.swift b/PayForMe/Util/FloatingAddButtonViewModifier.swift index d4bb470..06a1dee 100644 --- a/PayForMe/Util/FloatingAddButtonViewModifier.swift +++ b/PayForMe/Util/FloatingAddButtonViewModifier.swift @@ -46,7 +46,7 @@ private struct FloatingAddButtonView: View { struct FloatingAddButtonViewModifier_Previews: PreviewProvider { static var previews: some View { - FloatingAddButtonView(sheetToggle: .constant(true)) + // FloatingAddButtonView(sheetToggle: .constant(true)) let viewModel = BillListViewModel() previewProject.members = previewPersons viewModel.currentProject = previewProject diff --git a/PayForMe/Views/BillDetail/CommunicationIndicator.swift b/PayForMe/Views/BillDetail/CommunicationIndicator.swift index 8094d53..85d131b 100644 --- a/PayForMe/Views/BillDetail/CommunicationIndicator.swift +++ b/PayForMe/Views/BillDetail/CommunicationIndicator.swift @@ -37,7 +37,7 @@ struct LoadingRings: View { .frame(width: 100, height: 100) .foregroundColor(.red) .rotation3DEffect(.degrees(spin3D_x ? 180 : 1), axis: (x: spin3D_x ? 1 : 0, y: 0, z: 0)) - .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) + .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false), value: self.spin3D_x) .onAppear { self.spin3D_x.toggle() } @@ -46,7 +46,7 @@ struct LoadingRings: View { .frame(width: 60, height: 60) .foregroundColor(.green) .rotation3DEffect(.degrees(spin3D_y ? 360 : 1), axis: (x: 0, y: spin3D_y ? 1 : 0, z: 0)) - .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) + .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false), value: self.spin3D_y) .onAppear { self.spin3D_y.toggle() } @@ -55,7 +55,7 @@ struct LoadingRings: View { .frame(width: 20, height: 20) .foregroundColor(.blue) .rotation3DEffect(.degrees(spin3D_xy ? 180 : 1), axis: (x: spin3D_xy ? 0 : 1, y: spin3D_xy ? 0 : 1, z: 0)) - .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) + .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false), value: self.spin3D_xy) .onAppear { self.spin3D_xy.toggle() } diff --git a/PayForMe/Views/LoadingDots.swift b/PayForMe/Views/LoadingDots.swift index f197d95..388209f 100644 --- a/PayForMe/Views/LoadingDots.swift +++ b/PayForMe/Views/LoadingDots.swift @@ -21,7 +21,7 @@ struct LoadingDots: View { .stroke(lineWidth: 3) .frame(width: 12, height: 12) .scaleEffect(leftAnimates ? 1 : 0) - .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5)) + .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5), value: self.leftAnimates) .onAppear { self.leftAnimates.toggle() } @@ -30,7 +30,7 @@ struct LoadingDots: View { .stroke(lineWidth: 3) .frame(width: 12, height: 12) .scaleEffect(middleAnimates ? 1 : 0) - .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5).delay(0.15)) + .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5).delay(0.15), value: self.middleAnimates) .onAppear { self.middleAnimates.toggle() } @@ -40,7 +40,7 @@ struct LoadingDots: View { .stroke(lineWidth: 3) .frame(width: 12, height: 12) .scaleEffect(rightAnimates ? 1 : 0) - .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5).delay(0.25)) + .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5).delay(0.25), value: rightAnimates) .onAppear { self.rightAnimates.toggle() } @@ -48,7 +48,7 @@ struct LoadingDots: View { .stroke(lineWidth: 3) .frame(width: 12, height: 12) .scaleEffect(rightAnimates ? 1 : 0) - .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5).delay(0.35)) + .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5).delay(0.35), value: rightAnimates) .onAppear { self.rightAnimates.toggle() } @@ -56,7 +56,7 @@ struct LoadingDots: View { .stroke(lineWidth: 3) .frame(width: 12, height: 12) .scaleEffect(rightAnimates ? 1 : 0) - .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5).delay(0.45)) + .animation(Animation.spring().repeatForever(autoreverses: false).speed(0.5).delay(0.45), value: rightAnimates) .onAppear { self.rightAnimates.toggle() } @@ -65,6 +65,7 @@ struct LoadingDots: View { } struct LoadingDots_Previews: PreviewProvider { + static var previews: some View { LoadingDots() } diff --git a/PayForMe/Views/Projects/Manual/AddProjectManualView.swift b/PayForMe/Views/Projects/Manual/AddProjectManualView.swift index 2fc535a..a9921c2 100644 --- a/PayForMe/Views/Projects/Manual/AddProjectManualView.swift +++ b/PayForMe/Views/Projects/Manual/AddProjectManualView.swift @@ -84,13 +84,17 @@ struct AddProjectManualView: View { } private func pasteLink(pasteString: String) { - viewmodel.pasteAddress(address: pasteString) + DispatchQueue.main.async { + viewmodel.pasteAddress(address: pasteString) + } } private func pasteLink() { - if let pasteString = UIPasteboard.general.string { - print(pasteString) - viewmodel.pasteAddress(address: pasteString) + DispatchQueue.main.async { + if let pasteString = UIPasteboard.general.string { + print(pasteString) + viewmodel.pasteAddress(address: pasteString) + } } } } diff --git a/PayForMe/Views/Projects/Manual/AddProjectManualViewModel.swift b/PayForMe/Views/Projects/Manual/AddProjectManualViewModel.swift index 484a1c7..5523371 100644 --- a/PayForMe/Views/Projects/Manual/AddProjectManualViewModel.swift +++ b/PayForMe/Views/Projects/Manual/AddProjectManualViewModel.swift @@ -69,17 +69,15 @@ class AddProjectManualViewModel: ObservableObject { return } // If it is another url - - let pathComponents = url.pathComponents - let pureUrl = url.deletingPathExtension().absoluteString - let trimmIndices = url.absoluteString.indices(of: "/") - if let cutIndex = trimmIndices[safe: 2] { - let trimmedUrl = pureUrl[...cutIndex] - serverAddress = String(trimmedUrl) + if url.scheme != nil && url.host != nil { + serverAddress = "\(url.scheme!)://\(url.host!)" + if url.port != nil { + serverAddress+=":\(url.port!)" + } } else { - serverAddress = pureUrl + serverAddress = url.deletingPathExtension().absoluteString } - fillFieldsFromComponents(components: pathComponents) + fillFieldsFromComponents(components: url.pathComponents) } var serverAddressFormatted: AnyPublisher { diff --git a/PayForMe/Views/Projects/ProjectListEntry.swift b/PayForMe/Views/Projects/ProjectListEntry.swift index 2674d96..db7926a 100644 --- a/PayForMe/Views/Projects/ProjectListEntry.swift +++ b/PayForMe/Views/Projects/ProjectListEntry.swift @@ -17,6 +17,13 @@ struct ProjectListEntry: View { @State var edit = false @State var me = 0 + + func actionShare(project: Project) { + guard let data = URL(string: "\(project.url)/apps/cospend/s/\(project.token)") else { return } + let av = UIActivityViewController(activityItems: [data.absoluteString], applicationActivities: nil) + UIApplication.shared.connectedScenes.flatMap { ($0 as? UIWindowScene)?.windows ?? [] } + .first { $0.isKeyWindow }?.rootViewController!.present(av, animated: true) + } var body: some View { Button(action: { @@ -26,6 +33,8 @@ struct ProjectListEntry: View { HStack { VStack(alignment: .leading) { Text(project.name) + .allowsTightening(true) + .lineLimit(1) Text(project.backend == .cospend ? "Cospend" : "iHateMoney").font(.caption).foregroundColor(Color.gray) } Spacer() @@ -35,16 +44,19 @@ struct ProjectListEntry: View { }, label: { Image(systemName: "pencil") }) - .padding(.trailing, 5) + .padding(.trailing, 8) } if project.backend == .cospend { + Button(action: { + actionShare(project: project) + }, label: { + Image(systemName: "square.and.arrow.up") + }) + .padding(.trailing, 8) Button(action: { self.shareProject = project }, label: { - HStack(spacing: 5) { - Image(systemName: "square.and.arrow.up") - Image(systemName: "qrcode") - } + Image(systemName: "qrcode") }) } } diff --git a/PayForMe/Views/Projects/QRCodes/AddProjectQRViewModel.swift b/PayForMe/Views/Projects/QRCodes/AddProjectQRViewModel.swift index 9211cb5..1631d30 100644 --- a/PayForMe/Views/Projects/QRCodes/AddProjectQRViewModel.swift +++ b/PayForMe/Views/Projects/QRCodes/AddProjectQRViewModel.swift @@ -102,12 +102,16 @@ class AddProjectQRViewModel: ObservableObject { do { let apiProject = try await NetworkService.shared.getProjectName(project) try ProjectManager.shared.addProject(apiProject) - self.isTestingSubject.send(.success) + DispatchQueue.main.async { + self.isTestingSubject.send(.success) + } } catch { print(codedUrl) print() print(error) - self.isTestingSubject.send(.failure) + DispatchQueue.main.async { + self.isTestingSubject.send(.failure) + } } } // NetworkService.shared.testProject(project) diff --git a/PayForMe/Views/Projects/ShareProjectQRCode.swift b/PayForMe/Views/Projects/ShareProjectQRCode.swift index 446000c..adc85b1 100644 --- a/PayForMe/Views/Projects/ShareProjectQRCode.swift +++ b/PayForMe/Views/Projects/ShareProjectQRCode.swift @@ -17,7 +17,15 @@ struct ShareProjectQRCode: View { var body: some View { VStack { - Text(dataString).font(.caption) + Button(action: { + let pasteboard = UIPasteboard.general + pasteboard.string = dataString + }, label: { + Text("Copy Link") + }) + Text(dataString) + .padding() + .font(.caption) CarBode.CBBarcodeView(data: $dataString, barcodeType: .constant(.qrCode), orientation: .constant(.up), onGenerated: nil) .aspectRatio(contentMode: .fit) } diff --git a/PayForMeTests/AddProjectManuallyTests.swift b/PayForMeTests/AddProjectManuallyTests.swift index 12634bb..d70ccc4 100644 --- a/PayForMeTests/AddProjectManuallyTests.swift +++ b/PayForMeTests/AddProjectManuallyTests.swift @@ -76,7 +76,7 @@ class AddProjectManuallyTests: XCTestCase { exp2.fulfill() }.store(in: &subscriptions) viewmodel.$projectPassword.sink { password in - XCTAssertEqual("", password) + XCTAssertEqual("no-pass", password) exp3.fulfill() }.store(in: &subscriptions) waitForExpectations(timeout: 1) @@ -124,7 +124,7 @@ class AddProjectManuallyTests: XCTestCase { XCTAssertEqual(project.backend, .cospend) XCTAssertEqual(project.name, "02939asdasd12asdj23") XCTAssertEqual(project.token, "02939asdasd12asdj23") - XCTAssertEqual(project.password, "") + XCTAssertEqual(project.password, "no-pass") XCTAssertEqual(project.url.absoluteString, "https://myserver.de") exp.fulfill() }.store(in: &subscriptions)