Philipp Hörist pushed to branch mainwindow at gajim / gajim
Commits: 70ade17b by lovetox at 2021-02-02T22:56:57+01:00 Remove unread_messages table
- - - - - 7373b349 by lovetox at 2021-02-02T22:56:57+01:00 add unread cache
- - - - - 0bcf9951 by lovetox at 2021-02-02T22:58:47+01:00 Add notifications
- - - - -
13 changed files:
- gajim/chat_control.py - gajim/chat_control_base.py - gajim/common/connection_handlers_events.py - gajim/common/modules/mam.py - gajim/common/modules/message.py - gajim/common/storage/archive.py - gajim/common/storage/cache.py - gajim/groupchat_control.py - gajim/gtk/chat_list.py - gajim/gtk/chat_list_stack.py - gajim/gtk/chat_stack.py - gajim/gtk/main.py - gajim/gui_interface.py
Changes:
===================================== gajim/chat_control.py ===================================== @@ -227,7 +227,7 @@ def __init__(self, parent_win, contact, acct, session, resource=None): ('caps-update', ged.GUI1, self._on_caps_update), ('message-sent', ged.OUT_POSTCORE, self._on_message_sent), ('mam-decrypted-message-received', ged.GUI1, self._on_mam_decrypted_message_received), - ('decrypted-message-received', ged.GUI1, self._on_decrypted_message_received), + # ('decrypted-message-received', ged.GUI1, self._on_decrypted_message_received), ('receipt-received', ged.GUI1, self._receipt_received), ('displayed-received', ged.GUI1, self._displayed_received), ('message-error', ged.GUI1, self._on_message_error), @@ -604,34 +604,6 @@ def _on_mam_decrypted_message_received(self, event): message_id=event.properties.id, additional_data=event.additional_data)
- @event_filter(['account']) - def _on_decrypted_message_received(self, event): - if not event.msgtxt: - return True - - if event.session.control != self: - return - - typ = '' - if event.properties.is_sent_carbon: - typ = 'out' - - self.add_message(event.msgtxt, - typ, - tim=event.properties.timestamp, - subject=event.properties.subject, - displaymarking=event.displaymarking, - msg_log_id=event.msg_log_id, - message_id=event.properties.id, - correct_id=event.correct_id, - additional_data=event.additional_data) - if event.msg_log_id: - pw = self.parent_win - end = self.conv_textview.autoscroll - if not pw or (pw.get_active_control() and self \ - == pw.get_active_control() and pw.is_active() and end): - app.storage.archive.set_read_messages([event.msg_log_id]) - @event_filter(['account', 'jid']) def _on_message_error(self, event): self.conv_textview.show_error(event.message_id, event.error) @@ -1229,17 +1201,6 @@ def shutdown(self): self.get_full_jid(), types=['printed_%s' % self._type, str(self._type)]) # Remove contact instance if contact has been removed - key = (self.contact.jid, self.account) - roster = app.interface.roster - has_pending = roster.contact_has_pending_roster_events(self.contact, - self.account) - if key in roster.contacts_to_be_removed.keys() and not has_pending: - backend = roster.contacts_to_be_removed[key]['backend'] - del roster.contacts_to_be_removed[key] - roster.remove_contact(self.contact.jid, - self.account, - force=True, - backend=backend)
super(ChatControl, self).shutdown()
===================================== gajim/chat_control_base.py ===================================== @@ -1180,15 +1180,15 @@ def add_message(self, self.save_message(text, 'received')
# Send chat marker if we’re actively following the chat - if self.parent_win and self.contact.settings.get('send_marker'): - if (self.parent_win.get_active_control() == self and - self.parent_win.is_active() and - self.has_focus() and end): - con = app.connections[self.account] - con.get_module('ChatMarkers').send_displayed_marker( - self.contact, - self.last_msg_id, - self._type) + # if self.parent_win and self.contact.settings.get('send_marker'): + # if (self.parent_win.get_active_control() == self and + # self.parent_win.is_active() and + # self.has_focus() and end): + # con = app.connections[self.account] + # con.get_module('ChatMarkers').send_displayed_marker( + # self.contact, + # self.last_msg_id, + # self._type)
# TODO old event Code # if kind in ('incoming', 'incoming_queue', 'error'):
===================================== gajim/common/connection_handlers_events.py ===================================== @@ -132,8 +132,7 @@ def generate(self):
class NotificationEvent(nec.NetworkIncomingEvent): name = 'notification' - base_network_events = ['decrypted-message-received', - 'gc-message-received', + base_network_events = ['gc-message-received', 'presence-received']
def generate(self):
===================================== gajim/common/modules/mam.py ===================================== @@ -238,7 +238,6 @@ def _mam_message_received(self, _con, stanza, properties): with_, properties.mam.timestamp, kind, - unread=False, message=msgtxt, contact_name=properties.muc_nickname, additional_data=additional_data,
===================================== gajim/common/modules/message.py ===================================== @@ -134,22 +134,22 @@ def _message_received(self, _con, stanza, properties): msgtxt = properties.body
session = None - if not properties.type.is_groupchat: - if properties.is_muc_pm and properties.type.is_error: - session = self._con.find_session(fjid, properties.thread) - if not session: - session = self._con.get_latest_session(fjid) - if not session: - session = self._con.make_new_session( - fjid, properties.thread, type_='pm') - else: - session = self._con.get_or_create_session( - fjid, properties.thread) - - if properties.thread and not session.received_thread_id: - session.received_thread_id = True - - session.last_receive = time.time() + # if not properties.type.is_groupchat: + # if properties.is_muc_pm and properties.type.is_error: + # session = self._con.find_session(fjid, properties.thread) + # if not session: + # session = self._con.get_latest_session(fjid) + # if not session: + # session = self._con.make_new_session( + # fjid, properties.thread, type_='pm') + # else: + # session = self._con.get_or_create_session( + # fjid, properties.thread) + + # if properties.thread and not session.received_thread_id: + # session.received_thread_id = True + + # session.last_receive = time.time()
additional_data = AdditionalDataDict()
@@ -210,7 +210,7 @@ def _message_received(self, _con, stanza, properties): return
app.nec.push_incoming_event( - NetworkEvent('decrypted-message-received', **event_attr)) + NetworkEvent('message-received', **event_attr))
def _message_error_received(self, _con, _stanza, properties): jid = properties.jid
===================================== gajim/common/storage/archive.py ===================================== @@ -48,12 +48,6 @@ jid TEXT UNIQUE, type INTEGER ); - CREATE TABLE unread_messages( - message_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, - jid_id INTEGER, - shown BOOLEAN default 0 - ); - CREATE INDEX idx_unread_messages_jid_id ON unread_messages (jid_id); CREATE TABLE logs( log_line_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, account_id INTEGER, @@ -326,78 +320,6 @@ def convert_show_values_to_db_api_values(show): # it's a RFC violation .... but we should not crash return None
- @timeit - def insert_unread_events(self, message_id, jid_id): - """ - Add unread message with id: message_id - """ - sql = '''INSERT INTO unread_messages (message_id, jid_id, shown) - VALUES (?, ?, 0)''' - self._con.execute(sql, (message_id, jid_id)) - self._delayed_commit() - - @timeit - def set_read_messages(self, message_ids): - """ - Mark all messages with ids in message_ids as read - """ - ids = ','.join([str(i) for i in message_ids]) - sql = 'DELETE FROM unread_messages WHERE message_id IN (%s)' % ids - self._con.execute(sql) - self._delayed_commit() - - @timeit - def set_shown_unread_msgs(self, msg_log_id): - """ - Mark unread message as shown un GUI - """ - sql = 'UPDATE unread_messages SET shown = 1 where message_id = %s' % \ - msg_log_id - self._con.execute(sql) - self._delayed_commit() - - @timeit - def reset_shown_unread_messages(self): - """ - Set shown field to False in unread_messages table - """ - sql = 'UPDATE unread_messages SET shown = 0' - self._con.execute(sql) - self._delayed_commit() - - @timeit - def get_unread_msgs(self): - """ - Get all unread messages - """ - all_messages = [] - try: - unread_results = self._con.execute( - 'SELECT message_id, shown from unread_messages').fetchall() - except Exception: - unread_results = [] - for message in unread_results: - msg_log_id = message.message_id - shown = message.shown - # here we get infos for that message, and related jid from jids table - # do NOT change order of SELECTed things, unless you change function(s) - # that called this function - result = self._con.execute(''' - SELECT logs.log_line_id, logs.message, logs.time, logs.subject, - jids.jid, logs.additional_data - FROM logs, jids - WHERE logs.log_line_id = %d AND logs.jid_id = jids.jid_id - ''' % msg_log_id - ).fetchone() - if result is None: - # Log line is no more in logs table. - # remove it from unread_messages - self.set_read_messages([msg_log_id]) - continue - - all_messages.append((result, shown)) - return all_messages - @timeit def load_groupchat_messages(self, account, jid): account_id = self.get_account_id(account, type_=JIDConstant.ROOM_TYPE) @@ -824,8 +746,7 @@ def insert_jid(self, jid, kind=None, type_=JIDConstant.NORMAL_TYPE): return self.get_jid_id(jid, kind, type_)
@timeit - def insert_into_logs(self, account, jid, time_, kind, - unread=True, **kwargs): + def insert_into_logs(self, account, jid, time_, kind, **kwargs): """ Insert a new message into the `logs` table
@@ -863,11 +784,6 @@ def insert_into_logs(self, account, jid, time_, kind, log.info('Insert into DB: jid: %s, time: %s, kind: %s, stanza_id: %s', jid, time_, kind, kwargs.get('stanza_id', None))
- if unread and kind == KindConstant.CHAT_MSG_RECV: - sql = '''INSERT INTO unread_messages (message_id, jid_id) - VALUES (?, (SELECT jid_id FROM jids WHERE jid = ?))''' - self._con.execute(sql, (lastrowid, jid)) - self._delayed_commit()
return lastrowid
===================================== gajim/common/storage/cache.py ===================================== @@ -23,7 +23,7 @@ from gajim.common.storage.base import timeit
-CURRENT_USER_VERSION = 6 +CURRENT_USER_VERSION = 7
CACHE_SQL_STATEMENT = ''' CREATE TABLE caps_cache ( @@ -45,6 +45,14 @@ jid TEXT PRIMARY KEY UNIQUE, avatar_sha TEXT ); + CREATE TABLE unread( + account TEXT, + jid TEXT, + count INTEGER, + message_id TEXT, + timestamp INTEGER, + PRIMARY KEY (account, jid) + ); PRAGMA user_version=%s; ''' % CURRENT_USER_VERSION
@@ -88,6 +96,23 @@ def _migrate(self):
if user_version < 6: self._reinit_storage() + return + + if user_version < 7: + statements = [ + '''CREATE TABLE unread( + account TEXT, + jid TEXT, + count INTEGER, + message_id TEXT, + timestamp INTEGER, + PRIMARY KEY (account, jid))''', + + 'CREATE INDEX idx_unread ON unread(account, jid)', + 'PRAGMA user_version=7' + ] + + self._execute_multiple(statements)
@timeit def _load_caps_data(self): @@ -262,3 +287,28 @@ def get_muc_avatar_sha(self, jid): """
return self._muc_avatar_sha_cache.get(jid) + + @timeit + def get_unread_count(self, account, jid): + sql = '''SELECT count, message_id, timestamp FROM unread + WHERE account = ? AND jid = ?''' + return self._con.execute(sql, (account, jid)).fetchone() + + @timeit + def set_unread_count(self, account, jid, count, message_id, timestamp): + sql = '''INSERT INTO unread (account, jid, count, message_id, timestamp) + VALUES (?, ?, ?, ?, ?)''' + self._con.execute(sql, (account, jid, count, message_id, timestamp)) + self._delayed_commit() + + @timeit + def update_unread_count(self, account, jid, count): + sql = 'UPDATE unread SET count = ? WHERE account = ? AND jid = ?' + self._con.execute(sql, (count, account, jid)) + self._delayed_commit() + + @timeit + def reset_unread_count(self, account, jid): + sql = 'DELETE FROM unread WHERE account = ? AND jid = ?' + self._con.execute(sql, (account, jid)) + self._delayed_commit()
===================================== gajim/groupchat_control.py ===================================== @@ -1610,10 +1610,10 @@ def on_cancel(is_checked): on_yes(self)
def _close_control(self, reason=None): - if self.parent_win is None: - self.shutdown(reason) - else: - self.parent_win.remove_tab(self, None, reason=reason, force=True) + # if self.parent_win is None: + self.shutdown(reason) + # else: + # self.parent_win.remove_tab(self, None, reason=reason, force=True)
def set_control_active(self, state): self.conv_textview.allow_focus_out_line = True
===================================== gajim/gtk/chat_list.py ===================================== @@ -33,12 +33,11 @@ def __init__(self, workspace_id): self._timer_id = GLib.timeout_add_seconds(60, self._update_timer)
def _on_destroy(self): - if self._timer_id is not None: - GLib.source_remove(self._timer_id) + GLib.source_remove(self._timer_id)
def _update_timer(self): - self.update() - GLib.timeout_add_seconds(60, self._update_timer) + self.update_time() + return True
def _filter_func(self, row): if not self._current_filter_text: @@ -87,9 +86,14 @@ def get_open_chats(self): open_chats.append(key + (value.type,)) return open_chats
- def update(self): + def update_time(self): for _, row in self._chats.items(): - row.update() + row.update_time() + + def update(self, event): + row = self._chats.get((event.account, event.jid)) + row.add_unread() + row.set_last_message_text('Me', event.msgtext)
class ChatRow(Gtk.ListBoxRow): @@ -150,11 +154,11 @@ def __init__(self, workspace_id, account, jid, type_): chat_name_label.set_ellipsize(Pango.EllipsizeMode.END) chat_name_label.set_text(name)
- last_message_label = Gtk.Label() - last_message_label.set_halign(Gtk.Align.START) - last_message_label.set_xalign(0) - last_message_label.set_ellipsize(Pango.EllipsizeMode.END) - last_message_label.get_style_context().add_class('small-label') + self._last_message_label = Gtk.Label() + self._last_message_label.set_halign(Gtk.Align.START) + self._last_message_label.set_xalign(0) + self._last_message_label.set_ellipsize(Pango.EllipsizeMode.END) + self._last_message_label.get_style_context().add_class('small-label')
self._timestamp_label = Gtk.Label() self._timestamp_label.set_halign(Gtk.Align.END) @@ -167,23 +171,24 @@ def __init__(self, workspace_id, account, jid, type_): last_message_box = Gtk.Box(spacing=3) if line is not None and line.message is not None: one_line = ' '.join(line.message.splitlines()) - last_message_label.set_text(one_line) - nick_label = Gtk.Label() - nick_label.set_halign(Gtk.Align.START) - nick_label.get_style_context().add_class('small-label') - nick_label.get_style_context().add_class('dim-label') + + self._last_message_label.set_text(one_line) + self._nick_label = Gtk.Label() + self._nick_label.set_halign(Gtk.Align.START) + self._nick_label.get_style_context().add_class('small-label') + self._nick_label.get_style_context().add_class('dim-label') if line.kind in (KindConstant.CHAT_MSG_SENT, KindConstant.SINGLE_MSG_SENT): - nick_label.set_text(_('Me:')) - last_message_box.add(nick_label) + self._nick_label.set_text(_('Me:')) + last_message_box.add(self._nick_label) if line.kind == KindConstant.GC_MSG: our_nick = get_group_chat_nick(account, jid) if line.contact_name == our_nick: - nick_label.set_text(_('Me:')) + self._nick_label.set_text(_('Me:')) else: - nick_label.set_text(_('%(muc_nick)s: ') % { + self._nick_label.set_text(_('%(muc_nick)s: ') % { 'muc_nick': line.contact_name}) - last_message_box.add(nick_label) + last_message_box.add(self._nick_label)
# TODO: file transfers have to be displayed differently
@@ -191,7 +196,7 @@ def __init__(self, workspace_id, account, jid, type_): uf_timestamp = get_uf_relative_time(line.time) self._timestamp_label.set_text(uf_timestamp)
- last_message_box.add(last_message_label) + last_message_box.add(self._last_message_label)
self._unread_label = Gtk.Label() self._unread_label.set_no_show_all(True) @@ -242,16 +247,16 @@ def _on_state_flags_changed(self, _listboxrow, *args): def _on_close_button_clicked(self, _button): app.window.remove_chat(self.workspace_id, self.account, self.jid)
- def update(self): + def update_time(self): if self._timestamp is not None: uf_timestamp = get_uf_relative_time(self._timestamp) self._timestamp_label.set_text(uf_timestamp)
- def set_unread(self, count): - log.info('Set unread count: %s (%s)', self.jid, count) - self._unread_count = count - if not count: - self._unread_label.hide() - else: - self._unread_label.set_text(str(count)) - self._unread_label.show() + def add_unread(self): + self._unread_count += 1 + self._unread_label.set_text(str(self._unread_count)) + self._unread_label.show() + + def set_last_message_text(self, nickname, text): + self._last_message_label.set_text(text) + self._nick_label.set_text(nickname)
===================================== gajim/gtk/chat_list_stack.py ===================================== @@ -120,3 +120,7 @@ def contains_chat(self, account, jid, workspace_id=None):
chat_list = self._chat_lists[workspace_id] return chat_list.contains_chat(account, jid) + + def update(self, event): + chat_list = self._find_chat(event.account, event.jid) + chat_list.update(event)
===================================== gajim/gtk/chat_stack.py ===================================== @@ -83,3 +83,23 @@ def show_chat(self, account, jid):
def clear(self): self.set_visible_child_name('empty') + + def update(self, event): + if not event.msgtxt: + return + + control = self.get_control(event.account, event.jid) + + typ = '' + if event.properties.is_sent_carbon: + typ = 'out' + + control.add_message(event.msgtxt, + typ, + tim=event.properties.timestamp, + subject=event.properties.subject, + displaymarking=event.displaymarking, + msg_log_id=event.msg_log_id, + message_id=event.properties.id, + correct_id=event.correct_id, + additional_data=event.additional_data)
===================================== gajim/gtk/main.py ===================================== @@ -4,6 +4,7 @@ from gi.repository import Gio
from gajim.common import app +from gajim.common import ged from gajim.common.i18n import _ from gajim.gui.util import get_builder from gajim.gui.util import load_icon @@ -61,6 +62,10 @@ def __init__(self): 'clicked', self._on_start_chat_clicked) self._ui.connect_signals(self)
+ app.ged.register_event_handler('message-received', + ged.CORE, + self._on_message_received) + self.show_all()
self._load_chats() @@ -236,6 +241,13 @@ def _on_edit_workspace_clicked(self, _button): open_window('WorkspaceDialog', workspace_id=self.get_active_workspace())
+ def _on_message_received(self, event): + if not self.chat_exists(event.account, event.jid): + self.add_chat(event.account, event.jid, 'contact') + + self._chat_stack.update(event) + self._chat_list_stack.update(event) + def quit(self): accounts = list(app.connections.keys()) get_msg = False
===================================== gajim/gui_interface.py ===================================== @@ -63,7 +63,6 @@ from gajim.chat_control import ChatControl from gajim.groupchat_control import GroupchatControl from gajim.privatechat_control import PrivateChatControl -from gajim.message_window import MessageWindowMgr
from gajim.session import ChatControlSession
@@ -2124,8 +2123,6 @@ def __init__(self): # Load CSS files app.load_css_config()
- app.storage.archive.reset_shown_unread_messages() - for account in app.settings.get_accounts(): if app.settings.get_account_setting(account, 'is_zeroconf'): app.ZEROCONF_ACC_NAME = account
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/97dfbb01b552f37cbb1444759e907ce7...