diff options
-rw-r--r-- | libdino/src/service/database.vala | 5 | ||||
-rw-r--r-- | libdino/src/service/roster_manager.vala | 1 | ||||
-rw-r--r-- | main/src/ui/application.vala | 2 | ||||
-rw-r--r-- | main/src/ui/conversation_content_view/subscription_notification.vala | 35 | ||||
-rw-r--r-- | xmpp-vala/src/module/roster/item.vala | 26 |
5 files changed, 53 insertions, 16 deletions
diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala index bfa76890..06676951 100644 --- a/libdino/src/service/database.vala +++ b/libdino/src/service/database.vala @@ -7,7 +7,7 @@ using Dino.Entities; namespace Dino { public class Database : Qlite.Database { - private const int VERSION = 28; + private const int VERSION = 29; public class AccountTable : Table { public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true }; @@ -345,10 +345,11 @@ public class Database : Qlite.Database { public Column<string> jid = new Column.Text("jid"); public Column<string> handle = new Column.Text("name"); public Column<string> subscription = new Column.Text("subscription"); + public Column<string> ask = new Column.Text("ask") { min_version=29 }; internal RosterTable(Database db) { base(db, "roster"); - init({account_id, jid, handle, subscription}); + init({account_id, jid, handle, subscription, ask}); unique({account_id, jid}, "IGNORE"); } } diff --git a/libdino/src/service/roster_manager.vala b/libdino/src/service/roster_manager.vala index 8d9d91fb..6ddcda68 100644 --- a/libdino/src/service/roster_manager.vala +++ b/libdino/src/service/roster_manager.vala @@ -133,6 +133,7 @@ public class RosterStoreImpl : Roster.Storage, Object { .value(db.roster.jid, item.jid.to_string(), true) .value(db.roster.handle, item.name) .value(db.roster.subscription, item.subscription) + .value(db.roster.ask, item.ask) .perform(); } diff --git a/main/src/ui/application.vala b/main/src/ui/application.vala index 796146f8..e80a65d0 100644 --- a/main/src/ui/application.vala +++ b/main/src/ui/application.vala @@ -12,7 +12,7 @@ public class Dino.Ui.Application : Adw.Application, Dino.Application { private const string[] KEY_COMBINATION_LOOP_CONVERSATIONS_REV = {"<Ctrl><Shift>Tab", null}; private const string[] KEY_COMBINATION_SHOW_SETTINGS = {"<Ctrl>comma", null}; - private MainWindow window; + public MainWindow window; public MainWindowController controller; public Database db { get; set; } diff --git a/main/src/ui/conversation_content_view/subscription_notification.vala b/main/src/ui/conversation_content_view/subscription_notification.vala index b825f4ad..7fdda0b3 100644 --- a/main/src/ui/conversation_content_view/subscription_notification.vala +++ b/main/src/ui/conversation_content_view/subscription_notification.vala @@ -18,7 +18,7 @@ public class SubscriptionNotitication : Object { Conversation relevant_conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(jid, account, Conversation.Type.CHAT); stream_interactor.get_module(ConversationManager.IDENTITY).start_conversation(relevant_conversation); if (conversation != null && account.equals(conversation.account) && jid.equals(conversation.counterpart)) { - show_notification(); + show_pending_subscription_request(); } }); } @@ -27,22 +27,51 @@ public class SubscriptionNotitication : Object { this.conversation = conversation; this.conversation_view = conversation_view; + if (conversation.type_ != Conversation.Type.CHAT) return; + if (stream_interactor.get_module(PresenceManager.IDENTITY).exists_subscription_request(conversation.account, conversation.counterpart)) { - show_notification(); + show_pending_subscription_request(); + } else { + var roster_item = stream_interactor.get_module(RosterManager.IDENTITY).get_roster_item(conversation.account, conversation.counterpart); + if (roster_item == null || + (roster_item.subscription == Xmpp.Roster.Item.SUBSCRIPTION_NONE || roster_item.subscription == Xmpp.Roster.Item.SUBSCRIPTION_FROM) && + !roster_item.subscription_requested) { + show_no_subscription(roster_item != null); + } } } - private void show_notification() { + private void show_no_subscription(bool already_in_roster) { + Box box = new Box(Orientation.HORIZONTAL, 5); + Button accept_button = new Button.with_label(_("Send request")); + GLib.Application app = GLib.Application.get_default(); + accept_button.clicked.connect(() => { + if (!already_in_roster) { + stream_interactor.get_module(RosterManager.IDENTITY).add_jid(conversation.account, conversation.counterpart, null); + } + stream_interactor.get_module(PresenceManager.IDENTITY).request_subscription(conversation.account, conversation.counterpart); + app.activate_action("accept-subscription", conversation.id); + ((Dino.Ui.Application) app).window.conversation_view.chat_input.chat_text_view.text_view.grab_focus(); + conversation_view.remove_notification(box); + }); + box.append(new Label(_("You do not receive status updates from this contact yet.")) { margin_end=10 }); + box.append(accept_button); + conversation_view.add_notification(box); + } + + private void show_pending_subscription_request() { Box box = new Box(Orientation.HORIZONTAL, 5); Button accept_button = new Button.with_label(_("Accept")); Button deny_button = new Button.with_label(_("Deny")); GLib.Application app = GLib.Application.get_default(); accept_button.clicked.connect(() => { app.activate_action("accept-subscription", conversation.id); + ((Dino.Ui.Application) app).window.conversation_view.chat_input.chat_text_view.text_view.grab_focus(); conversation_view.remove_notification(box); }); deny_button.clicked.connect(() => { app.activate_action("deny-subscription", conversation.id); + ((Dino.Ui.Application) app).window.conversation_view.chat_input.chat_text_view.text_view.grab_focus(); conversation_view.remove_notification(box); }); box.append(new Label(_("This contact would like to add you to their contact list")) { margin_end=10 }); diff --git a/xmpp-vala/src/module/roster/item.vala b/xmpp-vala/src/module/roster/item.vala index 78974a35..4c9f30ef 100644 --- a/xmpp-vala/src/module/roster/item.vala +++ b/xmpp-vala/src/module/roster/item.vala @@ -4,12 +4,10 @@ namespace Xmpp.Roster { public class Item { - public const string NODE_JID = "jid"; - public const string NODE_NAME = "name"; - public const string NODE_SUBSCRIPTION = "subscription"; - public const string SUBSCRIPTION_NONE = "none"; + /** the user has a subscription to the contact's presence, but the contact does not have a subscription to the user's presence */ public const string SUBSCRIPTION_TO = "to"; + /** the contact has a subscription to the user's presence, but the user does not have a subscription to the contact's presence */ public const string SUBSCRIPTION_FROM = "from"; public const string SUBSCRIPTION_BOTH = "both"; public const string SUBSCRIPTION_REMOVE = "remove"; @@ -20,23 +18,31 @@ public class Item { public Jid? jid { get { try { - return jid_ ?? (jid_ = new Jid(stanza_node.get_attribute(NODE_JID))); + return jid_ ?? (jid_ = new Jid(stanza_node.get_attribute("jid"))); } catch (InvalidJidError e) { warning("Ignoring invalid Jid in roster entry: %s", e.message); return null; } } - set { stanza_node.set_attribute(NODE_JID, value.to_string()); } + set { stanza_node.set_attribute("jid", value.to_string()); } } public string? name { - get { return stanza_node.get_attribute(NODE_NAME); } - set { if (value != null) stanza_node.set_attribute(NODE_NAME, value); } + get { return stanza_node.get_attribute("name"); } + set { if (value != null) stanza_node.set_attribute("name", value); } } public string? subscription { - get { return stanza_node.get_attribute(NODE_SUBSCRIPTION); } - set { if (value != null) stanza_node.set_attribute(NODE_SUBSCRIPTION, value); } + get { return stanza_node.get_attribute("subscription"); } + set { if (value != null) stanza_node.set_attribute("subscription", value); } + } + + public string? ask { + get { return stanza_node.get_attribute("ask"); } + } + + public bool subscription_requested { + get { return this.ask != null; } } public Item() { |