diff --git a/toxygen/app.py b/toxygen/app.py index d20eea7..a4c466d 100644 --- a/toxygen/app.py +++ b/toxygen/app.py @@ -296,7 +296,6 @@ class App: self._smiley_loader = SmileyLoader(self._settings) self._tox_dns = ToxDns(self._settings) self._ms = MainWindow(self._settings, self._tray) - self._calls_manager = CallsManager(self._tox.AV, self._settings) db = Database(self._path.replace('.tox', '.db'), self._toxes) friend_items_factory = FriendItemsFactory(self._settings, self._ms) @@ -312,8 +311,9 @@ class App: self._contacts_provider, history, self._tox_dns, messages_items_factory) history.set_contacts_manager(self._contacts_manager) + self._calls_manager = CallsManager(self._tox.AV, self._settings, self._ms, self._contacts_manager) self._messenger = Messenger(self._tox, self._plugin_loader, self._ms, self._contacts_manager, - self._contacts_provider, messages_items_factory, profile) + self._contacts_provider, messages_items_factory, profile, self._calls_manager) file_transfers_message_service = FileTransfersMessagesService(self._contacts_manager, messages_items_factory, profile, self._ms) self._file_transfer_handler = FileTransfersHandler(self._tox, self._settings, self._contacts_provider, diff --git a/toxygen/av/calls_manager.py b/toxygen/av/calls_manager.py index 6e290e2..26a06f4 100644 --- a/toxygen/av/calls_manager.py +++ b/toxygen/av/calls_manager.py @@ -1,19 +1,37 @@ import threading import cv2 import av.calls -import utils.ui as util_ui from messenger.messages import * import time from ui import av_widgets +import common.event as event class CallsManager: - def __init__(self, toxAV, settings): + def __init__(self, toxAV, settings, screen, contacts_manager): self._call = av.calls.AV(toxAV, settings) # object with data about calls self._call_widgets = {} # dict of incoming call widgets self._incoming_calls = set() self._settings = settings + self._screen = screen + self._contacts_manager = contacts_manager + self._call_started_event = event.Event() # friend_number, audio, video, is_outgoing + self._call_finished_event = event.Event() # friend_number, is_declined + + # ----------------------------------------------------------------------------------------------------------------- + # Events + # ----------------------------------------------------------------------------------------------------------------- + + def get_call_started_event(self): + return self._call_started_event + + call_started_event = property(get_call_started_event) + + def get_call_finished_event(self): + return self._call_finished_event + + call_finished_event = property(get_call_finished_event) # ----------------------------------------------------------------------------------------------------------------- # AV support @@ -26,21 +44,17 @@ class CallsManager: def call_click(self, audio=True, video=False): """User clicked audio button in main window""" - num = self.get_active_number() - if not self.is_active_a_friend(): + num = self._contacts_manager.get_active_number() + if not self._contacts_manager.is_active_a_friend(): return - if num not in self._call and self.is_active_online(): # start call + if num not in self._call and self._contacts_manager.is_active_online(): # start call if not self._settings.audio['enabled']: return self._call(num, audio, video) self._screen.active_call() - if video: - text = util_ui.tr("Outgoing video call") - else: - text = util_ui.tr("Outgoing audio call") - self.get_curr_friend().append_message(InfoMessage(text, time.time())) - self.create_message_item(text, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE']) - self._messages.scrollToBottom() + self._call_started_event(num, audio, video, True) + self._contacts_manager.get_curr_friend().append_message(InfoMessage(text, time.time())) + self._screen.messages.scrollToBottom() elif num in self._call: # finish or cancel call if you call with active friend self.stop_call(num, False) @@ -50,17 +64,12 @@ class CallsManager: """ if not self._settings.audio['enabled']: return - friend = self.get_friend_by_number(friend_number) - if video: - text = util_ui.tr("Incoming video call") - else: - text = util_ui.tr("Incoming audio call") + friend = self._contacts_manager.get_friend_by_number(friend_number) + self._call_started_event(friend_number, audio, video, False) friend.append_message(InfoMessage(text, time.time())) self._incoming_calls.add(friend_number) - if friend_number == self.get_active_number(): + if friend_number == self._contacts_manager.get_active_number(): self._screen.incoming_call() - self.create_message_item(text, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE']) - self._messages.scrollToBottom() else: friend.actions = True self._call_widgets[friend_number] = av_widgets.IncomingCallWidget(friend_number, text, friend.name) @@ -83,8 +92,10 @@ class CallsManager: """ if friend_number in self._incoming_calls: self._incoming_calls.remove(friend_number) + is_declined = True text = util_ui.tr("Call declined") else: + is_declined = False text = util_ui.tr("Call finished") self._screen.call_finished() is_video = self._call.is_video_call(friend_number) @@ -98,11 +109,7 @@ class CallsManager: cv2.destroyWindow(str(friend_number)) threading.Timer(2.0, destroy_window).start() - friend = self.get_friend_by_number(friend_number) - friend.append_message(InfoMessage(text, time.time())) - if friend_number == self.get_active_number(): - self.create_message_item(text, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE']) - self._messages.scrollToBottom() + self._call_finished_event(friend_number, is_declined) def friend_exit(self, friend_number): if friend_number in self._call: diff --git a/toxygen/contacts/profile.py b/toxygen/contacts/profile.py index 6393f7e..c775268 100644 --- a/toxygen/contacts/profile.py +++ b/toxygen/contacts/profile.py @@ -1,8 +1,4 @@ -from contacts.friend import * -from file_transfers.file_transfers import * -import time from contacts import basecontact -import utils.ui as util_ui import random import threading @@ -28,7 +24,7 @@ class Profile(basecontact.BaseContact): self._contacts_provider = contacts_provider self._reset_action = reset_action self._waiting_for_reconnection = False - self._timer = threading.Timer(50, self._reconnect) + self._timer = None # ----------------------------------------------------------------------------------------------------------------- # Edit current user's data @@ -47,21 +43,14 @@ class Profile(basecontact.BaseContact): self._tox.self_set_status(status) elif not self._waiting_for_reconnection: self._waiting_for_reconnection = True + self._timer = threading.Timer(50, self._reconnect) self._timer.start() def set_name(self, value): if self.name == value: return - tmp = self.name super().set_name(value.encode('utf-8')) self._tox.self_set_name(self._name.encode('utf-8')) - message = util_ui.tr('User {} is now known as {}') - message = message.format(tmp, value) - for friend in self._contacts: - friend.append_message(InfoMessage(message, time.time())) - if self._active_friend + 1: - self.create_message_item(message, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE']) - self._messages.scrollToBottom() def set_status_message(self, value): super().set_status_message(value) @@ -74,15 +63,6 @@ class Profile(basecontact.BaseContact): return self._tox_id - # ----------------------------------------------------------------------------------------------------------------- - # Private messages - # ----------------------------------------------------------------------------------------------------------------- - - def receipt(self): - i = 0 - while i < self._messages.count() and not self._messages.itemWidget(self._messages.item(i)).mark_as_sent(): - i += 1 - # ----------------------------------------------------------------------------------------------------------------- # Reset # ----------------------------------------------------------------------------------------------------------------- @@ -101,10 +81,5 @@ class Profile(basecontact.BaseContact): if self.status is None or all(list(map(lambda x: x.status is None, contacts))) and len(contacts): self._waiting_for_reconnection = True self._restart() + self._timer = threading.Timer(50, self._reconnect) self._timer.start() - - def close(self): - for friend in filter(lambda x: type(x) is Friend, self._contacts): - self.friend_exit(friend.number) - for i in range(len(self._contacts)): - del self._contacts[0] diff --git a/toxygen/messenger/messages.py b/toxygen/messenger/messages.py index 69b5b39..62f8804 100644 --- a/toxygen/messenger/messages.py +++ b/toxygen/messenger/messages.py @@ -216,5 +216,5 @@ class InlineImageMessage(Message): class InfoMessage(TextMessage): - def __init__(self, id, message, time): - super().__init__(id, message, None, time, MESSAGE_TYPE['INFO_MESSAGE']) + def __init__(self, message, time): + super().__init__(message, None, time, MESSAGE_TYPE['INFO_MESSAGE']) diff --git a/toxygen/messenger/messenger.py b/toxygen/messenger/messenger.py index 968ca97..8f3feb2 100644 --- a/toxygen/messenger/messenger.py +++ b/toxygen/messenger/messenger.py @@ -1,14 +1,11 @@ -import utils.util as util import common.tox_save as tox_save -from wrapper.toxcore_enums_and_consts import * from messenger.messages import * -# TODO: sub profile name changed event? - class Messenger(tox_save.ToxSave): - def __init__(self, tox, plugin_loader, screen, contacts_manager, contacts_provider, items_factory, profile): + def __init__(self, tox, plugin_loader, screen, contacts_manager, contacts_provider, items_factory, profile, + calls_manager): super().__init__(tox) self._plugin_loader = plugin_loader self._screen = screen @@ -16,6 +13,11 @@ class Messenger(tox_save.ToxSave): self._contacts_provider = contacts_provider self._items_factory = items_factory self._profile = profile + self._profile_name = profile.name + + profile.name_changed_event.add_callback(self._on_profile_name_changed) + calls_manager.call_started_event.add_callback(self._on_call_started) + calls_manager.call_finished_event.add_callback(self._on_call_finished) # ----------------------------------------------------------------------------------------------------------------- # Private methods @@ -160,3 +162,36 @@ class Messenger(tox_save.ToxSave): def _get_friend_by_number(self, friend_number): return self._contacts_provider.get_friend_by_number(friend_number) + + def _on_profile_name_changed(self, new_name): + if self._profile_name == new_name: + return + message = util_ui.tr('User {} is now known as {}') + message = message.format(self._profile_name, new_name) + for friend in self._contacts_provider.get_all_friends(): + friend.append_message(InfoMessage(message, util.get_unix_time())) + if self._contacts_manager.is_active_a_friend(): + self._items_factory.create_message_item(message) + self._screen.messages.scrollToBottom() + self._profile_name = new_name + + def _on_call_started(self, friend_number, audio, video, is_outgoing): + if is_outgoing: + text = util_ui.tr("Outgoing video call") if video else util_ui.tr("Outgoing audio call") + else: + text = util_ui.tr("Incoming video call") if video else util_ui.tr("Incoming audio call") + friend = self._get_friend_by_number(friend_number) + message = InfoMessage(text, util.get_unix_time()) + friend.append_message(message) + if self._contacts_manager.is_friend_active(friend_number): + self._items_factory.create_message_item(message) + self._screen.messages.scrollToBottom() + + def _on_call_finished(self, friend_number, is_declined): + text = util_ui.tr("Call declined") if is_declined else util_ui.tr("Call finished") + friend = self._get_friend_by_number(friend_number) + message = InfoMessage(text, util.get_unix_time()) + friend.append_message(message) + if self._contacts_manager.is_friend_active(friend_number): + self._items_factory.create_message_item(message) + self._screen.messages.scrollToBottom()