aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/contact_details
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/ui/contact_details')
-rw-r--r--main/src/ui/contact_details/dialog.vala120
-rw-r--r--main/src/ui/contact_details/muc_config_form_provider.vala131
-rw-r--r--main/src/ui/contact_details/settings_provider.vala102
3 files changed, 353 insertions, 0 deletions
diff --git a/main/src/ui/contact_details/dialog.vala b/main/src/ui/contact_details/dialog.vala
new file mode 100644
index 00000000..7e2f6100
--- /dev/null
+++ b/main/src/ui/contact_details/dialog.vala
@@ -0,0 +1,120 @@
+using Gee;
+using Gtk;
+using Markup;
+
+using Dino.Entities;
+
+namespace Dino.Ui.ContactDetails {
+
+[GtkTemplate (ui = "/org/dino-im/contact_details_dialog.ui")]
+public class Dialog : Gtk.Dialog {
+
+ [GtkChild] public Image avatar;
+ [GtkChild] public Label name_label;
+ [GtkChild] public Label jid_label;
+ [GtkChild] public Label account_label;
+ [GtkChild] public Box main_box;
+
+ private StreamInteractor stream_interactor;
+ private Conversation conversation;
+
+ private Plugins.ContactDetails contact_details = new Plugins.ContactDetails();
+ private HashMap<string, ListBox> categories = new HashMap<string, ListBox>();
+ private Util.LabelHybridGroup hybrid_group = new Util.LabelHybridGroup();
+
+ public Dialog(StreamInteractor stream_interactor, Conversation conversation) {
+ Object(use_header_bar : 1);
+ this.stream_interactor = stream_interactor;
+ this.conversation = conversation;
+
+ title = conversation.type_ == Conversation.Type.GROUPCHAT ? _("Conference Details") : _("Contact Details");
+ (get_header_bar() as HeaderBar).set_subtitle(Util.get_conversation_display_name(stream_interactor, conversation));
+
+ name_label.label = Util.get_conversation_display_name(stream_interactor, conversation);
+ jid_label.label = conversation.counterpart.to_string();
+ account_label.label = "via " + conversation.account.bare_jid.to_string();
+ Util.image_set_from_scaled_pixbuf(avatar, (new AvatarGenerator(50, 50, avatar.scale_factor)).draw_conversation(stream_interactor, conversation));
+
+ contact_details.add.connect(add_entry);
+
+ Application app = GLib.Application.get_default() as Application;
+ app.plugin_registry.register_contact_details_entry(new SettingsProvider(stream_interactor));
+ app.plugin_registry.register_contact_details_entry(new MucConfigFormProvider(stream_interactor));
+
+ foreach (Plugins.ContactDetailsProvider provider in app.plugin_registry.contact_details_entries) {
+ provider.populate(conversation, contact_details);
+ }
+
+ destroy.connect(() => {
+ contact_details.save();
+ });
+ }
+
+ public void add_entry(string category, string label, string? description, Widget w) {
+ add_category(category);
+
+ ListBoxRow list_row = new ListBoxRow() { activatable=false, visible=true };
+ Box row = new Box(Orientation.HORIZONTAL, 20) { margin_left=15, margin_right=15, margin_top=3, margin_bottom=3, visible=true };
+ list_row.add(row);
+ Label label_label = new Label(label) { xalign=0, yalign=0.5f, hexpand=true, visible=true };
+ if (description != null && description != "") {
+ Box box = new Box(Orientation.VERTICAL, 0) { visible=true };
+ box.add(label_label);
+ Label desc_label = new Label("") { xalign=0, yalign=0.5f, hexpand=true, visible=true };
+ desc_label.set_markup("<span size='small'>%s</span>".printf(Markup.escape_text(description)));
+ desc_label.get_style_context().add_class("dim-label");
+ box.add(desc_label);
+ row.add(box);
+ } else {
+ row.add(label_label);
+ }
+
+ Widget widget = w;
+ if (widget.get_type().is_a(typeof(Entry))) {
+ Util.EntryLabelHybrid hybrid = new Util.EntryLabelHybrid(widget as Entry) { xalign=1, visible=true };
+ hybrid_group.add(hybrid);
+ widget = hybrid;
+ } else if (widget.get_type().is_a(typeof(ComboBoxText))) {
+ Util.ComboBoxTextLabelHybrid hybrid = new Util.ComboBoxTextLabelHybrid(widget as ComboBoxText) { xalign=1, visible=true };
+ hybrid_group.add(hybrid);
+ widget = hybrid;
+ }
+ widget.margin_bottom = 5;
+ widget.margin_top = 5;
+
+
+ row.add(widget);
+ categories[category].add(list_row);
+
+ Idle.add(() => {
+ int pref_height, pref_width;
+ get_content_area().get_preferred_height(null, out pref_height);
+ get_preferred_width(out pref_width, null);
+ resize(pref_width, int.min(500, pref_height));
+ return false;
+ });
+ }
+
+ public void add_category(string category) {
+ if (!categories.has_key(category)) {
+ ListBox list_box = new ListBox() { selection_mode=SelectionMode.NONE, visible=true };
+ categories[category] = list_box;
+ list_box.set_header_func((row, before_row) => {
+ if (row.get_header() == null && before_row != null) {
+ row.set_header(new Separator(Orientation.HORIZONTAL));
+ }
+ });
+ Box box = new Box(Orientation.VERTICAL, 5) { margin_top=12, margin_bottom=12, visible=true };
+ Label category_label = new Label("") { xalign=0, visible=true };
+ category_label.set_markup(@"<b>$(Markup.escape_text(category))</b>");
+ box.add(category_label);
+ Frame frame = new Frame(null) { visible=true };
+ frame.add(list_box);
+ box.add(frame);
+ main_box.add(box);
+ }
+ }
+}
+
+}
+
diff --git a/main/src/ui/contact_details/muc_config_form_provider.vala b/main/src/ui/contact_details/muc_config_form_provider.vala
new file mode 100644
index 00000000..44659888
--- /dev/null
+++ b/main/src/ui/contact_details/muc_config_form_provider.vala
@@ -0,0 +1,131 @@
+using Gee;
+using Gtk;
+
+using Dino.Entities;
+using Xmpp.Xep;
+
+namespace Dino.Ui.ContactDetails {
+
+public class MucConfigFormProvider : Plugins.ContactDetailsProvider {
+ public override string id { get { return "muc_config_form"; } }
+ private StreamInteractor stream_interactor;
+
+ public MucConfigFormProvider(StreamInteractor stream_interactor) {
+ this.stream_interactor = stream_interactor;
+ }
+
+ public override void populate(Conversation conversation, Plugins.ContactDetails contact_details) {
+ if (conversation.type_ == Conversation.Type.GROUPCHAT) {
+ Xmpp.Core.XmppStream? stream = stream_interactor.get_stream(conversation.account);
+ if (stream == null) return;
+ stream_interactor.get_module(MucManager.IDENTITY).get_config_form(conversation.account, conversation.counterpart, (jid, data_form, store) => {
+ Plugins.ContactDetails contact_details_ = store as Plugins.ContactDetails;
+ contact_details_.save.connect(() => {
+ data_form.submit();
+ });
+ Idle.add(() => {
+ for (int i = 0; i < data_form.fields.size; i++) {
+ DataForms.DataForm.Field field = data_form.fields[i];
+ add_field(field, contact_details_);
+ }
+ return false;
+ });
+ }, contact_details);
+ }
+ }
+
+ public static void add_field(DataForms.DataForm.Field field, Plugins.ContactDetails contact_details) {
+ string label = field.label ?? "";
+ string? desc = null;
+ switch (field.var) {
+ case "muc#roomconfig_roomname":
+ label = _("Name");
+ desc = _("Name of the room");
+ break;
+ case "muc#roomconfig_roomdesc":
+ label = _("Description");
+ desc = _("Description of the room");
+ break;
+ case "muc#roomconfig_persistentroom":
+ label = _("Persistent");
+ break;
+ case "muc#roomconfig_publicroom":
+ label = _("Publicly searchable");
+ break;
+ case "muc#roomconfig_changesubject":
+ label = _("Occupants may change subject");
+ break;
+ case "muc#roomconfig_whois":
+ label = _("Discover real jids");
+ desc = "Who may discover real jids";
+ break;
+ case "muc#roomconfig_roomsecret":
+ label = _("Password");
+ desc = _("Passwort required to enter the room. Leave empty for none.");
+ break;
+ case "muc#roomconfig_moderatedroom":
+ label = _("Moderated");
+ break;
+ case "muc#roomconfig_membersonly":
+ label = _("Members only");
+ desc = _("Only members may enter the room");
+ break;
+ case "muc#roomconfig_historylength":
+ label = _("Message History");
+ desc = _("Maximum number of history messages returned by the room");
+ break;
+ }
+
+ Widget? widget = get_widget(field);
+ if (widget != null) contact_details.add(_("Room Configuration"), label, desc, widget);
+ }
+
+ private static Widget? get_widget(DataForms.DataForm.Field field) {
+ switch (field.type_) {
+ case DataForms.DataForm.Type.BOOLEAN:
+ DataForms.DataForm.BooleanField boolean_field = field as DataForms.DataForm.BooleanField;
+ Switch sw = new Switch() { active=boolean_field.value, valign=Align.CENTER, visible=true };
+ sw.state_set.connect((state) => {
+ boolean_field.value = state;
+ return false;
+ });
+ return sw;
+ case DataForms.DataForm.Type.JID_MULTI:
+ return null;
+ case DataForms.DataForm.Type.LIST_SINGLE:
+ DataForms.DataForm.ListSingleField list_single_field = field as DataForms.DataForm.ListSingleField;
+ ComboBoxText combobox = new ComboBoxText() { valign=Align.CENTER, visible=true };
+ for (int i = 0; i < list_single_field.options.size; i++) {
+ DataForms.DataForm.Option option = list_single_field.options[i];
+ combobox.append(option.value, option.label);
+ if (option.value == list_single_field.value) combobox.active = i;
+ }
+ combobox.changed.connect(() => {
+ list_single_field.value = combobox.get_active_id();
+ });
+ return combobox;
+ case DataForms.DataForm.Type.LIST_MULTI:
+ return null;
+ case DataForms.DataForm.Type.TEXT_PRIVATE:
+ DataForms.DataForm.TextPrivateField text_private_field = field as DataForms.DataForm.TextPrivateField;
+ Entry entry = new Entry() { text=text_private_field.value ?? "", valign=Align.CENTER, visible=true, visibility=false };
+ entry.key_release_event.connect(() => {
+ text_private_field.value = entry.text;
+ return false;
+ });
+ return entry;
+ case DataForms.DataForm.Type.TEXT_SINGLE:
+ DataForms.DataForm.TextSingleField text_single_field = field as DataForms.DataForm.TextSingleField;
+ Entry entry = new Entry() { text=text_single_field.value ?? "", valign=Align.CENTER, visible=true };
+ entry.key_release_event.connect(() => {
+ text_single_field.value = entry.text;
+ return false;
+ });
+ return entry;
+ default:
+ return null;
+ }
+ }
+}
+
+} \ No newline at end of file
diff --git a/main/src/ui/contact_details/settings_provider.vala b/main/src/ui/contact_details/settings_provider.vala
new file mode 100644
index 00000000..fd49f9a1
--- /dev/null
+++ b/main/src/ui/contact_details/settings_provider.vala
@@ -0,0 +1,102 @@
+using Gtk;
+
+using Dino.Entities;
+
+namespace Dino.Ui.ContactDetails {
+
+public class SettingsProvider : Plugins.ContactDetailsProvider {
+ public override string id { get { return "chat_settings"; } }
+
+ private StreamInteractor stream_interactor;
+
+ public SettingsProvider(StreamInteractor stream_interactor) {
+ this.stream_interactor = stream_interactor;
+ }
+
+ public override void populate(Conversation conversation, Plugins.ContactDetails contact_details) {
+ if (conversation.type_ == Conversation.Type.CHAT) {
+ ComboBoxText[] comboboxes = new ComboBoxText[2];
+ for (int i = 0; i < 3; i++) {
+ comboboxes[i] = new ComboBoxText() { visible=true };
+ comboboxes[i].append("default", _("Default"));
+ comboboxes[i].append("on", _("On"));
+ comboboxes[i].append("off", _("Off"));
+ }
+
+ contact_details.add(_("Settings"), _("Send typing notifications"), "", comboboxes[0]);
+ comboboxes[0].active_id = get_setting_id(conversation.get_send_typing_setting());
+ comboboxes[0].changed.connect(() => { print("changed!\n"); conversation.send_typing = get_setting(comboboxes[0].active_id); } );
+
+ contact_details.add(_("Settings"), _("Send message marker"), "", comboboxes[1]);
+ comboboxes[1].active_id = get_setting_id(conversation.get_send_marker_setting());
+ comboboxes[1].changed.connect(() => { conversation.send_marker = get_setting(comboboxes[1].active_id); } );
+
+ contact_details.add(_("Settings"), _("Notifications"), "", comboboxes[2]);
+ comboboxes[2].active_id = get_notify_setting_id(conversation.get_notification_setting(stream_interactor));
+ comboboxes[2].changed.connect(() => { conversation.notify_setting = get_notify_setting(comboboxes[2].active_id); } );
+ } else if (conversation.type_ == Conversation.Type.GROUPCHAT) {
+ ComboBoxText combobox = new ComboBoxText() { visible=true };
+ combobox.append("default", _("Default"));
+ combobox.append("hightlight", _("Only when mentioned"));
+ combobox.append("on", _("On"));
+ combobox.append("off", _("Off"));
+ contact_details.add(_("Local Settings"), _("Notifications"), "", combobox);
+ combobox.active_id = get_notify_setting_id(conversation.get_notification_setting(stream_interactor));
+ combobox.changed.connect(() => { conversation.notify_setting = get_notify_setting(combobox.active_id); } );
+ }
+ }
+
+ public Conversation.Setting get_setting(string id) {
+ switch (id) {
+ case "default":
+ return Conversation.Setting.DEFAULT;
+ case "on":
+ return Conversation.Setting.ON;
+ case "off":
+ return Conversation.Setting.OFF;
+ }
+ assert_not_reached();
+ }
+
+ public Conversation.NotifySetting get_notify_setting(string id) {
+ switch (id) {
+ case "default":
+ return Conversation.NotifySetting.DEFAULT;
+ case "on":
+ return Conversation.NotifySetting.ON;
+ case "off":
+ return Conversation.NotifySetting.OFF;
+ case "highlight":
+ return Conversation.NotifySetting.HIGHLIGHT;
+ }
+ assert_not_reached();
+ }
+
+ public string get_setting_id(Conversation.Setting setting) {
+ switch (setting) {
+ case Conversation.Setting.DEFAULT:
+ return "default";
+ case Conversation.Setting.ON:
+ return "on";
+ case Conversation.Setting.OFF:
+ return "off";
+ }
+ assert_not_reached();
+ }
+
+ public string get_notify_setting_id(Conversation.NotifySetting setting) {
+ switch (setting) {
+ case Conversation.NotifySetting.DEFAULT:
+ return "default";
+ case Conversation.NotifySetting.ON:
+ return "on";
+ case Conversation.NotifySetting.OFF:
+ return "off";
+ case Conversation.NotifySetting.HIGHLIGHT:
+ return "hightlight";
+ }
+ assert_not_reached();
+ }
+}
+
+} \ No newline at end of file