UI + libdino: Improve MUJI calls from MUC
- Move calls from ICE-thead onto main thread - Identify Call.ourpart as MUC nick if in MUC - Keep track of the initiator of a call
This commit is contained in:
parent
ff4e2540ae
commit
f0c7dd0682
|
@ -20,9 +20,12 @@ namespace Dino.Entities {
|
||||||
|
|
||||||
public int id { get; set; default=-1; }
|
public int id { get; set; default=-1; }
|
||||||
public Account account { get; set; }
|
public Account account { get; set; }
|
||||||
public Jid counterpart { get; set; } // For backwards compatibility with db version 21. Not to be used anymore.
|
public Jid counterpart { get; set; }
|
||||||
public Gee.List<Jid> counterparts = new Gee.ArrayList<Jid>(Jid.equals_bare_func);
|
public Gee.List<Jid> counterparts = new Gee.ArrayList<Jid>(Jid.equals_bare_func);
|
||||||
public Jid ourpart { get; set; }
|
public Jid ourpart { get; set; }
|
||||||
|
public Jid proposer {
|
||||||
|
get { return direction == DIRECTION_OUTGOING ? ourpart : counterpart; }
|
||||||
|
}
|
||||||
public bool direction { get; set; }
|
public bool direction { get; set; }
|
||||||
public DateTime time { get; set; }
|
public DateTime time { get; set; }
|
||||||
public DateTime local_time { get; set; }
|
public DateTime local_time { get; set; }
|
||||||
|
@ -58,7 +61,6 @@ namespace Dino.Entities {
|
||||||
if (!counterparts.contains(peer)) { // Legacy: The first peer is also in the `call` table. Don't add twice.
|
if (!counterparts.contains(peer)) { // Legacy: The first peer is also in the `call` table. Don't add twice.
|
||||||
counterparts.add(peer);
|
counterparts.add(peer);
|
||||||
}
|
}
|
||||||
if (counterpart == null) counterpart = peer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
counterpart = db.get_jid_by_id(row[db.call.counterpart_id]);
|
counterpart = db.get_jid_by_id(row[db.call.counterpart_id]);
|
||||||
|
@ -66,7 +68,6 @@ namespace Dino.Entities {
|
||||||
if (counterpart_resource != null) counterpart = counterpart.with_resource(counterpart_resource);
|
if (counterpart_resource != null) counterpart = counterpart.with_resource(counterpart_resource);
|
||||||
if (counterparts.is_empty) {
|
if (counterparts.is_empty) {
|
||||||
counterparts.add(counterpart);
|
counterparts.add(counterpart);
|
||||||
counterpart = counterpart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notify.connect(on_update);
|
notify.connect(on_update);
|
||||||
|
@ -107,8 +108,6 @@ namespace Dino.Entities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_peer(Jid peer) {
|
public void add_peer(Jid peer) {
|
||||||
if (counterpart == null) counterpart = peer;
|
|
||||||
|
|
||||||
if (counterparts.contains(peer)) return;
|
if (counterparts.contains(peer)) return;
|
||||||
|
|
||||||
counterparts.add(peer);
|
counterparts.add(peer);
|
||||||
|
|
|
@ -127,8 +127,6 @@ public class Dino.PeerState : Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reject() {
|
public void reject() {
|
||||||
call.state = Call.State.DECLINED;
|
|
||||||
|
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
foreach (Xep.Jingle.Content content in session.contents) {
|
foreach (Xep.Jingle.Content content in session.contents) {
|
||||||
content.reject();
|
content.reject();
|
||||||
|
@ -299,7 +297,12 @@ public class Dino.PeerState : Object {
|
||||||
|
|
||||||
debug(@"[%s] %s connecting content signals %s", call.account.bare_jid.to_string(), jid.to_string(), rtp_content_parameter.media);
|
debug(@"[%s] %s connecting content signals %s", call.account.bare_jid.to_string(), jid.to_string(), rtp_content_parameter.media);
|
||||||
rtp_content_parameter.stream_created.connect((stream) => on_stream_created(rtp_content_parameter.media, stream));
|
rtp_content_parameter.stream_created.connect((stream) => on_stream_created(rtp_content_parameter.media, stream));
|
||||||
rtp_content_parameter.connection_ready.connect((status) => on_connection_ready(content, rtp_content_parameter.media));
|
rtp_content_parameter.connection_ready.connect((status) => {
|
||||||
|
Idle.add(() => {
|
||||||
|
on_connection_ready(content, rtp_content_parameter.media);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
content.senders_modify_incoming.connect((content, proposed_senders) => {
|
content.senders_modify_incoming.connect((content, proposed_senders) => {
|
||||||
if (content.session.senders_include_us(content.senders) != content.session.senders_include_us(proposed_senders)) {
|
if (content.session.senders_include_us(content.senders) != content.session.senders_include_us(proposed_senders)) {
|
||||||
|
@ -342,7 +345,10 @@ public class Dino.PeerState : Object {
|
||||||
if (media == "video" && stream.receiving) {
|
if (media == "video" && stream.receiving) {
|
||||||
counterpart_sends_video = true;
|
counterpart_sends_video = true;
|
||||||
video_content_parameter.connection_ready.connect((status) => {
|
video_content_parameter.connection_ready.connect((status) => {
|
||||||
counterpart_sends_video_updated(false);
|
Idle.add(() => {
|
||||||
|
counterpart_sends_video_updated(false);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class Dino.CallState : Object {
|
||||||
foreach (PeerState peer in peers_cpy) {
|
foreach (PeerState peer in peers_cpy) {
|
||||||
peer.end(Xep.Jingle.ReasonElement.CANCEL);
|
peer.end(Xep.Jingle.ReasonElement.CANCEL);
|
||||||
}
|
}
|
||||||
if (parent_muc != null) {
|
if (parent_muc != null && group_call != null) {
|
||||||
XmppStream stream = stream_interactor.get_stream(call.account);
|
XmppStream stream = stream_interactor.get_stream(call.account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
stream.get_module(Xep.MujiMeta.Module.IDENTITY).send_invite_retract_to_peer(stream, parent_muc, group_call.muc_jid, message_type);
|
stream.get_module(Xep.MujiMeta.Module.IDENTITY).send_invite_retract_to_peer(stream, parent_muc, group_call.muc_jid, message_type);
|
||||||
|
@ -242,7 +242,12 @@ public class Dino.CallState : Object {
|
||||||
XmppStream stream = stream_interactor.get_stream(call.account);
|
XmppStream stream = stream_interactor.get_stream(call.account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
|
|
||||||
Jid muc_jid = stream_interactor.get_module(MucManager.IDENTITY).default_muc_server[call.account] ?? new Jid("chat.jabberfr.org");
|
Jid? muc_jid = null;
|
||||||
|
if (muc_jid == null) {
|
||||||
|
warning("Failed to initiate group call: MUC server not known.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
muc_jid = new Jid("%08x@".printf(Random.next_int()) + muc_jid.to_string()); // TODO longer?
|
muc_jid = new Jid("%08x@".printf(Random.next_int()) + muc_jid.to_string()); // TODO longer?
|
||||||
|
|
||||||
debug("[%s] Converting call to groupcall %s", call.account.bare_jid.to_string(), muc_jid.to_string());
|
debug("[%s] Converting call to groupcall %s", call.account.bare_jid.to_string(), muc_jid.to_string());
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace Dino {
|
||||||
cache_call(call);
|
cache_call(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Call? get_call_by_id(int id) {
|
public Call? get_call_by_id(int id, Conversation conversation) {
|
||||||
Call? call = calls_by_db_id[id];
|
Call? call = calls_by_db_id[id];
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
return call;
|
return call;
|
||||||
|
@ -38,14 +38,17 @@ namespace Dino {
|
||||||
|
|
||||||
RowOption row_option = db.call.select().with(db.call.id, "=", id).row();
|
RowOption row_option = db.call.select().with(db.call.id, "=", id).row();
|
||||||
|
|
||||||
return create_call_from_row_opt(row_option);
|
return create_call_from_row_opt(row_option, conversation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Call? create_call_from_row_opt(RowOption row_opt) {
|
private Call? create_call_from_row_opt(RowOption row_opt, Conversation conversation) {
|
||||||
if (!row_opt.is_present()) return null;
|
if (!row_opt.is_present()) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Call call = new Call.from_row(db, row_opt.inner);
|
Call call = new Call.from_row(db, row_opt.inner);
|
||||||
|
if (conversation.type_.is_muc_semantic()) {
|
||||||
|
call.ourpart = conversation.counterpart.with_resource(call.ourpart.resourcepart);
|
||||||
|
}
|
||||||
cache_call(call);
|
cache_call(call);
|
||||||
return call;
|
return call;
|
||||||
} catch (InvalidJidError e) {
|
} catch (InvalidJidError e) {
|
||||||
|
|
|
@ -39,9 +39,8 @@ namespace Dino {
|
||||||
Call call = new Call();
|
Call call = new Call();
|
||||||
call.direction = Call.DIRECTION_OUTGOING;
|
call.direction = Call.DIRECTION_OUTGOING;
|
||||||
call.account = conversation.account;
|
call.account = conversation.account;
|
||||||
// TODO we should only do that for Conversation.Type.CHAT, but the database currently requires a counterpart from the start
|
|
||||||
call.counterpart = conversation.counterpart;
|
call.counterpart = conversation.counterpart;
|
||||||
call.ourpart = conversation.account.full_jid;
|
call.ourpart = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account) ?? conversation.account.full_jid;
|
||||||
call.time = call.local_time = call.end_time = new DateTime.now_utc();
|
call.time = call.local_time = call.end_time = new DateTime.now_utc();
|
||||||
call.state = Call.State.RINGING;
|
call.state = Call.State.RINGING;
|
||||||
|
|
||||||
|
@ -57,7 +56,7 @@ namespace Dino {
|
||||||
PeerState peer_state = call_state.set_first_peer(conversation.counterpart);
|
PeerState peer_state = call_state.set_first_peer(conversation.counterpart);
|
||||||
yield peer_state.initiate_call(conversation.counterpart);
|
yield peer_state.initiate_call(conversation.counterpart);
|
||||||
} else {
|
} else {
|
||||||
call_state.initiate_groupchat_call(conversation.counterpart);
|
call_state.initiate_groupchat_call.begin(conversation.counterpart);
|
||||||
}
|
}
|
||||||
|
|
||||||
conversation.last_active = call.time;
|
conversation.last_active = call.time;
|
||||||
|
@ -213,24 +212,23 @@ namespace Dino {
|
||||||
|
|
||||||
private PeerState create_received_call(Account account, Jid from, Jid to, bool video_requested) {
|
private PeerState create_received_call(Account account, Jid from, Jid to, bool video_requested) {
|
||||||
Call call = new Call();
|
Call call = new Call();
|
||||||
Jid counterpart = null;
|
|
||||||
if (from.equals_bare(account.bare_jid)) {
|
if (from.equals_bare(account.bare_jid)) {
|
||||||
// Call requested by another of our devices
|
// Call requested by another of our devices
|
||||||
call.direction = Call.DIRECTION_OUTGOING;
|
call.direction = Call.DIRECTION_OUTGOING;
|
||||||
call.ourpart = from;
|
call.ourpart = from;
|
||||||
call.state = Call.State.OTHER_DEVICE;
|
call.state = Call.State.OTHER_DEVICE;
|
||||||
counterpart = to;
|
call.counterpart = to;
|
||||||
} else {
|
} else {
|
||||||
call.direction = Call.DIRECTION_INCOMING;
|
call.direction = Call.DIRECTION_INCOMING;
|
||||||
call.ourpart = account.full_jid;
|
call.ourpart = account.full_jid;
|
||||||
call.state = Call.State.RINGING;
|
call.state = Call.State.RINGING;
|
||||||
counterpart = from;
|
call.counterpart = from;
|
||||||
}
|
}
|
||||||
call.add_peer(counterpart);
|
call.add_peer(call.counterpart);
|
||||||
call.account = account;
|
call.account = account;
|
||||||
call.time = call.local_time = call.end_time = new DateTime.now_utc();
|
call.time = call.local_time = call.end_time = new DateTime.now_utc();
|
||||||
|
|
||||||
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(counterpart.bare_jid, account, Conversation.Type.CHAT);
|
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(call.counterpart.bare_jid, account, Conversation.Type.CHAT);
|
||||||
|
|
||||||
stream_interactor.get_module(CallStore.IDENTITY).add_call(call, conversation);
|
stream_interactor.get_module(CallStore.IDENTITY).add_call(call, conversation);
|
||||||
|
|
||||||
|
@ -238,7 +236,7 @@ namespace Dino {
|
||||||
|
|
||||||
var call_state = new CallState(call, stream_interactor);
|
var call_state = new CallState(call, stream_interactor);
|
||||||
connect_call_state_signals(call_state);
|
connect_call_state_signals(call_state);
|
||||||
PeerState peer_state = call_state.set_first_peer(counterpart);
|
PeerState peer_state = call_state.set_first_peer(call.counterpart);
|
||||||
call_state.we_should_send_video = video_requested;
|
call_state.we_should_send_video = video_requested;
|
||||||
call_state.we_should_send_audio = true;
|
call_state.we_should_send_audio = true;
|
||||||
|
|
||||||
|
@ -283,7 +281,7 @@ namespace Dino {
|
||||||
Call call = new Call();
|
Call call = new Call();
|
||||||
call.direction = Call.DIRECTION_INCOMING;
|
call.direction = Call.DIRECTION_INCOMING;
|
||||||
call.ourpart = account.full_jid;
|
call.ourpart = account.full_jid;
|
||||||
call.add_peer(inviter_jid); // not rly
|
call.counterpart = inviter_jid;
|
||||||
call.account = account;
|
call.account = account;
|
||||||
call.time = call.local_time = call.end_time = new DateTime.now_utc();
|
call.time = call.local_time = call.end_time = new DateTime.now_utc();
|
||||||
call.state = Call.State.RINGING;
|
call.state = Call.State.RINGING;
|
||||||
|
@ -361,13 +359,14 @@ namespace Dino {
|
||||||
if (from.equals(account.full_jid)) return;
|
if (from.equals(account.full_jid)) return;
|
||||||
|
|
||||||
Call call = current_jmi_request_peer[account].call;
|
Call call = current_jmi_request_peer[account].call;
|
||||||
|
call.ourpart = from;
|
||||||
call.state = Call.State.OTHER_DEVICE;
|
call.state = Call.State.OTHER_DEVICE;
|
||||||
remove_call_from_datastructures(call);
|
remove_call_from_datastructures(call);
|
||||||
} else if (from.equals_bare(current_jmi_request_peer[account].jid) && to.equals(account.full_jid)) { // Message from our peer
|
} else if (from.equals_bare(current_jmi_request_peer[account].jid) && to.equals(account.full_jid)) { // Message from our peer
|
||||||
// We proposed the call
|
// We proposed the call
|
||||||
// We know the full jid of our peer now
|
// We know the full jid of our peer now
|
||||||
current_jmi_request_call[account].rename_peer(current_jmi_request_peer[account].jid, from);
|
current_jmi_request_call[account].rename_peer(current_jmi_request_peer[account].jid, from);
|
||||||
current_jmi_request_peer[account].call_resource(from);
|
current_jmi_request_peer[account].call_resource.begin(from);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mi_module.session_rejected.connect((from, to, sid) => {
|
mi_module.session_rejected.connect((from, to, sid) => {
|
||||||
|
@ -378,6 +377,9 @@ namespace Dino {
|
||||||
bool incoming_reject = call.direction == Call.DIRECTION_INCOMING && from.equals_bare(account.bare_jid);
|
bool incoming_reject = call.direction == Call.DIRECTION_INCOMING && from.equals_bare(account.bare_jid);
|
||||||
if (!outgoing_reject && !incoming_reject) return;
|
if (!outgoing_reject && !incoming_reject) return;
|
||||||
|
|
||||||
|
// We don't care if a single person in a group call rejected the call
|
||||||
|
if (incoming_reject && call_states[call].group_call != null) return;
|
||||||
|
|
||||||
call.state = Call.State.DECLINED;
|
call.state = Call.State.DECLINED;
|
||||||
call_states[call].terminated(from, Xep.Jingle.ReasonElement.DECLINE, "JMI reject");
|
call_states[call].terminated(from, Xep.Jingle.ReasonElement.DECLINE, "JMI reject");
|
||||||
remove_call_from_datastructures(call);
|
remove_call_from_datastructures(call);
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class ContentItemStore : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
Call? call = stream_interactor.get_module(CallStore.IDENTITY).get_call_by_id(foreign_id);
|
Call? call = stream_interactor.get_module(CallStore.IDENTITY).get_call_by_id(foreign_id, conversation);
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
var call_item = new CallItem(call, conversation, row[db.content_item.id]);
|
var call_item = new CallItem(call, conversation, row[db.content_item.id]);
|
||||||
items.add(call_item);
|
items.add(call_item);
|
||||||
|
@ -321,7 +321,7 @@ public class CallItem : ContentItem {
|
||||||
public Conversation conversation;
|
public Conversation conversation;
|
||||||
|
|
||||||
public CallItem(Call call, Conversation conversation, int id) {
|
public CallItem(Call call, Conversation conversation, int id) {
|
||||||
base(id, TYPE, call.direction == Call.DIRECTION_OUTGOING ? conversation.account.bare_jid : conversation.counterpart, call.time, call.encryption, Message.Marked.NONE);
|
base(id, TYPE, call.proposer, call.time, call.encryption, Message.Marked.NONE);
|
||||||
|
|
||||||
this.call = call;
|
this.call = call;
|
||||||
this.conversation = conversation;
|
this.conversation = conversation;
|
||||||
|
|
|
@ -424,7 +424,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
foreach (Xep.ServiceDiscovery.Identity identity in identities) {
|
foreach (Xep.ServiceDiscovery.Identity identity in identities) {
|
||||||
if (identity.category == Xep.ServiceDiscovery.Identity.CATEGORY_CONFERENCE) {
|
if (identity.category == Xep.ServiceDiscovery.Identity.CATEGORY_CONFERENCE) {
|
||||||
default_muc_server[account] = item.jid;
|
default_muc_server[account] = item.jid;
|
||||||
print(@"$(account.bare_jid) Default MUC: $(item.jid)\n");
|
debug("[%s] Default MUC: %s", account.bare_jid.to_string(), item.jid.to_string());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="multiparty_peer_box">
|
<object class="GtkBox" id="multiparty_peer_box">
|
||||||
<property name="margin">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="spacing">5</property>
|
<property name="spacing">7</property>
|
||||||
<property name="hexpand">True</property>
|
<property name="hexpand">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|
|
@ -206,9 +206,14 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
|
||||||
});
|
});
|
||||||
add_action(open_shortcuts_action);
|
add_action(open_shortcuts_action);
|
||||||
|
|
||||||
SimpleAction accept_call_action = new SimpleAction("accept-call", VariantType.INT32);
|
SimpleAction accept_call_action = new SimpleAction("accept-call", new VariantType.tuple(new VariantType[]{VariantType.INT32, VariantType.INT32}));
|
||||||
accept_call_action.activate.connect((variant) => {
|
accept_call_action.activate.connect((variant) => {
|
||||||
Call? call = stream_interactor.get_module(CallStore.IDENTITY).get_call_by_id(variant.get_int32());
|
int conversation_id = variant.get_child_value(0).get_int32();
|
||||||
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation_by_id(conversation_id);
|
||||||
|
if (conversation == null) return;
|
||||||
|
|
||||||
|
int call_id = variant.get_child_value(1).get_int32();
|
||||||
|
Call? call = stream_interactor.get_module(CallStore.IDENTITY).get_call_by_id(call_id, conversation);
|
||||||
CallState? call_state = stream_interactor.get_module(Calls.IDENTITY).call_states[call];
|
CallState? call_state = stream_interactor.get_module(Calls.IDENTITY).call_states[call];
|
||||||
if (call_state == null) return;
|
if (call_state == null) return;
|
||||||
|
|
||||||
|
@ -220,9 +225,14 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
|
||||||
});
|
});
|
||||||
add_action(accept_call_action);
|
add_action(accept_call_action);
|
||||||
|
|
||||||
SimpleAction deny_call_action = new SimpleAction("reject-call", VariantType.INT32);
|
SimpleAction deny_call_action = new SimpleAction("reject-call", new VariantType.tuple(new VariantType[]{VariantType.INT32, VariantType.INT32}));
|
||||||
deny_call_action.activate.connect((variant) => {
|
deny_call_action.activate.connect((variant) => {
|
||||||
Call? call = stream_interactor.get_module(CallStore.IDENTITY).get_call_by_id(variant.get_int32());
|
int conversation_id = variant.get_child_value(0).get_int32();
|
||||||
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation_by_id(conversation_id);
|
||||||
|
if (conversation == null) return;
|
||||||
|
|
||||||
|
int call_id = variant.get_child_value(1).get_int32();
|
||||||
|
Call? call = stream_interactor.get_module(CallStore.IDENTITY).get_call_by_id(call_id, conversation);
|
||||||
CallState? call_state = stream_interactor.get_module(Calls.IDENTITY).call_states[call];
|
CallState? call_state = stream_interactor.get_module(Calls.IDENTITY).call_states[call];
|
||||||
if (call_state == null) return;
|
if (call_state == null) return;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Dino.Ui {
|
||||||
public Revealer header_bar_revealer = new Revealer() { halign=Align.END, valign=Align.START, transition_type=RevealerTransitionType.CROSSFADE, transition_duration=200, visible=true };
|
public Revealer header_bar_revealer = new Revealer() { halign=Align.END, valign=Align.START, transition_type=RevealerTransitionType.CROSSFADE, transition_duration=200, visible=true };
|
||||||
public Box own_video_box = new Box(Orientation.HORIZONTAL, 0) { halign=Align.END, valign=Align.END, visible=true };
|
public Box own_video_box = new Box(Orientation.HORIZONTAL, 0) { halign=Align.END, valign=Align.END, visible=true };
|
||||||
public Revealer invite_button_revealer = new Revealer() { margin_top=50, margin_right=30, halign=Align.END, valign=Align.START, transition_type=RevealerTransitionType.CROSSFADE, transition_duration=200 };
|
public Revealer invite_button_revealer = new Revealer() { margin_top=50, margin_right=30, halign=Align.END, valign=Align.START, transition_type=RevealerTransitionType.CROSSFADE, transition_duration=200 };
|
||||||
public Button invite_button = new Button.from_icon_name("dino-account-plus") { relief=ReliefStyle.NONE };
|
public Button invite_button = new Button.from_icon_name("dino-account-plus") { relief=ReliefStyle.NONE, visible=false };
|
||||||
private Widget? own_video = null;
|
private Widget? own_video = null;
|
||||||
private HashMap<string, ParticipantWidget> participant_widgets = new HashMap<string, ParticipantWidget>();
|
private HashMap<string, ParticipantWidget> participant_widgets = new HashMap<string, ParticipantWidget>();
|
||||||
private ArrayList<string> participants = new ArrayList<string>();
|
private ArrayList<string> participants = new ArrayList<string>();
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace Dino.Ui {
|
||||||
|
|
||||||
private void update_counterparts() {
|
private void update_counterparts() {
|
||||||
if (call.state != Call.State.IN_PROGRESS && call.state != Call.State.ENDED) return;
|
if (call.state != Call.State.IN_PROGRESS && call.state != Call.State.ENDED) return;
|
||||||
if (call.counterparts.size <= 1) return;
|
if (call.counterparts.size <= 1 && conversation.type_ == Conversation.Type.CHAT) return;
|
||||||
|
|
||||||
multiparty_peer_box.foreach((widget) => { multiparty_peer_box.remove(widget); });
|
multiparty_peer_box.foreach((widget) => { multiparty_peer_box.remove(widget); });
|
||||||
|
|
||||||
|
|
|
@ -115,13 +115,17 @@ namespace Dino.Ui {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Conversation conv_bak = conversation;
|
if (conversation.type_ == Conversation.Type.CHAT) {
|
||||||
bool audio_works = yield stream_interactor.get_module(Calls.IDENTITY).can_do_audio_calls_async(conversation);
|
Conversation conv_bak = conversation;
|
||||||
bool video_works = yield stream_interactor.get_module(Calls.IDENTITY).can_do_video_calls_async(conversation);
|
bool audio_works = yield stream_interactor.get_module(Calls.IDENTITY).can_do_audio_calls_async(conversation);
|
||||||
if (conv_bak != conversation) return;
|
bool video_works = yield stream_interactor.get_module(Calls.IDENTITY).can_do_video_calls_async(conversation);
|
||||||
|
if (conv_bak != conversation) return;
|
||||||
|
|
||||||
visible = audio_works;
|
visible = audio_works;
|
||||||
video_button.visible = video_works;
|
video_button.visible = video_works;
|
||||||
|
} else {
|
||||||
|
visible = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public new void unset_conversation() { }
|
public new void unset_conversation() { }
|
||||||
|
|
|
@ -141,10 +141,12 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
|
||||||
GLib.Application.get_default().activate_action("open-conversation", new Variant.int32(conversation.id));
|
GLib.Application.get_default().activate_action("open-conversation", new Variant.int32(conversation.id));
|
||||||
});
|
});
|
||||||
add_action_listener(notification_id, "reject", () => {
|
add_action_listener(notification_id, "reject", () => {
|
||||||
GLib.Application.get_default().activate_action("reject-call", new Variant.int32(call.id));
|
var variant = new Variant.tuple(new Variant[] {new Variant.int32(conversation.id), new Variant.int32(call.id)});
|
||||||
|
GLib.Application.get_default().activate_action("reject-call", variant);
|
||||||
});
|
});
|
||||||
add_action_listener(notification_id, "accept", () => {
|
add_action_listener(notification_id, "accept", () => {
|
||||||
GLib.Application.get_default().activate_action("accept-call", new Variant.int32(call.id));
|
var variant = new Variant.tuple(new Variant[] {new Variant.int32(conversation.id), new Variant.int32(call.id)});
|
||||||
|
GLib.Application.get_default().activate_action("accept-call", variant);
|
||||||
});
|
});
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
warning("Failed showing subscription request notification: %s", e.message);
|
warning("Failed showing subscription request notification: %s", e.message);
|
||||||
|
|
Loading…
Reference in a new issue