group moderation screen and all callbacks

This commit is contained in:
ingvar1995 2018-08-05 12:34:11 +03:00
parent 8f9b573253
commit 33052f8a98
8 changed files with 509 additions and 8 deletions

View file

@ -181,9 +181,12 @@ class GroupMenuGenerator(BaseContactMenuGenerator):
menu = (builder
.with_action(util_ui.tr('Set alias'), lambda: main_screen.set_alias(number))
.with_submenu(copy_menu_builder)
.with_optional_action(util_ui.tr('Manage group'),
lambda: groups_service.show_group_management_screen(self._contact),
self._contact.is_self_founder())
.with_optional_action(util_ui.tr('Set topic'),
lambda: groups_service.set_group_topic(self._contact),
self._contact.is_moderator_or_founder())
self._contact.is_self_moderator_or_founder())
.with_action(util_ui.tr('Reconnect to group'),
lambda: groups_service.reconnect_to_group(self._contact.number))
.with_optional_action(util_ui.tr('Disconnect from group'),

View file

@ -12,6 +12,8 @@ class GroupChat(contact.Contact, ToxSave):
super().__init__(profile_manager, message_getter, number, name, status_message, widget, tox_id)
ToxSave.__init__(self, tox)
self._is_private = is_private
self._password = None
self._peers_limit = 512
self._peers = []
self._add_self_to_gc()
@ -32,7 +34,26 @@ class GroupChat(contact.Contact, ToxSave):
def get_is_private(self):
return self._is_private
is_private = property(get_is_private)
def set_is_private(self, is_private):
self._is_private = is_private
is_private = property(get_is_private, set_is_private)
def get_password(self):
return self._password
def set_password(self, password):
self._password = password
password = property(get_password, set_password)
def get_peers_limit(self):
return self._peers_limit
def set_peers_limit(self, peers_limit):
self._peers_limit = peers_limit
peers_limit = property(get_peers_limit, set_peers_limit)
# -----------------------------------------------------------------------------------------------------------------
# Peers methods
@ -47,9 +68,12 @@ class GroupChat(contact.Contact, ToxSave):
def get_self_role(self):
return self._peers[0].role
def is_moderator_or_founder(self):
def is_self_moderator_or_founder(self):
return self.get_self_role() <= constants.TOX_GROUP_ROLE['MODERATOR']
def is_self_founder(self):
return self.get_self_role() == constants.TOX_GROUP_ROLE['FOUNDER']
def add_peer(self, peer_id, is_current_user=False):
peer = GroupChatPeer(peer_id,
self._tox.group_peer_get_name(self._number, peer_id),

View file

@ -15,7 +15,7 @@ class GroupsService(tox_save.ToxSave):
self._peers_list_widget = main_screen.peers_list
self._widgets_factory_provider = widgets_factory_provider
self._group_invites = []
self._peer_screen = None
self._peer_screen = self._management_screen = None
def set_tox(self, tox):
super().set_tox(tox)
@ -70,14 +70,14 @@ class GroupsService(tox_save.ToxSave):
friend = self._get_friend_by_number(friend_number)
invite = GroupInvite(friend.tox_id, group_name, invite_data)
self._group_invites.append(invite)
self._main_screen.update_gc_invites_button_state()
self._update_invites_button_state()
def accept_group_invite(self, invite, name, status, password):
pk = invite.friend_public_key
friend = self._get_friend_by_public_key(pk)
self._join_gc_via_invite(invite.invite_data, friend.number, name, status, password)
self._delete_group_invite(invite)
self._main_screen.update_gc_invites_button_state()
self._update_invites_button_state()
def decline_group_invite(self, invite):
self._delete_group_invite(invite)
@ -102,7 +102,7 @@ class GroupsService(tox_save.ToxSave):
group.status_message = self._tox.group_get_topic(group.number)
def set_group_topic(self, group):
if not group.is_moderator_or_founder():
if not group.is_self_moderator_or_founder():
return
text = util_ui.tr('New topic for group "{}":'.format(group.name))
title = util_ui.tr('Set group topic')
@ -112,6 +112,30 @@ class GroupsService(tox_save.ToxSave):
self._tox.group_set_topic(group.number, topic)
group.status_message = topic
def show_group_management_screen(self, group):
widgets_factory = self._get_widgets_factory()
self._management_screen = widgets_factory.create_group_management_screen(group)
self._management_screen.show()
def set_group_password(self, group, password):
if group.password == password:
return
self._tox.group_founder_set_password(group.number, password)
group.password = password
def set_group_peers_limit(self, group, peers_limit):
if group.peers_limit == peers_limit:
return
self._tox.group_founder_set_peer_limit(group.number, peers_limit)
group.peers_limit = peers_limit
def set_group_privacy_state(self, group, privacy_state):
is_private = privacy_state == constants.TOX_GROUP_PRIVACY_STATE['PRIVATE']
if group.is_private == is_private:
return
self._tox.group_founder_set_privacy_state(group.number, privacy_state)
group.is_private = is_private
# -----------------------------------------------------------------------------------------------------------------
# Peers list
# -----------------------------------------------------------------------------------------------------------------
@ -123,7 +147,7 @@ class GroupsService(tox_save.ToxSave):
PeersListGenerator().generate(group.peers, self, self._peers_list_widget, group.tox_id)
def peer_selected(self, chat_id, peer_id):
widgets_factory = self._widgets_factory_provider.get_item()
widgets_factory = self._get_widgets_factory()
group = self._get_group_by_public_key(chat_id)
self_peer = group.get_self_peer()
if self_peer.id != peer_id:
@ -186,3 +210,9 @@ class GroupsService(tox_save.ToxSave):
def _join_gc_via_invite(self, invite_data, friend_number, nick, status, password):
group_number = self._tox.group_invite_accept(invite_data, friend_number, nick, status, password)
self._add_new_group_by_number(group_number)
def _update_invites_button_state(self):
self._main_screen.update_gc_invites_button_state()
def _get_widgets_factory(self):
return self._widgets_factory_provider.get_item()

View file

@ -506,6 +506,34 @@ def group_moderation(groups_service, contacts_provider, contacts_manager, messen
return wrapped
def group_password(contacts_provider):
def wrapped(tox_link, group_number, password, length, user_data):
password = str(password[:length], 'utf-8')
group = contacts_provider.get_group_by_number(group_number)
group.password = password
return wrapped
def group_peer_limit(contacts_provider):
def wrapped(tox_link, group_number, peer_limit, user_data):
group = contacts_provider.get_group_by_number(group_number)
group.peer_limit = peer_limit
return wrapped
def group_privacy_state(contacts_provider):
def wrapped(tox_link, group_number, privacy_state, user_data):
group = contacts_provider.get_group_by_number(group_number)
group.is_private = privacy_state == TOX_GROUP_PRIVACY_STATE['PRIVATE']
return wrapped
# -----------------------------------------------------------------------------------------------------------------
# Callbacks - initialization
# -----------------------------------------------------------------------------------------------------------------
@ -573,3 +601,6 @@ def init_callbacks(tox, profile, settings, plugin_loader, contacts_manager,
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)
tox.callback_group_password(group_password(contacts_provider), 0)
tox.callback_group_peer_limit(group_peer_limit(contacts_provider), 0)
tox.callback_group_privacy_state(group_privacy_state(contacts_provider), 0)

View file

@ -0,0 +1,46 @@
from ui.widgets import CenteredWidget
from PyQt5 import uic
import utils.util as util
import utils.ui as util_ui
class GroupManagementScreen(CenteredWidget):
def __init__(self, groups_service, group):
super().__init__()
self._groups_service = groups_service
self._group = group
uic.loadUi(util.get_views_path('group_management_screen'), self)
self._update_ui()
def _update_ui(self):
self._retranslate_ui()
self.passwordLineEdit.setText(self._group.password)
self.privacyStateComboBox.setCurrentIndex(1 if self._group.is_private else 0)
self.peersLimitSpinBox.setValue(self._group.peers_limit)
self.savePushButton.clicked.connect(self._save)
def _retranslate_ui(self):
self.setWindowTitle(util_ui.tr('Group "{}"').format(self._group.name))
self.passwordLabel.setText(util_ui.tr('Password'))
self.peerLimitLabel.setText(util_ui.tr('Peer limit:'))
self.privacyStateLabel.setText(util_ui.tr('Privacy state'))
self.savePushButton.setText(util_ui.tr('Save'))
self.privacyStateComboBox.clear()
self.privacyStateComboBox.addItem(util_ui.tr('Public'))
self.privacyStateComboBox.addItem(util_ui.tr('Private'))
def _save(self):
password = self.passwordLineEdit.text()
privacy_state = self.privacyStateComboBox.currentIndex()
peers_limit = self.peersLimitSpinBox.value()
self._groups_service.set_group_password(self._group, password)
self._groups_service.set_group_privacy_state(self._group, privacy_state)
self._groups_service.set_group_peers_limit(self._group, peers_limit)
self.close()

View file

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>658</width>
<height>238</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QLineEdit" name="passwordLineEdit">
<property name="geometry">
<rect>
<x>180</x>
<y>20</y>
<width>450</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="passwordLabel">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>145</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="peerLimitLabel">
<property name="geometry">
<rect>
<x>20</x>
<y>80</y>
<width>145</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QSpinBox" name="peersLimitSpinBox">
<property name="geometry">
<rect>
<x>180</x>
<y>70</y>
<width>450</width>
<height>40</height>
</rect>
</property>
<property name="minimum">
<number>2</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="value">
<number>512</number>
</property>
</widget>
<widget class="QLabel" name="privacyStateLabel">
<property name="geometry">
<rect>
<x>20</x>
<y>130</y>
<width>145</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QComboBox" name="privacyStateComboBox">
<property name="geometry">
<rect>
<x>180</x>
<y>120</y>
<width>450</width>
<height>40</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="savePushButton">
<property name="geometry">
<rect>
<x>20</x>
<y>180</y>
<width>611</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -0,0 +1,253 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>552</width>
<height>847</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>532</width>
<height>827</height>
</rect>
</property>
<widget class="QLabel" name="themeLabel">
<property name="geometry">
<rect>
<x>30</x>
<y>140</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QComboBox" name="themeComboBox">
<property name="geometry">
<rect>
<x>20</x>
<y>180</y>
<width>471</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="languageComboBox">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>471</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="languageLabel">
<property name="geometry">
<rect>
<x>30</x>
<y>20</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QCheckBox" name="mirrorModeCheckBox">
<property name="geometry">
<rect>
<x>30</x>
<y>220</y>
<width>461</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>CheckBox</string>
</property>
</widget>
<widget class="QGroupBox" name="smileysGroupBox">
<property name="geometry">
<rect>
<x>30</x>
<y>280</y>
<width>461</width>
<height>221</height>
</rect>
</property>
<property name="title">
<string>GroupBox</string>
</property>
<widget class="QCheckBox" name="smileysCheckBox">
<property name="geometry">
<rect>
<x>30</x>
<y>40</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>CheckBox</string>
</property>
</widget>
<widget class="QLabel" name="smileysPackLabel">
<property name="geometry">
<rect>
<x>30</x>
<y>80</y>
<width>411</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QComboBox" name="smileysPackComboBox">
<property name="geometry">
<rect>
<x>30</x>
<y>120</y>
<width>411</width>
<height>31</height>
</rect>
</property>
</widget>
</widget>
<widget class="QCheckBox" name="compactModeCheckBox">
<property name="geometry">
<rect>
<x>30</x>
<y>250</y>
<width>461</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>CheckBox</string>
</property>
</widget>
<widget class="QPushButton" name="importStickersPushButton">
<property name="geometry">
<rect>
<x>30</x>
<y>750</y>
<width>471</width>
<height>40</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
<widget class="QPushButton" name="importSmileysPushButton">
<property name="geometry">
<rect>
<x>30</x>
<y>690</y>
<width>471</width>
<height>40</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
<widget class="QCheckBox" name="showAvatarsCheckBox">
<property name="geometry">
<rect>
<x>30</x>
<y>520</y>
<width>461</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>CheckBox</string>
</property>
</widget>
<widget class="QGroupBox" name="appClosingGroupBox">
<property name="geometry">
<rect>
<x>30</x>
<y>550</y>
<width>471</width>
<height>131</height>
</rect>
</property>
<property name="title">
<string>GroupBox</string>
</property>
<widget class="QRadioButton" name="closeRadioButton">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>421</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>RadioButton</string>
</property>
</widget>
<widget class="QRadioButton" name="hideRadioButton">
<property name="geometry">
<rect>
<x>30</x>
<y>60</y>
<width>431</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>RadioButton</string>
</property>
</widget>
<widget class="QRadioButton" name="closeToTrayRadioButton">
<property name="geometry">
<rect>
<x>30</x>
<y>90</y>
<width>421</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>RadioButton</string>
</property>
</widget>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -4,6 +4,7 @@ from ui.groups_widgets import *
from ui.peer_screen import *
from ui.self_peer_screen import *
from ui.group_invites_widgets import *
from ui.group_management_screen import *
class WidgetsFactory:
@ -82,3 +83,6 @@ class WidgetsFactory:
def create_group_invites_window(self):
return GroupInvitesScreen(self._groups_service, self._profile, self._contacts_provider)
def create_group_management_screen(self, group):
return GroupManagementScreen(self._groups_service, group)