Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions PayForMe.xcworkspace/xcshareddata/swiftpm/Package.resolved

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outdated, GRDB is up to date now and two major versions ahead.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion PayForMe/Services/StorageService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 6 additions & 0 deletions PayForMe/Strings/cs.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@

"Paste Link" = "Vložit odkaz";


"Copy Link" = "Kopírovat odkaz";


/* BillDetail.swift */
"Payer" = "Plátce";

Expand All @@ -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";

Expand Down
5 changes: 5 additions & 0 deletions PayForMe/Strings/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@
"Paste Link" = "Link einsetzen";


"Copy Link" = "Link kopieren";


"Payer" = "Zahler";

/* ProjectQRPermissionCheckerView.swift */
Expand All @@ -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";

Expand Down
5 changes: 5 additions & 0 deletions PayForMe/Strings/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@

"Paste Link" = "Paste Link";


"Copy Link" = "Copy Link";

/* BillDetail.swift */
"Payer" = "Payer";

Expand All @@ -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";

Expand Down
5 changes: 5 additions & 0 deletions PayForMe/Strings/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@
"Paste Link" = "Pegar enlace";


"Copy Link" = "Copiar enlace";


"Payer" = "Pagador";

/* */
Expand All @@ -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
Expand Down
5 changes: 5 additions & 0 deletions PayForMe/Strings/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@
"Paste Link" = "Lien de collage";


"Copy Link" = "Copier le lien";


"Payer" = "Prêteur";

/* */
Expand All @@ -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
Expand Down
5 changes: 5 additions & 0 deletions PayForMe/Strings/ru.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@
"Paste Link" = "Вставить ссылку";


"Copy Link" = "Копировать ссылку";


"Payer" = "Кто платил";

/* */
Expand All @@ -101,6 +104,8 @@
/* */
"Scan the Cospend QR code to proceed" = "Сканирование QR-кода Cospend для продолжения работы";

"Scan the QR code to proceed" = "Сканируйте QR-код, чтобы продолжить";


/*

Expand Down
2 changes: 1 addition & 1 deletion PayForMe/Util/FloatingAddButtonViewModifier.swift

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is only for preview, and preview works without initializing this struct (again), better remove it completely.

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions PayForMe/Views/BillDetail/CommunicationIndicator.swift

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'animation' was deprecated in iOS 15.0 – so it would be even better to use 'withAnimation'. Your fix works too, though – but let's make the switch sooner than later.

Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand All @@ -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()
}
Expand All @@ -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()
}
Expand Down
11 changes: 6 additions & 5 deletions PayForMe/Views/LoadingDots.swift

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'animation' was deprecated in iOS 15.0 – so it would be even better to use 'withAnimation'. Your fix works too, though – but let's make the switch sooner than later.

Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand All @@ -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()
}
Expand All @@ -40,23 +40,23 @@ 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()
}
Circle()
.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()
}
Circle()
.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()
}
Expand All @@ -65,6 +65,7 @@ struct LoadingDots: View {
}

struct LoadingDots_Previews: PreviewProvider {

static var previews: some View {
LoadingDots()
}
Expand Down
12 changes: 8 additions & 4 deletions PayForMe/Views/Projects/Manual/AddProjectManualView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
}
Expand Down
16 changes: 7 additions & 9 deletions PayForMe/Views/Projects/Manual/AddProjectManualViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Never> {
Expand Down
22 changes: 17 additions & 5 deletions PayForMe/Views/Projects/ProjectListEntry.swift

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super helpful feature, thank you! It's best practice to keep logic and interface separated. Would you mind "outsourcing" this feature? This way it can easily be reused in different places and even tested automatically (more easily).

Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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()
Expand All @@ -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")
})
}
}
Expand Down
8 changes: 6 additions & 2 deletions PayForMe/Views/Projects/QRCodes/AddProjectQRViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 9 additions & 1 deletion PayForMe/Views/Projects/ShareProjectQRCode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
4 changes: 2 additions & 2 deletions PayForMeTests/AddProjectManuallyTests.swift

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outdated but correct! …at this time already in the codebase

Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down