diff options
author | wurstsalat <mailtrash@posteo.de> | 2023-02-24 22:01:50 +0300 |
---|---|---|
committer | wurstsalat <mailtrash@posteo.de> | 2023-06-15 22:54:38 +0300 |
commit | 22108427be37c9e5ed91b7351d2c74c9be083333 (patch) | |
tree | 7d010d370dafe1c3f2d305fc15ba1869f6afbb08 | |
parent | 0180cae59a6eedd395e7cc25c9a28d5adcdbb1d9 (diff) |
imprv: Restore chats when enabling account
This moves settings formerly stored in workspace settings to contact's and group chat contact's settings respectively.
New contact settings: 'opened', 'pinned', 'position'
Fixes #10872
-rw-r--r-- | gajim/common/modules/contacts.py | 5 | ||||
-rw-r--r-- | gajim/common/setting_values.py | 18 | ||||
-rw-r--r-- | gajim/common/settings.py | 32 | ||||
-rw-r--r-- | gajim/gtk/chat_list.py | 34 | ||||
-rw-r--r-- | gajim/gtk/chat_list_stack.py | 35 | ||||
-rw-r--r-- | gajim/gtk/chat_page.py | 34 | ||||
-rw-r--r-- | gajim/gtk/main.py | 3 |
7 files changed, 105 insertions, 56 deletions
diff --git a/gajim/common/modules/contacts.py b/gajim/common/modules/contacts.py index 6f6819232..000702082 100644 --- a/gajim/common/modules/contacts.py +++ b/gajim/common/modules/contacts.py @@ -44,6 +44,7 @@ from gajim.common.modules.base import BaseModule from gajim.common.modules.util import LogAdapter from gajim.common.setting_values import BoolContactSettings from gajim.common.setting_values import BoolGroupChatSettings +from gajim.common.setting_values import IntContactSettings from gajim.common.setting_values import IntGroupChatSettings from gajim.common.setting_values import StringContactSettings from gajim.common.setting_values import StringGroupChatSettings @@ -62,6 +63,8 @@ class ContactSettings: def get(self, setting: StringContactSettings) -> str: ... # noqa: E704 @overload def get(self, setting: BoolContactSettings) -> bool: ... # noqa: E704 + @overload + def get(self, setting: IntContactSettings) -> int: ... # noqa: E704 def get(self, setting: Any) -> Any: return app.settings.get_contact_setting( @@ -71,6 +74,8 @@ class ContactSettings: def set(self, setting: StringContactSettings, value: str | None) -> None: ... # noqa: E501, E704 @overload def set(self, setting: BoolContactSettings, value: bool | None) -> None: ... # noqa: E501, E704 + @overload + def set(self, setting: IntContactSettings, value: int | None) -> None: ... # noqa: E501, E704 def set(self, setting: Any, value: Any) -> None: app.settings.set_contact_setting( diff --git a/gajim/common/setting_values.py b/gajim/common/setting_values.py index ec52aa6af..b783d200f 100644 --- a/gajim/common/setting_values.py +++ b/gajim/common/setting_values.py @@ -368,6 +368,8 @@ AllAccountSettings = Literal[BoolAccountSettings, BoolGroupChatSettings = Literal[ 'notify_on_all_messages', + 'opened', + 'pinned', 'print_join_left', 'print_status', 'send_marker', @@ -382,6 +384,7 @@ StringGroupChatSettings = Literal[ ] IntGroupChatSettings = Literal[ + 'position', 'sync_threshold', ] @@ -394,9 +397,15 @@ AllGroupChatSettingsT = str | int | bool BoolContactSettings = Literal[ + 'opened', + 'pinned', 'send_marker', ] +IntContactSettings = Literal[ + 'position', +] + StringContactSettings = Literal[ 'encryption', 'mute_until', @@ -406,9 +415,10 @@ StringContactSettings = Literal[ ] AllContactSettings = Literal[BoolContactSettings, + IntContactSettings, StringContactSettings] -AllContactSettingsT = str | bool +AllContactSettingsT = str | int | bool ACCOUNT_SETTINGS = { @@ -488,6 +498,9 @@ ACCOUNT_SETTINGS = { 'send_marker': HAS_ACCOUNT_DEFAULT, 'speller_language': '', 'workspace': '', + 'opened': False, + 'pinned': False, + 'position': -1, }, 'group_chat': { @@ -501,6 +514,9 @@ ACCOUNT_SETTINGS = { 'speller_language': '', 'sync_threshold': HAS_APP_DEFAULT, 'workspace': '', + 'opened': False, + 'pinned': False, + 'position': -1, }, } diff --git a/gajim/common/settings.py b/gajim/common/settings.py index bcf4abcbe..0cb841699 100644 --- a/gajim/common/settings.py +++ b/gajim/common/settings.py @@ -29,6 +29,7 @@ import weakref from collections import defaultdict from collections import namedtuple from collections.abc import Callable +from collections.abc import Generator from pathlib import Path from gi.repository import GLib @@ -56,6 +57,7 @@ from gajim.common.setting_values import HAS_ACCOUNT_DEFAULT from gajim.common.setting_values import HAS_APP_DEFAULT from gajim.common.setting_values import INITAL_WORKSPACE from gajim.common.setting_values import IntAccountSettings +from gajim.common.setting_values import IntContactSettings from gajim.common.setting_values import IntGroupChatSettings from gajim.common.setting_values import IntSettings from gajim.common.setting_values import OpenChatsSettingT @@ -73,6 +75,7 @@ from gajim.common.setting_values import WORKSPACE_SETTINGS from gajim.common.setting_values import WorkspaceSettings from gajim.common.storage.base import Encoder from gajim.common.storage.base import json_decoder +from gajim.common.types import ChatContactT SETTING_TYPE = bool | int | str | object @@ -1026,6 +1029,14 @@ class Settings: def get_contact_setting(self, account: str, jid: JID, + setting: IntContactSettings + ) -> int: + ... + + @overload + def get_contact_setting(self, + account: str, + jid: JID, setting: StringContactSettings ) -> str: ... @@ -1066,6 +1077,14 @@ class Settings: def set_contact_setting(self, account: str, jid: JID, + setting: IntContactSettings, + value: int) -> None: + ... + + @overload + def set_contact_setting(self, + account: str, + jid: JID, setting: BoolContactSettings, value: bool | None) -> None: ... @@ -1122,6 +1141,19 @@ class Settings: for jid in acc_settings['contact']: self.set_contact_setting(account, jid, setting, value) + def iter_contact_settings(self, + account: str + ) -> Generator[ChatContactT, None, None]: + + client = app.get_client(account) + chats = self._account_settings[account]['contact'] + for address in chats: + yield client.get_module('Contacts').get_contact(address) + group_chats = self._account_settings[account]['group_chat'] + for address in group_chats: + yield client.get_module('Contacts').get_contact( + address, groupchat=True) + def set_soundevent_setting(self, event_name: str, setting: str, diff --git a/gajim/gtk/chat_list.py b/gajim/gtk/chat_list.py index 144bd491b..29b6c5d9b 100644 --- a/gajim/gtk/chat_list.py +++ b/gajim/gtk/chat_list.py @@ -22,7 +22,6 @@ import time from gi.repository import Gdk from gi.repository import GLib -from gi.repository import GObject from gi.repository import Gtk from nbxmpp import JID @@ -47,13 +46,6 @@ MessageEventT = (events.MessageReceived | class ChatList(Gtk.ListBox, EventHelper): - - __gsignals__ = { - 'chat-order-changed': (GObject.SignalFlags.RUN_LAST, - None, - ()), - } - def __init__(self, workspace_id: str) -> None: Gtk.ListBox.__init__(self) EventHelper.__init__(self) @@ -170,12 +162,20 @@ class ChatList(Gtk.ListBox, EventHelper): def toggle_chat_pinned(self, account: str, jid: JID) -> None: row = self._chats[(account, jid)] + client = app.get_client(account) + contact = client.get_module('Contacts').get_contact(jid) + if row.is_pinned: self._chat_order.remove(row) - row.position = -1 + contact.settings.set('pinned', False) + new_position = -1 else: self._chat_order.append(row) - row.position = self._chat_order.index(row) + contact.settings.set('pinned', True) + new_position = self._chat_order.index(row) + + row.position = new_position + contact.settings.set('position', new_position) row.toggle_pinned() self.invalidate_sort() @@ -287,7 +287,8 @@ class ChatList(Gtk.ListBox, EventHelper): def remove_chat(self, account: str, jid: JID, - emit_unread: bool = True + emit_unread: bool = True, + store: bool = True ) -> None: row = self._chats.pop((account, jid)) @@ -295,6 +296,10 @@ class ChatList(Gtk.ListBox, EventHelper): self._chat_order.remove(row) self.remove(row) row.destroy() + + if store: + app.settings.set_contact_setting(account, jid, 'opened', False) + if emit_unread: self._emit_unread_changed() @@ -302,7 +307,7 @@ class ChatList(Gtk.ListBox, EventHelper): for row_account, jid in list(self._chats.keys()): if row_account != account: continue - self.remove_chat(account, jid) + self.remove_chat(account, jid, store=False) self._emit_unread_changed() def clear_chat_list_row(self, account: str, jid: JID) -> None: @@ -448,9 +453,10 @@ class ChatList(Gtk.ListBox, EventHelper): row_before.position + offset, self._drag_row) for row in self._chat_order: - row.position = self._chat_order.index(row) + new_position = self._chat_order.index(row) + row.position = new_position + row.contact.settings.set('position', new_position) - self.emit('chat-order-changed') self._pinned_order_change = True self.invalidate_sort() self._pinned_order_change = False diff --git a/gajim/gtk/chat_list_stack.py b/gajim/gtk/chat_list_stack.py index e39c83029..27a75bfb2 100644 --- a/gajim/gtk/chat_list_stack.py +++ b/gajim/gtk/chat_list_stack.py @@ -147,7 +147,6 @@ class ChatListStack(Gtk.Stack, EventHelper): def add_chat_list(self, workspace_id: str) -> ChatList: chat_list = ChatList(workspace_id) chat_list.connect('row-selected', self._on_row_selected) - chat_list.connect('chat-order-changed', self._on_chat_order_changed) self._chat_lists[workspace_id] = chat_list self.add_named(chat_list, workspace_id) @@ -174,12 +173,6 @@ class ChatListStack(Gtk.Stack, EventHelper): self.emit('chat-selected', row.workspace_id, row.account, row.jid) - def _on_chat_order_changed(self, - chat_list: ChatList - ) -> None: - - self.store_open_chats(chat_list.workspace_id) - def show_chat_list(self, workspace_id: str) -> None: cur_workspace_id = self.get_visible_child_name() if cur_workspace_id != 'default' and cur_workspace_id is not None: @@ -209,17 +202,6 @@ class ChatListStack(Gtk.Stack, EventHelper): self.show_chat_list(chat_list.workspace_id) chat_list.select_chat(account, jid) - def store_open_chats(self, workspace_id: str) -> None: - chat_list = self._chat_lists[workspace_id] - open_chats = chat_list.get_open_chats() - for chat in open_chats: - client = app.get_client(chat['account']) - contact = client.get_module('Contacts').get_contact(chat['jid']) - contact.settings.set('workspace', workspace_id) - - app.settings.set_workspace_setting( - workspace_id, 'chats', open_chats) - @structs.actionmethod def _toggle_chat_pinned(self, _action: Gio.SimpleAction, @@ -228,7 +210,6 @@ class ChatListStack(Gtk.Stack, EventHelper): chat_list = self._chat_lists[params.workspace_id] chat_list.toggle_chat_pinned(params.account, params.jid) - self.store_open_chats(params.workspace_id) @structs.actionmethod def _move_chat_to_workspace(self, @@ -245,13 +226,15 @@ class ChatListStack(Gtk.Stack, EventHelper): if type_ is None: return - source_chatlist.remove_chat(params.account, params.jid) + source_chatlist.remove_chat(params.account, params.jid, store=False) new_chatlist = self.get_chatlist(workspace_id) new_chatlist.add_chat(params.account, params.jid, type_, False, -1) - self.store_open_chats(source_chatlist.workspace_id) - self.store_open_chats(workspace_id) + client = app.get_client(params.account) + contact = client.get_module('Contacts').get_contact(params.jid) + contact.settings.set('workspace', workspace_id) + contact.settings.set('pinned', False) @structs.actionmethod def _mark_as_read(self, @@ -264,6 +247,7 @@ class ChatListStack(Gtk.Stack, EventHelper): def remove_chat(self, workspace_id: str, account: str, jid: JID) -> None: chat_list = self._chat_lists[workspace_id] type_ = chat_list.get_chat_type(account, jid) + client = app.get_client(account) def _leave(not_ask_again: bool) -> None: if not_ask_again: @@ -272,14 +256,14 @@ class ChatListStack(Gtk.Stack, EventHelper): def _remove() -> None: chat_list.remove_chat(account, jid, emit_unread=False) - self.store_open_chats(workspace_id) + contact = client.get_module('Contacts').get_contact(jid) + contact.settings.set('opened', False) self.emit('chat-removed', account, jid, type_) if type_ != 'groupchat' or not app.settings.get('confirm_close_muc'): _remove() return - client = app.get_client(account) contact = client.get_module('Contacts').get_contact(jid, groupchat=True) if contact.is_not_joined and client.state.is_available: @@ -300,9 +284,8 @@ class ChatListStack(Gtk.Stack, EventHelper): transient_for=app.window).show() def remove_chats_for_account(self, account: str) -> None: - for workspace_id, chat_list in self._chat_lists.items(): + for chat_list in self._chat_lists.values(): chat_list.remove_chats_for_account(account) - self.store_open_chats(workspace_id) def find_chat(self, account: str, jid: JID) -> ChatList | None: for chat_list in self._chat_lists.values(): diff --git a/gajim/gtk/chat_page.py b/gajim/gtk/chat_page.py index 30a2491de..ba78ce3f1 100644 --- a/gajim/gtk/chat_page.py +++ b/gajim/gtk/chat_page.py @@ -264,27 +264,31 @@ class ChatPage(Gtk.Box): if self._startup_finished: if select: self._chat_list_stack.select_chat(account, jid) - self._chat_list_stack.store_open_chats(workspace_id) + + contact = client.get_module('Contacts').get_contact(jid) + contact.settings.set('opened', True) + if message is not None: message_input = self._chat_stack.get_message_input() message_input.insert_text(message) def load_workspace_chats(self, workspace_id: str) -> None: - open_chats = app.settings.get_workspace_setting(workspace_id, - 'chats') - active_accounts = app.settings.get_active_accounts() - for open_chat in open_chats: - account = open_chat['account'] - if account not in active_accounts: - continue - - self.add_chat_for_workspace(workspace_id, - account, - open_chat['jid'], - open_chat['type'], - pinned=open_chat['pinned'], - position=open_chat['position']) + for account in active_accounts: + for contact in app.settings.iter_contact_settings(account): + if not contact.settings.get('workspace') == workspace_id: + continue + + if not contact.settings.get('opened'): + continue + + self.add_chat_for_workspace( + workspace_id, + account, + contact.jid, + contact.type_string, + pinned=contact.settings.get('pinned'), + position=contact.settings.get('position')) def is_chat_selected(self, account: str, jid: JID) -> bool: return self._chat_list_stack.is_chat_selected(account, jid) diff --git a/gajim/gtk/main.py b/gajim/gtk/main.py index f3cb06381..0e49af080 100644 --- a/gajim/gtk/main.py +++ b/gajim/gtk/main.py @@ -238,6 +238,9 @@ class MainWindow(Gtk.ApplicationWindow, EventHelper): client = app.get_client(event.account) client.connect_signal('state-changed', self._on_client_state_changed) + for workspace_id in app.settings.get_workspaces(): + self._chat_page.load_workspace_chats(workspace_id) + def _on_account_disabled(self, event: events.AccountDisabled) -> None: workspace_id = self._workspace_side_bar.get_first_workspace() self.activate_workspace(workspace_id) |