Philipp Hörist pushed to branch master at gajim / gajim

Commits:

6 changed files:

Changes:

  • gajim/chat_control.py
    ... ... @@ -134,11 +134,6 @@ class ChatControl(ChatControlBase):
    134 134
             self.show_avatar()
    
    135 135
     
    
    136 136
             # Hook up signals
    
    137
    -        message_tv_buffer = self.msg_textview.get_buffer()
    
    138
    -        id_ = message_tv_buffer.connect('changed',
    
    139
    -            self._on_message_tv_buffer_changed)
    
    140
    -        self.handlers[id_] = message_tv_buffer
    
    141
    -
    
    142 137
             widget = self.xml.get_object('avatar_eventbox')
    
    143 138
             widget.set_property('height-request', AvatarSize.CHAT)
    
    144 139
     
    
    ... ... @@ -680,7 +675,11 @@ class ChatControl(ChatControlBase):
    680 675
             status_escaped = GLib.markup_escape_text(status_reduced)
    
    681 676
     
    
    682 677
             st = app.config.get('displayed_chat_state_notifications')
    
    683
    -        cs = app.contacts.get_combined_chatstate(self.account, self.contact.jid)
    
    678
    +        if self.TYPE_ID == 'pm':
    
    679
    +            cs = self.gc_contact.chatstate
    
    680
    +        else:
    
    681
    +            cs = app.contacts.get_combined_chatstate(
    
    682
    +                self.account, self.contact.jid)
    
    684 683
             if cs and st in ('composing_only', 'all'):
    
    685 684
                 if contact.show == 'offline':
    
    686 685
                     chatstate = ''
    
    ... ... @@ -1152,13 +1151,21 @@ class ChatControl(ChatControlBase):
    1152 1151
             if event.account != self.account:
    
    1153 1152
                 return
    
    1154 1153
     
    
    1155
    -        if event.jid != self.contact.jid:
    
    1156
    -            return
    
    1154
    +        if self.TYPE_ID == 'pm':
    
    1155
    +            if event.contact != self.gc_contact:
    
    1156
    +                return
    
    1157
    +        else:
    
    1158
    +            if event.contact.jid != self.contact.jid:
    
    1159
    +                return
    
    1157 1160
     
    
    1158 1161
             self.draw_banner_text()
    
    1162
    +
    
    1159 1163
             # update chatstate in tab for this chat
    
    1160
    -        chatstate = app.contacts.get_combined_chatstate(
    
    1161
    -            self.account, self.contact.jid)
    
    1164
    +        if event.contact.is_gc_contact:
    
    1165
    +            chatstate = event.contact.chatstate
    
    1166
    +        else:
    
    1167
    +            chatstate = app.contacts.get_combined_chatstate(
    
    1168
    +                self.account, self.contact.jid)
    
    1162 1169
             self.parent_win.redraw_tab(self, chatstate)
    
    1163 1170
     
    
    1164 1171
         def _nec_caps_received(self, obj):
    
    ... ... @@ -1239,12 +1246,6 @@ class ChatControl(ChatControlBase):
    1239 1246
     
    
    1240 1247
                 dialogs.TransformChatToMUC(self.account, [c.jid], [dropped_jid])
    
    1241 1248
     
    
    1242
    -    def _on_message_tv_buffer_changed(self, textbuffer):
    
    1243
    -        super()._on_message_tv_buffer_changed(textbuffer)
    
    1244
    -        if textbuffer.get_char_count() and self.encryption:
    
    1245
    -            app.plugin_manager.extension_point(
    
    1246
    -                'typing' + self.encryption, self)
    
    1247
    -
    
    1248 1249
         def restore_conversation(self):
    
    1249 1250
             jid = self.contact.jid
    
    1250 1251
             # don't restore lines if it's a transport
    

  • gajim/chat_control_base.py
    ... ... @@ -341,10 +341,9 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
    341 341
             con = app.connections[self.account]
    
    342 342
             con.get_module('Chatstate').set_active(self.contact.jid)
    
    343 343
     
    
    344
    -        message_tv_buffer = self.msg_textview.get_buffer()
    
    345
    -        id_ = message_tv_buffer.connect('changed',
    
    344
    +        id_ = self.msg_textview.connect('text-changed',
    
    346 345
                 self._on_message_tv_buffer_changed)
    
    347
    -        self.handlers[id_] = message_tv_buffer
    
    346
    +        self.handlers[id_] = self.msg_textview
    
    348 347
             if parent_win is not None:
    
    349 348
                 id_ = parent_win.window.connect('motion-notify-event',
    
    350 349
                     self._on_window_motion_notify)
    
    ... ... @@ -837,10 +836,14 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
    837 836
                 con = app.connections[self.account]
    
    838 837
                 con.get_module('Chatstate').set_mouse_activity(self.contact)
    
    839 838
     
    
    840
    -    def _on_message_tv_buffer_changed(self, *args):
    
    839
    +    def _on_message_tv_buffer_changed(self, textview, textbuffer):
    
    840
    +        if textbuffer.get_char_count() and self.encryption:
    
    841
    +            app.plugin_manager.extension_point(
    
    842
    +                'typing' + self.encryption, self)
    
    843
    +
    
    841 844
             con = app.connections[self.account]
    
    842 845
             con.get_module('Chatstate').set_keyboard_activity(self.contact)
    
    843
    -        if not self.msg_textview.has_text():
    
    846
    +        if not textview.has_text():
    
    844 847
                 con.get_module('Chatstate').set_chatstate(self.contact,
    
    845 848
                                                           Chatstate.ACTIVE)
    
    846 849
                 return
    

  • gajim/common/contacts.py
    ... ... @@ -60,6 +60,8 @@ class CommonContact(XMPPEntity):
    60 60
             # this is contact's chatstate
    
    61 61
             self._chatstate = chatstate
    
    62 62
     
    
    63
    +        self._is_pm_contact = False
    
    64
    +
    
    63 65
         @property
    
    64 66
         def show(self):
    
    65 67
             return self._show
    
    ... ... @@ -91,6 +93,10 @@ class CommonContact(XMPPEntity):
    91 93
         def is_gc_contact(self):
    
    92 94
             return isinstance(self, GC_Contact)
    
    93 95
     
    
    96
    +    @property
    
    97
    +    def is_pm_contact(self):
    
    98
    +        return self._is_pm_contact
    
    99
    +
    
    94 100
         def get_full_jid(self):
    
    95 101
             raise NotImplementedError
    
    96 102
     
    
    ... ... @@ -117,7 +123,8 @@ class Contact(CommonContact):
    117 123
         """
    
    118 124
         def __init__(self, jid, account, name='', groups=None, show='', status='',
    
    119 125
         sub='', ask='', resource='', priority=0, keyID='', client_caps=None,
    
    120
    -    chatstate=None, idle_time=None, avatar_sha=None, groupchat=False):
    
    126
    +    chatstate=None, idle_time=None, avatar_sha=None, groupchat=False,
    
    127
    +    is_pm_contact=False):
    
    121 128
             if not isinstance(jid, str):
    
    122 129
                 print('no str')
    
    123 130
             if groups is None:
    
    ... ... @@ -130,6 +137,7 @@ class Contact(CommonContact):
    130 137
             self.groups = [i if i else _('General') for i in set(groups)] # filter duplicate values
    
    131 138
             self.avatar_sha = avatar_sha
    
    132 139
             self._is_groupchat = groupchat
    
    140
    +        self._is_pm_contact = is_pm_contact
    
    133 141
     
    
    134 142
             self.sub = sub
    
    135 143
             self.ask = ask
    
    ... ... @@ -227,7 +235,8 @@ class GC_Contact(CommonContact):
    227 235
             """
    
    228 236
             return Contact(jid=self.get_full_jid(), account=self.account,
    
    229 237
                 name=self.name, groups=[], show=self.show, status=self.status,
    
    230
    -            sub='none', client_caps=self.client_caps, avatar_sha=self.avatar_sha)
    
    238
    +            sub='none', client_caps=self.client_caps, avatar_sha=self.avatar_sha,
    
    239
    +            is_pm_contact=True)
    
    231 240
     
    
    232 241
     
    
    233 242
     class LegacyContactsAPI:
    

  • gajim/common/modules/chatstates.py
    ... ... @@ -103,13 +103,21 @@ class Chatstate:
    103 103
                 # Dont show chatstates from our own resources
    
    104 104
                 return
    
    105 105
     
    
    106
    +        if event.mtype == 'groupchat':
    
    107
    +            # Not implemented yet
    
    108
    +            return
    
    109
    +
    
    106 110
             chatstate = parse_chatstate(event.stanza)
    
    107 111
             if chatstate is None:
    
    108 112
                 return
    
    109 113
     
    
    110
    -        contact = app.contacts.get_contact_from_full_jid(
    
    111
    -            self._account, event.fjid)
    
    112
    -        if contact is None or contact.is_gc_contact:
    
    114
    +        if event.muc_pm:
    
    115
    +            contact = app.contacts.get_gc_contact(
    
    116
    +                self._account, event.jid, event.resource)
    
    117
    +        else:
    
    118
    +            contact = app.contacts.get_contact_from_full_jid(
    
    119
    +                self._account, event.fjid)
    
    120
    +        if contact is None:
    
    113 121
                 return
    
    114 122
     
    
    115 123
             contact.chatstate = chatstate
    
    ... ... @@ -117,7 +125,7 @@ class Chatstate:
    117 125
             app.nec.push_outgoing_event(
    
    118 126
                 NetworkEvent('chatstate-received',
    
    119 127
                              account=self._account,
    
    120
    -                         jid=event.jid))
    
    128
    +                         contact=contact))
    
    121 129
     
    
    122 130
         def _check_last_interaction(self) -> GLib.SOURCE_CONTINUE:
    
    123 131
             setting = app.config.get('outgoing_chat_state_notifications')
    
    ... ... @@ -129,10 +137,10 @@ class Chatstate:
    129 137
                 current_state = self._chatstates.get(jid)
    
    130 138
                 if current_state is None:
    
    131 139
                     self._last_mouse_activity.pop(jid, None)
    
    132
    -                return GLib.SOURCE_CONTINUE
    
    140
    +                continue
    
    133 141
     
    
    134 142
                 if current_state in (State.GONE, State.INACTIVE):
    
    135
    -                return GLib.SOURCE_CONTINUE
    
    143
    +                continue
    
    136 144
     
    
    137 145
                 new_chatstate = None
    
    138 146
                 if now - time_ > INACTIVE_AFTER:
    
    ... ... @@ -147,9 +155,15 @@ class Chatstate:
    147 155
                     if self._chatstates.get(jid) != new_chatstate:
    
    148 156
                         contact = app.contacts.get_contact(self._account, jid)
    
    149 157
                         if contact is None:
    
    150
    -                        self._last_mouse_activity.pop(jid, None)
    
    151
    -                        return GLib.SOURCE_CONTINUE
    
    152
    -                    self.set_chatstate(contact, new_chatstate)
    
    158
    +                        room, nick = app.get_room_and_nick_from_fjid(jid)
    
    159
    +                        contact = app.contacts.get_gc_contact(
    
    160
    +                            self._account, room, nick)
    
    161
    +                        if contact is not None:
    
    162
    +                            contact = contact.as_contact()
    
    163
    +                        else:
    
    164
    +                            self._last_mouse_activity.pop(jid, None)
    
    165
    +                            continue
    
    166
    +                self.set_chatstate(contact, new_chatstate)
    
    153 167
     
    
    154 168
             return GLib.SOURCE_CONTINUE
    
    155 169
     
    
    ... ... @@ -196,8 +210,9 @@ class Chatstate:
    196 210
             if not contact.is_groupchat():
    
    197 211
                 # Dont leak presence to contacts
    
    198 212
                 # which are not allowed to see our status
    
    199
    -            if contact and contact.sub in ('to', 'none'):
    
    200
    -                return
    
    213
    +            if not contact.is_pm_contact:
    
    214
    +                if contact and contact.sub in ('to', 'none'):
    
    215
    +                    return
    
    201 216
     
    
    202 217
                 if contact.show == 'offline':
    
    203 218
                     return
    

  • gajim/message_textview.py
    ... ... @@ -21,6 +21,7 @@ import gc
    21 21
     
    
    22 22
     from gi.repository import Gtk
    
    23 23
     from gi.repository import GLib
    
    24
    +from gi.repository import GObject
    
    24 25
     from gi.repository import Pango
    
    25 26
     
    
    26 27
     from gajim.common import app
    
    ... ... @@ -36,6 +37,10 @@ class MessageTextView(Gtk.TextView):
    36 37
         Class for the message textview (where user writes new messages) for
    
    37 38
         chat/groupchat windows
    
    38 39
         """
    
    40
    +    __gsignals__ = {
    
    41
    +        'text-changed': (GObject.SIGNAL_RUN_LAST, None, (Gtk.TextBuffer,))
    
    42
    +    }
    
    43
    +
    
    39 44
         UNDO_LIMIT = 20
    
    40 45
         PLACEHOLDER = _('Write a message…')
    
    41 46
     
    
    ... ... @@ -60,6 +65,9 @@ class MessageTextView(Gtk.TextView):
    60 65
             self.undo_pressed = False
    
    61 66
     
    
    62 67
             buffer_ = self.get_buffer()
    
    68
    +        buffer_.connect('changed', self._on_buffer_changed)
    
    69
    +        self._last_text = ''
    
    70
    +
    
    63 71
             self.begin_tags = {}
    
    64 72
             self.end_tags = {}
    
    65 73
             self.color_tags = []
    
    ... ... @@ -94,6 +102,16 @@ class MessageTextView(Gtk.TextView):
    94 102
             buffer_.insert_with_tags(
    
    95 103
                 start, self.PLACEHOLDER, self.placeholder_tag)
    
    96 104
     
    
    105
    +    def _on_buffer_changed(self, *args):
    
    106
    +        text = self.get_text()
    
    107
    +        # Because of inserting and removing PLACEHOLDER text
    
    108
    +        # the signal becomes unreliable when determining if the user
    
    109
    +        # typed in new text. So we send our own signal depending on if
    
    110
    +        # there is real new text that is not the PLACEHOLDER
    
    111
    +        if text != self._last_text:
    
    112
    +            self.emit('text-changed', self.get_buffer())
    
    113
    +            self._last_text = text
    
    114
    +
    
    97 115
         def has_text(self):
    
    98 116
             buf = self.get_buffer()
    
    99 117
             start, end = buf.get_bounds()
    

  • gajim/remote_control.py
    ... ... @@ -324,9 +324,14 @@ class GajimRemote(Server):
    324 324
                 self.on_message_sent)
    
    325 325
     
    
    326 326
         def on_chatstate_received(self, obj):
    
    327
    -        chatstate = app.contacts.get_combined_chatstate(
    
    328
    -            obj.account, obj.jid)
    
    329
    -        self.raise_signal('ChatState', (obj.account, [obj.jid, chatstate]))
    
    327
    +        if obj.contact.is_gc_contact:
    
    328
    +            jid = obj.contact.get_full_jid()
    
    329
    +            chatstate = obj.contact.chatstate
    
    330
    +        else:
    
    331
    +            jid = obj.contact.jid
    
    332
    +            chatstate = app.contacts.get_combined_chatstate(
    
    333
    +                obj.account, obj.contact.jid)
    
    334
    +        self.raise_signal('ChatState', (obj.account, [jid, chatstate]))
    
    330 335
     
    
    331 336
         def on_message_sent(self, obj):
    
    332 337
             try: