private messages support
This commit is contained in:
parent
e15620c3ad
commit
5521b768bc
@ -32,6 +32,8 @@ from history.history import History
|
|||||||
from file_transfers.file_transfers_messages_service import FileTransfersMessagesService
|
from file_transfers.file_transfers_messages_service import FileTransfersMessagesService
|
||||||
from groups.groups_service import GroupsService
|
from groups.groups_service import GroupsService
|
||||||
from ui.create_profile_screen import CreateProfileScreen
|
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
|
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._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._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._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
|
self._group_factory = self._groups_service = self._profile = None
|
||||||
if uri is not None and uri.startswith('tox:'):
|
if uri is not None and uri.startswith('tox:'):
|
||||||
self._uri = uri[4:]
|
self._uri = uri[4:]
|
||||||
@ -336,7 +339,9 @@ class App:
|
|||||||
self._friend_factory = FriendFactory(self._profile_manager, self._settings,
|
self._friend_factory = FriendFactory(self._profile_manager, self._settings,
|
||||||
self._tox, db, contact_items_factory)
|
self._tox, db, contact_items_factory)
|
||||||
self._group_factory = GroupFactory(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._profile = Profile(self._profile_manager, self._tox, self._ms, self._contacts_provider, self._reset)
|
||||||
self._init_profile()
|
self._init_profile()
|
||||||
self._plugin_loader = PluginLoader(self._settings, self)
|
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,
|
self._file_transfer_handler = FileTransfersHandler(self._tox, self._settings, self._contacts_provider,
|
||||||
file_transfers_message_service, self._profile)
|
file_transfers_message_service, self._profile)
|
||||||
messages_items_factory.set_file_transfers_handler(self._file_transfer_handler)
|
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,
|
widgets_factory = WidgetsFactory(self._settings, self._profile, self._profile_manager, self._contacts_manager,
|
||||||
self._file_transfer_handler, self._smiley_loader, self._plugin_loader,
|
self._file_transfer_handler, self._smiley_loader, self._plugin_loader,
|
||||||
self._toxes, self._version, self._groups_service, history)
|
self._toxes, self._version, self._groups_service, history)
|
||||||
|
13
toxygen/common/provider.py
Normal file
13
toxygen/common/provider.py
Normal file
@ -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
|
@ -3,10 +3,11 @@ import common.tox_save as tox_save
|
|||||||
|
|
||||||
class ContactProvider(tox_save.ToxSave):
|
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)
|
super().__init__(tox)
|
||||||
self._friend_factory = friend_factory
|
self._friend_factory = friend_factory
|
||||||
self._group_factory = group_factory
|
self._group_factory = group_factory
|
||||||
|
self._group_peer_factory = group_peer_factory
|
||||||
self._cache = {} # key - contact's public key, value - contact instance
|
self._cache = {} # key - contact's public key, value - contact instance
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
@ -34,7 +35,7 @@ class ContactProvider(tox_save.ToxSave):
|
|||||||
return list(friends)
|
return list(friends)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# GC
|
# Groups
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def get_all_groups(self):
|
def get_all_groups(self):
|
||||||
@ -57,12 +58,29 @@ class ContactProvider(tox_save.ToxSave):
|
|||||||
|
|
||||||
return group
|
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
|
# All contacts
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def get_all(self):
|
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
|
# Caching
|
||||||
@ -84,3 +102,6 @@ class ContactProvider(tox_save.ToxSave):
|
|||||||
|
|
||||||
def _add_to_cache(self, public_key, contact):
|
def _add_to_cache(self, public_key, contact):
|
||||||
self._cache[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)
|
||||||
|
@ -2,6 +2,7 @@ from contacts.friend import Friend
|
|||||||
from contacts.group_chat import GroupChat
|
from contacts.group_chat import GroupChat
|
||||||
from messenger.messages import *
|
from messenger.messages import *
|
||||||
from common.tox_save import ToxSave
|
from common.tox_save import ToxSave
|
||||||
|
from contacts.group_peer_contact import GroupPeerContact
|
||||||
|
|
||||||
|
|
||||||
class ContactsManager(ToxSave):
|
class ContactsManager(ToxSave):
|
||||||
@ -223,6 +224,17 @@ class ContactsManager(ToxSave):
|
|||||||
def get_group_by_number(self, number):
|
def get_group_by_number(self, number):
|
||||||
return list(filter(lambda c: c.number == number and type(c) is GroupChat, self._contacts))[0]
|
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):
|
def get_contact_by_tox_id(self, tox_id):
|
||||||
return list(filter(lambda c: c.tox_id == tox_id, self._contacts))[0]
|
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)
|
num = self._contacts.index(group)
|
||||||
self._delete_contact(num)
|
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
|
# Friend requests
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -11,8 +11,6 @@ class GroupChat(contact.Contact, ToxSave):
|
|||||||
def __init__(self, tox, profile_manager, message_getter, number, name, status_message, widget, tox_id):
|
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)
|
super().__init__(profile_manager, message_getter, number, name, status_message, widget, tox_id)
|
||||||
ToxSave.__init__(self, tox)
|
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._peers = []
|
||||||
self._add_self_to_gc()
|
self._add_self_to_gc()
|
||||||
|
|
||||||
@ -57,6 +55,11 @@ class GroupChat(contact.Contact, ToxSave):
|
|||||||
|
|
||||||
return peers[0]
|
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):
|
def remove_all_peers_except_self(self):
|
||||||
self._peers = self._peers[:1]
|
self._peers = self._peers[:1]
|
||||||
|
|
||||||
|
@ -3,11 +3,17 @@ import contacts.contact
|
|||||||
|
|
||||||
class GroupPeerContact(contacts.contact.Contact):
|
class GroupPeerContact(contacts.contact.Contact):
|
||||||
|
|
||||||
def __init__(self, profile_manager, message_getter, peer_number, name, status_messsage, widget, tox_id, group_pk):
|
def __init__(self, profile_manager, message_getter, peer_number, name, widget, tox_id, group_pk):
|
||||||
super().__init__(profile_manager, message_getter, peer_number, name, status_messsage, widget, tox_id)
|
super().__init__(profile_manager, message_getter, peer_number, name, str(), widget, tox_id)
|
||||||
self._group_pk = group_pk
|
self._group_pk = group_pk
|
||||||
|
|
||||||
def get_group_pk(self):
|
def get_group_pk(self):
|
||||||
return self._group_pk
|
return self._group_pk
|
||||||
|
|
||||||
group_pk = property(get_group_pk)
|
group_pk = property(get_group_pk)
|
||||||
|
|
||||||
|
def remove_invalid_unsent_files(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_context_menu_generator(self):
|
||||||
|
return None
|
||||||
|
23
toxygen/contacts/group_peer_factory.py
Normal file
23
toxygen/contacts/group_peer_factory.py
Normal file
@ -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()
|
@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
class GroupChatPeer:
|
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._peer_id = peer_id
|
||||||
self._name = name
|
self._name = name
|
||||||
self._status = status
|
self._status = status
|
||||||
self._role = role
|
self._role = role
|
||||||
self._public_key = public_key
|
self._public_key = public_key
|
||||||
self._is_current_user = is_current_user
|
self._is_current_user = is_current_user
|
||||||
|
self._is_muted = is_muted
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return self._peer_id
|
return self._peer_id
|
||||||
@ -48,3 +49,8 @@ class GroupChatPeer:
|
|||||||
return self._is_current_user
|
return self._is_current_user
|
||||||
|
|
||||||
is_current_user = property(get_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)
|
||||||
|
@ -6,11 +6,13 @@ import wrapper.toxcore_enums_and_consts as constants
|
|||||||
|
|
||||||
class GroupsService(tox_save.ToxSave):
|
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)
|
super().__init__(tox)
|
||||||
self._contacts_manager = contacts_manager
|
self._contacts_manager = contacts_manager
|
||||||
self._contacts_provider = contacts_provider
|
self._contacts_provider = contacts_provider
|
||||||
self._peers_list_widget = main_screen.peers_list
|
self._peers_list_widget = main_screen.peers_list
|
||||||
|
self._widgets_factory_provider = widgets_factory_provider
|
||||||
|
self._peer_screen = None
|
||||||
|
|
||||||
def set_tox(self, tox):
|
def set_tox(self, tox):
|
||||||
super().set_tox(tox)
|
super().set_tox(tox)
|
||||||
@ -23,8 +25,12 @@ class GroupsService(tox_save.ToxSave):
|
|||||||
|
|
||||||
def create_new_gc(self, name, privacy_state):
|
def create_new_gc(self, name, privacy_state):
|
||||||
group_number = self._tox.group_new(privacy_state, name.encode('utf-8'))
|
group_number = self._tox.group_new(privacy_state, name.encode('utf-8'))
|
||||||
if group_number != -1:
|
if group_number == -1:
|
||||||
|
return
|
||||||
|
|
||||||
self._add_new_group_by_number(group_number)
|
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):
|
def join_gc_by_id(self, chat_id, password):
|
||||||
group_number = self._tox.group_join(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):
|
def disconnect_from_group(self, group_number):
|
||||||
self._tox.group_disconnect(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
|
group.status = None
|
||||||
self._clear_peers_list(group)
|
self._clear_peers_list(group)
|
||||||
|
|
||||||
def reconnect_to_group(self, group_number):
|
def reconnect_to_group(self, group_number):
|
||||||
self._tox.group_reconnect(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']
|
group.status = constants.TOX_USER_STATUS['NONE']
|
||||||
self._clear_peers_list(group)
|
self._clear_peers_list(group)
|
||||||
|
|
||||||
@ -63,7 +69,7 @@ class GroupsService(tox_save.ToxSave):
|
|||||||
self._tox.group_invite_friend(group_number, friend_number)
|
self._tox.group_invite_friend(group_number, friend_number)
|
||||||
|
|
||||||
def process_group_invite(self, friend_number, group_name, invite_data):
|
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?')
|
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')):
|
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)
|
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)
|
PeersListGenerator().generate(group.peers, self, self._peers_list_widget, group.tox_id)
|
||||||
|
|
||||||
def peer_selected(self, chat_id, peer_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
|
# Private methods
|
||||||
@ -107,15 +116,18 @@ class GroupsService(tox_save.ToxSave):
|
|||||||
def _add_new_group_by_number(self, group_number):
|
def _add_new_group_by_number(self, group_number):
|
||||||
self._contacts_manager.add_group(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)
|
return self._contacts_provider.get_group_by_number(group_number)
|
||||||
|
|
||||||
def _get_friend(self, friend_number):
|
def _get_group_by_public_key(self, public_key):
|
||||||
return self._contacts_provider.get_friend_by_number(friend_number)
|
return self._contacts_provider.get_group_by_public_key(public_key)
|
||||||
|
|
||||||
def _get_all_groups(self):
|
def _get_all_groups(self):
|
||||||
return self._contacts_provider.get_all_groups()
|
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):
|
def _clear_peers_list(self, group):
|
||||||
group.remove_all_peers_except_self()
|
group.remove_all_peers_except_self()
|
||||||
self.generate_peers_list()
|
self.generate_peers_list()
|
||||||
|
@ -46,8 +46,10 @@ class Messenger(tox_save.ToxSave):
|
|||||||
text = self._screen.messageEdit.toPlainText()
|
text = self._screen.messageEdit.toPlainText()
|
||||||
if self._contacts_manager.is_active_a_friend():
|
if self._contacts_manager.is_active_a_friend():
|
||||||
self.send_message_to_friend(text)
|
self.send_message_to_friend(text)
|
||||||
else:
|
elif self._contacts_manager.is_active_a_group():
|
||||||
self.send_message_to_group(text)
|
self.send_message_to_group(text)
|
||||||
|
else:
|
||||||
|
self.send_message_to_group_peer(text)
|
||||||
|
|
||||||
def send_message_to_friend(self, text, friend_number=None):
|
def send_message_to_friend(self, text, friend_number=None):
|
||||||
"""
|
"""
|
||||||
@ -57,10 +59,15 @@ class Messenger(tox_save.ToxSave):
|
|||||||
"""
|
"""
|
||||||
if friend_number is None:
|
if friend_number is None:
|
||||||
friend_number = self._contacts_manager.get_active_number()
|
friend_number = self._contacts_manager.get_active_number()
|
||||||
|
|
||||||
if text.startswith('/plugin '):
|
if text.startswith('/plugin '):
|
||||||
self._plugin_loader.command(text[8:])
|
self._plugin_loader.command(text[8:])
|
||||||
self._screen.messageEdit.clear()
|
self._screen.messageEdit.clear()
|
||||||
elif text and friend_number >= 0:
|
return
|
||||||
|
|
||||||
|
if not text or friend_number < 0:
|
||||||
|
return
|
||||||
|
|
||||||
if text.startswith('/me '):
|
if text.startswith('/me '):
|
||||||
message_type = TOX_MESSAGE_TYPE['ACTION']
|
message_type = TOX_MESSAGE_TYPE['ACTION']
|
||||||
text = text[4:]
|
text = text[4:]
|
||||||
@ -77,7 +84,8 @@ class Messenger(tox_save.ToxSave):
|
|||||||
message_author = MessageAuthor(self._profile.name, MESSAGE_AUTHOR['NOT_SENT'])
|
message_author = MessageAuthor(self._profile.name, MESSAGE_AUTHOR['NOT_SENT'])
|
||||||
message = OutgoingTextMessage(text, message_author, t, message_type, message_id)
|
message = OutgoingTextMessage(text, message_author, t, message_type, message_id)
|
||||||
friend.append_message(message)
|
friend.append_message(message)
|
||||||
if self._contacts_manager.is_friend_active(friend_number):
|
if not self._contacts_manager.is_friend_active(friend_number):
|
||||||
|
return
|
||||||
self._create_message_item(message)
|
self._create_message_item(message)
|
||||||
self._screen.messageEdit.clear()
|
self._screen.messageEdit.clear()
|
||||||
self._screen.messages.scrollToBottom()
|
self._screen.messages.scrollToBottom()
|
||||||
@ -103,10 +111,15 @@ class Messenger(tox_save.ToxSave):
|
|||||||
def send_message_to_group(self, text, group_number=None):
|
def send_message_to_group(self, text, group_number=None):
|
||||||
if group_number is None:
|
if group_number is None:
|
||||||
group_number = self._contacts_manager.get_active_number()
|
group_number = self._contacts_manager.get_active_number()
|
||||||
|
|
||||||
if text.startswith('/plugin '):
|
if text.startswith('/plugin '):
|
||||||
self._plugin_loader.command(text[8:])
|
self._plugin_loader.command(text[8:])
|
||||||
self._screen.messageEdit.clear()
|
self._screen.messageEdit.clear()
|
||||||
elif text and group_number >= 0:
|
return
|
||||||
|
|
||||||
|
if not text or group_number < 0:
|
||||||
|
return
|
||||||
|
|
||||||
if text.startswith('/me '):
|
if text.startswith('/me '):
|
||||||
message_type = TOX_MESSAGE_TYPE['ACTION']
|
message_type = TOX_MESSAGE_TYPE['ACTION']
|
||||||
text = text[4:]
|
text = text[4:]
|
||||||
@ -120,7 +133,8 @@ class Messenger(tox_save.ToxSave):
|
|||||||
message_author = MessageAuthor(group.get_self_name(), MESSAGE_AUTHOR['GC_PEER'])
|
message_author = MessageAuthor(group.get_self_name(), MESSAGE_AUTHOR['GC_PEER'])
|
||||||
message = OutgoingTextMessage(text, message_author, t, message_type)
|
message = OutgoingTextMessage(text, message_author, t, message_type)
|
||||||
group.append_message(message)
|
group.append_message(message)
|
||||||
if self._contacts_manager.is_group_active(group_number):
|
if not self._contacts_manager.is_group_active(group_number):
|
||||||
|
return
|
||||||
self._create_message_item(message)
|
self._create_message_item(message)
|
||||||
self._screen.messageEdit.clear()
|
self._screen.messageEdit.clear()
|
||||||
self._screen.messages.scrollToBottom()
|
self._screen.messages.scrollToBottom()
|
||||||
@ -137,6 +151,53 @@ class Messenger(tox_save.ToxSave):
|
|||||||
text_message = TextMessage(message, MessageAuthor(peer.name, MESSAGE_AUTHOR['GC_PEER']), t, message_type)
|
text_message = TextMessage(message, MessageAuthor(peer.name, MESSAGE_AUTHOR['GC_PEER']), t, message_type)
|
||||||
self._add_message(text_message, group)
|
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
|
# Message receipts
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
@ -211,6 +272,9 @@ class Messenger(tox_save.ToxSave):
|
|||||||
def _get_group_by_number(self, group_number):
|
def _get_group_by_number(self, group_number):
|
||||||
return self._contacts_provider.get_group_by_number(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):
|
def _on_profile_name_changed(self, new_name):
|
||||||
if self._profile_name == new_name:
|
if self._profile_name == new_name:
|
||||||
return
|
return
|
||||||
|
@ -375,6 +375,26 @@ def group_message(window, tray, tox, messenger, settings, profile):
|
|||||||
return wrapped
|
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 group_invite(groups_service):
|
||||||
def wrapped(tox, friend_number, invite_data, length, group_name, group_name_length, user_data):
|
def wrapped(tox, friend_number, invite_data, length, group_name, group_name_length, user_data):
|
||||||
group_name = bytes(group_name[:group_name_length])
|
group_name = bytes(group_name[:group_name_length])
|
||||||
@ -499,6 +519,7 @@ def init_callbacks(tox, profile, settings, plugin_loader, contacts_manager,
|
|||||||
|
|
||||||
# gc callbacks
|
# gc callbacks
|
||||||
tox.callback_group_message(group_message(main_window, tray, tox, messenger, settings, profile), 0)
|
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_invite(group_invite(groups_service), 0)
|
||||||
tox.callback_group_self_join(group_self_join(contacts_provider, 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_join(group_peer_join(contacts_provider, groups_service), 0)
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
from wrapper.toxcore_enums_and_consts import *
|
from wrapper.toxcore_enums_and_consts import *
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
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 utils.util import *
|
||||||
from ui.widgets import DataLabel, create_menu
|
from ui.widgets import DataLabel
|
||||||
from user_data import settings
|
|
||||||
|
|
||||||
|
|
||||||
class ContactItem(QtWidgets.QWidget):
|
class ContactItem(QtWidgets.QWidget):
|
||||||
|
36
toxygen/ui/peer_screen.py
Normal file
36
toxygen/ui/peer_screen.py
Normal file
@ -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()
|
83
toxygen/ui/views/peer_screen.ui
Normal file
83
toxygen/ui/views/peer_screen.ui
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?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>600</width>
|
||||||
|
<height>400</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>600</width>
|
||||||
|
<height>400</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>600</width>
|
||||||
|
<height>400</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QLabel" name="peerNameLabel">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>110</x>
|
||||||
|
<y>10</y>
|
||||||
|
<width>431</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="sendPrivateMessagePushButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>50</x>
|
||||||
|
<y>120</y>
|
||||||
|
<width>500</width>
|
||||||
|
<height>50</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>PushButton</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QCheckBox" name="ignorePeerCheckBox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>50</x>
|
||||||
|
<y>70</y>
|
||||||
|
<width>500</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>CheckBox</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QGroupBox" name="banGroupBox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>50</x>
|
||||||
|
<y>200</y>
|
||||||
|
<width>521</width>
|
||||||
|
<height>161</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>GroupBox</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -1,6 +1,7 @@
|
|||||||
from ui.main_screen_widgets import *
|
from ui.main_screen_widgets import *
|
||||||
from ui.menu import *
|
from ui.menu import *
|
||||||
from ui.groups_widgets import *
|
from ui.groups_widgets import *
|
||||||
|
from ui.peer_screen import *
|
||||||
|
|
||||||
|
|
||||||
class WidgetsFactory:
|
class WidgetsFactory:
|
||||||
@ -69,3 +70,6 @@ class WidgetsFactory:
|
|||||||
|
|
||||||
def create_search_screen(self, messages):
|
def create_search_screen(self, messages):
|
||||||
return SearchScreen(self._contacts_manager, self._history, messages, messages.parent())
|
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)
|
||||||
|
@ -1804,7 +1804,7 @@ class Tox:
|
|||||||
"""
|
"""
|
||||||
Write the group public key with the designated peer_id for the designated group number to public_key.
|
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.
|
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.
|
`public_key` should have room for at least TOX_GROUP_PEER_PUBLIC_KEY_SIZE bytes.
|
||||||
|
Loading…
Reference in New Issue
Block a user