Add chat state setting per room

- Add menu option to the group chat menu for setting the chat state
- Up the paused timer to 10 seconds
- Default for group chats is composing only
This commit is contained in:
Philipp Hörist 2019-01-06 02:01:12 +01:00
parent 777b8d72e4
commit eb99291d44
5 changed files with 64 additions and 24 deletions

View File

@ -339,7 +339,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
self.seclabel_combo = self.xml.get_object('label_selector')
con = app.connections[self.account]
con.get_module('Chatstate').set_active(self.contact.jid)
con.get_module('Chatstate').set_active(self.contact)
id_ = self.msg_textview.connect('text-changed',
self._on_message_tv_buffer_changed)
@ -813,7 +813,8 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
if self.parent_win.get_active_jid() == self.contact.jid:
# if window is the active one, set last interaction
con = app.connections[self.account]
con.get_module('Chatstate').set_mouse_activity(self.contact)
con.get_module('Chatstate').set_mouse_activity(
self.contact, self.msg_textview.has_text())
def _on_message_tv_buffer_changed(self, textview, textbuffer):
if textbuffer.get_char_count() and self.encryption:

View File

@ -443,6 +443,7 @@ class Config:
'print_join_left': [opt_bool, False, _('Show a status message for every join or leave in a group chat')],
'minimize_on_autojoin': [opt_bool, True, _('If the group chat is minimized into the roster on autojoin')],
'minimize_on_close': [opt_bool, True, _('If the group chat is minimized into the roster on close')],
'send_chatstate': [opt_str, 'composing_only', _('Chat state notifications that are sent to the group chat. Possible values: all, composing_only, disabled')],
}, {}),
'plugins': ({
'active': [opt_bool, False, _('State whether plugins should be activated on startup (this is saved on Gajim exit). This option SHOULD NOT be used to (de)activate plug-ins. Use GUI instead.')],

View File

@ -40,7 +40,7 @@ from gajim.common.types import ConnectionT
log = logging.getLogger('gajim.c.m.chatstates')
INACTIVE_AFTER = 60
PAUSED_AFTER = 5
PAUSED_AFTER = 10
def ensure_enabled(func):
@ -174,10 +174,6 @@ class Chatstate:
@ensure_enabled
def _check_last_interaction(self) -> GLib.SOURCE_CONTINUE:
setting = app.config.get('outgoing_chat_state_notifications')
if setting in ('composing_only', 'disabled'):
return GLib.SOURCE_CONTINUE
now = time.time()
for jid in list(self._last_mouse_activity.keys()):
time_ = self._last_mouse_activity[jid]
@ -222,17 +218,15 @@ class Chatstate:
return GLib.SOURCE_CONTINUE
@ensure_enabled
def set_active(self, jid: str) -> None:
self._last_mouse_activity[jid] = time.time()
setting = app.config.get('outgoing_chat_state_notifications')
if setting == 'disabled':
def set_active(self, contact: ContactT) -> None:
if self._get_chatstate_setting(contact) == 'disabled':
return
self._chatstates[jid] = State.ACTIVE
self._last_mouse_activity[contact.jid] = time.time()
self._chatstates[contact.jid] = State.ACTIVE
def get_active_chatstate(self, contact: ContactT) -> Optional[str]:
# determines if we add 'active' on outgoing messages
setting = app.config.get('outgoing_chat_state_notifications')
if setting == 'disabled':
if self._get_chatstate_setting(contact) == 'disabled':
return None
if not contact.is_groupchat():
@ -277,11 +271,13 @@ class Chatstate:
self.remove_delay_timeout(contact)
current_state = self._chatstates.get(contact.jid)
setting = app.config.get('outgoing_chat_state_notifications')
setting = self._get_chatstate_setting(contact)
if setting == 'disabled':
# Send a last 'active' state after user disabled chatstates
if current_state is not None:
log.info('Send: %-10s - %s', State.ACTIVE, contact.jid)
log.info('Disabled for %s', contact.jid)
log.info('Send last state: %-10s - %s',
State.ACTIVE, contact.jid)
event_attrs = {'account': self._account,
'jid': contact.jid,
@ -317,7 +313,7 @@ class Chatstate:
self._last_mouse_activity[contact.jid] = time.time()
if setting == 'composing_only':
if state in (State.INACTIVE, State.GONE, State.PAUSED):
if state in (State.INACTIVE, State.GONE):
state = State.ACTIVE
if current_state == state:
@ -340,18 +336,28 @@ class Chatstate:
self._chatstates[contact.jid] = state
@ensure_enabled
def set_mouse_activity(self, contact: ContactT) -> None:
self._last_mouse_activity[contact.jid] = time.time()
setting = app.config.get('outgoing_chat_state_notifications')
if setting == 'disabled':
def set_mouse_activity(self, contact: ContactT, was_paused: bool) -> None:
if self._get_chatstate_setting(contact) == 'disabled':
return
self._last_mouse_activity[contact.jid] = time.time()
if self._chatstates.get(contact.jid) == State.INACTIVE:
self.set_chatstate(contact, State.ACTIVE)
if was_paused:
self.set_chatstate(contact, State.PAUSED)
else:
self.set_chatstate(contact, State.ACTIVE)
@ensure_enabled
def set_keyboard_activity(self, contact: ContactT) -> None:
self._last_keyboard_activity[contact.jid] = time.time()
@staticmethod
def _get_chatstate_setting(contact):
if contact.is_groupchat():
return app.config.get_per(
'rooms', contact.jid, 'send_chatstate', 'composing_only')
else:
return app.config.get('outgoing_chat_state_notifications')
def remove_delay_timeout(self, contact):
timeout = self._delay_timeout_ids.get(contact.jid)
if timeout is not None:

View File

@ -393,6 +393,16 @@ class GroupchatControl(ChatControlBase):
act.connect('change-state', self._on_minimize_on_autojoin)
self.parent_win.window.add_action(act)
chatstate = app.config.get_per(
'rooms', self.contact.jid, 'send_chatstate', 'composing_only')
act = Gio.SimpleAction.new_stateful(
'send-chatstate-' + self.control_id,
GLib.VariantType.new("s"),
GLib.Variant("s", chatstate))
act.connect('change-state', self._on_send_chatstate)
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')
@ -713,6 +723,11 @@ class GroupchatControl(ChatControlBase):
app.config.set_per('rooms', self.contact.jid,
'minimize_on_autojoin', param.get_boolean())
def _on_send_chatstate(self, action, param):
action.set_state(param)
app.config.set_per('rooms', self.contact.jid,
'send_chatstate', param.get_string())
def _on_notify_on_all_messages(self, action, param):
action.set_state(param)
app.config.set_per('rooms', self.contact.jid,

View File

@ -665,8 +665,9 @@ def get_groupchat_menu(control_id, account, jid):
('win.notify-on-message-', _('Notify on all messages')),
('win.minimize-on-close-', _('Minimize on close')),
('win.minimize-on-autojoin-', _('Minimize on autojoin')),
(_('Send Chatstate'), ['chatstate']),
]),
(_('Sync Threshold'), []),
(_('Sync Threshold'), ['sync']),
('win.change-nick-', _('Change Nick')),
('win.bookmark-', _('Bookmark Room')),
('win.request-voice-', _('Request Voice')),
@ -692,9 +693,11 @@ def get_groupchat_menu(control_id, account, jid):
menu.append(label, action_name + control_id)
else:
label, sub_menu = item
if not sub_menu:
if 'sync' in sub_menu:
# Sync threshold menu
submenu = build_sync_menu()
elif 'chatstate' in sub_menu:
submenu = build_chatstate_menu()
else:
# This is a submenu
submenu = build_menu(sub_menu)
@ -714,6 +717,20 @@ def get_groupchat_menu(control_id, account, jid):
menu.append(label, '%s%s' % (action_name, day))
return menu
def build_chatstate_menu():
menu = Gio.Menu()
entrys = [
(_('Disabled'), 'disabled'),
(_('Composing only'), 'composing_only'),
(_('All chat states'), 'all')
]
for entry in entrys:
label, setting = entry
action = 'win.send-chatstate-%s::%s' % (control_id, setting)
menu.append(label, action)
return menu
return build_menu(groupchat_menu)