Sync MUC join/part behaviour with autojoin flag in bookmarks
This commit is contained in:
parent
5c8275ed4e
commit
3eb9aa0fa7
37
README.md
37
README.md
|
@ -1,24 +1,7 @@
|
||||||
Dino
|
![Dino](https://cdn.rawgit.com/fiaxh/3cb1391c5a94443098d004b4bf7c712c/raw/62f6a5e7de8402a0a89ffc73e8d1ed170054051c/dino-writing.svg)
|
||||||
====
|
=======
|
||||||
|
|
||||||
![screenshots](http://i.imgur.com/xIKPEFF.png)
|
![screenshots](https://i.imgur.com/xIKPEFF.png)
|
||||||
|
|
||||||
Install
|
|
||||||
-------
|
|
||||||
| OS | Package|
|
|
||||||
| ------------ | ------ |
|
|
||||||
| Arch Linux | [`dino-git`](https://aur.archlinux.org/packages/dino-git/) (AUR) |
|
|
||||||
| Fedora ≥ 25 | [`dino`](https://copr.fedorainfracloud.org/coprs/larma/dino/) (copr) |
|
|
||||||
|
|
||||||
**Dependencies**
|
|
||||||
|
|
||||||
* GLib (≥ 2.38)
|
|
||||||
* GTK (≥ 3.22)
|
|
||||||
* GPGME (For the OpenPGP plugin)
|
|
||||||
* libgee-0.8 (≥ 0.10)
|
|
||||||
* libgcrypt (For the OMEMO plugin)
|
|
||||||
* libnotify
|
|
||||||
* SQLite3
|
|
||||||
|
|
||||||
Build
|
Build
|
||||||
-----
|
-----
|
||||||
|
@ -31,12 +14,26 @@ Build
|
||||||
* ninja(-build) (recommend)
|
* ninja(-build) (recommend)
|
||||||
* valac (≥ 0.30)
|
* valac (≥ 0.30)
|
||||||
|
|
||||||
|
**Run-time dependencies**
|
||||||
|
|
||||||
|
* GLib (≥ 2.38)
|
||||||
|
* GTK (≥ 3.22)
|
||||||
|
* GPGME (For the OpenPGP plugin)
|
||||||
|
* libgee-0.8 (≥ 0.10)
|
||||||
|
* libgcrypt (For the OMEMO plugin)
|
||||||
|
* libnotify
|
||||||
|
* SQLite3
|
||||||
|
|
||||||
**Instructions**
|
**Instructions**
|
||||||
|
|
||||||
./configure
|
./configure
|
||||||
make
|
make
|
||||||
build/dino
|
build/dino
|
||||||
|
|
||||||
|
Resources
|
||||||
|
---------
|
||||||
|
Please refer to [the wiki](https://github.com/dino/dino/wiki) for further information.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
Dino - Modern Jabber/XMPP Client using GTK+/Vala
|
Dino - Modern Jabber/XMPP Client using GTK+/Vala
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class ConversationManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gee.List<Conversation> get_active_conversations() {
|
public Gee.List<Conversation> get_active_conversations() {
|
||||||
ArrayList<Conversation> ret = new ArrayList<Conversation>(Conversation.equals_func);
|
Gee.List<Conversation> ret = new ArrayList<Conversation>(Conversation.equals_func);
|
||||||
foreach (Account account in conversations.keys) {
|
foreach (Account account in conversations.keys) {
|
||||||
foreach (Conversation conversation in conversations[account].values) {
|
foreach (Conversation conversation in conversations[account].values) {
|
||||||
if(conversation.active) ret.add(conversation);
|
if(conversation.active) ret.add(conversation);
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
public signal void joined(Account account, Jid jid, string nick);
|
public signal void joined(Account account, Jid jid, string nick);
|
||||||
public signal void left(Account account, Jid jid);
|
public signal void left(Account account, Jid jid);
|
||||||
public signal void subject_set(Account account, Jid jid, string? subject);
|
public signal void subject_set(Account account, Jid jid, string? subject);
|
||||||
public signal void bookmarks_updated(Account account, ArrayList<Xep.Bookmarks.Conference> conferences);
|
public signal void bookmarks_updated(Account account, Gee.List<Xep.Bookmarks.Conference> conferences);
|
||||||
|
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
|
|
||||||
|
@ -31,12 +31,18 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
Core.XmppStream stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart;
|
string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart;
|
||||||
|
set_autojoin(stream, jid, nick_, password);
|
||||||
stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid.to_string(), nick_, password);
|
stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid.to_string(), nick_, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void part(Account account, Jid jid) {
|
public void part(Account account, Jid jid) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
Core.XmppStream stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).exit(stream, jid.bare_jid.to_string());
|
if (stream == null) return;
|
||||||
|
unset_autojoin(stream, jid);
|
||||||
|
stream.get_module(Xep.Muc.Module.IDENTITY).exit(stream, jid.bare_jid.to_string());
|
||||||
|
|
||||||
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(jid, account);
|
||||||
|
if (conversation != null) stream_interactor.get_module(ConversationManager.IDENTITY).close_conversation(conversation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_subject(Account account, Jid jid, string subject) {
|
public void change_subject(Account account, Jid jid, string subject) {
|
||||||
|
@ -156,7 +162,8 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).subject_set.connect( (stream, subject, jid) => {
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).subject_set.connect( (stream, subject, jid) => {
|
||||||
subject_set(account, new Jid(jid), subject);
|
subject_set(account, new Jid(jid), subject);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Xep.Bookmarks.Module.IDENTITY).conferences_updated.connect( (stream, conferences) => {
|
stream_interactor.module_manager.get_module(account, Xep.Bookmarks.Module.IDENTITY).received_conferences.connect( (stream, conferences) => {
|
||||||
|
sync_autojoin_active(account, conferences);
|
||||||
bookmarks_updated(account, conferences);
|
bookmarks_updated(account, conferences);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -195,6 +202,70 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sync_autojoin_active(Account account, Gee.List<Xep.Bookmarks.Conference> conferences) {
|
||||||
|
Gee.List<Conversation> conversations = stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations();
|
||||||
|
leave_non_autojoin(account, conferences, conversations);
|
||||||
|
join_autojoin(account, conferences, conversations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void leave_non_autojoin(Account account, Gee.List<Xep.Bookmarks.Conference> conferences, Gee.List<Conversation> conversations) {
|
||||||
|
foreach (Conversation conversation in conversations) {
|
||||||
|
if (conversation.type_ != Conversation.Type.GROUPCHAT || !conversation.account.equals(account)) continue;
|
||||||
|
bool is_autojoin = false;
|
||||||
|
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
||||||
|
if (conference.jid == conversation.counterpart.to_string()) {
|
||||||
|
if (conference.autojoin) is_autojoin = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_autojoin) {
|
||||||
|
part(account, conversation.counterpart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void join_autojoin(Account account, Gee.List<Xep.Bookmarks.Conference> conferences, Gee.List<Conversation> conversations) {
|
||||||
|
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
||||||
|
if (!conference.autojoin) continue;
|
||||||
|
bool is_active = false;
|
||||||
|
foreach (Conversation conversation in conversations) {
|
||||||
|
if (conference.jid == conversation.counterpart.to_string()) is_active = true;
|
||||||
|
}
|
||||||
|
if (!is_active) {
|
||||||
|
join(account, new Jid(conference.jid), conference.nick, conference.password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void set_autojoin(Core.XmppStream stream, Jid jid, string? nick, string? password) {
|
||||||
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (stream, conferences, storage) => {
|
||||||
|
Triple<Jid, string?, string?> triple = storage as Triple<Jid, string?, string?>;
|
||||||
|
Xep.Bookmarks.Conference changed = new Xep.Bookmarks.Conference(triple.a.to_string()) { nick=triple.b, password=triple.c, autojoin=true };
|
||||||
|
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
||||||
|
if (conference.jid == triple.a.bare_jid.to_string() && conference.nick == triple.b && conference.password == triple.c) {
|
||||||
|
if (!conference.autojoin) {
|
||||||
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).replace_conference(stream, conference, changed);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).add_conference(stream, changed);
|
||||||
|
}, Triple.create(jid, nick, password));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unset_autojoin(Core.XmppStream stream, Jid jid) {
|
||||||
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (stream, conferences, storage) => {
|
||||||
|
Jid jid_ = storage as Jid;
|
||||||
|
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
||||||
|
if (conference.jid == jid_.bare_jid.to_string()) {
|
||||||
|
if (conference.autojoin) {
|
||||||
|
Xep.Bookmarks.Conference change = new Xep.Bookmarks.Conference(conference.jid) { nick=conference.nick, password=conference.password, autojoin=false };
|
||||||
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).replace_conference(stream, conference, change);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, jid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ protected class RosterList : FilterableList {
|
||||||
public signal void conversation_selected(Conversation? conversation);
|
public signal void conversation_selected(Conversation? conversation);
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
|
|
||||||
private HashMap<Jid, ListRow> rows = new HashMap<Jid, ListRow>(Jid.hash_func, Jid.equals_func);
|
private HashMap<Account, HashMap<Jid, ListRow>> rows = new HashMap<Account, HashMap<Jid, ListRow>>(Account.hash_func, Account.equals_func);
|
||||||
|
|
||||||
public RosterList(StreamInteractor stream_interactor) {
|
public RosterList(StreamInteractor stream_interactor) {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
|
@ -26,6 +26,7 @@ protected class RosterList : FilterableList {
|
||||||
Idle.add(() => { on_updated_roster_item(account, jid, roster_item); return false;});});
|
Idle.add(() => { on_updated_roster_item(account, jid, roster_item); return false;});});
|
||||||
|
|
||||||
foreach (Account account in stream_interactor.get_accounts()) {
|
foreach (Account account in stream_interactor.get_accounts()) {
|
||||||
|
rows[account] = new HashMap<Jid, ListRow>(Jid.hash_func, Jid.equals_func);
|
||||||
foreach (Roster.Item roster_item in stream_interactor.get_module(RosterManager.IDENTITY).get_roster(account)) {
|
foreach (Roster.Item roster_item in stream_interactor.get_module(RosterManager.IDENTITY).get_roster(account)) {
|
||||||
on_updated_roster_item(account, new Jid(roster_item.jid), roster_item);
|
on_updated_roster_item(account, new Jid(roster_item.jid), roster_item);
|
||||||
}
|
}
|
||||||
|
@ -33,16 +34,16 @@ protected class RosterList : FilterableList {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_removed_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
private void on_removed_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
||||||
if (rows.has_key(jid)) {
|
if (rows.has_key(account) && rows[account].has_key(jid)) {
|
||||||
remove(rows[jid]);
|
remove(rows[account][jid]);
|
||||||
rows.unset(jid);
|
rows[account].unset(jid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_updated_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
private void on_updated_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
||||||
on_removed_roster_item(account, jid, roster_item);
|
on_removed_roster_item(account, jid, roster_item);
|
||||||
ListRow row = new ListRow.from_jid(stream_interactor, new Jid(roster_item.jid), account);
|
ListRow row = new ListRow.from_jid(stream_interactor, new Jid(roster_item.jid), account);
|
||||||
rows[jid] = row;
|
rows[account][jid] = row;
|
||||||
add(row);
|
add(row);
|
||||||
invalidate_sort();
|
invalidate_sort();
|
||||||
invalidate_filter();
|
invalidate_filter();
|
||||||
|
|
|
@ -11,7 +11,7 @@ protected class ConferenceList : FilterableList {
|
||||||
public signal void conversation_selected(Conversation? conversation);
|
public signal void conversation_selected(Conversation? conversation);
|
||||||
|
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
private HashMap<Account, ArrayList<Xep.Bookmarks.Conference>> lists = new HashMap<Account, ArrayList<Xep.Bookmarks.Conference>>();
|
private HashMap<Account, Gee.List<Xep.Bookmarks.Conference>> lists = new HashMap<Account, Gee.List<Xep.Bookmarks.Conference>>();
|
||||||
|
|
||||||
public ConferenceList(StreamInteractor stream_interactor) {
|
public ConferenceList(StreamInteractor stream_interactor) {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
|
@ -42,7 +42,7 @@ protected class ConferenceList : FilterableList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void on_conference_bookmarks_received(Core.XmppStream stream, ArrayList<Xep.Bookmarks.Conference> conferences, Object? o) {
|
private static void on_conference_bookmarks_received(Core.XmppStream stream, Gee.List<Xep.Bookmarks.Conference> conferences, Object? o) {
|
||||||
Idle.add(() => {
|
Idle.add(() => {
|
||||||
Tuple<ConferenceList, Account> tuple = o as Tuple<ConferenceList, Account>;
|
Tuple<ConferenceList, Account> tuple = o as Tuple<ConferenceList, Account>;
|
||||||
ConferenceList list = tuple.a;
|
ConferenceList list = tuple.a;
|
||||||
|
@ -89,13 +89,15 @@ internal class ConferenceListRow : ListRow {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.bookmark = bookmark;
|
this.bookmark = bookmark;
|
||||||
|
|
||||||
if (bookmark.name != "" && bookmark.name != bookmark.jid) {
|
name_label.label = bookmark.name ?? bookmark.jid;
|
||||||
name_label.label = bookmark.name;
|
if (stream_interactor.get_accounts().size > 1) {
|
||||||
|
via_label.label = "via " + account.bare_jid.to_string();
|
||||||
|
} else if (bookmark.name != null && bookmark.name != bookmark.jid) {
|
||||||
via_label.label = bookmark.jid;
|
via_label.label = bookmark.jid;
|
||||||
} else {
|
} else {
|
||||||
name_label.label = bookmark.jid;
|
|
||||||
via_label.visible = false;
|
via_label.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
image.set_from_pixbuf((new AvatarGenerator(35, 35)).set_stateless(true).draw_jid(stream_interactor, jid, account));
|
image.set_from_pixbuf((new AvatarGenerator(35, 35)).set_stateless(true).draw_jid(stream_interactor, jid, account));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ namespace Dino.Ui.ConversationSelector {
|
||||||
public abstract class ConversationRow : ListBoxRow {
|
public abstract class ConversationRow : ListBoxRow {
|
||||||
|
|
||||||
public signal void closed();
|
public signal void closed();
|
||||||
public signal void disappeared();
|
|
||||||
|
|
||||||
[GtkChild] protected Image image;
|
[GtkChild] protected Image image;
|
||||||
[GtkChild] private Label name_label;
|
[GtkChild] private Label name_label;
|
||||||
|
@ -149,7 +148,6 @@ public abstract class ConversationRow : ListBoxRow {
|
||||||
closed();
|
closed();
|
||||||
main_revealer.notify["child-revealed"].connect(() => {
|
main_revealer.notify["child-revealed"].connect(() => {
|
||||||
stream_interactor.get_module(ConversationManager.IDENTITY).close_conversation(conversation);
|
stream_interactor.get_module(ConversationManager.IDENTITY).close_conversation(conversation);
|
||||||
disappeared();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,19 +23,22 @@ public class List : ListBox {
|
||||||
set_sort_func(sort);
|
set_sort_func(sort);
|
||||||
|
|
||||||
stream_interactor.get_module(ChatInteraction.IDENTITY).conversation_read.connect((conversation) => {
|
stream_interactor.get_module(ChatInteraction.IDENTITY).conversation_read.connect((conversation) => {
|
||||||
Idle.add(() => {if (rows.has_key(conversation)) rows[conversation].mark_read(); return false;});
|
Idle.add(() => { if (rows.has_key(conversation)) rows[conversation].mark_read(); return false; });
|
||||||
});
|
});
|
||||||
stream_interactor.get_module(ChatInteraction.IDENTITY).conversation_unread.connect((conversation) => {
|
stream_interactor.get_module(ChatInteraction.IDENTITY).conversation_unread.connect((conversation) => {
|
||||||
Idle.add(() => {if (rows.has_key(conversation)) rows[conversation].mark_unread(); return false;});
|
Idle.add(() => { if (rows.has_key(conversation)) rows[conversation].mark_unread(); return false; });
|
||||||
});
|
});
|
||||||
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_activated.connect((conversation) => {
|
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_activated.connect((conversation) => {
|
||||||
Idle.add(() => {add_conversation(conversation); return false;});
|
Idle.add(() => { add_conversation(conversation); return false; });
|
||||||
|
});
|
||||||
|
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_deactivated.connect((conversation) => {
|
||||||
|
Idle.add(() => { remove_conversation(conversation); return false; });
|
||||||
});
|
});
|
||||||
stream_interactor.get_module(MessageProcessor.IDENTITY).message_received.connect((message, conversation) => {
|
stream_interactor.get_module(MessageProcessor.IDENTITY).message_received.connect((message, conversation) => {
|
||||||
Idle.add(() => {on_message_received(message, conversation); return false;});
|
Idle.add(() => { on_message_received(message, conversation); return false; });
|
||||||
});
|
});
|
||||||
stream_interactor.get_module(MessageProcessor.IDENTITY).message_sent.connect((message, conversation) => {
|
stream_interactor.get_module(MessageProcessor.IDENTITY).message_sent.connect((message, conversation) => {
|
||||||
Idle.add(() => {on_message_received(message, conversation); return false;});
|
Idle.add(() => { on_message_received(message, conversation); return false; });
|
||||||
});
|
});
|
||||||
stream_interactor.get_module(PresenceManager.IDENTITY).show_received.connect((show, jid, account) => {
|
stream_interactor.get_module(PresenceManager.IDENTITY).show_received.connect((show, jid, account) => {
|
||||||
Idle.add(() => {
|
Idle.add(() => {
|
||||||
|
@ -132,7 +135,6 @@ public class List : ListBox {
|
||||||
rows[conversation] = row;
|
rows[conversation] = row;
|
||||||
add(row);
|
add(row);
|
||||||
row.closed.connect(() => { select_next_conversation(conversation); });
|
row.closed.connect(() => { select_next_conversation(conversation); });
|
||||||
row.disappeared.connect(() => { remove_conversation(conversation); });
|
|
||||||
row.main_revealer.set_reveal_child(true);
|
row.main_revealer.set_reveal_child(true);
|
||||||
}
|
}
|
||||||
invalidate_sort();
|
invalidate_sort();
|
||||||
|
@ -156,6 +158,7 @@ public class List : ListBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void remove_conversation(Conversation conversation) {
|
private void remove_conversation(Conversation conversation) {
|
||||||
|
select_next_conversation(conversation);
|
||||||
if (rows.has_key(conversation) && !conversation.active) {
|
if (rows.has_key(conversation) && !conversation.active) {
|
||||||
remove(rows[conversation]);
|
remove(rows[conversation]);
|
||||||
rows.unset(conversation);
|
rows.unset(conversation);
|
||||||
|
|
|
@ -39,8 +39,12 @@ public class UnifiedWindow : Window {
|
||||||
|
|
||||||
stream_interactor.account_added.connect((account) => { check_stack(true); });
|
stream_interactor.account_added.connect((account) => { check_stack(true); });
|
||||||
stream_interactor.account_removed.connect((account) => { check_stack(); });
|
stream_interactor.account_removed.connect((account) => { check_stack(); });
|
||||||
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_activated.connect((conversation) => { check_stack(); });
|
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_activated.connect( (conversation) => {
|
||||||
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_deactivated.connect((conversation) => { check_stack(); });
|
Idle.add( () => { check_stack(); return false; });
|
||||||
|
});
|
||||||
|
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_deactivated.connect( (conversation) => {
|
||||||
|
Idle.add( () => { check_stack(); return false; });
|
||||||
|
});
|
||||||
accounts_placeholder.primary_button.clicked.connect(() => { get_application().activate_action("accounts", null); });
|
accounts_placeholder.primary_button.clicked.connect(() => { get_application().activate_action("accounts", null); });
|
||||||
conversations_placeholder.primary_button.clicked.connect(() => { get_application().activate_action("add_chat", null); });
|
conversations_placeholder.primary_button.clicked.connect(() => { get_application().activate_action("add_chat", null); });
|
||||||
conversations_placeholder.secondary_button.clicked.connect(() => { get_application().activate_action("add_conference", null); });
|
conversations_placeholder.secondary_button.clicked.connect(() => { get_application().activate_action("add_conference", null); });
|
||||||
|
|
|
@ -28,7 +28,10 @@ public class Conference : Object {
|
||||||
|
|
||||||
public string? name {
|
public string? name {
|
||||||
get { return stanza_node.get_attribute(ATTRIBUTE_NAME); }
|
get { return stanza_node.get_attribute(ATTRIBUTE_NAME); }
|
||||||
set { stanza_node.set_attribute(ATTRIBUTE_NAME, value); }
|
set {
|
||||||
|
if (value == null) return; // TODO actually remove
|
||||||
|
stanza_node.set_attribute(ATTRIBUTE_NAME, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? nick {
|
public string? nick {
|
||||||
|
@ -58,6 +61,10 @@ public class Conference : Object {
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
StanzaNode? password_node = stanza_node.get_subnode(NODE_PASSWORD);
|
StanzaNode? password_node = stanza_node.get_subnode(NODE_PASSWORD);
|
||||||
|
if (value == null) {
|
||||||
|
if (password_node != null) stanza_node.sub_nodes.remove(password_node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (password_node == null) {
|
if (password_node == null) {
|
||||||
password_node = new StanzaNode.build(NODE_PASSWORD);
|
password_node = new StanzaNode.build(NODE_PASSWORD);
|
||||||
stanza_node.put_node(password_node);
|
stanza_node.put_node(password_node);
|
||||||
|
|
|
@ -8,25 +8,27 @@ private const string NS_URI = "storage:bookmarks";
|
||||||
public class Module : XmppStreamModule {
|
public class Module : XmppStreamModule {
|
||||||
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0048_bookmarks_module");
|
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0048_bookmarks_module");
|
||||||
|
|
||||||
public signal void conferences_updated(XmppStream stream, ArrayList<Conference> conferences);
|
public signal void received_conferences(XmppStream stream, Gee.List<Conference> conferences);
|
||||||
|
|
||||||
[CCode (has_target = false)] public delegate void OnResult(XmppStream stream, ArrayList<Conference> conferences, Object? reference);
|
[CCode (has_target = false)] public delegate void OnResult(XmppStream stream, Gee.List<Conference> conferences, Object? storage);
|
||||||
public void get_conferences(XmppStream stream, OnResult listener, Object? store) {
|
public void get_conferences(XmppStream stream, OnResult listener, Object? store) {
|
||||||
StanzaNode get_node = new StanzaNode.build("storage", NS_URI).add_self_xmlns();
|
StanzaNode get_node = new StanzaNode.build("storage", NS_URI).add_self_xmlns();
|
||||||
stream.get_module(PrivateXmlStorage.Module.IDENTITY).retrieve(stream, get_node, (stream, node, o) => {
|
stream.get_module(PrivateXmlStorage.Module.IDENTITY).retrieve(stream, get_node, (stream, node, o) => {
|
||||||
Tuple<OnResult, Object?> tuple = o as Tuple<OnResult, Object?>;
|
Tuple<OnResult, Object?> tuple = o as Tuple<OnResult, Object?>;
|
||||||
OnResult on_result = tuple.a;
|
OnResult on_result = tuple.a;
|
||||||
on_result(stream, get_conferences_from_stanza(node), tuple.b);
|
Gee.List<Conference> conferences = get_conferences_from_stanza(node);
|
||||||
|
stream.get_module(Module.IDENTITY).received_conferences(stream, conferences);
|
||||||
|
on_result(stream, conferences, tuple.b);
|
||||||
}, Tuple.create(listener, store));
|
}, Tuple.create(listener, store));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_conferences(XmppStream stream, ArrayList<Conference> conferences) {
|
public void set_conferences(XmppStream stream, Gee.List<Conference> conferences) {
|
||||||
StanzaNode storage_node = (new StanzaNode.build("storage", NS_URI)).add_self_xmlns();
|
StanzaNode storage_node = (new StanzaNode.build("storage", NS_URI)).add_self_xmlns();
|
||||||
foreach (Conference conference in conferences) {
|
foreach (Conference conference in conferences) {
|
||||||
storage_node.put_node(conference.stanza_node);
|
storage_node.put_node(conference.stanza_node);
|
||||||
}
|
}
|
||||||
stream.get_module(PrivateXmlStorage.Module.IDENTITY).store(stream, storage_node, (stream, o) => {
|
stream.get_module(PrivateXmlStorage.Module.IDENTITY).store(stream, storage_node, (stream, o) => {
|
||||||
stream.get_module(Module.IDENTITY).conferences_updated(stream, o as ArrayList<Conference>);
|
stream.get_module(Module.IDENTITY).received_conferences(stream, o as ArrayList<Conference>);
|
||||||
}, conferences);
|
}, conferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue