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
+
+
+