From 5521b768bc5fe0cc46579f042f6e1ff7127a1108 Mon Sep 17 00:00:00 2001 From: ingvar1995 Date: Sun, 22 Jul 2018 12:59:52 +0300 Subject: [PATCH] private messages support --- toxygen/app.py | 14 ++- toxygen/common/provider.py | 13 +++ toxygen/contacts/contact_provider.py | 27 ++++- toxygen/contacts/contacts_manager.py | 22 ++++ toxygen/contacts/group_chat.py | 7 +- toxygen/contacts/group_peer_contact.py | 10 +- toxygen/contacts/group_peer_factory.py | 23 ++++ toxygen/groups/group_peer.py | 8 +- toxygen/groups/groups_service.py | 32 ++++-- toxygen/messenger/messenger.py | 142 ++++++++++++++++++------- toxygen/middleware/callbacks.py | 21 ++++ toxygen/ui/contact_items.py | 5 +- toxygen/ui/peer_screen.py | 36 +++++++ toxygen/ui/views/peer_screen.ui | 83 +++++++++++++++ toxygen/ui/widgets_factory.py | 4 + toxygen/wrapper/tox.py | 2 +- 16 files changed, 384 insertions(+), 65 deletions(-) create mode 100644 toxygen/common/provider.py create mode 100644 toxygen/contacts/group_peer_factory.py create mode 100644 toxygen/ui/peer_screen.py create mode 100644 toxygen/ui/views/peer_screen.ui diff --git a/toxygen/app.py b/toxygen/app.py index ec0a1cb..b270f10 100644 --- a/toxygen/app.py +++ b/toxygen/app.py @@ -32,6 +32,8 @@ from history.history import History from file_transfers.file_transfers_messages_service import FileTransfersMessagesService from groups.groups_service import GroupsService from ui.create_profile_screen import CreateProfileScreen +from common.provider import Provider +from contacts.group_peer_factory import GroupPeerFactory import styles.style # TODO: dynamic loading @@ -42,7 +44,8 @@ class App: self._app = self._settings = self._profile_manager = self._plugin_loader = self._messenger = None self._tox = self._ms = self._init = self._main_loop = self._av_loop = None self._uri = self._toxes = self._tray = self._file_transfer_handler = self._contacts_provider = None - self._friend_factory = self._calls_manager = self._contacts_manager = self._smiley_loader = self._tox_dns = None + self._friend_factory = self._calls_manager = self._contacts_manager = self._smiley_loader = None + self._group_peer_factory = self._tox_dns = None self._group_factory = self._groups_service = self._profile = None if uri is not None and uri.startswith('tox:'): self._uri = uri[4:] @@ -336,7 +339,9 @@ class App: self._friend_factory = FriendFactory(self._profile_manager, self._settings, self._tox, db, contact_items_factory) self._group_factory = GroupFactory(self._profile_manager, self._settings, self._tox, db, contact_items_factory) - self._contacts_provider = ContactProvider(self._tox, self._friend_factory, self._group_factory) + self._group_peer_factory = GroupPeerFactory(self._tox, self._profile_manager, db, contact_items_factory) + self._contacts_provider = ContactProvider(self._tox, self._friend_factory, self._group_factory, + self._group_peer_factory) self._profile = Profile(self._profile_manager, self._tox, self._ms, self._contacts_provider, self._reset) self._init_profile() self._plugin_loader = PluginLoader(self._settings, self) @@ -357,7 +362,10 @@ class App: self._file_transfer_handler = FileTransfersHandler(self._tox, self._settings, self._contacts_provider, file_transfers_message_service, self._profile) messages_items_factory.set_file_transfers_handler(self._file_transfer_handler) - self._groups_service = GroupsService(self._tox, self._contacts_manager, self._contacts_provider, self._ms) + widgets_factory = None + widgets_factory_provider = Provider(lambda: widgets_factory) + self._groups_service = GroupsService(self._tox, self._contacts_manager, self._contacts_provider, self._ms, + widgets_factory_provider) widgets_factory = WidgetsFactory(self._settings, self._profile, self._profile_manager, self._contacts_manager, self._file_transfer_handler, self._smiley_loader, self._plugin_loader, self._toxes, self._version, self._groups_service, history) diff --git a/toxygen/common/provider.py b/toxygen/common/provider.py new file mode 100644 index 0000000..d16edb4 --- /dev/null +++ b/toxygen/common/provider.py @@ -0,0 +1,13 @@ + + +class Provider: + + def __init__(self, get_item_action): + self._get_item_action = get_item_action + self._item = None + + def get_item(self): + if self._item is None: + self._item = self._get_item_action() + + return self._item diff --git a/toxygen/contacts/contact_provider.py b/toxygen/contacts/contact_provider.py index 6f13596..76e8e79 100644 --- a/toxygen/contacts/contact_provider.py +++ b/toxygen/contacts/contact_provider.py @@ -3,10 +3,11 @@ import common.tox_save as tox_save class ContactProvider(tox_save.ToxSave): - def __init__(self, tox, friend_factory, group_factory): + def __init__(self, tox, friend_factory, group_factory, group_peer_factory): super().__init__(tox) self._friend_factory = friend_factory self._group_factory = group_factory + self._group_peer_factory = group_peer_factory self._cache = {} # key - contact's public key, value - contact instance # ----------------------------------------------------------------------------------------------------------------- @@ -34,7 +35,7 @@ class ContactProvider(tox_save.ToxSave): return list(friends) # ----------------------------------------------------------------------------------------------------------------- - # GC + # Groups # ----------------------------------------------------------------------------------------------------------------- def get_all_groups(self): @@ -57,12 +58,29 @@ class ContactProvider(tox_save.ToxSave): return group + # ----------------------------------------------------------------------------------------------------------------- + # Group peers + # ----------------------------------------------------------------------------------------------------------------- + + def get_all_group_peers(self): + return list() + + def get_group_peer_by_id(self, group, peer_id): + peer = group.get_peer_by_id(peer_id) + + return self._get_group_peer(group, peer) + + def get_group_peer_by_public_key(self, group, public_key): + peer = group.get_peer_by_public_key(public_key) + + return self._get_group_peer(group, peer) + # ----------------------------------------------------------------------------------------------------------------- # All contacts # ----------------------------------------------------------------------------------------------------------------- def get_all(self): - return self.get_all_friends() + self.get_all_groups() + return self.get_all_friends() + self.get_all_groups() + self.get_all_group_peers() # ----------------------------------------------------------------------------------------------------------------- # Caching @@ -84,3 +102,6 @@ class ContactProvider(tox_save.ToxSave): def _add_to_cache(self, public_key, contact): self._cache[public_key] = contact + + def _get_group_peer(self, group, peer): + return self._group_peer_factory.create_group_peer(group, peer) diff --git a/toxygen/contacts/contacts_manager.py b/toxygen/contacts/contacts_manager.py index 2729959..6135967 100644 --- a/toxygen/contacts/contacts_manager.py +++ b/toxygen/contacts/contacts_manager.py @@ -2,6 +2,7 @@ from contacts.friend import Friend from contacts.group_chat import GroupChat from messenger.messages import * from common.tox_save import ToxSave +from contacts.group_peer_contact import GroupPeerContact class ContactsManager(ToxSave): @@ -223,6 +224,17 @@ class ContactsManager(ToxSave): def get_group_by_number(self, number): return list(filter(lambda c: c.number == number and type(c) is GroupChat, self._contacts))[0] + def get_or_create_group_peer_contact(self, group_number, peer_id): + group = self.get_group_by_number(group_number) + peer = group.get_peer_by_id(peer_id) + if not self.check_if_contact_exists(peer.public_key): + self.add_group_peer(group, peer) + + return self.get_contact_by_tox_id(peer.public_key) + + def check_if_contact_exists(self, tox_id): + return any(filter(lambda c: c.tox_id == tox_id, self._contacts)) + def get_contact_by_tox_id(self, tox_id): return list(filter(lambda c: c.tox_id == tox_id, self._contacts))[0] @@ -340,6 +352,16 @@ class ContactsManager(ToxSave): num = self._contacts.index(group) self._delete_contact(num) + # ----------------------------------------------------------------------------------------------------------------- + # Groups private messaging + # ----------------------------------------------------------------------------------------------------------------- + + def add_group_peer(self, group, peer): + contact = self._contact_provider.get_group_peer_by_id(group, peer.id) + self._contacts.append(contact) + contact.reset_avatar(self._settings['identicons']) + self._save_profile() + # ----------------------------------------------------------------------------------------------------------------- # Friend requests # ----------------------------------------------------------------------------------------------------------------- diff --git a/toxygen/contacts/group_chat.py b/toxygen/contacts/group_chat.py index fac2165..61b3858 100644 --- a/toxygen/contacts/group_chat.py +++ b/toxygen/contacts/group_chat.py @@ -11,8 +11,6 @@ class GroupChat(contact.Contact, ToxSave): def __init__(self, tox, profile_manager, message_getter, number, name, status_message, widget, tox_id): super().__init__(profile_manager, message_getter, number, name, status_message, widget, tox_id) ToxSave.__init__(self, tox) - status = self._tox.group_is_connected(number) - self.set_status(constants.TOX_USER_STATUS['NONE'] if status else None) self._peers = [] self._add_self_to_gc() @@ -57,6 +55,11 @@ class GroupChat(contact.Contact, ToxSave): return peers[0] + def get_peer_by_public_key(self, public_key): + peers = list(filter(lambda p: p.public_key == public_key, self._peers)) + + return peers[0] + def remove_all_peers_except_self(self): self._peers = self._peers[:1] diff --git a/toxygen/contacts/group_peer_contact.py b/toxygen/contacts/group_peer_contact.py index 1c51f67..47cd16b 100644 --- a/toxygen/contacts/group_peer_contact.py +++ b/toxygen/contacts/group_peer_contact.py @@ -3,11 +3,17 @@ import contacts.contact class GroupPeerContact(contacts.contact.Contact): - def __init__(self, profile_manager, message_getter, peer_number, name, status_messsage, widget, tox_id, group_pk): - super().__init__(profile_manager, message_getter, peer_number, name, status_messsage, widget, tox_id) + def __init__(self, profile_manager, message_getter, peer_number, name, widget, tox_id, group_pk): + super().__init__(profile_manager, message_getter, peer_number, name, str(), widget, tox_id) self._group_pk = group_pk def get_group_pk(self): return self._group_pk group_pk = property(get_group_pk) + + def remove_invalid_unsent_files(self): + pass + + def get_context_menu_generator(self): + return None diff --git a/toxygen/contacts/group_peer_factory.py b/toxygen/contacts/group_peer_factory.py new file mode 100644 index 0000000..38b3a20 --- /dev/null +++ b/toxygen/contacts/group_peer_factory.py @@ -0,0 +1,23 @@ +from common.tox_save import ToxSave +from contacts.group_peer_contact import GroupPeerContact + + +class GroupPeerFactory(ToxSave): + + def __init__(self, tox, profile_manager, db, items_factory): + super().__init__(tox) + self._profile_manager = profile_manager + self._db = db + self._items_factory = items_factory + + def create_group_peer(self, group, peer): + item = self._create_group_peer_item() + message_getter = self._db.messages_getter(peer.public_key) + group_peer_contact = GroupPeerContact(self._profile_manager, message_getter, peer.id, peer.name, + item, peer.public_key, group.tox_id) + group_peer_contact.status = peer.status + + return group_peer_contact + + def _create_group_peer_item(self): + return self._items_factory.create_contact_item() diff --git a/toxygen/groups/group_peer.py b/toxygen/groups/group_peer.py index d2d5aeb..57724a5 100644 --- a/toxygen/groups/group_peer.py +++ b/toxygen/groups/group_peer.py @@ -2,13 +2,14 @@ class GroupChatPeer: - def __init__(self, peer_id, name, status, role, public_key, is_current_user): + def __init__(self, peer_id, name, status, role, public_key, is_current_user=False, is_muted=False): self._peer_id = peer_id self._name = name self._status = status self._role = role self._public_key = public_key self._is_current_user = is_current_user + self._is_muted = is_muted def get_id(self): return self._peer_id @@ -48,3 +49,8 @@ class GroupChatPeer: return self._is_current_user is_current_user = property(get_is_current_user) + + def get_is_muted(self): + return self._is_muted + + is_muted = property(get_is_muted) diff --git a/toxygen/groups/groups_service.py b/toxygen/groups/groups_service.py index 1a8ccc0..49d5f25 100644 --- a/toxygen/groups/groups_service.py +++ b/toxygen/groups/groups_service.py @@ -6,11 +6,13 @@ import wrapper.toxcore_enums_and_consts as constants class GroupsService(tox_save.ToxSave): - def __init__(self, tox, contacts_manager, contacts_provider, main_screen): + def __init__(self, tox, contacts_manager, contacts_provider, main_screen, widgets_factory_provider): super().__init__(tox) self._contacts_manager = contacts_manager self._contacts_provider = contacts_provider self._peers_list_widget = main_screen.peers_list + self._widgets_factory_provider = widgets_factory_provider + self._peer_screen = None def set_tox(self, tox): super().set_tox(tox) @@ -23,8 +25,12 @@ class GroupsService(tox_save.ToxSave): def create_new_gc(self, name, privacy_state): group_number = self._tox.group_new(privacy_state, name.encode('utf-8')) - if group_number != -1: - self._add_new_group_by_number(group_number) + if group_number == -1: + return + + self._add_new_group_by_number(group_number) + group = self._get_group_by_number(group_number) + group.status = constants.TOX_USER_STATUS['NONE'] def join_gc_by_id(self, chat_id, password): group_number = self._tox.group_join(chat_id, password) @@ -45,13 +51,13 @@ class GroupsService(tox_save.ToxSave): def disconnect_from_group(self, group_number): self._tox.group_disconnect(group_number) - group = self._get_group(group_number) + group = self._get_group_by_number(group_number) group.status = None self._clear_peers_list(group) def reconnect_to_group(self, group_number): self._tox.group_reconnect(group_number) - group = self._get_group(group_number) + group = self._get_group_by_number(group_number) group.status = constants.TOX_USER_STATUS['NONE'] self._clear_peers_list(group) @@ -63,7 +69,7 @@ class GroupsService(tox_save.ToxSave): self._tox.group_invite_friend(group_number, friend_number) def process_group_invite(self, friend_number, group_name, invite_data): - friend = self._get_friend(friend_number) + friend = self._get_friend_by_number(friend_number) text = util_ui.tr('Friend {} invites you to group "{}". Accept?') if util_ui.question(text.format(friend.name, group_name), util_ui.tr('Group invite')): self.join_gc_via_invite(invite_data, friend_number, None) @@ -98,7 +104,10 @@ 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): - pass + widgets_factory = self._widgets_factory_provider.get_item() + group = self._get_group_by_public_key(chat_id) + self._peer_screen = widgets_factory.create_peer_screen_window(group, peer_id) + self._peer_screen.show() # ----------------------------------------------------------------------------------------------------------------- # Private methods @@ -107,15 +116,18 @@ class GroupsService(tox_save.ToxSave): def _add_new_group_by_number(self, group_number): self._contacts_manager.add_group(group_number) - def _get_group(self, group_number): + def _get_group_by_number(self, group_number): return self._contacts_provider.get_group_by_number(group_number) - def _get_friend(self, friend_number): - return self._contacts_provider.get_friend_by_number(friend_number) + def _get_group_by_public_key(self, public_key): + return self._contacts_provider.get_group_by_public_key(public_key) def _get_all_groups(self): return self._contacts_provider.get_all_groups() + def _get_friend_by_number(self, friend_number): + return self._contacts_provider.get_friend_by_number(friend_number) + def _clear_peers_list(self, group): group.remove_all_peers_except_self() self.generate_peers_list() diff --git a/toxygen/messenger/messenger.py b/toxygen/messenger/messenger.py index dbd2d1e..0768f2b 100644 --- a/toxygen/messenger/messenger.py +++ b/toxygen/messenger/messenger.py @@ -46,8 +46,10 @@ class Messenger(tox_save.ToxSave): text = self._screen.messageEdit.toPlainText() if self._contacts_manager.is_active_a_friend(): self.send_message_to_friend(text) - else: + elif self._contacts_manager.is_active_a_group(): self.send_message_to_group(text) + else: + self.send_message_to_group_peer(text) def send_message_to_friend(self, text, friend_number=None): """ @@ -57,30 +59,36 @@ class Messenger(tox_save.ToxSave): """ if friend_number is None: friend_number = self._contacts_manager.get_active_number() + if text.startswith('/plugin '): self._plugin_loader.command(text[8:]) self._screen.messageEdit.clear() - elif text and friend_number >= 0: - if text.startswith('/me '): - message_type = TOX_MESSAGE_TYPE['ACTION'] - text = text[4:] + return + + if not text or friend_number < 0: + return + + if text.startswith('/me '): + message_type = TOX_MESSAGE_TYPE['ACTION'] + text = text[4:] + else: + message_type = TOX_MESSAGE_TYPE['NORMAL'] + friend = self._get_friend_by_number(friend_number) + messages = self._split_message(text.encode('utf-8')) + t = util.get_unix_time() + for message in messages: + if friend.status is not None: + message_id = self._tox.friend_send_message(friend_number, message_type, message) else: - message_type = TOX_MESSAGE_TYPE['NORMAL'] - friend = self._get_friend_by_number(friend_number) - messages = self._split_message(text.encode('utf-8')) - t = util.get_unix_time() - for message in messages: - if friend.status is not None: - message_id = self._tox.friend_send_message(friend_number, message_type, message) - else: - message_id = 0 - message_author = MessageAuthor(self._profile.name, MESSAGE_AUTHOR['NOT_SENT']) - message = OutgoingTextMessage(text, message_author, t, message_type, message_id) - friend.append_message(message) - if self._contacts_manager.is_friend_active(friend_number): - self._create_message_item(message) - self._screen.messageEdit.clear() - self._screen.messages.scrollToBottom() + message_id = 0 + message_author = MessageAuthor(self._profile.name, MESSAGE_AUTHOR['NOT_SENT']) + message = OutgoingTextMessage(text, message_author, t, message_type, message_id) + friend.append_message(message) + if not self._contacts_manager.is_friend_active(friend_number): + return + self._create_message_item(message) + self._screen.messageEdit.clear() + self._screen.messages.scrollToBottom() def send_messages(self, friend_number): """ @@ -103,27 +111,33 @@ class Messenger(tox_save.ToxSave): def send_message_to_group(self, text, group_number=None): if group_number is None: group_number = self._contacts_manager.get_active_number() + if text.startswith('/plugin '): self._plugin_loader.command(text[8:]) self._screen.messageEdit.clear() - elif text and group_number >= 0: - if text.startswith('/me '): - message_type = TOX_MESSAGE_TYPE['ACTION'] - text = text[4:] - else: - message_type = TOX_MESSAGE_TYPE['NORMAL'] - group = self._get_group_by_number(group_number) - messages = self._split_message(text.encode('utf-8')) - t = util.get_unix_time() - for message in messages: - self._tox.group_send_message(group_number, message_type, message) - message_author = MessageAuthor(group.get_self_name(), MESSAGE_AUTHOR['GC_PEER']) - message = OutgoingTextMessage(text, message_author, t, message_type) - group.append_message(message) - if self._contacts_manager.is_group_active(group_number): - self._create_message_item(message) - self._screen.messageEdit.clear() - self._screen.messages.scrollToBottom() + return + + if not text or group_number < 0: + return + + if text.startswith('/me '): + message_type = TOX_MESSAGE_TYPE['ACTION'] + text = text[4:] + else: + message_type = TOX_MESSAGE_TYPE['NORMAL'] + group = self._get_group_by_number(group_number) + messages = self._split_message(text.encode('utf-8')) + t = util.get_unix_time() + for message in messages: + self._tox.group_send_message(group_number, message_type, message) + message_author = MessageAuthor(group.get_self_name(), MESSAGE_AUTHOR['GC_PEER']) + message = OutgoingTextMessage(text, message_author, t, message_type) + group.append_message(message) + if not self._contacts_manager.is_group_active(group_number): + return + self._create_message_item(message) + self._screen.messageEdit.clear() + self._screen.messages.scrollToBottom() def new_group_message(self, group_number, message_type, message, peer_id): """ @@ -137,6 +151,53 @@ class Messenger(tox_save.ToxSave): text_message = TextMessage(message, MessageAuthor(peer.name, MESSAGE_AUTHOR['GC_PEER']), t, message_type) self._add_message(text_message, group) + # ----------------------------------------------------------------------------------------------------------------- + # Messaging - group peers + # ----------------------------------------------------------------------------------------------------------------- + + def send_message_to_group_peer(self, text, group_number=None, peer_id=None): + if group_number is None or peer_id is None: + group_peer_contact = self._contacts_manager.get_curr_contact() + peer_id = group_peer_contact.number + group = self._get_group_by_public_key(group_peer_contact.group_pk) + group_number = group.number + + if text.startswith('/plugin '): + self._plugin_loader.command(text[8:]) + self._screen.messageEdit.clear() + return + + if not text or group_number < 0 or peer_id < 0: + return + + group_peer_contact = self._contacts_manager.get_or_create_group_peer_contact(group_number, peer_id) + group = self._get_group_by_number(group_number) + messages = self._split_message(text.encode('utf-8')) + t = util.get_unix_time() + for message in messages: + self._tox.group_send_private_message(group_number, peer_id, message) + message_author = MessageAuthor(group.get_self_name(), MESSAGE_AUTHOR['GC_PEER']) + message = OutgoingTextMessage(text, message_author, t, MESSAGE_TYPE['TEXT']) + group_peer_contact.append_message(message) + if not self._contacts_manager.is_contact_active(group_peer_contact): + return + self._create_message_item(message) + self._screen.messageEdit.clear() + self._screen.messages.scrollToBottom() + + def new_group_private_message(self, group_number, message, peer_id): + """ + Current user gets new message + :param message: text of message + """ + t = util.get_unix_time() + group = self._get_group_by_number(group_number) + peer = group.get_peer_by_id(peer_id) + text_message = TextMessage(message, MessageAuthor(peer.name, MESSAGE_AUTHOR['GC_PEER']), + t, MESSAGE_TYPE['TEXT']) + group_peer_contact = self._contacts_manager.get_or_create_group_peer_contact(group_number, peer_id) + self._add_message(text_message, group_peer_contact) + # ----------------------------------------------------------------------------------------------------------------- # Message receipts # ----------------------------------------------------------------------------------------------------------------- @@ -211,6 +272,9 @@ class Messenger(tox_save.ToxSave): def _get_group_by_number(self, group_number): return self._contacts_provider.get_group_by_number(group_number) + def _get_group_by_public_key(self, public_key): + return self._contacts_provider.get_group_by_public_key( public_key) + def _on_profile_name_changed(self, new_name): if self._profile_name == new_name: return diff --git a/toxygen/middleware/callbacks.py b/toxygen/middleware/callbacks.py index 8730b54..323d5d1 100644 --- a/toxygen/middleware/callbacks.py +++ b/toxygen/middleware/callbacks.py @@ -375,6 +375,26 @@ def group_message(window, tray, tox, messenger, settings, profile): return wrapped +def group_private_message(window, tray, tox, messenger, settings, profile): + """ + New private message in group chat + """ + def wrapped(tox_link, group_number, peer_id, message, length, user_data): + message = str(message[:length], 'utf-8') + invoke_in_main_thread(messenger.new_group_private_message, group_number, message, peer_id) + if not window.isActiveWindow(): + bl = settings['notify_all_gc'] or profile.name in message + name = tox.group_peer_get_name(group_number, peer_id) + if settings['notifications'] and profile.status != TOX_USER_STATUS['BUSY'] and (not settings.locked) and bl: + invoke_in_main_thread(tray_notification, name, message, tray, window) + if settings['sound_notifications'] and bl and profile.status != TOX_USER_STATUS['BUSY']: + sound_notification(SOUND_NOTIFICATION['MESSAGE']) + icon = os.path.join(util.get_images_directory(), 'icon_new_messages.png') + invoke_in_main_thread(tray.setIcon, QtGui.QIcon(icon)) + + return wrapped + + def group_invite(groups_service): def wrapped(tox, friend_number, invite_data, length, group_name, group_name_length, user_data): group_name = bytes(group_name[:group_name_length]) @@ -499,6 +519,7 @@ def init_callbacks(tox, profile, settings, plugin_loader, contacts_manager, # gc callbacks tox.callback_group_message(group_message(main_window, tray, tox, messenger, settings, profile), 0) + tox.callback_group_private_message(group_private_message(main_window, tray, tox, messenger, settings, profile), 0) 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) diff --git a/toxygen/ui/contact_items.py b/toxygen/ui/contact_items.py index 2ad3ad2..7a32284 100644 --- a/toxygen/ui/contact_items.py +++ b/toxygen/ui/contact_items.py @@ -1,10 +1,7 @@ from wrapper.toxcore_enums_and_consts import * from PyQt5 import QtCore, QtGui, QtWidgets -from contacts import profile -from file_transfers.file_transfers import FILE_TRANSFER_STATE, PAUSED_FILE_TRANSFERS, DO_NOT_SHOW_ACCEPT_BUTTON, ACTIVE_FILE_TRANSFERS, SHOW_PROGRESS_BAR from utils.util import * -from ui.widgets import DataLabel, create_menu -from user_data import settings +from ui.widgets import DataLabel class ContactItem(QtWidgets.QWidget): diff --git a/toxygen/ui/peer_screen.py b/toxygen/ui/peer_screen.py new file mode 100644 index 0000000..4145fe1 --- /dev/null +++ b/toxygen/ui/peer_screen.py @@ -0,0 +1,36 @@ +from ui.widgets import CenteredWidget +from PyQt5 import QtCore, QtWidgets, uic +import utils.util as util +import utils.ui as util_ui +from ui.contact_items import * + + +class PeerScreen(CenteredWidget): + + def __init__(self, contacts_manager, groups_service, group, peer_id): + super().__init__() + self._contacts_manager = contacts_manager + self._groups_service = groups_service + self._group = group + self._peer = group.get_peer_by_id(peer_id) + + 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.update(self._peer.status) + self.peerNameLabel.setText(self._peer.name) + self.ignorePeerCheckBox.setChecked(self._peer.is_muted) + self.sendPrivateMessagePushButton.clicked.connect(self._send_private_message) + self._retranslate_ui() + + def _retranslate_ui(self): + self.setWindowTitle(util_ui.tr('Peer details')) + self.ignorePeerCheckBox.setText(util_ui.tr('Ignore peer')) + self.sendPrivateMessagePushButton.setText(util_ui.tr('Send private message')) + + def _send_private_message(self): + self._contacts_manager.add_group_peer(self._group, self._peer) + self.close() diff --git a/toxygen/ui/views/peer_screen.ui b/toxygen/ui/views/peer_screen.ui new file mode 100644 index 0000000..cf221c0 --- /dev/null +++ b/toxygen/ui/views/peer_screen.ui @@ -0,0 +1,83 @@ + + + Form + + + + 0 + 0 + 600 + 400 + + + + + 600 + 400 + + + + + 600 + 400 + + + + Form + + + + + 110 + 10 + 431 + 41 + + + + TextLabel + + + + + + 50 + 120 + 500 + 50 + + + + PushButton + + + + + + 50 + 70 + 500 + 23 + + + + CheckBox + + + + + + 50 + 200 + 521 + 161 + + + + GroupBox + + + + + + diff --git a/toxygen/ui/widgets_factory.py b/toxygen/ui/widgets_factory.py index ead09ce..6a0d772 100644 --- a/toxygen/ui/widgets_factory.py +++ b/toxygen/ui/widgets_factory.py @@ -1,6 +1,7 @@ from ui.main_screen_widgets import * from ui.menu import * from ui.groups_widgets import * +from ui.peer_screen import * class WidgetsFactory: @@ -69,3 +70,6 @@ class WidgetsFactory: def create_search_screen(self, messages): return SearchScreen(self._contacts_manager, self._history, messages, messages.parent()) + + def create_peer_screen_window(self, group, peer_id): + return PeerScreen(self._contacts_manager, self._groups_service, group, peer_id) diff --git a/toxygen/wrapper/tox.py b/toxygen/wrapper/tox.py index 9cdac2e..7912103 100644 --- a/toxygen/wrapper/tox.py +++ b/toxygen/wrapper/tox.py @@ -1804,7 +1804,7 @@ class Tox: """ Write the group public key with the designated peer_id for the designated group number to public_key. - This key will be parmanently tied to a particular peer until they explicitly leave the group or + This key will be permanently tied to a particular peer until they explicitly leave the group or get kicked/banned, and is the only way to reliably identify the same peer across client restarts. `public_key` should have room for at least TOX_GROUP_PEER_PUBLIC_KEY_SIZE bytes.