From 182a73bf49893de6e9073794cc0f287ccc756fae Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 12 Aug 2024 23:45:43 +0200 Subject: [PATCH 01/40] works --- RadixWallet.xcodeproj/project.pbxproj | 12 +++- .../OverlayWindowClient+Interface.swift | 56 ++++++++++++------ .../OverlayWindowClient+Live.swift | 41 +++++++++++++ .../OverlayWindowClient+Test.swift | 1 + .../AppFeature/Overlay/HUD+View.swift | 2 +- .../AppFeature/Overlay/Overlay+Reducer.swift | 22 ++++++- .../AppFeature/Overlay/Overlay+View.swift | 8 +++ .../AppFeature/Overlay/Sheet+Reducer.swift | 28 +++++++++ .../AppFeature/Overlay/Sheet+View.swift | 59 +++++++++++++++++++ 9 files changed, 205 insertions(+), 24 deletions(-) create mode 100644 RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift create mode 100644 RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift diff --git a/RadixWallet.xcodeproj/project.pbxproj b/RadixWallet.xcodeproj/project.pbxproj index 9f55f9d755..b9886c91e1 100644 --- a/RadixWallet.xcodeproj/project.pbxproj +++ b/RadixWallet.xcodeproj/project.pbxproj @@ -1080,6 +1080,8 @@ A47572052B29B4F20059A95D /* IOSSecurityClient+Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = A47572022B29B3CA0059A95D /* IOSSecurityClient+Test.swift */; }; A47572062B29B4F50059A95D /* IOSSecurityClient+Live.swift in Sources */ = {isa = PBXBuildFile; fileRef = A47572012B29B3CA0059A95D /* IOSSecurityClient+Live.swift */; }; A47809082BDBDB4C006B68C0 /* RadixDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A47809072BDBDB4C006B68C0 /* RadixDateFormatter.swift */; }; + A48C95AE2C6A97D80047A056 /* Sheet+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AD2C6A97D80047A056 /* Sheet+Reducer.swift */; }; + A48C95B02C6A98380047A056 /* Sheet+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AF2C6A98380047A056 /* Sheet+View.swift */; }; A48FD15F2B55E671009295E9 /* TrackedPoolInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */; }; A48FD1612B55F8F0009295E9 /* TransactionReview+Sections.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */; }; A4B017F72B4C099D00B42B8E /* TransactionReview+DepositSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4B017F42B4BF59000B42B8E /* TransactionReview+DepositSettingView.swift */; }; @@ -2231,6 +2233,8 @@ A47572022B29B3CA0059A95D /* IOSSecurityClient+Test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IOSSecurityClient+Test.swift"; sourceTree = ""; }; A47572032B29B3CA0059A95D /* IOSSecurityClient+Interface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IOSSecurityClient+Interface.swift"; sourceTree = ""; }; A47809072BDBDB4C006B68C0 /* RadixDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadixDateFormatter.swift; sourceTree = ""; }; + A48C95AD2C6A97D80047A056 /* Sheet+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sheet+Reducer.swift"; sourceTree = ""; }; + A48C95AF2C6A98380047A056 /* Sheet+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sheet+View.swift"; sourceTree = ""; }; A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackedPoolInteraction.swift; sourceTree = ""; }; A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionReview+Sections.swift"; sourceTree = ""; }; A4A1379A2BE4630200D84B50 /* RadixWalletDebug-PreAlpha.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "RadixWalletDebug-PreAlpha.entitlements"; sourceTree = ""; }; @@ -2835,11 +2839,13 @@ isa = PBXGroup; children = ( 48CFBCCA2ADC10D800E77A5C /* HUD+Reducer.swift */, - E7AE2D0D2C07359500830BAA /* FullScreenOverlayCoordinator+Reducer.swift */, 48CFBCCC2ADC10D800E77A5C /* HUD+View.swift */, + E7AE2D0D2C07359500830BAA /* FullScreenOverlayCoordinator+Reducer.swift */, + E7AE2D0F2C07371C00830BAA /* FullScreenOverlayCoordinator+View.swift */, + A48C95AD2C6A97D80047A056 /* Sheet+Reducer.swift */, + A48C95AF2C6A98380047A056 /* Sheet+View.swift */, 48CFBCCB2ADC10D800E77A5C /* Overlay+Reducer.swift */, 48CFBCCD2ADC10D800E77A5C /* Overlay+View.swift */, - E7AE2D0F2C07371C00830BAA /* FullScreenOverlayCoordinator+View.swift */, ); path = Overlay; sourceTree = ""; @@ -7048,6 +7054,7 @@ 48CFC2D32ADC10D900E77A5C /* AccountDetails+Reducer.swift in Sources */, 48CFC4822ADC10DA00E77A5C /* ROLAClient+Mock.swift in Sources */, 48CFC5022ADC10DA00E77A5C /* CursorLimitMixin.swift in Sources */, + A48C95AE2C6A97D80047A056 /* Sheet+Reducer.swift in Sources */, 48CFC42A2ADC10DA00E77A5C /* SafeCompare.swift in Sources */, 48CFC4512ADC10DA00E77A5C /* NetworkSwitchingClient+Test.swift in Sources */, 48CFC56D2ADC10DA00E77A5C /* TransactionReceipt.swift in Sources */, @@ -7838,6 +7845,7 @@ 83EE477A2AF0EE3C00155F03 /* ProgrammaticScryptoSborValueI8.swift in Sources */, 48CFC57B2ADC10DA00E77A5C /* PublicKeyHash.swift in Sources */, 48CFC2FC2ADC10D900E77A5C /* DefaultDepositGuarantees+Reducer.swift in Sources */, + A48C95B02C6A98380047A056 /* Sheet+View.swift in Sources */, 48CFC2D12ADC10D900E77A5C /* Style.swift in Sources */, 48CFC48B2ADC10DA00E77A5C /* DiskPersistenceClient+Interface.swift in Sources */, 48CFC3E92ADC10D900E77A5C /* Hashing.swift in Sources */, diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift index 54e8c9b649..862afc4820 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift @@ -15,6 +15,10 @@ public struct OverlayWindowClient: Sendable { /// Usually to be called from the Main Window. public var scheduleHUD: ScheduleHUD + /// Schedule a sheet to be shown in the Overlay Window. + /// Usually to be called from the Main Window. + public var scheduleSheet: ScheduleSheet + /// Schedule a FullScreen to be shown in the Overlay Window. /// Usually to be called from the Main Window. public var scheduleFullScreen: ScheduleFullScreen @@ -33,6 +37,7 @@ public struct OverlayWindowClient: Sendable { scheduleAlert: @escaping ScheduleAlert, scheduleAlertAndIgnoreAction: @escaping ScheduleAlertAndIgnoreAction, scheduleHUD: @escaping ScheduleHUD, + scheduleSheet: @escaping ScheduleSheet, scheduleFullScreen: @escaping ScheduleFullScreen, sendAlertAction: @escaping SendAlertAction, sendFullScreenAction: @escaping SendFullScreenAction, @@ -43,6 +48,7 @@ public struct OverlayWindowClient: Sendable { self.scheduleAlert = scheduleAlert self.scheduleAlertAndIgnoreAction = scheduleAlertAndIgnoreAction self.scheduleHUD = scheduleHUD + self.scheduleSheet = scheduleSheet self.scheduleFullScreen = scheduleFullScreen self.sendAlertAction = sendAlertAction self.sendFullScreenAction = sendFullScreenAction @@ -58,6 +64,7 @@ extension OverlayWindowClient { public typealias ScheduleAlert = @Sendable (Item.AlertState) async -> Item.AlertAction public typealias ScheduleAlertAndIgnoreAction = @Sendable (Item.AlertState) -> Void public typealias ScheduleHUD = @Sendable (Item.HUD) -> Void + public typealias ScheduleSheet = @Sendable (Item.SheetState, SheetBehavior) -> Void public typealias ScheduleFullScreen = @Sendable (FullScreenOverlayCoordinator.State) async -> FullScreenAction public typealias SendAlertAction = @Sendable (Item.AlertAction, Item.AlertState.ID) -> Void public typealias SendFullScreenAction = @Sendable (FullScreenAction, FullScreenID) -> Void @@ -78,29 +85,18 @@ extension OverlayWindowClient { case emailSupport(additionalInfo: String) } + public struct SheetState: Sendable, Hashable, Identifiable { + public let id = UUID() +// public let icon: Icon? + public let title: String + public let text: String + } + public struct HUD: Sendable, Hashable, Identifiable { public let id = UUID() public let text: String public let icon: Icon? - public struct Icon: Hashable, Sendable { - public enum Kind: Hashable, Sendable { - case asset(ImageAsset) - case system(String) - } - - public let kind: Kind - public let foregroundColor: Color - - public init( - kind: Kind, - foregroundColor: Color = .app.green1 - ) { - self.kind = kind - self.foregroundColor = foregroundColor - } - } - public init( text: String, icon: Icon? = Icon( @@ -113,10 +109,34 @@ extension OverlayWindowClient { } } + public struct Icon: Hashable, Sendable { + public enum Kind: Hashable, Sendable { + case asset(ImageAsset) + case system(String) + } + + public let kind: Kind + public let foregroundColor: Color + + public init( + kind: Kind, + foregroundColor: Color = .app.green1 + ) { + self.kind = kind + self.foregroundColor = foregroundColor + } + } + case hud(HUD) + case sheet(SheetState, SheetBehavior) case alert(AlertState) case fullScreen(FullScreenOverlayCoordinator.State) } + + public enum SheetBehavior: Sendable { + case enqueue + case replace + } } extension DependencyValues { diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index 0b06b921a9..5656ab4ed4 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -50,6 +50,7 @@ extension OverlayWindowClient: DependencyKey { }, scheduleAlertAndIgnoreAction: scheduleAlertAndIgnoreAction, scheduleHUD: { items.send(.hud($0)) }, + scheduleSheet: { items.send(.sheet($0, $1)) }, scheduleFullScreen: { fullScreen in items.send(.fullScreen(fullScreen)) return await fullScreenActions.first { $0.id == fullScreen.id }?.action ?? .dismiss @@ -62,6 +63,46 @@ extension OverlayWindowClient: DependencyKey { }() } +// MARK: - OverlayWindowClient.InfoLink +extension OverlayWindowClient { + public enum InfoLink: String, Sendable { + private static let scheme: String = "infolink" + + case linkingNewAccount + case somethingElse + + public init?(url: URL) { + guard url.scheme == Self.scheme, let host = url.host(), let link = InfoLink(rawValue: host) else { + return nil + } + self = link + } + } +} + +extension OverlayWindowClient { + public func showInfoLink(_ infoLink: InfoLink) { + scheduleSheet(infoLink.sheetState, .replace) + } +} + +extension OverlayWindowClient.InfoLink { + var sheetState: OverlayWindowClient.Item.SheetState { + switch self { + case .linkingNewAccount: + .init(title: "Why your Accounts will be linked", text: linkingNewAccountString) + case .somethingElse: + .init(title: "blabla", text: "blablabettiblabbety blablabettiblabbety blablabettiblabbety") + } + } +} + +let linkingNewAccountString = """ +Paying your transaction fee from this Account will make you identifiable on ledger as both the owner of the fee-paying Account and all other Accounts you use in this transaction. + +*This* is _because_ you’ll **sign** the [transactions](https://github.com) from each [Account](infolink://somethingElse) at the same time, so your Accounts will be linked together in the transaction record. +""" + extension OverlayWindowClient.Item.HUD { public static let updatedAccount = Self(text: L10n.AccountSettings.updatedAccountHUDMessage) public static let copied = Self(text: L10n.AddressAction.copiedToClipboard) diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Test.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Test.swift index ac84a191bb..599e34c6fd 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Test.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Test.swift @@ -6,6 +6,7 @@ extension OverlayWindowClient: TestDependencyKey { scheduleAlert: unimplemented("\(Self.self).scheduleAlert"), scheduleAlertAndIgnoreAction: unimplemented("\(Self.self).scheduleAlertAndIgnoreAction"), scheduleHUD: unimplemented("\(Self.self).scheduleHUD"), + scheduleSheet: unimplemented("\(Self.self).scheduleSheet"), scheduleFullScreen: unimplemented("\(Self.self).scheduleFullScreen"), sendAlertAction: unimplemented("\(Self.self).sendAlertAction"), sendFullScreenAction: unimplemented("\(Self.self).sendFullScreenAction"), diff --git a/RadixWallet/Features/AppFeature/Overlay/HUD+View.swift b/RadixWallet/Features/AppFeature/Overlay/HUD+View.swift index 456503d37b..d537afc0e3 100644 --- a/RadixWallet/Features/AppFeature/Overlay/HUD+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/HUD+View.swift @@ -12,7 +12,7 @@ extension HUD { struct ViewState: Equatable, Sendable { let offset: Double let text: String - let icon: OverlayWindowClient.Item.HUD.Icon? + let icon: OverlayWindowClient.Item.Icon? } struct View: SwiftUI.View { diff --git a/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift index 1148e16b42..1bf0f57047 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift @@ -26,6 +26,7 @@ struct OverlayReducer: Sendable, FeatureReducer { @CasePathable public enum State: Sendable, Hashable { case hud(HUD.State) + case sheet(Sheet.State) case alert(OverlayWindowClient.Item.AlertState) case fullScreen(FullScreenOverlayCoordinator.State) } @@ -33,6 +34,7 @@ struct OverlayReducer: Sendable, FeatureReducer { @CasePathable public enum Action: Sendable, Equatable { case hud(HUD.Action) + case sheet(Sheet.Action) case alert(OverlayWindowClient.Item.AlertAction) case fullScreen(FullScreenOverlayCoordinator.Action) } @@ -41,7 +43,9 @@ struct OverlayReducer: Sendable, FeatureReducer { Scope(state: \.hud, action: \.hud) { HUD() } - + Scope(state: \.sheet, action: \.sheet) { + Sheet() + } Scope(state: \.fullScreen, action: \.fullScreen) { FullScreenOverlayCoordinator() } @@ -75,8 +79,13 @@ struct OverlayReducer: Sendable, FeatureReducer { func reduce(into state: inout State, internalAction: InternalAction) -> Effect { switch internalAction { case let .scheduleItem(event): - state.itemsQueue.append(event) - return showItemIfPossible(state: &state) + if case let .sheet(sheetState, .replace) = event, case .sheet = state.destination { + state.destination = .sheet(sheetState) + return .none + } else { + state.itemsQueue.append(event) + return showItemIfPossible(state: &state) + } case .showNextItemIfPossible: return showItemIfPossible(state: &state) } @@ -99,6 +108,9 @@ struct OverlayReducer: Sendable, FeatureReducer { case .hud(.delegate(.dismiss)): return dismiss(&state) + case .sheet(.delegate(.dismiss)): + return dismiss(&state) + case let .fullScreen(.delegate(action)): if case let .fullScreen(state) = state.itemsQueue.first { overlayWindowClient.sendFullScreenAction(action, state.id) @@ -148,6 +160,10 @@ struct OverlayReducer: Sendable, FeatureReducer { state.destination = .hud(.init(content: hud)) return .none + case let .sheet(sheetState, _): + state.destination = .sheet(sheetState) + return setIsUserInteractionEnabled(&state, isEnabled: true) + case let .alert(alert): state.destination = .alert(alert) return setIsUserInteractionEnabled(&state, isEnabled: true) diff --git a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift index dc31fdb8cb..98a09b9158 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift @@ -34,6 +34,7 @@ private extension View { func destinations(with store: StoreOf) -> some View { let destinationStore = store.destination return alert(with: destinationStore) + .sheet(with: destinationStore) .fullScreenCover(with: destinationStore) } @@ -41,6 +42,13 @@ private extension View { alert(store: destinationStore.scope(state: \.alert, action: \.alert)) } + private func sheet(with destinationStore: PresentationStoreOf) -> some View { + sheet(store: destinationStore.scope(state: \.sheet, action: \.sheet)) { + Sheet.View(store: $0) + .presentationDetents([.medium]) + } + } + private func fullScreenCover(with destinationStore: PresentationStoreOf) -> some View { fullScreenCover(store: destinationStore.scope(state: \.fullScreen, action: \.fullScreen)) { FullScreenOverlayCoordinator.View(store: $0) diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift new file mode 100644 index 0000000000..e2e7b47970 --- /dev/null +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift @@ -0,0 +1,28 @@ +import Foundation + +public struct Sheet: FeatureReducer { + public typealias State = OverlayWindowClient.Item.SheetState + + public enum ViewAction: Equatable, Sendable { + case infoLinkTapped(OverlayWindowClient.InfoLink) + case closeButtonTapped + } + + public enum DelegateAction: Equatable, Sendable { + case dismiss + } + + @Dependency(\.overlayWindowClient) var overlayWindowClient + + public func reduce(into state: inout State, viewAction: ViewAction) -> Effect { + switch viewAction { + case let .infoLinkTapped(infoLink): + overlayWindowClient.showInfoLink(infoLink) + return .none + case .closeButtonTapped: + return .run { send in + await send(.delegate(.dismiss)) + } + } + } +} diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift new file mode 100644 index 0000000000..67fab9c3ef --- /dev/null +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -0,0 +1,59 @@ +import Foundation + +extension Sheet { + public struct View: SwiftUI.View { + private let store: StoreOf + + public init(store: StoreOf) { + self.store = store + } + + public var body: some SwiftUI.View { + WithViewStore(store, observe: { $0 }, send: { .view($0) }) { viewStore in + VStack(spacing: .zero) { + HStack(spacing: .zero) { + CloseButton { + store.send(.view(.closeButtonTapped)) + } + + Spacer() + } + .padding(.horizontal, .medium3) + + Group { + Text(viewStore.title) + .textStyle(.sheetTitle) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.center) + .padding(.bottom, .large2) + + if let attributed = try? AttributedString(markdown: viewStore.text) { + Text(attributed) + .textStyle(.body1Regular) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.leading) + .flushedLeft + .environment(\.openURL, openURL) + } + } + .padding(.horizontal, .large2) + + Spacer() + } + .padding(.top, .medium3) + .animation(.default, value: viewStore.state) + } + } + + private var openURL: OpenURLAction { + OpenURLAction { url in + if let infoLink = OverlayWindowClient.InfoLink(url: url) { + store.send(.view(.infoLinkTapped(infoLink))) + return .handled + } else { + return .systemAction + } + } + } + } +} From a72c46978cc9c56bb0dad669f56361dc63de8857 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Tue, 13 Aug 2024 14:09:53 +0200 Subject: [PATCH 02/40] minor --- .../OverlayWindowClient+Live.swift | 2 +- .../AppFeature/Overlay/Sheet+View.swift | 21 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index 5656ab4ed4..38fb57c80e 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -100,7 +100,7 @@ extension OverlayWindowClient.InfoLink { let linkingNewAccountString = """ Paying your transaction fee from this Account will make you identifiable on ledger as both the owner of the fee-paying Account and all other Accounts you use in this transaction. -*This* is _because_ you’ll **sign** the [transactions](https://github.com) from each [Account](infolink://somethingElse) at the same time, so your Accounts will be linked together in the transaction record. +*This* is _because_ you’ll **sign** the [transactions](https://github.com) from each [Account **ⓘ**](infolink://somethingElse) at the same time, so your Accounts will be linked together in the transaction record. """ extension OverlayWindowClient.Item.HUD { diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift index 67fab9c3ef..890c1ae52e 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -1,5 +1,6 @@ import Foundation +// MARK: - Sheet.View extension Sheet { public struct View: SwiftUI.View { private let store: StoreOf @@ -27,14 +28,12 @@ extension Sheet { .multilineTextAlignment(.center) .padding(.bottom, .large2) - if let attributed = try? AttributedString(markdown: viewStore.text) { - Text(attributed) - .textStyle(.body1Regular) - .foregroundColor(.app.gray1) - .multilineTextAlignment(.leading) - .flushedLeft - .environment(\.openURL, openURL) - } + Text(viewStore.attributedString) + .textStyle(.body1Regular) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.leading) + .flushedLeft + .environment(\.openURL, openURL) } .padding(.horizontal, .large2) @@ -57,3 +56,9 @@ extension Sheet { } } } + +extension Sheet.State { + var attributedString: AttributedString { + (try? AttributedString(markdown: text, options: .init(interpretedSyntax: .inlineOnlyPreservingWhitespace))) ?? .init(text) + } +} From fd4f9f73535dc6e7221d14f4c373559fa4c3a5a5 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Tue, 13 Aug 2024 14:48:29 +0200 Subject: [PATCH 03/40] with parsing --- .../OverlayWindowClient+Live.swift | 3 +- .../AppFeature/Overlay/Sheet+View.swift | 106 +++++++++++++++--- .../HomeFeature/Coordinator/Home.swift | 12 +- 3 files changed, 100 insertions(+), 21 deletions(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index 38fb57c80e..ef8248d4a6 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -92,12 +92,13 @@ extension OverlayWindowClient.InfoLink { case .linkingNewAccount: .init(title: "Why your Accounts will be linked", text: linkingNewAccountString) case .somethingElse: - .init(title: "blabla", text: "blablabettiblabbety blablabettiblabbety blablabettiblabbety") + .init(title: "blabla", text: "# antoher headiing\n blablabettiblabbety blablabettiblabbety blablabettiblabbety") } } } let linkingNewAccountString = """ +# Why your Accounts will be linked!! Paying your transaction fee from this Account will make you identifiable on ledger as both the owner of the fee-paying Account and all other Accounts you use in this transaction. *This* is _because_ you’ll **sign** the [transactions](https://github.com) from each [Account **ⓘ**](infolink://somethingElse) at the same time, so your Accounts will be linked together in the transaction record. diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift index 890c1ae52e..04075dd59b 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -21,20 +21,10 @@ extension Sheet { } .padding(.horizontal, .medium3) - Group { - Text(viewStore.title) - .textStyle(.sheetTitle) - .foregroundColor(.app.gray1) - .multilineTextAlignment(.center) - .padding(.bottom, .large2) - - Text(viewStore.attributedString) - .textStyle(.body1Regular) - .foregroundColor(.app.gray1) - .multilineTextAlignment(.leading) - .flushedLeft - .environment(\.openURL, openURL) + ForEachStatic(viewStore.parts) { part in + PartView(part: part) } + .environment(\.openURL, openURL) .padding(.horizontal, .large2) Spacer() @@ -55,10 +45,96 @@ extension Sheet { } } } + + struct PartView: SwiftUI.View { + let part: Part + + var body: some SwiftUI.View { + switch part { + case let .heading1(heading1): + Text(heading1) + .textStyle(.sheetTitle) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.center) + .padding(.bottom, .medium3) + case let .heading2(heading2): + Text(heading2) + .textStyle(.body1Header) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.center) + .padding(.bottom, .medium3) + case let .heading3(heading3): + Text(heading3) + .textStyle(.body2Header) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.center) + .padding(.bottom, .medium3) + case let .text(text): + Text(text) + .textStyle(.body1Regular) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.leading) + .flushedLeft + .padding(.bottom, .large2) + } + } + } +} + +// MARK: - Sheet.Part +extension Sheet { + enum Part { + case heading1(String) + case heading2(String) + case heading3(String) + case text(AttributedString) + } } extension Sheet.State { - var attributedString: AttributedString { - (try? AttributedString(markdown: text, options: .init(interpretedSyntax: .inlineOnlyPreservingWhitespace))) ?? .init(text) + private func heading(from row: Substring) -> Sheet.Part? { + if row.hasPrefix("# ") { + .heading1(String(row.dropFirst(2))) + } else if row.hasPrefix("## ") { + .heading2(String(row.dropFirst(3))) + } else if row.hasPrefix("### ") { + .heading3(String(row.dropFirst(4))) + } else { + nil + } + } + + var parts: [Sheet.Part] { + var result: [Sheet.Part] = [] + var currentText = "" + + func addCurrentText() { + if !currentText.isEmpty { + result.append(.text(currentText.markdownAttributed)) + currentText = "" + } + } + + for row in text.split(separator: "\n", omittingEmptySubsequences: false) { + if let heading = heading(from: row) { + addCurrentText() + result.append(heading) + } else { + if !currentText.isEmpty { + currentText.append("\n") + } + currentText.append(String(row)) + } + } + + addCurrentText() + + return result + } +} + +extension String { + var markdownAttributed: AttributedString { + (try? AttributedString(markdown: self, options: .init(interpretedSyntax: .inlineOnlyPreservingWhitespace))) ?? .init(self) } } diff --git a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift index bd68b8769e..ccf6650765 100644 --- a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift +++ b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift @@ -193,11 +193,13 @@ public struct Home: Sendable, FeatureReducer { return .cancel(id: CancellableId.fetchAccountPortfolios) case .createAccountButtonTapped: - state.destination = .createAccount( - .init(config: .init( - purpose: .newAccountFromHome - )) - ) + overlayWindowClient.showInfoLink(.linkingNewAccount) + +// state.destination = .createAccount( +// .init(config: .init( +// purpose: .newAccountFromHome +// )) +// ) return .none case .pullToRefreshStarted: From 521e2ca68000bae4a4b317ef43158662ebf2f779 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Tue, 13 Aug 2024 15:53:45 +0200 Subject: [PATCH 04/40] parsing complete --- .../OverlayWindowClient+Interface.swift | 1 - .../OverlayWindowClient+Live.swift | 63 ++++++++++++++++--- .../DesignSystem/Components/CloseButton.swift | 2 +- .../AppFeature/Overlay/Sheet+View.swift | 38 ++++++----- 4 files changed, 74 insertions(+), 30 deletions(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift index 862afc4820..f82a92d9b0 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift @@ -88,7 +88,6 @@ extension OverlayWindowClient { public struct SheetState: Sendable, Hashable, Identifiable { public let id = UUID() // public let icon: Icon? - public let title: String public let text: String } diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index ef8248d4a6..641557d3c5 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -69,7 +69,11 @@ extension OverlayWindowClient { private static let scheme: String = "infolink" case linkingNewAccount - case somethingElse + case poolunit + case gateways + case radixconnect + case transactionfee + case securityshield public init?(url: URL) { guard url.scheme == Self.scheme, let host = url.host(), let link = InfoLink(rawValue: host) else { @@ -82,26 +86,69 @@ extension OverlayWindowClient { extension OverlayWindowClient { public func showInfoLink(_ infoLink: InfoLink) { - scheduleSheet(infoLink.sheetState, .replace) + scheduleSheet(.init(text: infoLink.string), .replace) } } extension OverlayWindowClient.InfoLink { - var sheetState: OverlayWindowClient.Item.SheetState { + var string: String { switch self { case .linkingNewAccount: - .init(title: "Why your Accounts will be linked", text: linkingNewAccountString) - case .somethingElse: - .init(title: "blabla", text: "# antoher headiing\n blablabettiblabbety blablabettiblabbety blablabettiblabbety") + linkingNewAccountString + case .poolunit: + poolunitString + case .gateways: + gatewaysString + case .radixconnect: + radixconnectString + case .transactionfee: + transactionfeeString + case .securityshield: + securityshieldString } } } let linkingNewAccountString = """ -# Why your Accounts will be linked!! +# Why your Accounts will be linked Paying your transaction fee from this Account will make you identifiable on ledger as both the owner of the fee-paying Account and all other Accounts you use in this transaction. -*This* is _because_ you’ll **sign** the [transactions](https://github.com) from each [Account **ⓘ**](infolink://somethingElse) at the same time, so your Accounts will be linked together in the transaction record. +*This* is _because_ you’ll **sign** the transactions on [github](https://github.com) from each [transaction fee ⓘ](infolink://transactionfee) at the same time, so your Accounts will be linked together in the transaction record. +""" + +let poolunitString = """ +# Pool Units +Pool units are fungible tokens that represent the proportional size of a user's contribution to a liquidity pool (LP). + +Pool units are redeemable for the user's portion of the LP, but can also be traded, sold and used in DeFi applications. +""" + +let gatewaysString = """ +# Gateways +Gateways are your connection to blockchain networks – they enable users to communicate with the Radix Network and transfer data to and from it. As there are multiple different networks within the Radix ecosystem (for example, the Stokenet test environment or the Babylon mainnet), there a multiple gateways providing access to each one. +""" + +let radixconnectString = """ +# Radix Connect +Radix Connect enables users to link their Radix Wallet to desktop dApps. +""" + +let transactionfeeString = """ +# Transaction Fee + +## Network fee +These go to Radix node operators who validate transactions and secure the Radix Network. Network fees reflect the size of the transaction. + +## Royalty fee +These are set by developers and allow them to collect a “use fee” every time their work is used in a transaction. + +## Tip +These are optional payments you can make directly to validators to speed up transactions. [pool unit ⓘ](infolink://poolunit) +""" + +let securityshieldString = """ +# Security Shields +Security Shields are a combination of security factors you use to sign transactions, and recover locked Accounts and Personas. You'll need to pay a small transaction fee to apply one to the Radix Network. """ extension OverlayWindowClient.Item.HUD { diff --git a/RadixWallet/Core/DesignSystem/Components/CloseButton.swift b/RadixWallet/Core/DesignSystem/Components/CloseButton.swift index 742a5a0a7f..884d058762 100644 --- a/RadixWallet/Core/DesignSystem/Components/CloseButton.swift +++ b/RadixWallet/Core/DesignSystem/Components/CloseButton.swift @@ -8,9 +8,9 @@ public struct CloseButtonBar: View { public var body: some View { HStack { - Spacer() CloseButton(action: action) .padding(.small2) + Spacer() } } } diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift index 04075dd59b..6f0b4c951c 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -12,25 +12,23 @@ extension Sheet { public var body: some SwiftUI.View { WithViewStore(store, observe: { $0 }, send: { .view($0) }) { viewStore in VStack(spacing: .zero) { - HStack(spacing: .zero) { - CloseButton { - store.send(.view(.closeButtonTapped)) - } - - Spacer() + CloseButtonBar { + store.send(.view(.closeButtonTapped)) } - .padding(.horizontal, .medium3) - - ForEachStatic(viewStore.parts) { part in - PartView(part: part) + .padding(.horizontal, .small3) + + ScrollView { + VStack(spacing: .zero) { + ForEach(viewStore.parts, id: \.self) { part in + PartView(part: part) + } + .environment(\.openURL, openURL) + .padding(.horizontal, .large2) + } + .padding(.top, .small2) } - .environment(\.openURL, openURL) - .padding(.horizontal, .large2) - - Spacer() + .animation(.default, value: viewStore.text) } - .padding(.top, .medium3) - .animation(.default, value: viewStore.state) } } @@ -59,13 +57,13 @@ extension Sheet { .padding(.bottom, .medium3) case let .heading2(heading2): Text(heading2) - .textStyle(.body1Header) + .textStyle(.sectionHeader) .foregroundColor(.app.gray1) .multilineTextAlignment(.center) .padding(.bottom, .medium3) case let .heading3(heading3): Text(heading3) - .textStyle(.body2Header) + .textStyle(.body1Header) .foregroundColor(.app.gray1) .multilineTextAlignment(.center) .padding(.bottom, .medium3) @@ -75,7 +73,7 @@ extension Sheet { .foregroundColor(.app.gray1) .multilineTextAlignment(.leading) .flushedLeft - .padding(.bottom, .large2) + .padding(.bottom, .small3) } } } @@ -83,7 +81,7 @@ extension Sheet { // MARK: - Sheet.Part extension Sheet { - enum Part { + enum Part: Hashable { case heading1(String) case heading2(String) case heading3(String) From a9035b0ac9adabc767ef846a132a7e49afae16c2 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Tue, 13 Aug 2024 16:25:51 +0200 Subject: [PATCH 05/40] glossary anchor --- .../OverlayWindowClient/OverlayWindowClient+Live.swift | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index 641557d3c5..90c28a0cd0 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -76,9 +76,15 @@ extension OverlayWindowClient { case securityshield public init?(url: URL) { - guard url.scheme == Self.scheme, let host = url.host(), let link = InfoLink(rawValue: host) else { + guard url.scheme == nil, url.host == nil, url.pathComponents.isEmpty, let query = url.query() else { return nil } + + let parts = query.split(separator: "=") + guard parts.count == 2, parts[0] == "glossaryAnchor", let link = InfoLink(rawValue: String(parts[1])) else { + return nil + } + self = link } } @@ -111,7 +117,7 @@ extension OverlayWindowClient.InfoLink { let linkingNewAccountString = """ # Why your Accounts will be linked -Paying your transaction fee from this Account will make you identifiable on ledger as both the owner of the fee-paying Account and all other Accounts you use in this transaction. +Paying your transaction fee from this Account will make you [poolunit](?glossaryAnchor=poolunit) identifiable on ledger as both the owner of the fee-paying Account and all other Accounts you use in this transaction. *This* is _because_ you’ll **sign** the transactions on [github](https://github.com) from each [transaction fee ⓘ](infolink://transactionfee) at the same time, so your Accounts will be linked together in the transaction record. """ From 3d59e64e40b131828537af78d93696b2cd2dcd1a Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 14 Aug 2024 10:01:00 +0200 Subject: [PATCH 06/40] infolink --- RadixWallet.xcodeproj/project.pbxproj | 4 + .../OverlayWindowClient/InfoLink.swift | 113 ++++++++++++++++++ .../OverlayWindowClient+Live.swift | 88 -------------- .../HomeFeature/Coordinator/Home.swift | 2 +- 4 files changed, 118 insertions(+), 89 deletions(-) create mode 100644 RadixWallet/Clients/OverlayWindowClient/InfoLink.swift diff --git a/RadixWallet.xcodeproj/project.pbxproj b/RadixWallet.xcodeproj/project.pbxproj index b9886c91e1..e581600088 100644 --- a/RadixWallet.xcodeproj/project.pbxproj +++ b/RadixWallet.xcodeproj/project.pbxproj @@ -1082,6 +1082,7 @@ A47809082BDBDB4C006B68C0 /* RadixDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A47809072BDBDB4C006B68C0 /* RadixDateFormatter.swift */; }; A48C95AE2C6A97D80047A056 /* Sheet+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AD2C6A97D80047A056 /* Sheet+Reducer.swift */; }; A48C95B02C6A98380047A056 /* Sheet+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AF2C6A98380047A056 /* Sheet+View.swift */; }; + A48C95B22C6C9A660047A056 /* InfoLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95B12C6C9A660047A056 /* InfoLink.swift */; }; A48FD15F2B55E671009295E9 /* TrackedPoolInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */; }; A48FD1612B55F8F0009295E9 /* TransactionReview+Sections.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */; }; A4B017F72B4C099D00B42B8E /* TransactionReview+DepositSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4B017F42B4BF59000B42B8E /* TransactionReview+DepositSettingView.swift */; }; @@ -2235,6 +2236,7 @@ A47809072BDBDB4C006B68C0 /* RadixDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadixDateFormatter.swift; sourceTree = ""; }; A48C95AD2C6A97D80047A056 /* Sheet+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sheet+Reducer.swift"; sourceTree = ""; }; A48C95AF2C6A98380047A056 /* Sheet+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sheet+View.swift"; sourceTree = ""; }; + A48C95B12C6C9A660047A056 /* InfoLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoLink.swift; sourceTree = ""; }; A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackedPoolInteraction.swift; sourceTree = ""; }; A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionReview+Sections.swift"; sourceTree = ""; }; A4A1379A2BE4630200D84B50 /* RadixWalletDebug-PreAlpha.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "RadixWalletDebug-PreAlpha.entitlements"; sourceTree = ""; }; @@ -4488,6 +4490,7 @@ 48CFBF8B2ADC10D900E77A5C /* OverlayWindowClient+Test.swift */, 48CFBFB22ADC10D900E77A5C /* OverlayWindowClient+Live.swift */, 48CFBF8C2ADC10D900E77A5C /* OverlayWindowClient+Interface.swift */, + A48C95B12C6C9A660047A056 /* InfoLink.swift */, ); path = OverlayWindowClient; sourceTree = ""; @@ -7512,6 +7515,7 @@ E65D6CEE2BC98267001D8A39 /* Stage2MigrateToSargon+AppPreferences+ViaProfile.swift in Sources */, E634CA2F2AFD25B100C43DB7 /* DebugKeychainContents+View.swift in Sources */, 48CFC53F2ADC10DA00E77A5C /* MetadataU8Value.swift in Sources */, + A48C95B22C6C9A660047A056 /* InfoLink.swift in Sources */, 48CFC4CC2ADC10DA00E77A5C /* Models.swift in Sources */, 83EE5ED62BE3C16F00B1531D /* AccountDepositPreValidationResourceSpecificBehaviourItem.swift in Sources */, 48CFC3132ADC10D900E77A5C /* CompletionMigrateOlympiaAccountsToBabylon+View.swift in Sources */, diff --git a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift new file mode 100644 index 0000000000..ea2c94f053 --- /dev/null +++ b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift @@ -0,0 +1,113 @@ +import Foundation + +// MARK: - OverlayWindowClient.InfoLink +extension OverlayWindowClient { + public enum InfoLink: Equatable, Sendable { + case info(InfoItem) + case glossary(GlossaryItem) + + public enum InfoItem: String, Sendable { + case radixConnect + case linkingNewAccount + } + + public enum GlossaryItem: String, Sendable { + case radixnetwork + } + } +} + +extension OverlayWindowClient.InfoLink { + public enum AnchorType: String, Sendable { + case info = "infoAnchor" + case glossary = "glossaryAnchor" + } + + public init?(url: URL) { + guard url.scheme == nil, url.host == nil, url.pathComponents.isEmpty, let query = url.query() else { + return nil + } + + let parts = query.split(separator: "=") + guard parts.count == 2, let type = AnchorType(rawValue: String(parts[0])) else { return nil } + switch type { + case .info: + guard let item = InfoItem(rawValue: String(parts[1])) else { return nil } + self = .info(item) + case .glossary: + guard let item = GlossaryItem(rawValue: String(parts[1])) else { return nil } + self = .glossary(item) + } + } + + var string: String { + switch self { + case let .info(item): + item.string + case let .glossary(item): + item.string + } + } +} + +extension OverlayWindowClient.InfoLink.InfoItem { + var string: String { + switch self { + case .radixConnect: + radixconnectString + case .linkingNewAccount: + linkingNewAccountString + } + } +} + +extension OverlayWindowClient.InfoLink.GlossaryItem { + var string: String { + switch self { + case .radixnetwork: + transactionfeeString + } + } +} + +let linkingNewAccountString = """ +# Why your Accounts will be linked +Paying your transaction fee from this Account will make you [poolunit](?glossaryAnchor=poolunit) identifiable on ledger as both the owner of the fee-paying Account and all other Accounts you use in this transaction. + +*This* is _because_ you’ll **sign** the transactions on [github](https://github.com) from each [transaction fee ⓘ](infolink://transactionfee) at the same time, so your Accounts will be linked together in the transaction record. +""" + +let poolunitString = """ +# Pool Units +Pool units are fungible tokens that represent the proportional size of a user's contribution to a liquidity pool (LP). + +Pool units are redeemable for the user's portion of the LP, but can also be traded, sold and used in DeFi applications. +""" + +let gatewaysString = """ +# Gateways +Gateways are your connection to blockchain networks – they enable users to communicate with the Radix Network and transfer data to and from it. As there are multiple different networks within the Radix ecosystem (for example, the Stokenet test environment or the Babylon mainnet), there a multiple gateways providing access to each one. +""" + +let radixconnectString = """ +# Radix Connect +Radix Connect enables users to link their Radix Wallet to desktop dApps. +""" + +let transactionfeeString = """ +# Transaction Fee + +## Network fee +These go to Radix node operators who validate transactions and secure the Radix Network. Network fees reflect the size of the transaction. + +## Royalty fee +These are set by developers and allow them to collect a “use fee” every time their work is used in a transaction. + +## Tip +These are optional payments you can make directly to validators to speed up transactions. [pool unit ⓘ](infolink://poolunit) +""" + +let securityshieldString = """ +# Security Shields +Security Shields are a combination of security factors you use to sign transactions, and recover locked Accounts and Personas. You'll need to pay a small transaction fee to apply one to the Radix Network. +""" diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index 90c28a0cd0..68c2ad1874 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -63,100 +63,12 @@ extension OverlayWindowClient: DependencyKey { }() } -// MARK: - OverlayWindowClient.InfoLink -extension OverlayWindowClient { - public enum InfoLink: String, Sendable { - private static let scheme: String = "infolink" - - case linkingNewAccount - case poolunit - case gateways - case radixconnect - case transactionfee - case securityshield - - public init?(url: URL) { - guard url.scheme == nil, url.host == nil, url.pathComponents.isEmpty, let query = url.query() else { - return nil - } - - let parts = query.split(separator: "=") - guard parts.count == 2, parts[0] == "glossaryAnchor", let link = InfoLink(rawValue: String(parts[1])) else { - return nil - } - - self = link - } - } -} - extension OverlayWindowClient { public func showInfoLink(_ infoLink: InfoLink) { scheduleSheet(.init(text: infoLink.string), .replace) } } -extension OverlayWindowClient.InfoLink { - var string: String { - switch self { - case .linkingNewAccount: - linkingNewAccountString - case .poolunit: - poolunitString - case .gateways: - gatewaysString - case .radixconnect: - radixconnectString - case .transactionfee: - transactionfeeString - case .securityshield: - securityshieldString - } - } -} - -let linkingNewAccountString = """ -# Why your Accounts will be linked -Paying your transaction fee from this Account will make you [poolunit](?glossaryAnchor=poolunit) identifiable on ledger as both the owner of the fee-paying Account and all other Accounts you use in this transaction. - -*This* is _because_ you’ll **sign** the transactions on [github](https://github.com) from each [transaction fee ⓘ](infolink://transactionfee) at the same time, so your Accounts will be linked together in the transaction record. -""" - -let poolunitString = """ -# Pool Units -Pool units are fungible tokens that represent the proportional size of a user's contribution to a liquidity pool (LP). - -Pool units are redeemable for the user's portion of the LP, but can also be traded, sold and used in DeFi applications. -""" - -let gatewaysString = """ -# Gateways -Gateways are your connection to blockchain networks – they enable users to communicate with the Radix Network and transfer data to and from it. As there are multiple different networks within the Radix ecosystem (for example, the Stokenet test environment or the Babylon mainnet), there a multiple gateways providing access to each one. -""" - -let radixconnectString = """ -# Radix Connect -Radix Connect enables users to link their Radix Wallet to desktop dApps. -""" - -let transactionfeeString = """ -# Transaction Fee - -## Network fee -These go to Radix node operators who validate transactions and secure the Radix Network. Network fees reflect the size of the transaction. - -## Royalty fee -These are set by developers and allow them to collect a “use fee” every time their work is used in a transaction. - -## Tip -These are optional payments you can make directly to validators to speed up transactions. [pool unit ⓘ](infolink://poolunit) -""" - -let securityshieldString = """ -# Security Shields -Security Shields are a combination of security factors you use to sign transactions, and recover locked Accounts and Personas. You'll need to pay a small transaction fee to apply one to the Radix Network. -""" - extension OverlayWindowClient.Item.HUD { public static let updatedAccount = Self(text: L10n.AccountSettings.updatedAccountHUDMessage) public static let copied = Self(text: L10n.AddressAction.copiedToClipboard) diff --git a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift index ccf6650765..2d5e0de364 100644 --- a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift +++ b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift @@ -193,7 +193,7 @@ public struct Home: Sendable, FeatureReducer { return .cancel(id: CancellableId.fetchAccountPortfolios) case .createAccountButtonTapped: - overlayWindowClient.showInfoLink(.linkingNewAccount) + overlayWindowClient.showInfoLink(.info(.linkingNewAccount)) // state.destination = .createAccount( // .init(config: .init( From fc9fe7a2cc41a69173cf497ddd9413690588818a Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 14 Aug 2024 12:20:47 +0200 Subject: [PATCH 07/40] wip --- .../OverlayWindowClient/InfoLink.swift | 65 ++++++++++++++++++- .../HomeFeature/Coordinator/Home.swift | 3 +- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift index ea2c94f053..3130897818 100644 --- a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift +++ b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift @@ -13,6 +13,27 @@ extension OverlayWindowClient { public enum GlossaryItem: String, Sendable { case radixnetwork + case radquest + case tokens + case nfts + case web3 + case accounts + case personas + case radixwallet + case dapps + case transactions + case transactionfee + case xrd + case badges + case transfers + case dex + case guarantees + case networkstaking + case validators + case radixconnector + case connectbutton + case dashboard + case bridging } } } @@ -65,7 +86,49 @@ extension OverlayWindowClient.InfoLink.GlossaryItem { var string: String { switch self { case .radixnetwork: - transactionfeeString + L10n.InfoLink.Glossary.radixnetwork + case .radquest: + L10n.InfoLink.Glossary.radquest + case .tokens: + L10n.InfoLink.Glossary.tokens + case .nfts: + L10n.InfoLink.Glossary.nfts + case .web3: + L10n.InfoLink.Glossary.web3 + case .accounts: + L10n.InfoLink.Glossary.accounts + case .personas: + L10n.InfoLink.Glossary.personas + case .radixwallet: + L10n.InfoLink.Glossary.radixwallet + case .dapps: + L10n.InfoLink.Glossary.dapps + case .transactions: + L10n.InfoLink.Glossary.transactions + case .transactionfee: + L10n.InfoLink.Glossary.transactionfee + case .xrd: + L10n.InfoLink.Glossary.xrd + case .badges: + L10n.InfoLink.Glossary.badges + case .transfers: + L10n.InfoLink.Glossary.transfers + case .dex: + L10n.InfoLink.Glossary.dex + case .guarantees: + L10n.InfoLink.Glossary.guarantees + case .networkstaking: + L10n.InfoLink.Glossary.networkstaking + case .validators: + L10n.InfoLink.Glossary.validators + case .radixconnector: + L10n.InfoLink.Glossary.radixconnector + case .connectbutton: + L10n.InfoLink.Glossary.connectbutton + case .dashboard: + L10n.InfoLink.Glossary.dashboard + case .bridging: + L10n.InfoLink.Glossary.bridging } } } diff --git a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift index 2d5e0de364..e19b97441d 100644 --- a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift +++ b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift @@ -193,7 +193,8 @@ public struct Home: Sendable, FeatureReducer { return .cancel(id: CancellableId.fetchAccountPortfolios) case .createAccountButtonTapped: - overlayWindowClient.showInfoLink(.info(.linkingNewAccount)) +// overlayWindowClient.showInfoLink(.info(.linkingNewAccount)) + overlayWindowClient.showInfoLink(.glossary(.radixnetwork)) // state.destination = .createAccount( // .init(config: .init( From c80a53292b659f2296d3f34ff715b9dafdcc08c4 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 14 Aug 2024 12:33:56 +0200 Subject: [PATCH 08/40] wip --- .../OverlayWindowClient/InfoLink.swift | 46 +------------------ 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift index 3130897818..0ef5af584d 100644 --- a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift +++ b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift @@ -75,9 +75,9 @@ extension OverlayWindowClient.InfoLink.InfoItem { var string: String { switch self { case .radixConnect: - radixconnectString + fatalError() case .linkingNewAccount: - linkingNewAccountString + fatalError() } } } @@ -132,45 +132,3 @@ extension OverlayWindowClient.InfoLink.GlossaryItem { } } } - -let linkingNewAccountString = """ -# Why your Accounts will be linked -Paying your transaction fee from this Account will make you [poolunit](?glossaryAnchor=poolunit) identifiable on ledger as both the owner of the fee-paying Account and all other Accounts you use in this transaction. - -*This* is _because_ you’ll **sign** the transactions on [github](https://github.com) from each [transaction fee ⓘ](infolink://transactionfee) at the same time, so your Accounts will be linked together in the transaction record. -""" - -let poolunitString = """ -# Pool Units -Pool units are fungible tokens that represent the proportional size of a user's contribution to a liquidity pool (LP). - -Pool units are redeemable for the user's portion of the LP, but can also be traded, sold and used in DeFi applications. -""" - -let gatewaysString = """ -# Gateways -Gateways are your connection to blockchain networks – they enable users to communicate with the Radix Network and transfer data to and from it. As there are multiple different networks within the Radix ecosystem (for example, the Stokenet test environment or the Babylon mainnet), there a multiple gateways providing access to each one. -""" - -let radixconnectString = """ -# Radix Connect -Radix Connect enables users to link their Radix Wallet to desktop dApps. -""" - -let transactionfeeString = """ -# Transaction Fee - -## Network fee -These go to Radix node operators who validate transactions and secure the Radix Network. Network fees reflect the size of the transaction. - -## Royalty fee -These are set by developers and allow them to collect a “use fee” every time their work is used in a transaction. - -## Tip -These are optional payments you can make directly to validators to speed up transactions. [pool unit ⓘ](infolink://poolunit) -""" - -let securityshieldString = """ -# Security Shields -Security Shields are a combination of security factors you use to sign transactions, and recover locked Accounts and Personas. You'll need to pay a small transaction fee to apply one to the Radix Network. -""" From 0728d4f0d4eea89560b3cfa2622809a5b656d92a Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 21 Aug 2024 14:39:54 +0200 Subject: [PATCH 09/40] wip --- .../OverlayWindowClient/InfoLink.swift | 27 +++++++++++++++++++ .../AppFeature/Overlay/Sheet+View.swift | 10 ++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift index 0ef5af584d..ea9c64e498 100644 --- a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift +++ b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift @@ -83,6 +83,33 @@ extension OverlayWindowClient.InfoLink.InfoItem { } extension OverlayWindowClient.InfoLink.GlossaryItem { +// var image: Image { +// switch self { +// case .radixnetwork: +// case .radquest: +// case .tokens: +// case .nfts: +// case .web3: +// case .accounts: +// case .personas: +// case .radixwallet: +// case .dapps: +// case .transactions: +// case .transactionfee: +// case .xrd: +// case .badges: +// case .transfers: +// case .dex: +// case .guarantees: +// case .networkstaking: +// case .validators: +// case .radixconnector: +// case .connectbutton: +// case .dashboard: +// case .bridging: +// } +// } + var string: String { switch self { case .radixnetwork: diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift index 6f0b4c951c..ff3fc084a7 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -54,7 +54,7 @@ extension Sheet { .textStyle(.sheetTitle) .foregroundColor(.app.gray1) .multilineTextAlignment(.center) - .padding(.bottom, .medium3) + .padding(.bottom, .large2) case let .heading2(heading2): Text(heading2) .textStyle(.sectionHeader) @@ -74,6 +74,11 @@ extension Sheet { .multilineTextAlignment(.leading) .flushedLeft .padding(.bottom, .small3) + case .divider: + Divider() + .padding(.top, .small1) + .padding(.horizontal, -.small2) + .padding(.bottom, .large2) } } } @@ -86,6 +91,7 @@ extension Sheet { case heading2(String) case heading3(String) case text(AttributedString) + case divider } } @@ -97,6 +103,8 @@ extension Sheet.State { .heading2(String(row.dropFirst(3))) } else if row.hasPrefix("### ") { .heading3(String(row.dropFirst(4))) + } else if row.hasPrefix("---") { + .divider } else { nil } From 1724a6dba0aca889c124b20028bf626ab2d847d4 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Thu, 22 Aug 2024 10:51:03 +0200 Subject: [PATCH 10/40] cleanup --- .../OverlayWindowClient/InfoLink.swift | 150 +++++++----------- .../OverlayWindowClient+Live.swift | 4 +- .../Generated/AssetResource.generated.swift | 7 +- .../Contents.json | 0 .../ICON-NFTS.pdf | Bin .../Icon-Market-Cap.imageset/Contents.json | 21 --- .../Icon-Market-Cap.pdf | Bin 15093 -> 0 bytes .../Placeholders/nft.imageset/Contents.json | 12 -- .../Placeholders/nft.imageset/icon-nft.pdf | Bin 20865 -> 0 bytes .../poolUnit.imageset/Contents.json | 12 -- .../poolUnit.imageset/icon-pool-unit.pdf | Bin 11106 -> 0 bytes .../Contents.json | 12 ++ .../iconLiquidStakeUnits.pdf | Bin 0 -> 12358 bytes .../Contents.json | 12 ++ .../iconPackageOwnerBadge.pdf | Bin 0 -> 7086 bytes .../AppFeature/Overlay/Sheet+Reducer.swift | 2 +- .../AppFeature/Overlay/Sheet+View.swift | 47 +++--- .../HelperViews/EmptyAssetListView.swift | 2 +- .../AccountRow/Home+AccountRow+View.swift | 2 +- .../HomeFeature/Coordinator/Home.swift | 4 +- 20 files changed, 110 insertions(+), 177 deletions(-) rename RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/{nonfungbile-tokens.imageset => nft.imageset}/Contents.json (100%) rename RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/{nonfungbile-tokens.imageset => nft.imageset}/ICON-NFTS.pdf (100%) delete mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/Icon-Market-Cap.imageset/Contents.json delete mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/Icon-Market-Cap.imageset/Icon-Market-Cap.pdf delete mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/Placeholders/nft.imageset/Contents.json delete mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/Placeholders/nft.imageset/icon-nft.pdf delete mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/Placeholders/poolUnit.imageset/Contents.json delete mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/Placeholders/poolUnit.imageset/icon-pool-unit.pdf create mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/iconLiquidStakeUnits.imageset/Contents.json create mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/iconLiquidStakeUnits.imageset/iconLiquidStakeUnits.pdf create mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/iconPackageOwnerBadge.imageset/Contents.json create mode 100644 RadixWallet/Core/Resources/Resources/Assets.xcassets/iconPackageOwnerBadge.imageset/iconPackageOwnerBadge.pdf diff --git a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift index ea9c64e498..f3e14ac5e0 100644 --- a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift +++ b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift @@ -1,48 +1,35 @@ import Foundation -// MARK: - OverlayWindowClient.InfoLink +// MARK: - OverlayWindowClient.GlossaryItem extension OverlayWindowClient { - public enum InfoLink: Equatable, Sendable { - case info(InfoItem) - case glossary(GlossaryItem) - - public enum InfoItem: String, Sendable { - case radixConnect - case linkingNewAccount - } - - public enum GlossaryItem: String, Sendable { - case radixnetwork - case radquest - case tokens - case nfts - case web3 - case accounts - case personas - case radixwallet - case dapps - case transactions - case transactionfee - case xrd - case badges - case transfers - case dex - case guarantees - case networkstaking - case validators - case radixconnector - case connectbutton - case dashboard - case bridging - } + public enum GlossaryItem: String, Sendable { + case radixnetwork + case radquest + case tokens + case nfts + case web3 + case accounts + case personas + case radixwallet + case dapps + case transactions + case transactionfee + case xrd + case badges + case transfers + case dex + case guarantees + case networkstaking + case validators + case radixconnector + case connectbutton + case dashboard + case bridging } } -extension OverlayWindowClient.InfoLink { - public enum AnchorType: String, Sendable { - case info = "infoAnchor" - case glossary = "glossaryAnchor" - } +extension OverlayWindowClient.GlossaryItem { + private static let fieldName = "glossaryAnchor" public init?(url: URL) { guard url.scheme == nil, url.host == nil, url.pathComponents.isEmpty, let query = url.query() else { @@ -50,65 +37,38 @@ extension OverlayWindowClient.InfoLink { } let parts = query.split(separator: "=") - guard parts.count == 2, let type = AnchorType(rawValue: String(parts[0])) else { return nil } - switch type { - case .info: - guard let item = InfoItem(rawValue: String(parts[1])) else { return nil } - self = .info(item) - case .glossary: - guard let item = GlossaryItem(rawValue: String(parts[1])) else { return nil } - self = .glossary(item) - } - } + guard parts.count == 2, String(parts[0]) == Self.fieldName else { return nil } - var string: String { - switch self { - case let .info(item): - item.string - case let .glossary(item): - item.string - } - } -} - -extension OverlayWindowClient.InfoLink.InfoItem { - var string: String { - switch self { - case .radixConnect: - fatalError() - case .linkingNewAccount: - fatalError() - } + guard let item = Self(rawValue: String(parts[1])) else { return nil } + self = item } -} -extension OverlayWindowClient.InfoLink.GlossaryItem { -// var image: Image { -// switch self { -// case .radixnetwork: -// case .radquest: -// case .tokens: -// case .nfts: -// case .web3: -// case .accounts: -// case .personas: -// case .radixwallet: -// case .dapps: -// case .transactions: -// case .transactionfee: -// case .xrd: -// case .badges: -// case .transfers: -// case .dex: -// case .guarantees: -// case .networkstaking: -// case .validators: -// case .radixconnector: -// case .connectbutton: -// case .dashboard: -// case .bridging: -// } -// } + // var image: Image { + // switch self { + // case .radixnetwork: + // case .radquest: + // case .tokens: + // case .nfts: + // case .web3: + // case .accounts: + // case .personas: + // case .radixwallet: + // case .dapps: + // case .transactions: + // case .transactionfee: + // case .xrd: + // case .badges: + // case .transfers: + // case .dex: + // case .guarantees: + // case .networkstaking: + // case .validators: + // case .radixconnector: + // case .connectbutton: + // case .dashboard: + // case .bridging: + // } + // } var string: String { switch self { diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index 68c2ad1874..167a2ae876 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -64,8 +64,8 @@ extension OverlayWindowClient: DependencyKey { } extension OverlayWindowClient { - public func showInfoLink(_ infoLink: InfoLink) { - scheduleSheet(.init(text: infoLink.string), .replace) + public func showInfoLink(_ item: GlossaryItem) { + scheduleSheet(.init(text: item.string), .replace) } } diff --git a/RadixWallet/Core/Resources/Generated/AssetResource.generated.swift b/RadixWallet/Core/Resources/Generated/AssetResource.generated.swift index dee29ddd95..5e768aa4db 100644 --- a/RadixWallet/Core/Resources/Generated/AssetResource.generated.swift +++ b/RadixWallet/Core/Resources/Generated/AssetResource.generated.swift @@ -32,7 +32,7 @@ public enum AssetResource { public static let chooseAccount = ImageAsset(name: "chooseAccount") public static let transfer = ImageAsset(name: "transfer") public static let fungibleTokens = ImageAsset(name: "fungible-tokens") - public static let nonfungbileTokens = ImageAsset(name: "nonfungbile-tokens") + public static let nft = ImageAsset(name: "nft") public static let poolUnits = ImageAsset(name: "pool-units") public static let stakes = ImageAsset(name: "stakes") public static let freezableByAnyone = ImageAsset(name: "freezable-by-anyone") @@ -98,12 +98,9 @@ public enum AssetResource { public static let homeAggregatedValueHidden = ImageAsset(name: "home-aggregatedValue-hidden") public static let homeAggregatedValueShown = ImageAsset(name: "home-aggregatedValue-shown") public static let homeHeaderSettings = ImageAsset(name: "home-header-settings") - public static let iconMarketCap = ImageAsset(name: "Icon-Market-Cap") public static let placeholderSecurityStructure = ImageAsset(name: "PLACEHOLDER_SecurityStructure") public static let brokenImagePlaceholder = ImageAsset(name: "broken-image-placeholder") - public static let nft = ImageAsset(name: "nft") public static let persona = ImageAsset(name: "persona") - public static let poolUnit = ImageAsset(name: "poolUnit") public static let token = ImageAsset(name: "token") public static let unknownComponent = ImageAsset(name: "unknown-component") public static let xrd = ImageAsset(name: "xrd") @@ -155,6 +152,8 @@ public enum AssetResource { public static let successCheckmark = ImageAsset(name: "success-checkmark") public static let transactionInProgress = ImageAsset(name: "transaction_in_progress") public static let folder = ImageAsset(name: "folder") + public static let iconLiquidStakeUnits = ImageAsset(name: "iconLiquidStakeUnits") + public static let iconPackageOwnerBadge = ImageAsset(name: "iconPackageOwnerBadge") public static let radixIconWhite = ImageAsset(name: "radix-icon-white") public static let securityFactors = ImageAsset(name: "security_factors") } diff --git a/RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/nonfungbile-tokens.imageset/Contents.json b/RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/nft.imageset/Contents.json similarity index 100% rename from RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/nonfungbile-tokens.imageset/Contents.json rename to RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/nft.imageset/Contents.json diff --git a/RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/nonfungbile-tokens.imageset/ICON-NFTS.pdf b/RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/nft.imageset/ICON-NFTS.pdf similarity index 100% rename from RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/nonfungbile-tokens.imageset/ICON-NFTS.pdf rename to RadixWallet/Core/Resources/Resources/Assets.xcassets/AssetsList/nft.imageset/ICON-NFTS.pdf diff --git a/RadixWallet/Core/Resources/Resources/Assets.xcassets/Icon-Market-Cap.imageset/Contents.json b/RadixWallet/Core/Resources/Resources/Assets.xcassets/Icon-Market-Cap.imageset/Contents.json deleted file mode 100644 index 60f6ef8905..0000000000 --- a/RadixWallet/Core/Resources/Resources/Assets.xcassets/Icon-Market-Cap.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "filename" : "Icon-Market-Cap.pdf", - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/RadixWallet/Core/Resources/Resources/Assets.xcassets/Icon-Market-Cap.imageset/Icon-Market-Cap.pdf b/RadixWallet/Core/Resources/Resources/Assets.xcassets/Icon-Market-Cap.imageset/Icon-Market-Cap.pdf deleted file mode 100644 index 0019d0a086a246646d6122e3c75c5576832ff9b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15093 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 diff --git a/RadixWallet/Core/Resources/Resources/Assets.xcassets/Placeholders/nft.imageset/Contents.json b/RadixWallet/Core/Resources/Resources/Assets.xcassets/Placeholders/nft.imageset/Contents.json deleted file mode 100644 index 63b75377ca..0000000000 --- a/RadixWallet/Core/Resources/Resources/Assets.xcassets/Placeholders/nft.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "filename" : "icon-nft.pdf", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/RadixWallet/Core/Resources/Resources/Assets.xcassets/Placeholders/nft.imageset/icon-nft.pdf b/RadixWallet/Core/Resources/Resources/Assets.xcassets/Placeholders/nft.imageset/icon-nft.pdf deleted file mode 100644 index 02d4f6522030fbaa7123627f199c662454e0cdb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20865 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 K&z`;h`OUw|RYY$9 literal 0 HcmV?d00001 diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift index e2e7b47970..8db97acfb4 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift @@ -4,7 +4,7 @@ public struct Sheet: FeatureReducer { public typealias State = OverlayWindowClient.Item.SheetState public enum ViewAction: Equatable, Sendable { - case infoLinkTapped(OverlayWindowClient.InfoLink) + case infoLinkTapped(OverlayWindowClient.GlossaryItem) case closeButtonTapped } diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift index ff3fc084a7..d1c2435984 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -34,7 +34,7 @@ extension Sheet { private var openURL: OpenURLAction { OpenURLAction { url in - if let infoLink = OverlayWindowClient.InfoLink(url: url) { + if let infoLink = OverlayWindowClient.GlossaryItem(url: url) { store.send(.view(.infoLinkTapped(infoLink))) return .handled } else { @@ -49,18 +49,12 @@ extension Sheet { var body: some SwiftUI.View { switch part { - case let .heading1(heading1): - Text(heading1) - .textStyle(.sheetTitle) - .foregroundColor(.app.gray1) - .multilineTextAlignment(.center) - .padding(.bottom, .large2) case let .heading2(heading2): Text(heading2) - .textStyle(.sectionHeader) + .textStyle(.sheetTitle) .foregroundColor(.app.gray1) .multilineTextAlignment(.center) - .padding(.bottom, .medium3) + .padding(.bottom, .large2) case let .heading3(heading3): Text(heading3) .textStyle(.body1Header) @@ -75,7 +69,7 @@ extension Sheet { .flushedLeft .padding(.bottom, .small3) case .divider: - Divider() + Separator() .padding(.top, .small1) .padding(.horizontal, -.small2) .padding(.bottom, .large2) @@ -87,7 +81,6 @@ extension Sheet { // MARK: - Sheet.Part extension Sheet { enum Part: Hashable { - case heading1(String) case heading2(String) case heading3(String) case text(AttributedString) @@ -96,21 +89,11 @@ extension Sheet { } extension Sheet.State { - private func heading(from row: Substring) -> Sheet.Part? { - if row.hasPrefix("# ") { - .heading1(String(row.dropFirst(2))) - } else if row.hasPrefix("## ") { - .heading2(String(row.dropFirst(3))) - } else if row.hasPrefix("### ") { - .heading3(String(row.dropFirst(4))) - } else if row.hasPrefix("---") { - .divider - } else { - nil - } + var parts: [Sheet.Part] { + Self.parse(string: text) } - var parts: [Sheet.Part] { + private static func parse(string: String) -> [Sheet.Part] { var result: [Sheet.Part] = [] var currentText = "" @@ -121,8 +104,8 @@ extension Sheet.State { } } - for row in text.split(separator: "\n", omittingEmptySubsequences: false) { - if let heading = heading(from: row) { + for row in string.split(separator: "\n", omittingEmptySubsequences: false) { + if let heading = nonTextPart(from: row) { addCurrentText() result.append(heading) } else { @@ -137,6 +120,18 @@ extension Sheet.State { return result } + + private static func nonTextPart(from row: Substring) -> Sheet.Part? { + if row.hasPrefix("## ") { + .heading2(String(row.dropFirst(3))) + } else if row.hasPrefix("### ") { + .heading3(String(row.dropFirst(4))) + } else if row.hasPrefix("---") { + .divider + } else { + nil + } + } } extension String { diff --git a/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift b/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift index 09f5571f8c..c7da6c8dba 100644 --- a/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift +++ b/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift @@ -29,7 +29,7 @@ extension EmptyAssetListView { } static var nonFungibleResources: Self { - .init(viewState: .init(imageAsset: AssetResource.nonfungbileTokens, description: L10n.AssetDetails.NFTDetails.noNfts)) + .init(viewState: .init(imageAsset: AssetResource.nft, description: L10n.AssetDetails.NFTDetails.noNfts)) } static var stakes: Self { diff --git a/RadixWallet/Features/HomeFeature/Children/AccountRow/Home+AccountRow+View.swift b/RadixWallet/Features/HomeFeature/Children/AccountRow/Home+AccountRow+View.swift index 23e96e4310..951bba3d4e 100644 --- a/RadixWallet/Features/HomeFeature/Children/AccountRow/Home+AccountRow+View.swift +++ b/RadixWallet/Features/HomeFeature/Children/AccountRow/Home+AccountRow+View.swift @@ -164,7 +164,7 @@ extension Home.AccountRow.View { } if viewStore.poolUnitsCount > 0 { - LabelledIcon(roundIcon: AssetResource.poolUnit, label: "\(viewStore.poolUnitsCount)") + LabelledIcon(roundIcon: AssetResource.poolUnits, label: "\(viewStore.poolUnitsCount)") } } } diff --git a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift index e19b97441d..923edd7f96 100644 --- a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift +++ b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift @@ -193,8 +193,8 @@ public struct Home: Sendable, FeatureReducer { return .cancel(id: CancellableId.fetchAccountPortfolios) case .createAccountButtonTapped: -// overlayWindowClient.showInfoLink(.info(.linkingNewAccount)) - overlayWindowClient.showInfoLink(.glossary(.radixnetwork)) + // FIXME: Revert + overlayWindowClient.showInfoLink(.radixnetwork) // state.destination = .createAccount( // .init(config: .init( From c865ef7a701bb1fa8d899c20b561722597333037 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Thu, 22 Aug 2024 11:59:15 +0200 Subject: [PATCH 11/40] refactoring --- .../OverlayWindowClient/InfoLink.swift | 133 ++++++++++-------- .../OverlayWindowClient+Interface.swift | 2 +- .../OverlayWindowClient+Live.swift | 2 +- .../AppFeature/Overlay/Sheet+View.swift | 9 +- 4 files changed, 84 insertions(+), 62 deletions(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift index f3e14ac5e0..a9ffb711a1 100644 --- a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift +++ b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift @@ -3,28 +3,34 @@ import Foundation // MARK: - OverlayWindowClient.GlossaryItem extension OverlayWindowClient { public enum GlossaryItem: String, Sendable { - case radixnetwork - case radquest case tokens case nfts - case web3 - case accounts + case networkstaking case personas - case radixwallet case dapps - case transactions - case transactionfee - case xrd + case guarantees case badges - case transfers + case poolunits + case gateways + case radixconnect + case transactionfee + case behaviors + case claimnfts + case liquidstakeunits + case radixnetwork + case accounts + case radixwallet + case transactions case dex - case guarantees - case networkstaking case validators case radixconnector case connectbutton + case xrd + case web3 + case transfers case dashboard case bridging + case payingaccount } } @@ -43,79 +49,88 @@ extension OverlayWindowClient.GlossaryItem { self = item } - // var image: Image { - // switch self { - // case .radixnetwork: - // case .radquest: - // case .tokens: - // case .nfts: - // case .web3: - // case .accounts: - // case .personas: - // case .radixwallet: - // case .dapps: - // case .transactions: - // case .transactionfee: - // case .xrd: - // case .badges: - // case .transfers: - // case .dex: - // case .guarantees: - // case .networkstaking: - // case .validators: - // case .radixconnector: - // case .connectbutton: - // case .dashboard: - // case .bridging: - // } - // } + var image: ImageAsset? { + switch self { + case .nfts: + AssetResource.nft + case .networkstaking: + AssetResource.stakes + case .badges: + AssetResource.iconPackageOwnerBadge + case .poolunits: + AssetResource.poolUnits + case .radixnetwork: + AssetResource.fungibleTokens + default: + nil + } + } var string: String { switch self { - case .radixnetwork: - L10n.InfoLink.Glossary.radixnetwork - case .radquest: - L10n.InfoLink.Glossary.radquest case .tokens: L10n.InfoLink.Glossary.tokens case .nfts: L10n.InfoLink.Glossary.nfts - case .web3: - L10n.InfoLink.Glossary.web3 - case .accounts: - L10n.InfoLink.Glossary.accounts + case .networkstaking: + L10n.InfoLink.Glossary.networkstaking case .personas: L10n.InfoLink.Glossary.personas - case .radixwallet: - L10n.InfoLink.Glossary.radixwallet case .dapps: L10n.InfoLink.Glossary.dapps - case .transactions: - L10n.InfoLink.Glossary.transactions - case .transactionfee: - L10n.InfoLink.Glossary.transactionfee - case .xrd: - L10n.InfoLink.Glossary.xrd + case .guarantees: + L10n.InfoLink.Glossary.guarantees case .badges: L10n.InfoLink.Glossary.badges - case .transfers: - L10n.InfoLink.Glossary.transfers + case .poolunits: +// L10n.InfoLink.Glossary.poolunits + "FIXME: String" + case .gateways: +// L10n.InfoLink.Glossary.gateways + "FIXME: String" + case .radixconnect: +// L10n.InfoLink.Glossary.radixconnect + "FIXME: String" + case .transactionfee: + L10n.InfoLink.Glossary.transactionfee + case .behaviors: +// L10n.InfoLink.Glossary.behaviors + "FIXME: String" + case .claimnfts: +// L10n.InfoLink.Glossary.claimnfts + "FIXME: String" + case .liquidstakeunits: +// L10n.InfoLink.Glossary.liquidstakeunits + "FIXME: String" + case .radixnetwork: + L10n.InfoLink.Glossary.radixnetwork + case .accounts: + L10n.InfoLink.Glossary.accounts + case .radixwallet: + L10n.InfoLink.Glossary.radixwallet + case .transactions: + L10n.InfoLink.Glossary.transactions case .dex: L10n.InfoLink.Glossary.dex - case .guarantees: - L10n.InfoLink.Glossary.guarantees - case .networkstaking: - L10n.InfoLink.Glossary.networkstaking case .validators: L10n.InfoLink.Glossary.validators case .radixconnector: L10n.InfoLink.Glossary.radixconnector case .connectbutton: L10n.InfoLink.Glossary.connectbutton + case .xrd: + L10n.InfoLink.Glossary.xrd + case .web3: + L10n.InfoLink.Glossary.web3 + case .transfers: + L10n.InfoLink.Glossary.transfers case .dashboard: L10n.InfoLink.Glossary.dashboard case .bridging: L10n.InfoLink.Glossary.bridging + case .payingaccount: +// L10n.InfoLink.Glossary.payingaccount + "FIXME: String" } } } diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift index f82a92d9b0..91cecc54a3 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift @@ -87,7 +87,7 @@ extension OverlayWindowClient { public struct SheetState: Sendable, Hashable, Identifiable { public let id = UUID() -// public let icon: Icon? + public let image: ImageAsset? public let text: String } diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index 167a2ae876..c8a405ad8e 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -65,7 +65,7 @@ extension OverlayWindowClient: DependencyKey { extension OverlayWindowClient { public func showInfoLink(_ item: GlossaryItem) { - scheduleSheet(.init(text: item.string), .replace) + scheduleSheet(.init(image: item.image, text: item.string), .replace) } } diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift index d1c2435984..6b528ab4e4 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -19,6 +19,13 @@ extension Sheet { ScrollView { VStack(spacing: .zero) { + if let image = viewStore.image { + Image(asset: image) + .resizable() + .frame(.veryLarge) + .padding(.bottom, .medium2) + } + ForEach(viewStore.parts, id: \.self) { part in PartView(part: part) } @@ -54,7 +61,7 @@ extension Sheet { .textStyle(.sheetTitle) .foregroundColor(.app.gray1) .multilineTextAlignment(.center) - .padding(.bottom, .large2) + .padding(.bottom, .large1) case let .heading3(heading3): Text(heading3) .textStyle(.body1Header) From e15b70ca45afef85685f5828efe3012bc2b520bf Mon Sep 17 00:00:00 2001 From: kugel3 Date: Thu, 22 Aug 2024 12:14:58 +0200 Subject: [PATCH 12/40] Infobutton --- RadixWallet.xcodeproj/project.pbxproj | 4 +++ .../DesignSystem/Components/InfoButton.swift | 25 +++++++++++++++++++ .../DesignSystem/Styles/InfoButtonStyle.swift | 2 +- .../HomeFeature/Coordinator/Home+View.swift | 6 +++++ .../HomeFeature/Coordinator/Home.swift | 13 ++++------ 5 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 RadixWallet/Core/DesignSystem/Components/InfoButton.swift diff --git a/RadixWallet.xcodeproj/project.pbxproj b/RadixWallet.xcodeproj/project.pbxproj index e581600088..0361f87ffa 100644 --- a/RadixWallet.xcodeproj/project.pbxproj +++ b/RadixWallet.xcodeproj/project.pbxproj @@ -1085,6 +1085,7 @@ A48C95B22C6C9A660047A056 /* InfoLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95B12C6C9A660047A056 /* InfoLink.swift */; }; A48FD15F2B55E671009295E9 /* TrackedPoolInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */; }; A48FD1612B55F8F0009295E9 /* TransactionReview+Sections.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */; }; + A4A96BB82C7743B200E19CD5 /* InfoButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4A96BB72C7743B200E19CD5 /* InfoButton.swift */; }; A4B017F72B4C099D00B42B8E /* TransactionReview+DepositSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4B017F42B4BF59000B42B8E /* TransactionReview+DepositSettingView.swift */; }; A4CFB55D2BA8CA3200778BDD /* TransactionHistory+TableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4CFB55C2BA8CA3200778BDD /* TransactionHistory+TableView.swift */; }; A4CFB55F2BAA821E00778BDD /* HScrollBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4CFB55E2BAA821E00778BDD /* HScrollBar.swift */; }; @@ -2240,6 +2241,7 @@ A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackedPoolInteraction.swift; sourceTree = ""; }; A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionReview+Sections.swift"; sourceTree = ""; }; A4A1379A2BE4630200D84B50 /* RadixWalletDebug-PreAlpha.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "RadixWalletDebug-PreAlpha.entitlements"; sourceTree = ""; }; + A4A96BB72C7743B200E19CD5 /* InfoButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoButton.swift; sourceTree = ""; }; A4B017F42B4BF59000B42B8E /* TransactionReview+DepositSettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionReview+DepositSettingView.swift"; sourceTree = ""; }; A4CFB55C2BA8CA3200778BDD /* TransactionHistory+TableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionHistory+TableView.swift"; sourceTree = ""; }; A4CFB55E2BAA821E00778BDD /* HScrollBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HScrollBar.swift; sourceTree = ""; }; @@ -5110,6 +5112,7 @@ 48CFC1082ADC10D900E77A5C /* AppTextField.swift */, 48CFC1092ADC10D900E77A5C /* CloseButton.swift */, 48CFC10A2ADC10D900E77A5C /* Card.swift */, + A4A96BB72C7743B200E19CD5 /* InfoButton.swift */, 48CFC10B2ADC10D900E77A5C /* DeveloperDisclaimerBanner.swift */, 48CFC10C2ADC10D900E77A5C /* BackButton.swift */, 48CFC10D2ADC10D900E77A5C /* RadioButton.swift */, @@ -7708,6 +7711,7 @@ 48CFC3552ADC10D900E77A5C /* ImportOlympiaLedgerAccountsAndFactorSources+View.swift in Sources */, 48CFC4E12ADC10DA00E77A5C /* StateEntityDetailsResponseFungibleVaultDetails.swift in Sources */, 48CFC5B22ADC10DA00E77A5C /* Footer.swift in Sources */, + A4A96BB82C7743B200E19CD5 /* InfoButton.swift in Sources */, 4813B0032BCA4FD60046BCAD /* Stage1MigrateToSargon+Persona.swift in Sources */, 48CFC4152ADC10DA00E77A5C /* PasteboardClient+Interface.swift in Sources */, 48CFC2902ADC10D900E77A5C /* TransactionReviewAccount.swift in Sources */, diff --git a/RadixWallet/Core/DesignSystem/Components/InfoButton.swift b/RadixWallet/Core/DesignSystem/Components/InfoButton.swift new file mode 100644 index 0000000000..f0e520eae1 --- /dev/null +++ b/RadixWallet/Core/DesignSystem/Components/InfoButton.swift @@ -0,0 +1,25 @@ +import SwiftUI + +public struct InfoButton: View { + public let item: OverlayWindowClient.GlossaryItem + public let label: String? + + public init(_ item: OverlayWindowClient.GlossaryItem, label: String? = nil) { + self.item = item + self.label = label + } + + public var body: some View { + Button(action: showInfo) { + if let label { + Text(label) + } + } + .buttonStyle(.info) + } + + private func showInfo() { + @Dependency(\.overlayWindowClient) var overlayWindowClient + overlayWindowClient.showInfoLink(item) + } +} diff --git a/RadixWallet/Core/DesignSystem/Styles/InfoButtonStyle.swift b/RadixWallet/Core/DesignSystem/Styles/InfoButtonStyle.swift index 465d51488e..f7b932ba22 100644 --- a/RadixWallet/Core/DesignSystem/Styles/InfoButtonStyle.swift +++ b/RadixWallet/Core/DesignSystem/Styles/InfoButtonStyle.swift @@ -12,7 +12,7 @@ public struct InfoButtonStyle: ButtonStyle { configuration.label .textStyle(.body1StandaloneLink) } icon: { - Image(asset: AssetResource.info) + Image(.info) } .labelStyle(.titleAndIcon) .foregroundColor(.app.blue2) diff --git a/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift b/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift index 9de909332e..7671dd9231 100644 --- a/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift +++ b/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift @@ -56,6 +56,12 @@ extension Home { } .padding(.horizontal, .medium1) + // FIXME: Revert + InfoButton(.radixnetwork) + .border(.green) + + InfoButton(.behaviors, label: "Read about behaviours") + Button(L10n.HomePage.createNewAccount) { store.send(.view(.createAccountButtonTapped)) } diff --git a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift index 923edd7f96..bd68b8769e 100644 --- a/RadixWallet/Features/HomeFeature/Coordinator/Home.swift +++ b/RadixWallet/Features/HomeFeature/Coordinator/Home.swift @@ -193,14 +193,11 @@ public struct Home: Sendable, FeatureReducer { return .cancel(id: CancellableId.fetchAccountPortfolios) case .createAccountButtonTapped: - // FIXME: Revert - overlayWindowClient.showInfoLink(.radixnetwork) - -// state.destination = .createAccount( -// .init(config: .init( -// purpose: .newAccountFromHome -// )) -// ) + state.destination = .createAccount( + .init(config: .init( + purpose: .newAccountFromHome + )) + ) return .none case .pullToRefreshStarted: From 0a792900dbfffcb611a2d2594de5f5394e78444a Mon Sep 17 00:00:00 2001 From: kugel3 Date: Thu, 22 Aug 2024 13:38:25 +0200 Subject: [PATCH 13/40] wip --- RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift b/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift index 7671dd9231..f0b9fffcc1 100644 --- a/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift +++ b/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift @@ -57,9 +57,6 @@ extension Home { .padding(.horizontal, .medium1) // FIXME: Revert - InfoButton(.radixnetwork) - .border(.green) - InfoButton(.behaviors, label: "Read about behaviours") Button(L10n.HomePage.createNewAccount) { From 614f3f567759e037cf75a8b9259221e371f92e5c Mon Sep 17 00:00:00 2001 From: kugel3 Date: Thu, 22 Aug 2024 13:51:20 +0200 Subject: [PATCH 14/40] with strings --- .../OverlayWindowClient/InfoLink.swift | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift index a9ffb711a1..cd46fcd959 100644 --- a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift +++ b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift @@ -83,25 +83,19 @@ extension OverlayWindowClient.GlossaryItem { case .badges: L10n.InfoLink.Glossary.badges case .poolunits: -// L10n.InfoLink.Glossary.poolunits - "FIXME: String" + L10n.InfoLink.Glossary.poolunits case .gateways: -// L10n.InfoLink.Glossary.gateways - "FIXME: String" + L10n.InfoLink.Glossary.gateways case .radixconnect: -// L10n.InfoLink.Glossary.radixconnect - "FIXME: String" + L10n.InfoLink.Glossary.radixconnect case .transactionfee: L10n.InfoLink.Glossary.transactionfee case .behaviors: -// L10n.InfoLink.Glossary.behaviors - "FIXME: String" + L10n.InfoLink.Glossary.behaviors case .claimnfts: -// L10n.InfoLink.Glossary.claimnfts - "FIXME: String" + L10n.InfoLink.Glossary.claimnfts case .liquidstakeunits: -// L10n.InfoLink.Glossary.liquidstakeunits - "FIXME: String" + L10n.InfoLink.Glossary.liquidstakeunits case .radixnetwork: L10n.InfoLink.Glossary.radixnetwork case .accounts: @@ -129,8 +123,7 @@ extension OverlayWindowClient.GlossaryItem { case .bridging: L10n.InfoLink.Glossary.bridging case .payingaccount: -// L10n.InfoLink.Glossary.payingaccount - "FIXME: String" + L10n.InfoLink.Glossary.payingaccount } } } From ffa1e2469a6580ade834e9e9a3a9bb1ecfd962ba Mon Sep 17 00:00:00 2001 From: kugel3 Date: Thu, 22 Aug 2024 21:50:40 +0200 Subject: [PATCH 15/40] Scroll to top --- .../AppFeature/Overlay/Sheet+View.swift | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift index 6b528ab4e4..b60638cca3 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -17,28 +17,38 @@ extension Sheet { } .padding(.horizontal, .small3) - ScrollView { - VStack(spacing: .zero) { - if let image = viewStore.image { - Image(asset: image) - .resizable() - .frame(.veryLarge) - .padding(.bottom, .medium2) + ScrollViewReader { proxy in + ScrollView { + VStack(spacing: .zero) { + if let image = viewStore.image { + Image(asset: image) + .resizable() + .frame(.veryLarge) + .padding(.bottom, .medium2) + } + + ForEach(viewStore.parts, id: \.self) { part in + PartView(part: part) + } + .environment(\.openURL, openURL) + .padding(.horizontal, .large2) } - - ForEach(viewStore.parts, id: \.self) { part in - PartView(part: part) + .padding(.top, .small2) + .id(scrollViewTopID) + } + .animation(.default, value: viewStore.text) + .onChange(of: viewStore.text) { _ in + withAnimation { + proxy.scrollTo(scrollViewTopID, anchor: .top) } - .environment(\.openURL, openURL) - .padding(.horizontal, .large2) } - .padding(.top, .small2) } - .animation(.default, value: viewStore.text) } } } + private let scrollViewTopID = "scrollViewTopID" + private var openURL: OpenURLAction { OpenURLAction { url in if let infoLink = OverlayWindowClient.GlossaryItem(url: url) { From 63504fdbf1cb934e3006a86466e22e40414ff06d Mon Sep 17 00:00:00 2001 From: kugel3 Date: Fri, 23 Aug 2024 10:32:36 +0200 Subject: [PATCH 16/40] faster fade --- RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift index b60638cca3..bef2fca764 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -36,7 +36,7 @@ extension Sheet { .padding(.top, .small2) .id(scrollViewTopID) } - .animation(.default, value: viewStore.text) + .animation(.default.speed(2), value: viewStore.text) .onChange(of: viewStore.text) { _ in withAnimation { proxy.scrollTo(scrollViewTopID, anchor: .top) From e520ae8384b5f1737a7de6806ae017b74c85c0b0 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Fri, 23 Aug 2024 14:43:09 +0200 Subject: [PATCH 17/40] transaction fee button --- .../TransactionReview+View.swift | 17 ----------------- .../TransactionReviewNetworkFee+View.swift | 6 ++---- .../TransactionReviewNetworkFee.swift | 3 --- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/RadixWallet/Features/TransactionReviewFeature/TransactionReview+View.swift b/RadixWallet/Features/TransactionReviewFeature/TransactionReview+View.swift index 9323bc827b..2c5e9c2470 100644 --- a/RadixWallet/Features/TransactionReviewFeature/TransactionReview+View.swift +++ b/RadixWallet/Features/TransactionReviewFeature/TransactionReview+View.swift @@ -688,23 +688,6 @@ struct RawTransactionView: SwiftUI.View { } } -// MARK: - TransactionReviewInfoButton -public struct TransactionReviewInfoButton: View { - private let action: () -> Void - - public init(action: @escaping () -> Void) { - self.action = action - } - - public var body: some SwiftUI.View { - Button(action: action) { - Image(asset: AssetResource.info) - .renderingMode(.template) - .foregroundColor(.app.gray3) - } - } -} - extension StrokeStyle { static let transactionReview = StrokeStyle(lineWidth: 2, dash: [5, 5]) } diff --git a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee+View.swift b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee+View.swift index 692ec8e4a8..60130448f8 100644 --- a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee+View.swift +++ b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee+View.swift @@ -25,10 +25,7 @@ extension TransactionReviewNetworkFee { .sectionHeading .textCase(.uppercase) - // FIXME: Uncomment and implement - // TransactionReviewInfoButton { - // viewStore.send(.infoTapped) - // } + InfoButton(.transactionfee) Spacer(minLength: 0) @@ -64,6 +61,7 @@ extension TransactionReviewNetworkFee { } .textStyle(.body1StandaloneLink) .foregroundColor(.app.blue2) + .padding(.top, .small2) } } .task { diff --git a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee.swift b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee.swift index 5e56c57d3b..0371c3dfca 100644 --- a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee.swift +++ b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee.swift @@ -16,7 +16,6 @@ public struct TransactionReviewNetworkFee: Sendable, FeatureReducer { public enum ViewAction: Sendable, Equatable { case task - case infoTapped case customizeTapped } @@ -51,8 +50,6 @@ public struct TransactionReviewNetworkFee: Sendable, FeatureReducer { } await send(.internal(.setTokenPrices(result))) } - case .infoTapped: - return .none case .customizeTapped: return .send(.delegate(.showCustomizeFees)) } From 6a4876646103d3aa6332f346eaff47e78c90ee2d Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 13:19:36 +0200 Subject: [PATCH 18/40] Empty asset list buttons --- .../AssetsFeature/AssetsView+View.swift | 8 ++-- .../HelperViews/EmptyAssetListView.swift | 48 +++++++++++++------ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/RadixWallet/Features/AssetsFeature/AssetsView+View.swift b/RadixWallet/Features/AssetsFeature/AssetsView+View.swift index 86262c0d37..99f0ac3998 100644 --- a/RadixWallet/Features/AssetsFeature/AssetsView+View.swift +++ b/RadixWallet/Features/AssetsFeature/AssetsView+View.swift @@ -36,7 +36,7 @@ extension AssetsView { action: \.child.fungibleTokenList ), then: { FungibleAssetList.View(store: $0) }, - else: { EmptyAssetListView.fungibleResources } + else: { EmptyAssetListView(.fungibleResources) } ) case .nonFungible: IfLetStore( @@ -45,7 +45,7 @@ extension AssetsView { action: \.child.nonFungibleTokenList ), then: { NonFungibleAssetList.View(store: $0) }, - else: { EmptyAssetListView.nonFungibleResources } + else: { EmptyAssetListView(.nonFungibleResources) } ) case .stakeUnits: IfLetStore( @@ -54,7 +54,7 @@ extension AssetsView { action: \.child.stakeUnitList ), then: { StakeUnitList.View(store: $0) }, - else: { EmptyAssetListView.stakes } + else: { EmptyAssetListView(.stakes) } ) case .poolUnits: IfLetStore( @@ -63,7 +63,7 @@ extension AssetsView { action: \.child.poolUnitsList ), then: { PoolUnitsList.View(store: $0) }, - else: { EmptyAssetListView.poolUnits } + else: { EmptyAssetListView(.poolUnits) } ) } } diff --git a/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift b/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift index c7da6c8dba..7104d1f1c9 100644 --- a/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift +++ b/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift @@ -3,19 +3,27 @@ import SwiftUI // MARK: - EmptyAssetListView struct EmptyAssetListView: View { - struct ViewState { + struct ViewState: Sendable, Equatable { let imageAsset: ImageAsset let description: String + let glossaryItem: OverlayWindowClient.GlossaryItem + let glossaryLabel: String } let viewState: ViewState + init(_ viewState: ViewState) { + self.viewState = viewState + } + var body: some View { VStack(spacing: .large2) { Image(asset: viewState.imageAsset) Text(viewState.description) .foregroundColor(.app.gray1) .textStyle(.sectionHeader) + + InfoButton(viewState.glossaryItem, label: viewState.glossaryLabel) } .padding(.top, .large2) .centered @@ -23,20 +31,32 @@ struct EmptyAssetListView: View { } } -extension EmptyAssetListView { - static var fungibleResources: Self { - .init(viewState: .init(imageAsset: AssetResource.fungibleTokens, description: L10n.AssetDetails.TokenDetails.noTokens)) - } +extension EmptyAssetListView.ViewState { + static let fungibleResources = Self( + imageAsset: AssetResource.fungibleTokens, + description: L10n.AssetDetails.TokenDetails.noTokens, + glossaryItem: .tokens, + glossaryLabel: L10n.AssetDetails.TokenDetails.whatAreTokens + ) - static var nonFungibleResources: Self { - .init(viewState: .init(imageAsset: AssetResource.nft, description: L10n.AssetDetails.NFTDetails.noNfts)) - } + static let nonFungibleResources = Self( + imageAsset: AssetResource.nft, + description: L10n.AssetDetails.NFTDetails.noNfts, + glossaryItem: .nfts, + glossaryLabel: L10n.AssetDetails.NFTDetails.whatAreNfts + ) - static var stakes: Self { - .init(viewState: .init(imageAsset: AssetResource.stakes, description: L10n.AssetDetails.StakingDetails.noStakes)) - } + static let stakes = Self( + imageAsset: AssetResource.stakes, + description: L10n.AssetDetails.StakingDetails.noStakes, + glossaryItem: .networkstaking, + glossaryLabel: L10n.AssetDetails.StakingDetails.whatIsStaking + ) - static var poolUnits: Self { - .init(viewState: .init(imageAsset: AssetResource.poolUnits, description: L10n.AssetDetails.PoolUnitDetails.noPoolUnits)) - } + static let poolUnits = Self( + imageAsset: AssetResource.poolUnits, + description: L10n.AssetDetails.PoolUnitDetails.noPoolUnits, + glossaryItem: .poolunits, + glossaryLabel: L10n.AssetDetails.PoolUnitDetails.whatArePoolUnits + ) } From 395f0e7e0992debb5997e0b83e12dc0be58c1a27 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 13:26:03 +0200 Subject: [PATCH 19/40] Personas --- .../DappsAndPersonas/Personas/Child/List/PersonaList+View.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RadixWallet/Features/DappsAndPersonas/Personas/Child/List/PersonaList+View.swift b/RadixWallet/Features/DappsAndPersonas/Personas/Child/List/PersonaList+View.swift index 2ebb646712..93cc7ed9bb 100644 --- a/RadixWallet/Features/DappsAndPersonas/Personas/Child/List/PersonaList+View.swift +++ b/RadixWallet/Features/DappsAndPersonas/Personas/Child/List/PersonaList+View.swift @@ -19,6 +19,8 @@ extension PersonaList { .textStyle(.body1Link) .foregroundColor(.app.gray2) + InfoButton(.personas, label: L10n.Personas.whatIsPersona) + PersonaListCoreView(store: store, tappable: true, showShield: true) Button(L10n.Personas.createNewPersona) { From 2ca8fb4ea28d537ef7777c2afe79a00241042e94 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 13:26:51 +0200 Subject: [PATCH 20/40] AuthorizedDapps --- .../DappsAndPersonas/AuthorizedDApps/AuthorizedDApps+View.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RadixWallet/Features/DappsAndPersonas/AuthorizedDApps/AuthorizedDApps+View.swift b/RadixWallet/Features/DappsAndPersonas/AuthorizedDApps/AuthorizedDApps+View.swift index d988b265fb..4a75776712 100644 --- a/RadixWallet/Features/DappsAndPersonas/AuthorizedDApps/AuthorizedDApps+View.swift +++ b/RadixWallet/Features/DappsAndPersonas/AuthorizedDApps/AuthorizedDApps+View.swift @@ -37,6 +37,8 @@ extension AuthorizedDappsFeature { Text(L10n.AuthorizedDapps.subtitle) .textBlock + InfoButton(.dapps, label: L10n.AuthorizedDapps.whatIsDapp) + VStack(spacing: .small1) { ForEach(viewStore.dAppsDetails) { dApp in Card { From 8058dd81b7ba8675c1fc718b7275991e5f48725c Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 13:31:55 +0200 Subject: [PATCH 21/40] in customize guarantees --- .../TransactionReviewGuarantees+View.swift | 16 +++------------- .../TransactionReviewGuarantees.swift | 14 -------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewGuarantees/TransactionReviewGuarantees+View.swift b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewGuarantees/TransactionReviewGuarantees+View.swift index e8935c502b..1eae8a31d9 100644 --- a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewGuarantees/TransactionReviewGuarantees+View.swift +++ b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewGuarantees/TransactionReviewGuarantees+View.swift @@ -31,13 +31,9 @@ extension TransactionReviewGuarantees { .multilineTextAlignment(.center) .padding(.vertical, .medium3) - // FIXME: Uncomment and implement - // Button(L10n.TransactionReview.Guarantees.howDoGuaranteesWork) { - // store.send(.view(.infoTapped)) - // } - // .buttonStyle(.info) - // .padding(.horizontal, .large2) - // .padding(.bottom, .medium1) + InfoButton(.guarantees, label: L10n.TransactionReview.Guarantees.howDoGuaranteesWork) + .padding(.horizontal, .large2) + .padding(.bottom, .medium1) Text(L10n.TransactionReview.Guarantees.subtitle) .textStyle(.body1Regular) @@ -65,12 +61,6 @@ extension TransactionReviewGuarantees { .controlState(viewStore.isValid ? .enabled : .disabled) } } - .sheet(store: store.scope(state: \.$info, action: \.child.info)) { - SlideUpPanel.View(store: $0) - .presentationDetents([.medium]) - .presentationDragIndicator(.visible) - .presentationBackground(.blur) - } .toolbar { ToolbarItem(placement: .cancellationAction) { CloseButton { diff --git a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewGuarantees/TransactionReviewGuarantees.swift b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewGuarantees/TransactionReviewGuarantees.swift index fe7f907c45..686000209e 100644 --- a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewGuarantees/TransactionReviewGuarantees.swift +++ b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewGuarantees/TransactionReviewGuarantees.swift @@ -12,16 +12,12 @@ public struct TransactionReviewGuarantees: Sendable, FeatureReducer { guarantees.allSatisfy(\.percentageStepper.isValid) } - @PresentationState - public var info: SlideUpPanel.State? - public init(guarantees: IdentifiedArrayOf) { self.guarantees = guarantees } } public enum ViewAction: Sendable, Equatable { - case infoTapped case applyTapped case closeTapped } @@ -29,7 +25,6 @@ public struct TransactionReviewGuarantees: Sendable, FeatureReducer { @CasePathable public enum ChildAction: Sendable, Equatable { case guarantee(id: TransactionReviewGuarantee.State.ID, action: TransactionReviewGuarantee.Action) - case info(PresentationAction) } public enum DelegateAction: Sendable, Equatable { @@ -43,19 +38,10 @@ public struct TransactionReviewGuarantees: Sendable, FeatureReducer { .forEach(\.guarantees, action: /Action.child .. /ChildAction.guarantee) { TransactionReviewGuarantee() } - .ifLet(\.$info, action: /Action.child .. /ChildAction.info) { - SlideUpPanel() - } } public func reduce(into state: inout State, viewAction: ViewAction) -> Effect { switch viewAction { - case .infoTapped: - // FIXME: For mainnet - // state.info = .init(title: L10n.TransactionReview.Guarantees.explanationTitle, - // explanation: L10n.TransactionReview.Guarantees.explanationText) - return .none - case .applyTapped: let guarantees = state.guarantees return .run { send in From 052ceb967081b9028b3604992160c7155c7a8c8c Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 13:59:01 +0200 Subject: [PATCH 22/40] gateways --- .../GatewaySettings+Reducer.swift | 21 -------------- .../GatewaySettings+View.swift | 28 ++++++------------- 2 files changed, 9 insertions(+), 40 deletions(-) diff --git a/RadixWallet/Features/GatewaySettingsFeature/GatewaySettings+Reducer.swift b/RadixWallet/Features/GatewaySettingsFeature/GatewaySettings+Reducer.swift index 6c8cff102a..96819e0d7d 100644 --- a/RadixWallet/Features/GatewaySettingsFeature/GatewaySettings+Reducer.swift +++ b/RadixWallet/Features/GatewaySettingsFeature/GatewaySettings+Reducer.swift @@ -24,7 +24,6 @@ public struct GatewaySettings: Sendable, FeatureReducer { public enum ViewAction: Sendable, Equatable { case task case addGatewayButtonTapped - case popoverButtonTapped } public enum InternalAction: Sendable, Equatable { @@ -44,7 +43,6 @@ public struct GatewaySettings: Sendable, FeatureReducer { public enum State: Sendable, Hashable { case addNewGateway(AddNewGateway.State) case createAccount(CreateAccountCoordinator.State) - case slideUpPanel(SlideUpPanel.State) case removeGateway(AlertState) } @@ -52,7 +50,6 @@ public struct GatewaySettings: Sendable, FeatureReducer { public enum Action: Sendable, Equatable { case addNewGateway(AddNewGateway.Action) case createAccount(CreateAccountCoordinator.Action) - case slideUpPanel(SlideUpPanel.Action) case removeGateway(RemoveGatewayAlert) public enum RemoveGatewayAlert: Sendable, Hashable { @@ -68,9 +65,6 @@ public struct GatewaySettings: Sendable, FeatureReducer { Scope(state: \.createAccount, action: \.createAccount) { CreateAccountCoordinator() } - Scope(state: \.slideUpPanel, action: \.slideUpPanel) { - SlideUpPanel() - } } } @@ -116,17 +110,6 @@ public struct GatewaySettings: Sendable, FeatureReducer { case .addGatewayButtonTapped: state.destination = .addNewGateway(AddNewGateway.State()) return .none - - case .popoverButtonTapped: -// state.destination = .slideUpPanel( -// .init( -// title: L10n.Gateways.WhatIsAGateway.title, -// explanation: L10n.Gateways.WhatIsAGateway.explanation -// ) -// ) - // FIXME: display what is a gateway once we have copy - loggerGlobal.warning("What is A gateway tutorial slide up panel skipped, since no copy.") - return .none } } @@ -236,10 +219,6 @@ public struct GatewaySettings: Sendable, FeatureReducer { await send(.internal(.switchToGatewayResult(result))) } - case .slideUpPanel(.delegate(.dismiss)): - state.destination = nil - return .none - case let .removeGateway(removeGatewayAction): switch removeGatewayAction { case let .removeButtonTapped(gatewayState): diff --git a/RadixWallet/Features/GatewaySettingsFeature/GatewaySettings+View.swift b/RadixWallet/Features/GatewaySettingsFeature/GatewaySettings+View.swift index f3493e6be0..3605dad413 100644 --- a/RadixWallet/Features/GatewaySettingsFeature/GatewaySettings+View.swift +++ b/RadixWallet/Features/GatewaySettingsFeature/GatewaySettings+View.swift @@ -25,18 +25,15 @@ extension GatewaySettings { } private func coreView() -> some SwiftUI.View { - VStack(spacing: .zero) { - VStack(alignment: .leading) { - subtitle - - // FIXME: Uncomment and implement - // Button(L10n.Gateways.whatIsAGateway) { - // store.send(.view(.popoverButtonTapped)) - // } - // .buttonStyle(.info) - // .padding(.vertical, .medium2) - } - .padding(.medium3) + VStack(alignment: .leading, spacing: .zero) { + subtitle + .padding(.top, .medium3) + .padding(.horizontal, .medium3) + .padding(.bottom, .large2) + + InfoButton(.gateways, label: L10n.Gateways.whatIsAGateway) + .padding(.horizontal, .medium3) + .padding(.bottom, .large2) GatewayList.View(store: store.gatewayList) @@ -77,7 +74,6 @@ private extension View { return removeGateway(with: destinationStore) .addNewGateway(with: destinationStore) .createAccount(with: destinationStore) - .slideUpPanel(with: destinationStore) } private func removeGateway(with destinationStore: PresentationStoreOf) -> some View { @@ -95,12 +91,6 @@ private extension View { CreateAccountCoordinator.View(store: $0) } } - - private func slideUpPanel(with destinationStore: PresentationStoreOf) -> some View { - sheet(store: destinationStore.scope(state: \.slideUpPanel, action: \.slideUpPanel)) { - SlideUpPanel.View(store: $0) - } - } } #if DEBUG From 7cb7184594973c67a9f4cafc8fc68bf3832fde2a Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 13:59:12 +0200 Subject: [PATCH 23/40] intro to personas --- .../IntroductionToPersonas+View.swift | 18 +------- .../Introduction/IntroductionToPersonas.swift | 41 ++----------------- 2 files changed, 4 insertions(+), 55 deletions(-) diff --git a/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas+View.swift b/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas+View.swift index a0556f9744..63313ff318 100644 --- a/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas+View.swift +++ b/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas+View.swift @@ -23,11 +23,7 @@ extension IntroductionToPersonas { .foregroundColor(.app.gray1) .textStyle(.sheetTitle) - // FIXME: Uncomment and implement - // Button(L10n.CreatePersona.Introduction.learnAboutPersonas) { - // viewStore.send(.showTutorial) - // } - // .buttonStyle(.info) + InfoButton(.personas, label: L10n.CreatePersona.Introduction.learnAboutPersonas) Text(L10n.CreatePersona.Introduction.subtitle1) .font(.app.body1Regular) @@ -48,23 +44,11 @@ extension IntroductionToPersonas { .buttonStyle(.primaryRectangular) } .onAppear { store.send(.view(.appeared)) } - .destinations(with: store) } } } } -@MainActor -private extension View { - func destinations(with store: StoreOf) -> some View { - let slideUpStore = store.scope(state: \.$infoPanel) { .child(.infoPanel($0)) } - return sheet( - store: slideUpStore, - content: { SlideUpPanel.View(store: $0) } - ) - } -} - // #if DEBUG // import SwiftUI import ComposableArchitecture // diff --git a/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas.swift b/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas.swift index 506fe7e3a2..133a9ae54f 100644 --- a/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas.swift +++ b/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas.swift @@ -4,22 +4,13 @@ import SwiftUI @Reducer public struct IntroductionToPersonas: Sendable, FeatureReducer { @ObservableState - public struct State: Sendable, Hashable { - @Presents - public var infoPanel: SlideUpPanel.State? - public init() {} - } + public struct State: Sendable, Hashable {} public typealias Action = FeatureAction public enum ViewAction: Sendable, Equatable { case appeared case continueButtonTapped - case showTutorial - } - - public enum ChildAction: Sendable, Equatable { - case infoPanel(PresentationAction) } public enum DelegateAction: Sendable, Equatable { @@ -28,38 +19,12 @@ public struct IntroductionToPersonas: Sendable, FeatureReducer { public init() {} - public var body: some ReducerOf { - Reduce(core) - .ifLet(\.$infoPanel, action: /Action.child .. ChildAction.infoPanel) { - SlideUpPanel() - } - } - - public func reduce(into state: inout State, childAction: ChildAction) -> Effect { - switch childAction { - case .infoPanel(.presented(.delegate(.dismiss))): - state.infoPanel = nil - return .none - default: - return .none - } - } - public func reduce(into state: inout State, viewAction: ViewAction) -> Effect { switch viewAction { case .appeared: - return .none - case .showTutorial: -// state.infoPanel = .init( -// title: "Learn about Personas", -// explanation: "Info about personas" -// ) - - // FIXME: display what is a gateway once we have copy - loggerGlobal.warning("Learn about Personas tutorial slide up panel skipped, since no copy.") - return .none + .none case .continueButtonTapped: - return .send(.delegate(.done)) + .send(.delegate(.done)) } } } From 24f1de74e33def4475967666a325159ec603385a Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 14:00:59 +0200 Subject: [PATCH 24/40] create/edit persona --- .../EditPersonaFeature/EditPersona/EditPersona+View.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RadixWallet/Features/EditPersonaFeature/EditPersona/EditPersona+View.swift b/RadixWallet/Features/EditPersonaFeature/EditPersona/EditPersona+View.swift index 806ae293be..0cd65b1333 100644 --- a/RadixWallet/Features/EditPersonaFeature/EditPersona/EditPersona+View.swift +++ b/RadixWallet/Features/EditPersonaFeature/EditPersona/EditPersona+View.swift @@ -83,6 +83,8 @@ extension EditPersona { Text(L10n.CreatePersona.Introduction.title) .foregroundColor(.app.gray1) .textStyle(.sheetTitle) + + InfoButton(.personas, label: L10n.CreatePersona.Introduction.learnAboutPersonas) } Thumbnail(.persona, url: viewStore.avatarURL, size: .veryLarge) From 9de808c39227c1cf273fe00728f2060e2834f2a5 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 14:07:22 +0200 Subject: [PATCH 25/40] Eliminate SlideUpPanel --- RadixWallet.xcodeproj/project.pbxproj | 20 +-- .../SlideUpPanel/SlideUpPanel+Reducer.swift | 34 ----- .../SlideUpPanel/SlideUpPanel+View.swift | 137 ------------------ .../FeaturePrelude/WithNavigationBar.swift | 58 ++++++++ 4 files changed, 62 insertions(+), 187 deletions(-) delete mode 100644 RadixWallet/Core/FeaturePrelude/SlideUpPanel/SlideUpPanel+Reducer.swift delete mode 100644 RadixWallet/Core/FeaturePrelude/SlideUpPanel/SlideUpPanel+View.swift create mode 100644 RadixWallet/Core/FeaturePrelude/WithNavigationBar.swift diff --git a/RadixWallet.xcodeproj/project.pbxproj b/RadixWallet.xcodeproj/project.pbxproj index 0361f87ffa..3f55a72541 100644 --- a/RadixWallet.xcodeproj/project.pbxproj +++ b/RadixWallet.xcodeproj/project.pbxproj @@ -757,8 +757,6 @@ 48CFC5E82ADC10DA00E77A5C /* FeatureReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CFC13F2ADC10D900E77A5C /* FeatureReducer.swift */; }; 48CFC5EB2ADC10DA00E77A5C /* AddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CFC1432ADC10D900E77A5C /* AddressView.swift */; }; 48CFC5EC2ADC10DA00E77A5C /* Loadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CFC1442ADC10D900E77A5C /* Loadable.swift */; }; - 48CFC5ED2ADC10DA00E77A5C /* SlideUpPanel+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CFC1462ADC10D900E77A5C /* SlideUpPanel+Reducer.swift */; }; - 48CFC5EE2ADC10DA00E77A5C /* SlideUpPanel+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CFC1472ADC10D900E77A5C /* SlideUpPanel+View.swift */; }; 48CFC5F02ADC10DA00E77A5C /* UserDefaultsClient+AccountRecovery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CFC1492ADC10D900E77A5C /* UserDefaultsClient+AccountRecovery.swift */; }; 48CFC5F22ADC10DA00E77A5C /* AssetResource.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CFC14D2ADC10D900E77A5C /* AssetResource.generated.swift */; }; 48CFC5F32ADC10DA00E77A5C /* Fonts.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CFC14E2ADC10D900E77A5C /* Fonts.generated.swift */; }; @@ -1105,6 +1103,7 @@ A4ECE2792BEEB01800468BF6 /* CloudBackupClient+Interface.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4ECE2752BEEB01800468BF6 /* CloudBackupClient+Interface.swift */; }; A4ECE27A2BEEB01800468BF6 /* CloudBackupClient+Live.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4ECE2762BEEB01800468BF6 /* CloudBackupClient+Live.swift */; }; A4ECE27B2BEEB01800468BF6 /* CloudBackupClient+Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4ECE2772BEEB01800468BF6 /* CloudBackupClient+Test.swift */; }; + A4F30C942C7CA71400F983D6 /* WithNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4F30C932C7CA71400F983D6 /* WithNavigationBar.swift */; }; E60D5E1F2C2EFAA2008BCF1F /* Sargon in Frameworks */ = {isa = PBXBuildFile; productRef = E60D5E1E2C2EFAA2008BCF1F /* Sargon */; }; E62449D52AFBA61100272C67 /* Home+AccountRow+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E62449D32AFBA61100272C67 /* Home+AccountRow+Reducer.swift */; }; E62449D62AFBA61100272C67 /* Home+AccountRow+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = E62449D42AFBA61100272C67 /* Home+AccountRow+View.swift */; }; @@ -1943,8 +1942,6 @@ 48CFC13F2ADC10D900E77A5C /* FeatureReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureReducer.swift; sourceTree = ""; }; 48CFC1432ADC10D900E77A5C /* AddressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressView.swift; sourceTree = ""; }; 48CFC1442ADC10D900E77A5C /* Loadable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Loadable.swift; sourceTree = ""; }; - 48CFC1462ADC10D900E77A5C /* SlideUpPanel+Reducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SlideUpPanel+Reducer.swift"; sourceTree = ""; }; - 48CFC1472ADC10D900E77A5C /* SlideUpPanel+View.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SlideUpPanel+View.swift"; sourceTree = ""; }; 48CFC1492ADC10D900E77A5C /* UserDefaultsClient+AccountRecovery.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserDefaultsClient+AccountRecovery.swift"; sourceTree = ""; }; 48CFC14D2ADC10D900E77A5C /* AssetResource.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetResource.generated.swift; sourceTree = ""; }; 48CFC14E2ADC10D900E77A5C /* Fonts.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fonts.generated.swift; sourceTree = ""; }; @@ -2261,6 +2258,7 @@ A4ECE2752BEEB01800468BF6 /* CloudBackupClient+Interface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CloudBackupClient+Interface.swift"; sourceTree = ""; }; A4ECE2762BEEB01800468BF6 /* CloudBackupClient+Live.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CloudBackupClient+Live.swift"; sourceTree = ""; }; A4ECE2772BEEB01800468BF6 /* CloudBackupClient+Test.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CloudBackupClient+Test.swift"; sourceTree = ""; }; + A4F30C932C7CA71400F983D6 /* WithNavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WithNavigationBar.swift; sourceTree = ""; }; E62449D32AFBA61100272C67 /* Home+AccountRow+Reducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Home+AccountRow+Reducer.swift"; sourceTree = ""; }; E62449D42AFBA61100272C67 /* Home+AccountRow+View.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Home+AccountRow+View.swift"; sourceTree = ""; }; E62BB7622AEA856300D46DAC /* ImportMnemonicTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportMnemonicTests.swift; sourceTree = ""; }; @@ -5164,6 +5162,7 @@ children = ( 5B6E11462C45834C00C20F2D /* AccountCard */, 48CFC1332ADC10D900E77A5C /* LedgerRowView.swift */, + A4F30C932C7CA71400F983D6 /* WithNavigationBar.swift */, 48CFC22C2ADC10D900E77A5C /* Radix+Dashboard.swift */, 48CFC1342ADC10D900E77A5C /* OnFirstTaskViewModifier.swift */, 48076E3F2B14F5CA004575F8 /* OnFirstAppearViewModifier.swift */, @@ -5173,7 +5172,6 @@ 48CFC13F2ADC10D900E77A5C /* FeatureReducer.swift */, 48CFC1412ADC10D900E77A5C /* AddressView */, 48CFC1442ADC10D900E77A5C /* Loadable.swift */, - 48CFC1452ADC10D900E77A5C /* SlideUpPanel */, 48CFC1492ADC10D900E77A5C /* UserDefaultsClient+AccountRecovery.swift */, A47809072BDBDB4C006B68C0 /* RadixDateFormatter.swift */, ); @@ -5205,15 +5203,6 @@ path = AddressView; sourceTree = ""; }; - 48CFC1452ADC10D900E77A5C /* SlideUpPanel */ = { - isa = PBXGroup; - children = ( - 48CFC1462ADC10D900E77A5C /* SlideUpPanel+Reducer.swift */, - 48CFC1472ADC10D900E77A5C /* SlideUpPanel+View.swift */, - ); - path = SlideUpPanel; - sourceTree = ""; - }; 48CFC14B2ADC10D900E77A5C /* Resources */ = { isa = PBXGroup; children = ( @@ -7798,7 +7787,6 @@ 48D5F3912BD8DDB9000DE964 /* DebugUserDefaultsContents+View.swift in Sources */, 48AF19CE2BB71C1600796130 /* IntoSargon+Bridge.swift in Sources */, 5B9846C02BBD5F0800E814F3 /* SensitiveInfoClient+Interface.swift in Sources */, - 48CFC5EE2ADC10DA00E77A5C /* SlideUpPanel+View.swift in Sources */, 48CFC3492ADC10D900E77A5C /* PersonaDataPermissionBox.swift in Sources */, 5BBC43A92BBAC6B0005747B1 /* AppTextEditor.swift in Sources */, A41266F12B15579E00EA38E9 /* ManualAccountRecoverySeedPhrase+View.swift in Sources */, @@ -7861,7 +7849,6 @@ 48CFC5312ADC10DA00E77A5C /* MetadataInstantValue.swift in Sources */, 48CFC5A02ADC10DA00E77A5C /* Binding+Extra.swift in Sources */, 48CFC2992ADC10D900E77A5C /* CustomizeFees.swift in Sources */, - 48CFC5ED2ADC10DA00E77A5C /* SlideUpPanel+Reducer.swift in Sources */, 48CFC68C2ADC10DB00E77A5C /* Radix+Dashboard.swift in Sources */, 48CFC2CF2ADC10D900E77A5C /* TransferAccountList+Reducer.swift in Sources */, 48CFC31F2ADC10D900E77A5C /* NameAccount+Reducer.swift in Sources */, @@ -7886,6 +7873,7 @@ A41266EF2B15578600EA38E9 /* ManualAccountRecoverySeedPhrase+Reducer.swift in Sources */, 83EE479A2AF0EE3C00155F03 /* ProgrammaticScryptoSborValueI32.swift in Sources */, 48CFC5BE2ADC10DA00E77A5C /* RoundedCornerBackground.swift in Sources */, + A4F30C942C7CA71400F983D6 /* WithNavigationBar.swift in Sources */, 48AE39DD2B0CBE3900813CF3 /* AccountRecoveryScanCoordinator+View.swift in Sources */, 48CFC2FA2ADC10D900E77A5C /* NewPersonaCompletion+View.swift in Sources */, 48CFC3702ADC10D900E77A5C /* FungibleAssetList+Reducer.swift in Sources */, diff --git a/RadixWallet/Core/FeaturePrelude/SlideUpPanel/SlideUpPanel+Reducer.swift b/RadixWallet/Core/FeaturePrelude/SlideUpPanel/SlideUpPanel+Reducer.swift deleted file mode 100644 index b67261c1c5..0000000000 --- a/RadixWallet/Core/FeaturePrelude/SlideUpPanel/SlideUpPanel+Reducer.swift +++ /dev/null @@ -1,34 +0,0 @@ - -// MARK: - SlideUpPanel -public struct SlideUpPanel: Sendable, FeatureReducer { - public struct State: Sendable, Hashable { - var title: String - var explanation: String - - public init( - title: String, - explanation: String - ) { - self.title = title - self.explanation = explanation - } - } - - public enum ViewAction: Sendable, Equatable { - case closeButtonTapped - case willDisappear - } - - public enum DelegateAction: Sendable, Equatable { - case dismiss - } - - public init() {} - - public func reduce(into state: inout State, viewAction: ViewAction) -> Effect { - switch viewAction { - case .closeButtonTapped, .willDisappear: - .send(.delegate(.dismiss)) - } - } -} diff --git a/RadixWallet/Core/FeaturePrelude/SlideUpPanel/SlideUpPanel+View.swift b/RadixWallet/Core/FeaturePrelude/SlideUpPanel/SlideUpPanel+View.swift deleted file mode 100644 index c211da5569..0000000000 --- a/RadixWallet/Core/FeaturePrelude/SlideUpPanel/SlideUpPanel+View.swift +++ /dev/null @@ -1,137 +0,0 @@ - -extension SlideUpPanel.State { - var viewState: SlideUpPanel.ViewState { - .init( - title: title, - explanation: explanation - ) - } -} - -// MARK: - WithNavigationBar -public struct WithNavigationBar: View { - private let closeAction: () -> Void - private let content: Content - - public init( - closeAction: @escaping () -> Void, - @ViewBuilder content: () -> Content - ) { - self.init( - closeAction: closeAction, - content: content() - ) - } - - init( - closeAction: @escaping () -> Void, - content: Content - ) { - self.content = content - self.closeAction = closeAction - } - - public var body: some View { - NavigationStack { - content - .presentationDragIndicator(.visible) - .toolbar { - ToolbarItem(placement: .cancellationAction) { - CloseButton(action: closeAction) - } - } - } - } -} - -extension View { - public var inNavigationView: some View { - NavigationView { - self - } - } - - @MainActor - public var inNavigationStack: some View { - NavigationStack { - self - } - } - - public func withNavigationBar( - closeAction: @escaping () -> Void - ) -> some View { - WithNavigationBar(closeAction: closeAction, content: self) - } -} - -// MARK: - SlideUpPanel.View -extension SlideUpPanel { - public struct ViewState: Equatable { - let title: String - let explanation: String - } - - @MainActor - public struct View: SwiftUI.View { - private let store: StoreOf - - public init(store: StoreOf) { - self.store = store - } - - public var body: some SwiftUI.View { - WithViewStore(store, observe: \.viewState, send: { .view($0) }) { viewStore in - VStack(spacing: .zero) { - CloseButtonBar { - viewStore.send(.closeButtonTapped) - } - - ScrollView { - VStack(spacing: .large3) { - Text(viewStore.title) - .foregroundColor(.app.gray1) - .textStyle(.sheetTitle) - - Text(viewStore.explanation) - .foregroundColor(.app.gray1) - .textStyle(.body1Regular) - .multilineTextAlignment(.leading) - - Spacer() - } - .padding(.medium3) - } - } - .presentationDetents([.medium]) - .presentationDragIndicator(.visible) - .presentationBackground(.blur) - .onWillDisappear { - viewStore.send(.willDisappear) - } - } - } - } -} - -#if DEBUG - -// MARK: - SlideUpPanel_Preview -struct SlideUpPanel_Preview: PreviewProvider { - static var previews: some View { - SlideUpPanel.View( - store: .init( - initialState: .previewValue, - reducer: SlideUpPanel.init - ) - ) - } -} - -extension SlideUpPanel.State { - public static let previewValue = Self( - title: "A title", - explanation: "Explanation text that can span across multiple lines and can probably be very long" - ) -} -#endif diff --git a/RadixWallet/Core/FeaturePrelude/WithNavigationBar.swift b/RadixWallet/Core/FeaturePrelude/WithNavigationBar.swift new file mode 100644 index 0000000000..912c61ad45 --- /dev/null +++ b/RadixWallet/Core/FeaturePrelude/WithNavigationBar.swift @@ -0,0 +1,58 @@ +import SwiftUI + +// MARK: - WithNavigationBar +public struct WithNavigationBar: View { + private let closeAction: () -> Void + private let content: Content + + public init( + closeAction: @escaping () -> Void, + @ViewBuilder content: () -> Content + ) { + self.init( + closeAction: closeAction, + content: content() + ) + } + + init( + closeAction: @escaping () -> Void, + content: Content + ) { + self.content = content + self.closeAction = closeAction + } + + public var body: some View { + NavigationStack { + content + .presentationDragIndicator(.visible) + .toolbar { + ToolbarItem(placement: .cancellationAction) { + CloseButton(action: closeAction) + } + } + } + } +} + +extension View { + public var inNavigationView: some View { + NavigationView { + self + } + } + + @MainActor + public var inNavigationStack: some View { + NavigationStack { + self + } + } + + public func withNavigationBar( + closeAction: @escaping () -> Void + ) -> some View { + WithNavigationBar(closeAction: closeAction, content: self) + } +} From d75736141162ada3081870f92b77dfe274b6b957 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 14:07:36 +0200 Subject: [PATCH 26/40] Remove debug code --- RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift b/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift index f0b9fffcc1..9de909332e 100644 --- a/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift +++ b/RadixWallet/Features/HomeFeature/Coordinator/Home+View.swift @@ -56,9 +56,6 @@ extension Home { } .padding(.horizontal, .medium1) - // FIXME: Revert - InfoButton(.behaviors, label: "Read about behaviours") - Button(L10n.HomePage.createNewAccount) { store.send(.view(.createAccountButtonTapped)) } From 669cce06caefb026383fa260191a02844251d09b Mon Sep 17 00:00:00 2001 From: kugel3 Date: Mon, 26 Aug 2024 14:51:02 +0200 Subject: [PATCH 27/40] behaviours --- .../Components/HelperViews/AssetBehaviorsView.swift | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift b/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift index 4805e6974e..60874274b6 100644 --- a/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift +++ b/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift @@ -9,9 +9,15 @@ struct AssetBehaviorsView: View { var body: some View { if !behaviors.isEmpty { Group { - Text(L10n.AssetDetails.behavior) - .textStyle(.body1Regular) - .foregroundColor(.app.gray2) + HStack(spacing: .zero) { + Text(L10n.AssetDetails.behavior) + .textStyle(.body1Regular) + .foregroundColor(.app.gray2) + + Spacer(minLength: .small2) + + InfoButton(.behaviors, label: "What are behaviors?") // FIXME: Strings + } VStack(alignment: .leading, spacing: .small1) { ForEach(filteredBehaviors, id: \.self) { behavior in From a38aa0bbd728144ab9a63b43d4d7429d084f47ec Mon Sep 17 00:00:00 2001 From: kugel3 Date: Tue, 27 Aug 2024 23:18:22 +0200 Subject: [PATCH 28/40] works --- .../OverlayWindowClient+Interface.swift | 15 +--- .../OverlayWindowClient+Live.swift | 12 +-- ...FullScreenOverlayCoordinator+Reducer.swift | 3 +- .../AppFeature/Overlay/Overlay+Reducer.swift | 10 +-- .../AppFeature/Overlay/Overlay+View.swift | 2 +- .../AppFeature/Overlay/Sheet+Reducer.swift | 75 ++++++++++++++++++- .../AppFeature/Overlay/Sheet+View.swift | 56 +++++++++++--- 7 files changed, 134 insertions(+), 39 deletions(-) diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift index 91cecc54a3..aac8b0eb7f 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift @@ -64,7 +64,7 @@ extension OverlayWindowClient { public typealias ScheduleAlert = @Sendable (Item.AlertState) async -> Item.AlertAction public typealias ScheduleAlertAndIgnoreAction = @Sendable (Item.AlertState) -> Void public typealias ScheduleHUD = @Sendable (Item.HUD) -> Void - public typealias ScheduleSheet = @Sendable (Item.SheetState, SheetBehavior) -> Void + public typealias ScheduleSheet = @Sendable (SheetOverlayCoordinator.Root.State, SheetBehavior) -> Void public typealias ScheduleFullScreen = @Sendable (FullScreenOverlayCoordinator.State) async -> FullScreenAction public typealias SendAlertAction = @Sendable (Item.AlertAction, Item.AlertState.ID) -> Void public typealias SendFullScreenAction = @Sendable (FullScreenAction, FullScreenID) -> Void @@ -85,12 +85,6 @@ extension OverlayWindowClient { case emailSupport(additionalInfo: String) } - public struct SheetState: Sendable, Hashable, Identifiable { - public let id = UUID() - public let image: ImageAsset? - public let text: String - } - public struct HUD: Sendable, Hashable, Identifiable { public let id = UUID() public let text: String @@ -127,15 +121,10 @@ extension OverlayWindowClient { } case hud(HUD) - case sheet(SheetState, SheetBehavior) case alert(AlertState) + case sheet(SheetOverlayCoordinator.Root.State, SheetBehavior) case fullScreen(FullScreenOverlayCoordinator.State) } - - public enum SheetBehavior: Sendable { - case enqueue - case replace - } } extension DependencyValues { diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index c8a405ad8e..47e6eaf3ad 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -19,11 +19,11 @@ extension OverlayWindowClient: DependencyKey { return Item.alert(.init( title: { TextState(L10n.Common.errorAlertTitle) }, actions: { - let buttons: [ButtonState] = [ - .init(role: .cancel, action: .dismissed, label: { TextState(L10n.Common.cancel) }), - .init(action: .emailSupport(additionalInfo: error.localizedDescription), label: { TextState(L10n.Error.emailSupportButtonTitle) }), - ] - return buttons + ButtonState(role: .cancel, action: .dismissed) { + TextState(L10n.Common.cancel) + } + ButtonState(action: .emailSupport(additionalInfo: error.localizedDescription)) { TextState(L10n.Error.emailSupportButtonTitle) + } }, message: { TextState(message) } )) @@ -65,7 +65,7 @@ extension OverlayWindowClient: DependencyKey { extension OverlayWindowClient { public func showInfoLink(_ item: GlossaryItem) { - scheduleSheet(.init(image: item.image, text: item.string), .replace) + scheduleSheet(.infoLink(.init(image: item.image, text: item.string)), .replace) } } diff --git a/RadixWallet/Features/AppFeature/Overlay/FullScreenOverlayCoordinator+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/FullScreenOverlayCoordinator+Reducer.swift index 8a651c4f70..b1e3b95a58 100644 --- a/RadixWallet/Features/AppFeature/Overlay/FullScreenOverlayCoordinator+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/FullScreenOverlayCoordinator+Reducer.swift @@ -1,5 +1,6 @@ import ComposableArchitecture -import SwiftUI + +// import SwiftUI public struct FullScreenOverlayCoordinator: Sendable, FeatureReducer { public struct State: Sendable, Hashable, Identifiable { diff --git a/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift index 1bf0f57047..f0edaa308c 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift @@ -26,7 +26,7 @@ struct OverlayReducer: Sendable, FeatureReducer { @CasePathable public enum State: Sendable, Hashable { case hud(HUD.State) - case sheet(Sheet.State) + case sheet(SheetOverlayCoordinator.State) case alert(OverlayWindowClient.Item.AlertState) case fullScreen(FullScreenOverlayCoordinator.State) } @@ -34,7 +34,7 @@ struct OverlayReducer: Sendable, FeatureReducer { @CasePathable public enum Action: Sendable, Equatable { case hud(HUD.Action) - case sheet(Sheet.Action) + case sheet(SheetOverlayCoordinator.Action) case alert(OverlayWindowClient.Item.AlertAction) case fullScreen(FullScreenOverlayCoordinator.Action) } @@ -44,7 +44,7 @@ struct OverlayReducer: Sendable, FeatureReducer { HUD() } Scope(state: \.sheet, action: \.sheet) { - Sheet() + SheetOverlayCoordinator() } Scope(state: \.fullScreen, action: \.fullScreen) { FullScreenOverlayCoordinator() @@ -80,7 +80,7 @@ struct OverlayReducer: Sendable, FeatureReducer { switch internalAction { case let .scheduleItem(event): if case let .sheet(sheetState, .replace) = event, case .sheet = state.destination { - state.destination = .sheet(sheetState) + state.destination = .sheet(.init(root: sheetState)) return .none } else { state.itemsQueue.append(event) @@ -161,7 +161,7 @@ struct OverlayReducer: Sendable, FeatureReducer { return .none case let .sheet(sheetState, _): - state.destination = .sheet(sheetState) + state.destination = .sheet(.init(root: sheetState)) return setIsUserInteractionEnabled(&state, isEnabled: true) case let .alert(alert): diff --git a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift index 98a09b9158..8130acff12 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift @@ -44,7 +44,7 @@ private extension View { private func sheet(with destinationStore: PresentationStoreOf) -> some View { sheet(store: destinationStore.scope(state: \.sheet, action: \.sheet)) { - Sheet.View(store: $0) + SheetOverlayCoordinator.View(store: $0) .presentationDetents([.medium]) } } diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift index 8db97acfb4..c2beac88ca 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift @@ -1,7 +1,78 @@ import Foundation -public struct Sheet: FeatureReducer { - public typealias State = OverlayWindowClient.Item.SheetState +// MARK: - SheetBehavior +public enum SheetBehavior: Sendable { + case enqueue + case replace +} + +// MARK: - SheetOverlayCoordinator +public struct SheetOverlayCoordinator: Sendable, FeatureReducer { + public struct State: Sendable, Hashable, Identifiable { + public let id: UUID = .init() + public var root: Root.State + + public init(root: Root.State) { + self.root = root + } + } + + @CasePathable + public enum ChildAction: Sendable, Equatable { + case root(Root.Action) + } + + public enum DelegateAction: Sendable, Equatable { + case infoLink(InfoLinkSheet.DelegateAction) + case dismiss + } + + public struct Root: Sendable, Hashable, Reducer { + @CasePathable + public enum State: Sendable, Hashable { + case infoLink(InfoLinkSheet.State) + } + + @CasePathable + public enum Action: Sendable, Equatable { + case infoLink(InfoLinkSheet.Action) + } + + public var body: some ReducerOf { + Scope(state: \.infoLink, action: \.infoLink) { + InfoLinkSheet() + } + } + } + + public init() {} + + public var body: some ReducerOf { + Scope(state: \.root, action: \.child.root) { + Root() + } + Reduce(core) + } + + public func reduce(into state: inout State, childAction: ChildAction) -> Effect { + switch childAction { + // Forward all delegate actions, re-wrapped + case let .root(.infoLink(.delegate(action))): + .send(.delegate(.infoLink(action))) + + default: + .none + } + } +} + +// MARK: - InfoLinkSheet +public struct InfoLinkSheet: FeatureReducer { + public struct State: Sendable, Hashable, Identifiable { + public let id = UUID() + public let image: ImageAsset? + public let text: String + } public enum ViewAction: Equatable, Sendable { case infoLinkTapped(OverlayWindowClient.GlossaryItem) diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift index bef2fca764..b7498a7012 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift @@ -1,11 +1,45 @@ -import Foundation +import ComposableArchitecture +import SwiftUI + +// MARK: - SheetOverlayCoordinator.View +extension SheetOverlayCoordinator { + @MainActor + public struct View: SwiftUI.View { + private let store: StoreOf + + public init(store: StoreOf) { + self.store = store + } + + public var body: some SwiftUI.View { + NavigationStack { + root(for: store.scope(state: \.root, action: \.child.root)) + } + } + + private func root( + for store: StoreOf + ) -> some SwiftUI.View { + SwitchStore(store) { state in + switch state { + case .infoLink: + CaseLet( + /SheetOverlayCoordinator.Root.State.infoLink, + action: SheetOverlayCoordinator.Root.Action.infoLink, + then: { InfoLinkSheet.View(store: $0) } + ) + } + } + } + } +} // MARK: - Sheet.View -extension Sheet { +extension InfoLinkSheet { public struct View: SwiftUI.View { - private let store: StoreOf + private let store: StoreOf - public init(store: StoreOf) { + public init(store: StoreOf) { self.store = store } @@ -95,8 +129,8 @@ extension Sheet { } } -// MARK: - Sheet.Part -extension Sheet { +// MARK: - InfoLinkSheet.Part +extension InfoLinkSheet { enum Part: Hashable { case heading2(String) case heading3(String) @@ -105,13 +139,13 @@ extension Sheet { } } -extension Sheet.State { - var parts: [Sheet.Part] { +extension InfoLinkSheet.State { + var parts: [InfoLinkSheet.Part] { Self.parse(string: text) } - private static func parse(string: String) -> [Sheet.Part] { - var result: [Sheet.Part] = [] + private static func parse(string: String) -> [InfoLinkSheet.Part] { + var result: [InfoLinkSheet.Part] = [] var currentText = "" func addCurrentText() { @@ -138,7 +172,7 @@ extension Sheet.State { return result } - private static func nonTextPart(from row: Substring) -> Sheet.Part? { + private static func nonTextPart(from row: Substring) -> InfoLinkSheet.Part? { if row.hasPrefix("## ") { .heading2(String(row.dropFirst(3))) } else if row.hasPrefix("### ") { From 386e29908cf3d6c959ff725963d4ad6f12dd6ae1 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Tue, 27 Aug 2024 23:28:11 +0200 Subject: [PATCH 29/40] refactor --- RadixWallet.xcodeproj/project.pbxproj | 16 ++++++++-------- .../OverlayWindowClient+Interface.swift | 5 +++++ ...ift => SheetOverlayCoordinator+Reducer.swift} | 6 ------ ....swift => SheetOverlayCoordinator+View.swift} | 0 4 files changed, 13 insertions(+), 14 deletions(-) rename RadixWallet/Features/AppFeature/Overlay/{Sheet+Reducer.swift => SheetOverlayCoordinator+Reducer.swift} (95%) rename RadixWallet/Features/AppFeature/Overlay/{Sheet+View.swift => SheetOverlayCoordinator+View.swift} (100%) diff --git a/RadixWallet.xcodeproj/project.pbxproj b/RadixWallet.xcodeproj/project.pbxproj index 3f55a72541..27c2b8b2b4 100644 --- a/RadixWallet.xcodeproj/project.pbxproj +++ b/RadixWallet.xcodeproj/project.pbxproj @@ -1078,8 +1078,8 @@ A47572052B29B4F20059A95D /* IOSSecurityClient+Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = A47572022B29B3CA0059A95D /* IOSSecurityClient+Test.swift */; }; A47572062B29B4F50059A95D /* IOSSecurityClient+Live.swift in Sources */ = {isa = PBXBuildFile; fileRef = A47572012B29B3CA0059A95D /* IOSSecurityClient+Live.swift */; }; A47809082BDBDB4C006B68C0 /* RadixDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A47809072BDBDB4C006B68C0 /* RadixDateFormatter.swift */; }; - A48C95AE2C6A97D80047A056 /* Sheet+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AD2C6A97D80047A056 /* Sheet+Reducer.swift */; }; - A48C95B02C6A98380047A056 /* Sheet+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AF2C6A98380047A056 /* Sheet+View.swift */; }; + A48C95AE2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AD2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift */; }; + A48C95B02C6A98380047A056 /* SheetOverlayCoordinator+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AF2C6A98380047A056 /* SheetOverlayCoordinator+View.swift */; }; A48C95B22C6C9A660047A056 /* InfoLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95B12C6C9A660047A056 /* InfoLink.swift */; }; A48FD15F2B55E671009295E9 /* TrackedPoolInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */; }; A48FD1612B55F8F0009295E9 /* TransactionReview+Sections.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */; }; @@ -2232,8 +2232,8 @@ A47572022B29B3CA0059A95D /* IOSSecurityClient+Test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IOSSecurityClient+Test.swift"; sourceTree = ""; }; A47572032B29B3CA0059A95D /* IOSSecurityClient+Interface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IOSSecurityClient+Interface.swift"; sourceTree = ""; }; A47809072BDBDB4C006B68C0 /* RadixDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadixDateFormatter.swift; sourceTree = ""; }; - A48C95AD2C6A97D80047A056 /* Sheet+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sheet+Reducer.swift"; sourceTree = ""; }; - A48C95AF2C6A98380047A056 /* Sheet+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sheet+View.swift"; sourceTree = ""; }; + A48C95AD2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SheetOverlayCoordinator+Reducer.swift"; sourceTree = ""; }; + A48C95AF2C6A98380047A056 /* SheetOverlayCoordinator+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SheetOverlayCoordinator+View.swift"; sourceTree = ""; }; A48C95B12C6C9A660047A056 /* InfoLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoLink.swift; sourceTree = ""; }; A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackedPoolInteraction.swift; sourceTree = ""; }; A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionReview+Sections.swift"; sourceTree = ""; }; @@ -2844,8 +2844,8 @@ 48CFBCCC2ADC10D800E77A5C /* HUD+View.swift */, E7AE2D0D2C07359500830BAA /* FullScreenOverlayCoordinator+Reducer.swift */, E7AE2D0F2C07371C00830BAA /* FullScreenOverlayCoordinator+View.swift */, - A48C95AD2C6A97D80047A056 /* Sheet+Reducer.swift */, - A48C95AF2C6A98380047A056 /* Sheet+View.swift */, + A48C95AD2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift */, + A48C95AF2C6A98380047A056 /* SheetOverlayCoordinator+View.swift */, 48CFBCCB2ADC10D800E77A5C /* Overlay+Reducer.swift */, 48CFBCCD2ADC10D800E77A5C /* Overlay+View.swift */, ); @@ -7049,7 +7049,7 @@ 48CFC2D32ADC10D900E77A5C /* AccountDetails+Reducer.swift in Sources */, 48CFC4822ADC10DA00E77A5C /* ROLAClient+Mock.swift in Sources */, 48CFC5022ADC10DA00E77A5C /* CursorLimitMixin.swift in Sources */, - A48C95AE2C6A97D80047A056 /* Sheet+Reducer.swift in Sources */, + A48C95AE2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift in Sources */, 48CFC42A2ADC10DA00E77A5C /* SafeCompare.swift in Sources */, 48CFC4512ADC10DA00E77A5C /* NetworkSwitchingClient+Test.swift in Sources */, 48CFC56D2ADC10DA00E77A5C /* TransactionReceipt.swift in Sources */, @@ -7841,7 +7841,7 @@ 83EE477A2AF0EE3C00155F03 /* ProgrammaticScryptoSborValueI8.swift in Sources */, 48CFC57B2ADC10DA00E77A5C /* PublicKeyHash.swift in Sources */, 48CFC2FC2ADC10D900E77A5C /* DefaultDepositGuarantees+Reducer.swift in Sources */, - A48C95B02C6A98380047A056 /* Sheet+View.swift in Sources */, + A48C95B02C6A98380047A056 /* SheetOverlayCoordinator+View.swift in Sources */, 48CFC2D12ADC10D900E77A5C /* Style.swift in Sources */, 48CFC48B2ADC10DA00E77A5C /* DiskPersistenceClient+Interface.swift in Sources */, 48CFC3E92ADC10D900E77A5C /* Hashing.swift in Sources */, diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift index aac8b0eb7f..95cb622d65 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift @@ -125,6 +125,11 @@ extension OverlayWindowClient { case sheet(SheetOverlayCoordinator.Root.State, SheetBehavior) case fullScreen(FullScreenOverlayCoordinator.State) } + + public enum SheetBehavior: Sendable { + case enqueue + case replace + } } extension DependencyValues { diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift similarity index 95% rename from RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift rename to RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift index c2beac88ca..15ed7e0c20 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Sheet+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift @@ -1,11 +1,5 @@ import Foundation -// MARK: - SheetBehavior -public enum SheetBehavior: Sendable { - case enqueue - case replace -} - // MARK: - SheetOverlayCoordinator public struct SheetOverlayCoordinator: Sendable, FeatureReducer { public struct State: Sendable, Hashable, Identifiable { diff --git a/RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift similarity index 100% rename from RadixWallet/Features/AppFeature/Overlay/Sheet+View.swift rename to RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift From 7574fa0523f3acc3a39d24fb57191a718a237a88 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Tue, 27 Aug 2024 23:39:42 +0200 Subject: [PATCH 30/40] Move closebutton --- .../SheetOverlayCoordinator+Reducer.swift | 26 +++------ .../SheetOverlayCoordinator+View.swift | 53 +++++++++---------- 2 files changed, 32 insertions(+), 47 deletions(-) diff --git a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift index 15ed7e0c20..8a68cbbd73 100644 --- a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift @@ -11,13 +11,16 @@ public struct SheetOverlayCoordinator: Sendable, FeatureReducer { } } + public enum ViewAction: Sendable, Equatable { + case closeButtonTapped + } + @CasePathable public enum ChildAction: Sendable, Equatable { case root(Root.Action) } public enum DelegateAction: Sendable, Equatable { - case infoLink(InfoLinkSheet.DelegateAction) case dismiss } @@ -48,14 +51,10 @@ public struct SheetOverlayCoordinator: Sendable, FeatureReducer { Reduce(core) } - public func reduce(into state: inout State, childAction: ChildAction) -> Effect { - switch childAction { - // Forward all delegate actions, re-wrapped - case let .root(.infoLink(.delegate(action))): - .send(.delegate(.infoLink(action))) - - default: - .none + public func reduce(into state: inout State, viewAction: ViewAction) -> Effect { + switch viewAction { + case .closeButtonTapped: + .send(.delegate(.dismiss)) } } } @@ -70,11 +69,6 @@ public struct InfoLinkSheet: FeatureReducer { public enum ViewAction: Equatable, Sendable { case infoLinkTapped(OverlayWindowClient.GlossaryItem) - case closeButtonTapped - } - - public enum DelegateAction: Equatable, Sendable { - case dismiss } @Dependency(\.overlayWindowClient) var overlayWindowClient @@ -84,10 +78,6 @@ public struct InfoLinkSheet: FeatureReducer { case let .infoLinkTapped(infoLink): overlayWindowClient.showInfoLink(infoLink) return .none - case .closeButtonTapped: - return .run { send in - await send(.delegate(.dismiss)) - } } } } diff --git a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift index b7498a7012..c377832ee8 100644 --- a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift @@ -12,7 +12,9 @@ extension SheetOverlayCoordinator { } public var body: some SwiftUI.View { - NavigationStack { + WithNavigationBar { + store.send(.view(.closeButtonTapped)) + } content: { root(for: store.scope(state: \.root, action: \.child.root)) } } @@ -45,36 +47,29 @@ extension InfoLinkSheet { public var body: some SwiftUI.View { WithViewStore(store, observe: { $0 }, send: { .view($0) }) { viewStore in - VStack(spacing: .zero) { - CloseButtonBar { - store.send(.view(.closeButtonTapped)) - } - .padding(.horizontal, .small3) - - ScrollViewReader { proxy in - ScrollView { - VStack(spacing: .zero) { - if let image = viewStore.image { - Image(asset: image) - .resizable() - .frame(.veryLarge) - .padding(.bottom, .medium2) - } - - ForEach(viewStore.parts, id: \.self) { part in - PartView(part: part) - } - .environment(\.openURL, openURL) - .padding(.horizontal, .large2) + ScrollViewReader { proxy in + ScrollView { + VStack(spacing: .zero) { + if let image = viewStore.image { + Image(asset: image) + .resizable() + .frame(.veryLarge) + .padding(.bottom, .medium2) } - .padding(.top, .small2) - .id(scrollViewTopID) - } - .animation(.default.speed(2), value: viewStore.text) - .onChange(of: viewStore.text) { _ in - withAnimation { - proxy.scrollTo(scrollViewTopID, anchor: .top) + + ForEach(viewStore.parts, id: \.self) { part in + PartView(part: part) } + .environment(\.openURL, openURL) + .padding(.horizontal, .large2) + } + .padding(.top, .small2) + .id(scrollViewTopID) + } + .animation(.default.speed(2), value: viewStore.text) + .onChange(of: viewStore.text) { _ in + withAnimation { + proxy.scrollTo(scrollViewTopID, anchor: .top) } } } From 6f8960a51c133f4d2c015e2025377fb35894eaec Mon Sep 17 00:00:00 2001 From: kugel3 Date: Tue, 27 Aug 2024 23:49:22 +0200 Subject: [PATCH 31/40] Move hebaviours button --- .../HelperViews/AssetBehaviorsView.swift | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift b/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift index 60874274b6..80f9679e93 100644 --- a/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift +++ b/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift @@ -9,21 +9,17 @@ struct AssetBehaviorsView: View { var body: some View { if !behaviors.isEmpty { Group { - HStack(spacing: .zero) { - Text(L10n.AssetDetails.behavior) - .textStyle(.body1Regular) - .foregroundColor(.app.gray2) - - Spacer(minLength: .small2) - - InfoButton(.behaviors, label: "What are behaviors?") // FIXME: Strings - } + Text(L10n.AssetDetails.behavior) + .textStyle(.body1Regular) + .foregroundColor(.app.gray2) VStack(alignment: .leading, spacing: .small1) { ForEach(filteredBehaviors, id: \.self) { behavior in AssetBehaviorRow(behavior: behavior, isXRD: isXRD) } } + + InfoButton(.behaviors, label: "What are behaviors?") // FIXME: Strings } .transition(.opacity.combined(with: .scale(scale: 0.8))) } From deb8461066cbb120d0aeb408a59cb93e8d66ff0f Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 28 Aug 2024 00:08:15 +0200 Subject: [PATCH 32/40] Use string --- .../Components/HelperViews/AssetBehaviorsView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift b/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift index 80f9679e93..53b0e181b9 100644 --- a/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift +++ b/RadixWallet/Features/AssetsFeature/Components/HelperViews/AssetBehaviorsView.swift @@ -19,7 +19,7 @@ struct AssetBehaviorsView: View { } } - InfoButton(.behaviors, label: "What are behaviors?") // FIXME: Strings + InfoButton(.behaviors, label: L10n.AssetDetails.Behaviors.whatAreBehaviors) } .transition(.opacity.combined(with: .scale(scale: 0.8))) } From 558c365825094c7aa7c81e12b80e8fc4449a1b97 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 28 Aug 2024 10:14:19 +0200 Subject: [PATCH 33/40] aligment --- .../TransactionReviewNetworkFee+View.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee+View.swift b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee+View.swift index 60130448f8..0145de6e86 100644 --- a/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee+View.swift +++ b/RadixWallet/Features/TransactionReviewFeature/TransactionReviewNetworkFee/TransactionReviewNetworkFee+View.swift @@ -21,11 +21,13 @@ extension TransactionReviewNetworkFee { WithViewStore(store, observe: { $0 }, send: { .view($0) }) { viewStore in VStack(alignment: .leading, spacing: .zero) { HStack(alignment: .top) { - Text(L10n.TransactionReview.NetworkFee.heading) - .sectionHeading - .textCase(.uppercase) + HStack(spacing: .small2) { + Text(L10n.TransactionReview.NetworkFee.heading) + .sectionHeading + .textCase(.uppercase) - InfoButton(.transactionfee) + InfoButton(.transactionfee) + } Spacer(minLength: 0) From d204205e20ee567805e6ce151adeb41c26a23f8e Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 28 Aug 2024 10:20:39 +0200 Subject: [PATCH 34/40] Move files --- RadixWallet.xcodeproj/project.pbxproj | 8 + .../Overlay/InfoLinkSheet+Reducer.swift | 24 +++ .../Overlay/InfoLinkSheet+View.swift | 151 ++++++++++++++++++ .../SheetOverlayCoordinator+Reducer.swift | 23 --- .../SheetOverlayCoordinator+View.swift | 150 ----------------- 5 files changed, 183 insertions(+), 173 deletions(-) create mode 100644 RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+Reducer.swift create mode 100644 RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift diff --git a/RadixWallet.xcodeproj/project.pbxproj b/RadixWallet.xcodeproj/project.pbxproj index 27c2b8b2b4..84600ca441 100644 --- a/RadixWallet.xcodeproj/project.pbxproj +++ b/RadixWallet.xcodeproj/project.pbxproj @@ -1032,6 +1032,8 @@ 83EE5EF32BE3C16F00B1531D /* StateAccountResourcePreferencesPageResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83EE5ECE2BE3C16F00B1531D /* StateAccountResourcePreferencesPageResponse.swift */; }; 83EE5EF42BE3C16F00B1531D /* TransactionAccountDepositPreValidationAuthorizedDepositorBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83EE5ECF2BE3C16F00B1531D /* TransactionAccountDepositPreValidationAuthorizedDepositorBadge.swift */; }; 83FDF7EC2AF260D600D9AA8B /* ProgrammaticScryptoSborValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FDF7EB2AF260D600D9AA8B /* ProgrammaticScryptoSborValue.swift */; }; + A40816682C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40816672C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift */; }; + A408166A2C7F14F1005E65B9 /* InfoLinkSheet+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40816692C7F14F1005E65B9 /* InfoLinkSheet+View.swift */; }; A41266EF2B15578600EA38E9 /* ManualAccountRecoverySeedPhrase+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A41266EE2B15578600EA38E9 /* ManualAccountRecoverySeedPhrase+Reducer.swift */; }; A41266F12B15579E00EA38E9 /* ManualAccountRecoverySeedPhrase+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A41266F02B15579E00EA38E9 /* ManualAccountRecoverySeedPhrase+View.swift */; }; A41266F72B160F3F00EA38E9 /* ManualAccountRecoveryCoordinator+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A41266F62B160F3F00EA38E9 /* ManualAccountRecoveryCoordinator+Reducer.swift */; }; @@ -2184,6 +2186,8 @@ 83EE5ECE2BE3C16F00B1531D /* StateAccountResourcePreferencesPageResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateAccountResourcePreferencesPageResponse.swift; sourceTree = ""; }; 83EE5ECF2BE3C16F00B1531D /* TransactionAccountDepositPreValidationAuthorizedDepositorBadge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAccountDepositPreValidationAuthorizedDepositorBadge.swift; sourceTree = ""; }; 83FDF7EB2AF260D600D9AA8B /* ProgrammaticScryptoSborValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgrammaticScryptoSborValue.swift; sourceTree = ""; }; + A40816672C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InfoLinkSheet+Reducer.swift"; sourceTree = ""; }; + A40816692C7F14F1005E65B9 /* InfoLinkSheet+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InfoLinkSheet+View.swift"; sourceTree = ""; }; A41266EE2B15578600EA38E9 /* ManualAccountRecoverySeedPhrase+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ManualAccountRecoverySeedPhrase+Reducer.swift"; sourceTree = ""; }; A41266F02B15579E00EA38E9 /* ManualAccountRecoverySeedPhrase+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ManualAccountRecoverySeedPhrase+View.swift"; sourceTree = ""; }; A41266F62B160F3F00EA38E9 /* ManualAccountRecoveryCoordinator+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ManualAccountRecoveryCoordinator+Reducer.swift"; sourceTree = ""; }; @@ -2846,6 +2850,8 @@ E7AE2D0F2C07371C00830BAA /* FullScreenOverlayCoordinator+View.swift */, A48C95AD2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift */, A48C95AF2C6A98380047A056 /* SheetOverlayCoordinator+View.swift */, + A40816672C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift */, + A40816692C7F14F1005E65B9 /* InfoLinkSheet+View.swift */, 48CFBCCB2ADC10D800E77A5C /* Overlay+Reducer.swift */, 48CFBCCD2ADC10D800E77A5C /* Overlay+View.swift */, ); @@ -6967,11 +6973,13 @@ 48CFC34E2ADC10D900E77A5C /* Login+View.swift in Sources */, 48CFC3122ADC10D900E77A5C /* AccountsToImport.swift in Sources */, E62449D62AFBA61100272C67 /* Home+AccountRow+View.swift in Sources */, + A40816682C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift in Sources */, 48CFC5FE2ADC10DA00E77A5C /* Account+PreviewValues.swift in Sources */, 48CFC5522ADC10DA00E77A5C /* StateEntityNonFungiblesPageResponse.swift in Sources */, 5BBC7DAA2C403F3400B04BD6 /* AccountCard.swift in Sources */, 48CFC5672ADC10DA00E77A5C /* AtLedgerStateMixin.swift in Sources */, A462B5B02B84078D00C26D20 /* CoreAPI_StringPlaintextMessageContent.swift in Sources */, + A408166A2C7F14F1005E65B9 /* InfoLinkSheet+View.swift in Sources */, 48CFC4172ADC10DA00E77A5C /* PasteboardClient+Live.swift in Sources */, 48CFC61D2ADC10DA00E77A5C /* P2P+RTCIncomingMessage.swift in Sources */, 48CFC3092ADC10D900E77A5C /* DisplayMnemonics.swift in Sources */, diff --git a/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+Reducer.swift new file mode 100644 index 0000000000..6bdf18ee78 --- /dev/null +++ b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+Reducer.swift @@ -0,0 +1,24 @@ +import Foundation + +// MARK: - InfoLinkSheet +public struct InfoLinkSheet: FeatureReducer { + public struct State: Sendable, Hashable, Identifiable { + public let id = UUID() + public let image: ImageAsset? + public let text: String + } + + public enum ViewAction: Equatable, Sendable { + case infoLinkTapped(OverlayWindowClient.GlossaryItem) + } + + @Dependency(\.overlayWindowClient) var overlayWindowClient + + public func reduce(into state: inout State, viewAction: ViewAction) -> Effect { + switch viewAction { + case let .infoLinkTapped(infoLink): + overlayWindowClient.showInfoLink(infoLink) + return .none + } + } +} diff --git a/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift new file mode 100644 index 0000000000..b07c5d6d04 --- /dev/null +++ b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift @@ -0,0 +1,151 @@ +import Foundation + +// MARK: - InfoLinkSheet.View +extension InfoLinkSheet { + public struct View: SwiftUI.View { + private let store: StoreOf + + public init(store: StoreOf) { + self.store = store + } + + public var body: some SwiftUI.View { + WithViewStore(store, observe: { $0 }, send: { .view($0) }) { viewStore in + ScrollViewReader { proxy in + ScrollView { + VStack(spacing: .zero) { + if let image = viewStore.image { + Image(asset: image) + .resizable() + .frame(.veryLarge) + .padding(.bottom, .medium2) + } + + ForEach(viewStore.parts, id: \.self) { part in + PartView(part: part) + } + .environment(\.openURL, openURL) + .padding(.horizontal, .large2) + } + .padding(.top, .small2) + .id(scrollViewTopID) + } + .animation(.default.speed(2), value: viewStore.text) + .onChange(of: viewStore.text) { _ in + withAnimation { + proxy.scrollTo(scrollViewTopID, anchor: .top) + } + } + } + } + } + + private let scrollViewTopID = "scrollViewTopID" + + private var openURL: OpenURLAction { + OpenURLAction { url in + if let infoLink = OverlayWindowClient.GlossaryItem(url: url) { + store.send(.view(.infoLinkTapped(infoLink))) + return .handled + } else { + return .systemAction + } + } + } + } + + struct PartView: SwiftUI.View { + let part: Part + + var body: some SwiftUI.View { + switch part { + case let .heading2(heading2): + Text(heading2) + .textStyle(.sheetTitle) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.center) + .padding(.bottom, .large1) + case let .heading3(heading3): + Text(heading3) + .textStyle(.body1Header) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.center) + .padding(.bottom, .medium3) + case let .text(text): + Text(text) + .textStyle(.body1Regular) + .foregroundColor(.app.gray1) + .multilineTextAlignment(.leading) + .flushedLeft + .padding(.bottom, .small3) + case .divider: + Separator() + .padding(.top, .small1) + .padding(.horizontal, -.small2) + .padding(.bottom, .large2) + } + } + } +} + +// MARK: - InfoLinkSheet.Part +extension InfoLinkSheet { + enum Part: Hashable { + case heading2(String) + case heading3(String) + case text(AttributedString) + case divider + } +} + +extension InfoLinkSheet.State { + var parts: [InfoLinkSheet.Part] { + Self.parse(string: text) + } + + private static func parse(string: String) -> [InfoLinkSheet.Part] { + var result: [InfoLinkSheet.Part] = [] + var currentText = "" + + func addCurrentText() { + if !currentText.isEmpty { + result.append(.text(currentText.markdownAttributed)) + currentText = "" + } + } + + for row in string.split(separator: "\n", omittingEmptySubsequences: false) { + if let heading = nonTextPart(from: row) { + addCurrentText() + result.append(heading) + } else { + if !currentText.isEmpty { + currentText.append("\n") + } + currentText.append(String(row)) + } + } + + addCurrentText() + + return result + } + + private static func nonTextPart(from row: Substring) -> InfoLinkSheet.Part? { + if row.hasPrefix("## ") { + .heading2(String(row.dropFirst(3))) + } else if row.hasPrefix("### ") { + .heading3(String(row.dropFirst(4))) + } else if row.hasPrefix("---") { + .divider + } else { + nil + } + } +} + +extension String { + var markdownAttributed: AttributedString { + (try? AttributedString(markdown: self, options: .init(interpretedSyntax: .inlineOnlyPreservingWhitespace))) ?? .init(self) + } +} diff --git a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift index 8a68cbbd73..6721a6b2cb 100644 --- a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift @@ -58,26 +58,3 @@ public struct SheetOverlayCoordinator: Sendable, FeatureReducer { } } } - -// MARK: - InfoLinkSheet -public struct InfoLinkSheet: FeatureReducer { - public struct State: Sendable, Hashable, Identifiable { - public let id = UUID() - public let image: ImageAsset? - public let text: String - } - - public enum ViewAction: Equatable, Sendable { - case infoLinkTapped(OverlayWindowClient.GlossaryItem) - } - - @Dependency(\.overlayWindowClient) var overlayWindowClient - - public func reduce(into state: inout State, viewAction: ViewAction) -> Effect { - switch viewAction { - case let .infoLinkTapped(infoLink): - overlayWindowClient.showInfoLink(infoLink) - return .none - } - } -} diff --git a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift index c377832ee8..153b475edc 100644 --- a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+View.swift @@ -35,153 +35,3 @@ extension SheetOverlayCoordinator { } } } - -// MARK: - Sheet.View -extension InfoLinkSheet { - public struct View: SwiftUI.View { - private let store: StoreOf - - public init(store: StoreOf) { - self.store = store - } - - public var body: some SwiftUI.View { - WithViewStore(store, observe: { $0 }, send: { .view($0) }) { viewStore in - ScrollViewReader { proxy in - ScrollView { - VStack(spacing: .zero) { - if let image = viewStore.image { - Image(asset: image) - .resizable() - .frame(.veryLarge) - .padding(.bottom, .medium2) - } - - ForEach(viewStore.parts, id: \.self) { part in - PartView(part: part) - } - .environment(\.openURL, openURL) - .padding(.horizontal, .large2) - } - .padding(.top, .small2) - .id(scrollViewTopID) - } - .animation(.default.speed(2), value: viewStore.text) - .onChange(of: viewStore.text) { _ in - withAnimation { - proxy.scrollTo(scrollViewTopID, anchor: .top) - } - } - } - } - } - - private let scrollViewTopID = "scrollViewTopID" - - private var openURL: OpenURLAction { - OpenURLAction { url in - if let infoLink = OverlayWindowClient.GlossaryItem(url: url) { - store.send(.view(.infoLinkTapped(infoLink))) - return .handled - } else { - return .systemAction - } - } - } - } - - struct PartView: SwiftUI.View { - let part: Part - - var body: some SwiftUI.View { - switch part { - case let .heading2(heading2): - Text(heading2) - .textStyle(.sheetTitle) - .foregroundColor(.app.gray1) - .multilineTextAlignment(.center) - .padding(.bottom, .large1) - case let .heading3(heading3): - Text(heading3) - .textStyle(.body1Header) - .foregroundColor(.app.gray1) - .multilineTextAlignment(.center) - .padding(.bottom, .medium3) - case let .text(text): - Text(text) - .textStyle(.body1Regular) - .foregroundColor(.app.gray1) - .multilineTextAlignment(.leading) - .flushedLeft - .padding(.bottom, .small3) - case .divider: - Separator() - .padding(.top, .small1) - .padding(.horizontal, -.small2) - .padding(.bottom, .large2) - } - } - } -} - -// MARK: - InfoLinkSheet.Part -extension InfoLinkSheet { - enum Part: Hashable { - case heading2(String) - case heading3(String) - case text(AttributedString) - case divider - } -} - -extension InfoLinkSheet.State { - var parts: [InfoLinkSheet.Part] { - Self.parse(string: text) - } - - private static func parse(string: String) -> [InfoLinkSheet.Part] { - var result: [InfoLinkSheet.Part] = [] - var currentText = "" - - func addCurrentText() { - if !currentText.isEmpty { - result.append(.text(currentText.markdownAttributed)) - currentText = "" - } - } - - for row in string.split(separator: "\n", omittingEmptySubsequences: false) { - if let heading = nonTextPart(from: row) { - addCurrentText() - result.append(heading) - } else { - if !currentText.isEmpty { - currentText.append("\n") - } - currentText.append(String(row)) - } - } - - addCurrentText() - - return result - } - - private static func nonTextPart(from row: Substring) -> InfoLinkSheet.Part? { - if row.hasPrefix("## ") { - .heading2(String(row.dropFirst(3))) - } else if row.hasPrefix("### ") { - .heading3(String(row.dropFirst(4))) - } else if row.hasPrefix("---") { - .divider - } else { - nil - } - } -} - -extension String { - var markdownAttributed: AttributedString { - (try? AttributedString(markdown: self, options: .init(interpretedSyntax: .inlineOnlyPreservingWhitespace))) ?? .init(self) - } -} From 8467c666be44ad27dc7ef322859c6893c3d3aa61 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 28 Aug 2024 14:00:23 +0200 Subject: [PATCH 35/40] Allow expanding --- RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift index 8130acff12..dbb0000730 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift @@ -45,7 +45,7 @@ private extension View { private func sheet(with destinationStore: PresentationStoreOf) -> some View { sheet(store: destinationStore.scope(state: \.sheet, action: \.sheet)) { SheetOverlayCoordinator.View(store: $0) - .presentationDetents([.medium]) + .presentationDetents([.medium, .large]) } } From 2d38468d975478f0df8d8af823d27cb0fc655762 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 28 Aug 2024 14:00:40 +0200 Subject: [PATCH 36/40] Show/hide title --- .../Core/DesignSystem/Measure+Position.swift | 10 ++++-- .../Overlay/InfoLinkSheet+View.swift | 32 ++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/RadixWallet/Core/DesignSystem/Measure+Position.swift b/RadixWallet/Core/DesignSystem/Measure+Position.swift index 7fb6e37581..e2c1caede4 100644 --- a/RadixWallet/Core/DesignSystem/Measure+Position.swift +++ b/RadixWallet/Core/DesignSystem/Measure+Position.swift @@ -1,11 +1,15 @@ import Foundation extension View { - public func measurePosition(_ id: AnyHashable, coordSpace: String) -> some View { + public func measurePosition(_ id: AnyHashable?, coordSpace: String) -> some View { background { - GeometryReader { proxy in + if let id { + GeometryReader { proxy in + Color.clear + .preference(key: PositionsPreferenceKey.self, value: [id: proxy.frame(in: .named(coordSpace))]) + } + } else { Color.clear - .preference(key: PositionsPreferenceKey.self, value: [id: proxy.frame(in: .named(coordSpace))]) } } } diff --git a/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift index b07c5d6d04..c1340e059d 100644 --- a/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift @@ -3,6 +3,8 @@ import Foundation // MARK: - InfoLinkSheet.View extension InfoLinkSheet { public struct View: SwiftUI.View { + @SwiftUI.State private var showTitle: Bool = false + private let store: StoreOf public init(store: StoreOf) { @@ -21,8 +23,10 @@ extension InfoLinkSheet { .padding(.bottom, .medium2) } - ForEach(viewStore.parts, id: \.self) { part in + let parts = viewStore.parts + ForEach(parts, id: \.self) { part in PartView(part: part) + .measurePosition(part == parts.first ? scrollViewTopID : nil, coordSpace: coordSpace) } .environment(\.openURL, openURL) .padding(.horizontal, .large2) @@ -30,16 +34,33 @@ extension InfoLinkSheet { .padding(.top, .small2) .id(scrollViewTopID) } + .coordinateSpace(name: coordSpace) .animation(.default.speed(2), value: viewStore.text) .onChange(of: viewStore.text) { _ in withAnimation { proxy.scrollTo(scrollViewTopID, anchor: .top) } } + .onPreferenceChange(PositionsPreferenceKey.self) { rects in + guard let offset = rects[scrollViewTopID]?.maxY else { return } + if !showTitle, offset < showTitleOffset { + showTitle = true + } else if showTitle, offset > hideTitleOffset { + showTitle = false + } + } } + .navigationBarTitleDisplayMode(.inline) + .navigationTitle(showTitle ? viewStore.title : "") } } + private let showTitleOffset: CGFloat = 40 + + private let hideTitleOffset: CGFloat = 47 + + private let coordSpace: String = "InfoLinkSheet" + private let scrollViewTopID = "scrollViewTopID" private var openURL: OpenURLAction { @@ -99,6 +120,10 @@ extension InfoLinkSheet { } extension InfoLinkSheet.State { + var title: String { + text.split(separator: "\n", omittingEmptySubsequences: false).first.flatMap(Self.title) ?? "" + } + var parts: [InfoLinkSheet.Part] { Self.parse(string: text) } @@ -131,6 +156,11 @@ extension InfoLinkSheet.State { return result } + private static func title(in row: Substring) -> String? { + guard case let .heading2(heading) = nonTextPart(from: row) else { return nil } + return heading + } + private static func nonTextPart(from row: Substring) -> InfoLinkSheet.Part? { if row.hasPrefix("## ") { .heading2(String(row.dropFirst(3))) From 4da5cb1bc20cfda0e0b7128dcbdd1788dc1aaff5 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 28 Aug 2024 14:00:48 +0200 Subject: [PATCH 37/40] Add blur --- RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift index dbb0000730..8eadab9130 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift @@ -46,6 +46,7 @@ private extension View { sheet(store: destinationStore.scope(state: \.sheet, action: \.sheet)) { SheetOverlayCoordinator.View(store: $0) .presentationDetents([.medium, .large]) + .presentationBackground(.blur) } } From 732201101d399b3e4e053f704af12be4a6167948 Mon Sep 17 00:00:00 2001 From: kugel3 Date: Wed, 28 Aug 2024 16:52:36 +0200 Subject: [PATCH 38/40] XRD icon --- RadixWallet/Clients/OverlayWindowClient/InfoLink.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift index cd46fcd959..78c699a8ce 100644 --- a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift +++ b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift @@ -61,6 +61,8 @@ extension OverlayWindowClient.GlossaryItem { AssetResource.poolUnits case .radixnetwork: AssetResource.fungibleTokens + case .xrd: + AssetResource.xrd default: nil } From 1930a0448775e584a6344ffbbf72c7964313197b Mon Sep 17 00:00:00 2001 From: Ghenadie Vasiliev-Pusca Date: Mon, 2 Sep 2024 14:31:37 +0300 Subject: [PATCH 39/40] address comments --- RadixWallet.xcodeproj/project.pbxproj | 16 +- .../OverlayWindowClient/InfoLink.swift | 131 ---------------- .../OverlayWindowClient+Interface.swift | 9 +- .../OverlayWindowClient+Live.swift | 6 +- .../DesignSystem/Components/InfoButton.swift | 6 +- ...FullScreenOverlayCoordinator+Reducer.swift | 4 - .../Overlay/InfoLinkSheet+Reducer.swift | 144 +++++++++++++++++- .../Overlay/InfoLinkSheet+View.swift | 42 ++--- .../AppFeature/Overlay/Overlay+Reducer.swift | 11 +- .../AppFeature/Overlay/Overlay+View.swift | 2 +- .../SheetOverlayCoordinator+Reducer.swift | 3 +- .../HelperViews/EmptyAssetListView.swift | 2 +- .../IntroductionToPersonas+View.swift | 24 --- .../Introduction/IntroductionToPersonas.swift | 6 - 14 files changed, 179 insertions(+), 227 deletions(-) delete mode 100644 RadixWallet/Clients/OverlayWindowClient/InfoLink.swift diff --git a/RadixWallet.xcodeproj/project.pbxproj b/RadixWallet.xcodeproj/project.pbxproj index f2331d2122..fec40c790a 100644 --- a/RadixWallet.xcodeproj/project.pbxproj +++ b/RadixWallet.xcodeproj/project.pbxproj @@ -810,8 +810,6 @@ 83EE48E02B8F68B5006CE672 /* FiatWorth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83EE48DF2B8F68B5006CE672 /* FiatWorth.swift */; }; 83EE48E22B8F69D6006CE672 /* ResourceAmount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83EE48E12B8F69D6006CE672 /* ResourceAmount.swift */; }; 83FDF7EC2AF260D600D9AA8B /* ProgrammaticScryptoSborValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FDF7EB2AF260D600D9AA8B /* ProgrammaticScryptoSborValue.swift */; }; - A40816682C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40816672C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift */; }; - A408166A2C7F14F1005E65B9 /* InfoLinkSheet+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40816692C7F14F1005E65B9 /* InfoLinkSheet+View.swift */; }; A408154C2C7E0D08005E65B9 /* CodableHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40814312C7E0D08005E65B9 /* CodableHelper.swift */; }; A408154D2C7E0D08005E65B9 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40814322C7E0D08005E65B9 /* Extensions.swift */; }; A408154E2C7E0D08005E65B9 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40814332C7E0D08005E65B9 /* Models.swift */; }; @@ -1092,6 +1090,8 @@ A40816622C7E0D08005E65B9 /* ValidatorUptimeCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40815482C7E0D08005E65B9 /* ValidatorUptimeCollection.swift */; }; A40816632C7E0D08005E65B9 /* ValidatorUptimeCollectionItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40815492C7E0D08005E65B9 /* ValidatorUptimeCollectionItem.swift */; }; A40816642C7E0D08005E65B9 /* ValidatorVaultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A408154A2C7E0D08005E65B9 /* ValidatorVaultItem.swift */; }; + A40816682C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40816672C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift */; }; + A408166A2C7F14F1005E65B9 /* InfoLinkSheet+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40816692C7F14F1005E65B9 /* InfoLinkSheet+View.swift */; }; A41266EF2B15578600EA38E9 /* ManualAccountRecoverySeedPhrase+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A41266EE2B15578600EA38E9 /* ManualAccountRecoverySeedPhrase+Reducer.swift */; }; A41266F12B15579E00EA38E9 /* ManualAccountRecoverySeedPhrase+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A41266F02B15579E00EA38E9 /* ManualAccountRecoverySeedPhrase+View.swift */; }; A41266F72B160F3F00EA38E9 /* ManualAccountRecoveryCoordinator+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A41266F62B160F3F00EA38E9 /* ManualAccountRecoveryCoordinator+Reducer.swift */; }; @@ -1129,7 +1129,6 @@ A47809082BDBDB4C006B68C0 /* RadixDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A47809072BDBDB4C006B68C0 /* RadixDateFormatter.swift */; }; A48C95AE2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AD2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift */; }; A48C95B02C6A98380047A056 /* SheetOverlayCoordinator+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95AF2C6A98380047A056 /* SheetOverlayCoordinator+View.swift */; }; - A48C95B22C6C9A660047A056 /* InfoLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48C95B12C6C9A660047A056 /* InfoLink.swift */; }; A48FD15F2B55E671009295E9 /* TrackedPoolInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */; }; A48FD1612B55F8F0009295E9 /* TransactionReview+Sections.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */; }; A4A96BB82C7743B200E19CD5 /* InfoButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4A96BB72C7743B200E19CD5 /* InfoButton.swift */; }; @@ -2011,8 +2010,6 @@ 83EE48DF2B8F68B5006CE672 /* FiatWorth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiatWorth.swift; sourceTree = ""; }; 83EE48E12B8F69D6006CE672 /* ResourceAmount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResourceAmount.swift; sourceTree = ""; }; 83FDF7EB2AF260D600D9AA8B /* ProgrammaticScryptoSborValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgrammaticScryptoSborValue.swift; sourceTree = ""; }; - A40816672C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InfoLinkSheet+Reducer.swift"; sourceTree = ""; }; - A40816692C7F14F1005E65B9 /* InfoLinkSheet+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InfoLinkSheet+View.swift"; sourceTree = ""; }; A40814312C7E0D08005E65B9 /* CodableHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodableHelper.swift; sourceTree = ""; }; A40814322C7E0D08005E65B9 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; A40814332C7E0D08005E65B9 /* Models.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Models.swift; sourceTree = ""; }; @@ -2293,6 +2290,8 @@ A40815482C7E0D08005E65B9 /* ValidatorUptimeCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidatorUptimeCollection.swift; sourceTree = ""; }; A40815492C7E0D08005E65B9 /* ValidatorUptimeCollectionItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidatorUptimeCollectionItem.swift; sourceTree = ""; }; A408154A2C7E0D08005E65B9 /* ValidatorVaultItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidatorVaultItem.swift; sourceTree = ""; }; + A40816672C7F14D4005E65B9 /* InfoLinkSheet+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InfoLinkSheet+Reducer.swift"; sourceTree = ""; }; + A40816692C7F14F1005E65B9 /* InfoLinkSheet+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InfoLinkSheet+View.swift"; sourceTree = ""; }; A41266EE2B15578600EA38E9 /* ManualAccountRecoverySeedPhrase+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ManualAccountRecoverySeedPhrase+Reducer.swift"; sourceTree = ""; }; A41266F02B15579E00EA38E9 /* ManualAccountRecoverySeedPhrase+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ManualAccountRecoverySeedPhrase+View.swift"; sourceTree = ""; }; A41266F62B160F3F00EA38E9 /* ManualAccountRecoveryCoordinator+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ManualAccountRecoveryCoordinator+Reducer.swift"; sourceTree = ""; }; @@ -2332,7 +2331,6 @@ A47809072BDBDB4C006B68C0 /* RadixDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadixDateFormatter.swift; sourceTree = ""; }; A48C95AD2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SheetOverlayCoordinator+Reducer.swift"; sourceTree = ""; }; A48C95AF2C6A98380047A056 /* SheetOverlayCoordinator+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SheetOverlayCoordinator+View.swift"; sourceTree = ""; }; - A48C95B12C6C9A660047A056 /* InfoLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoLink.swift; sourceTree = ""; }; A48FD15E2B55E671009295E9 /* TrackedPoolInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackedPoolInteraction.swift; sourceTree = ""; }; A48FD1602B55F8F0009295E9 /* TransactionReview+Sections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransactionReview+Sections.swift"; sourceTree = ""; }; A4A1379A2BE4630200D84B50 /* RadixWalletDebug-PreAlpha.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "RadixWalletDebug-PreAlpha.entitlements"; sourceTree = ""; }; @@ -4589,7 +4587,6 @@ 48CFBF8B2ADC10D900E77A5C /* OverlayWindowClient+Test.swift */, 48CFBFB22ADC10D900E77A5C /* OverlayWindowClient+Live.swift */, 48CFBF8C2ADC10D900E77A5C /* OverlayWindowClient+Interface.swift */, - A48C95B12C6C9A660047A056 /* InfoLink.swift */, ); path = OverlayWindowClient; sourceTree = ""; @@ -7218,7 +7215,6 @@ 48CFC4082ADC10DA00E77A5C /* UInt11.swift in Sources */, 48CFC2D32ADC10D900E77A5C /* AccountDetails+Reducer.swift in Sources */, 48CFC4822ADC10DA00E77A5C /* ROLAClient+Mock.swift in Sources */, - 48CFC5022ADC10DA00E77A5C /* CursorLimitMixin.swift in Sources */, A48C95AE2C6A97D80047A056 /* SheetOverlayCoordinator+Reducer.swift in Sources */, A40815C02C7E0D08005E65B9 /* NetworkConfigurationResponseWellKnownAddresses.swift in Sources */, 48CFC42A2ADC10DA00E77A5C /* SafeCompare.swift in Sources */, @@ -7723,10 +7719,6 @@ A40816412C7E0D08005E65B9 /* TransactionFungibleBalanceChanges.swift in Sources */, E65D6CEE2BC98267001D8A39 /* Stage2MigrateToSargon+AppPreferences+ViaProfile.swift in Sources */, E634CA2F2AFD25B100C43DB7 /* DebugKeychainContents+View.swift in Sources */, - 48CFC53F2ADC10DA00E77A5C /* MetadataU8Value.swift in Sources */, - A48C95B22C6C9A660047A056 /* InfoLink.swift in Sources */, - 48CFC4CC2ADC10DA00E77A5C /* Models.swift in Sources */, - 83EE5ED62BE3C16F00B1531D /* AccountDepositPreValidationResourceSpecificBehaviourItem.swift in Sources */, 48CFC3132ADC10D900E77A5C /* CompletionMigrateOlympiaAccountsToBabylon+View.swift in Sources */, A4ECE2732BEEAFFC00468BF6 /* SecurityCenterClient+Live.swift in Sources */, 48CFC36D2ADC10D900E77A5C /* FungibleAssetList+Row+Reducer.swift in Sources */, diff --git a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift b/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift deleted file mode 100644 index 78c699a8ce..0000000000 --- a/RadixWallet/Clients/OverlayWindowClient/InfoLink.swift +++ /dev/null @@ -1,131 +0,0 @@ -import Foundation - -// MARK: - OverlayWindowClient.GlossaryItem -extension OverlayWindowClient { - public enum GlossaryItem: String, Sendable { - case tokens - case nfts - case networkstaking - case personas - case dapps - case guarantees - case badges - case poolunits - case gateways - case radixconnect - case transactionfee - case behaviors - case claimnfts - case liquidstakeunits - case radixnetwork - case accounts - case radixwallet - case transactions - case dex - case validators - case radixconnector - case connectbutton - case xrd - case web3 - case transfers - case dashboard - case bridging - case payingaccount - } -} - -extension OverlayWindowClient.GlossaryItem { - private static let fieldName = "glossaryAnchor" - - public init?(url: URL) { - guard url.scheme == nil, url.host == nil, url.pathComponents.isEmpty, let query = url.query() else { - return nil - } - - let parts = query.split(separator: "=") - guard parts.count == 2, String(parts[0]) == Self.fieldName else { return nil } - - guard let item = Self(rawValue: String(parts[1])) else { return nil } - self = item - } - - var image: ImageAsset? { - switch self { - case .nfts: - AssetResource.nft - case .networkstaking: - AssetResource.stakes - case .badges: - AssetResource.iconPackageOwnerBadge - case .poolunits: - AssetResource.poolUnits - case .radixnetwork: - AssetResource.fungibleTokens - case .xrd: - AssetResource.xrd - default: - nil - } - } - - var string: String { - switch self { - case .tokens: - L10n.InfoLink.Glossary.tokens - case .nfts: - L10n.InfoLink.Glossary.nfts - case .networkstaking: - L10n.InfoLink.Glossary.networkstaking - case .personas: - L10n.InfoLink.Glossary.personas - case .dapps: - L10n.InfoLink.Glossary.dapps - case .guarantees: - L10n.InfoLink.Glossary.guarantees - case .badges: - L10n.InfoLink.Glossary.badges - case .poolunits: - L10n.InfoLink.Glossary.poolunits - case .gateways: - L10n.InfoLink.Glossary.gateways - case .radixconnect: - L10n.InfoLink.Glossary.radixconnect - case .transactionfee: - L10n.InfoLink.Glossary.transactionfee - case .behaviors: - L10n.InfoLink.Glossary.behaviors - case .claimnfts: - L10n.InfoLink.Glossary.claimnfts - case .liquidstakeunits: - L10n.InfoLink.Glossary.liquidstakeunits - case .radixnetwork: - L10n.InfoLink.Glossary.radixnetwork - case .accounts: - L10n.InfoLink.Glossary.accounts - case .radixwallet: - L10n.InfoLink.Glossary.radixwallet - case .transactions: - L10n.InfoLink.Glossary.transactions - case .dex: - L10n.InfoLink.Glossary.dex - case .validators: - L10n.InfoLink.Glossary.validators - case .radixconnector: - L10n.InfoLink.Glossary.radixconnector - case .connectbutton: - L10n.InfoLink.Glossary.connectbutton - case .xrd: - L10n.InfoLink.Glossary.xrd - case .web3: - L10n.InfoLink.Glossary.web3 - case .transfers: - L10n.InfoLink.Glossary.transfers - case .dashboard: - L10n.InfoLink.Glossary.dashboard - case .bridging: - L10n.InfoLink.Glossary.bridging - case .payingaccount: - L10n.InfoLink.Glossary.payingaccount - } - } -} diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift index 95cb622d65..4504f35edf 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Interface.swift @@ -64,7 +64,7 @@ extension OverlayWindowClient { public typealias ScheduleAlert = @Sendable (Item.AlertState) async -> Item.AlertAction public typealias ScheduleAlertAndIgnoreAction = @Sendable (Item.AlertState) -> Void public typealias ScheduleHUD = @Sendable (Item.HUD) -> Void - public typealias ScheduleSheet = @Sendable (SheetOverlayCoordinator.Root.State, SheetBehavior) -> Void + public typealias ScheduleSheet = @Sendable (SheetOverlayCoordinator.Root.State) -> Void public typealias ScheduleFullScreen = @Sendable (FullScreenOverlayCoordinator.State) async -> FullScreenAction public typealias SendAlertAction = @Sendable (Item.AlertAction, Item.AlertState.ID) -> Void public typealias SendFullScreenAction = @Sendable (FullScreenAction, FullScreenID) -> Void @@ -122,14 +122,9 @@ extension OverlayWindowClient { case hud(HUD) case alert(AlertState) - case sheet(SheetOverlayCoordinator.Root.State, SheetBehavior) + case sheet(SheetOverlayCoordinator.Root.State) case fullScreen(FullScreenOverlayCoordinator.State) } - - public enum SheetBehavior: Sendable { - case enqueue - case replace - } } extension DependencyValues { diff --git a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift index 47e6eaf3ad..ebd0e9cd7a 100644 --- a/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift +++ b/RadixWallet/Clients/OverlayWindowClient/OverlayWindowClient+Live.swift @@ -50,7 +50,7 @@ extension OverlayWindowClient: DependencyKey { }, scheduleAlertAndIgnoreAction: scheduleAlertAndIgnoreAction, scheduleHUD: { items.send(.hud($0)) }, - scheduleSheet: { items.send(.sheet($0, $1)) }, + scheduleSheet: { items.send(.sheet($0)) }, scheduleFullScreen: { fullScreen in items.send(.fullScreen(fullScreen)) return await fullScreenActions.first { $0.id == fullScreen.id }?.action ?? .dismiss @@ -64,8 +64,8 @@ extension OverlayWindowClient: DependencyKey { } extension OverlayWindowClient { - public func showInfoLink(_ item: GlossaryItem) { - scheduleSheet(.infoLink(.init(image: item.image, text: item.string)), .replace) + public func showInfoLink(_ state: InfoLinkSheet.State) { + scheduleSheet(.infoLink(state)) } } diff --git a/RadixWallet/Core/DesignSystem/Components/InfoButton.swift b/RadixWallet/Core/DesignSystem/Components/InfoButton.swift index f0e520eae1..5c187ffeea 100644 --- a/RadixWallet/Core/DesignSystem/Components/InfoButton.swift +++ b/RadixWallet/Core/DesignSystem/Components/InfoButton.swift @@ -1,10 +1,10 @@ import SwiftUI public struct InfoButton: View { - public let item: OverlayWindowClient.GlossaryItem + public let item: InfoLinkSheet.GlossaryItem public let label: String? - public init(_ item: OverlayWindowClient.GlossaryItem, label: String? = nil) { + public init(_ item: InfoLinkSheet.GlossaryItem, label: String? = nil) { self.item = item self.label = label } @@ -20,6 +20,6 @@ public struct InfoButton: View { private func showInfo() { @Dependency(\.overlayWindowClient) var overlayWindowClient - overlayWindowClient.showInfoLink(item) + overlayWindowClient.showInfoLink(.init(glossaryItem: item)) } } diff --git a/RadixWallet/Features/AppFeature/Overlay/FullScreenOverlayCoordinator+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/FullScreenOverlayCoordinator+Reducer.swift index b1e3b95a58..f7df80ac41 100644 --- a/RadixWallet/Features/AppFeature/Overlay/FullScreenOverlayCoordinator+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/FullScreenOverlayCoordinator+Reducer.swift @@ -1,7 +1,3 @@ -import ComposableArchitecture - -// import SwiftUI - public struct FullScreenOverlayCoordinator: Sendable, FeatureReducer { public struct State: Sendable, Hashable, Identifiable { public let id: UUID = .init() diff --git a/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+Reducer.swift index 6bdf18ee78..39bacbf50e 100644 --- a/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+Reducer.swift @@ -2,23 +2,157 @@ import Foundation // MARK: - InfoLinkSheet public struct InfoLinkSheet: FeatureReducer { - public struct State: Sendable, Hashable, Identifiable { - public let id = UUID() + public struct State: Sendable, Hashable { public let image: ImageAsset? public let text: String + + init(glossaryItem: InfoLinkSheet.GlossaryItem) { + self.image = glossaryItem.image + self.text = glossaryItem.string + } } public enum ViewAction: Equatable, Sendable { - case infoLinkTapped(OverlayWindowClient.GlossaryItem) + case infoLinkTapped(InfoLinkSheet.GlossaryItem) } @Dependency(\.overlayWindowClient) var overlayWindowClient public func reduce(into state: inout State, viewAction: ViewAction) -> Effect { switch viewAction { - case let .infoLinkTapped(infoLink): - overlayWindowClient.showInfoLink(infoLink) + case let .infoLinkTapped(item): + state = .init(glossaryItem: item) return .none } } } + +// MARK: InfoLinkSheet.GlossaryItem +extension InfoLinkSheet { + public enum GlossaryItem: String, Sendable { + case tokens + case nfts + case networkstaking + case personas + case dapps + case guarantees + case badges + case poolunits + case gateways + case radixconnect + case transactionfee + case behaviors + case claimnfts + case liquidstakeunits + case radixnetwork + case accounts + case radixwallet + case transactions + case dex + case validators + case radixconnector + case connectbutton + case xrd + case web3 + case transfers + case dashboard + case bridging + case payingaccount + } +} + +extension InfoLinkSheet.GlossaryItem { + private static let fieldName = "glossaryAnchor" + + public init?(url: URL) { + guard url.scheme == nil, url.host == nil, url.pathComponents.isEmpty, let query = url.query() else { + return nil + } + + let parts = query.split(separator: "=") + guard parts.count == 2, String(parts[0]) == Self.fieldName else { return nil } + + guard let item = Self(rawValue: String(parts[1])) else { return nil } + self = item + } + + var image: ImageAsset? { + switch self { + case .nfts: + AssetResource.nft + case .networkstaking: + AssetResource.stakes + case .badges: + AssetResource.iconPackageOwnerBadge + case .poolunits: + AssetResource.poolUnits + case .radixnetwork: + AssetResource.fungibleTokens + case .xrd: + AssetResource.xrd + default: + nil + } + } + + var string: String { + switch self { + case .tokens: + L10n.InfoLink.Glossary.tokens + case .nfts: + L10n.InfoLink.Glossary.nfts + case .networkstaking: + L10n.InfoLink.Glossary.networkstaking + case .personas: + L10n.InfoLink.Glossary.personas + case .dapps: + L10n.InfoLink.Glossary.dapps + case .guarantees: + L10n.InfoLink.Glossary.guarantees + case .badges: + L10n.InfoLink.Glossary.badges + case .poolunits: + L10n.InfoLink.Glossary.poolunits + case .gateways: + L10n.InfoLink.Glossary.gateways + case .radixconnect: + L10n.InfoLink.Glossary.radixconnect + case .transactionfee: + L10n.InfoLink.Glossary.transactionfee + case .behaviors: + L10n.InfoLink.Glossary.behaviors + case .claimnfts: + L10n.InfoLink.Glossary.claimnfts + case .liquidstakeunits: + L10n.InfoLink.Glossary.liquidstakeunits + case .radixnetwork: + L10n.InfoLink.Glossary.radixnetwork + case .accounts: + L10n.InfoLink.Glossary.accounts + case .radixwallet: + L10n.InfoLink.Glossary.radixwallet + case .transactions: + L10n.InfoLink.Glossary.transactions + case .dex: + L10n.InfoLink.Glossary.dex + case .validators: + L10n.InfoLink.Glossary.validators + case .radixconnector: + L10n.InfoLink.Glossary.radixconnector + case .connectbutton: + L10n.InfoLink.Glossary.connectbutton + case .xrd: + L10n.InfoLink.Glossary.xrd + case .web3: + L10n.InfoLink.Glossary.web3 + case .transfers: + L10n.InfoLink.Glossary.transfers + case .dashboard: + L10n.InfoLink.Glossary.dashboard + case .bridging: + L10n.InfoLink.Glossary.bridging + case .payingaccount: + L10n.InfoLink.Glossary.payingaccount + } + } +} diff --git a/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift index c1340e059d..d7b3e99e35 100644 --- a/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/InfoLinkSheet+View.swift @@ -4,9 +4,27 @@ import Foundation extension InfoLinkSheet { public struct View: SwiftUI.View { @SwiftUI.State private var showTitle: Bool = false - private let store: StoreOf + private let showTitleOffset: CGFloat = 40 + + private let hideTitleOffset: CGFloat = 47 + + private let coordSpace: String = "InfoLinkSheet" + + private let scrollViewTopID = "scrollViewTopID" + + private var openURL: OpenURLAction { + OpenURLAction { url in + if let infoLink = InfoLinkSheet.GlossaryItem(url: url) { + store.send(.view(.infoLinkTapped(infoLink))) + return .handled + } else { + return .systemAction + } + } + } + public init(store: StoreOf) { self.store = store } @@ -54,27 +72,11 @@ extension InfoLinkSheet { .navigationTitle(showTitle ? viewStore.title : "") } } - - private let showTitleOffset: CGFloat = 40 - - private let hideTitleOffset: CGFloat = 47 - - private let coordSpace: String = "InfoLinkSheet" - - private let scrollViewTopID = "scrollViewTopID" - - private var openURL: OpenURLAction { - OpenURLAction { url in - if let infoLink = OverlayWindowClient.GlossaryItem(url: url) { - store.send(.view(.infoLinkTapped(infoLink))) - return .handled - } else { - return .systemAction - } - } - } } +} +// MARK: - InfoLinkSheet.PartView +extension InfoLinkSheet { struct PartView: SwiftUI.View { let part: Part diff --git a/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift index f0edaa308c..8fde8913a2 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Overlay+Reducer.swift @@ -79,13 +79,8 @@ struct OverlayReducer: Sendable, FeatureReducer { func reduce(into state: inout State, internalAction: InternalAction) -> Effect { switch internalAction { case let .scheduleItem(event): - if case let .sheet(sheetState, .replace) = event, case .sheet = state.destination { - state.destination = .sheet(.init(root: sheetState)) - return .none - } else { - state.itemsQueue.append(event) - return showItemIfPossible(state: &state) - } + state.itemsQueue.append(event) + return showItemIfPossible(state: &state) case .showNextItemIfPossible: return showItemIfPossible(state: &state) } @@ -160,7 +155,7 @@ struct OverlayReducer: Sendable, FeatureReducer { state.destination = .hud(.init(content: hud)) return .none - case let .sheet(sheetState, _): + case let .sheet(sheetState): state.destination = .sheet(.init(root: sheetState)) return setIsUserInteractionEnabled(&state, isEnabled: true) diff --git a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift index 8eadab9130..934571948a 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift @@ -45,7 +45,7 @@ private extension View { private func sheet(with destinationStore: PresentationStoreOf) -> some View { sheet(store: destinationStore.scope(state: \.sheet, action: \.sheet)) { SheetOverlayCoordinator.View(store: $0) - .presentationDetents([.medium, .large]) + .presentationDetents([.fraction(0.75)]) .presentationBackground(.blur) } } diff --git a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift index 6721a6b2cb..4245a02c90 100644 --- a/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift +++ b/RadixWallet/Features/AppFeature/Overlay/SheetOverlayCoordinator+Reducer.swift @@ -2,8 +2,7 @@ import Foundation // MARK: - SheetOverlayCoordinator public struct SheetOverlayCoordinator: Sendable, FeatureReducer { - public struct State: Sendable, Hashable, Identifiable { - public let id: UUID = .init() + public struct State: Sendable, Hashable { public var root: Root.State public init(root: Root.State) { diff --git a/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift b/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift index 7104d1f1c9..f93bbf83e9 100644 --- a/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift +++ b/RadixWallet/Features/AssetsFeature/Components/HelperViews/EmptyAssetListView.swift @@ -6,7 +6,7 @@ struct EmptyAssetListView: View { struct ViewState: Sendable, Equatable { let imageAsset: ImageAsset let description: String - let glossaryItem: OverlayWindowClient.GlossaryItem + let glossaryItem: InfoLinkSheet.GlossaryItem let glossaryLabel: String } diff --git a/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas+View.swift b/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas+View.swift index 63313ff318..5f467d7b9a 100644 --- a/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas+View.swift +++ b/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas+View.swift @@ -1,4 +1,3 @@ -import ComposableArchitecture import SwiftUI // MARK: - IntroductionToPersonas.View @@ -43,30 +42,7 @@ extension IntroductionToPersonas { } .buttonStyle(.primaryRectangular) } - .onAppear { store.send(.view(.appeared)) } } } } } - -// #if DEBUG -// import SwiftUI -import ComposableArchitecture // - -//// MARK: - IntroductionToEntity_Preview -// struct IntroductionToEntity_Preview: PreviewProvider { -// static var previews: some View { -// NavigationStack { -// IntroductionToEntity.View( -// store: .init( -// initialState: .init(), -// reducer: IntroductionToEntity.init -// ) -// ) -// #if os(iOS) -// .toolbar(.visible, for: .navigationBar) -// #endif -// } -// } -// } -// #endif diff --git a/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas.swift b/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas.swift index 133a9ae54f..5ed25121e9 100644 --- a/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas.swift +++ b/RadixWallet/Features/CreatePersona/Children/Introduction/IntroductionToPersonas.swift @@ -1,6 +1,3 @@ -import ComposableArchitecture -import SwiftUI - @Reducer public struct IntroductionToPersonas: Sendable, FeatureReducer { @ObservableState @@ -9,7 +6,6 @@ public struct IntroductionToPersonas: Sendable, FeatureReducer { public typealias Action = FeatureAction public enum ViewAction: Sendable, Equatable { - case appeared case continueButtonTapped } @@ -21,8 +17,6 @@ public struct IntroductionToPersonas: Sendable, FeatureReducer { public func reduce(into state: inout State, viewAction: ViewAction) -> Effect { switch viewAction { - case .appeared: - .none case .continueButtonTapped: .send(.delegate(.done)) } From 159eb14416efc3b69fe1ee3778d85a0f1b3ac6d2 Mon Sep 17 00:00:00 2001 From: Ghenadie Vasiliev-Pusca Date: Mon, 2 Sep 2024 14:56:06 +0300 Subject: [PATCH 40/40] wip --- RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift index 934571948a..5be4221dc8 100644 --- a/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift +++ b/RadixWallet/Features/AppFeature/Overlay/Overlay+View.swift @@ -45,7 +45,7 @@ private extension View { private func sheet(with destinationStore: PresentationStoreOf) -> some View { sheet(store: destinationStore.scope(state: \.sheet, action: \.sheet)) { SheetOverlayCoordinator.View(store: $0) - .presentationDetents([.fraction(0.75)]) + .presentationDetents([.fraction(0.75), .large]) .presentationBackground(.blur) } }