Improve MUC notifications
- Play sound for received messages, if notify for all messages is activated - Send system notifications on MUC messages - Make notify for all the default in private MUCs Fixes #9383
This commit is contained in:
		
							parent
							
								
									dac5370780
								
							
						
					
					
						commit
						760645f5c3
					
				
					 9 changed files with 92 additions and 33 deletions
				
			
		| 
						 | 
					@ -905,8 +905,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        if kind == 'incoming':
 | 
					        if kind == 'incoming':
 | 
				
			||||||
            if not self.type_id == message_control.TYPE_GC or \
 | 
					            if not self.type_id == message_control.TYPE_GC or \
 | 
				
			||||||
            app.config.get('notify_on_all_muc_messages') or \
 | 
					            app.config.notify_for_muc(jid) or \
 | 
				
			||||||
            app.config.get_per('rooms', jid, 'notify_on_all_messages') or \
 | 
					 | 
				
			||||||
            'marked' in other_tags_for_text:
 | 
					            'marked' in other_tags_for_text:
 | 
				
			||||||
                # it's a normal message, or a muc message with want to be
 | 
					                # it's a normal message, or a muc message with want to be
 | 
				
			||||||
                # notified about if quitting just after
 | 
					                # notified about if quitting just after
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,7 +482,7 @@ class Config:
 | 
				
			||||||
        'contact_disconnected': [False, 'disconnected.wav'],
 | 
					        'contact_disconnected': [False, 'disconnected.wav'],
 | 
				
			||||||
        'message_sent': [False, 'sent.wav'],
 | 
					        'message_sent': [False, 'sent.wav'],
 | 
				
			||||||
        'muc_message_highlight': [True, 'gc_message1.wav', _('Sound to play when a group chat message contains one of the words in muc_highlight_words, or when a group chat message contains your nickname.')],
 | 
					        'muc_message_highlight': [True, 'gc_message1.wav', _('Sound to play when a group chat message contains one of the words in muc_highlight_words, or when a group chat message contains your nickname.')],
 | 
				
			||||||
        'muc_message_received': [False, 'gc_message2.wav', _('Sound to play when any MUC message arrives.')],
 | 
					        'muc_message_received': [True, 'gc_message2.wav', _('Sound to play when any MUC message arrives.')],
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    proxies_default = {
 | 
					    proxies_default = {
 | 
				
			||||||
| 
						 | 
					@ -638,13 +638,15 @@ class Config:
 | 
				
			||||||
        obj[subname] = value
 | 
					        obj[subname] = value
 | 
				
			||||||
        self._timeout_save()
 | 
					        self._timeout_save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_per(self, optname, key=None, subname=None): # per_group_of_option
 | 
					    def get_per(self, optname, key=None, subname=None, default=None): # per_group_of_option
 | 
				
			||||||
        if optname not in self.__options_per_key:
 | 
					        if optname not in self.__options_per_key:
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
        dict_ = self.__options_per_key[optname][1]
 | 
					        dict_ = self.__options_per_key[optname][1]
 | 
				
			||||||
        if not key:
 | 
					        if not key:
 | 
				
			||||||
            return list(dict_.keys())
 | 
					            return list(dict_.keys())
 | 
				
			||||||
        if key not in dict_:
 | 
					        if key not in dict_:
 | 
				
			||||||
 | 
					            if default is not None:
 | 
				
			||||||
 | 
					                return default
 | 
				
			||||||
            if subname in self.__options_per_key[optname][0]:
 | 
					            if subname in self.__options_per_key[optname][0]:
 | 
				
			||||||
                return self.__options_per_key[optname][0][subname][1]
 | 
					                return self.__options_per_key[optname][0][subname][1]
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
| 
						 | 
					@ -712,6 +714,11 @@ class Config:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return (account not in no_log_for) and (jid not in no_log_for)
 | 
					        return (account not in no_log_for) and (jid not in no_log_for)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def notify_for_muc(self, room):
 | 
				
			||||||
 | 
					        all_ = self.get('notify_on_all_muc_messages')
 | 
				
			||||||
 | 
					        room = self.get_per('rooms', room, 'notify_on_all_messages')
 | 
				
			||||||
 | 
					        return all_ or room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _init_options(self):
 | 
					    def _init_options(self):
 | 
				
			||||||
        for opt in self.__options[0]:
 | 
					        for opt in self.__options[0]:
 | 
				
			||||||
            self.__options[1][opt] = self.__options[0][opt][Option.VAL]
 | 
					            self.__options[1][opt] = self.__options[0][opt][Option.VAL]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1036,7 +1036,46 @@ class NotificationEvent(nec.NetworkIncomingEvent):
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.do_sound = False
 | 
					            self.do_sound = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.do_popup = False
 | 
					        self.control = app.interface.msg_win_mgr.search_control(
 | 
				
			||||||
 | 
					            msg_obj.jid, self.account)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.control is not None:
 | 
				
			||||||
 | 
					            self.control_focused = self.control.has_focus()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if app.config.get('notify_on_new_message'):
 | 
				
			||||||
 | 
					            notify_for_muc = (app.config.notify_for_muc(self.jid) or
 | 
				
			||||||
 | 
					                              sound == 'highlight')
 | 
				
			||||||
 | 
					            if not notify_for_muc:
 | 
				
			||||||
 | 
					                self.do_popup = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            elif self.control_focused:
 | 
				
			||||||
 | 
					                self.do_popup = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            elif app.config.get('autopopupaway'):
 | 
				
			||||||
 | 
					                # always show notification
 | 
				
			||||||
 | 
					                self.do_popup = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            elif app.connections[self.conn.name].connected in (2, 3):
 | 
				
			||||||
 | 
					                # we're online or chat
 | 
				
			||||||
 | 
					                self.do_popup = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.popup_msg_type = 'gc_msg'
 | 
				
			||||||
 | 
					        self.popup_event_type = _('New Group Chat Message')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if app.config.get('notification_preview_message'):
 | 
				
			||||||
 | 
					            self.popup_text = msg_obj.msgtxt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        type_events = ['printed_marked_gc_msg', 'printed_gc_msg']
 | 
				
			||||||
 | 
					        count = len(app.events.get_events(self.account, self.jid, type_events))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        contact = app.contacts.get_contact(self.account, self.jid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.popup_title = i18n.ngettext(
 | 
				
			||||||
 | 
					            'New message from %(nickname)s',
 | 
				
			||||||
 | 
					            '%(n_msgs)i unread messages in %(groupchat_name)s',
 | 
				
			||||||
 | 
					            count) % {'nickname': self.base_event.nick,
 | 
				
			||||||
 | 
					                      'n_msgs': count,
 | 
				
			||||||
 | 
					                      'groupchat_name': contact.get_shown_name()}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_incoming_pres_event(self, pres_obj):
 | 
					    def handle_incoming_pres_event(self, pres_obj):
 | 
				
			||||||
        if app.jid_is_transport(pres_obj.jid):
 | 
					        if app.jid_is_transport(pres_obj.jid):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -332,6 +332,16 @@ class Events:
 | 
				
			||||||
                events_list.append(ev)
 | 
					                events_list.append(ev)
 | 
				
			||||||
        return events_list
 | 
					        return events_list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_all_events(self, types=None):
 | 
				
			||||||
 | 
					        accounts = self._events.keys()
 | 
				
			||||||
 | 
					        events = []
 | 
				
			||||||
 | 
					        for account in accounts:
 | 
				
			||||||
 | 
					            for jid in self._events[account]:
 | 
				
			||||||
 | 
					                for event in self._events[account][jid]:
 | 
				
			||||||
 | 
					                    if types is None or event.type_ in types:
 | 
				
			||||||
 | 
					                        events.append(event)
 | 
				
			||||||
 | 
					        return events
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_first_event(self, account=None, jid=None, type_=None):
 | 
					    def get_first_event(self, account=None, jid=None, type_=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Return the first event of type type_ if given
 | 
					        Return the first event of type type_ if given
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -375,8 +375,11 @@ class GroupchatControl(ChatControlBase):
 | 
				
			||||||
        act.connect('change-state', self._on_minimize)
 | 
					        act.connect('change-state', self._on_minimize)
 | 
				
			||||||
        self.parent_win.window.add_action(act)
 | 
					        self.parent_win.window.add_action(act)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Enable notify on all for private rooms
 | 
				
			||||||
 | 
					        members_only = muc_caps_cache.supports(self.contact.jid,
 | 
				
			||||||
 | 
					                                               'muc#roomconfig_membersonly')
 | 
				
			||||||
        value = app.config.get_per(
 | 
					        value = app.config.get_per(
 | 
				
			||||||
            'rooms', self.contact.jid, 'notify_on_all_messages')
 | 
					            'rooms', self.contact.jid, 'notify_on_all_messages', members_only)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        act = Gio.SimpleAction.new_stateful(
 | 
					        act = Gio.SimpleAction.new_stateful(
 | 
				
			||||||
            'notify-on-message-' + self.control_id,
 | 
					            'notify-on-message-' + self.control_id,
 | 
				
			||||||
| 
						 | 
					@ -1294,8 +1297,7 @@ class GroupchatControl(ChatControlBase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_nb_unread(self):
 | 
					    def get_nb_unread(self):
 | 
				
			||||||
        type_events = ['printed_marked_gc_msg']
 | 
					        type_events = ['printed_marked_gc_msg']
 | 
				
			||||||
        if app.config.get('notify_on_all_muc_messages') or \
 | 
					        if app.config.notify_for_muc(self.room_jid):
 | 
				
			||||||
        app.config.get_per('rooms', self.room_jid, 'notify_on_all_messages'):
 | 
					 | 
				
			||||||
            type_events.append('printed_gc_msg')
 | 
					            type_events.append('printed_gc_msg')
 | 
				
			||||||
        nb = len(app.events.get_events(self.account, self.room_jid,
 | 
					        nb = len(app.events.get_events(self.account, self.room_jid,
 | 
				
			||||||
            type_events))
 | 
					            type_events))
 | 
				
			||||||
| 
						 | 
					@ -1314,25 +1316,30 @@ class GroupchatControl(ChatControlBase):
 | 
				
			||||||
        Returns a 2-Tuple. The first says whether or not to highlight the text,
 | 
					        Returns a 2-Tuple. The first says whether or not to highlight the text,
 | 
				
			||||||
        the second, what sound to play
 | 
					        the second, what sound to play
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        highlight, sound = (None, None)
 | 
					        highlight, sound = None, None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        notify = app.config.notify_for_muc(self.room_jid)
 | 
				
			||||||
 | 
					        message_sound_enabled = app.config.get_per('soundevents',
 | 
				
			||||||
 | 
					                                                   'muc_message_received',
 | 
				
			||||||
 | 
					                                                   'enabled')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Are any of the defined highlighting words in the text?
 | 
					        # Are any of the defined highlighting words in the text?
 | 
				
			||||||
        if self.needs_visual_notification(text):
 | 
					        if self.needs_visual_notification(text):
 | 
				
			||||||
            highlight = True
 | 
					            highlight = True
 | 
				
			||||||
            if app.config.get_per('soundevents', 'muc_message_highlight',
 | 
					            if app.config.get_per('soundevents',
 | 
				
			||||||
            'enabled'):
 | 
					                                  'muc_message_highlight',
 | 
				
			||||||
 | 
					                                  'enabled'):
 | 
				
			||||||
                sound = 'highlight'
 | 
					                sound = 'highlight'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Do we play a sound on every muc message?
 | 
					        # Do we play a sound on every muc message?
 | 
				
			||||||
        elif app.config.get_per('soundevents', 'muc_message_received', \
 | 
					        elif notify and message_sound_enabled:
 | 
				
			||||||
        'enabled'):
 | 
					 | 
				
			||||||
            sound = 'received'
 | 
					            sound = 'received'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Is it a history message? Don't want sound-floods when we join.
 | 
					        # Is it a history message? Don't want sound-floods when we join.
 | 
				
			||||||
        if tim is not None and time.mktime(time.localtime()) - tim > 1:
 | 
					        if tim is not None and time.mktime(time.localtime()) - tim > 1:
 | 
				
			||||||
            sound = None
 | 
					            sound = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return (highlight, sound)
 | 
					        return highlight, sound
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def check_and_possibly_add_focus_out_line(self):
 | 
					    def check_and_possibly_add_focus_out_line(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,7 +111,8 @@ class Notification:
 | 
				
			||||||
            if event.type_ == 'gc-invitation':
 | 
					            if event.type_ == 'gc-invitation':
 | 
				
			||||||
                self._withdraw('gc-invitation', event.account, event.room_jid)
 | 
					                self._withdraw('gc-invitation', event.account, event.room_jid)
 | 
				
			||||||
            if event.type_ in ('normal', 'printed_chat', 'chat',
 | 
					            if event.type_ in ('normal', 'printed_chat', 'chat',
 | 
				
			||||||
                               'printed_pm', 'pm'):
 | 
					                               'printed_pm', 'pm', 'printed_marked_gc_msg',
 | 
				
			||||||
 | 
					                               'printed_gc_msg'):
 | 
				
			||||||
                self._withdraw('new-message', event.account, event.jid)
 | 
					                self._withdraw('new-message', event.account, event.jid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _nec_our_status(self, obj):
 | 
					    def _nec_our_status(self, obj):
 | 
				
			||||||
| 
						 | 
					@ -164,6 +165,7 @@ class Notification:
 | 
				
			||||||
        if event_type in (
 | 
					        if event_type in (
 | 
				
			||||||
                _('Contact Signed In'), _('Contact Signed Out'),
 | 
					                _('Contact Signed In'), _('Contact Signed Out'),
 | 
				
			||||||
                _('New Message'), _('New Single Message'), _('New Private Message'),
 | 
					                _('New Message'), _('New Single Message'), _('New Private Message'),
 | 
				
			||||||
 | 
					                _('New Group Chat Message'),
 | 
				
			||||||
                _('Contact Changed Status'), _('File Transfer Request'),
 | 
					                _('Contact Changed Status'), _('File Transfer Request'),
 | 
				
			||||||
                _('File Transfer Error'), _('File Transfer Completed'),
 | 
					                _('File Transfer Error'), _('File Transfer Completed'),
 | 
				
			||||||
                _('File Transfer Stopped'), _('Groupchat Invitation'),
 | 
					                _('File Transfer Stopped'), _('Groupchat Invitation'),
 | 
				
			||||||
| 
						 | 
					@ -193,7 +195,8 @@ class Notification:
 | 
				
			||||||
                notif_id = self._make_id('connection-failed', account)
 | 
					                notif_id = self._make_id('connection-failed', account)
 | 
				
			||||||
            elif event_type in (_('New Message'),
 | 
					            elif event_type in (_('New Message'),
 | 
				
			||||||
                                _('New Single Message'),
 | 
					                                _('New Single Message'),
 | 
				
			||||||
                                _('New Private Message')):
 | 
					                                _('New Private Message'),
 | 
				
			||||||
 | 
					                                _('New Group Chat Message')):
 | 
				
			||||||
                avatar = app.contacts.get_avatar(account, jid)
 | 
					                avatar = app.contacts.get_avatar(account, jid)
 | 
				
			||||||
                if avatar:
 | 
					                if avatar:
 | 
				
			||||||
                    icon_pixbuf = avatar
 | 
					                    icon_pixbuf = avatar
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -467,11 +467,8 @@ def get_show_in_systray(type_, jid):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Return True if this event must be shown in systray, else False
 | 
					    Return True if this event must be shown in systray, else False
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    notify = app.config.get('notify_on_all_muc_messages')
 | 
					    notify = app.config.notify_for_muc(jid)
 | 
				
			||||||
    notify_for_jid = app.config.get_per(
 | 
					    if type_ == 'printed_gc_msg' and not notify:
 | 
				
			||||||
        'rooms', jid, 'notify_on_all_messages')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if type_ == 'printed_gc_msg' and not notify and not notify_for_jid:
 | 
					 | 
				
			||||||
        # it's not an highlighted message, don't show in systray
 | 
					        # it's not an highlighted message, don't show in systray
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
    return app.config.get('trayicon_notification_on_events')
 | 
					    return app.config.get('trayicon_notification_on_events')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -490,10 +490,9 @@ class MessageWindow:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        unread = 0
 | 
					        unread = 0
 | 
				
			||||||
        for ctrl in self.controls():
 | 
					        for ctrl in self.controls():
 | 
				
			||||||
            if ctrl.type_id == message_control.TYPE_GC and not \
 | 
					            if (ctrl.type_id == message_control.TYPE_GC and not
 | 
				
			||||||
            app.config.get('notify_on_all_muc_messages') and not \
 | 
					                    app.config.notify_for_muc(ctrl.room_jid) and not
 | 
				
			||||||
            app.config.get_per('rooms', ctrl.room_jid,
 | 
					                    ctrl.attention_flag):
 | 
				
			||||||
            'notify_on_all_messages') and not ctrl.attention_flag:
 | 
					 | 
				
			||||||
                # count only pm messages
 | 
					                # count only pm messages
 | 
				
			||||||
                unread += ctrl.get_nb_unread_pm()
 | 
					                unread += ctrl.get_nb_unread_pm()
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
| 
						 | 
					@ -509,10 +508,8 @@ class MessageWindow:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if control.type_id == message_control.TYPE_GC:
 | 
					        if control.type_id == message_control.TYPE_GC:
 | 
				
			||||||
            name = control.room_jid.split('@')[0]
 | 
					            name = control.room_jid.split('@')[0]
 | 
				
			||||||
            urgent = control.attention_flag or \
 | 
					            urgent = (control.attention_flag or
 | 
				
			||||||
                app.config.get('notify_on_all_muc_messages') or \
 | 
					                      app.config.notify_for_muc(control.room_jid))
 | 
				
			||||||
                app.config.get_per('rooms', control.room_jid,
 | 
					 | 
				
			||||||
                'notify_on_all_messages')
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            name = control.contact.get_shown_name()
 | 
					            name = control.contact.get_shown_name()
 | 
				
			||||||
            if control.resource:
 | 
					            if control.resource:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2520,10 +2520,10 @@ class RosterWindow:
 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
            # check if we have unread messages
 | 
					            # check if we have unread messages
 | 
				
			||||||
            unread = app.events.get_nb_events()
 | 
					            unread = app.events.get_nb_events()
 | 
				
			||||||
            if not app.config.get('notify_on_all_muc_messages'):
 | 
					
 | 
				
			||||||
                unread_not_to_notify = app.events.get_nb_events(
 | 
					            for event in app.events.get_all_events(['printed_gc_msg']):
 | 
				
			||||||
                        ['printed_gc_msg'])
 | 
					                if not app.config.notify_for_muc(event.jid):
 | 
				
			||||||
                unread -= unread_not_to_notify
 | 
					                    unread -= 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # check if we have recent messages
 | 
					            # check if we have recent messages
 | 
				
			||||||
            recent = False
 | 
					            recent = False
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue