From 43cc55ae4e733b0a4f3e39c2ad66a93e9114a259 Mon Sep 17 00:00:00 2001 From: blueJpg <2238288979@qq.com> Date: Mon, 15 Jul 2024 20:43:01 +0800 Subject: [PATCH] [*] improve ui --- src/config/conf.rs | 5 ++ src/config/data.rs | 21 +++++-- src/config/mod.rs | 2 +- src/logic/accounts.rs | 5 ++ src/logic/setting.rs | 21 ++++++- src/logic/tokens.rs | 79 ++++++++++++++++++++++-- src/logic/tr.rs | 10 +++ ui/appwindow.slint | 4 +- ui/base/def.slint | 7 ++- ui/base/token-sender.slint | 112 +++++++++++++++++++++++++++++++++- ui/base/transaction-fee.slint | 30 ++++++++- ui/base/widgets.slint | 3 +- ui/images/advance-setting.svg | 1 + ui/images/horse.svg | 1 + ui/images/rabbit.svg | 1 + ui/images/turtle.svg | 1 + ui/logic.slint | 22 ++++++- ui/panel/bodyer/home.slint | 22 ++++++- ui/panel/bodyer/setting.slint | 32 +++++++++- ui/store.slint | 4 ++ ui/theme.slint | 4 ++ 21 files changed, 366 insertions(+), 21 deletions(-) create mode 100644 ui/images/advance-setting.svg create mode 100644 ui/images/horse.svg create mode 100644 ui/images/rabbit.svg create mode 100644 ui/images/turtle.svg diff --git a/src/config/conf.rs b/src/config/conf.rs index 68c7839..fa80881 100644 --- a/src/config/conf.rs +++ b/src/config/conf.rs @@ -69,6 +69,10 @@ pub fn developer_mode() -> data::DeveloperMode { CONFIG.lock().unwrap().developer_mode.clone() } +pub fn security_privacy() -> data::SecurityPrivacy { + CONFIG.lock().unwrap().security_privacy.clone() +} + pub fn db_path() -> PathBuf { CONFIG.lock().unwrap().db_path.clone() } @@ -125,6 +129,7 @@ impl Config { self.appid = c.appid; self.ui = c.ui; self.developer_mode = c.developer_mode; + self.security_privacy = c.security_privacy; Ok(()) } Err(_) => { diff --git a/src/config/data.rs b/src/config/data.rs index 25fba39..9872108 100644 --- a/src/config/data.rs +++ b/src/config/data.rs @@ -21,10 +21,7 @@ pub struct Config { pub ui: UI, pub developer_mode: DeveloperMode, -} - -pub fn appid_default() -> String { - Uuid::new_v4().to_string() + pub security_privacy: SecurityPrivacy, } #[derive(Serialize, Deserialize, Debug, Clone, Derivative)] @@ -46,3 +43,19 @@ pub struct DeveloperMode { #[derivative(Default(value = "\"test\".to_string()"))] pub network: String, } + +#[derive(Serialize, Deserialize, Debug, Clone, Derivative)] +#[derivative(Default)] +pub struct SecurityPrivacy { + #[serde(default = "prioritization_fee_default")] + #[derivative(Default(value = "1000"))] + pub max_prioritization_fee: u64, +} + +pub fn appid_default() -> String { + Uuid::new_v4().to_string() +} + +pub fn prioritization_fee_default() -> u64 { + 1000 +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 50f3d22..cd2578c 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,4 +1,4 @@ mod conf; mod data; -pub use conf::{all, cache_dir, db_path, developer_mode, init, is_first_run, save, ui}; +pub use conf::{all, cache_dir, db_path, security_privacy, developer_mode, init, is_first_run, save, ui}; diff --git a/src/logic/accounts.rs b/src/logic/accounts.rs index dbdfaad..9e019a9 100644 --- a/src/logic/accounts.rs +++ b/src/logic/accounts.rs @@ -491,6 +491,11 @@ pub fn init(ui: &AppWindow) { } }); + let ui_handle = ui.as_weak(); + ui.global::().on_update_home_page(move || { + super::tokens::init_tokens(&ui_handle.unwrap()); + }); + let ui_handle = ui.as_weak(); ui.global::().on_show_mnemonic(move |password| { let ui_handle = ui_handle.clone(); diff --git a/src/logic/setting.rs b/src/logic/setting.rs index 2370e57..8901570 100644 --- a/src/logic/setting.rs +++ b/src/logic/setting.rs @@ -1,8 +1,8 @@ use super::tr::tr; use crate::{ config, - slint_generatedAppWindow::SettingDeveloperMode, slint_generatedAppWindow::{AppWindow, Logic, Store, Theme}, + slint_generatedAppWindow::{SettingDeveloperMode, SettingSecurityPrivacy}, }; use slint::ComponentHandle; @@ -67,6 +67,25 @@ pub fn init(ui: &AppWindow) { all.developer_mode.network = setting.network.into(); _ = config::save(all); }); + + ui.global::() + .on_get_setting_security_privacy(move || { + let setting = config::security_privacy(); + + SettingSecurityPrivacy { + max_prioritization_fee: slint::format!("{}", setting.max_prioritization_fee), + } + }); + + ui.global::() + .on_set_setting_security_privacy(move |setting| { + let mut all = config::all(); + all.security_privacy.max_prioritization_fee = setting + .max_prioritization_fee + .parse::() + .unwrap_or(1000_u64); + _ = config::save(all); + }); } fn init_setting(ui: &AppWindow) { diff --git a/src/logic/tokens.rs b/src/logic/tokens.rs index 484841f..afe11df 100644 --- a/src/logic/tokens.rs +++ b/src/logic/tokens.rs @@ -8,9 +8,10 @@ use crate::{ logic::message::{async_message_info, async_message_success, async_message_warn}, message_info, message_success, message_warn, slint_generatedAppWindow::{ - AppWindow, HomeIndex, Icons, LoadingStatus, Logic, SendTokenProps, Store, - TokenTileEntry as UITokenTileEntry, TokenTileWithSwitchEntry as UITokenTileWithSwitchEntry, - TokensSetting, TransactionTileStatus, Util, + AppWindow, HomeIndex, Icons, LoadingStatus, Logic, PrioritizationFeeStatus, SendTokenProps, + Store, TokenTileEntry as UITokenTileEntry, + TokenTileWithSwitchEntry as UITokenTileWithSwitchEntry, TokensSetting, + TransactionTileStatus, Util, }, }; use anyhow::{bail, Result}; @@ -27,6 +28,8 @@ use wallet::{ transaction::{self, SendLamportsProps, DEFAULT_TIMEOUT_SECS, DEFAULT_TRY_COUNTS}, }; +static PRIORITIZATION_FEES: Lazy> = Lazy::new(|| Mutex::new((0, 0, 0))); + static SOL_PRICE: Lazy> = Lazy::new(|| Mutex::new(0.0)); static SPL_TOKENS_PRICE_INFO: Lazy>> = @@ -185,6 +188,18 @@ pub async fn update_spl_tokens_price() { } } +pub async fn update_prioritization_fees(network: &str) { + let rpc_url_ty = RpcUrlType::from_str(network).unwrap_or(RpcUrlType::Main); + match transaction::prioritization_fees(rpc_url_ty, Some(transaction::DEFAULT_TIMEOUT_SECS)) + .await + { + Err(e) => log::warn!("{e:?}"), + Ok(v) => { + *PRIORITIZATION_FEES.lock().unwrap() = v; + } + } +} + async fn get_from_db(network: &str, account_address: &str) -> Vec { match db::entry::select_all(TOKENS_TABLE).await { Ok(items) => items @@ -281,6 +296,7 @@ pub fn init_tokens(ui: &AppWindow) { update_sol_price().await; update_spl_tokens_price().await; + update_prioritization_fees(&network).await; }); } @@ -425,6 +441,37 @@ pub fn init(ui: &AppWindow) { Err(_) => tr("非法地址").into(), _ => SharedString::default(), }); + + ui.global::() + .on_prioritization_fee(move |ty| match ty { + PrioritizationFeeStatus::Slow => PRIORITIZATION_FEES.lock().unwrap().0 as i32, + PrioritizationFeeStatus::Normal => PRIORITIZATION_FEES.lock().unwrap().1 as i32, + PrioritizationFeeStatus::Fast => PRIORITIZATION_FEES.lock().unwrap().2 as i32, + }); + + ui.global::() + .on_is_valid_prioritization_fee(move |fee| { + if fee.trim().is_empty() { + return SharedString::default(); + } + + match fee.parse::() { + Err(_) => tr("非法优先费用").into(), + Ok(v) => { + let max_prioritization_fee = config::security_privacy().max_prioritization_fee; + if v <= max_prioritization_fee { + SharedString::default() + } else { + slint::format!( + "{}{}, {}", + tr("最大优先费用"), + max_prioritization_fee, + tr("请设置更大的优先费用") + ) + } + } + } + }); } fn _add_token(entry: TokenTileEntry) { @@ -817,7 +864,12 @@ async fn _evaluate_spl_token_transaction_fee( }; let prioritization_fee = if !props.prioritization_fee.trim().is_empty() { - Some(props.prioritization_fee.trim().parse::()?) + let fee = props.prioritization_fee.trim().parse::()?; + if fee == 0 { + None + } else { + Some(fee) + } } else { None }; @@ -921,7 +973,12 @@ async fn _send_sol( }; let prioritization_fee = if !props.prioritization_fee.trim().is_empty() { - Some(props.prioritization_fee.trim().parse::()?) + let fee = props.prioritization_fee.trim().parse::()?; + if fee == 0 { + None + } else { + Some(fee) + } } else { None }; @@ -990,7 +1047,12 @@ async fn _send_spl_token( }; let prioritization_fee = if !props.prioritization_fee.trim().is_empty() { - Some(props.prioritization_fee.trim().parse::()?) + let fee = props.prioritization_fee.trim().parse::()?; + if fee == 0 { + None + } else { + Some(fee) + } } else { None }; @@ -1129,6 +1191,11 @@ fn _send_token( props: SendTokenProps, is_token_account_exist: bool, ) { + let network = props.network.clone(); + tokio::spawn(async move { + update_prioritization_fees(&network).await; + }); + tokio::spawn(async move { match super::accounts::is_valid_password_in_secret_info(&password).await { Err(e) => { diff --git a/src/logic/tr.rs b/src/logic/tr.rs index 1a12451..26d8e85 100644 --- a/src/logic/tr.rs +++ b/src/logic/tr.rs @@ -266,6 +266,16 @@ pub fn tr(text: &str) -> String { items.insert("创建组记词", "Create mnemonic"); items.insert("恢复账户", "Recover account"); items.insert("二维码", "QrCode"); + items.insert("高级设置", "Advance setting"); + items.insert("备注", "Memo"); + items.insert("优先费用", "Prioritization fee"); + items.insert("基础费用", "Base fee"); + items.insert("最大优先费用", "Max prioritization fee"); + items.insert("慢", "Slow"); + items.insert("正常", "Normal"); + items.insert("快", "Fast"); + items.insert("非法优先费用", "Invalid prioritization fee"); + items.insert("请设置更大的优先费用", "Please setting max prioritization fee"); items.insert( "更新账户余额失败. 账户不存在", "Refresh account balance failed. The account is not found", diff --git a/ui/appwindow.slint b/ui/appwindow.slint index 0d7265f..fad63d0 100644 --- a/ui/appwindow.slint +++ b/ui/appwindow.slint @@ -1,6 +1,6 @@ import { Theme, Icons } from "./theme.slint"; import { Logic } from "./logic.slint"; -import { Store, SettingDetailIndex, SettingDeveloperMode, SendTokenProps, HomeIndex } from "./store.slint"; +import { Store, SettingDetailIndex, SettingDeveloperMode, SettingSecurityPrivacy, SendTokenProps, HomeIndex } from "./store.slint"; import { Util } from "./util.slint"; import { Panel } from "./panel/panel.slint"; import { LoadingStatus, Toast, IconsDialogSetting, IconsDialog, OkCancelDialogV2, Blanket, LanguageDialog, OkCancelDialogSetting, LandingPage, Password, PasswordSetting, Password, AddressBookEntry, AddressBookSetting, AboutSetting, TransactionTileEntry, TransactionTileStatus, TokenTileEntry, TokenTileWithSwitchEntry } from "./base/widgets.slint"; @@ -114,4 +114,4 @@ export component AppWindow inherits Window { } } -export { Util, Logic, Store, Theme, Icons, IconsDialogSetting, LoadingStatus, SettingDetailIndex, AccountMnemonicSetting, AddressBookEntry, AddressBookSetting, PasswordSetting, AboutSetting, TransactionTileEntry, TransactionTileStatus, HistorySetting, SettingDeveloperMode, TokenTileEntry, TokensSetting, TokenTileWithSwitchEntry, SendTokenProps, HomeIndex } +export { Util, Logic, Store, Theme, Icons, IconsDialogSetting, LoadingStatus, SettingDetailIndex, AccountMnemonicSetting, AddressBookEntry, AddressBookSetting, PasswordSetting, AboutSetting, TransactionTileEntry, TransactionTileStatus, HistorySetting, SettingDeveloperMode, TokenTileEntry, TokensSetting, TokenTileWithSwitchEntry, SendTokenProps, HomeIndex, SettingSecurityPrivacy } diff --git a/ui/base/def.slint b/ui/base/def.slint index bf88831..6aa9a30 100644 --- a/ui/base/def.slint +++ b/ui/base/def.slint @@ -1,6 +1,11 @@ - export enum LoadingStatus { Loading, Fail, Success, } + +export enum PrioritizationFeeStatus { + Slow, + Normal, + Fast, +} diff --git a/ui/base/token-sender.slint b/ui/base/token-sender.slint index d00d909..b776fb6 100644 --- a/ui/base/token-sender.slint +++ b/ui/base/token-sender.slint @@ -4,8 +4,9 @@ import { Store } from "../store.slint"; import { Label } from "label.slint"; import { Avatar } from "avatar.slint"; import { LineInput } from "line-input.slint"; -import { CancelBtn, ConfirmBtn } from "btn.slint"; +import { CancelBtn, ConfirmBtn, TextBtn } from "btn.slint"; import { SettingDetail, SettingDetailInner, SettingDetailInnerVbox, SettingDetailLabel } from "setting-detail.slint"; +import { PrioritizationFeeStatus } from "def.slint"; export component TokenSender inherits SettingDetail { in property avatar <=> ava.icon; @@ -17,18 +18,31 @@ export component TokenSender inherits SettingDetail { in-out property send-amount <=> amount-input.text; in property total-balance <=> total-balance-label.text; in property total-balance-usdt <=> total-balance-usdt-label.text; + in property recipient-address-error-message; + in property prioritization-fee-error-message; + in-out property memo; + in-out property prioritization-fee; + in-out property is-show-advance-setting; private property is-token-edit; callback update-send-token-name(); callback recipient-address-edited(string); + callback prioritization-fee-edited(string); callback copy-send-address <=> send-address-input.clicked; callback open-address-book <=> recipient-address-input.clicked; callback open-network <=> network-input.clicked; callback cancel <=> cancel-btn.clicked; callback confirm <=> confirm-btn.clicked; + callback get-prioritization-fee(PrioritizationFeeStatus) -> int; + + public function reset-advance-setting() { + root.memo = ""; + root.prioritization-fee = ""; + } + title: Logic.tr(Store.is-cn, "发送代币"); SettingDetailInner { @@ -156,6 +170,102 @@ export component TokenSender inherits SettingDetail { } } + TextBtn { + text: Logic.tr(Store.is-cn, "高级设置"); + icon: Icons.advance-setting; + + clicked => { + root.is-show-advance-setting = !root.is-show-advance-setting; + } + } + + if is-show-advance-setting: SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "备注"); + } + + memo-input := LineInput { + width: root.width - Theme.spacing * 4; + icon: Icons.cancel; + text: root.memo; + + clicked => { + self.text = ""; + } + + edited => { + root.memo = self.text; + } + } + } + + if is-show-advance-setting: SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "优先费用"); + } + + prioritization-fee-input := LineInput { + width: root.width - Theme.spacing * 4; + icon: Icons.cancel; + input-type: InputType.number; + placeholder-text: "micro lamports"; + text: root.prioritization-fee; + + clicked => { + self.text = ""; + } + + edited => { + root.prioritization-fee = self.text; + root.prioritization-fee-edited(self.text); + } + } + + HorizontalLayout { + alignment: LayoutAlignment.start; + spacing: Theme.spacing * 2; + + TextBtn { + text: Logic.tr(Store.is-cn, "慢"); + bg-color: Theme.info-color; + use-auto-size: true; + icon: Icons.turtle; + + clicked => { + prioritization-fee-input.text = root.get-prioritization-fee(PrioritizationFeeStatus.Slow); + root.prioritization-fee = prioritization-fee-input.text; + } + } + + TextBtn { + text: Logic.tr(Store.is-cn,"正常"); + use-auto-size: true; + icon: Icons.rabbit; + + clicked => { + prioritization-fee-input.text = root.get-prioritization-fee(PrioritizationFeeStatus.Normal); + root.prioritization-fee = prioritization-fee-input.text; + } + } + + TextBtn { + text: Logic.tr(Store.is-cn,"快"); + use-auto-size: true; + icon: Icons.horse; + + clicked => { + prioritization-fee-input.text = root.get-prioritization-fee(PrioritizationFeeStatus.Fast); + root.prioritization-fee = prioritization-fee-input.text; + } + } + } + + if root.prioritization-fee-error-message != "": SettingDetailLabel { + color: Theme.danger-color; + text: root.prioritization-fee-error-message; + } + } + HorizontalLayout { alignment: LayoutAlignment.center; padding-top: Theme.padding * 5; diff --git a/ui/base/transaction-fee.slint b/ui/base/transaction-fee.slint index 886c0be..1f281b1 100644 --- a/ui/base/transaction-fee.slint +++ b/ui/base/transaction-fee.slint @@ -19,6 +19,8 @@ export component TransactionFee inherits SettingDetail { in property fee-usdt; in property create-token-account-fee; in property create-token-account-fee-usdt; + in property memo; + in property prioritization-fee; in property loading-status; @@ -107,7 +109,7 @@ export component TransactionFee inherits SettingDetail { if loading-status == LoadingStatus.Success: SettingDetailInnerVbox { SettingDetailLabel { - text: Logic.tr(Store.is-cn, "交易费用"); + text: Logic.tr(Store.is-cn, "基础费用"); } LineInput { @@ -123,6 +125,19 @@ export component TransactionFee inherits SettingDetail { } } + if root.prioritization-fee != "": SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "优先费用"); + } + + LineInput { + width: root.width - Theme.spacing * 4; + text: root.prioritization-fee; + is-show-icon: false; + enabled: false; + } + } + if loading-status == LoadingStatus.Success && root.create-token-account-fee != "": SettingDetailInnerVbox { SettingDetailLabel { text: Logic.tr(Store.is-cn, "创建账户费用"); @@ -141,6 +156,19 @@ export component TransactionFee inherits SettingDetail { } } + if root.memo != "": SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "备注"); + } + + LineInput { + width: root.width - Theme.spacing * 4; + text: root.memo; + is-show-icon: false; + enabled: false; + } + } + HorizontalLayout { padding-top: Theme.padding * 5; diff --git a/ui/base/widgets.slint b/ui/base/widgets.slint index 73a2393..5f426a0 100644 --- a/ui/base/widgets.slint +++ b/ui/base/widgets.slint @@ -1,4 +1,4 @@ -import { LoadingStatus } from "def.slint"; +import { LoadingStatus, PrioritizationFeeStatus } from "def.slint"; import { Toast } from "toast.slint"; import { TabBtn } from "tab-btn.slint"; import { IconBtn, RotationType } from "icon-btn.slint"; @@ -51,6 +51,7 @@ import { WaitTransactionConfirmed } from "wait-transaction-confirmed.slint"; export { LoadingStatus, + PrioritizationFeeStatus, Toast, TabBtn, IconBtn, diff --git a/ui/images/advance-setting.svg b/ui/images/advance-setting.svg new file mode 100644 index 0000000..dc76d14 --- /dev/null +++ b/ui/images/advance-setting.svg @@ -0,0 +1 @@ + diff --git a/ui/images/horse.svg b/ui/images/horse.svg new file mode 100644 index 0000000..20013ef --- /dev/null +++ b/ui/images/horse.svg @@ -0,0 +1 @@ + diff --git a/ui/images/rabbit.svg b/ui/images/rabbit.svg new file mode 100644 index 0000000..075e0bd --- /dev/null +++ b/ui/images/rabbit.svg @@ -0,0 +1 @@ + diff --git a/ui/images/turtle.svg b/ui/images/turtle.svg new file mode 100644 index 0000000..ccf1dc0 --- /dev/null +++ b/ui/images/turtle.svg @@ -0,0 +1 @@ + diff --git a/ui/logic.slint b/ui/logic.slint index 9a4a6b8..ea09290 100644 --- a/ui/logic.slint +++ b/ui/logic.slint @@ -1,7 +1,8 @@ -import { Store, SetupIndex, SettingUI, SettingDeveloperMode, AccountEntry, SendTokenProps } from "store.slint"; +import { Store, SetupIndex, SettingUI, SettingDeveloperMode, AccountEntry, SendTokenProps, SettingSecurityPrivacy } from "store.slint"; import { Icons } from "theme.slint"; import { TransactionTileEntry, TransactionTileStatus } from "base/transaction-tile.slint"; import { TokenTileEntry } from "base/token-tile.slint"; +import { PrioritizationFeeStatus } from "base/def.slint"; export global Logic { pure callback new-mnemonics(int) -> [string]; @@ -48,6 +49,8 @@ export global Logic { // (old-uuid, new-uuid) -> void callback switch-account(string, string); + callback update-home-page(); + pure callback qr-code(string) -> image; qr-code => { return Icons.no-data; @@ -132,6 +135,20 @@ export global Logic { // (address) -> (error_message) pure callback is-valid-address(string) -> string; + pure callback prioritization-fee(PrioritizationFeeStatus) -> int; + prioritization-fee(ty) => { + if (ty == PrioritizationFeeStatus.Slow) { + return 0; + } else if (ty == PrioritizationFeeStatus.Normal) { + return 1; + } else { + return 2; + } + } + + // (prioritization-fee) => string + pure callback is-valid-prioritization-fee(string) -> string; + callback update-cache-size(); callback remove-all-cache(); @@ -143,6 +160,9 @@ export global Logic { callback get-setting-ui() -> SettingUI; callback set-setting-ui(SettingUI); + callback get-setting-security-privacy() -> SettingSecurityPrivacy; + callback set-setting-security-privacy(SettingSecurityPrivacy); + pure callback get-current-network() -> string; callback get-setting-developer-mode() -> SettingDeveloperMode; callback set-setting-developer-mode(SettingDeveloperMode); diff --git a/ui/panel/bodyer/home.slint b/ui/panel/bodyer/home.slint index 6dc3a93..c0fdcc1 100644 --- a/ui/panel/bodyer/home.slint +++ b/ui/panel/bodyer/home.slint @@ -223,16 +223,30 @@ export component Home inherits Rectangle { Logic.open-blockchain-network(self.network); } - recipient-address-edited(text) => { self.recipient-address-error-message = Logic.is-valid-address(text); } + prioritization-fee-edited(text) => { + self.prioritization-fee-error-message = Logic.is-valid-prioritization-fee(text); + } + + get-prioritization-fee(ty) => { + return Logic.prioritization-fee(ty); + } + cancel => { self.back(); } confirm => { + self.recipient-address-error-message = Logic.is-valid-address(self.recipient-address); + + self.prioritization-fee-error-message = Logic.is-valid-prioritization-fee(self.prioritization-fee); + + if (self.prioritization-fee-error-message != "" || self.recipient-address-error-message != "") { + return; + } TokensSetting.sender.send-amount = self.send-amount; TokensSetting.sender.props = { @@ -244,10 +258,13 @@ export component Home inherits Rectangle { mint_address: root.selected-entry.mint-address, symbol: root.selected-entry.symbol, amount: self.send-amount, + memo: self.memo, + prioritization-fee: self.prioritization-fee, spl-token-account-address: root.selected-entry.token-account-address, spl-token-decimals: root.selected-entry.decimals, }; + self.reset-advance-setting(); TokensSetting.sender.signature = ""; PasswordSetting.set(true, "evaluate-transaction-fee", ""); } @@ -276,6 +293,9 @@ export component Home inherits Rectangle { create-token-account-fee: TokensSetting.sender.create-token-account-fee != "" ? TokensSetting.sender.create-token-account-fee + "SOL" : ""; create-token-account-fee-usdt: "$" + Logic.calculate-price-of-sol(TokensSetting.sender.create-token-account-fee); + memo: TokensSetting.sender.props.memo; + prioritization-fee: TokensSetting.sender.props.prioritization-fee; + loading-status: TokensSetting.sender.transaction-fee-loading-status; back => { diff --git a/ui/panel/bodyer/setting.slint b/ui/panel/bodyer/setting.slint index fe2e149..3da37ac 100644 --- a/ui/panel/bodyer/setting.slint +++ b/ui/panel/bodyer/setting.slint @@ -2,7 +2,7 @@ import { LineEdit, CheckBox, ComboBox } from "std-widgets.slint"; import { Theme, Icons } from "../../theme.slint"; import { Logic } from "../../logic.slint"; import { Util } from "../../util.slint"; -import { Store, SettingUI, SettingDeveloperMode, SettingDetailIndex, AccountEntry } from "../../store.slint"; +import { Store, SettingUI, SettingDeveloperMode, SettingDetailIndex, AccountEntry, SettingSecurityPrivacy } from "../../store.slint"; import { LineInput, CenterLayout, OkCancelDialogSetting, Divider, Link, Brand, IconBtn, Label, Mnemonic, Head, SettingEntry, SettingDetail, SettingDetailInner, TabBtn, SettingDetailInnerVbox, SettingDetailLabel, TxtEdit, CancelBtn, ConfirmBtn, NoDataImg, Tag, RadioBtn, TokenRecipient, SlideCard, ListTile, IconsDialogSetting, ElevatedBtn, PasswordSetting, Avatar, Help, AddressBook, AddressBookDetail, AddressBookEntry, SettingDetailSwitch, AddressBookSetting, About, ResetPassword } from "../../base/widgets.slint"; export global AccountMnemonicSetting { @@ -313,7 +313,31 @@ component AccountMnemonic inherits SettingDetailInner { component SecurityAndPrivacy inherits SettingDetail { title: Logic.tr(Store.is-cn, "安全与隐私"); + + public function get() -> SettingSecurityPrivacy { + return { + max-prioritization-fee: prioritization-fee-input.text, + }; + } + + public function set(setting: SettingSecurityPrivacy) { + prioritization-fee-input.text = setting.max-prioritization-fee; + } + SettingDetailInner { + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "最大优先费用"); + } + + prioritization-fee-input := LineInput { + width: root.width - Theme.padding * 4; + is-show-icon: false; + input-type: InputType.number; + placeholder-text: "micro lamports"; + } + } + SettingEntry { icon: Icons.password; text: Logic.tr(Store.is-cn, "更改密码"); @@ -612,8 +636,13 @@ export component Setting inherits Rectangle { } if Store.current-setting-detail-index == SettingDetailIndex.SecurityAndPrivacy: SecurityAndPrivacy { + init => { + self.set(Logic.get-setting-security-privacy()); + } + back => { Store.current-setting-detail-index = SettingDetailIndex.Home; + Logic.set-setting-security-privacy(self.get()); } } @@ -651,6 +680,7 @@ export component Setting inherits Rectangle { back => { Store.current-setting-detail-index = SettingDetailIndex.Home; Logic.set-setting-developer-mode(self.get()); + Logic.update-home-page(); } } diff --git a/ui/store.slint b/ui/store.slint index ca1104d..bf65e04 100644 --- a/ui/store.slint +++ b/ui/store.slint @@ -65,6 +65,10 @@ export struct SettingDeveloperMode { network: string, } +export struct SettingSecurityPrivacy { + max-prioritization-fee: string, +} + export struct SendTokenProps { token-uuid: string, derive_index: int, diff --git a/ui/theme.slint b/ui/theme.slint index 0704bc5..8c9df24 100644 --- a/ui/theme.slint +++ b/ui/theme.slint @@ -150,6 +150,10 @@ export global Icons { out property browser-access: @image-url("./images/browser-access.svg"); out property warning: @image-url("./images/warning.svg"); out property qrcode: @image-url("./images/qrcode.svg"); + out property advance-setting: @image-url("./images/advance-setting.svg"); + out property turtle: @image-url("./images/turtle.svg"); + out property rabbit: @image-url("./images/rabbit.svg"); + out property horse: @image-url("./images/horse.svg"); out property solana: @image-url("./images/solana.svg"); out property usdt: @image-url("./images/usdt.svg");