From 90f8e4a2bf9a7a1cffe1c9c1608549f0f8fb3712 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Sat, 19 Oct 2024 12:30:32 +0200 Subject: [PATCH] [#1377] Add UA to memo - Checkbox for the UA being included to the memo implemented [#1377] Add UA to memo - Select text made as a separate and independent feature with final design and its own feature flag [#1377] Add UA to memo - design modified to encapsulate in a rounded background even the memoBytes label --- modules/Package.swift | 1 + .../Features/Root/RootInitialization.swift | 3 + .../Features/SendFlow/SendFlowView.swift | 2 +- modules/Sources/Features/Tabs/TabsStore.swift | 12 +++ modules/Sources/Features/Tabs/TabsView.swift | 26 ++++++ .../TransactionListStore.swift | 5 ++ .../TransactionList/Views/MessageView.swift | 24 +++++- .../Views/TapToCopyTransactionDataView.swift | 2 +- modules/Sources/Generated/L10n.swift | 13 +++ .../icons/textInput.imageset/Contents.json | 12 +++ .../icons/textInput.imageset/textInput.png | Bin 0 -> 7259 bytes .../Generated/Resources/Localizable.strings | 6 ++ .../Generated/XCAssets+Generated.swift | 1 + modules/Sources/Models/FeatureFlags.swift | 12 ++- .../MessageEditor/MessageEditor.swift | 78 +++++++++++------- .../MessageEditor/MessageEditorStore.swift | 17 ++++ .../UIComponents/Toggle/ZashiToggle.swift | 10 ++- secant.xcodeproj/project.pbxproj | 6 +- 18 files changed, 187 insertions(+), 43 deletions(-) create mode 100644 modules/Sources/Generated/Resources/Assets.xcassets/icons/textInput.imageset/Contents.json create mode 100644 modules/Sources/Generated/Resources/Assets.xcassets/icons/textInput.imageset/textInput.png diff --git a/modules/Package.swift b/modules/Package.swift index 43b1128f..3f06523c 100644 --- a/modules/Package.swift +++ b/modules/Package.swift @@ -807,6 +807,7 @@ let package = Package( "LocalAuthenticationHandler", "Models", "NumberFormatter", + "Models", "SupportDataGenerator", "Utils", "ZcashSDKEnvironment", diff --git a/modules/Sources/Features/Root/RootInitialization.swift b/modules/Sources/Features/Root/RootInitialization.swift index e6e03d32..af2325ab 100644 --- a/modules/Sources/Features/Root/RootInitialization.swift +++ b/modules/Sources/Features/Root/RootInitialization.swift @@ -324,6 +324,9 @@ extension Root { case .initialization(.initializationSuccessfullyDone(let uAddress)): state.tabsState.receiveState.uAddress = uAddress state.tabsState.settingsState.integrationsState.uAddress = uAddress + if let uAddress = try? uAddress?.stringEncoded { + state.tabsState.sendState.memoState.uAddress = uAddress + } return .merge( .send(.initialization(.registerForSynchronizersUpdate)), .publisher { diff --git a/modules/Sources/Features/SendFlow/SendFlowView.swift b/modules/Sources/Features/SendFlow/SendFlowView.swift index d6169218..45a0f69a 100644 --- a/modules/Sources/Features/SendFlow/SendFlowView.swift +++ b/modules/Sources/Features/SendFlow/SendFlowView.swift @@ -134,7 +134,7 @@ public struct SendFlowView: View { } if store.isMemoInputEnabled { - MessageEditorView(store: store.memoStore()) + MessageEditorView(store: store.memoStore(), isAddUAtoMemoActive: true) .frame(minHeight: 155) .frame(maxHeight: 300) .id(InputID.message) diff --git a/modules/Sources/Features/Tabs/TabsStore.swift b/modules/Sources/Features/Tabs/TabsStore.swift index 0dd55a5a..db9282a9 100644 --- a/modules/Sources/Features/Tabs/TabsStore.swift +++ b/modules/Sources/Features/Tabs/TabsStore.swift @@ -85,6 +85,7 @@ public struct Tabs { public var receiveState: Receive.State public var requestZecState: RequestZec.State public var selectedTab: Tab = .account + public var selectTextRequest = false public var sendConfirmationState: SendConfirmation.State public var sendState: SendFlow.State public var settingsState: Settings.State @@ -94,6 +95,7 @@ public struct Tabs { public var stackDestinationMaxPrivacyBindingsAlive = 0 public var stackDestinationRequestPayment: StackDestinationRequestPayment? public var stackDestinationRequestPaymentBindingsAlive = 0 + public var textToSelect = "" public var zecKeyboardState: ZecKeyboard.State public init( @@ -136,6 +138,7 @@ public struct Tabs { case binding(BindingAction) case currencyConversionCloseTapped case currencyConversionSetup(CurrencyConversionSetup.Action) + case dismissSelectTextEditor case home(Home.Action) case onAppear case rateTooltipTapped @@ -307,6 +310,15 @@ public struct Tabs { state.selectedTab = .balances return .none + case .home(.transactionList(.selectText(let selectText))): + state.selectTextRequest = true + state.textToSelect = selectText + return .none + + case .dismissSelectTextEditor: + state.selectTextRequest = false + return .none + case .home: return .none diff --git a/modules/Sources/Features/Tabs/TabsView.swift b/modules/Sources/Features/Tabs/TabsView.swift index 9c62949d..16ba9ddb 100644 --- a/modules/Sources/Features/Tabs/TabsView.swift +++ b/modules/Sources/Features/Tabs/TabsView.swift @@ -208,6 +208,32 @@ public struct TabsView: View { .navigationBarItems(leading: hideBalancesButton(tab: store.selectedTab)) .zashiTitle { navBarView(store.selectedTab) } .walletStatusPanel() + .sheet(isPresented: $store.selectTextRequest) { + VStack(alignment: .leading) { + HStack { + Spacer() + + Button { + store.send(.dismissSelectTextEditor) + } label: { + Asset.Assets.buttonCloseX.image + .zImage(size: 24, style: Design.Btns.Tertiary.fg) + .padding(8) + .background { + RoundedRectangle(cornerRadius: 12) + .fill(Design.Btns.Tertiary.bg.color) + } + } + } + + TextEditor(text: $store.textToSelect) + .colorBackground(Asset.Colors.background.color) + .background(Asset.Colors.background.color) + .zFont(size: 14, style: Design.Text.primary) + } + .padding() + .applyScreenBackground() + } .overlayPreferenceValue(ExchangeRateStaleTooltipPreferenceKey.self) { preferences in WithPerceptionTracking { if store.isRateTooltipEnabled { diff --git a/modules/Sources/Features/TransactionList/TransactionListStore.swift b/modules/Sources/Features/TransactionList/TransactionListStore.swift index bbb85de8..77073957 100644 --- a/modules/Sources/Features/TransactionList/TransactionListStore.swift +++ b/modules/Sources/Features/TransactionList/TransactionListStore.swift @@ -18,6 +18,7 @@ public struct TransactionList { @ObservableState public struct State: Equatable { @Shared(.inMemory(.addressBookContacts)) public var addressBookContacts: AddressBookContacts = .empty + @Shared(.inMemory(.featureFlags)) public var featureFlags: FeatureFlags = .initial public var latestMinedHeight: BlockHeight? public var latestTransactionId = "" public var latestTransactionList: [TransactionState] = [] @@ -45,6 +46,7 @@ public struct TransactionList { case onAppear case onDisappear case saveAddressTapped(RedactableString) + case selectText(String) case synchronizerStateChanged(SyncStatus) case transactionCollapseRequested(String) case transactionAddressExpandRequested(String) @@ -124,6 +126,9 @@ public struct TransactionList { .cancel(id: CancelEventId) ) + case .selectText: + return .none + case .saveAddressTapped: return .none diff --git a/modules/Sources/Features/TransactionList/Views/MessageView.swift b/modules/Sources/Features/TransactionList/Views/MessageView.swift index 36e1d82f..3ae288a7 100644 --- a/modules/Sources/Features/TransactionList/Views/MessageView.swift +++ b/modules/Sources/Features/TransactionList/Views/MessageView.swift @@ -43,7 +43,7 @@ struct MessageView: View { ForEach(0..>> reply-to: %@ + public static func addUAformat(_ p1: Any) -> String { + return L10n.tr("Localizable", "messageEditor.addUAformat", String(describing: p1), fallback: "\n>>> reply-to: %@") + } + /// Your address is included in the memo + public static let removeUA = L10n.tr("Localizable", "messageEditor.removeUA", fallback: "Your address is included in the memo") + } public enum NotEnoughFreeSpace { /// Zashi requires at /// least %@ GB of space to @@ -893,6 +904,8 @@ public enum L10n { public static let receiving = L10n.tr("Localizable", "transaction.receiving", fallback: "Receiving...") /// Save address public static let saveAddress = L10n.tr("Localizable", "transaction.saveAddress", fallback: "Save address") + /// Select text + public static let selectText = L10n.tr("Localizable", "transaction.selectText", fallback: "Select text") /// Sending... public static let sending = L10n.tr("Localizable", "transaction.sending", fallback: "Sending...") /// Sent diff --git a/modules/Sources/Generated/Resources/Assets.xcassets/icons/textInput.imageset/Contents.json b/modules/Sources/Generated/Resources/Assets.xcassets/icons/textInput.imageset/Contents.json new file mode 100644 index 00000000..97d81ab8 --- /dev/null +++ b/modules/Sources/Generated/Resources/Assets.xcassets/icons/textInput.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "textInput.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/modules/Sources/Generated/Resources/Assets.xcassets/icons/textInput.imageset/textInput.png b/modules/Sources/Generated/Resources/Assets.xcassets/icons/textInput.imageset/textInput.png new file mode 100644 index 0000000000000000000000000000000000000000..e391af679e14d6c401002db49279e55c4613dc85 GIT binary patch literal 7259 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, title: String = L10n.Send.message, - placeholder: String = L10n.Send.memoPlaceholder + placeholder: String = L10n.Send.memoPlaceholder, + isAddUAtoMemoActive: Bool = false ) { self.store = store self.title = title self.placeholder = placeholder + self.isAddUAtoMemoActive = isAddUAtoMemoActive self.isFocused = false } @@ -44,43 +47,41 @@ public struct MessageEditorView: View { WithPerceptionTracking { VStack(alignment: .leading, spacing: 0) { Text(title) - .font(.custom(FontFamily.Inter.medium.name, size: 14)) - .foregroundColor(Design.Inputs.Filled.label.color) + .zFont(.medium, size: 14, style: Design.Inputs.Filled.label) .padding(.bottom, 6) - TextEditor(text: $store.text) - .focused($isFocused) - .font(.custom(FontFamily.Inter.regular.name, size: 16)) - .padding(.horizontal, 10) - .padding(.top, 2) - .padding(.bottom, 10) - .colorBackground(Design.Inputs.Default.bg.color) - .background(Design.Inputs.Default.bg.color) - .cornerRadius(10) - .overlay { - if store.text.isEmpty { - HStack { - VStack { - Text(placeholder) - .font(.custom(FontFamily.Inter.regular.name, size: 16)) - .foregroundColor(Design.Inputs.Default.text.color) - .onTapGesture { - isFocused = true - } + VStack(spacing: 0) { + TextEditor(text: $store.text) + .focused($isFocused) + .font(.custom(FontFamily.Inter.regular.name, size: 16)) + .padding(.horizontal, 10) + .padding(.top, 2) + .padding(.bottom, 10) + .colorBackground(Design.Inputs.Default.bg.color) + .cornerRadius(10) + .overlay { + if store.text.isEmpty { + HStack { + VStack { + Text(placeholder) + .font(.custom(FontFamily.Inter.regular.name, size: 16)) + .foregroundColor(Design.Inputs.Default.text.color) + .onTapGesture { + isFocused = true + } + + Spacer() + } + .padding(.top, 10) Spacer() } - .padding(.top, 10) - - Spacer() + .padding(.leading, 14) + } else { + EmptyView() } - .padding(.leading, 14) - } else { - EmptyView() } - } - - if store.isCharLimited { + HStack { Spacer() @@ -91,10 +92,25 @@ public struct MessageEditorView: View { ? Design.Inputs.Default.hint.color : Design.Inputs.Filled.required.color ) + .padding(.trailing, 14) + .padding(.bottom, 14) } .frame(height: 20) .padding(.top, 4) } + .background { + RoundedRectangle(cornerRadius: 10) + .fill(Design.Inputs.Default.bg.color) + } + + if store.featureFlags.addUAtoMemo && isAddUAtoMemoActive && !store.uAddress.isEmpty { + ZashiToggle( + isOn: $store.isUAaddedToMemo, + label: store.isUAaddedToMemo ? L10n.MessageEditor.addUA : L10n.MessageEditor.addUA, + textColor: Design.Inputs.Filled.label.color + ) + .padding(.top, 12) + } } } } diff --git a/modules/Sources/UIComponents/TextFields/MessageEditor/MessageEditorStore.swift b/modules/Sources/UIComponents/TextFields/MessageEditor/MessageEditorStore.swift index 8812138a..3341d40c 100644 --- a/modules/Sources/UIComponents/TextFields/MessageEditor/MessageEditorStore.swift +++ b/modules/Sources/UIComponents/TextFields/MessageEditor/MessageEditorStore.swift @@ -10,6 +10,7 @@ import ComposableArchitecture import SwiftUI import Utils import Generated +import Models @Reducer public struct MessageEditor { @@ -17,7 +18,10 @@ public struct MessageEditor { public struct State: Equatable { /// default 0, no char limit public var charLimit = 0 + @Shared(.inMemory(.featureFlags)) public var featureFlags: FeatureFlags = .initial + public var isUAaddedToMemo: Bool = false public var text = "" + public var uAddress = "" public var isCharLimited: Bool { charLimit > 0 @@ -58,6 +62,19 @@ public struct MessageEditor { Reduce { state, action in switch action { + case .binding(\.isUAaddedToMemo): + let blob = L10n.MessageEditor.addUAformat(state.uAddress) + if state.isUAaddedToMemo { + state.text += blob + } else { + if state.text.contains(blob) { + state.text = state.text.replacingOccurrences(of: blob, with: "") + } else if state.text.contains(state.uAddress) { + state.text = state.text.replacingOccurrences(of: state.uAddress, with: "") + } + } + return .none + case .binding: return .none } diff --git a/modules/Sources/UIComponents/Toggle/ZashiToggle.swift b/modules/Sources/UIComponents/Toggle/ZashiToggle.swift index 503c86da..34dadb15 100644 --- a/modules/Sources/UIComponents/Toggle/ZashiToggle.swift +++ b/modules/Sources/UIComponents/Toggle/ZashiToggle.swift @@ -11,10 +11,16 @@ import Generated public struct ZashiToggle: View { @Binding var isOn: Bool let label: String + let textColor: Color - public init(isOn: Binding, label: String) { + public init( + isOn: Binding, + label: String, + textColor: Color = Asset.Colors.primary.color + ) { self._isOn = isOn self.label = label + self.textColor = textColor } public var body: some View { @@ -27,7 +33,7 @@ public struct ZashiToggle: View { }) .toggleStyle(CheckboxToggleStyle()) } - .foregroundColor(Asset.Colors.primary.color) + .foregroundColor(textColor) } } diff --git a/secant.xcodeproj/project.pbxproj b/secant.xcodeproj/project.pbxproj index 763bba00..abf26598 100644 --- a/secant.xcodeproj/project.pbxproj +++ b/secant.xcodeproj/project.pbxproj @@ -2301,7 +2301,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = "zashi-internal.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"secant/Preview Content\""; DEVELOPMENT_TEAM = RLPRR8CPQG; @@ -2332,7 +2332,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = "zashi-internal.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_ASSET_PATHS = "\"secant/Preview Content\""; DEVELOPMENT_TEAM = RLPRR8CPQG; ENABLE_BITCODE = NO; @@ -2362,7 +2362,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = "zashi-internal.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_ASSET_PATHS = "\"secant/Preview Content\""; DEVELOPMENT_TEAM = RLPRR8CPQG; ENABLE_BITCODE = NO;