ui: modal show method refactoring, mnemonic word input, update translations
This commit is contained in:
parent
952796abff
commit
2f5011c36f
14 changed files with 376 additions and 226 deletions
|
@ -4,7 +4,6 @@ continue: Continue
|
||||||
complete: Complete
|
complete: Complete
|
||||||
wallets:
|
wallets:
|
||||||
title: Wallets
|
title: Wallets
|
||||||
new: New wallet
|
|
||||||
create_desc: Create or import existing wallet from saved recovery phrase.
|
create_desc: Create or import existing wallet from saved recovery phrase.
|
||||||
add: Add wallet
|
add: Add wallet
|
||||||
name: 'Name:'
|
name: 'Name:'
|
||||||
|
@ -13,13 +12,12 @@ wallets:
|
||||||
pass_empty: Enter password for wallet
|
pass_empty: Enter password for wallet
|
||||||
create: Create
|
create: Create
|
||||||
recover: Restore
|
recover: Restore
|
||||||
|
saved_phrase: Saved phrase
|
||||||
words_count: 'Words count:'
|
words_count: 'Words count:'
|
||||||
word_number: 'Word #%{number}'
|
enter_word: 'Enter word #%{number}:'
|
||||||
word_empty: 'Enter word #%{number} from your recovery phrase'
|
|
||||||
not_valid_word: Entered word is not valid
|
not_valid_word: Entered word is not valid
|
||||||
create_phrase_desc: Safely write down and save your recovery phrase.
|
create_phrase_desc: Safely write down and save your recovery phrase.
|
||||||
restore_phrase_desc: Enter words from your saved recovery phrase.
|
restore_phrase_desc: Enter words from your saved recovery phrase.
|
||||||
conf_phrase_desc: Select words in the same order as they are displayed in your recovery phrase.
|
|
||||||
setup_conn_desc: Choose wallet connection method.
|
setup_conn_desc: Choose wallet connection method.
|
||||||
network:
|
network:
|
||||||
self: Network
|
self: Network
|
||||||
|
|
|
@ -4,7 +4,6 @@ continue: Продолжить
|
||||||
complete: Завершить
|
complete: Завершить
|
||||||
wallets:
|
wallets:
|
||||||
title: Кошельки
|
title: Кошельки
|
||||||
new: Новый кошелёк
|
|
||||||
create_desc: Создайте или импортируйте существующий кошелёк из сохранённой фразы восстановления.
|
create_desc: Создайте или импортируйте существующий кошелёк из сохранённой фразы восстановления.
|
||||||
add: Добавить кошелёк
|
add: Добавить кошелёк
|
||||||
name: 'Название:'
|
name: 'Название:'
|
||||||
|
@ -13,13 +12,12 @@ wallets:
|
||||||
pass_empty: Введите пароль для кошелька
|
pass_empty: Введите пароль для кошелька
|
||||||
create: Создать
|
create: Создать
|
||||||
recover: Восстановить
|
recover: Восстановить
|
||||||
|
saved_phrase: Сохранённая фраза
|
||||||
words_count: 'Количество слов:'
|
words_count: 'Количество слов:'
|
||||||
word_number: 'Слово #%{number}'
|
enter_word: 'Введите слово #%{number}:'
|
||||||
word_empty: 'Введите слово #%{number} из вашей фразы восстановления'
|
|
||||||
not_valid_word: Введено недопустимое слово
|
not_valid_word: Введено недопустимое слово
|
||||||
create_phrase_desc: Безопасно запишите и сохраните свою фразу восстановления.
|
create_phrase_desc: Безопасно запишите и сохраните вашу фразу восстановления.
|
||||||
restore_phrase_desc: Введите слова из вашей сохранённой фразы восстановления.
|
restore_phrase_desc: Введите слова из вашей сохранённой фразы восстановления.
|
||||||
conf_phrase_desc: Выберите слова в таком же порядке, как они отображены в вашей фразе восстановления.
|
|
||||||
setup_conn_desc: Выберите способ подключения кошелька
|
setup_conn_desc: Выберите способ подключения кошелька
|
||||||
network:
|
network:
|
||||||
self: Сеть
|
self: Сеть
|
||||||
|
|
|
@ -114,16 +114,16 @@ impl Modal {
|
||||||
self.closeable.load(Ordering::Relaxed)
|
self.closeable.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set title text on Modal creation.
|
/// Set title text on [`Modal`] creation.
|
||||||
pub fn title(mut self, title: String) -> Self {
|
pub fn title(mut self, title: String) -> Self {
|
||||||
self.title = Some(title.to_uppercase());
|
self.title = Some(title.to_uppercase());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set [`Modal`] instance to show at ui.
|
/// Set [`Modal`] instance into state to show at ui.
|
||||||
pub fn show(modal: Modal) {
|
pub fn show(self) {
|
||||||
let mut w_nav = MODAL_STATE.write().unwrap();
|
let mut w_nav = MODAL_STATE.write().unwrap();
|
||||||
w_nav.modal = Some(modal);
|
w_nav.modal = Some(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove [`Modal`] from [`MODAL_STATE`] if it's showing and can be closed.
|
/// Remove [`Modal`] from [`MODAL_STATE`] if it's showing and can be closed.
|
||||||
|
|
|
@ -134,10 +134,10 @@ impl NetworkSettings {
|
||||||
t!("network_settings.reset_settings"));
|
t!("network_settings.reset_settings"));
|
||||||
View::button(ui, button_text, Colors::GOLD, || {
|
View::button(ui, button_text, Colors::GOLD, || {
|
||||||
// Show modal to confirm settings reset.
|
// Show modal to confirm settings reset.
|
||||||
let reset_modal = Modal::new(Self::RESET_SETTINGS_MODAL)
|
Modal::new(Self::RESET_SETTINGS_MODAL)
|
||||||
.position(ModalPosition::Center)
|
.position(ModalPosition::Center)
|
||||||
.title(t!("modal.confirmation"));
|
.title(t!("modal.confirmation"))
|
||||||
Modal::show(reset_modal);
|
.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show reminder to restart enabled node.
|
// Show reminder to restart enabled node.
|
||||||
|
@ -200,10 +200,10 @@ impl NetworkSettings {
|
||||||
pub fn show_node_restart_required_modal() {
|
pub fn show_node_restart_required_modal() {
|
||||||
if Node::is_running() {
|
if Node::is_running() {
|
||||||
// Show modal to apply changes by node restart.
|
// Show modal to apply changes by node restart.
|
||||||
let port_modal = Modal::new(Self::NODE_RESTART_REQUIRED_MODAL)
|
Modal::new(Self::NODE_RESTART_REQUIRED_MODAL)
|
||||||
.position(ModalPosition::Center)
|
.position(ModalPosition::Center)
|
||||||
.title(t!("network.settings"));
|
.title(t!("network.settings"))
|
||||||
Modal::show(port_modal);
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,10 +113,10 @@ impl DandelionSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.epoch_edit = epoch;
|
self.epoch_edit = epoch;
|
||||||
// Show epoch setup modal.
|
// Show epoch setup modal.
|
||||||
let epoch_modal = Modal::new(Self::EPOCH_MODAL)
|
Modal::new(Self::EPOCH_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(epoch_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -198,11 +198,10 @@ impl DandelionSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.embargo_edit = embargo;
|
self.embargo_edit = embargo;
|
||||||
// Show embargo setup modal.
|
// Show embargo setup modal.
|
||||||
let embargo_modal = Modal::new(Self::EMBARGO_MODAL)
|
Modal::new(Self::EMBARGO_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(embargo_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
}
|
}
|
||||||
|
@ -283,10 +282,10 @@ impl DandelionSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.aggregation_edit = agg;
|
self.aggregation_edit = agg;
|
||||||
// Show aggregation setup modal.
|
// Show aggregation setup modal.
|
||||||
let aggregation_modal = Modal::new(Self::AGGREGATION_MODAL)
|
Modal::new(Self::AGGREGATION_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(aggregation_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -368,10 +367,10 @@ impl DandelionSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.stem_prob_edit = stem_prob;
|
self.stem_prob_edit = stem_prob;
|
||||||
// Show stem probability setup modal.
|
// Show stem probability setup modal.
|
||||||
let embargo_modal = Modal::new(Self::STEM_PROBABILITY_MODAL)
|
Modal::new(Self::STEM_PROBABILITY_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(embargo_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
|
|
@ -221,10 +221,10 @@ impl NodeSetup {
|
||||||
self.api_port_available_edit = self.is_api_port_available;
|
self.api_port_available_edit = self.is_api_port_available;
|
||||||
|
|
||||||
// Show API port modal.
|
// Show API port modal.
|
||||||
let port_modal = Modal::new(Self::API_PORT_MODAL)
|
Modal::new(Self::API_PORT_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(port_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -335,10 +335,10 @@ impl NodeSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.secret_edit = secret_value.unwrap_or("".to_string());
|
self.secret_edit = secret_value.unwrap_or("".to_string());
|
||||||
// Show secret edit modal.
|
// Show secret edit modal.
|
||||||
let port_modal = Modal::new(modal_id)
|
Modal::new(modal_id)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(port_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -455,11 +455,11 @@ impl NodeSetup {
|
||||||
View::button(ui, format!("{} {}", CLOCK_CLOCKWISE, ftl.clone()), Colors::BUTTON, || {
|
View::button(ui, format!("{} {}", CLOCK_CLOCKWISE, ftl.clone()), Colors::BUTTON, || {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.ftl_edit = ftl;
|
self.ftl_edit = ftl;
|
||||||
// Show stratum port modal.
|
// Show ftl value setup modal.
|
||||||
let ftl_modal = Modal::new(Self::FTL_MODAL)
|
Modal::new(Self::FTL_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(ftl_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -478,7 +478,7 @@ impl NodeSetup {
|
||||||
.color(Colors::GRAY));
|
.color(Colors::GRAY));
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
|
|
||||||
// Draw stratum port text edit.
|
// Draw ftl value text edit.
|
||||||
let text_edit_resp = egui::TextEdit::singleline(&mut self.ftl_edit)
|
let text_edit_resp = egui::TextEdit::singleline(&mut self.ftl_edit)
|
||||||
.id(Id::from(modal.id))
|
.id(Id::from(modal.id))
|
||||||
.font(TextStyle::Heading)
|
.font(TextStyle::Heading)
|
||||||
|
|
|
@ -212,15 +212,15 @@ impl P2PSetup {
|
||||||
self.port_edit = port;
|
self.port_edit = port;
|
||||||
self.port_available_edit = self.is_port_available;
|
self.port_available_edit = self.is_port_available;
|
||||||
// Show p2p port modal.
|
// Show p2p port modal.
|
||||||
let port_modal = Modal::new(Self::PORT_MODAL)
|
Modal::new(Self::PORT_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(port_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
|
||||||
// Show error when stratum server port is unavailable.
|
// Show error when p2p port is unavailable.
|
||||||
if !self.is_port_available {
|
if !self.is_port_available {
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
ui.label(RichText::new(t!("network_settings.port_unavailable"))
|
ui.label(RichText::new(t!("network_settings.port_unavailable"))
|
||||||
|
@ -371,10 +371,10 @@ impl P2PSetup {
|
||||||
_ => Self::DNS_SEEDS_TITLE.to_string()
|
_ => Self::DNS_SEEDS_TITLE.to_string()
|
||||||
};
|
};
|
||||||
// Show modal to add peer.
|
// Show modal to add peer.
|
||||||
let peer_modal = Modal::new(modal_id)
|
Modal::new(modal_id)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(modal_title);
|
.title(modal_title)
|
||||||
Modal::show(peer_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -580,10 +580,10 @@ impl P2PSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.ban_window_edit = ban_window;
|
self.ban_window_edit = ban_window;
|
||||||
// Show ban window period setup modal.
|
// Show ban window period setup modal.
|
||||||
let ban_modal = Modal::new(Self::BAN_WINDOW_MODAL)
|
Modal::new(Self::BAN_WINDOW_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(ban_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -671,10 +671,10 @@ impl P2PSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.max_inbound_count = max_inbound;
|
self.max_inbound_count = max_inbound;
|
||||||
// Show maximum number of inbound peers setup modal.
|
// Show maximum number of inbound peers setup modal.
|
||||||
let max_inbound_modal = Modal::new(Self::MAX_INBOUND_MODAL)
|
Modal::new(Self::MAX_INBOUND_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(max_inbound_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -757,10 +757,10 @@ impl P2PSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.max_outbound_count = max_outbound;
|
self.max_outbound_count = max_outbound;
|
||||||
// Show maximum number of outbound peers setup modal.
|
// Show maximum number of outbound peers setup modal.
|
||||||
let max_outbound = Modal::new(Self::MAX_OUTBOUND_MODAL)
|
Modal::new(Self::MAX_OUTBOUND_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(max_outbound);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -843,10 +843,10 @@ impl P2PSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.min_outbound_count = min_outbound;
|
self.min_outbound_count = min_outbound;
|
||||||
// Show maximum number of outbound peers setup modal.
|
// Show maximum number of outbound peers setup modal.
|
||||||
let min_outbound = Modal::new(Self::MIN_OUTBOUND_MODAL)
|
Modal::new(Self::MIN_OUTBOUND_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(min_outbound);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
|
|
@ -115,10 +115,10 @@ impl PoolSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.fee_base_edit = fee;
|
self.fee_base_edit = fee;
|
||||||
// Show fee setup modal.
|
// Show fee setup modal.
|
||||||
let fee_modal = Modal::new(Self::FEE_BASE_MODAL)
|
Modal::new(Self::FEE_BASE_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(fee_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -200,10 +200,10 @@ impl PoolSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.reorg_period_edit = period;
|
self.reorg_period_edit = period;
|
||||||
// Show reorg period setup modal.
|
// Show reorg period setup modal.
|
||||||
let reorg_modal = Modal::new(Self::REORG_PERIOD_MODAL)
|
Modal::new(Self::REORG_PERIOD_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(reorg_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -285,10 +285,10 @@ impl PoolSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.pool_size_edit = size;
|
self.pool_size_edit = size;
|
||||||
// Show pool size setup modal.
|
// Show pool size setup modal.
|
||||||
let size_modal = Modal::new(Self::POOL_SIZE_MODAL)
|
Modal::new(Self::POOL_SIZE_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(size_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -370,10 +370,10 @@ impl PoolSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.stempool_size_edit = size;
|
self.stempool_size_edit = size;
|
||||||
// Show stempool size setup modal.
|
// Show stempool size setup modal.
|
||||||
let stem_modal = Modal::new(Self::STEMPOOL_SIZE_MODAL)
|
Modal::new(Self::STEMPOOL_SIZE_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(stem_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -455,10 +455,10 @@ impl PoolSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.max_weight_edit = weight;
|
self.max_weight_edit = weight;
|
||||||
// Show total tx weight setup modal.
|
// Show total tx weight setup modal.
|
||||||
let weight_modal = Modal::new(Self::MAX_WEIGHT_MODAL)
|
Modal::new(Self::MAX_WEIGHT_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(weight_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
|
|
@ -163,10 +163,10 @@ impl StratumSetup {
|
||||||
self.stratum_port_edit = port;
|
self.stratum_port_edit = port;
|
||||||
self.stratum_port_available_edit = self.is_port_available;
|
self.stratum_port_available_edit = self.is_port_available;
|
||||||
// Show stratum port modal.
|
// Show stratum port modal.
|
||||||
let port_modal = Modal::new(Self::STRATUM_PORT_MODAL)
|
Modal::new(Self::STRATUM_PORT_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(port_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(12.0);
|
ui.add_space(12.0);
|
||||||
|
@ -270,10 +270,10 @@ impl StratumSetup {
|
||||||
self.attempt_time_edit = time;
|
self.attempt_time_edit = time;
|
||||||
|
|
||||||
// Show attempt time modal.
|
// Show attempt time modal.
|
||||||
let time_modal = Modal::new(Self::ATTEMPT_TIME_MODAL)
|
Modal::new(Self::ATTEMPT_TIME_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(time_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -293,7 +293,7 @@ impl StratumSetup {
|
||||||
.color(Colors::GRAY));
|
.color(Colors::GRAY));
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
|
|
||||||
// Draw stratum port text edit.
|
// Draw attempt time text edit.
|
||||||
let text_edit_resp = egui::TextEdit::singleline(&mut self.attempt_time_edit)
|
let text_edit_resp = egui::TextEdit::singleline(&mut self.attempt_time_edit)
|
||||||
.id(Id::from(modal.id))
|
.id(Id::from(modal.id))
|
||||||
.font(TextStyle::Heading)
|
.font(TextStyle::Heading)
|
||||||
|
@ -360,11 +360,11 @@ impl StratumSetup {
|
||||||
// Setup values for modal.
|
// Setup values for modal.
|
||||||
self.min_share_diff_edit = diff;
|
self.min_share_diff_edit = diff;
|
||||||
|
|
||||||
// Show attempt time modal.
|
// Show share difficulty setup modal.
|
||||||
let diff_modal = Modal::new(Self::MIN_SHARE_DIFF_MODAL)
|
Modal::new(Self::MIN_SHARE_DIFF_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("network_settings.change_value"));
|
.title(t!("network_settings.change_value"))
|
||||||
Modal::show(diff_modal);
|
.show();
|
||||||
cb.show_keyboard();
|
cb.show_keyboard();
|
||||||
});
|
});
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
@ -379,7 +379,7 @@ impl StratumSetup {
|
||||||
.color(Colors::GRAY));
|
.color(Colors::GRAY));
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
|
|
||||||
// Draw stratum port text edit.
|
// Draw share difficulty text edit.
|
||||||
let text_edit_resp = egui::TextEdit::singleline(&mut self.min_share_diff_edit)
|
let text_edit_resp = egui::TextEdit::singleline(&mut self.min_share_diff_edit)
|
||||||
.id(Id::from(modal.id))
|
.id(Id::from(modal.id))
|
||||||
.font(TextStyle::Heading)
|
.font(TextStyle::Heading)
|
||||||
|
|
|
@ -142,8 +142,9 @@ impl Root {
|
||||||
|
|
||||||
/// Show exit confirmation modal.
|
/// Show exit confirmation modal.
|
||||||
pub fn show_exit_modal() {
|
pub fn show_exit_modal() {
|
||||||
let exit_modal = Modal::new(Self::EXIT_MODAL_ID).title(t!("modal.confirmation"));
|
Modal::new(Self::EXIT_MODAL_ID)
|
||||||
Modal::show(exit_modal);
|
.title(t!("modal.confirmation"))
|
||||||
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw exit confirmation modal content.
|
/// Draw exit confirmation modal content.
|
||||||
|
|
|
@ -66,11 +66,11 @@ impl Default for WalletCreation {
|
||||||
|
|
||||||
impl WalletCreation {
|
impl WalletCreation {
|
||||||
/// Wallet name/password input modal identifier.
|
/// Wallet name/password input modal identifier.
|
||||||
pub const MODAL_ID: &'static str = "create_wallet_modal";
|
pub const NAME_PASS_MODAL: &'static str = "name_pass_modal";
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||||
// Show wallet creation step description and confirmation panel.
|
// Show wallet creation step description and confirmation bottom panel.
|
||||||
if self.can_go_back() {
|
if self.step.is_some() {
|
||||||
egui::TopBottomPanel::bottom("wallet_creation_step_panel")
|
egui::TopBottomPanel::bottom("wallet_creation_step_panel")
|
||||||
.frame(egui::Frame {
|
.frame(egui::Frame {
|
||||||
stroke: View::DEFAULT_STROKE,
|
stroke: View::DEFAULT_STROKE,
|
||||||
|
@ -85,37 +85,56 @@ impl WalletCreation {
|
||||||
.show_inside(ui, |ui| {
|
.show_inside(ui, |ui| {
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
if let Some(step) = &self.step {
|
if let Some(step) = &self.step {
|
||||||
// Setup step description text.
|
// Setup step description text and availability.
|
||||||
let step_text = match step {
|
let (step_text, step_available) = match step {
|
||||||
Step::EnterMnemonic => {
|
Step::EnterMnemonic => {
|
||||||
let mode = &self.mnemonic_setup.mnemonic.mode;
|
let mode = &self.mnemonic_setup.mnemonic.mode;
|
||||||
let size_value = self.mnemonic_setup.mnemonic.size.value();
|
let size_value = self.mnemonic_setup.mnemonic.size.value();
|
||||||
if mode == &PhraseMode::Generate {
|
let text = if mode == &PhraseMode::Generate {
|
||||||
t!("wallets.create_phrase_desc", "number" => size_value)
|
t!("wallets.create_phrase_desc", "number" => size_value)
|
||||||
} else {
|
} else {
|
||||||
t!("wallets.restore_phrase_desc", "number" => size_value)
|
t!("wallets.restore_phrase_desc", "number" => size_value)
|
||||||
|
};
|
||||||
|
let available = !self
|
||||||
|
.mnemonic_setup
|
||||||
|
.mnemonic
|
||||||
|
.words
|
||||||
|
.contains(&"".to_string());
|
||||||
|
(text, available)
|
||||||
}
|
}
|
||||||
}
|
Step::ConfirmMnemonic => {
|
||||||
Step::ConfirmMnemonic => t!("wallets.conf_phrase_desc"),
|
let text = t!("wallets.restore_phrase_desc");
|
||||||
Step::SetupConnection => t!("wallets.setup_conn_desc")
|
let available = !self
|
||||||
|
.mnemonic_setup
|
||||||
|
.mnemonic
|
||||||
|
.confirm_words
|
||||||
|
.contains(&"".to_string());
|
||||||
|
(text, available)
|
||||||
|
},
|
||||||
|
Step::SetupConnection => (t!("wallets.setup_conn_desc"), true)
|
||||||
};
|
};
|
||||||
// Show step description.
|
// Show step description.
|
||||||
ui.label(RichText::new(step_text).size(16.0).color(Colors::GRAY));
|
ui.label(RichText::new(step_text).size(16.0).color(Colors::GRAY));
|
||||||
ui.add_space(4.0);
|
|
||||||
|
|
||||||
// Setup next step button text.
|
// Show next step button if there are no empty words.
|
||||||
|
|
||||||
|
if step_available {
|
||||||
|
// Setup button text.
|
||||||
let (next_text, color) = if step == &Step::SetupConnection {
|
let (next_text, color) = if step == &Step::SetupConnection {
|
||||||
(format!("{} {}", CHECK, t!("complete")), Colors::GOLD)
|
(format!("{} {}", CHECK, t!("complete")), Colors::GOLD)
|
||||||
} else {
|
} else {
|
||||||
let text = format!("{} {}", SHARE_FAT, t!("continue"));
|
let text = format!("{} {}", SHARE_FAT, t!("continue"));
|
||||||
(text, Colors::WHITE)
|
(text, Colors::WHITE)
|
||||||
};
|
};
|
||||||
// Show next step button.
|
|
||||||
|
ui.add_space(4.0);
|
||||||
|
// Show button.
|
||||||
View::button(ui, next_text.to_uppercase(), color, || {
|
View::button(ui, next_text.to_uppercase(), color, || {
|
||||||
self.forward();
|
self.forward();
|
||||||
});
|
});
|
||||||
ui.add_space(4.0);
|
ui.add_space(4.0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -165,16 +184,18 @@ impl WalletCreation {
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
let add_text = format!("{} {}", PLUS_CIRCLE, t!("wallets.add"));
|
let add_text = format!("{} {}", PLUS_CIRCLE, t!("wallets.add"));
|
||||||
View::button(ui, add_text, Colors::BUTTON, || {
|
View::button(ui, add_text, Colors::BUTTON, || {
|
||||||
Self::show_modal();
|
self.show_name_pass_modal();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some(step) => {
|
Some(step) => {
|
||||||
match step {
|
match step {
|
||||||
Step::EnterMnemonic => {
|
Step::EnterMnemonic => {
|
||||||
self.mnemonic_setup.enter_ui(ui, cb);
|
self.mnemonic_setup.ui(ui);
|
||||||
|
}
|
||||||
|
Step::ConfirmMnemonic => {
|
||||||
|
self.mnemonic_setup.confirm_ui(ui);
|
||||||
}
|
}
|
||||||
Step::ConfirmMnemonic => {}
|
|
||||||
Step::SetupConnection => {}
|
Step::SetupConnection => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,10 +251,17 @@ impl WalletCreation {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start wallet creation from showing [`Modal`] to enter name and password.
|
/// Start wallet creation from showing [`Modal`] to enter name and password.
|
||||||
pub fn show_modal() {
|
pub fn show_name_pass_modal(&mut self) {
|
||||||
Modal::show(Modal::new(Self::MODAL_ID)
|
// Reset modal values.
|
||||||
|
self.hide_pass = false;
|
||||||
|
self.modal_just_opened = true;
|
||||||
|
self.name_edit = "".to_string();
|
||||||
|
self.pass_edit = "".to_string();
|
||||||
|
// Show modal.
|
||||||
|
Modal::new(Self::NAME_PASS_MODAL)
|
||||||
.position(ModalPosition::CenterTop)
|
.position(ModalPosition::CenterTop)
|
||||||
.title(t!("wallets.add")));
|
.title(t!("wallets.add"))
|
||||||
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw wallet creation [`Modal`] content.
|
/// Draw wallet creation [`Modal`] content.
|
||||||
|
@ -332,11 +360,6 @@ impl WalletCreation {
|
||||||
ui.columns(2, |columns| {
|
ui.columns(2, |columns| {
|
||||||
columns[0].vertical_centered_justified(|ui| {
|
columns[0].vertical_centered_justified(|ui| {
|
||||||
View::button(ui, t!("modal.cancel"), Colors::WHITE, || {
|
View::button(ui, t!("modal.cancel"), Colors::WHITE, || {
|
||||||
// Clear values.
|
|
||||||
self.hide_pass = false;
|
|
||||||
self.modal_just_opened = true;
|
|
||||||
self.name_edit = "".to_string();
|
|
||||||
self.pass_edit = "".to_string();
|
|
||||||
// Close modal.
|
// Close modal.
|
||||||
cb.hide_keyboard();
|
cb.hide_keyboard();
|
||||||
modal.close();
|
modal.close();
|
||||||
|
|
|
@ -12,35 +12,46 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use egui::{RichText, ScrollArea};
|
use egui::{Id, RichText, ScrollArea, TextStyle, Widget};
|
||||||
|
|
||||||
use crate::gui::Colors;
|
use crate::gui::Colors;
|
||||||
use crate::gui::icons::PENCIL;
|
use crate::gui::icons::PENCIL;
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
use crate::gui::views::{Root, View};
|
use crate::gui::views::{Modal, ModalPosition, Root, View};
|
||||||
use crate::gui::views::wallets::creation::types::{Mnemonic, PhraseMode, PhraseSize};
|
use crate::gui::views::wallets::creation::types::{Mnemonic, PhraseMode, PhraseSize};
|
||||||
|
|
||||||
/// Mnemonic phrase setup content.
|
/// Mnemonic phrase setup content.
|
||||||
pub struct MnemonicSetup {
|
pub struct MnemonicSetup {
|
||||||
/// Current mnemonic phrase.
|
/// Current mnemonic phrase.
|
||||||
pub(crate) mnemonic: Mnemonic,
|
pub(crate) mnemonic: Mnemonic,
|
||||||
/// Word value for [`Modal`].
|
|
||||||
|
/// Current word number to edit at [`Modal`].
|
||||||
|
word_num_edit: usize,
|
||||||
|
/// Entered word value for [`Modal`].
|
||||||
word_edit: String,
|
word_edit: String,
|
||||||
|
/// Flag to check if entered word is valid.
|
||||||
|
valid_word_edit: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MnemonicSetup {
|
impl Default for MnemonicSetup {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
mnemonic: Mnemonic::default(),
|
mnemonic: Mnemonic::default(),
|
||||||
|
word_num_edit: 0,
|
||||||
word_edit: "".to_string(),
|
word_edit: "".to_string(),
|
||||||
|
valid_word_edit: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MnemonicSetup {
|
impl MnemonicSetup {
|
||||||
pub fn enter_ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
/// Identifier for word input [`Modal`].
|
||||||
|
pub const WORD_INPUT_MODAL: &'static str = "word_input_modal";
|
||||||
|
|
||||||
|
/// Draw content for input step.
|
||||||
|
pub fn ui(&mut self, ui: &mut egui::Ui) {
|
||||||
ScrollArea::vertical()
|
ScrollArea::vertical()
|
||||||
.id_source("mnemonic_words_list")
|
.id_source("input_mnemonic_words_list")
|
||||||
.auto_shrink([false; 2])
|
.auto_shrink([false; 2])
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
ui.add_space(10.0);
|
ui.add_space(10.0);
|
||||||
|
@ -53,7 +64,23 @@ impl MnemonicSetup {
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
|
||||||
// Show words setup.
|
// Show words setup.
|
||||||
self.word_list_ui(ui);
|
self.word_list_ui(ui, self.mnemonic.mode == PhraseMode::Import);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Draw content for confirmation step.
|
||||||
|
pub fn confirm_ui(&mut self, ui: &mut egui::Ui) {
|
||||||
|
ui.add_space(4.0);
|
||||||
|
ui.vertical_centered(|ui| {
|
||||||
|
ui.label(RichText::new(t!("wallets.saved_phrase")).size(16.0).color(Colors::GRAY));
|
||||||
|
});
|
||||||
|
ui.add_space(6.0);
|
||||||
|
ScrollArea::vertical()
|
||||||
|
.id_source("confirm_mnemonic_words_list")
|
||||||
|
.auto_shrink([false; 2])
|
||||||
|
.show(ui, |ui| {
|
||||||
|
// Show words setup.
|
||||||
|
self.word_list_ui(ui, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,39 +116,191 @@ impl MnemonicSetup {
|
||||||
// Show mnemonic phrase size setup.
|
// Show mnemonic phrase size setup.
|
||||||
let mut size = self.mnemonic.size.clone();
|
let mut size = self.mnemonic.size.clone();
|
||||||
ui.columns(5, |columns| {
|
ui.columns(5, |columns| {
|
||||||
columns[0].vertical_centered(|ui| {
|
for (index, word) in PhraseSize::VALUES.iter().enumerate() {
|
||||||
let words12 = PhraseSize::Words12;
|
columns[index].vertical_centered(|ui| {
|
||||||
let text = words12.value().to_string();
|
let text = word.value().to_string();
|
||||||
View::radio_value(ui, &mut size, words12, text);
|
View::radio_value(ui, &mut size, word.clone(), text);
|
||||||
});
|
|
||||||
columns[1].vertical_centered(|ui| {
|
|
||||||
let words15 = PhraseSize::Words15;
|
|
||||||
let text = words15.value().to_string();
|
|
||||||
View::radio_value(ui, &mut size, words15, text);
|
|
||||||
});
|
|
||||||
columns[2].vertical_centered(|ui| {
|
|
||||||
let words18 = PhraseSize::Words18;
|
|
||||||
let text = words18.value().to_string();
|
|
||||||
View::radio_value(ui, &mut size, words18, text);
|
|
||||||
});
|
|
||||||
columns[3].vertical_centered(|ui| {
|
|
||||||
let words21 = PhraseSize::Words21;
|
|
||||||
let text = words21.value().to_string();
|
|
||||||
View::radio_value(ui, &mut size, words21, text);
|
|
||||||
});
|
|
||||||
columns[4].vertical_centered(|ui| {
|
|
||||||
let words24 = PhraseSize::Words24;
|
|
||||||
let text = words24.value().to_string();
|
|
||||||
View::radio_value(ui, &mut size, words24, text);
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if size != self.mnemonic.size {
|
if size != self.mnemonic.size {
|
||||||
self.mnemonic.set_size(size);
|
self.mnemonic.set_size(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate word list columns count based on available ui width.
|
/// Draw list of words for mnemonic phrase.
|
||||||
fn calc_columns_count(ui: &mut egui::Ui) -> usize {
|
fn word_list_ui(&mut self, ui: &mut egui::Ui, edit_words: bool) {
|
||||||
|
ui.add_space(6.0);
|
||||||
|
ui.scope(|ui| {
|
||||||
|
// Setup spacing between columns.
|
||||||
|
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 6.0);
|
||||||
|
|
||||||
|
// Select list of words based on current mode and edit flag.
|
||||||
|
let words = match self.mnemonic.mode {
|
||||||
|
PhraseMode::Generate => {
|
||||||
|
if edit_words {
|
||||||
|
self.mnemonic.confirm_words.clone()
|
||||||
|
} else {
|
||||||
|
self.mnemonic.words.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PhraseMode::Import => self.mnemonic.words.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut word_number = 0;
|
||||||
|
let cols = list_columns_count(ui);
|
||||||
|
let _ = words.chunks(cols).map(|chunk| {
|
||||||
|
let size = chunk.len();
|
||||||
|
word_number += 1;
|
||||||
|
if size > 1 {
|
||||||
|
ui.columns(cols, |columns| {
|
||||||
|
columns[0].horizontal(|ui| {
|
||||||
|
let word = chunk.get(0).unwrap();
|
||||||
|
self.word_item_ui(ui, word_number, word, edit_words);
|
||||||
|
});
|
||||||
|
columns[1].horizontal(|ui| {
|
||||||
|
word_number += 1;
|
||||||
|
let word = chunk.get(1).unwrap();
|
||||||
|
self.word_item_ui(ui, word_number, word, edit_words);
|
||||||
|
});
|
||||||
|
if size > 2 {
|
||||||
|
columns[2].horizontal(|ui| {
|
||||||
|
word_number += 1;
|
||||||
|
let word = chunk.get(2).unwrap();
|
||||||
|
self.word_item_ui(ui, word_number, word, edit_words);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if size > 3 {
|
||||||
|
columns[3].horizontal(|ui| {
|
||||||
|
word_number += 1;
|
||||||
|
let word = chunk.get(3).unwrap();
|
||||||
|
self.word_item_ui(ui, word_number, word, edit_words);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ui.columns(cols, |columns| {
|
||||||
|
columns[0].horizontal(|ui| {
|
||||||
|
let word = chunk.get(0).unwrap();
|
||||||
|
self.word_item_ui(ui, word_number, word, edit_words);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
});
|
||||||
|
ui.add_space(6.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Draw word list item for current mode.
|
||||||
|
fn word_item_ui(&mut self, ui: &mut egui::Ui, word_number: usize, word: &String, edit: bool) {
|
||||||
|
if edit {
|
||||||
|
ui.add_space(6.0);
|
||||||
|
View::button(ui, PENCIL.to_string(), Colors::BUTTON, || {
|
||||||
|
// Setup modal values.
|
||||||
|
self.word_num_edit = word_number;
|
||||||
|
self.word_edit = word.clone();
|
||||||
|
self.valid_word_edit = true;
|
||||||
|
// Show word edit modal.
|
||||||
|
Modal::new(MnemonicSetup::WORD_INPUT_MODAL)
|
||||||
|
.position(ModalPosition::CenterTop)
|
||||||
|
.title(t!("wallets.saved_phrase"))
|
||||||
|
.show();
|
||||||
|
});
|
||||||
|
ui.label(RichText::new(format!("#{} {}", word_number, word))
|
||||||
|
.size(17.0)
|
||||||
|
.color(Colors::BLACK));
|
||||||
|
} else {
|
||||||
|
ui.add_space(12.0);
|
||||||
|
let text = format!("#{} {}", word_number, word);
|
||||||
|
ui.label(RichText::new(text).size(17.0).color(Colors::BLACK));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset mnemonic phrase to default values.
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.mnemonic = Mnemonic::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Show word input [`Modal`] content.
|
||||||
|
pub fn modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {
|
||||||
|
ui.add_space(6.0);
|
||||||
|
ui.vertical_centered(|ui| {
|
||||||
|
ui.label(RichText::new(t!("wallets.enter_word", "number" => self.word_num_edit))
|
||||||
|
.size(17.0)
|
||||||
|
.color(Colors::GRAY));
|
||||||
|
ui.add_space(8.0);
|
||||||
|
|
||||||
|
// Draw word value text edit.
|
||||||
|
let text_edit_resp = egui::TextEdit::singleline(&mut self.word_edit)
|
||||||
|
.id(Id::from(format!("{}{}", modal.id, self.word_num_edit)))
|
||||||
|
.font(TextStyle::Heading)
|
||||||
|
.desired_width(ui.available_width())
|
||||||
|
.cursor_at_end(true)
|
||||||
|
.ui(ui);
|
||||||
|
text_edit_resp.request_focus();
|
||||||
|
if text_edit_resp.clicked() {
|
||||||
|
cb.show_keyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show error when specified word is not valid.
|
||||||
|
if !self.valid_word_edit {
|
||||||
|
ui.add_space(12.0);
|
||||||
|
ui.label(RichText::new(t!("wallets.not_valid_word"))
|
||||||
|
.size(17.0)
|
||||||
|
.color(Colors::RED));
|
||||||
|
}
|
||||||
|
ui.add_space(12.0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show modal buttons.
|
||||||
|
ui.scope(|ui| {
|
||||||
|
// Setup spacing between buttons.
|
||||||
|
ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0);
|
||||||
|
|
||||||
|
ui.columns(2, |columns| {
|
||||||
|
columns[0].vertical_centered_justified(|ui| {
|
||||||
|
View::button(ui, t!("modal.cancel"), Colors::WHITE, || {
|
||||||
|
// Close modal.
|
||||||
|
cb.hide_keyboard();
|
||||||
|
modal.close();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
columns[1].vertical_centered_justified(|ui| {
|
||||||
|
View::button(ui, t!("continue"), Colors::WHITE, || {
|
||||||
|
// Check if word is valid.
|
||||||
|
let word_index = self.word_num_edit - 1;
|
||||||
|
if !self.mnemonic.is_valid_word(&self.word_edit, word_index) {
|
||||||
|
self.valid_word_edit = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Select list where to save word.
|
||||||
|
let words = match self.mnemonic.mode {
|
||||||
|
PhraseMode::Generate => &mut self.mnemonic.confirm_words,
|
||||||
|
PhraseMode::Import => &mut self.mnemonic.words
|
||||||
|
};
|
||||||
|
// Save word at list.
|
||||||
|
words.remove(word_index);
|
||||||
|
words.insert(word_index, self.word_edit.clone());
|
||||||
|
// Close modal or go to next word to edit.
|
||||||
|
let close_modal = words.len() == self.word_num_edit
|
||||||
|
|| !words.get(self.word_num_edit).unwrap().is_empty();
|
||||||
|
if close_modal {
|
||||||
|
cb.hide_keyboard();
|
||||||
|
modal.close();
|
||||||
|
} else {
|
||||||
|
self.word_num_edit += 1;
|
||||||
|
self.word_edit = "".to_string();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ui.add_space(6.0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculate word list columns count based on available ui width.
|
||||||
|
fn list_columns_count(ui: &mut egui::Ui) -> usize {
|
||||||
let w = ui.available_width();
|
let w = ui.available_width();
|
||||||
let min_panel_w = Root::SIDE_PANEL_MIN_WIDTH - 12.0;
|
let min_panel_w = Root::SIDE_PANEL_MIN_WIDTH - 12.0;
|
||||||
let double_min_panel_w = min_panel_w * 2.0;
|
let double_min_panel_w = min_panel_w * 2.0;
|
||||||
|
@ -132,87 +311,4 @@ impl MnemonicSetup {
|
||||||
} else {
|
} else {
|
||||||
2
|
2
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw word list for mnemonic phrase.
|
|
||||||
fn word_list_ui(&self, ui: &mut egui::Ui) {
|
|
||||||
ui.scope(|ui| {
|
|
||||||
// Setup spacing between columns.
|
|
||||||
ui.spacing_mut().item_spacing = egui::Vec2::new(6.0, 6.0);
|
|
||||||
|
|
||||||
if self.mnemonic.mode == PhraseMode::Generate {
|
|
||||||
ui.add_space(6.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut word_number = 0;
|
|
||||||
let cols = Self::calc_columns_count(ui);
|
|
||||||
let _ = self.mnemonic.words.chunks(cols).map(|chunk| {
|
|
||||||
let size = chunk.len();
|
|
||||||
word_number += 1;
|
|
||||||
if size > 1 {
|
|
||||||
ui.columns(cols, |columns| {
|
|
||||||
columns[0].horizontal(|ui| {
|
|
||||||
self.word_item_ui(ui, word_number, chunk, 0);
|
|
||||||
});
|
|
||||||
columns[1].horizontal(|ui| {
|
|
||||||
word_number += 1;
|
|
||||||
self.word_item_ui(ui, word_number, chunk, 1);
|
|
||||||
});
|
|
||||||
if size > 2 {
|
|
||||||
columns[2].horizontal(|ui| {
|
|
||||||
word_number += 1;
|
|
||||||
self.word_item_ui(ui, word_number, chunk, 2);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if size > 3 {
|
|
||||||
columns[3].horizontal(|ui| {
|
|
||||||
word_number += 1;
|
|
||||||
self.word_item_ui(ui, word_number, chunk, 3);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ui.columns(cols, |columns| {
|
|
||||||
columns[0].horizontal(|ui| {
|
|
||||||
self.word_item_ui(ui, word_number, chunk, 0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
ui.add_space(12.0);
|
|
||||||
}
|
|
||||||
}).collect::<Vec<_>>();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw word item at given index from provided chunk.
|
|
||||||
fn word_item_ui(&self,
|
|
||||||
ui: &mut egui::Ui,
|
|
||||||
word_number: usize,
|
|
||||||
chunk: &[String],
|
|
||||||
index: usize) {
|
|
||||||
match self.mnemonic.mode {
|
|
||||||
PhraseMode::Generate => {
|
|
||||||
ui.add_space(12.0);
|
|
||||||
let word = chunk.get(index).unwrap();
|
|
||||||
let text = format!("#{} {}", word_number, word);
|
|
||||||
ui.label(RichText::new(text).size(17.0).color(Colors::BLACK));
|
|
||||||
}
|
|
||||||
PhraseMode::Import => {
|
|
||||||
let mut size = ui.available_size();
|
|
||||||
size.x = 90.0;
|
|
||||||
ui.allocate_ui(size, |ui| {
|
|
||||||
View::button(ui, PENCIL.to_string(), Colors::BUTTON, || {
|
|
||||||
//TODO: open modal
|
|
||||||
});
|
|
||||||
});
|
|
||||||
ui.label(RichText::new(format!("#{}", word_number))
|
|
||||||
.size(17.0)
|
|
||||||
.color(Colors::BLACK));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reset mnemonic phrase to default values.
|
|
||||||
pub fn reset(&mut self) {
|
|
||||||
self.mnemonic = Mnemonic::default();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use grin_keychain::mnemonic::from_entropy;
|
use grin_keychain::mnemonic::{from_entropy, search};
|
||||||
use rand::{Rng, thread_rng};
|
use rand::{Rng, thread_rng};
|
||||||
|
|
||||||
/// Wallet creation step.
|
/// Wallet creation step.
|
||||||
|
@ -20,7 +20,7 @@ use rand::{Rng, thread_rng};
|
||||||
pub enum Step {
|
pub enum Step {
|
||||||
/// Mnemonic phrase input.
|
/// Mnemonic phrase input.
|
||||||
EnterMnemonic,
|
EnterMnemonic,
|
||||||
/// Mnemonic phrase confirmation for [`Mnemonic`].
|
/// Mnemonic phrase confirmation.
|
||||||
ConfirmMnemonic,
|
ConfirmMnemonic,
|
||||||
/// Wallet connection setup.
|
/// Wallet connection setup.
|
||||||
SetupConnection
|
SetupConnection
|
||||||
|
@ -40,6 +40,14 @@ pub enum PhraseMode {
|
||||||
pub enum PhraseSize { Words12, Words15, Words18, Words21, Words24 }
|
pub enum PhraseSize { Words12, Words15, Words18, Words21, Words24 }
|
||||||
|
|
||||||
impl PhraseSize {
|
impl PhraseSize {
|
||||||
|
pub const VALUES: [PhraseSize; 5] = [
|
||||||
|
PhraseSize::Words12,
|
||||||
|
PhraseSize::Words15,
|
||||||
|
PhraseSize::Words18,
|
||||||
|
PhraseSize::Words21,
|
||||||
|
PhraseSize::Words24
|
||||||
|
];
|
||||||
|
|
||||||
/// Gen words count number.
|
/// Gen words count number.
|
||||||
pub fn value(&self) -> usize {
|
pub fn value(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -69,8 +77,10 @@ pub struct Mnemonic {
|
||||||
pub(crate) mode: PhraseMode,
|
pub(crate) mode: PhraseMode,
|
||||||
/// Size of phrase based on words count.
|
/// Size of phrase based on words count.
|
||||||
pub(crate) size: PhraseSize,
|
pub(crate) size: PhraseSize,
|
||||||
/// Words for phrase.
|
/// Generated words.
|
||||||
pub(crate) words: Vec<String>
|
pub(crate) words: Vec<String>,
|
||||||
|
/// Words to confirm the phrase.
|
||||||
|
pub(crate) confirm_words: Vec<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Mnemonic {
|
impl Default for Mnemonic {
|
||||||
|
@ -78,7 +88,8 @@ impl Default for Mnemonic {
|
||||||
let size = PhraseSize::Words24;
|
let size = PhraseSize::Words24;
|
||||||
let mode = PhraseMode::Generate;
|
let mode = PhraseMode::Generate;
|
||||||
let words = Self::generate_words(&mode, &size);
|
let words = Self::generate_words(&mode, &size);
|
||||||
Self { mode, size, words }
|
let confirm_words = Self::empty_words(&size);
|
||||||
|
Self { mode, size, words, confirm_words }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,15 +98,28 @@ impl Mnemonic {
|
||||||
pub fn set_mode(&mut self, mode: PhraseMode) {
|
pub fn set_mode(&mut self, mode: PhraseMode) {
|
||||||
self.mode = mode;
|
self.mode = mode;
|
||||||
self.words = Self::generate_words(&self.mode, &self.size);
|
self.words = Self::generate_words(&self.mode, &self.size);
|
||||||
|
self.confirm_words = Self::empty_words(&self.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change mnemonic phrase words [`PhraseSize`].
|
/// Change mnemonic phrase words [`PhraseSize`].
|
||||||
pub fn set_size(&mut self, size: PhraseSize) {
|
pub fn set_size(&mut self, size: PhraseSize) {
|
||||||
self.size = size;
|
self.size = size;
|
||||||
self.words = Self::generate_words(&self.mode, &self.size);
|
self.words = Self::generate_words(&self.mode, &self.size);
|
||||||
|
self.confirm_words = Self::empty_words(&self.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Setup words based on provided [`PhraseMode`] and [`PhraseSize`].
|
/// Check if provided word is in BIP39 format and equal to non-empty generated word at index.
|
||||||
|
pub fn is_valid_word(&self, word: &String, index: usize) -> bool {
|
||||||
|
let valid = search(word).is_ok();
|
||||||
|
let equal = if let Some(gen_word) = self.words.get(index) {
|
||||||
|
gen_word.is_empty() || gen_word == word
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
valid && equal
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate list of words based on provided [`PhraseMode`] and [`PhraseSize`].
|
||||||
fn generate_words(mode: &PhraseMode, size: &PhraseSize) -> Vec<String> {
|
fn generate_words(mode: &PhraseMode, size: &PhraseSize) -> Vec<String> {
|
||||||
match mode {
|
match mode {
|
||||||
PhraseMode::Generate => {
|
PhraseMode::Generate => {
|
||||||
|
@ -110,12 +134,17 @@ impl Mnemonic {
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
},
|
},
|
||||||
PhraseMode::Import => {
|
PhraseMode::Import => {
|
||||||
|
Self::empty_words(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate empty list of words based on provided [`PhraseSize`].
|
||||||
|
fn empty_words(size: &PhraseSize) -> Vec<String> {
|
||||||
let mut words = Vec::with_capacity(size.value());
|
let mut words = Vec::with_capacity(size.value());
|
||||||
for _ in 0..size.value() {
|
for _ in 0..size.value() {
|
||||||
words.push("".to_string())
|
words.push("".to_string())
|
||||||
}
|
}
|
||||||
words
|
words
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ use crate::gui::Colors;
|
||||||
use crate::gui::icons::{ARROW_LEFT, GEAR, GLOBE, PLUS};
|
use crate::gui::icons::{ARROW_LEFT, GEAR, GLOBE, PLUS};
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
use crate::gui::views::{Modal, ModalContainer, Root, TitlePanel, TitleType, View};
|
use crate::gui::views::{Modal, ModalContainer, Root, TitlePanel, TitleType, View};
|
||||||
use crate::gui::views::wallets::creation::WalletCreation;
|
use crate::gui::views::wallets::creation::{MnemonicSetup, WalletCreation};
|
||||||
use crate::gui::views::wallets::wallet::WalletContent;
|
use crate::gui::views::wallets::wallet::WalletContent;
|
||||||
|
|
||||||
/// Wallets content.
|
/// Wallets content.
|
||||||
|
@ -45,7 +45,8 @@ impl Default for Wallets {
|
||||||
item_content: None,
|
item_content: None,
|
||||||
creation_content: WalletCreation::default(),
|
creation_content: WalletCreation::default(),
|
||||||
modal_ids: vec![
|
modal_ids: vec![
|
||||||
WalletCreation::MODAL_ID
|
WalletCreation::NAME_PASS_MODAL,
|
||||||
|
MnemonicSetup::WORD_INPUT_MODAL
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +64,12 @@ impl Wallets {
|
||||||
if self.can_draw_modal() {
|
if self.can_draw_modal() {
|
||||||
Modal::ui(ui, |ui, modal| {
|
Modal::ui(ui, |ui, modal| {
|
||||||
match modal.id {
|
match modal.id {
|
||||||
WalletCreation::MODAL_ID => self.creation_content.modal_ui(ui, modal, cb),
|
WalletCreation::NAME_PASS_MODAL => {
|
||||||
|
self.creation_content.modal_ui(ui, modal, cb);
|
||||||
|
},
|
||||||
|
MnemonicSetup::WORD_INPUT_MODAL => {
|
||||||
|
self.creation_content.mnemonic_setup.modal_ui(ui, modal, cb);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -72,9 +78,9 @@ impl Wallets {
|
||||||
// Show title panel.
|
// Show title panel.
|
||||||
self.title_ui(ui, frame);
|
self.title_ui(ui, frame);
|
||||||
|
|
||||||
// Show wallet content.
|
|
||||||
let is_wallet_panel_open = Self::is_dual_panel_mode(ui, frame) || self.list.is_empty();
|
let is_wallet_panel_open = Self::is_dual_panel_mode(ui, frame) || self.list.is_empty();
|
||||||
let wallet_panel_width = self.wallet_panel_width(ui, frame);
|
let wallet_panel_width = self.wallet_panel_width(ui, frame);
|
||||||
|
// Show wallet content.
|
||||||
egui::SidePanel::right("wallet_panel")
|
egui::SidePanel::right("wallet_panel")
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
.min_width(wallet_panel_width)
|
.min_width(wallet_panel_width)
|
||||||
|
@ -105,7 +111,7 @@ impl Wallets {
|
||||||
});
|
});
|
||||||
// Show wallet creation button if wallet panel is not open.
|
// Show wallet creation button if wallet panel is not open.
|
||||||
if !is_wallet_panel_open {
|
if !is_wallet_panel_open {
|
||||||
self.add_wallet_btn_ui(ui);
|
self.create_wallet_btn_ui(ui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +120,7 @@ impl Wallets {
|
||||||
fn title_ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
|
fn title_ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
|
||||||
// Setup title text.
|
// Setup title text.
|
||||||
let title_text = if self.creation_content.can_go_back() {
|
let title_text = if self.creation_content.can_go_back() {
|
||||||
t!("wallets.new")
|
t!("wallets.add")
|
||||||
} else {
|
} else {
|
||||||
t!("wallets.title")
|
t!("wallets.title")
|
||||||
};
|
};
|
||||||
|
@ -178,7 +184,7 @@ impl Wallets {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw floating button to create the wallet.
|
/// Draw floating button to create the wallet.
|
||||||
fn add_wallet_btn_ui(&self, ui: &mut egui::Ui) {
|
fn create_wallet_btn_ui(&mut self, ui: &mut egui::Ui) {
|
||||||
egui::Window::new("create_wallet_button")
|
egui::Window::new("create_wallet_button")
|
||||||
.title_bar(false)
|
.title_bar(false)
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
|
@ -187,7 +193,7 @@ impl Wallets {
|
||||||
.frame(egui::Frame::default())
|
.frame(egui::Frame::default())
|
||||||
.show(ui.ctx(), |ui| {
|
.show(ui.ctx(), |ui| {
|
||||||
View::round_button(ui, PLUS, || {
|
View::round_button(ui, PLUS, || {
|
||||||
WalletCreation::show_modal();
|
self.creation_content.show_name_pass_modal();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue