Daniel Brötzmann pushed to branch master at gajim / gajim
Commits: de912f6c by wurstsalat at 2022-10-25T22:03:15+02:00 refactor: Move message correction handling to MessageInputTextView
- - - - - 266b16da by wurstsalat at 2022-10-25T22:14:08+02:00 fix: MessageInputTextView: Fix correction mode when switching chats
Fixes #11213
- - - - -
5 changed files:
- gajim/gtk/chat_stack.py - gajim/gtk/conversation/rows/widgets.py - gajim/gtk/main.py - gajim/gtk/message_actions_box.py - gajim/gtk/message_input.py
Changes:
===================================== gajim/gtk/chat_stack.py ===================================== @@ -741,22 +741,9 @@ def _on_send_message(self) -> None:
correct_id = None if self._message_action_box.is_correcting: - self._message_action_box.is_correcting = False - context = self._message_action_box.msg_textview.get_style_context() - context.remove_class('gajim-msg-correcting') - - correct_id = self._message_action_box.last_message_id.get( - (contact.account, contact.jid)) - message_row = app.storage.archive.get_last_correctable_message( - contact.account, contact.jid, correct_id) - if message_row is None: - self._message_action_box.msg_textview.clear() - log.info('Trying to correct message older than threshold') - return - - if message_row.message == message: - self._message_action_box.msg_textview.clear() - log.info('Trying to correct message with original text') + correct_id = self._message_action_box.try_message_correction( + message) + if correct_id is None: return
chatstate = client.get_module('Chatstate').get_active_chatstate( @@ -779,8 +766,8 @@ def _on_send_message(self) -> None:
self._message_action_box.msg_textview.clear()
- def get_last_message_id(self, account: str, jid: JID) -> Optional[str]: - return self._message_action_box.last_message_id.get((account, jid)) + def get_last_message_id(self, contact: ChatContactT) -> Optional[str]: + return self._message_action_box.get_last_message_id(contact)
def _close_control(self) -> None: assert self._current_contact is not None
===================================== gajim/gtk/conversation/rows/widgets.py ===================================== @@ -97,7 +97,7 @@ def _on_click(self, _button: Gtk.Button) -> None: show_correction = False if self._row.message_id is not None: show_correction = app.window.is_message_correctable( - self._contact.account, self._contact.jid, self._row.message_id) + self._contact, self._row.message_id)
self._create_popover(show_retract=show_retract, show_correction=show_correction)
===================================== gajim/gtk/main.py ===================================== @@ -30,6 +30,7 @@ from gajim.common import app from gajim.common import events from gajim.common import ged +from gajim.common import types from gajim.common.client import Client from gajim.common.const import Direction from gajim.common.const import Display @@ -855,17 +856,17 @@ def chat_exists(self, account: str, jid: JID) -> bool: return self._chat_page.chat_exists(account, jid)
def is_message_correctable(self, - account: str, - jid: JID, + contact: types.ChatContactT, message_id: str ) -> bool: + chat_stack = self._chat_page.get_chat_stack() - last_message_id = chat_stack.get_last_message_id(account, jid) + last_message_id = chat_stack.get_last_message_id(contact) if last_message_id is None or last_message_id != message_id: return False
message_row = app.storage.archive.get_last_correctable_message( - account, jid, last_message_id) + contact.account, contact.jid, last_message_id) return message_row is not None
def get_total_unread_count(self) -> int:
===================================== gajim/gtk/message_actions_box.py ===================================== @@ -32,11 +32,8 @@
from nbxmpp.const import Chatstate from nbxmpp.modules.security_labels import SecurityLabel -from nbxmpp.protocol import JID
from gajim.common import app -from gajim.common import events -from gajim.common import ged from gajim.common.commands import CommandFailed from gajim.common.i18n import _ from gajim.common.client import Client @@ -60,14 +57,12 @@ from .menus import get_singlechat_menu from .message_input import MessageInputTextView
- log = logging.getLogger('gajim.gui.messageactionsbox')
-class MessageActionsBox(Gtk.Grid, ged.EventHelper): +class MessageActionsBox(Gtk.Grid): def __init__(self) -> None: Gtk.Grid.__init__(self) - ged.EventHelper.__init__(self)
self._client: Optional[Client] = None self._contact: Optional[ChatContactT] = None @@ -80,10 +75,6 @@ def __init__(self) -> None: # For undo self.space_pressed = False
- # XEP-0308 Message Correction - self.is_correcting = False - self.last_message_id: dict[tuple[str, JID], Optional[str]] = {} - self._ui.send_message_button.set_visible( app.settings.get('show_send_message_button')) app.settings.bind_signal('show_send_message_button', @@ -117,10 +108,6 @@ def __init__(self) -> None:
self._connect_actions()
- self.register_events([ - ('message-sent', ged.GUI2, self._on_message_sent) - ]) - app.plugin_manager.gui_extension_point( 'message_actions_box', self, self._ui.box)
@@ -240,6 +227,19 @@ def clear(self) -> None: self._contact = None self._client = None
+ @property + def is_correcting(self) -> bool: + return self.msg_textview.correcting + + def toggle_message_correction(self) -> None: + self.msg_textview.toggle_message_correction() + + def try_message_correction(self, message: str) -> Optional[str]: + return self.msg_textview.try_message_correction(message) + + def get_last_message_id(self, contact: ChatContactT) -> Optional[str]: + return self.msg_textview.get_last_message_id(contact) + def _on_client_state_changed(self, _client: Client, _signal_name: str, @@ -606,45 +606,3 @@ def _paste_event_confirmed(self,
assert self._contact is not None app.interface.start_file_transfer(self._contact, path) - - def toggle_message_correction(self) -> None: - if self.is_correcting: - self.is_correcting = False - self.msg_textview.clear() - self.msg_textview.get_style_context().remove_class( - 'gajim-msg-correcting') - self.msg_textview.grab_focus() - return - - assert self._contact is not None - last_message_id = self.last_message_id.get( - (self._contact.account, self._contact.jid)) - if last_message_id is None: - return - - message_row = app.storage.archive.get_last_correctable_message( - self._contact.account, self._contact.jid, last_message_id) - if message_row is None: - return - - self.is_correcting = True - self.msg_textview.clear() - self.msg_textview.insert_text(message_row.message) - self.msg_textview.get_style_context().add_class('gajim-msg-correcting') - self.msg_textview.grab_focus() - - def _on_message_sent(self, event: events.MessageSent) -> None: - if not event.message: - return - - if event.correct_id is None: - # This wasn't a corrected message - assert self._contact is not None - oob_url = event.additional_data.get_value('gajim', 'oob_url') - account = self._contact.account - jid = self._contact.jid - if oob_url == event.message: - # Don't allow to correct HTTP Upload file transfer URLs - self.last_message_id[(account, jid)] = None - else: - self.last_message_id[(account, jid)] = event.message_id
===================================== gajim/gtk/message_input.py ===================================== @@ -22,6 +22,9 @@ from typing import Any from typing import Optional
+from collections import defaultdict + +import logging import sys
from gi.repository import Gtk @@ -31,6 +34,9 @@ from gi.repository import Pango
from gajim.common import app +from gajim.common import ged +from gajim.common.events import MessageSent +from gajim.common.ged import EventHelper from gajim.common.i18n import LANG from gajim.common.i18n import _ from gajim.common.styling import process @@ -52,13 +58,17 @@ 'pre': '`', }
+log = logging.getLogger('gajim.gui.message_input') +
-class MessageInputTextView(Gtk.TextView): +class MessageInputTextView(Gtk.TextView, EventHelper): ''' A Gtk.Textview for chat message input ''' def __init__(self) -> None: Gtk.TextView.__init__(self) + EventHelper.__init__(self) + self.set_border_width(3) self.set_accepts_tab(True) self.set_editable(True) @@ -77,6 +87,10 @@ def __init__(self) -> None:
self._contact: Optional[ChatContactT] = None
+ # XEP-0308 Message Correction + self._correcting: dict[ChatContactT, bool] = defaultdict(lambda: False) + self._last_message_id: dict[ChatContactT, Optional[str]] = {} + self._chat_action_processor = ChatActionProcessor(self)
self.get_buffer().create_tag('strong', weight=Pango.Weight.BOLD) @@ -91,11 +105,85 @@ def __init__(self) -> None: self.connect('destroy', self._on_destroy) self.connect('populate-popup', self._on_populate_popup)
+ self.register_events([ + ('message-sent', ged.GUI2, self._on_message_sent) + ]) + self._language_handler_id = self._init_spell_checker() app.settings.connect_signal('use_speller', self._on_toggle_spell_check)
app.plugin_manager.gui_extension_point('message_input', self)
+ @property + def correcting(self) -> bool: + assert self._contact is not None + return self._correcting[self._contact] + + @correcting.setter + def correcting(self, state: bool) -> None: + assert self._contact is not None + self._correcting[self._contact] = state + + def get_last_message_id(self, contact: ChatContactT) -> Optional[str]: + return self._last_message_id.get(contact) + + def toggle_message_correction(self) -> None: + self.clear() + self.grab_focus() + + if self.correcting: + self.correcting = False + self.get_style_context().remove_class('gajim-msg-correcting') + return + + assert self._contact is not None + last_message_id = self._last_message_id.get(self._contact) + if last_message_id is None: + return + + message_row = app.storage.archive.get_last_correctable_message( + self._contact.account, self._contact.jid, last_message_id) + if message_row is None: + return + + self.correcting = True + self.get_style_context().add_class('gajim-msg-correcting') + self.insert_text(message_row.message) + + def try_message_correction(self, message: str) -> Optional[str]: + assert self._contact is not None + if not self.correcting: + return None + + self.toggle_message_correction() + + correct_id = self._last_message_id.get(self._contact) + message_row = app.storage.archive.get_last_correctable_message( + self._contact.account, self._contact.jid, correct_id) + if message_row is None: + log.info('Trying to correct message older than threshold') + return None + + if message_row.message == message: + log.info('Trying to correct message with original text') + return None + + return correct_id + + def _on_message_sent(self, event: MessageSent) -> None: + if not event.message: + return + + if event.correct_id is None: + # This wasn't a corrected message + assert self._contact is not None + oob_url = event.additional_data.get_value('gajim', 'oob_url') + if oob_url == event.message: + # Don't allow to correct HTTP Upload file transfer URLs + self._last_message_id.pop(self._contact) + else: + self._last_message_id[self._contact] = event.message_id + def _init_spell_checker(self) -> int: if not app.is_installed('GSPELL'): return 0 @@ -161,6 +249,11 @@ def switch_contact(self, contact: ChatContactT) -> None: self.insert_text(draft)
self._contact = contact + if self.correcting: + self.get_style_context().add_class('gajim-msg-correcting') + else: + self.get_style_context().remove_class('gajim-msg-correcting') + self._chat_action_processor.switch_contact(contact) self._set_spell_checker_language(contact)
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/920f55b8946b8973540aec715f97f8e6...