aboutsummaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorfiaxh <git@lightrise.org>2021-04-08 12:07:04 +0200
committerfiaxh <git@lightrise.org>2021-04-09 22:23:13 +0200
commit8d1c6c29be7018c74ec3f8ea05f5849eac5b4069 (patch)
treedde27c13cd0ae8af31b9194b3450c58d4fe9cf02 /main
parent3454201e5a3da058ccbef0bbaf467599912a8c38 (diff)
downloaddino-8d1c6c29be7018c74ec3f8ea05f5849eac5b4069.tar.gz
dino-8d1c6c29be7018c74ec3f8ea05f5849eac5b4069.zip
Display+store call encryption info
Diffstat (limited to 'main')
-rw-r--r--main/data/theme.css25
-rw-r--r--main/src/ui/call_window/call_bottom_bar.vala53
-rw-r--r--main/src/ui/call_window/call_window_controller.vala4
-rw-r--r--main/src/ui/conversation_content_view/content_populator.vala1
-rw-r--r--main/src/ui/conversation_content_view/conversation_item_skeleton.vala74
5 files changed, 118 insertions, 39 deletions
diff --git a/main/data/theme.css b/main/data/theme.css
index 423cbf68..454bd2c1 100644
--- a/main/data/theme.css
+++ b/main/data/theme.css
@@ -235,17 +235,24 @@ box.dino-input-error label.input-status-highlight-once {
outline: 0;
border-radius: 1000px;
}
+
.dino-call-window button.white-button {
color: #1d1c1d;
- background: rgba(255,255,255,0.9);
+ background: rgba(255,255,255,0.85);
border: lightgrey;
}
+.dino-call-window button.white-button:hover {
+ background: rgba(255,255,255,1);
+}
.dino-call-window button.transparent-white-button {
color: white;
background: rgba(255,255,255,0.15);
border: none;
}
+.dino-call-window button.transparent-white-button:hover {
+ background: rgba(255,255,255,0.25);
+}
.dino-call-window button.call-mediadevice-settings-button {
border-radius: 1000px;
@@ -265,11 +272,21 @@ box.dino-input-error label.input-status-highlight-once {
margin: 0;
}
-.dino-call-window .unencrypted-box {
- color: @error_color;
- padding: 10px;
+.dino-call-window .encryption-box {
+ color: rgba(255,255,255,0.7);
border-radius: 5px;
background: rgba(0,0,0,0.5);
+ padding: 0px;
+ border: none;
+ box-shadow: none;
+}
+
+.dino-call-window .encryption-box.unencrypted {
+ color: @error_color;
+}
+
+.dino-call-window .encryption-box:hover {
+ background: rgba(20,20,20,0.5);
}
.dino-call-window .call-header-bar {
diff --git a/main/src/ui/call_window/call_bottom_bar.vala b/main/src/ui/call_window/call_bottom_bar.vala
index bc800485..c6375ea2 100644
--- a/main/src/ui/call_window/call_bottom_bar.vala
+++ b/main/src/ui/call_window/call_bottom_bar.vala
@@ -1,5 +1,6 @@
using Dino.Entities;
using Gtk;
+using Pango;
public class Dino.Ui.CallBottomBar : Gtk.Box {
@@ -24,6 +25,10 @@ public class Dino.Ui.CallBottomBar : Gtk.Box {
private MenuButton video_settings_button = new MenuButton() { halign=Align.END, valign=Align.END };
public VideoSettingsPopover? video_settings_popover;
+ private EventBox encryption_event_box = new EventBox() { visible=true };
+ private MenuButton encryption_button = new MenuButton() { relief=ReliefStyle.NONE, height_request=30, width_request=30, margin_start=20, margin_bottom=25, halign=Align.START, valign=Align.END };
+ private Image encryption_image = new Image.from_icon_name("changes-allow-symbolic", IconSize.BUTTON) { visible=true };
+
private Label label = new Label("") { margin=20, halign=Align.CENTER, valign=Align.CENTER, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true, visible=true };
private Stack stack = new Stack() { visible=true };
@@ -31,11 +36,9 @@ public class Dino.Ui.CallBottomBar : Gtk.Box {
Object(orientation:Orientation.HORIZONTAL, spacing:0);
Overlay default_control = new Overlay() { visible=true };
- Image encryption_image = new Image.from_icon_name("changes-allow-symbolic", IconSize.BUTTON) { margin_start=20, margin_bottom=25, halign=Align.START, valign=Align.END, visible=true };
- encryption_image.tooltip_text = _("Unencrypted");
- encryption_image.get_style_context().add_class("unencrypted-box");
-
- default_control.add_overlay(encryption_image);
+ encryption_button.add(encryption_image);
+ encryption_button.get_style_context().add_class("encryption-box");
+ default_control.add_overlay(encryption_button);
Box main_buttons = new Box(Orientation.HORIZONTAL, 20) { margin_start=40, margin_end=40, margin=20, halign=Align.CENTER, hexpand=true, visible=true };
@@ -87,6 +90,33 @@ public class Dino.Ui.CallBottomBar : Gtk.Box {
this.get_style_context().add_class("call-bottom-bar");
}
+ public void set_encryption(Xmpp.Xep.Jingle.ContentEncryption? encryption) {
+ encryption_button.visible = true;
+
+ Popover popover = new Popover(encryption_button);
+
+ if (encryption == null) {
+ encryption_image.set_from_icon_name("changes-allow-symbolic", IconSize.BUTTON);
+ encryption_button.get_style_context().add_class("unencrypted");
+
+ popover.add(new Label("This call isn't encrypted.") { margin=10, visible=true } );
+ } else {
+ encryption_image.set_from_icon_name("changes-prevent-symbolic", IconSize.BUTTON);
+ encryption_button.get_style_context().remove_class("unencrypted");
+
+ Grid encryption_info_grid = new Grid() { margin=10, row_spacing=3, column_spacing=5, visible=true };
+ encryption_info_grid.attach(new Label("<b>This call is end-to-end encrypted.</b>") { use_markup=true, xalign=0, visible=true }, 1, 1, 2, 1);
+ encryption_info_grid.attach(new Label("Peer key") { xalign=0, visible=true }, 1, 2, 1, 1);
+ encryption_info_grid.attach(new Label("Your key") { xalign=0, visible=true }, 1, 3, 1, 1);
+ encryption_info_grid.attach(new Label("<span font_family='monospace'>" + format_fingerprint(encryption.peer_key) + "</span>") { use_markup=true, max_width_chars=25, ellipsize=EllipsizeMode.MIDDLE, xalign=0, hexpand=true, visible=true }, 2, 2, 1, 1);
+ encryption_info_grid.attach(new Label("<span font_family='monospace'>" + format_fingerprint(encryption.our_key) + "</span>") { use_markup=true, max_width_chars=25, ellipsize=EllipsizeMode.MIDDLE, xalign=0, hexpand=true, visible=true }, 2, 3, 1, 1);
+
+ popover.add(encryption_info_grid);
+ }
+
+ encryption_button.set_popover(popover);
+ }
+
public AudioSettingsPopover? show_audio_device_choices(bool show) {
audio_settings_button.visible = show;
if (audio_settings_popover != null) audio_settings_popover.visible = false;
@@ -160,6 +190,17 @@ public class Dino.Ui.CallBottomBar : Gtk.Box {
}
public bool is_menu_active() {
- return video_settings_button.active || audio_settings_button.active;
+ return video_settings_button.active || audio_settings_button.active || encryption_button.active;
+ }
+
+ private string format_fingerprint(uint8[] fingerprint) {
+ var sb = new StringBuilder();
+ for (int i = 0; i < fingerprint.length; i++) {
+ sb.append("%02x".printf(fingerprint[i]));
+ if (i < fingerprint.length - 1) {
+ sb.append(":");
+ }
+ }
+ return sb.str;
}
} \ No newline at end of file
diff --git a/main/src/ui/call_window/call_window_controller.vala b/main/src/ui/call_window/call_window_controller.vala
index 09c8f88c..f66a37e1 100644
--- a/main/src/ui/call_window/call_window_controller.vala
+++ b/main/src/ui/call_window/call_window_controller.vala
@@ -67,6 +67,10 @@ public class Dino.Ui.CallWindowController : Object {
call_window.set_status("ringing");
}
});
+ calls.encryption_updated.connect((call, encryption) => {
+ if (!this.call.equals(call)) return;
+ call_window.bottom_bar.set_encryption(encryption);
+ });
own_video.resolution_changed.connect((width, height) => {
if (width == 0 || height == 0) return;
diff --git a/main/src/ui/conversation_content_view/content_populator.vala b/main/src/ui/conversation_content_view/content_populator.vala
index d7ce9ce5..ef859bde 100644
--- a/main/src/ui/conversation_content_view/content_populator.vala
+++ b/main/src/ui/conversation_content_view/content_populator.vala
@@ -88,6 +88,7 @@ public abstract class ContentMetaItem : Plugins.MetaConversationItem {
this.mark = content_item.mark;
content_item.bind_property("mark", this, "mark");
+ content_item.bind_property("encryption", this, "encryption");
this.can_merge = true;
this.requires_avatar = true;
diff --git a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
index c0099bf4..bcb6864e 100644
--- a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
+++ b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
@@ -104,7 +104,7 @@ public class ItemMetaDataHeader : Box {
[GtkChild] public Label dot_label;
[GtkChild] public Label time_label;
public Image received_image = new Image() { opacity=0.4 };
- public Image? unencrypted_image = null;
+ public Widget? encryption_image = null;
public static IconSize ICON_SIZE_HEADER = Gtk.icon_size_register("im.dino.Dino.HEADER_ICON", 17, 12);
@@ -124,50 +124,66 @@ public class ItemMetaDataHeader : Box {
update_name_label();
name_label.style_updated.connect(update_name_label);
+ conversation.notify["encryption"].connect(update_unencrypted_icon);
+ item.notify["encryption"].connect(update_encryption_icon);
+ update_encryption_icon();
+
+ this.add(received_image);
+
+ if (item.time != null) {
+ update_time();
+ }
+
+ item.bind_property("mark", this, "item-mark");
+ this.notify["item-mark"].connect_after(update_received_mark);
+ update_received_mark();
+ }
+
+ private void update_encryption_icon() {
Application app = GLib.Application.get_default() as Application;
ContentMetaItem ci = item as ContentMetaItem;
- if (ci != null) {
+ if (item.encryption != Encryption.NONE && ci != null) {
+ Widget? widget = null;
foreach(var e in app.plugin_registry.encryption_list_entries) {
if (e.encryption == item.encryption) {
- Object? w = e.get_encryption_icon(conversation, ci.content_item);
- if (w != null) {
- this.add(w as Widget);
- } else {
- Image image = new Image.from_icon_name("dino-changes-prevent-symbolic", ICON_SIZE_HEADER) { opacity=0.4, visible = true };
- this.add(image);
- }
+ widget = e.get_encryption_icon(conversation, ci.content_item) as Widget;
break;
}
}
+ if (widget == null) {
+ widget = new Image.from_icon_name("dino-changes-prevent-symbolic", ICON_SIZE_HEADER) { opacity=0.4, visible = true };
+ }
+ update_encryption_image(widget);
}
if (item.encryption == Encryption.NONE) {
- conversation.notify["encryption"].connect(update_unencrypted_icon);
update_unencrypted_icon();
}
+ }
- this.add(received_image);
-
- if (item.time != null) {
- update_time();
+ private void update_unencrypted_icon() {
+ if (item.encryption != Encryption.NONE) return;
+
+ if (conversation.encryption != Encryption.NONE && encryption_image == null) {
+ Image image = new Image() { opacity=0.4, visible = true };
+ image.set_from_icon_name("dino-changes-allowed-symbolic", ICON_SIZE_HEADER);
+ image.tooltip_text = _("Unencrypted");
+ update_encryption_image(image);
+ Util.force_error_color(image);
+ } else if (conversation.encryption == Encryption.NONE && encryption_image != null) {
+ update_encryption_image(null);
}
-
- item.bind_property("mark", this, "item-mark");
- this.notify["item-mark"].connect_after(update_received_mark);
- update_received_mark();
}
- private void update_unencrypted_icon() {
- if (conversation.encryption != Encryption.NONE && unencrypted_image == null) {
- unencrypted_image = new Image() { opacity=0.4, visible = true };
- unencrypted_image.set_from_icon_name("dino-changes-allowed-symbolic", ICON_SIZE_HEADER);
- unencrypted_image.tooltip_text = _("Unencrypted");
- this.add(unencrypted_image);
- this.reorder_child(unencrypted_image, 3);
- Util.force_error_color(unencrypted_image);
- } else if (conversation.encryption == Encryption.NONE && unencrypted_image != null) {
- this.remove(unencrypted_image);
- unencrypted_image = null;
+ private void update_encryption_image(Widget? widget) {
+ if (encryption_image != null) {
+ this.remove(encryption_image);
+ encryption_image = null;
+ }
+ if (widget != null) {
+ this.add(widget);
+ this.reorder_child(widget, 3);
+ encryption_image = widget;
}
}