diff options
| -rw-r--r-- | libdino/src/entity/settings.vala | 23 | ||||
| -rw-r--r-- | main/data/conversation_row.ui | 7 | ||||
| -rw-r--r-- | main/data/preferences_window/account_preferences_subpage.ui | 11 | ||||
| -rw-r--r-- | main/src/ui/conversation_selector/conversation_selector_row.vala | 25 | ||||
| -rw-r--r-- | main/src/windows/preferences_window/account_preferences_subpage.vala | 45 |
5 files changed, 110 insertions, 1 deletions
diff --git a/libdino/src/entity/settings.vala b/libdino/src/entity/settings.vala index c71a8e57..1b533667 100644 --- a/libdino/src/entity/settings.vala +++ b/libdino/src/entity/settings.vala @@ -2,6 +2,8 @@ namespace Dino.Entities { public class Settings : Object { + public signal void account_color_changed(Account account, string color); + private Database db; public Settings.from_db(Database db) { @@ -110,6 +112,27 @@ public class Settings : Object { } + + public string get_account_color(Account account) { + string? setting = db.account_settings.get_value(account.id, "conversation-list-color"); + if (setting != null && setting.length > 0) { + return setting; + } + + uint8[] rgb = Xmpp.Xep.ConsistentColor.string_to_rgb(account.bare_jid.to_string()); + return "#%02x%02x%02x".printf(rgb[0], rgb[1], rgb[2]).up(); + } + + public void set_account_color(Account account, string color) { + if (color == get_account_color(account)) return; + + db.account_settings.upsert() + .value(db.account_settings.key, "conversation-list-color", true) + .value(db.account_settings.account_id, account.id, true) + .value(db.account_settings.value, color) + .perform(); + account_color_changed(account, color); + } } } diff --git a/main/data/conversation_row.ui b/main/data/conversation_row.ui index 9b113427..461c1440 100644 --- a/main/data/conversation_row.ui +++ b/main/data/conversation_row.ui @@ -14,6 +14,13 @@ <property name="margin-start">2</property> <property name="margin-end">4</property> <child> + <object class="GtkDrawingArea" id="account_color_indicator"> + <property name="width-request">4</property> + <property name="margin-end">6</property> + <property name="vexpand">True</property> + </object> + </child> + <child> <object class="DinoUiAvatarPicture" id="picture"> <property name="height-request">35</property> <property name="width-request">35</property> diff --git a/main/data/preferences_window/account_preferences_subpage.ui b/main/data/preferences_window/account_preferences_subpage.ui index bb458e74..9860de27 100644 --- a/main/data/preferences_window/account_preferences_subpage.ui +++ b/main/data/preferences_window/account_preferences_subpage.ui @@ -78,6 +78,17 @@ </object> </child> <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Conversation color</property> + <property name="subtitle" translatable="yes">Used to distinguish this account in the conversation list</property> + <child type="suffix"> + <object class="GtkBox" id="account_color_box"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + <child> <object class="AdwActionRow" id="password_change"> <property name="title" translatable="yes">Password</property> <child type="suffix"> diff --git a/main/src/ui/conversation_selector/conversation_selector_row.vala b/main/src/ui/conversation_selector/conversation_selector_row.vala index fd5814fa..11107c57 100644 --- a/main/src/ui/conversation_selector/conversation_selector_row.vala +++ b/main/src/ui/conversation_selector/conversation_selector_row.vala @@ -13,6 +13,7 @@ namespace Dino.Ui { public class ConversationSelectorRow : ListBoxRow { [GtkChild] protected unowned AvatarPicture picture; + [GtkChild] protected unowned DrawingArea account_color_indicator; [GtkChild] protected unowned Label name_label; [GtkChild] protected unowned Label time_label; [GtkChild] protected unowned Label nick_label; @@ -63,6 +64,7 @@ public class ConversationSelectorRow : ListBoxRow { last_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_latest(conversation); picture.model = new ViewModel.CompatAvatarPictureModel(stream_interactor).set_conversation(conversation); + account_color_indicator.set_draw_func(draw_account_color); conversation.notify["read-up-to-item"].connect(() => update_read()); conversation.notify["pinned"].connect(() => { update_pinned_icon(); }); @@ -73,9 +75,31 @@ public class ConversationSelectorRow : ListBoxRow { connect_signals_weak(this); } + private static void draw_account_color(DrawingArea area, Cairo.Context context, int width, int height) { + ConversationSelectorRow? row = area.get_ancestor(typeof(ConversationSelectorRow)) as ConversationSelectorRow; + if (row == null) return; + + Gdk.RGBA color = Gdk.RGBA(); + if (!color.parse(Dino.Application.get_default().settings.get_account_color(row.conversation.account))) return; + + Gdk.cairo_set_source_rgba(context, color); + context.rectangle(0, 0, width, height); + context.fill(); + } + private static void connect_signals_weak(ConversationSelectorRow local_self) { var self_weak = WeakRef(local_self); + var settings = Dino.Application.get_default().settings; + ulong account_color_changed_handler_id = 0; + account_color_changed_handler_id = settings.account_color_changed.connect((account, color) => { + ConversationSelectorRow? self = self_weak.get() as ConversationSelectorRow?; + if (self == null) return; + if (self.conversation.account.equals(account)) { + self.account_color_indicator.queue_draw(); + } + }); + ulong room_info_updated_handler_id = 0; if (local_self.conversation.type_ == Conversation.Type.GROUPCHAT) { room_info_updated_handler_id = local_self.stream_interactor.get_module(MucManager.IDENTITY).room_info_updated.connect((account, jid) => { @@ -116,6 +140,7 @@ public class ConversationSelectorRow : ListBoxRow { local_self.weak_ref((self_obj) => { ConversationSelectorRow self = (ConversationSelectorRow) self_obj; + settings.disconnect(account_color_changed_handler_id); if (room_info_updated_handler_id != 0) { self.stream_interactor.get_module(MucManager.IDENTITY).disconnect(room_info_updated_handler_id); } diff --git a/main/src/windows/preferences_window/account_preferences_subpage.vala b/main/src/windows/preferences_window/account_preferences_subpage.vala index cc1e7b5e..d52a8c83 100644 --- a/main/src/windows/preferences_window/account_preferences_subpage.vala +++ b/main/src/windows/preferences_window/account_preferences_subpage.vala @@ -12,6 +12,7 @@ public class Dino.Ui.AccountPreferencesSubpage : Adw.NavigationPage { [GtkChild] public unowned AvatarPicture avatar; [GtkChild] public unowned Adw.ActionRow xmpp_address; [GtkChild] public unowned Adw.EntryRow local_alias; + [GtkChild] public unowned Box account_color_box; [GtkChild] public unowned Adw.ActionRow password_change; [GtkChild] public unowned Adw.ActionRow connection_status; [GtkChild] public unowned Button enter_password_button; @@ -28,6 +29,12 @@ public class Dino.Ui.AccountPreferencesSubpage : Adw.NavigationPage { private Binding[] bindings = new Binding[0]; private ulong[] account_notify_ids = new ulong[0]; private ulong alias_entry_changed = 0; + private bool updating_account_color = false; +#if GTK_4_12 + private ColorDialogButton account_color_button; +#else + private ColorButton account_color_button; +#endif construct { title = "Account"; @@ -45,6 +52,23 @@ public class Dino.Ui.AccountPreferencesSubpage : Adw.NavigationPage { remove_account_button.clicked.connect(() => { show_remove_account_dialog(); }); + +#if GTK_4_12 + var color_dialog = new ColorDialog() { + title = _("Choose account color"), + with_alpha = false + }; + account_color_button = new ColorDialogButton((owned) color_dialog) { valign=Align.CENTER }; +#else + account_color_button = new ColorButton() { + title = _("Choose account color"), + use_alpha = false, + valign = Align.CENTER + }; +#endif + account_color_button.notify["rgba"].connect(on_account_color_changed); + account_color_box.append(account_color_button); + password_change.activatable_widget = new Label(""); password_change.activated.connect(() => { var dialog = new ChangePasswordDialog(model.get_change_password_dialog_model()); @@ -121,6 +145,12 @@ public class Dino.Ui.AccountPreferencesSubpage : Adw.NavigationPage { account.alias = local_alias.text; }); + Gdk.RGBA account_color = Gdk.RGBA(); + account_color.parse(Dino.Application.get_default().settings.get_account_color(account)); + updating_account_color = true; + account_color_button.rgba = account_color; + updating_account_color = false; + bindings += account.bind_property("enabled", disable_account_button, "label", BindingFlags.SYNC_CREATE, account_enabled_to_disable_button_label); bindings += account.bind_property("enabled", avatar_menu_box, "visible", BindingFlags.SYNC_CREATE); bindings += account.bind_property("enabled", password_change, "visible", BindingFlags.SYNC_CREATE); @@ -137,6 +167,19 @@ public class Dino.Ui.AccountPreferencesSubpage : Adw.NavigationPage { on_connection_error_updated(); } + private void on_account_color_changed() { + if (updating_account_color) return; + +#if GTK_4_12 + unowned Gdk.RGBA? selected_color = account_color_button.get_rgba(); + if (selected_color != null) { + Dino.Application.get_default().settings.set_account_color(account, Util.rgba_to_hex(selected_color)); + } +#else + Dino.Application.get_default().settings.set_account_color(account, Util.rgba_to_hex(account_color_button.rgba)); +#endif + } + private void show_select_avatar() { FileChooserNative chooser = new FileChooserNative(_("Select avatar"), (Window)this.get_root(), FileChooserAction.OPEN, _("Select"), _("Cancel")); FileFilter filter = new FileFilter(); @@ -261,4 +304,4 @@ public class Dino.Ui.NaturalDirectionBoxLayout : LayoutManager { } } } -}
\ No newline at end of file +} |
