diff --git a/LDKNodeMonday.xcodeproj/project.pbxproj b/LDKNodeMonday.xcodeproj/project.pbxproj index 8de3a99..1cf0963 100644 --- a/LDKNodeMonday.xcodeproj/project.pbxproj +++ b/LDKNodeMonday.xcodeproj/project.pbxproj @@ -843,6 +843,7 @@ INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_UISupportsDocumentBrowser = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -877,6 +878,7 @@ INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_UISupportsDocumentBrowser = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/LDKNodeMonday/View/Home/BitcoinView.swift b/LDKNodeMonday/View/Home/BitcoinView.swift index 234b5d3..230d1c5 100644 --- a/LDKNodeMonday/View/Home/BitcoinView.swift +++ b/LDKNodeMonday/View/Home/BitcoinView.swift @@ -18,6 +18,9 @@ struct BitcoinView: View { @State private var showToast = false @State private var showingNodeIDView = false @State private var displayBalanceType = DisplayBalanceType.userDefaults + @State private var isReceiveSheetPresented = false + @State private var isSendSheetManualPresented = false + @State private var isSendSheetCameraPresented = false @StateObject var viewModel: BitcoinViewModel @StateObject private var eventService = EventService() @Binding var sendNavigationPath: NavigationPath @@ -28,9 +31,6 @@ struct BitcoinView: View { BalanceHeader(displayBalanceType: $displayBalanceType, viewModel: viewModel) .padding(.vertical, 40) - TransactionButtons(viewModel: viewModel) - .padding(.horizontal, 40) - PaymentsListView( payments: $viewModel.payments, displayBalanceType: $displayBalanceType, @@ -59,6 +59,38 @@ struct BitcoinView: View { } } } + ToolbarItemGroup(placement: .bottomBar) { + // Send button + Button { + isSendSheetManualPresented = true + } label: { + Label("Send", systemImage: "arrow.up") + }.disabled(viewModel.unifiedBalance == 0) + .glassEffect() + + Spacer() + + // Scan QR button + Button { + isSendSheetCameraPresented = true + } label: { + Label("Scan QR", systemImage: "qrcode.viewfinder") + } + .font(.title) + .disabled(viewModel.unifiedBalance == 0) + .glassEffect() + + Spacer() + + // Receive button + Button { + isReceiveSheetPresented = true + } label: { + Label("Receive", systemImage: "arrow.down") + } + .sensoryFeedback(.increase, trigger: isReceiveSheetPresented) + .glassEffect() + } } .dynamicTypeSize(...DynamicTypeSize.accessibility2) // Sets max dynamic size for all Text .onAppear { viewModel.update() } @@ -66,6 +98,11 @@ struct BitcoinView: View { of: eventService.lastEvent, { _, _ in showToast = eventService.lastEvent != nil + withAnimation { + isReceiveSheetPresented = false + isSendSheetManualPresented = false + isSendSheetCameraPresented = false + } } ) .onReceive(viewModel.$bitcoinViewError) { errorMessage in @@ -107,6 +144,34 @@ struct BitcoinView: View { viewModel: .init(lightningClient: viewModel.lightningClient) ) } + .sheet(isPresented: $isSendSheetManualPresented, onDismiss: { Task { viewModel.update() } }) + { + SendView( + viewModel: SendViewModel.init( + lightningClient: viewModel.lightningClient, + sendViewState: .manualEntry, + price: viewModel.price, + balances: viewModel.balances + ) + ) + .presentationDetents([.large]) + } + .sheet(isPresented: $isSendSheetCameraPresented, onDismiss: { Task { viewModel.update() } }) + { + SendView( + viewModel: SendViewModel.init( + lightningClient: viewModel.lightningClient, + sendViewState: .scanAddress, + price: viewModel.price, + balances: viewModel.balances + ) + ) + .presentationDetents([.large]) + } + .sheet(isPresented: $isReceiveSheetPresented, onDismiss: { Task { viewModel.update() } }) { + ReceiveView(viewModel: .init(lightningClient: viewModel.lightningClient)) + .presentationDetents([.large]) + } } } @@ -197,119 +262,6 @@ struct BalanceHeader: View { } } -struct TransactionButtons: View { - @ObservedObject var viewModel: BitcoinViewModel - @State private var isReceiveSheetPresented = false - @State private var isSendSheetManualPresented = false - @State private var isSendSheetCameraPresented = false - @StateObject private var eventService = EventService() - - var body: some View { - HStack(alignment: .center) { - - // Send button - Button { - isSendSheetManualPresented = true - } label: { - Text("Send") - }.buttonStyle( - BitcoinFilled( - width: 120, - tintColor: .accent, - isCapsule: true - ) - ).disabled(viewModel.unifiedBalance == 0) - - Spacer() - - // Scan QR button - Button { - isSendSheetCameraPresented = true - } label: { - Label("Scan QR", systemImage: "qrcode.viewfinder") - .font(.title) - .frame(height: 60, alignment: .center) - .labelStyle(.iconOnly) - .foregroundColor(.accentColor) - .padding() - }.disabled(viewModel.unifiedBalance == 0) - - Spacer() - - // Receive button - Button("Receive") { - isReceiveSheetPresented = true - } - .sensoryFeedback(.increase, trigger: isReceiveSheetPresented) - .buttonStyle( - BitcoinFilled( - width: 120, - tintColor: .accent, - isCapsule: true - ) - ) - .sheet( - isPresented: $isSendSheetManualPresented, - onDismiss: { - Task { - viewModel.update() - } - } - ) { - SendView( - viewModel: SendViewModel.init( - lightningClient: viewModel.lightningClient, - sendViewState: .manualEntry, - price: viewModel.price, - balances: viewModel.balances - ) - ) - .presentationDetents([.large]) - } - .sheet( - isPresented: $isSendSheetCameraPresented, - onDismiss: { - Task { - viewModel.update() - } - } - ) { - SendView( - viewModel: SendViewModel.init( - lightningClient: viewModel.lightningClient, - sendViewState: .scanAddress, - price: viewModel.price, - balances: viewModel.balances - ) - ) - .presentationDetents([.large]) - } - .sheet( - isPresented: $isReceiveSheetPresented, - onDismiss: { - Task { - viewModel.update() - } - } - ) { - ReceiveView(viewModel: .init(lightningClient: viewModel.lightningClient)) - .presentationDetents([.large]) - } - - }.onChange( - of: eventService.lastEvent, - { _, _ in - withAnimation { - isReceiveSheetPresented = false - isSendSheetManualPresented = false - isSendSheetCameraPresented = false - } - } - ) - } - -} - public enum DisplayBalanceType: String { case fiatSats case fiatBtc diff --git a/LDKNodeMonday/View/Home/OnboardingView.swift b/LDKNodeMonday/View/Home/OnboardingView.swift index eb7ab7c..6d34e80 100644 --- a/LDKNodeMonday/View/Home/OnboardingView.swift +++ b/LDKNodeMonday/View/Home/OnboardingView.swift @@ -19,118 +19,119 @@ struct OnboardingView: View { @State private var animateContent = false var body: some View { + NavigationView { + ZStack { + Color(uiColor: .systemBackground) + .ignoresSafeArea() - ZStack { - Color(uiColor: .systemBackground) - .ignoresSafeArea() - - VStack { - - // Network settings - HStack { - Spacer() - Button( - action: { - showingNetworkSettingsSheet.toggle() - }, - label: { - HStack(spacing: 5) { - Text( - viewModel.walletClient.network.description - .capitalized - ) - .opacity(animateContent ? 1 : 0) - .offset(x: animateContent ? 0 : 100) - Image(systemName: "gearshape") - .opacity(animateContent ? 1 : 0) - .offset(x: animateContent ? 0 : 100) - } - } - ) - .sheet(isPresented: $showingNetworkSettingsSheet) { - NavigationView { - NetworkSettingsView(walletClient: viewModel.$walletClient) + VStack { + // Logo, name and description + VStack { + Image(systemName: "bolt.horizontal.fill") + .resizable() + .aspectRatio(contentMode: .fit) + .foregroundColor(.accent) + .frame(width: 150, height: 150, alignment: .center) + .padding(40) + // .scaleEffect(animateContent ? 1 : 0) + // .opacity(animateContent ? 1 : 0) + // .animation( + // .spring(response: 0.6, dampingFraction: 0.5), + // value: animateContent + // ) + Group { + Text("Monday Wallet") + .font(.largeTitle.weight(.semibold)) + Text("An example bitcoin wallet\npowered by LDK Node") + .font(.body) + .multilineTextAlignment(.center) + .fixedSize(horizontal: false, vertical: true) } + // .opacity(animateContent ? 1 : 0) + // .offset(y: animateContent ? 0 : 20) + // .animation(.easeOut(duration: 0.5).delay(0.3), value: animateContent) } - } - .fontWeight(.medium) - .padding() - .animation(.easeOut(duration: 0.5).delay(0.6), value: animateContent) - // Logo, name and description - VStack { - Image(systemName: "bolt.horizontal.fill") - .resizable() - .aspectRatio(contentMode: .fit) - .foregroundColor(.accent) - .frame(width: 150, height: 150, alignment: .center) - .padding(40) - .scaleEffect(animateContent ? 1 : 0) - .opacity(animateContent ? 1 : 0) - .animation( - .spring(response: 0.6, dampingFraction: 0.5), - value: animateContent - ) - Group { - Text("Monday Wallet") - .font(.largeTitle.weight(.semibold)) - Text("An example bitcoin wallet\npowered by LDK Node") - .font(.body) - .multilineTextAlignment(.center) - .fixedSize(horizontal: false, vertical: true) - } - .opacity(animateContent ? 1 : 0) - .offset(y: animateContent ? 0 : 20) - .animation(.easeOut(duration: 0.5).delay(0.3), value: animateContent) - } + Spacer() - Spacer() + // Buttons for creating and importing wallet - // Buttons for creating and importing wallet + Group { - Group { - Button("Create wallet") { - Task { - await viewModel.saveSeed() + Button { + Task { + await viewModel.saveSeed() + } + } label: { + Text("Create wallet") + .padding(.all, 10) + .padding(.horizontal, 20) + } + .buttonStyle(.borderedProminent) + + Button { + showingImportWalletSheet.toggle() + } label: { + Text("Import wallet") + .padding(.all, 10) + .padding(.horizontal, 20) + } + .buttonStyle(.bordered) + .sheet(isPresented: $showingImportWalletSheet) { + ImportWalletView().environmentObject(viewModel) } - } - .buttonStyle( - BitcoinFilled( - tintColor: .accent, - isCapsule: true - ) - ) - Button("Import wallet") { - showingImportWalletSheet.toggle() } - .buttonStyle(BitcoinPlain(tintColor: .accent)) - .sheet(isPresented: $showingImportWalletSheet) { - ImportWalletView().environmentObject(viewModel) + // .opacity(animateContent ? 1 : 0) + // .offset(y: animateContent ? 0 : 30) + // .animation(.easeOut(duration: 0.5).delay(0.6), value: animateContent) + + } + .dynamicTypeSize(...DynamicTypeSize.accessibility2) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button( + action: { + showingNetworkSettingsSheet.toggle() + }, + label: { + HStack(spacing: 5) { + Text( + viewModel.walletClient.network.description + .capitalized + ) + Image(systemName: "gearshape") + } + .fontWeight(.medium) + } + ) + // .opacity(animateContent ? 1 : 0) + // .offset(x: animateContent ? 0 : 100) + // .animation(.easeOut(duration: 0.5).delay(0.6), value: animateContent) } } - .opacity(animateContent ? 1 : 0) - .offset(y: animateContent ? 0 : 30) - .animation(.easeOut(duration: 0.5).delay(0.6), value: animateContent) - - }.dynamicTypeSize(...DynamicTypeSize.accessibility2) // Sets max dynamic size for all Text - - }.padding(.bottom, 20) - .alert(isPresented: $showingOnboardingViewErrorAlert) { - Alert( - title: Text(viewModel.onboardingViewError?.title ?? "Unknown error"), - message: Text(viewModel.onboardingViewError?.detail ?? "No details"), - dismissButton: .default(Text("OK")) { - viewModel.onboardingViewError = nil + .sheet(isPresented: $showingNetworkSettingsSheet) { + NavigationView { + NetworkSettingsView(walletClient: viewModel.$walletClient) } - ) - } - .onAppear { - withAnimation { - animateContent = true } - } + }.padding(.bottom, 20) + .alert(isPresented: $showingOnboardingViewErrorAlert) { + Alert( + title: Text(viewModel.onboardingViewError?.title ?? "Unknown error"), + message: Text(viewModel.onboardingViewError?.detail ?? "No details"), + dismissButton: .default(Text("OK")) { + viewModel.onboardingViewError = nil + } + ) + } + // .onAppear { + // withAnimation { + // animateContent = true + // } + // } + } } } diff --git a/LDKNodeMonday/View/Home/Receive/AmountEntryView.swift b/LDKNodeMonday/View/Home/Receive/AmountEntryView.swift index bc29d9e..1e0953e 100644 --- a/LDKNodeMonday/View/Home/Receive/AmountEntryView.swift +++ b/LDKNodeMonday/View/Home/Receive/AmountEntryView.swift @@ -51,18 +51,28 @@ struct AmountEntryView: View { .padding(.horizontal, 50) .padding(.bottom, 30) - Button { + // Button { + // amount = UInt64(numpadAmount) ?? 0 + // dismiss() + // } label: { + // Text("Done") + // } + // .buttonStyle( + // BitcoinOutlined( + // tintColor: .accent, + // isCapsule: true + // ) + // ) + + Button.init { amount = UInt64(numpadAmount) ?? 0 dismiss() } label: { Text("Done") + .padding(.all, 10) + .padding(.horizontal, 80) } - .buttonStyle( - BitcoinOutlined( - tintColor: .accent, - isCapsule: true - ) - ) + .buttonStyle(.borderedProminent) } .padding(.bottom, 20) diff --git a/LDKNodeMonday/View/Home/Send/SendManualEntry.swift b/LDKNodeMonday/View/Home/Send/SendManualEntry.swift index 4dc15ac..f822218 100644 --- a/LDKNodeMonday/View/Home/Send/SendManualEntry.swift +++ b/LDKNodeMonday/View/Home/Send/SendManualEntry.swift @@ -118,18 +118,17 @@ struct SendManualEntry: View { Spacer() - Button { + Button.init { viewModel.sendViewState = .reviewPayment } label: { Text("Review") + .padding(.all, 10) + .padding(.horizontal, 80) } - .buttonStyle( - BitcoinFilled( - tintColor: .accent, - isCapsule: true - ) - ).disabled(viewModel.amountSat == 0) .padding(.bottom, 40) + .buttonStyle(.borderedProminent) + .disabled(viewModel.amountSat == 0) + } } diff --git a/LDKNodeMonday/View/Home/Send/SendReviewView.swift b/LDKNodeMonday/View/Home/Send/SendReviewView.swift index cb69f80..7c83b1c 100644 --- a/LDKNodeMonday/View/Home/Send/SendReviewView.swift +++ b/LDKNodeMonday/View/Home/Send/SendReviewView.swift @@ -41,7 +41,7 @@ struct SendReviewView: View { .padding(40) } - Button { + Button.init { Task { try await viewModel.send() } @@ -54,15 +54,13 @@ struct SendReviewView: View { } } label: { Text("Send") + .padding(.all, 10) + .padding(.horizontal, 80) } - .buttonStyle( - BitcoinFilled( - tintColor: .accent, - isCapsule: true - ) - ) - .disabled(disableSend()) .padding(.bottom, 40) + .buttonStyle(.borderedProminent) + .disabled(disableSend()) + } } diff --git a/LDKNodeMonday/View/Home/Send/SendView.swift b/LDKNodeMonday/View/Home/Send/SendView.swift index 072a531..ade5b37 100644 --- a/LDKNodeMonday/View/Home/Send/SendView.swift +++ b/LDKNodeMonday/View/Home/Send/SendView.swift @@ -35,18 +35,17 @@ struct SendView: View { .frame(width: 150, height: 150, alignment: .center) .padding(40) Spacer() - Button { + + Button.init { dismiss() } label: { Text("Done") + .padding(.all, 10) + .padding(.horizontal, 80) } - .buttonStyle( - BitcoinFilled( - tintColor: .accent, - isCapsule: true - ) - ) .padding(.bottom, 40) + .buttonStyle(.borderedProminent) + } } } diff --git a/LDKNodeMonday/View/Settings/Danger/SeedView.swift b/LDKNodeMonday/View/Settings/Danger/SeedView.swift index a8c3bb5..bd35a35 100644 --- a/LDKNodeMonday/View/Settings/Danger/SeedView.swift +++ b/LDKNodeMonday/View/Settings/Danger/SeedView.swift @@ -30,16 +30,21 @@ struct SeedView: View { .multilineTextAlignment(.center) .padding(40) Spacer() - Button("Show Recovery Phrase") { + Button.init { showAlert = true - }.buttonStyle(BitcoinFilled(tintColor: .accentColor, isCapsule: true)) - .alert( - "Are you sure you want to view the recovery phrase?", - isPresented: $showAlert - ) { - Button("Yes", role: .destructive) { showRecoveryPhrase = true } - Button("No", role: .cancel) {} - } + } label: { + Text("Show Recovery Phrase") + .padding(.all, 10) + .padding(.horizontal, 60) + } + .buttonStyle(.borderedProminent) + .alert( + "Are you sure you want to view the recovery phrase?", + isPresented: $showAlert + ) { + Button("Yes", role: .destructive) { showRecoveryPhrase = true } + Button("No", role: .cancel) {} + } } else { SeedPhraseView( words: viewModel.seed.mnemonic.components(separatedBy: " "),