diff --git a/RadixWallet.xcodeproj/project.pbxproj b/RadixWallet.xcodeproj/project.pbxproj index a378de2881..99259304e6 100644 --- a/RadixWallet.xcodeproj/project.pbxproj +++ b/RadixWallet.xcodeproj/project.pbxproj @@ -1084,6 +1084,7 @@ 48FFFB082ADC6FD300B2B213 /* SwiftUINavigationCore in Frameworks */ = {isa = PBXBuildFile; productRef = 48FFFB072ADC6FD300B2B213 /* SwiftUINavigationCore */; }; 48FFFB0A2ADC721800B2B213 /* Atomics in Frameworks */ = {isa = PBXBuildFile; productRef = 48FFFB092ADC721800B2B213 /* Atomics */; }; 48FFFB0D2ADC744700B2B213 /* TextBuilder in Frameworks */ = {isa = PBXBuildFile; productRef = 48FFFB0C2ADC744700B2B213 /* TextBuilder */; }; + 5BBC43A92BBAC6B0005747B1 /* AppTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BBC43A82BBAC6B0005747B1 /* AppTextEditor.swift */; }; 830818482B9F1621002D8351 /* HTTPClient+Live.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830818472B9F1621002D8351 /* HTTPClient+Live.swift */; }; 8308184A2B9F162B002D8351 /* HTTPClient+Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830818492B9F162B002D8351 /* HTTPClient+Mock.swift */; }; 8308184C2B9F169B002D8351 /* TokenPriceClient+Live.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8308184B2B9F169B002D8351 /* TokenPriceClient+Live.swift */; }; @@ -2380,6 +2381,7 @@ 48F9CFE62B03A0A000657755 /* ProfileBuilderTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileBuilderTest.swift; sourceTree = ""; }; 48FF43142AE43C7C00C568B9 /* TimeLimit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeLimit.swift; sourceTree = ""; }; 48FFFAF12ADC23AC00B2B213 /* Exports.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exports.swift; sourceTree = ""; }; + 5BBC43A82BBAC6B0005747B1 /* AppTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTextEditor.swift; sourceTree = ""; }; 830818472B9F1621002D8351 /* HTTPClient+Live.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HTTPClient+Live.swift"; sourceTree = ""; }; 830818492B9F162B002D8351 /* HTTPClient+Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HTTPClient+Mock.swift"; sourceTree = ""; }; 8308184B2B9F169B002D8351 /* TokenPriceClient+Live.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TokenPriceClient+Live.swift"; sourceTree = ""; }; @@ -5868,6 +5870,7 @@ 48CFC1182ADC10D900E77A5C /* LoadingView.swift */, 48CFC1192ADC10D900E77A5C /* ApprovalSlider.swift */, 48CFC11A2ADC10D900E77A5C /* FixedSpacer.swift */, + 5BBC43A82BBAC6B0005747B1 /* AppTextEditor.swift */, ); path = Components; sourceTree = ""; @@ -8897,6 +8900,7 @@ 48CFC64D2ADC10DB00E77A5C /* PersonaData+PostalAddress.swift in Sources */, 48CFC5EE2ADC10DA00E77A5C /* SlideUpPanel+View.swift in Sources */, 48CFC3492ADC10D900E77A5C /* PersonaDataPermissionBox.swift in Sources */, + 5BBC43A92BBAC6B0005747B1 /* AppTextEditor.swift in Sources */, 48CFC68E2ADC10DB00E77A5C /* AddressKind.swift in Sources */, A41266F12B15579E00EA38E9 /* ManualAccountRecoverySeedPhrase+View.swift in Sources */, 48CFC4F32ADC10DA00E77A5C /* StateEntityDetailsResponsePackageDetails.swift in Sources */, diff --git a/RadixWallet/Core/DesignSystem/Components/AppTextEditor.swift b/RadixWallet/Core/DesignSystem/Components/AppTextEditor.swift new file mode 100644 index 0000000000..645e7e2688 --- /dev/null +++ b/RadixWallet/Core/DesignSystem/Components/AppTextEditor.swift @@ -0,0 +1,23 @@ +import SwiftUI + +/// A helper view that allows to show a placeholder on the `TextEditor` while the content is empty. +/// +/// This is a workaround while Apple doesn't provide a way of setting the placeholder on the native view. +struct AppTextEditor: View { + let placeholder: String + @Binding var text: String + + var body: some View { + ZStack(alignment: .topLeading) { + if text.isEmpty { + Text(placeholder) + .padding(.top, 10) + .padding(.leading, 6) + .disabled(true) + .foregroundColor(.app.gray2) + } + + TextEditor(text: $text) + } + } +} diff --git a/RadixWallet/Core/Resources/Generated/L10n.generated.swift b/RadixWallet/Core/Resources/Generated/L10n.generated.swift index dce7db7d81..24b4987611 100644 --- a/RadixWallet/Core/Resources/Generated/L10n.generated.swift +++ b/RadixWallet/Core/Resources/Generated/L10n.generated.swift @@ -637,6 +637,8 @@ public enum L10n { public static let sendTransferButton = L10n.tr("Localizable", "assetTransfer_sendTransferButton", fallback: "Continue") /// Message public static let transactionMessage = L10n.tr("Localizable", "assetTransfer_transactionMessage", fallback: "Message") + /// Add a message + public static let transactionMessagePlaceholder = L10n.tr("Localizable", "assetTransfer_transactionMessagePlaceholder", fallback: "Add a message") public enum AccountList { /// Add Transfer public static let addAccountButton = L10n.tr("Localizable", "assetTransfer_accountList_addAccountButton", fallback: "Add Transfer") diff --git a/RadixWallet/Core/Resources/Resources/en.lproj/Localizable.strings b/RadixWallet/Core/Resources/Resources/en.lproj/Localizable.strings index 15619ad328..945d7d52b8 100644 --- a/RadixWallet/Core/Resources/Resources/en.lproj/Localizable.strings +++ b/RadixWallet/Core/Resources/Resources/en.lproj/Localizable.strings @@ -639,6 +639,7 @@ Or you can clear this wallet from this phone and start fresh."; "misc_remoteThumbnails_vectorImageFailure" = "Can\'t displays image of vector type"; "misc_remoteThumbnails_loadingFailure" = "Can\'t load image"; "assetTransfer_transactionMessage" = "Message"; +"assetTransfer_transactionMessagePlaceholder" = "Add a message"; "assetTransfer_qrScanInstructions" = "Scan a QR code of a Radix Account address from another wallet or an exchange."; "assetTransfer_sendTransferButton" = "Continue"; "assetTransfer_accountList_externalAccountName" = "Account"; @@ -1036,4 +1037,4 @@ If you have any “Legacy” Accounts (created on the Olympia network) to import "survey_highestScoreLabel" = "10 - Very likely"; "survey_reason_heading" = "What’s the main reason for your score?"; "survey_reason_fieldHint" = "Let us know..."; -"survey_submitButton" = "Submit Feedback - Thanks!"; \ No newline at end of file +"survey_submitButton" = "Submit Feedback - Thanks!"; diff --git a/RadixWallet/Features/AssetTransferFeature/Components/AssetTransferMessage/AssetTransferMessage+View.swift b/RadixWallet/Features/AssetTransferFeature/Components/AssetTransferMessage/AssetTransferMessage+View.swift index 61d4605801..75061486e7 100644 --- a/RadixWallet/Features/AssetTransferFeature/Components/AssetTransferMessage/AssetTransferMessage+View.swift +++ b/RadixWallet/Features/AssetTransferFeature/Components/AssetTransferMessage/AssetTransferMessage+View.swift @@ -56,8 +56,9 @@ extension AssetTransferMessage.View { .padding(.medium3) .roundedCorners(.top, strokeColor: .borderColor) - TextEditor(text: - viewStore.binding( + AppTextEditor( + placeholder: L10n.AssetTransfer.transactionMessagePlaceholder, + text: viewStore.binding( get: \.message, send: { .messageChanged($0) } )