From 20f36e06ad59d5cadbf96340708b652564c7f553 Mon Sep 17 00:00:00 2001 From: ingvar1995 Date: Mon, 23 Jul 2018 00:35:52 +0300 Subject: [PATCH] roles support - callbacks, peer screen --- toxygen/app.py | 5 +-- toxygen/contacts/contacts_manager.py | 51 +++++++++++++++++----------- toxygen/contacts/group_chat.py | 3 ++ toxygen/groups/groups_service.py | 13 +++++++ toxygen/middleware/callbacks.py | 37 ++++++++++++++++++-- toxygen/ui/peer_screen.py | 49 +++++++++++++++++++++----- toxygen/ui/views/peer_screen.ui | 14 ++++++-- 7 files changed, 139 insertions(+), 33 deletions(-) diff --git a/toxygen/app.py b/toxygen/app.py index b270f10..23a465a 100644 --- a/toxygen/app.py +++ b/toxygen/app.py @@ -237,7 +237,7 @@ class App: self._profile_manager = ProfileManager(self._settings, self._toxes, profile_path) data = self._profile_manager.open_profile() if self._toxes.is_data_encrypted(data): - data = self._enter_pass(data) + data = self._enter_password(data) self._tox = self._create_tox(data) def _create_new_profile(self, profile_name): @@ -292,7 +292,7 @@ class App: # Other private methods # ----------------------------------------------------------------------------------------------------------------- - def _enter_pass(self, data): + def _enter_password(self, data): """ Show password screen """ @@ -326,6 +326,7 @@ class App: self._calls_manager.set_toxav(self._tox.AV) self._contacts_manager.update_friends_numbers() + self._contacts_manager.update_groups_lists() self._init_callbacks() diff --git a/toxygen/contacts/contacts_manager.py b/toxygen/contacts/contacts_manager.py index 5913617..10f50ca 100644 --- a/toxygen/contacts/contacts_manager.py +++ b/toxygen/contacts/contacts_manager.py @@ -260,25 +260,26 @@ class ContactsManager(ToxSave): text = util_ui.tr("Enter new alias for friend {} or leave empty to use friend's name:").format(name) title = util_ui.tr('Set alias') text, ok = util_ui.text_dialog(text, title, name) - if ok: - aliases = self._settings['friends_aliases'] - if text: - friend.name = text - try: - index = list(map(lambda x: x[0], aliases)).index(friend.tox_id) - aliases[index] = (friend.tox_id, text) - except: - aliases.append((friend.tox_id, text)) - friend.set_alias(text) - else: # use default name - friend.name = self._tox.friend_get_name(friend.number) - friend.set_alias('') - try: - index = list(map(lambda x: x[0], aliases)).index(friend.tox_id) - del aliases[index] - except: - pass - self._settings.save() + if not ok: + return + aliases = self._settings['friends_aliases'] + if text: + friend.name = text + try: + index = list(map(lambda x: x[0], aliases)).index(friend.tox_id) + aliases[index] = (friend.tox_id, text) + except: + aliases.append((friend.tox_id, text)) + friend.set_alias(text) + else: # use default name + friend.name = self._tox.friend_get_name(friend.number) + friend.set_alias('') + try: + index = list(map(lambda x: x[0], aliases)).index(friend.tox_id) + del aliases[index] + except: + pass + self._settings.save() def friend_public_key(self, num): return self._contacts[num].tox_id @@ -362,6 +363,13 @@ class ContactsManager(ToxSave): contact.reset_avatar(self._settings['identicons']) self._save_profile() + def remove_group_peer_by_id(self, group, peer_id): + peer = group.get_peer_by_id(peer_id) + if not self.check_if_contact_exists(peer.public_key): + return + contact = self.get_contact_by_tox_id(peer.public_key) + self.remove_group_peer(contact) + def remove_group_peer(self, group_peer_contact): contact = self.get_contact_by_tox_id(group_peer_contact.tox_id) self._cleanup_contact_data(contact) @@ -438,6 +446,11 @@ class ContactsManager(ToxSave): group.number = i self.update_filtration() + def update_groups_lists(self): + groups = self._contact_provider.get_all_groups() + for group in groups: + group.remove_all_peers_except_self() + # ----------------------------------------------------------------------------------------------------------------- # Private methods # ----------------------------------------------------------------------------------------------------------------- diff --git a/toxygen/contacts/group_chat.py b/toxygen/contacts/group_chat.py index 61b3858..5409a26 100644 --- a/toxygen/contacts/group_chat.py +++ b/toxygen/contacts/group_chat.py @@ -28,6 +28,9 @@ class GroupChat(contact.Contact, ToxSave): # Peers methods # ----------------------------------------------------------------------------------------------------------------- + def get_self_peer(self): + return self._peers[0] + def get_self_name(self): return self._peers[0].name diff --git a/toxygen/groups/groups_service.py b/toxygen/groups/groups_service.py index 49d5f25..692fb31 100644 --- a/toxygen/groups/groups_service.py +++ b/toxygen/groups/groups_service.py @@ -109,6 +109,19 @@ class GroupsService(tox_save.ToxSave): self._peer_screen = widgets_factory.create_peer_screen_window(group, peer_id) self._peer_screen.show() + # ----------------------------------------------------------------------------------------------------------------- + # Peers actions + # ----------------------------------------------------------------------------------------------------------------- + + def set_new_peer_role(self, group, peer, role): + self._tox.group_mod_set_role(group.number, peer.id, role) + peer.role = role + self.generate_peers_list() + + def toggle_ignore_peer(self, group, peer, ignore): + self._tox.group_toggle_ignore(group.number, peer.id, ignore) + peer.is_muted = ignore + # ----------------------------------------------------------------------------------------------------------------- # Private methods # ----------------------------------------------------------------------------------------------------------------- diff --git a/toxygen/middleware/callbacks.py b/toxygen/middleware/callbacks.py index 9e6059c..a480223 100644 --- a/toxygen/middleware/callbacks.py +++ b/toxygen/middleware/callbacks.py @@ -424,9 +424,10 @@ def group_peer_join(contacts_provider, groups_service): return wrapped -def group_peer_exit(contacts_provider, groups_service): +def group_peer_exit(contacts_provider, groups_service, contacts_manager): def wrapped(tox, group_number, peer_id, message, length, user_data): group = contacts_provider.get_group_by_number(group_number) + contacts_manager.remove_group_peer_by_id(group, peer_id) group.remove_peer(peer_id) invoke_in_main_thread(groups_service.generate_peers_list) @@ -461,6 +462,37 @@ def group_topic(contacts_provider): return wrapped + +def group_moderation(groups_service, contacts_provider, contacts_manager, messenger): + + def update_peer_role(group, mod_peer_id, peer_id, new_role): + peer = group.get_peer_by_id(peer_id) + peer.role = new_role + # TODO: add info message + + def remove_peer(group, mod_peer_id, peer_id, is_ban): + contacts_manager.remove_group_peer_by_id(group, peer_id) + group.remove_peer(peer_id) + # TODO: add info message + + def wrapped(tox, group_number, mod_peer_id, peer_id, event_type, user_data): + group = contacts_provider.get_group_by_number(group_number) + + if event_type == TOX_GROUP_MOD_EVENT['KICK']: + remove_peer(group, mod_peer_id, peer_id, False) + elif event_type == TOX_GROUP_MOD_EVENT['BAN']: + remove_peer(group, mod_peer_id, peer_id, True) + elif event_type == TOX_GROUP_MOD_EVENT['OBSERVER']: + update_peer_role(group, mod_peer_id, peer_id, TOX_GROUP_ROLE['OBSERVER']) + elif event_type == TOX_GROUP_MOD_EVENT['USER']: + update_peer_role(group, mod_peer_id, peer_id, TOX_GROUP_ROLE['USER']) + elif event_type == TOX_GROUP_MOD_EVENT['MODERATOR']: + update_peer_role(group, mod_peer_id, peer_id, TOX_GROUP_ROLE['MODERATOR']) + + groups_service.generate_peers_list() + + return wrapped + # ----------------------------------------------------------------------------------------------------------------- # Callbacks - initialization # ----------------------------------------------------------------------------------------------------------------- @@ -523,7 +555,8 @@ def init_callbacks(tox, profile, settings, plugin_loader, contacts_manager, tox.callback_group_invite(group_invite(groups_service), 0) tox.callback_group_self_join(group_self_join(contacts_provider, groups_service), 0) tox.callback_group_peer_join(group_peer_join(contacts_provider, groups_service), 0) - tox.callback_group_peer_exit(group_peer_exit(contacts_provider, groups_service), 0) + tox.callback_group_peer_exit(group_peer_exit(contacts_provider, groups_service, contacts_manager), 0) tox.callback_group_peer_name(group_peer_name(contacts_provider, groups_service), 0) tox.callback_group_peer_status(group_peer_status(contacts_provider, groups_service), 0) tox.callback_group_topic(group_topic(contacts_provider), 0) + tox.callback_group_moderation(group_moderation(groups_service, contacts_provider, contacts_manager, messenger), 0) diff --git a/toxygen/ui/peer_screen.py b/toxygen/ui/peer_screen.py index 6850125..651d998 100644 --- a/toxygen/ui/peer_screen.py +++ b/toxygen/ui/peer_screen.py @@ -14,36 +14,69 @@ class PeerScreen(CenteredWidget): self._group = group self._peer = group.get_peer_by_id(peer_id) + self._roles = { + TOX_GROUP_ROLE['FOUNDER']: util_ui.tr('Administrator'), + TOX_GROUP_ROLE['MODERATOR']: util_ui.tr('Moderator'), + TOX_GROUP_ROLE['USER']: util_ui.tr('User'), + TOX_GROUP_ROLE['OBSERVER']: util_ui.tr('Observer') + } + uic.loadUi(util.get_views_path('peer_screen'), self) self._update_ui() def _update_ui(self): self.statusCircle = StatusCircle(self) - self.statusCircle.setGeometry(50, 20, 20, 20) + self.statusCircle.setGeometry(50, 15, 30, 30) + self.statusCircle.update(self._peer.status) self.peerNameLabel.setText(self._peer.name) self.ignorePeerCheckBox.setChecked(self._peer.is_muted) + self.ignorePeerCheckBox.clicked.connect(self._toggle_ignore) self.sendPrivateMessagePushButton.clicked.connect(self._send_private_message) self.copyPublicKeyPushButton.clicked.connect(self._copy_public_key) self.roleNameLabel.setText(self._get_role_name()) + can_change_role = self._can_change_role() + self.rolesComboBox.setVisible(can_change_role) + self.roleNameLabel.setVisible(not can_change_role) + self._retranslate_ui() + self.rolesComboBox.currentIndexChanged.connect(self._role_set) + def _retranslate_ui(self): self.setWindowTitle(util_ui.tr('Peer details')) self.ignorePeerCheckBox.setText(util_ui.tr('Ignore peer')) self.roleLabel.setText(util_ui.tr('Role:')) self.copyPublicKeyPushButton.setText(util_ui.tr('Copy public key')) self.sendPrivateMessagePushButton.setText(util_ui.tr('Send private message')) + self.banGroupBox.setTitle(util_ui.tr('Moderation')) + + self.rolesComboBox.clear() + index = self._group.get_self_peer().role + roles = list(self._roles.values()) + for role in roles[index + 1:]: + self.rolesComboBox.addItem(role) + self.rolesComboBox.setCurrentIndex(self._peer.role - index - 1) + + def _can_change_role(self): + self_peer = self._group.get_self_peer() + if self_peer.role > TOX_GROUP_ROLE['MODERATOR']: + return False + + return self_peer.role < self._peer.role + + def _role_set(self): + index = self.rolesComboBox.currentIndex() + all_roles_count = len(self._roles) + diff = all_roles_count - self.rolesComboBox.count() + self._groups_service.set_new_peer_role(self._group, self._peer, index + diff) def _get_role_name(self): - roles = { - 0: util_ui.tr('Administrator'), - 1: util_ui.tr('Moderator'), - 2: util_ui.tr('User'), - 3: util_ui.tr('Observer') - } + return self._roles[self._peer.role] - return roles[self._peer.role] + def _toggle_ignore(self): + ignore = self.ignorePeerCheckBox.isChecked() + self._groups_service.toggle_ignore_peer(self._group, self._peer, ignore) def _send_private_message(self): self._contacts_manager.add_group_peer(self._group, self._peer) diff --git a/toxygen/ui/views/peer_screen.ui b/toxygen/ui/views/peer_screen.ui index f719ec6..f6b13b3 100644 --- a/toxygen/ui/views/peer_screen.ui +++ b/toxygen/ui/views/peer_screen.ui @@ -93,9 +93,9 @@ - 140 + 130 60 - 401 + 411 20 @@ -116,6 +116,16 @@ PushButton + + + + 130 + 55 + 291 + 30 + + +