From 3dc4d7f1558bb574eb99dade9a05727604e2e2ca Mon Sep 17 00:00:00 2001 From: fiaxh Date: Thu, 4 Nov 2021 17:35:11 +0100 Subject: Add (disabled) multi-party call UI --- .../ui/conversation_content_view/call_widget.vala | 74 +++++++++++++++++----- .../conversation_item_skeleton.vala | 1 - 2 files changed, 58 insertions(+), 17 deletions(-) (limited to 'main/src/ui/conversation_content_view') diff --git a/main/src/ui/conversation_content_view/call_widget.vala b/main/src/ui/conversation_content_view/call_widget.vala index 62156761..aad1e6d8 100644 --- a/main/src/ui/conversation_content_view/call_widget.vala +++ b/main/src/ui/conversation_content_view/call_widget.vala @@ -2,6 +2,7 @@ using Gee; using Gdk; using Gtk; using Pango; +using Xmpp; using Dino.Entities; @@ -18,7 +19,8 @@ namespace Dino.Ui { public override Object? get_widget(Plugins.WidgetType type) { CallItem call_item = content_item as CallItem; - return new CallWidget(stream_interactor, call_item.call, call_item.conversation) { visible=true }; + CallState? call_state = stream_interactor.get_module(Calls.IDENTITY).call_states[call_item.call]; + return new CallWidget(stream_interactor, call_item.call, call_state, call_item.conversation) { visible=true }; } public override Gee.List? get_item_actions(Plugins.WidgetType type) { return null; } @@ -31,10 +33,14 @@ namespace Dino.Ui { [GtkChild] public unowned Label title_label; [GtkChild] public unowned Label subtitle_label; [GtkChild] public unowned Revealer incoming_call_revealer; + [GtkChild] public unowned Box outer_additional_box; + [GtkChild] public unowned Box incoming_call_box; + [GtkChild] public unowned Box multiparty_peer_box; [GtkChild] public unowned Button accept_call_button; [GtkChild] public unowned Button reject_call_button; private StreamInteractor stream_interactor; + private CallState call_manager; private Call call; private Conversation conversation; public Call.State call_state { get; set; } // needs to be public for binding @@ -45,8 +51,10 @@ namespace Dino.Ui { size_request_mode = SizeRequestMode.HEIGHT_FOR_WIDTH; } - public CallWidget(StreamInteractor stream_interactor, Call call, Conversation conversation) { + /** @param call_state Null if it's an old call and we can't interact with it anymore */ + public CallWidget(StreamInteractor stream_interactor, Call call, CallState? call_state, Conversation conversation) { this.stream_interactor = stream_interactor; + this.call_manager = call_state; this.call = call; this.conversation = conversation; @@ -57,36 +65,63 @@ namespace Dino.Ui { }); call.bind_property("state", this, "call-state"); - this.notify["call-state"].connect(update_widget); + this.notify["call-state"].connect(update_call_state); + + if (call_manager != null && (call.state == Call.State.ESTABLISHING || call.state == Call.State.IN_PROGRESS)) { + call_manager.peer_joined.connect(update_counterparts); + } accept_call_button.clicked.connect(() => { - stream_interactor.get_module(Calls.IDENTITY).accept_call(call); + call_manager.accept(); var call_window = new CallWindow(); - call_window.controller = new CallWindowController(call_window, call, stream_interactor); + call_window.controller = new CallWindowController(call_window, call_state, stream_interactor); call_window.present(); }); - reject_call_button.clicked.connect(() => { - stream_interactor.get_module(Calls.IDENTITY).reject_call(call); - }); + reject_call_button.clicked.connect(call_manager.reject); + + update_call_state(); + } + + private void update_counterparts() { + if (call.state != Call.State.IN_PROGRESS && call.state != Call.State.ENDED) return; + if (call.counterparts.size <= 1) return; - update_widget(); + multiparty_peer_box.foreach((widget) => { multiparty_peer_box.remove(widget); }); + + foreach (Jid counterpart in call.counterparts) { + AvatarImage image = new AvatarImage() { force_gray=true, margin_top=2, visible=true }; + image.set_conversation_participant(stream_interactor, conversation, counterpart.bare_jid); + multiparty_peer_box.add(image); + } + AvatarImage image2 = new AvatarImage() { force_gray=true, margin_top=2, visible=true }; + image2.set_conversation_participant(stream_interactor, conversation, call.account.bare_jid); + multiparty_peer_box.add(image2); + + outer_additional_box.get_style_context().add_class("multiparty-participants"); + + multiparty_peer_box.visible = true; + incoming_call_box.visible = false; + incoming_call_revealer.reveal_child = true; } - private void update_widget() { + private void update_call_state() { incoming_call_revealer.reveal_child = false; incoming_call_revealer.get_style_context().remove_class("incoming"); + outer_additional_box.get_style_context().remove_class("incoming-call-box"); switch (call.state) { case Call.State.RINGING: image.set_from_icon_name("dino-phone-ring-symbolic", IconSize.LARGE_TOOLBAR); if (call.direction == Call.DIRECTION_INCOMING) { - bool video = stream_interactor.get_module(Calls.IDENTITY).should_we_send_video(call); + bool video = call_manager.should_we_send_video(); title_label.label = video ? _("Incoming video call") : _("Incoming call"); subtitle_label.label = "Ring ring…!"; + incoming_call_box.visible = true; incoming_call_revealer.reveal_child = true; incoming_call_revealer.get_style_context().add_class("incoming"); + outer_additional_box.get_style_context().add_class("incoming-call-box"); } else { title_label.label = _("Calling…"); subtitle_label.label = "Ring ring…?"; @@ -100,9 +135,11 @@ namespace Dino.Ui { subtitle_label.label = _("Started %s ago").printf(duration); time_update_handler_id = Timeout.add_seconds(get_next_time_change() + 1, () => { - Source.remove(time_update_handler_id); - time_update_handler_id = 0; - update_widget(); + if (time_update_handler_id != 0) { + Source.remove(time_update_handler_id); + time_update_handler_id = 0; + update_call_state(); + } return true; }); @@ -128,7 +165,7 @@ namespace Dino.Ui { if (call.direction == Call.DIRECTION_INCOMING) { subtitle_label.label = _("You missed this call"); } else { - string who = Util.get_participant_display_name(stream_interactor, conversation, call.to); + string who = Util.get_conversation_display_name(stream_interactor, conversation); subtitle_label.label = _("%s missed this call").printf(who); } break; @@ -138,7 +175,7 @@ namespace Dino.Ui { if (call.direction == Call.DIRECTION_INCOMING) { subtitle_label.label = _("You declined this call"); } else { - string who = Util.get_participant_display_name(stream_interactor, conversation, call.to); + string who = Util.get_conversation_display_name(stream_interactor, conversation); subtitle_label.label = _("%s declined this call").printf(who); } break; @@ -148,6 +185,8 @@ namespace Dino.Ui { subtitle_label.label = "Call failed to establish"; break; } + + update_counterparts(); } private string get_duration_string(TimeSpan duration) { @@ -201,6 +240,9 @@ namespace Dino.Ui { Source.remove(time_update_handler_id); time_update_handler_id = 0; } + if (call_manager != null) { + call_manager.peer_joined.disconnect(update_counterparts); + } } } } 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 b356d8cc..73f7c671 100644 --- a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala +++ b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala @@ -114,7 +114,6 @@ public class ConversationItemSkeleton : EventBox { [GtkTemplate (ui = "/im/dino/Dino/conversation_content_view/item_metadata_header.ui")] public class ItemMetaDataHeader : Box { [GtkChild] public unowned Label name_label; - [GtkChild] public unowned Label dot_label; [GtkChild] public unowned Label time_label; public Image received_image = new Image() { opacity=0.4 }; public Widget? encryption_image = null; -- cgit v1.2.3-54-g00ecf