Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 85 additions & 15 deletions src/verification_modal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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}

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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);
}
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");
Expand Down Expand Up @@ -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);
Expand All @@ -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,
Expand All @@ -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));
Expand Down