diff --git a/src/core/core.cpp b/src/core/core.cpp index eb2cbd7b3..deb9174b1 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -320,7 +320,12 @@ void Core::start(const QByteArray& savedata) tox_callback_friend_read_receipt(tox, onReadReceiptCallback); tox_callback_conference_invite(tox, onGroupInvite); tox_callback_conference_message(tox, onGroupMessage); +#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) + tox_callback_conference_peer_list_changed(tox, onGroupPeerListChange); + tox_callback_conference_peer_name(tox, onGroupPeerNameChange); +#else tox_callback_conference_namelist_change(tox, onGroupNamelistChange); +#endif tox_callback_conference_title(tox, onGroupTitleChange); tox_callback_file_chunk_request(tox, CoreFile::onFileDataCallback); tox_callback_file_recv(tox, CoreFile::onFileReceiveCallback); @@ -546,15 +551,33 @@ void Core::onGroupMessage(Tox*, uint32_t groupId, uint32_t peerId, TOX_MESSAGE_T emit core->groupMessageReceived(groupId, peerId, message, isAction); } +#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) +void Core::onGroupPeerListChange(Tox*, uint32_t groupId, void* core) +{ + const auto coreAv = static_cast(core)->getAv(); + if (coreAv->isGroupAvEnabled(groupId)) { + CoreAV::invalidateGroupCallSources(groupId); + } + + qDebug() << QString("Group %1 peerlist changed").arg(groupId); + emit static_cast(core)->groupPeerlistChanged(groupId); +} + +void Core::onGroupPeerNameChange(Tox*, uint32_t groupId, uint32_t peerId, + const uint8_t* name, size_t length, void* core) +{ + const auto newName = ToxString(name, length).getQString(); + qDebug() << QString("Group %1, Peer %2, name changed to %3").arg(groupId).arg(peerId).arg(newName); + emit static_cast(core)->groupPeerNameChanged(groupId, peerId, newName); +} + +#else +// for toxcore < 0.2.0, aka old groups void Core::onGroupNamelistChange(Tox*, uint32_t groupId, uint32_t peerId, TOX_CONFERENCE_STATE_CHANGE change, void* core) { CoreAV* coreAv = static_cast(core)->getAv(); -#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) - const auto changed = change == TOX_CONFERENCE_STATE_CHANGE_LIST_CHANGED; -#else const auto changed = change == TOX_CONFERENCE_STATE_CHANGE_PEER_EXIT; -#endif if (changed && coreAv->isGroupAvEnabled(groupId)) { CoreAV::invalidateGroupCallPeerSource(groupId, peerId); } @@ -562,6 +585,7 @@ void Core::onGroupNamelistChange(Tox*, uint32_t groupId, uint32_t peerId, qDebug() << QString("Group namelist change %1:%2 %3").arg(groupId).arg(peerId).arg(change); emit static_cast(core)->groupNamelistChanged(groupId, peerId, change); } +#endif void Core::onGroupTitleChange(Tox*, uint32_t groupId, uint32_t peerId, const uint8_t* cTitle, size_t length, void* vCore) diff --git a/src/core/core.h b/src/core/core.h index ef4747f08..38603399a 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -146,6 +146,8 @@ signals: void groupInviteReceived(const GroupInvite& inviteInfo); void groupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction); void groupNamelistChanged(int groupnumber, int peernumber, uint8_t change); + void groupPeerlistChanged(int groupnumber); + void groupPeerNameChanged(int groupnumber, int peernumber, const QString& newName); void groupTitleChanged(int groupnumber, const QString& author, const QString& title); void groupPeerAudioPlaying(int groupnumber, int peernumber); @@ -203,8 +205,14 @@ private: const uint8_t* cookie, size_t length, void* vCore); static void onGroupMessage(Tox* tox, uint32_t groupId, uint32_t peerId, TOX_MESSAGE_TYPE type, const uint8_t* cMessage, size_t length, void* vCore); +#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) + static void onGroupPeerListChange(Tox*, uint32_t groupId, void* core); + static void onGroupPeerNameChange(Tox*, uint32_t groupId, uint32_t peerId, + const uint8_t* name, size_t length, void* core); +#else static void onGroupNamelistChange(Tox* tox, uint32_t groupId, uint32_t peerId, TOX_CONFERENCE_STATE_CHANGE change, void* core); +#endif static void onGroupTitleChange(Tox* tox, uint32_t groupId, uint32_t peerId, const uint8_t* cTitle, size_t length, void* vCore); static void onReadReceiptCallback(Tox* tox, uint32_t friendId, uint32_t receipt, void* core); diff --git a/src/core/coreav.cpp b/src/core/coreav.cpp index 66c823821..e81728170 100644 --- a/src/core/coreav.cpp +++ b/src/core/coreav.cpp @@ -461,6 +461,36 @@ void CoreAV::toggleMuteCallOutput(const Friend* f) * @param[in] sample_rate the audio sample rate * @param[in] core the qTox Core class */ +#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) +void CoreAV::groupCallCallback(void* tox, uint32_t group, uint32_t peer, const int16_t* data, + unsigned samples, uint8_t channels, uint32_t sample_rate, void* core) +{ + Q_UNUSED(tox); + + Core* c = static_cast(core); + CoreAV* cav = c->getAv(); + + if (cav->groupCalls.find(group) == cav->groupCalls.end()) { + return; + } + + ToxGroupCall& call = cav->groupCalls[group]; + + emit c->groupPeerAudioPlaying(group, peer); + + if (call.getMuteVol() || !call.isActive()) { + return; + } + + Audio& audio = Audio::getInstance(); + if (!call.getPeers()[peer]) { + // FIXME: 0 is a valid sourceId, we shouldn't necessarily re-subscribe just because we have 0 + audio.subscribeOutput(call.getPeers()[peer]); + } + + audio.playAudioBuffer(call.getPeers()[peer], data, samples, channels, sample_rate); +} +#else void CoreAV::groupCallCallback(void* tox, int group, int peer, const int16_t* data, unsigned samples, uint8_t channels, unsigned sample_rate, void* core) { @@ -489,6 +519,7 @@ void CoreAV::groupCallCallback(void* tox, int group, int peer, const int16_t* da audio.playAudioBuffer(call.getPeers()[peer], data, samples, channels, sample_rate); } +#endif /** * @brief Called from core to make sure the source for that peer is invalidated when they leave. @@ -502,6 +533,16 @@ void CoreAV::invalidateGroupCallPeerSource(int group, int peer) groupCalls[group].getPeers()[peer] = 0; } +/** + * @brief Called from core to make sure the sources for that group are invalidated when + * the peer list changes. + * @param group Group Index + */ +void CoreAV::invalidateGroupCallSources(int group) +{ + groupCalls.erase(group); +} + /** * @brief Get a call's video source. * @param friendNum Id of friend in call list. diff --git a/src/core/coreav.h b/src/core/coreav.h index 894d0d0ff..a8dbd5944 100644 --- a/src/core/coreav.h +++ b/src/core/coreav.h @@ -25,6 +25,7 @@ #include #include #include +#include // for TOX_VERSION_IS_API_COMPATIBLE macro #include class Friend; @@ -76,10 +77,15 @@ public: bool isCallOutputMuted(const Friend* f) const; void toggleMuteCallInput(const Friend* f); void toggleMuteCallOutput(const Friend* f); - +#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) + static void groupCallCallback(void* tox, uint32_t group, uint32_t peer, const int16_t* data, unsigned samples, + uint8_t channels, uint32_t sample_rate, void* core); +#else static void groupCallCallback(void* tox, int group, int peer, const int16_t* data, unsigned samples, uint8_t channels, unsigned sample_rate, void* core); +#endif static void invalidateGroupCallPeerSource(int group, int peer); + static void invalidateGroupCallSources(int group); public slots: bool startCall(uint32_t friendNum, bool video); diff --git a/src/nexus.cpp b/src/nexus.cpp index c6e10cb82..d90d8d11f 100644 --- a/src/nexus.cpp +++ b/src/nexus.cpp @@ -209,7 +209,9 @@ void Nexus::showMainGUI() connect(core, &Core::friendMessageReceived, widget, &Widget::onFriendMessageReceived); connect(core, &Core::groupInviteReceived, widget, &Widget::onGroupInviteReceived); connect(core, &Core::groupMessageReceived, widget, &Widget::onGroupMessageReceived); - connect(core, &Core::groupNamelistChanged, widget, &Widget::onGroupNamelistChanged); + connect(core, &Core::groupNamelistChanged, widget, &Widget::onGroupNamelistChangedOld); // TODO(sudden6): toxcore < 0.2.0, remove + connect(core, &Core::groupPeerlistChanged, widget, &Widget::onGroupPeerlistChanged); + connect(core, &Core::groupPeerNameChanged, widget, &Widget::onGroupPeerNameChanged); connect(core, &Core::groupTitleChanged, widget, &Widget::onGroupTitleChanged); connect(core, &Core::groupPeerAudioPlaying, widget, &Widget::onGroupPeerAudioPlaying); connect(core, &Core::emptyGroupCreated, widget, &Widget::onEmptyGroupCreated); diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 44900b76e..3593d6ddf 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -1736,8 +1736,48 @@ void Widget::onGroupMessageReceived(int groupnumber, int peernumber, const QStri newGroupMessageAlert(groupId, targeted || Settings::getInstance().getGroupAlwaysNotify()); } -void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Change) +void Widget::onGroupPeerlistChanged(int groupnumber) { +#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) + Group* g = GroupList::findGroup(groupnumber); + if (!g) { + qDebug() << "onGroupNamelistChanged: Group " << groupnumber << " not found, creating it"; + g = createGroup(groupnumber); + if (!g) { + return; + } + } + g->regeneratePeerList(); +#endif +} + +void Widget::onGroupPeerNameChanged(int groupnumber, int peernumber, const QString& newName) +{ +#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) + Group* g = GroupList::findGroup(groupnumber); + if (!g) { + qDebug() << "onGroupNamelistChanged: Group " << groupnumber << " not found, creating it"; + g = createGroup(groupnumber); + if (!g) { + return; + } + } + + QString setName = newName; + if (newName.isEmpty()) { + setName = tr("", "Placeholder when someone's name in a group chat is empty"); + } + + g->updatePeer(peernumber, setName); +#endif +} + +/** + * @deprecated Remove after dropping support for toxcore 0.1.x + */ +void Widget::onGroupNamelistChangedOld(int groupnumber, int peernumber, uint8_t Change) +{ +#if !(TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0)) Group* g = GroupList::findGroup(groupnumber); if (!g) { qDebug() << "onGroupNamelistChanged: Group " << groupnumber << " not found, creating it"; @@ -1748,15 +1788,10 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha } TOX_CONFERENCE_STATE_CHANGE change = static_cast(Change); -#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) - if (change == TOX_CONFERENCE_STATE_CHANGE_LIST_CHANGED) { - g->regeneratePeerList(); -#else if (change == TOX_CONFERENCE_STATE_CHANGE_PEER_JOIN) { g->regeneratePeerList(); } else if (change == TOX_CONFERENCE_STATE_CHANGE_PEER_EXIT) { g->regeneratePeerList(); -#endif } else if (change == TOX_CONFERENCE_STATE_CHANGE_PEER_NAME_CHANGE) // core overwrites old name // before telling us it // changed... @@ -1767,6 +1802,7 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha g->updatePeer(peernumber, name); } +#endif } void Widget::onGroupTitleChanged(int groupnumber, const QString& author, const QString& title) diff --git a/src/widget/widget.h b/src/widget/widget.h index 3a87bfc16..81d8e99e8 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -168,7 +168,9 @@ public slots: void onGroupInviteReceived(const GroupInvite& inviteInfo); void onGroupInviteAccepted(const GroupInvite& inviteInfo); void onGroupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction); - void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change); + void onGroupNamelistChangedOld(int groupnumber, int peernumber, uint8_t change); + void onGroupPeerlistChanged(int groupnumber); + void onGroupPeerNameChanged(int groupnumber, int peernumber, const QString& newName); void onGroupTitleChanged(int groupnumber, const QString& author, const QString& title); void onGroupPeerAudioPlaying(int groupnumber, int peernumber); void onGroupSendFailed(int groupId);