2017-03-02 14:37:32 +00:00
|
|
|
using Gee;
|
|
|
|
|
|
|
|
using Xmpp;
|
2019-11-17 16:53:46 +00:00
|
|
|
using Xmpp.Xep;
|
2017-03-02 14:37:32 +00:00
|
|
|
using Dino.Entities;
|
|
|
|
|
|
|
|
namespace Dino {
|
|
|
|
public class MucManager : StreamInteractionModule, Object {
|
2017-03-19 11:55:36 +00:00
|
|
|
public static ModuleIdentity<MucManager> IDENTITY = new ModuleIdentity<MucManager>("muc_manager");
|
|
|
|
public string id { get { return IDENTITY.id; } }
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-04-11 16:06:01 +00:00
|
|
|
public signal void left(Account account, Jid jid);
|
|
|
|
public signal void subject_set(Account account, Jid jid, string? subject);
|
2018-08-20 00:59:58 +00:00
|
|
|
public signal void room_name_set(Account account, Jid jid, string? room_name);
|
2018-12-04 09:21:24 +00:00
|
|
|
public signal void private_room_occupant_updated(Account account, Jid room, Jid occupant);
|
2019-08-22 14:05:28 +00:00
|
|
|
public signal void invite_received(Account account, Jid room_jid, Jid from_jid, string? password, string? reason);
|
2019-09-28 19:40:43 +00:00
|
|
|
public signal void bookmarks_updated(Account account, Set<Conference> conferences);
|
|
|
|
public signal void conference_added(Account account, Conference conference);
|
|
|
|
public signal void conference_removed(Account account, Jid jid);
|
2017-03-02 14:37:32 +00:00
|
|
|
|
|
|
|
private StreamInteractor stream_interactor;
|
2017-06-13 14:04:26 +00:00
|
|
|
private HashMap<Jid, Xep.Muc.MucEnterError> enter_errors = new HashMap<Jid, Xep.Muc.MucEnterError>(Jid.hash_func, Jid.equals_func);
|
2018-01-19 21:37:02 +00:00
|
|
|
private ReceivedMessageListener received_message_listener;
|
2019-09-28 19:40:43 +00:00
|
|
|
private HashMap<Account, BookmarksProvider> bookmarks_provider = new HashMap<Account, BookmarksProvider>(Account.hash_func, Account.equals_func);
|
2017-03-02 14:37:32 +00:00
|
|
|
public static void start(StreamInteractor stream_interactor) {
|
|
|
|
MucManager m = new MucManager(stream_interactor);
|
|
|
|
stream_interactor.add_module(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
private MucManager(StreamInteractor stream_interactor) {
|
|
|
|
this.stream_interactor = stream_interactor;
|
2018-01-19 21:37:02 +00:00
|
|
|
this.received_message_listener = new ReceivedMessageListener(stream_interactor);
|
2017-03-02 14:37:32 +00:00
|
|
|
stream_interactor.account_added.connect(on_account_added);
|
|
|
|
stream_interactor.stream_negotiated.connect(on_stream_negotiated);
|
2018-01-19 21:37:02 +00:00
|
|
|
stream_interactor.get_module(MessageProcessor.IDENTITY).received_pipeline.connect(received_message_listener);
|
2020-01-15 22:44:15 +00:00
|
|
|
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_deactivated.connect((conversation) => {
|
|
|
|
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
|
|
|
|
part(conversation.account, conversation.counterpart);
|
|
|
|
}
|
|
|
|
});
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2019-11-17 16:53:46 +00:00
|
|
|
public async Muc.JoinResult? join(Account account, Jid jid, string? nick, string? password) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
2019-11-17 16:53:46 +00:00
|
|
|
if (stream == null) return null;
|
2020-01-08 17:15:42 +00:00
|
|
|
string nick_ = (nick ?? account.localpart) ?? account.domainpart;
|
2017-08-05 10:56:32 +00:00
|
|
|
|
2017-08-16 15:58:04 +00:00
|
|
|
DateTime? history_since = null;
|
2017-08-05 10:56:32 +00:00
|
|
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(jid, account);
|
|
|
|
if (conversation != null) {
|
|
|
|
Entities.Message? last_message = stream_interactor.get_module(MessageStorage.IDENTITY).get_last_message(conversation);
|
2017-08-16 15:58:04 +00:00
|
|
|
if (last_message != null) history_since = last_message.time;
|
2017-08-05 10:56:32 +00:00
|
|
|
}
|
2018-08-20 00:59:58 +00:00
|
|
|
|
2019-12-24 15:46:55 +00:00
|
|
|
Muc.JoinResult? res = yield stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid, nick_, password, history_since);
|
|
|
|
|
|
|
|
if (res.nick != null) {
|
|
|
|
// Join completed
|
|
|
|
enter_errors.unset(jid);
|
|
|
|
set_autojoin(account, stream, jid, nick, password);
|
|
|
|
stream_interactor.get_module(MessageProcessor.IDENTITY).send_unsent_messages(account, jid);
|
|
|
|
|
|
|
|
Conversation joined_conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(jid, account, Conversation.Type.GROUPCHAT);
|
|
|
|
joined_conversation.nickname = nick;
|
|
|
|
stream_interactor.get_module(ConversationManager.IDENTITY).start_conversation(conversation);
|
|
|
|
} else if (res.muc_error != null) {
|
|
|
|
// Join failed
|
|
|
|
enter_errors[jid] = res.muc_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void part(Account account, Jid jid) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
2017-04-23 11:50:32 +00:00
|
|
|
if (stream == null) return;
|
2019-09-28 19:40:43 +00:00
|
|
|
unset_autojoin(account, stream, jid);
|
2018-01-12 20:03:09 +00:00
|
|
|
stream.get_module(Xep.Muc.Module.IDENTITY).exit(stream, jid.bare_jid);
|
2017-04-23 11:50:32 +00:00
|
|
|
|
|
|
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(jid, account);
|
|
|
|
if (conversation != null) stream_interactor.get_module(ConversationManager.IDENTITY).close_conversation(conversation);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 00:34:28 +00:00
|
|
|
public async DataForms.DataForm? get_config_form(Account account, Jid jid) {
|
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream == null) return null;
|
|
|
|
return yield stream.get_module(Xep.Muc.Module.IDENTITY).get_config_form(stream, jid);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void set_config_form(Account account, Jid jid, DataForms.DataForm data_form) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
2017-05-30 20:47:16 +00:00
|
|
|
if (stream == null) return;
|
2019-12-16 00:34:28 +00:00
|
|
|
stream.get_module(Xep.Muc.Module.IDENTITY).set_config_form(stream, jid, data_form);
|
2017-05-30 20:47:16 +00:00
|
|
|
}
|
|
|
|
|
2017-03-02 14:37:32 +00:00
|
|
|
public void change_subject(Account account, Jid jid, string subject) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_subject(stream, jid.bare_jid, subject);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void change_nick(Account account, Jid jid, string new_nick) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_nick(stream, jid.bare_jid, new_nick);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2017-06-11 11:59:24 +00:00
|
|
|
public void invite(Account account, Jid muc, Jid invitee) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).invite(stream, muc.bare_jid, invitee.bare_jid);
|
2017-06-11 11:59:24 +00:00
|
|
|
}
|
|
|
|
|
2017-03-02 14:37:32 +00:00
|
|
|
public void kick(Account account, Jid jid, string nick) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).kick(stream, jid.bare_jid, nick);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2018-01-09 00:06:32 +00:00
|
|
|
public void change_affiliation(Account account, Jid jid, string nick, string role) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_affiliation(stream, jid.bare_jid, nick, role);
|
2018-01-09 00:06:32 +00:00
|
|
|
}
|
|
|
|
|
2017-06-11 11:59:24 +00:00
|
|
|
public bool kick_possible(Account account, Jid occupant) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) return stream.get_module(Xep.Muc.Module.IDENTITY).kick_possible(stream, occupant);
|
2017-06-11 11:59:24 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-12-04 09:21:24 +00:00
|
|
|
//the term `private room` is a short hand for members-only+non-anonymous rooms
|
|
|
|
public bool is_private_room(Account account, Jid jid) {
|
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream == null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Xep.Muc.Flag? flag = stream.get_flag(Xep.Muc.Flag.IDENTITY);
|
|
|
|
if (flag == null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return flag.has_room_feature(jid, Xep.Muc.Feature.NON_ANONYMOUS) && flag.has_room_feature(jid, Xep.Muc.Feature.MEMBERS_ONLY);
|
|
|
|
}
|
|
|
|
|
2019-05-11 22:09:50 +00:00
|
|
|
public bool is_public_room(Account account, Jid jid) {
|
|
|
|
return is_groupchat(jid, account) && !is_private_room(account, jid);
|
|
|
|
}
|
|
|
|
|
2018-01-12 20:03:09 +00:00
|
|
|
public Gee.List<Jid>? get_occupants(Jid jid, Account account) {
|
2017-03-23 23:15:00 +00:00
|
|
|
if (is_groupchat(jid, account)) {
|
2018-07-31 15:49:10 +00:00
|
|
|
Gee.List<Jid> ret = new ArrayList<Jid>(Jid.equals_func);
|
|
|
|
Gee.List<Jid>? full_jids = stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(jid, account);
|
|
|
|
if (full_jids != null) {
|
|
|
|
ret.add_all(full_jids);
|
|
|
|
// Remove eventual presence from bare jid
|
|
|
|
ret.remove(jid);
|
|
|
|
}
|
|
|
|
return ret;
|
2017-03-23 23:15:00 +00:00
|
|
|
}
|
|
|
|
return null;
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2018-01-12 20:03:09 +00:00
|
|
|
public Gee.List<Jid>? get_other_occupants(Jid jid, Account account) {
|
|
|
|
Gee.List<Jid>? occupants = get_occupants(jid, account);
|
2017-06-11 11:59:24 +00:00
|
|
|
Jid? own_jid = get_own_jid(jid, account);
|
|
|
|
if (occupants != null && own_jid != null) {
|
2018-07-31 15:49:10 +00:00
|
|
|
occupants.remove(own_jid);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
return occupants;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool is_groupchat(Jid jid, Account account) {
|
2019-10-18 14:52:29 +00:00
|
|
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(jid, account, Conversation.Type.GROUPCHAT);
|
|
|
|
return !jid.is_full() && conversation != null;
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public bool is_groupchat_occupant(Jid jid, Account account) {
|
2018-08-19 23:12:11 +00:00
|
|
|
return is_groupchat(jid.bare_jid, account) && jid.resourcepart != null;
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2019-09-28 19:40:43 +00:00
|
|
|
public async Set<Conference>? get_bookmarks(Account account) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
2019-09-28 19:40:43 +00:00
|
|
|
if (stream == null) return null;
|
|
|
|
|
|
|
|
return yield bookmarks_provider[account].get_conferences(stream);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2019-09-28 19:40:43 +00:00
|
|
|
public void add_bookmark(Account account, Conference conference) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
2017-03-02 14:37:32 +00:00
|
|
|
if (stream != null) {
|
2019-09-28 19:40:43 +00:00
|
|
|
bookmarks_provider[account].add_conference.begin(stream, conference);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-28 19:40:43 +00:00
|
|
|
public void remove_bookmark(Account account, Conference conference) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
2017-03-02 14:37:32 +00:00
|
|
|
if (stream != null) {
|
2019-09-28 19:40:43 +00:00
|
|
|
bookmarks_provider[account].remove_conference.begin(stream, conference);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:29:02 +00:00
|
|
|
public string? get_room_name(Account account, Jid jid) {
|
2018-04-17 18:11:44 +00:00
|
|
|
Xep.Muc.Flag? flag = get_muc_flag(account);
|
|
|
|
if (flag != null) {
|
|
|
|
return flag.get_room_name(jid);
|
|
|
|
}
|
|
|
|
return null;
|
2017-06-16 12:29:02 +00:00
|
|
|
}
|
|
|
|
|
2017-03-02 14:37:32 +00:00
|
|
|
public string? get_groupchat_subject(Jid jid, Account account) {
|
2018-04-17 18:11:44 +00:00
|
|
|
Xep.Muc.Flag? flag = get_muc_flag(account);
|
|
|
|
if (flag != null) {
|
|
|
|
return flag.get_muc_subject(jid.bare_jid);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Jid? get_real_jid(Jid jid, Account account) {
|
2018-04-17 18:11:44 +00:00
|
|
|
Xep.Muc.Flag? flag = get_muc_flag(account);
|
|
|
|
if (flag != null) {
|
|
|
|
return flag.get_real_jid(jid);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-06-11 11:59:24 +00:00
|
|
|
public Xep.Muc.Role? get_role(Jid jid, Account account) {
|
2018-04-17 18:11:44 +00:00
|
|
|
Xep.Muc.Flag? flag = get_muc_flag(account);
|
|
|
|
if (flag != null) {
|
|
|
|
return flag.get_occupant_role(jid);
|
|
|
|
}
|
2017-06-11 11:59:24 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-05-18 21:14:44 +00:00
|
|
|
public Xep.Muc.Affiliation? get_affiliation(Jid muc_jid, Jid jid, Account account) {
|
2018-04-17 18:11:44 +00:00
|
|
|
Xep.Muc.Flag? flag = get_muc_flag(account);
|
|
|
|
if (flag != null) {
|
|
|
|
return flag.get_affiliation(muc_jid, jid);
|
|
|
|
}
|
2017-05-18 21:14:44 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Gee.List<Jid>? get_offline_members(Jid jid, Account account) {
|
2018-04-17 18:11:44 +00:00
|
|
|
Xep.Muc.Flag? flag = get_muc_flag(account);
|
|
|
|
if (flag != null) {
|
|
|
|
return flag.get_offline_members(jid);
|
2017-05-18 21:14:44 +00:00
|
|
|
}
|
2018-01-12 20:03:09 +00:00
|
|
|
return null;
|
2017-05-18 21:14:44 +00:00
|
|
|
}
|
|
|
|
|
2018-12-04 09:21:24 +00:00
|
|
|
public Gee.List<Jid>? get_other_offline_members(Jid jid, Account account) {
|
|
|
|
Gee.List<Jid>? occupants = get_offline_members(jid, account);
|
|
|
|
if (occupants != null) {
|
|
|
|
occupants.remove(account.bare_jid);
|
|
|
|
}
|
|
|
|
return occupants;
|
|
|
|
}
|
|
|
|
|
2017-06-11 11:59:24 +00:00
|
|
|
public Jid? get_own_jid(Jid muc_jid, Account account) {
|
2019-12-22 03:10:53 +00:00
|
|
|
try {
|
|
|
|
Xep.Muc.Flag? flag = get_muc_flag(account);
|
|
|
|
if (flag != null) {
|
|
|
|
string? nick = flag.get_muc_nick(muc_jid);
|
|
|
|
if (nick != null) return muc_jid.with_resource(nick);
|
|
|
|
}
|
|
|
|
} catch (InvalidJidError e) {
|
|
|
|
warning("Joined MUC with invalid Jid: %s", e.message);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2018-04-17 18:11:44 +00:00
|
|
|
private Xep.Muc.Flag? get_muc_flag(Account account) {
|
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) {
|
|
|
|
return stream.get_flag(Xep.Muc.Flag.IDENTITY);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-04-11 16:06:01 +00:00
|
|
|
public bool is_joined(Jid jid, Account account) {
|
2017-06-11 11:59:24 +00:00
|
|
|
return get_own_jid(jid, account) != null;
|
2017-04-11 16:06:01 +00:00
|
|
|
}
|
|
|
|
|
2017-03-02 14:37:32 +00:00
|
|
|
private void on_account_added(Account account) {
|
2017-04-11 16:06:01 +00:00
|
|
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).self_removed_from_room.connect( (stream, jid, code) => {
|
2018-01-12 20:03:09 +00:00
|
|
|
left(account, jid);
|
2017-04-11 16:06:01 +00:00
|
|
|
});
|
2017-03-10 20:45:56 +00:00
|
|
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).subject_set.connect( (stream, subject, jid) => {
|
2018-01-12 20:03:09 +00:00
|
|
|
subject_set(account, jid, subject);
|
2017-03-02 14:37:32 +00:00
|
|
|
});
|
2019-08-22 14:05:28 +00:00
|
|
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).invite_received.connect( (stream, room_jid, from_jid, password, reason) => {
|
|
|
|
invite_received(account, room_jid, from_jid, password, reason);
|
|
|
|
});
|
2018-08-20 00:59:58 +00:00
|
|
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).room_name_set.connect( (stream, jid, room_name) => {
|
|
|
|
room_name_set(account, jid, room_name);
|
|
|
|
});
|
2018-12-04 09:21:24 +00:00
|
|
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).received_occupant_jid.connect( (stream, room, occupant) => {
|
|
|
|
if (is_private_room(account, room.bare_jid)) {
|
|
|
|
private_room_occupant_updated(account, room, occupant);
|
|
|
|
}
|
|
|
|
});
|
2019-09-28 19:40:43 +00:00
|
|
|
|
|
|
|
bookmarks_provider[account] = stream_interactor.module_manager.get_module(account, Xep.Bookmarks.Module.IDENTITY);
|
|
|
|
|
|
|
|
bookmarks_provider[account].received_conferences.connect( (stream, conferences) => {
|
2017-04-23 11:50:32 +00:00
|
|
|
sync_autojoin_active(account, conferences);
|
2017-03-02 14:37:32 +00:00
|
|
|
bookmarks_updated(account, conferences);
|
|
|
|
});
|
2019-09-28 19:40:43 +00:00
|
|
|
bookmarks_provider[account].conference_added.connect( (stream, conference) => {
|
2020-01-17 19:48:29 +00:00
|
|
|
// TODO join (for Bookmarks2)
|
2019-09-28 19:40:43 +00:00
|
|
|
conference_added(account, conference);
|
|
|
|
});
|
|
|
|
bookmarks_provider[account].conference_removed.connect( (stream, jid) => {
|
2020-01-17 19:48:29 +00:00
|
|
|
// TODO part (for Bookmarks2)
|
2019-09-28 19:40:43 +00:00
|
|
|
conference_removed(account, jid);
|
|
|
|
});
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2019-09-28 19:40:43 +00:00
|
|
|
private async void on_stream_negotiated(Account account, XmppStream stream) {
|
|
|
|
if (bookmarks_provider[account] == null) return;
|
|
|
|
|
|
|
|
Set<Conference>? conferences = yield bookmarks_provider[account].get_conferences(stream);
|
|
|
|
|
|
|
|
if (conferences == null) {
|
|
|
|
join_all_active(account);
|
|
|
|
} else {
|
|
|
|
sync_autojoin_active(account, conferences);
|
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2018-01-12 20:13:46 +00:00
|
|
|
private void join_all_active(Account account) {
|
|
|
|
Gee.List<Conversation> conversations = stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations(account);
|
|
|
|
foreach (Conversation conversation in conversations) {
|
|
|
|
if (conversation.type_ == Conversation.Type.GROUPCHAT && conversation.nickname != null) {
|
2019-11-17 16:53:46 +00:00
|
|
|
join.begin(account, conversation.counterpart, conversation.nickname, null);
|
2018-01-12 20:13:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-28 19:40:43 +00:00
|
|
|
private void sync_autojoin_active(Account account, Set<Conference> conferences) {
|
2020-01-17 19:48:29 +00:00
|
|
|
Gee.List<Conversation> active_conversations = stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations(account);
|
2017-04-23 11:50:32 +00:00
|
|
|
|
2020-01-17 19:48:29 +00:00
|
|
|
// Join auto-join MUCs
|
|
|
|
foreach (Conference conference in conferences) {
|
|
|
|
if (!conference.autojoin) continue;
|
2019-09-28 19:40:43 +00:00
|
|
|
|
2017-04-23 11:50:32 +00:00
|
|
|
bool is_active = false;
|
2020-01-17 19:48:29 +00:00
|
|
|
foreach (Conversation conversation in active_conversations) {
|
|
|
|
if (conference.jid.equals(conversation.counterpart)) {
|
|
|
|
is_active = true;
|
|
|
|
}
|
2017-04-23 11:50:32 +00:00
|
|
|
}
|
2020-01-17 19:48:29 +00:00
|
|
|
if (!is_active || !is_joined(conference.jid, account)) {
|
2019-11-17 16:53:46 +00:00
|
|
|
join.begin(account, conference.jid, conference.nick, conference.password);
|
2017-04-23 11:50:32 +00:00
|
|
|
}
|
2020-01-17 19:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Part MUCs that aren't auto-join (which closes those conversations)
|
|
|
|
foreach (Conversation conversation in active_conversations) {
|
|
|
|
if (conversation.type_ != Conversation.Type.GROUPCHAT) continue;
|
|
|
|
|
|
|
|
bool should_be_active = false;
|
|
|
|
foreach (Conference conference in conferences) {
|
|
|
|
if (conference.jid.equals(conversation.counterpart) && conference.autojoin) {
|
|
|
|
should_be_active = true;
|
2019-09-28 19:40:43 +00:00
|
|
|
}
|
|
|
|
}
|
2020-01-17 19:48:29 +00:00
|
|
|
if (!should_be_active) {
|
|
|
|
part(conversation.account, conversation.counterpart);
|
2019-09-28 19:40:43 +00:00
|
|
|
}
|
2017-04-23 11:50:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-28 19:40:43 +00:00
|
|
|
private void set_autojoin(Account account, XmppStream stream, Jid jid, string? nick, string? password) {
|
|
|
|
bookmarks_provider[account].get_conferences.begin(stream, (_, res) => {
|
|
|
|
Set<Conference>? conferences = bookmarks_provider[account].get_conferences.end(res);
|
2018-01-12 20:03:09 +00:00
|
|
|
if (conferences == null) return;
|
2019-09-28 19:40:43 +00:00
|
|
|
|
|
|
|
foreach (Conference conference in conferences) {
|
|
|
|
if (conference.jid.equals(jid)) {
|
2017-04-23 11:50:32 +00:00
|
|
|
if (!conference.autojoin) {
|
2020-02-20 15:29:23 +00:00
|
|
|
Conference new_conference = new Conference() { jid=jid, nick=conference.nick, name=conference.name, password=conference.password, autojoin=true };
|
|
|
|
bookmarks_provider[account].replace_conference.begin(stream, jid, new_conference);
|
2017-04-23 11:50:32 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2020-01-08 17:15:42 +00:00
|
|
|
Conference changed = new Xep.Bookmarks.Bookmarks1Conference(jid) { nick=nick, password=password, autojoin=true };
|
2019-09-28 19:40:43 +00:00
|
|
|
bookmarks_provider[account].add_conference.begin(stream, changed);
|
2017-06-13 16:14:59 +00:00
|
|
|
});
|
2017-04-23 11:50:32 +00:00
|
|
|
}
|
|
|
|
|
2019-09-28 19:40:43 +00:00
|
|
|
private void unset_autojoin(Account account, XmppStream stream, Jid jid) {
|
|
|
|
bookmarks_provider[account].get_conferences.begin(stream, (_, res) => {
|
|
|
|
Set<Conference>? conferences = bookmarks_provider[account].get_conferences.end(res);
|
2018-01-12 20:03:09 +00:00
|
|
|
if (conferences == null) return;
|
2019-09-28 19:40:43 +00:00
|
|
|
|
|
|
|
foreach (Conference conference in conferences) {
|
|
|
|
if (conference.jid.equals(jid)) {
|
2017-04-23 11:50:32 +00:00
|
|
|
if (conference.autojoin) {
|
2020-02-20 15:29:23 +00:00
|
|
|
Conference new_conference = new Conference() { jid=jid, nick=conference.nick, name=conference.name, password=conference.password, autojoin=false };
|
|
|
|
bookmarks_provider[account].replace_conference.begin(stream, jid, new_conference);
|
2018-01-16 15:16:43 +00:00
|
|
|
return;
|
2017-04-23 11:50:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-06-13 16:14:59 +00:00
|
|
|
});
|
2017-04-23 11:50:32 +00:00
|
|
|
}
|
2018-01-19 21:37:02 +00:00
|
|
|
|
|
|
|
private class ReceivedMessageListener : MessageListener {
|
|
|
|
|
2018-01-30 16:29:54 +00:00
|
|
|
public string[] after_actions_const = new string[]{ };
|
|
|
|
public override string action_group { get { return "MUC"; } }
|
2018-01-19 21:37:02 +00:00
|
|
|
public override string[] after_actions { get { return after_actions_const; } }
|
|
|
|
|
|
|
|
private StreamInteractor stream_interactor;
|
|
|
|
|
|
|
|
public ReceivedMessageListener(StreamInteractor stream_interactor) {
|
|
|
|
this.stream_interactor = stream_interactor;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override async bool run(Entities.Message message, Xmpp.MessageStanza stanza, Conversation conversation) {
|
|
|
|
if (conversation.type_ != Conversation.Type.GROUPCHAT) return false;
|
|
|
|
XmppStream stream = stream_interactor.get_stream(conversation.account);
|
|
|
|
if (stream == null) return false;
|
2019-05-21 19:42:39 +00:00
|
|
|
if (Xep.DelayedDelivery.MessageFlag.get_flag(stanza) == null) {
|
2018-01-19 21:37:02 +00:00
|
|
|
Jid? real_jid = stream.get_flag(Xep.Muc.Flag.IDENTITY).get_real_jid(message.counterpart);
|
|
|
|
if (real_jid != null && !real_jid.equals(message.counterpart)) {
|
|
|
|
message.real_jid = real_jid.bare_jid;
|
|
|
|
}
|
|
|
|
}
|
2018-03-07 19:41:08 +00:00
|
|
|
Jid? own_muc_jid = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(message.counterpart.bare_jid, conversation.account);
|
2019-03-16 00:13:40 +00:00
|
|
|
if (stanza.id != null && own_muc_jid != null && message.from.equals(own_muc_jid)) {
|
|
|
|
Entities.Message? m = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(stanza.id, conversation);
|
|
|
|
if (m != null) {
|
|
|
|
// For own messages from this device (msg is a duplicate)
|
|
|
|
m.marked = Message.Marked.RECEIVED;
|
2018-01-19 21:37:02 +00:00
|
|
|
}
|
2018-08-05 22:51:23 +00:00
|
|
|
// For own messages from other devices (msg is not a duplicate msg)
|
|
|
|
message.marked = Message.Marked.RECEIVED;
|
2018-01-19 21:37:02 +00:00
|
|
|
}
|
2018-03-07 19:41:08 +00:00
|
|
|
|
2018-01-19 21:37:02 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
2017-03-19 11:55:36 +00:00
|
|
|
|
2017-06-13 16:14:59 +00:00
|
|
|
}
|