parent
a2f63a7789
commit
05561dd677
|
@ -1,6 +1,7 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp;
|
using Xmpp;
|
||||||
|
using Xmpp.Xep;
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
|
||||||
namespace Dino {
|
namespace Dino {
|
||||||
|
@ -36,9 +37,9 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
stream_interactor.get_module(MessageProcessor.IDENTITY).received_pipeline.connect(received_message_listener);
|
stream_interactor.get_module(MessageProcessor.IDENTITY).received_pipeline.connect(received_message_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void join(Account account, Jid jid, string? nick, string? password) {
|
public async Muc.JoinResult? join(Account account, Jid jid, string? nick, string? password) {
|
||||||
XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) return;
|
if (stream == null) return null;
|
||||||
string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart;
|
string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart;
|
||||||
|
|
||||||
DateTime? history_since = null;
|
DateTime? history_since = null;
|
||||||
|
@ -48,7 +49,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
if (last_message != null) history_since = last_message.time;
|
if (last_message != null) history_since = last_message.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid, nick_, password, history_since);
|
return yield stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid, nick_, password, history_since);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void part(Account account, Jid jid) {
|
public void part(Account account, Jid jid) {
|
||||||
|
@ -323,7 +324,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
Gee.List<Conversation> conversations = stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations(account);
|
Gee.List<Conversation> conversations = stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations(account);
|
||||||
foreach (Conversation conversation in conversations) {
|
foreach (Conversation conversation in conversations) {
|
||||||
if (conversation.type_ == Conversation.Type.GROUPCHAT && conversation.nickname != null) {
|
if (conversation.type_ == Conversation.Type.GROUPCHAT && conversation.nickname != null) {
|
||||||
join(account, conversation.counterpart, conversation.nickname, null);
|
join.begin(account, conversation.counterpart, conversation.nickname, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,7 +346,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
if (conference.jid.equals(conversation.counterpart)) is_active = true;
|
if (conference.jid.equals(conversation.counterpart)) is_active = true;
|
||||||
}
|
}
|
||||||
if (!is_active || !is_joined(jid, account)) {
|
if (!is_active || !is_joined(jid, account)) {
|
||||||
join(account, conference.jid, conference.nick, conference.password);
|
join.begin(account, conference.jid, conference.nick, conference.password);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Leave if we should leave
|
// Leave if we should leave
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
using Xmpp;
|
using Xmpp;
|
||||||
|
using Xmpp.Xep;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
@ -49,7 +50,6 @@ public class AddConferenceDialog : Gtk.Dialog {
|
||||||
cancel_button.clicked.connect(on_cancel);
|
cancel_button.clicked.connect(on_cancel);
|
||||||
ok_button.label = _("Next");
|
ok_button.label = _("Next");
|
||||||
ok_button.sensitive = select_fragment.done;
|
ok_button.sensitive = select_fragment.done;
|
||||||
ok_button.clicked.disconnect(on_ok_button_clicked);
|
|
||||||
ok_button.clicked.connect(on_next_button_clicked);
|
ok_button.clicked.connect(on_next_button_clicked);
|
||||||
details_fragment.notify["done"].disconnect(set_ok_sensitive_from_details);
|
details_fragment.notify["done"].disconnect(set_ok_sensitive_from_details);
|
||||||
select_fragment.notify["done"].connect(set_ok_sensitive_from_select);
|
select_fragment.notify["done"].connect(set_ok_sensitive_from_select);
|
||||||
|
@ -69,7 +69,6 @@ public class AddConferenceDialog : Gtk.Dialog {
|
||||||
ok_button.label = _("Join");
|
ok_button.label = _("Join");
|
||||||
ok_button.sensitive = details_fragment.done;
|
ok_button.sensitive = details_fragment.done;
|
||||||
ok_button.clicked.disconnect(on_next_button_clicked);
|
ok_button.clicked.disconnect(on_next_button_clicked);
|
||||||
ok_button.clicked.connect(on_ok_button_clicked);
|
|
||||||
select_fragment.notify["done"].disconnect(set_ok_sensitive_from_select);
|
select_fragment.notify["done"].disconnect(set_ok_sensitive_from_select);
|
||||||
details_fragment.notify["done"].connect(set_ok_sensitive_from_details);
|
details_fragment.notify["done"].connect(set_ok_sensitive_from_details);
|
||||||
}
|
}
|
||||||
|
@ -143,7 +142,6 @@ public class AddConferenceDialog : Gtk.Dialog {
|
||||||
|
|
||||||
Button ok_button = new Button() { label=_("Join"), halign = Align.END, can_focus=true, can_default=true, visible=true };
|
Button ok_button = new Button() { label=_("Join"), halign = Align.END, can_focus=true, can_default=true, visible=true };
|
||||||
ok_button.get_style_context().add_class("suggested-action");
|
ok_button.get_style_context().add_class("suggested-action");
|
||||||
ok_button.clicked.connect(on_ok_button_clicked);
|
|
||||||
details_fragment.notify["done"].connect(() => { ok_button.sensitive = select_fragment.done; });
|
details_fragment.notify["done"].connect(() => { ok_button.sensitive = select_fragment.done; });
|
||||||
details_fragment.ok_button = ok_button;
|
details_fragment.ok_button = ok_button;
|
||||||
|
|
||||||
|
@ -182,10 +180,6 @@ public class AddConferenceDialog : Gtk.Dialog {
|
||||||
show_conference_details_view();
|
show_conference_details_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_ok_button_clicked() {
|
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).join(details_fragment.account, new Jid(details_fragment.jid), details_fragment.nick, details_fragment.password);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void on_joined(Account account, Jid jid, string nick) {
|
private void on_joined(Account account, Jid jid, string nick) {
|
||||||
if (account.equals(details_fragment.account) && jid.equals_bare(new Jid(details_fragment.jid))) {
|
if (account.equals(details_fragment.account) && jid.equals_bare(new Jid(details_fragment.jid))) {
|
||||||
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(jid, account, Conversation.Type.GROUPCHAT);
|
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(jid, account, Conversation.Type.GROUPCHAT);
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
using Xmpp;
|
using Xmpp;
|
||||||
|
using Xmpp.Xep;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
@ -86,9 +87,9 @@ protected class ConferenceDetailsFragment : Box {
|
||||||
set {
|
set {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
value.clicked.connect(() => {
|
value.clicked.connect(() => {
|
||||||
ok_button.label = _("Joining…");
|
on_ok_button_clicked();
|
||||||
ok_button.sensitive = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ok_button_ = value;
|
ok_button_ = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +97,6 @@ protected class ConferenceDetailsFragment : Box {
|
||||||
|
|
||||||
public ConferenceDetailsFragment(StreamInteractor stream_interactor) {
|
public ConferenceDetailsFragment(StreamInteractor stream_interactor) {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
this.ok_button = ok_button;
|
|
||||||
|
|
||||||
account_combobox.initialize(stream_interactor);
|
account_combobox.initialize(stream_interactor);
|
||||||
|
|
||||||
|
@ -114,7 +114,6 @@ protected class ConferenceDetailsFragment : Box {
|
||||||
jid_entry.key_release_event.connect(() => { done = true; return false; }); // just for notifying
|
jid_entry.key_release_event.connect(() => { done = true; return false; }); // just for notifying
|
||||||
nick_entry.key_release_event.connect(() => { done = true; return false; });
|
nick_entry.key_release_event.connect(() => { done = true; return false; });
|
||||||
|
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).enter_error.connect(on_enter_error);
|
|
||||||
notification_button.clicked.connect(() => { notification_revealer.set_reveal_child(false); });
|
notification_button.clicked.connect(() => { notification_revealer.set_reveal_child(false); });
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
@ -137,29 +136,40 @@ protected class ConferenceDetailsFragment : Box {
|
||||||
password_stack.set_visible_child_name("entry");
|
password_stack.set_visible_child_name("entry");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_enter_error(Account account, Jid jid, Xmpp.Xep.Muc.MucEnterError error) {
|
private async void on_ok_button_clicked() {
|
||||||
|
ok_button.label = _("Joining…");
|
||||||
|
ok_button.sensitive = false;
|
||||||
|
|
||||||
|
Muc.JoinResult? join_result = yield stream_interactor.get_module(MucManager.IDENTITY).join(account, new Jid(jid), nick, password);
|
||||||
|
|
||||||
ok_button.label = _("Join");
|
ok_button.label = _("Join");
|
||||||
ok_button.sensitive = true;
|
ok_button.sensitive = true;
|
||||||
|
if (join_result == null || join_result.nick != null) return;
|
||||||
|
|
||||||
string label_text = "";
|
string label_text = "";
|
||||||
switch (error) {
|
if (join_result.muc_error != null) {
|
||||||
case Xmpp.Xep.Muc.MucEnterError.PASSWORD_REQUIRED:
|
switch (join_result.muc_error) {
|
||||||
label_text = _("Password required to enter room");
|
case Muc.MucEnterError.PASSWORD_REQUIRED:
|
||||||
password_text_label.visible = true;
|
label_text = _("Password required to enter room");
|
||||||
password_stack.visible = true;
|
password_text_label.visible = true;
|
||||||
break;
|
password_stack.visible = true;
|
||||||
case Xmpp.Xep.Muc.MucEnterError.BANNED:
|
break;
|
||||||
label_text = _("Banned from joining or creating conference"); break;
|
case Muc.MucEnterError.BANNED:
|
||||||
case Xmpp.Xep.Muc.MucEnterError.ROOM_DOESNT_EXIST:
|
label_text = _("Banned from joining or creating conference"); break;
|
||||||
label_text = _("Room does not exist"); break;
|
case Muc.MucEnterError.ROOM_DOESNT_EXIST:
|
||||||
case Xmpp.Xep.Muc.MucEnterError.CREATION_RESTRICTED:
|
label_text = _("Room does not exist"); break;
|
||||||
label_text = _("Not allowed to create room"); break;
|
case Muc.MucEnterError.CREATION_RESTRICTED:
|
||||||
case Xmpp.Xep.Muc.MucEnterError.NOT_IN_MEMBER_LIST:
|
label_text = _("Not allowed to create room"); break;
|
||||||
label_text = _("Members-only room"); break;
|
case Muc.MucEnterError.NOT_IN_MEMBER_LIST:
|
||||||
case Xmpp.Xep.Muc.MucEnterError.USE_RESERVED_ROOMNICK:
|
label_text = _("Members-only room"); break;
|
||||||
case Xmpp.Xep.Muc.MucEnterError.NICK_CONFLICT:
|
case Muc.MucEnterError.USE_RESERVED_ROOMNICK:
|
||||||
label_text = _("Choose a different nick"); break;
|
case Muc.MucEnterError.NICK_CONFLICT:
|
||||||
case Xmpp.Xep.Muc.MucEnterError.OCCUPANT_LIMIT_REACHED:
|
label_text = _("Choose a different nick"); break;
|
||||||
label_text = _("Too many occupants in room"); break;
|
case Muc.MucEnterError.OCCUPANT_LIMIT_REACHED:
|
||||||
|
label_text = _("Too many occupants in room"); break;
|
||||||
|
}
|
||||||
|
} else if (join_result.stanza_error != null) {
|
||||||
|
label_text = _("Failed connecting to %s").printf((new Jid(jid)).domainpart);
|
||||||
}
|
}
|
||||||
notification_label.label = label_text;
|
notification_label.label = label_text;
|
||||||
notification_revealer.set_reveal_child(true);
|
notification_revealer.set_reveal_child(true);
|
||||||
|
|
|
@ -169,7 +169,6 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
|
||||||
content_area.add(conference_fragment);
|
content_area.add(conference_fragment);
|
||||||
dialog.response.connect((response_id) => {
|
dialog.response.connect((response_id) => {
|
||||||
if (response_id == ResponseType.OK) {
|
if (response_id == ResponseType.OK) {
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).join(conference_fragment.account, new Jid(conference_fragment.jid), conference_fragment.nick, conference_fragment.password);
|
|
||||||
dialog.destroy();
|
dialog.destroy();
|
||||||
} else if (response_id == ResponseType.CANCEL) {
|
} else if (response_id == ResponseType.CANCEL) {
|
||||||
dialog.destroy();
|
dialog.destroy();
|
||||||
|
|
|
@ -9,6 +9,7 @@ public class Flag : XmppStreamFlag {
|
||||||
private HashMap<Jid, string> room_names = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
private HashMap<Jid, string> room_names = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
|
|
||||||
private HashMap<Jid, string> enter_ids = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
private HashMap<Jid, string> enter_ids = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
|
public HashMap<Jid, Promise<JoinResult?>> enter_futures = new HashMap<Jid, Promise<JoinResult?>>(Jid.hash_func, Jid.equals_func);
|
||||||
private HashMap<Jid, string> own_nicks = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
private HashMap<Jid, string> own_nicks = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private HashMap<Jid, string> subjects = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
private HashMap<Jid, string> subjects = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private HashMap<Jid, Jid> subjects_by = new HashMap<Jid, Jid>(Jid.hash_bare_func, Jid.equals_bare_func);
|
private HashMap<Jid, Jid> subjects_by = new HashMap<Jid, Jid>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
|
|
|
@ -53,6 +53,12 @@ public enum Feature {
|
||||||
UNSECURED
|
UNSECURED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class JoinResult : Object {
|
||||||
|
public MucEnterError? muc_error { get; set; }
|
||||||
|
public string? stanza_error { get; set; }
|
||||||
|
public string? nick { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class Module : XmppStreamModule {
|
public class Module : XmppStreamModule {
|
||||||
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0045_muc_module");
|
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0045_muc_module");
|
||||||
|
|
||||||
|
@ -74,7 +80,7 @@ public class Module : XmppStreamModule {
|
||||||
received_pipeline_listener = new ReceivedPipelineListener(this);
|
received_pipeline_listener = new ReceivedPipelineListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enter(XmppStream stream, Jid bare_jid, string nick, string? password, DateTime? history_since) {
|
public async JoinResult? enter(XmppStream stream, Jid bare_jid, string nick, string? password, DateTime? history_since) {
|
||||||
Presence.Stanza presence = new Presence.Stanza();
|
Presence.Stanza presence = new Presence.Stanza();
|
||||||
presence.to = bare_jid.with_resource(nick);
|
presence.to = bare_jid.with_resource(nick);
|
||||||
StanzaNode x_node = new StanzaNode.build("x", NS_URI).add_self_xmlns();
|
StanzaNode x_node = new StanzaNode.build("x", NS_URI).add_self_xmlns();
|
||||||
|
@ -92,6 +98,16 @@ public class Module : XmppStreamModule {
|
||||||
|
|
||||||
query_room_info(stream, bare_jid);
|
query_room_info(stream, bare_jid);
|
||||||
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
||||||
|
|
||||||
|
var promise = new Promise<JoinResult?>();
|
||||||
|
stream.get_flag(Flag.IDENTITY).enter_futures[bare_jid] = promise;
|
||||||
|
try {
|
||||||
|
JoinResult? enter_result = yield promise.future.wait_async();
|
||||||
|
stream.get_flag(Flag.IDENTITY).enter_futures.unset(bare_jid);
|
||||||
|
return enter_result;
|
||||||
|
} catch (Gee.FutureError e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exit(XmppStream stream, Jid jid) {
|
public void exit(XmppStream stream, Jid jid) {
|
||||||
|
@ -262,7 +278,12 @@ public class Module : XmppStreamModule {
|
||||||
if (ErrorStanza.TYPE_CANCEL == error_stanza.type_) error = MucEnterError.USE_RESERVED_ROOMNICK;
|
if (ErrorStanza.TYPE_CANCEL == error_stanza.type_) error = MucEnterError.USE_RESERVED_ROOMNICK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (error != MucEnterError.NONE) room_enter_error(stream, bare_jid, error);
|
if (error != MucEnterError.NONE) {
|
||||||
|
room_enter_error(stream, bare_jid, error);
|
||||||
|
flag.enter_futures[bare_jid].set_value(new JoinResult() {muc_error=error});
|
||||||
|
} else {
|
||||||
|
flag.enter_futures[bare_jid].set_value(new JoinResult() {stanza_error=error_stanza.condition});
|
||||||
|
}
|
||||||
flag.finish_muc_enter(bare_jid);
|
flag.finish_muc_enter(bare_jid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,6 +300,7 @@ public class Module : XmppStreamModule {
|
||||||
if (flag.get_enter_id(bare_jid) != null) {
|
if (flag.get_enter_id(bare_jid) != null) {
|
||||||
room_entered(stream, bare_jid, presence.from.resourcepart);
|
room_entered(stream, bare_jid, presence.from.resourcepart);
|
||||||
flag.finish_muc_enter(bare_jid, presence.from.resourcepart);
|
flag.finish_muc_enter(bare_jid, presence.from.resourcepart);
|
||||||
|
flag.enter_futures[bare_jid].set_value(new JoinResult() {nick=presence.from.resourcepart});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
string? affiliation_str = x_node.get_deep_attribute("item", "affiliation");
|
string? affiliation_str = x_node.get_deep_attribute("item", "affiliation");
|
||||||
|
|
Loading…
Reference in a new issue