anotherim-desktop/main/src/ui/conversation_content_view/call_widget.vala

207 lines
8.6 KiB
Vala
Raw Normal View History

2021-03-19 22:09:56 +00:00
using Gee;
using Gdk;
using Gtk;
using Pango;
using Dino.Entities;
namespace Dino.Ui {
public class CallMetaItem : ConversationSummary.ContentMetaItem {
private StreamInteractor stream_interactor;
public CallMetaItem(ContentItem content_item, StreamInteractor stream_interactor) {
base(content_item);
this.stream_interactor = stream_interactor;
}
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 };
}
public override Gee.List<Plugins.MessageAction>? get_item_actions(Plugins.WidgetType type) { return null; }
}
[GtkTemplate (ui = "/im/dino/Dino/call_widget.ui")]
public class CallWidget : SizeRequestBox {
[GtkChild] public unowned Image image;
[GtkChild] public unowned Label title_label;
[GtkChild] public unowned Label subtitle_label;
[GtkChild] public unowned Revealer incoming_call_revealer;
[GtkChild] public unowned Button accept_call_button;
[GtkChild] public unowned Button reject_call_button;
2021-03-19 22:09:56 +00:00
private StreamInteractor stream_interactor;
private Call call;
private Conversation conversation;
public Call.State call_state { get; set; } // needs to be public for binding
private uint time_update_handler_id = 0;
construct {
margin_top = 4;
size_request_mode = SizeRequestMode.HEIGHT_FOR_WIDTH;
}
public CallWidget(StreamInteractor stream_interactor, Call call, Conversation conversation) {
this.stream_interactor = stream_interactor;
this.call = call;
this.conversation = conversation;
size_allocate.connect((allocation) => {
if (allocation.height > parent.get_allocated_height()) {
Idle.add(() => { parent.queue_resize(); return false; });
}
});
call.bind_property("state", this, "call-state");
this.notify["call-state"].connect(update_widget);
accept_call_button.clicked.connect(() => {
stream_interactor.get_module(Calls.IDENTITY).accept_call(call);
var call_window = new CallWindow();
call_window.controller = new CallWindowController(call_window, call, stream_interactor);
call_window.present();
});
reject_call_button.clicked.connect(() => {
stream_interactor.get_module(Calls.IDENTITY).reject_call(call);
});
update_widget();
}
private void update_widget() {
incoming_call_revealer.reveal_child = false;
incoming_call_revealer.get_style_context().remove_class("incoming");
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);
2021-09-25 14:04:13 +00:00
title_label.label = video ? _("Incoming video call") : _("Incoming call");
2021-03-19 22:09:56 +00:00
subtitle_label.label = "Ring ring…!";
incoming_call_revealer.reveal_child = true;
incoming_call_revealer.get_style_context().add_class("incoming");
} else {
2021-09-25 14:04:13 +00:00
title_label.label = _("Calling…");
2021-03-19 22:09:56 +00:00
subtitle_label.label = "Ring ring…?";
}
break;
case Call.State.ESTABLISHING:
case Call.State.IN_PROGRESS:
image.set_from_icon_name("dino-phone-in-talk-symbolic", IconSize.LARGE_TOOLBAR);
2021-09-25 14:04:13 +00:00
title_label.label = _("Call started");
2021-03-19 22:09:56 +00:00
string duration = get_duration_string((new DateTime.now_utc()).difference(call.local_time));
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();
return true;
});
break;
case Call.State.OTHER_DEVICE_ACCEPTED:
image.set_from_icon_name("dino-phone-hangup-symbolic", IconSize.LARGE_TOOLBAR);
title_label.label = call.direction == Call.DIRECTION_INCOMING ? _("Incoming call") : _("Outgoing call");
subtitle_label.label = _("You handled this call on another device");
break;
case Call.State.ENDED:
image.set_from_icon_name("dino-phone-hangup-symbolic", IconSize.LARGE_TOOLBAR);
title_label.label = _("Call ended");
string formated_end = Util.format_time(call.end_time, _("%H%M"), _("%l%M %p"));
string duration = get_duration_string(call.end_time.difference(call.local_time));
subtitle_label.label = _("Ended at %s").printf(formated_end) +
" · " +
2021-09-25 14:04:13 +00:00
_("Lasted %s").printf(duration);
2021-03-19 22:09:56 +00:00
break;
case Call.State.MISSED:
image.set_from_icon_name("dino-phone-missed-symbolic", IconSize.LARGE_TOOLBAR);
title_label.label = _("Call missed");
if (call.direction == Call.DIRECTION_INCOMING) {
2021-09-25 14:04:13 +00:00
subtitle_label.label = _("You missed this call");
2021-03-19 22:09:56 +00:00
} else {
2021-09-25 14:04:13 +00:00
string who = Util.get_participant_display_name(stream_interactor, conversation, call.to);
subtitle_label.label = _("%s missed this call").printf(who);
2021-03-19 22:09:56 +00:00
}
break;
case Call.State.DECLINED:
image.set_from_icon_name("dino-phone-hangup-symbolic", IconSize.LARGE_TOOLBAR);
title_label.label = _("Call declined");
if (call.direction == Call.DIRECTION_INCOMING) {
2021-09-25 14:04:13 +00:00
subtitle_label.label = _("You declined this call");
2021-03-19 22:09:56 +00:00
} else {
2021-09-25 14:04:13 +00:00
string who = Util.get_participant_display_name(stream_interactor, conversation, call.to);
subtitle_label.label = _("%s declined this call").printf(who);
2021-03-19 22:09:56 +00:00
}
break;
case Call.State.FAILED:
image.set_from_icon_name("dino-phone-hangup-symbolic", IconSize.LARGE_TOOLBAR);
title_label.label = _("Call failed");
2021-04-29 13:56:22 +00:00
subtitle_label.label = "Call failed to establish";
2021-03-19 22:09:56 +00:00
break;
}
}
private string get_duration_string(TimeSpan duration) {
DateTime a = new DateTime.now_utc();
DateTime b = new DateTime.now_utc();
a.difference(b);
TimeSpan remainder_duration = duration;
int hours = (int) Math.floor(remainder_duration / TimeSpan.HOUR);
remainder_duration -= hours * TimeSpan.HOUR;
int minutes = (int) Math.floor(remainder_duration / TimeSpan.MINUTE);
remainder_duration -= minutes * TimeSpan.MINUTE;
string ret = "";
if (hours > 0) {
ret += n("%i hour", "%i hours", hours).printf(hours);
}
if (minutes > 0) {
if (ret.length > 0) {
ret += " ";
}
ret += n("%i minute", "%i minutes", minutes).printf(minutes);
}
if (ret.length > 0) {
return ret;
}
2021-09-25 14:04:13 +00:00
return _("a few seconds");
2021-03-19 22:09:56 +00:00
}
private int get_next_time_change() {
DateTime now = new DateTime.now_local();
DateTime item_time = call.local_time;
if (now.get_second() < item_time.get_second()) {
return item_time.get_second() - now.get_second();
} else {
return 60 - (now.get_second() - item_time.get_second());
}
}
public override void dispose() {
base.dispose();
if (time_update_handler_id != 0) {
Source.remove(time_update_handler_id);
time_update_handler_id = 0;
}
}
}
}