diff --git a/src/verification_modal.rs b/src/verification_modal.rs index 70f010d91..ac1fe7fe7 100644 --- a/src/verification_modal.rs +++ b/src/verification_modal.rs @@ -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. + 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::>() - .join("\n ") - ) + ); + for (index, emoji) in emoji_list.emojis.iter().enumerate() { + self.populate_emoji_cell(cx, index, emoji.symbol, emoji.description); + } + 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. + 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));