-
Notifications
You must be signed in to change notification settings - Fork 63
improved layout of verification modal #950
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,6 +10,32 @@ script_mod! { | |||||||||
| use mod.widgets.* | ||||||||||
|
|
||||||||||
|
|
||||||||||
| mod.widgets.VerificationEmojiCell = View { | ||||||||||
| width: Fit, height: Fit | ||||||||||
| flow: Down | ||||||||||
| align: Align{x: 0.5} | ||||||||||
| padding: Inset{top: 6, right: 6, bottom: 6, left: 6} | ||||||||||
| spacing: 4 | ||||||||||
|
|
||||||||||
| symbol := Label { | ||||||||||
| width: Fit, height: Fit | ||||||||||
| align: Align{x: 0.5} | ||||||||||
| draw_text +: { | ||||||||||
| text_style: REGULAR_TEXT {font_size: 30}, | ||||||||||
| color: #000 | ||||||||||
| } | ||||||||||
| } | ||||||||||
| description := Label { | ||||||||||
| width: Fit{max: FitBound.Abs(72.0)}, height: Fit | ||||||||||
| flow: Flow.Right{wrap: true} | ||||||||||
| align: Align{x: 0.5} | ||||||||||
| draw_text +: { | ||||||||||
| text_style: REGULAR_TEXT {font_size: 9}, | ||||||||||
| color: #000 | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| mod.widgets.VerificationModal = set_type_default() do #(VerificationModal::register_widget(vm)) { | ||||||||||
| ..mod.widgets.SmallModal | ||||||||||
|
|
||||||||||
|
|
@@ -19,6 +45,24 @@ script_mod! { | |||||||||
|
|
||||||||||
| body := ModalBody {} | ||||||||||
|
|
||||||||||
| // SAS V1 always produces exactly 7 emojis, so 7 cells are declared up front. | ||||||||||
| emojis_view := View { | ||||||||||
| width: Fill, height: Fit | ||||||||||
| flow: Flow.Right{wrap: true} | ||||||||||
| align: Align{x: 0.5} | ||||||||||
| spacing: 10 | ||||||||||
| margin: Inset{top: 15, bottom: 5} | ||||||||||
| visible: false | ||||||||||
|
|
||||||||||
| emoji0 := mod.widgets.VerificationEmojiCell {} | ||||||||||
| emoji1 := mod.widgets.VerificationEmojiCell {} | ||||||||||
| emoji2 := mod.widgets.VerificationEmojiCell {} | ||||||||||
| emoji3 := mod.widgets.VerificationEmojiCell {} | ||||||||||
| emoji4 := mod.widgets.VerificationEmojiCell {} | ||||||||||
| emoji5 := mod.widgets.VerificationEmojiCell {} | ||||||||||
| emoji6 := mod.widgets.VerificationEmojiCell {} | ||||||||||
| } | ||||||||||
|
|
||||||||||
| buttons_view := ModalButtonsRow { | ||||||||||
| margin: Inset{top: 30} | ||||||||||
|
|
||||||||||
|
|
@@ -111,6 +155,10 @@ impl WidgetMatchEvent for VerificationModal { | |||||||||
| // Outgoing verification requests start with the accept button hidden | ||||||||||
| // since we're still in the waiting state then, so show it now | ||||||||||
| accept_button.set_visible(cx, true); | ||||||||||
| // The emoji grid is only relevant during the `KeysExchanged` emoji | ||||||||||
| // step; hide it by default and let that branch re-show it, so it | ||||||||||
| // never leaks into other states. | ||||||||||
|
Comment on lines
+158
to
+160
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please don't use LLM-style comments. This can be really simple.
Suggested change
|
||||||||||
| self.view.view(cx, ids!(emojis_view)).set_visible(cx, false); | ||||||||||
| match verification_action { | ||||||||||
| VerificationAction::RequestCancelled(cancel_info) => { | ||||||||||
| self.label(cx, ids!(body)).set_text( | ||||||||||
|
|
@@ -193,26 +241,25 @@ impl WidgetMatchEvent for VerificationModal { | |||||||||
| } | ||||||||||
|
|
||||||||||
| VerificationAction::KeysExchanged { emojis, decimals } => { | ||||||||||
| let text = if let Some(emoji_list) = emojis { | ||||||||||
| format!( | ||||||||||
| "Keys have been exchanged. Please verify the following emoji:\ | ||||||||||
| \n {}\n\n\ | ||||||||||
| if let Some(emoji_list) = emojis { | ||||||||||
| self.label(cx, ids!(body)).set_text( | ||||||||||
| cx, | ||||||||||
| "Keys have been exchanged. Please verify the following emoji:\n\n\ | ||||||||||
| Do these emoji keys match?", | ||||||||||
| emoji_list.emojis | ||||||||||
| .iter() | ||||||||||
| .map(|em| format!("{} ({})", em.symbol, em.description)) | ||||||||||
| .collect::<Vec<_>>() | ||||||||||
| .join("\n ") | ||||||||||
| ) | ||||||||||
| ); | ||||||||||
| for (index, emoji) in emoji_list.emojis.iter().enumerate() { | ||||||||||
| self.populate_emoji_cell(cx, index, emoji.symbol, emoji.description); | ||||||||||
| } | ||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is better than the previous C-style loop that you had before, but we can do even better than this with Rust. Check out the Once you see how that works, you'll recognize that you can also easily move the body of |
||||||||||
| self.view.view(cx, ids!(emojis_view)).set_visible(cx, true); | ||||||||||
| } else { | ||||||||||
| format!( | ||||||||||
| let text = format!( | ||||||||||
| "Keys have been exchanged. Please verify the following numbers:\n\ | ||||||||||
| \n {}\n {}\n {}\n\n\ | ||||||||||
| Do these number keys match?", | ||||||||||
| decimals.0, decimals.1, decimals.2, | ||||||||||
| ) | ||||||||||
| }; | ||||||||||
| self.label(cx, ids!(body)).set_text(cx, &text); | ||||||||||
| ); | ||||||||||
| self.label(cx, ids!(body)).set_text(cx, &text); | ||||||||||
| } | ||||||||||
| accept_button.set_enabled(cx, true); | ||||||||||
| accept_button.set_text(cx, "Yes"); | ||||||||||
| cancel_button.set_text(cx, "No"); | ||||||||||
|
|
@@ -245,7 +292,12 @@ impl WidgetMatchEvent for VerificationModal { | |||||||||
| } | ||||||||||
|
|
||||||||||
| VerificationAction::RequestCompleted => { | ||||||||||
| self.label(cx, ids!(body)).set_text(cx, "Verification completed successfully!"); | ||||||||||
| self.label(cx, ids!(body)).set_text( | ||||||||||
| cx, | ||||||||||
| "Verification completed successfully!\n\ | ||||||||||
| Now you can send and receive encrypted messages, \ | ||||||||||
| and everyone you chat with can trust this device is yours.", | ||||||||||
| ); | ||||||||||
| accept_button.set_text(cx, "Ok"); | ||||||||||
| accept_button.set_enabled(cx, true); | ||||||||||
| cancel_button.set_visible(cx, false); | ||||||||||
|
|
@@ -270,6 +322,21 @@ impl VerificationModal { | |||||||||
| self.is_final = false; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| fn populate_emoji_cell(&mut self, cx: &mut Cx, index: usize, symbol: &str, description: &str) { | ||||||||||
| let cell = match index { | ||||||||||
| 0 => self.view.view(cx, ids!(emoji0)), | ||||||||||
| 1 => self.view.view(cx, ids!(emoji1)), | ||||||||||
| 2 => self.view.view(cx, ids!(emoji2)), | ||||||||||
| 3 => self.view.view(cx, ids!(emoji3)), | ||||||||||
| 4 => self.view.view(cx, ids!(emoji4)), | ||||||||||
| 5 => self.view.view(cx, ids!(emoji5)), | ||||||||||
| 6 => self.view.view(cx, ids!(emoji6)), | ||||||||||
| _ => return, | ||||||||||
| }; | ||||||||||
| cell.label(cx, ids!(symbol)).set_text(cx, symbol); | ||||||||||
| cell.label(cx, ids!(description)).set_text(cx, description); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| fn initialize_with_data( | ||||||||||
| &mut self, | ||||||||||
| cx: &mut Cx, | ||||||||||
|
|
@@ -296,6 +363,9 @@ impl VerificationModal { | |||||||||
| ).into() | ||||||||||
| }; | ||||||||||
| self.label(cx, ids!(body)).set_text(cx, &prompt_text); | ||||||||||
| // Ensure the emoji grid from any prior verification is not shown | ||||||||||
| // on the initial prompt screen. | ||||||||||
|
Comment on lines
+366
to
+367
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. again, LLM comments like this aren't necessary, you can just delete it entirely. Good comments explain a design choice or why we're doing something complex that is non-obvious, but here it is very obvious what's happening.
Suggested change
|
||||||||||
| self.view.view(cx, ids!(emojis_view)).set_visible(cx, false); | ||||||||||
|
|
||||||||||
| let accept_button = self.button(cx, ids!(accept_button)); | ||||||||||
| let cancel_button = self.button(cx, ids!(cancel_button)); | ||||||||||
|
|
||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, i don't quite understand this
widthchoice. Can you explain why we need a max width here? Seems like for something like this we would want both thesymboland thedescriptionto have a fixed width (perhaps 72 as you used for the max width here).I can't think of a scenario where we'd need a width that is Fit but expands to a max of 72. But let me know if i'm overlooking something.