Compare commits
10 commits
dc96f66d8c
...
098f295cb0
Author | SHA1 | Date | |
---|---|---|---|
|
098f295cb0 | ||
|
2fc90880b8 | ||
|
1ab59ee422 | ||
|
735c88d5bf | ||
|
2745caa531 | ||
|
4abd72e278 | ||
|
f775203f4c | ||
|
8a53fc8727 | ||
|
bb4e80ca09 | ||
|
3602b3433e |
9 changed files with 239 additions and 182 deletions
|
@ -29,7 +29,7 @@ class BaseContact:
|
||||||
self.load_avatar()
|
self.load_avatar()
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# name - current name or alias of user
|
# Name - current name or alias of user
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
|
@ -43,7 +43,7 @@ class BaseContact:
|
||||||
name = property(get_name, set_name)
|
name = property(get_name, set_name)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Status message
|
# Status message or group topic
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def get_status_message(self):
|
def get_status_message(self):
|
||||||
|
|
|
@ -293,7 +293,7 @@ def callback_audio(toxav, friend_number, samples, audio_samples_per_channel, aud
|
||||||
|
|
||||||
def group_message(window, tray, tox):
|
def group_message(window, tray, tox):
|
||||||
"""
|
"""
|
||||||
New message from friend
|
New message in group chat
|
||||||
"""
|
"""
|
||||||
def wrapped(tox_link, group_number, peer_id, message_type, message, length, user_data):
|
def wrapped(tox_link, group_number, peer_id, message_type, message, length, user_data):
|
||||||
profile = Profile.get_instance()
|
profile = Profile.get_instance()
|
||||||
|
@ -303,9 +303,9 @@ def group_message(window, tray, tox):
|
||||||
if not window.isActiveWindow():
|
if not window.isActiveWindow():
|
||||||
bl = settings['notify_all_gc'] or profile.name in message
|
bl = settings['notify_all_gc'] or profile.name in message
|
||||||
name = tox.group_peer_get_name(group_number, peer_id)
|
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:
|
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)
|
invoke_in_main_thread(tray_notification, name, message, tray, window)
|
||||||
if (settings['sound_notifications'] or bl) and profile.status != TOX_USER_STATUS['BUSY']:
|
if settings['sound_notifications'] and bl and profile.status != TOX_USER_STATUS['BUSY']:
|
||||||
sound_notification(SOUND_NOTIFICATION['MESSAGE'])
|
sound_notification(SOUND_NOTIFICATION['MESSAGE'])
|
||||||
invoke_in_main_thread(tray.setIcon, QtGui.QIcon(curr_directory() + '/images/icon_new_messages.png'))
|
invoke_in_main_thread(tray.setIcon, QtGui.QIcon(curr_directory() + '/images/icon_new_messages.png'))
|
||||||
return wrapped
|
return wrapped
|
||||||
|
@ -314,7 +314,20 @@ def group_message(window, tray, tox):
|
||||||
def group_invite(tox, friend_number, invite_data, length, user_data):
|
def group_invite(tox, friend_number, invite_data, length, user_data):
|
||||||
invoke_in_main_thread(Profile.get_instance().process_group_invite,
|
invoke_in_main_thread(Profile.get_instance().process_group_invite,
|
||||||
friend_number,
|
friend_number,
|
||||||
invite_data[:length])
|
bytes(invite_data[:length]))
|
||||||
|
|
||||||
|
|
||||||
|
def group_self_join(tox, group_number, user_data):
|
||||||
|
pr = Profile.get_instance()
|
||||||
|
gc = pr.get_gc_by_number(group_number)
|
||||||
|
invoke_in_main_thread(gc.set_status, TOX_USER_STATUS['NONE'])
|
||||||
|
if not pr.is_active_a_friend() and pr.get_active_number() == group_number:
|
||||||
|
invoke_in_main_thread(pr.set_active)
|
||||||
|
|
||||||
|
|
||||||
|
def group_peer_join(tox, group_number, peer_id, user_data):
|
||||||
|
gc = Profile.get_instance().get_gc_by_number(group_number)
|
||||||
|
gc.add_peer(peer_id)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -355,4 +368,6 @@ def init_callbacks(tox, window, tray):
|
||||||
|
|
||||||
tox.callback_group_message(group_message(window, tray, tox), 0)
|
tox.callback_group_message(group_message(window, tray, tox), 0)
|
||||||
tox.callback_group_invite(group_invite, 0)
|
tox.callback_group_invite(group_invite, 0)
|
||||||
|
tox.callback_group_self_join(group_self_join, 0)
|
||||||
|
tox.callback_group_peer_join(group_peer_join, 0)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ except ImportError:
|
||||||
import basecontact
|
import basecontact
|
||||||
from messages import *
|
from messages import *
|
||||||
from history import *
|
from history import *
|
||||||
|
import file_transfers as ft
|
||||||
|
import util
|
||||||
|
|
||||||
|
|
||||||
class Contact(basecontact.BaseContact):
|
class Contact(basecontact.BaseContact):
|
||||||
|
@ -25,6 +27,7 @@ class Contact(basecontact.BaseContact):
|
||||||
self._message_getter = message_getter
|
self._message_getter = message_getter
|
||||||
self._new_messages = False
|
self._new_messages = False
|
||||||
self._visible = True
|
self._visible = True
|
||||||
|
self._alias = False
|
||||||
self._number = number
|
self._number = number
|
||||||
self._corr = []
|
self._corr = []
|
||||||
self._unsaved_messages = 0
|
self._unsaved_messages = 0
|
||||||
|
@ -57,11 +60,8 @@ class Contact(basecontact.BaseContact):
|
||||||
Get data to save in db
|
Get data to save in db
|
||||||
:return: list of unsaved messages or []
|
:return: list of unsaved messages or []
|
||||||
"""
|
"""
|
||||||
if hasattr(self, '_message_getter'):
|
|
||||||
del self._message_getter
|
|
||||||
messages = list(filter(lambda x: x.get_type() <= 1, self._corr))
|
messages = list(filter(lambda x: x.get_type() <= 1, self._corr))
|
||||||
return list(
|
return list(map(lambda x: x.get_data(), messages[-self._unsaved_messages:])) if self._unsaved_messages else []
|
||||||
map(lambda x: x.get_data(), list(messages[-self._unsaved_messages:]))) if self._unsaved_messages else []
|
|
||||||
|
|
||||||
def get_corr(self):
|
def get_corr(self):
|
||||||
return self._corr[:]
|
return self._corr[:]
|
||||||
|
@ -81,16 +81,26 @@ class Contact(basecontact.BaseContact):
|
||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def clear_corr(self):
|
def get_unsent_messages(self):
|
||||||
"""
|
"""
|
||||||
Clear messages list
|
:return list of unsent messages
|
||||||
"""
|
"""
|
||||||
if hasattr(self, '_message_getter'):
|
messages = filter(lambda x: x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr)
|
||||||
del self._message_getter
|
return list(messages)
|
||||||
# don't delete data about active file transfer
|
|
||||||
self._corr = list(filter(lambda x: x.get_type() in (2, 3) and (x.get_status() >= 2 or x.get_status() is None),
|
def get_unsent_messages_for_saving(self):
|
||||||
self._corr))
|
"""
|
||||||
self._unsaved_messages = 0
|
:return list of unsent messages for saving
|
||||||
|
"""
|
||||||
|
messages = filter(lambda x: x.get_type() <= 1 and x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr)
|
||||||
|
return list(map(lambda x: x.get_data(), messages))
|
||||||
|
|
||||||
|
def delete_message(self, time):
|
||||||
|
elem = list(filter(lambda x: type(x) is TextMessage and x.get_data()[2] == time, self._corr))[0]
|
||||||
|
tmp = list(filter(lambda x: x.get_type() <= 1, self._corr))
|
||||||
|
if elem in tmp[-self._unsaved_messages:]:
|
||||||
|
self._unsaved_messages -= 1
|
||||||
|
self._corr.remove(elem)
|
||||||
|
|
||||||
def delete_old_messages(self):
|
def delete_old_messages(self):
|
||||||
old = filter(lambda x: x.get_type() in (2, 3) and (x.get_status() >= 2 or x.get_status() is None),
|
old = filter(lambda x: x.get_type() in (2, 3) and (x.get_status() >= 2 or x.get_status() is None),
|
||||||
|
@ -100,6 +110,30 @@ class Contact(basecontact.BaseContact):
|
||||||
self._unsaved_messages -= l
|
self._unsaved_messages -= l
|
||||||
self._corr = old + self._corr[-SAVE_MESSAGES:]
|
self._corr = old + self._corr[-SAVE_MESSAGES:]
|
||||||
|
|
||||||
|
def mark_as_sent(self):
|
||||||
|
try:
|
||||||
|
message = list(filter(lambda x: x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr))[0]
|
||||||
|
message.mark_as_sent()
|
||||||
|
except Exception as ex:
|
||||||
|
util.log('Mark as sent ex: ' + str(ex))
|
||||||
|
|
||||||
|
def clear_corr(self, save_unsent=False):
|
||||||
|
"""
|
||||||
|
Clear messages list
|
||||||
|
"""
|
||||||
|
if hasattr(self, '_message_getter'):
|
||||||
|
del self._message_getter
|
||||||
|
# don't delete data about active file transfer
|
||||||
|
if not save_unsent:
|
||||||
|
self._corr = list(filter(lambda x: x.get_type() in (2, 3) and
|
||||||
|
x.get_status() in ft.ACTIVE_FILE_TRANSFERS, self._corr))
|
||||||
|
self._unsaved_messages = 0
|
||||||
|
else:
|
||||||
|
self._corr = list(filter(lambda x: (x.get_type() in (2, 3) and x.get_status() in ft.ACTIVE_FILE_TRANSFERS)
|
||||||
|
or (x.get_type() <= 1 and x.get_owner() == MESSAGE_OWNER['NOT_SENT']),
|
||||||
|
self._corr))
|
||||||
|
self._unsaved_messages = len(self.get_unsent_messages())
|
||||||
|
|
||||||
def get_curr_text(self):
|
def get_curr_text(self):
|
||||||
return self._curr_text
|
return self._curr_text
|
||||||
|
|
||||||
|
@ -161,3 +195,18 @@ class Contact(basecontact.BaseContact):
|
||||||
self._number = value
|
self._number = value
|
||||||
|
|
||||||
number = property(get_number, set_number)
|
number = property(get_number, set_number)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
# Alias support
|
||||||
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def set_name(self, value):
|
||||||
|
"""
|
||||||
|
Set new name or ignore if alias exists
|
||||||
|
:param value: new name
|
||||||
|
"""
|
||||||
|
if not self._alias:
|
||||||
|
super(Contact, self).set_name(value)
|
||||||
|
|
||||||
|
def set_alias(self, alias):
|
||||||
|
self._alias = bool(alias)
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
import contact
|
import contact
|
||||||
from messages import *
|
from messages import *
|
||||||
from history import *
|
|
||||||
import util
|
|
||||||
import file_transfers as ft
|
|
||||||
|
|
||||||
|
|
||||||
class Friend(contact.Contact):
|
class Friend(contact.Contact):
|
||||||
|
@ -15,7 +12,6 @@ class Friend(contact.Contact):
|
||||||
:param number: number of friend.
|
:param number: number of friend.
|
||||||
"""
|
"""
|
||||||
super(Friend, self).__init__(*args)
|
super(Friend, self).__init__(*args)
|
||||||
self._alias = False
|
|
||||||
self._receipts = 0
|
self._receipts = 0
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
@ -38,100 +34,6 @@ class Friend(contact.Contact):
|
||||||
self._receipts -= 1
|
self._receipts -= 1
|
||||||
self.mark_as_sent()
|
self.mark_as_sent()
|
||||||
|
|
||||||
def load_corr(self, first_time=True):
|
|
||||||
"""
|
|
||||||
:param first_time: friend became active, load first part of messages
|
|
||||||
"""
|
|
||||||
if (first_time and self._history_loaded) or (not hasattr(self, '_message_getter')):
|
|
||||||
return
|
|
||||||
data = list(self._message_getter.get(PAGE_SIZE))
|
|
||||||
if data is not None and len(data):
|
|
||||||
data.reverse()
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
data = list(map(lambda tupl: TextMessage(*tupl), data))
|
|
||||||
self._corr = data + self._corr
|
|
||||||
self._history_loaded = True
|
|
||||||
|
|
||||||
def get_corr_for_saving(self):
|
|
||||||
"""
|
|
||||||
Get data to save in db
|
|
||||||
:return: list of unsaved messages or []
|
|
||||||
"""
|
|
||||||
messages = list(filter(lambda x: x.get_type() <= 1, self._corr))
|
|
||||||
return list(map(lambda x: x.get_data(), messages[-self._unsaved_messages:])) if self._unsaved_messages else []
|
|
||||||
|
|
||||||
def get_corr(self):
|
|
||||||
return self._corr[:]
|
|
||||||
|
|
||||||
def append_message(self, message):
|
|
||||||
"""
|
|
||||||
:param message: text or file transfer message
|
|
||||||
"""
|
|
||||||
self._corr.append(message)
|
|
||||||
if message.get_type() <= 1:
|
|
||||||
self._unsaved_messages += 1
|
|
||||||
|
|
||||||
def get_last_message_text(self):
|
|
||||||
messages = list(filter(lambda x: x.get_type() <= 1 and x.get_owner() != MESSAGE_OWNER['FRIEND'], self._corr))
|
|
||||||
if messages:
|
|
||||||
return messages[-1].get_data()[0]
|
|
||||||
else:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def get_unsent_messages(self):
|
|
||||||
"""
|
|
||||||
:return list of unsent messages
|
|
||||||
"""
|
|
||||||
messages = filter(lambda x: x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr)
|
|
||||||
return list(messages)
|
|
||||||
|
|
||||||
def get_unsent_messages_for_saving(self):
|
|
||||||
"""
|
|
||||||
:return list of unsent messages for saving
|
|
||||||
"""
|
|
||||||
messages = filter(lambda x: x.get_type() <= 1 and x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr)
|
|
||||||
return list(map(lambda x: x.get_data(), messages))
|
|
||||||
|
|
||||||
def delete_message(self, time):
|
|
||||||
elem = list(filter(lambda x: type(x) is TextMessage and x.get_data()[2] == time, self._corr))[0]
|
|
||||||
tmp = list(filter(lambda x: x.get_type() <= 1, self._corr))
|
|
||||||
if elem in tmp[-self._unsaved_messages:]:
|
|
||||||
self._unsaved_messages -= 1
|
|
||||||
self._corr.remove(elem)
|
|
||||||
|
|
||||||
def mark_as_sent(self):
|
|
||||||
try:
|
|
||||||
message = list(filter(lambda x: x.get_owner() == MESSAGE_OWNER['NOT_SENT'], self._corr))[0]
|
|
||||||
message.mark_as_sent()
|
|
||||||
except Exception as ex:
|
|
||||||
util.log('Mark as sent ex: ' + str(ex))
|
|
||||||
|
|
||||||
def clear_corr(self, save_unsent=False):
|
|
||||||
"""
|
|
||||||
Clear messages list
|
|
||||||
"""
|
|
||||||
if hasattr(self, '_message_getter'):
|
|
||||||
del self._message_getter
|
|
||||||
# don't delete data about active file transfer
|
|
||||||
if not save_unsent:
|
|
||||||
self._corr = list(filter(lambda x: x.get_type() in (2, 3) and
|
|
||||||
x.get_status() in ft.ACTIVE_FILE_TRANSFERS, self._corr))
|
|
||||||
self._unsaved_messages = 0
|
|
||||||
else:
|
|
||||||
self._corr = list(filter(lambda x: (x.get_type() in (2, 3) and x.get_status() in ft.ACTIVE_FILE_TRANSFERS)
|
|
||||||
or (x.get_type() <= 1 and x.get_owner() == MESSAGE_OWNER['NOT_SENT']),
|
|
||||||
self._corr))
|
|
||||||
self._unsaved_messages = len(self.get_unsent_messages())
|
|
||||||
|
|
||||||
def get_curr_text(self):
|
|
||||||
return self._curr_text
|
|
||||||
|
|
||||||
def set_curr_text(self, value):
|
|
||||||
self._curr_text = value
|
|
||||||
|
|
||||||
curr_text = property(get_curr_text, set_curr_text)
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# File transfers support
|
# File transfers support
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -160,18 +62,3 @@ class Friend(contact.Contact):
|
||||||
|
|
||||||
def delete_one_unsent_file(self, time):
|
def delete_one_unsent_file(self, time):
|
||||||
self._corr = list(filter(lambda x: not (type(x) is UnsentFile and x.get_data()[2] == time), self._corr))
|
self._corr = list(filter(lambda x: not (type(x) is UnsentFile and x.get_data()[2] == time), self._corr))
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
|
||||||
# Alias support
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def set_name(self, value):
|
|
||||||
"""
|
|
||||||
Set new name or ignore if alias exists
|
|
||||||
:param value: new name
|
|
||||||
"""
|
|
||||||
if not self._alias:
|
|
||||||
super(Friend, self).set_name(value)
|
|
||||||
|
|
||||||
def set_alias(self, alias):
|
|
||||||
self._alias = bool(alias)
|
|
||||||
|
|
|
@ -10,4 +10,27 @@ class GroupChat(contact.Contact):
|
||||||
def load_avatar(self, default_path='group.png'):
|
def load_avatar(self, default_path='group.png'):
|
||||||
super().load_avatar(default_path)
|
super().load_avatar(default_path)
|
||||||
|
|
||||||
# TODO: get peers list and add other methods
|
def set_status(self, value):
|
||||||
|
print('In gc set_status')
|
||||||
|
super().set_status(value)
|
||||||
|
self.name = bytes(self._tox.group_get_name(self._number), 'utf-8')
|
||||||
|
self._tox_id = self._tox.group_get_chat_id(self._number)
|
||||||
|
self.status_message = bytes(self._tox.group_get_topic(self._number), 'utf-8')
|
||||||
|
|
||||||
|
def add_peer(self, peer_id):
|
||||||
|
print(peer_id)
|
||||||
|
print(self._tox.group_peer_get_name(self._number, peer_id))
|
||||||
|
|
||||||
|
# TODO: get peers list and add other methods
|
||||||
|
|
||||||
|
def get_peers_list(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
class Peer:
|
||||||
|
|
||||||
|
def __init__(self, peer_id, name, status, role):
|
||||||
|
self._data = (peer_id, name, status, role)
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
return self._data
|
||||||
|
|
|
@ -558,7 +558,15 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
auto = QtGui.QApplication.translate("MainWindow", 'Disallow auto accept', None, QtGui.QApplication.UnicodeUTF8) if allowed else QtGui.QApplication.translate("MainWindow", 'Allow auto accept', None, QtGui.QApplication.UnicodeUTF8)
|
auto = QtGui.QApplication.translate("MainWindow", 'Disallow auto accept', None, QtGui.QApplication.UnicodeUTF8) if allowed else QtGui.QApplication.translate("MainWindow", 'Allow auto accept', None, QtGui.QApplication.UnicodeUTF8)
|
||||||
if item is not None:
|
if item is not None:
|
||||||
self.listMenu = QtGui.QMenu()
|
self.listMenu = QtGui.QMenu()
|
||||||
if type(friend) is Friend: # TODO: add `invite to gc` submenu
|
if type(friend) is Friend:
|
||||||
|
arr = Profile.get_instance().get_all_gc()
|
||||||
|
if arr:
|
||||||
|
gc_menu = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Invite to group chat', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
for gc in arr:
|
||||||
|
item = gc_menu.addAction(gc.name)
|
||||||
|
self.connect(item, QtCore.SIGNAL("triggered()"),
|
||||||
|
lambda: Profile.get_instance().invite_friend(gc.number, friend.number))
|
||||||
|
|
||||||
set_alias_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Set alias', None, QtGui.QApplication.UnicodeUTF8))
|
set_alias_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Set alias', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
clear_history_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Clear history', None, QtGui.QApplication.UnicodeUTF8))
|
clear_history_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Clear history', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
copy_menu = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Copy', None, QtGui.QApplication.UnicodeUTF8))
|
copy_menu = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Copy', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
@ -574,16 +582,30 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
if len(submenu):
|
if len(submenu):
|
||||||
plug = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Plugins', None, QtGui.QApplication.UnicodeUTF8))
|
plug = self.listMenu.addMenu(QtGui.QApplication.translate("MainWindow", 'Plugins', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
plug.addActions(submenu)
|
plug.addActions(submenu)
|
||||||
self.connect(set_alias_item, QtCore.SIGNAL("triggered()"), lambda: self.set_alias(num))
|
|
||||||
self.connect(remove_item, QtCore.SIGNAL("triggered()"), lambda: self.remove_friend(num))
|
self.connect(remove_item, QtCore.SIGNAL("triggered()"), lambda: self.remove_friend(num))
|
||||||
self.connect(copy_key_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_friend_key(num))
|
|
||||||
self.connect(clear_history_item, QtCore.SIGNAL("triggered()"), lambda: self.clear_history(num))
|
|
||||||
self.connect(auto_accept_item, QtCore.SIGNAL("triggered()"), lambda: self.auto_accept(num, not allowed))
|
self.connect(auto_accept_item, QtCore.SIGNAL("triggered()"), lambda: self.auto_accept(num, not allowed))
|
||||||
self.connect(notes_item, QtCore.SIGNAL("triggered()"), lambda: self.show_note(friend))
|
|
||||||
self.connect(copy_name_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_name(friend))
|
|
||||||
self.connect(copy_status_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_status(friend))
|
|
||||||
else:
|
else:
|
||||||
pass # TODO: add menu for gc
|
copy_menu = self.listMenu.addMenu(
|
||||||
|
QtGui.QApplication.translate("MainWindow", 'Copy', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
copy_name_item = copy_menu.addAction(
|
||||||
|
QtGui.QApplication.translate("MainWindow", 'Name', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
copy_status_item = copy_menu.addAction(
|
||||||
|
QtGui.QApplication.translate("MainWindow", 'Topic', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
copy_key_item = copy_menu.addAction(
|
||||||
|
QtGui.QApplication.translate("MainWindow", 'Public key', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
leave_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Leave group', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
set_alias_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Set alias', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
clear_history_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Clear history', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
notes_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Notes', None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.connect(leave_item, QtCore.SIGNAL("triggered()"), lambda: Profile.get_instance().leave_group(num))
|
||||||
|
|
||||||
|
self.connect(notes_item, QtCore.SIGNAL("triggered()"), lambda: self.show_note(friend))
|
||||||
|
self.connect(set_alias_item, QtCore.SIGNAL("triggered()"), lambda: self.set_alias(num))
|
||||||
|
self.connect(clear_history_item, QtCore.SIGNAL("triggered()"), lambda: self.clear_history(num))
|
||||||
|
self.connect(copy_name_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_name(friend))
|
||||||
|
self.connect(copy_status_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_status(friend))
|
||||||
|
self.connect(copy_key_item, QtCore.SIGNAL("triggered()"), lambda: self.copy_friend_key(num))
|
||||||
|
|
||||||
parent_position = self.friends_list.mapToGlobal(QtCore.QPoint(0, 0))
|
parent_position = self.friends_list.mapToGlobal(QtCore.QPoint(0, 0))
|
||||||
self.listMenu.move(parent_position + pos)
|
self.listMenu.move(parent_position + pos)
|
||||||
self.listMenu.show()
|
self.listMenu.show()
|
||||||
|
@ -607,7 +629,7 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
self.profile.set_alias(num)
|
self.profile.set_alias(num)
|
||||||
|
|
||||||
def remove_friend(self, num):
|
def remove_friend(self, num):
|
||||||
self.profile.delete_friend(num)
|
self.profile.delete_friend_or_gc(num)
|
||||||
|
|
||||||
def copy_friend_key(self, num):
|
def copy_friend_key(self, num):
|
||||||
tox_id = self.profile.friend_public_key(num)
|
tox_id = self.profile.friend_public_key(num)
|
||||||
|
|
|
@ -638,6 +638,7 @@ class NotificationsSettings(CenteredWidget):
|
||||||
settings['notifications'] = self.enableNotifications.isChecked()
|
settings['notifications'] = self.enableNotifications.isChecked()
|
||||||
settings['sound_notifications'] = self.soundNotifications.isChecked()
|
settings['sound_notifications'] = self.soundNotifications.isChecked()
|
||||||
settings['calls_sound'] = self.callsSound.isChecked()
|
settings['calls_sound'] = self.callsSound.isChecked()
|
||||||
|
settings['notify_all_gc'] = self.gcNotifications.isChecked()
|
||||||
settings.save()
|
settings.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,24 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
friend = Friend(i, message_getter, name, status_message, item, tox_id)
|
friend = Friend(i, message_getter, name, status_message, item, tox_id)
|
||||||
friend.set_alias(alias)
|
friend.set_alias(alias)
|
||||||
self._friends_and_gc.append(friend)
|
self._friends_and_gc.append(friend)
|
||||||
# TODO: list of gc
|
|
||||||
|
l = self._tox.group_get_number_groups()
|
||||||
|
for i in range(l): # creates list of group chats
|
||||||
|
tox_id = tox.group_get_chat_id(i)
|
||||||
|
try:
|
||||||
|
alias = list(filter(lambda x: x[0] == tox_id, aliases))[0][1]
|
||||||
|
except:
|
||||||
|
alias = ''
|
||||||
|
item = self.create_friend_item()
|
||||||
|
name = alias or tox.group_get_name(i) or tox_id
|
||||||
|
status_message = tox.group_get_topic(i)
|
||||||
|
if not self._history.friend_exists_in_db(tox_id):
|
||||||
|
self._history.add_friend_to_db(tox_id)
|
||||||
|
message_getter = self._history.messages_getter(tox_id)
|
||||||
|
gc = GroupChat(self._tox, i, message_getter, name, status_message, item, tox_id)
|
||||||
|
gc.set_alias(alias)
|
||||||
|
self._friends_and_gc.append(gc)
|
||||||
|
|
||||||
self.filtration(self._show_online)
|
self.filtration(self._show_online)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -79,6 +96,9 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
self.set_status((self._status + 1) % 3)
|
self.set_status((self._status + 1) % 3)
|
||||||
|
|
||||||
def set_status(self, status):
|
def set_status(self, status):
|
||||||
|
if self.status is None:
|
||||||
|
for gc in filter(lambda x: type(x) is GroupChat, self._friends_and_gc):
|
||||||
|
self._tox.group_reconnect(gc.number)
|
||||||
super(Profile, self).set_status(status)
|
super(Profile, self).set_status(status)
|
||||||
if status is not None:
|
if status is not None:
|
||||||
self._tox.self_set_status(status)
|
self._tox.self_set_status(status)
|
||||||
|
@ -233,7 +253,10 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
self._screen.account_status.setText(friend_or_gc.status_message)
|
self._screen.account_status.setText(friend_or_gc.status_message)
|
||||||
avatar_path = (ProfileHelper.get_path() + 'avatars/{}.png').format(friend_or_gc.tox_id[:TOX_PUBLIC_KEY_SIZE * 2])
|
avatar_path = (ProfileHelper.get_path() + 'avatars/{}.png').format(friend_or_gc.tox_id[:TOX_PUBLIC_KEY_SIZE * 2])
|
||||||
if not os.path.isfile(avatar_path): # load default image
|
if not os.path.isfile(avatar_path): # load default image
|
||||||
avatar_path = curr_directory() + '/images/avatar.png'
|
if type(friend_or_gc) is Friend:
|
||||||
|
avatar_path = curr_directory() + '/images/avatar.png'
|
||||||
|
else:
|
||||||
|
avatar_path = curr_directory() + '/images/group.png'
|
||||||
os.chdir(os.path.dirname(avatar_path))
|
os.chdir(os.path.dirname(avatar_path))
|
||||||
pixmap = QtGui.QPixmap(QtCore.QSize(64, 64))
|
pixmap = QtGui.QPixmap(QtCore.QSize(64, 64))
|
||||||
pixmap.load(avatar_path)
|
pixmap.load(avatar_path)
|
||||||
|
@ -394,24 +417,28 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
:param is_group: is group chat message or not
|
:param is_group: is group chat message or not
|
||||||
:param peer_id: if gc - peer id
|
:param peer_id: if gc - peer id
|
||||||
"""
|
"""
|
||||||
|
t = time.time()
|
||||||
|
active = False
|
||||||
if num == self.get_active_number() and is_group != self.is_active_a_friend(): # add message to list
|
if num == self.get_active_number() and is_group != self.is_active_a_friend(): # add message to list
|
||||||
t = time.time()
|
if not is_group:
|
||||||
self.create_message_item(message, t, MESSAGE_OWNER['FRIEND'], message_type)
|
self.create_message_item(message, t, MESSAGE_OWNER['FRIEND'], message_type)
|
||||||
self._messages.scrollToBottom()
|
|
||||||
self._friends_and_gc[self._active_friend_or_gc].append_message(
|
|
||||||
TextMessage(message, MESSAGE_OWNER['FRIEND'], t, message_type))
|
|
||||||
else:
|
|
||||||
if is_group:
|
|
||||||
friend_or_gc = self.get_gc_by_number(num)
|
|
||||||
friend_or_gc.append_message(GroupChatTextMessage(self._tox.group_peer_get_name(num, peer_id),
|
|
||||||
message, MESSAGE_OWNER['FRIEND'],
|
|
||||||
time.time(), message_type))
|
|
||||||
else:
|
else:
|
||||||
friend_or_gc = self.get_friend_by_number(num)
|
self.create_message_item(message, t, MESSAGE_OWNER['FRIEND'], message_type, True,
|
||||||
friend_or_gc.inc_messages()
|
self._tox.group_peer_get_name(num, peer_id))
|
||||||
friend_or_gc.append_message(TextMessage(message, MESSAGE_OWNER['FRIEND'], time.time(), message_type))
|
self._messages.scrollToBottom()
|
||||||
if not friend_or_gc.visibility:
|
active = True
|
||||||
self.update_filtration()
|
if is_group:
|
||||||
|
friend_or_gc = self.get_gc_by_number(num)
|
||||||
|
friend_or_gc.append_message(GroupChatTextMessage(self._tox.group_peer_get_name(num, peer_id),
|
||||||
|
message, MESSAGE_OWNER['FRIEND'],
|
||||||
|
time.time(), message_type))
|
||||||
|
else:
|
||||||
|
friend_or_gc = self.get_friend_by_number(num)
|
||||||
|
friend_or_gc.append_message(TextMessage(message, MESSAGE_OWNER['FRIEND'], time.time(), message_type))
|
||||||
|
if not active:
|
||||||
|
friend_or_gc.inc_messages()
|
||||||
|
if not friend_or_gc.visibility:
|
||||||
|
self.update_filtration()
|
||||||
|
|
||||||
def send_message(self, text, number=None, is_gc=False):
|
def send_message(self, text, number=None, is_gc=False):
|
||||||
"""
|
"""
|
||||||
|
@ -473,6 +500,7 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
Save history to db
|
Save history to db
|
||||||
"""
|
"""
|
||||||
s = Settings.get_instance()
|
s = Settings.get_instance()
|
||||||
|
# TODO: different saving for friends and gc
|
||||||
if hasattr(self, '_history'):
|
if hasattr(self, '_history'):
|
||||||
if s['save_history']:
|
if s['save_history']:
|
||||||
for friend_or_gc in self._friends_and_gc:
|
for friend_or_gc in self._friends_and_gc:
|
||||||
|
@ -674,10 +702,12 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
def friend_public_key(self, num):
|
def friend_public_key(self, num):
|
||||||
return self._friends_and_gc[num].tox_id
|
return self._friends_and_gc[num].tox_id
|
||||||
|
|
||||||
def delete_friend(self, num):
|
def delete_friend_or_gc(self, num, is_gc=False, message=None):
|
||||||
"""
|
"""
|
||||||
Removes friend from contact list
|
Removes friend or gc from contact list
|
||||||
:param num: number of friend in list
|
:param num: number of friend or gc in list
|
||||||
|
:param is_gc: is a group chat
|
||||||
|
:param message: message in gc
|
||||||
"""
|
"""
|
||||||
friend = self._friends_and_gc[num]
|
friend = self._friends_and_gc[num]
|
||||||
settings = Settings.get_instance()
|
settings = Settings.get_instance()
|
||||||
|
@ -692,11 +722,14 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
self.clear_history(num)
|
self.clear_history(num)
|
||||||
if self._history.friend_exists_in_db(friend.tox_id):
|
if self._history.friend_exists_in_db(friend.tox_id):
|
||||||
self._history.delete_friend_from_db(friend.tox_id)
|
self._history.delete_friend_from_db(friend.tox_id)
|
||||||
self._tox.friend_delete(friend.number)
|
if not is_gc:
|
||||||
|
self._tox.friend_delete(friend.number)
|
||||||
|
else:
|
||||||
|
self._tox.group_leave(friend.number, message.encode('utf-8') if message is not None else None)
|
||||||
del self._friends_and_gc[num]
|
del self._friends_and_gc[num]
|
||||||
self._screen.friends_list.takeItem(num)
|
self._screen.friends_list.takeItem(num)
|
||||||
if num == self._active_friend_or_gc: # active friend was deleted
|
if num == self._active_friend_or_gc: # active friend or gc was deleted
|
||||||
if not len(self._friends_and_gc): # last friend was deleted
|
if not len(self._friends_and_gc): # last contact was deleted
|
||||||
self.set_active(-1)
|
self.set_active(-1)
|
||||||
else:
|
else:
|
||||||
self.set_active(0)
|
self.set_active(0)
|
||||||
|
@ -732,7 +765,7 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
settings.save()
|
settings.save()
|
||||||
try:
|
try:
|
||||||
num = self._tox.friend_by_public_key(tox_id)
|
num = self._tox.friend_by_public_key(tox_id)
|
||||||
self.delete_friend(num)
|
self.delete_friend_or_gc(num)
|
||||||
data = self._tox.get_savedata()
|
data = self._tox.get_savedata()
|
||||||
ProfileHelper.get_instance().save_profile(data)
|
ProfileHelper.get_instance().save_profile(data)
|
||||||
except: # not in friend list
|
except: # not in friend list
|
||||||
|
@ -1155,6 +1188,8 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
|
|
||||||
def call_click(self, audio=True, video=False):
|
def call_click(self, audio=True, video=False):
|
||||||
"""User clicked audio button in main window"""
|
"""User clicked audio button in main window"""
|
||||||
|
if not self.is_active_a_friend():
|
||||||
|
return
|
||||||
num = self.get_active_number()
|
num = self.get_active_number()
|
||||||
if num not in self._call and self.is_active_online(): # start call
|
if num not in self._call and self.is_active_online(): # start call
|
||||||
self._call(num, audio, video)
|
self._call(num, audio, video)
|
||||||
|
@ -1228,10 +1263,16 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
# Group chats support
|
# Group chats support
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def get_all_gc(self):
|
||||||
|
return list(filter(lambda x: type(x) is GroupChat, self._friends_and_gc))
|
||||||
|
|
||||||
def add_gc(self, num):
|
def add_gc(self, num):
|
||||||
tox_id = self._tox.group_get_chat_id(num)
|
try:
|
||||||
name = self._tox.group_get_name(num)
|
tox_id = self._tox.group_get_chat_id(num)
|
||||||
topic = self._tox.group_get_topic(num)
|
name = self._tox.group_get_name(num)
|
||||||
|
topic = self._tox.group_get_topic(num)
|
||||||
|
except:
|
||||||
|
tox_id = name = topic = ''
|
||||||
item = self.create_friend_item()
|
item = self.create_friend_item()
|
||||||
try:
|
try:
|
||||||
if not self._history.friend_exists_in_db(tox_id):
|
if not self._history.friend_exists_in_db(tox_id):
|
||||||
|
@ -1256,6 +1297,7 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
if password:
|
if password:
|
||||||
self._tox.group_founder_set_password(num, bytes(password, 'utf-8'))
|
self._tox.group_founder_set_password(num, bytes(password, 'utf-8'))
|
||||||
self.add_gc(num)
|
self.add_gc(num)
|
||||||
|
self.get_gc_by_number(num).set_status(TOX_USER_STATUS['NONE'])
|
||||||
|
|
||||||
def process_group_invite(self, friend_num, data):
|
def process_group_invite(self, friend_num, data):
|
||||||
# TODO: support password
|
# TODO: support password
|
||||||
|
@ -1266,9 +1308,10 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
fr_req = QtGui.QApplication.translate('MainWindow', 'Group chat invite', None, QtGui.QApplication.UnicodeUTF8)
|
fr_req = QtGui.QApplication.translate('MainWindow', 'Group chat invite', None, QtGui.QApplication.UnicodeUTF8)
|
||||||
reply = QtGui.QMessageBox.question(None, fr_req, info, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
reply = QtGui.QMessageBox.question(None, fr_req, info, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
||||||
if reply == QtGui.QMessageBox.Yes: # accepted
|
if reply == QtGui.QMessageBox.Yes: # accepted
|
||||||
num = self._tox.group_invite_accept(data)
|
num = self._tox.group_invite_accept(data, friend_num)
|
||||||
data = self._tox.get_savedata()
|
data = self._tox.get_savedata()
|
||||||
ProfileHelper.get_instance().save_profile(data)
|
ProfileHelper.get_instance().save_profile(data)
|
||||||
|
print('In gc invite', num)
|
||||||
self.add_gc(num)
|
self.add_gc(num)
|
||||||
elif reply != QtGui.QMessageBox.No:
|
elif reply != QtGui.QMessageBox.No:
|
||||||
if friend_num in self._gc_invites:
|
if friend_num in self._gc_invites:
|
||||||
|
@ -1278,6 +1321,12 @@ class Profile(basecontact.BaseContact, Singleton):
|
||||||
except Exception as ex: # something is wrong
|
except Exception as ex: # something is wrong
|
||||||
log('Accept group chat invite failed! ' + str(ex))
|
log('Accept group chat invite failed! ' + str(ex))
|
||||||
|
|
||||||
|
def invite_friend(self, group_number, friend_number):
|
||||||
|
self._tox.group_invite_friend(group_number, friend_number)
|
||||||
|
|
||||||
|
def leave_group(self, num, message=None):
|
||||||
|
self.delete_friend_or_gc(num, True, message)
|
||||||
|
|
||||||
|
|
||||||
def tox_factory(data=None, settings=None):
|
def tox_factory(data=None, settings=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1549,9 +1549,7 @@ class Tox:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
error = c_int()
|
error = c_int()
|
||||||
func = Tox.libtoxcore.tox_group_new
|
result = Tox.libtoxcore.tox_group_new(self._tox_pointer, privacy_state, group_name,
|
||||||
func.restype = c_uint32
|
|
||||||
result = func(self._tox_pointer, privacy_state, group_name,
|
|
||||||
len(group_name), byref(error))
|
len(group_name), byref(error))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -1570,7 +1568,7 @@ class Tox:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
error = c_int()
|
error = c_int()
|
||||||
result = Tox.libtoxcore.tox_group_join(self._tox_pointer, chat_id,
|
result = Tox.libtoxcore.tox_group_join(self._tox_pointer, string_to_bin(chat_id),
|
||||||
password,
|
password,
|
||||||
len(password) if password is not None else 0,
|
len(password) if password is not None else 0,
|
||||||
byref(error))
|
byref(error))
|
||||||
|
@ -1607,7 +1605,10 @@ class Tox:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
error = c_int()
|
error = c_int()
|
||||||
result = Tox.libtoxcore.tox_group_leave(self._tox_pointer, groupnumber, message, len(message), byref(error))
|
f = Tox.libtoxcore.tox_group_leave
|
||||||
|
f.restype = c_bool
|
||||||
|
result = f(self._tox_pointer, groupnumber, message,
|
||||||
|
len(message) if message is not None else 0, byref(error))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1964,7 +1965,7 @@ class Tox:
|
||||||
|
|
||||||
see the `Group chat founder controls` section for the respective set function.
|
see the `Group chat founder controls` section for the respective set function.
|
||||||
|
|
||||||
:return true on success.
|
:return password
|
||||||
"""
|
"""
|
||||||
|
|
||||||
error = c_int()
|
error = c_int()
|
||||||
|
@ -2153,7 +2154,7 @@ class Tox:
|
||||||
result = Tox.libtoxcore.tox_group_invite_friend(self._tox_pointer, groupnumber, friend_number, byref(error))
|
result = Tox.libtoxcore.tox_group_invite_friend(self._tox_pointer, groupnumber, friend_number, byref(error))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def group_invite_accept(self, invite_data, password=None):
|
def group_invite_accept(self, invite_data, friend_number, password=None):
|
||||||
"""
|
"""
|
||||||
Accept an invite to a group chat that the client previously received from a friend. The invite
|
Accept an invite to a group chat that the client previously received from a friend. The invite
|
||||||
is only valid while the inviter is present in the group.
|
is only valid while the inviter is present in the group.
|
||||||
|
@ -2164,10 +2165,11 @@ class Tox:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
error = c_int()
|
error = c_int()
|
||||||
result = Tox.libtoxcore.tox_group_invite_accept(self._tox_pointer, invite_data, len(invite_data),
|
f = Tox.libtoxcore.tox_group_invite_accept
|
||||||
password,
|
f.restype = c_uint32
|
||||||
len(password) if password is not None else 0,
|
result = f(self._tox_pointer, friend_number, invite_data, len(invite_data), password,
|
||||||
byref(error))
|
len(password) if password is not None else 0, byref(error))
|
||||||
|
print('Invite accept. Result:', result, 'Error:', error.value)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def callback_group_invite(self, callback, user_data):
|
def callback_group_invite(self, callback, user_data):
|
||||||
|
@ -2185,7 +2187,7 @@ class Tox:
|
||||||
user_data - user data
|
user_data - user data
|
||||||
"""
|
"""
|
||||||
|
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_char_p, c_size_t, c_void_p)
|
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, POINTER(c_uint8), c_size_t, c_void_p)
|
||||||
self.group_invite_cb = c_callback(callback)
|
self.group_invite_cb = c_callback(callback)
|
||||||
Tox.libtoxcore.tox_callback_group_invite(self._tox_pointer, self.group_invite_cb, user_data)
|
Tox.libtoxcore.tox_callback_group_invite(self._tox_pointer, self.group_invite_cb, user_data)
|
||||||
|
|
||||||
|
@ -2194,6 +2196,11 @@ class Tox:
|
||||||
Set the callback for the `group_peer_join` event. Pass NULL to unset.
|
Set the callback for the `group_peer_join` event. Pass NULL to unset.
|
||||||
|
|
||||||
This event is triggered when a peer other than self joins the group.
|
This event is triggered when a peer other than self joins the group.
|
||||||
|
Callback: python function with params:
|
||||||
|
tox - Tox*
|
||||||
|
group_number - group number
|
||||||
|
peer_id - peer id
|
||||||
|
user_data - user data
|
||||||
"""
|
"""
|
||||||
|
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_void_p)
|
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_void_p)
|
||||||
|
@ -2217,6 +2224,10 @@ class Tox:
|
||||||
|
|
||||||
This event is triggered when the client has successfully joined a group. Use this to initialize
|
This event is triggered when the client has successfully joined a group. Use this to initialize
|
||||||
any group information the client may need.
|
any group information the client may need.
|
||||||
|
Callback: python fucntion with params:
|
||||||
|
tox - *Tox
|
||||||
|
group_number - group number
|
||||||
|
user_data - user data
|
||||||
"""
|
"""
|
||||||
|
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_void_p)
|
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_void_p)
|
||||||
|
|
Loading…
Reference in a new issue