Browse Source

feat(groups): Allow being in group call if only member

In other applications chatrooms allow you to idle in a call and have
people hop in and out as desired. If a user is the only one presently
online in a group but knows someone will be joining shortly they should
be able to join the call ahead of time.
reviewable/pr5982/r2
Mick Sayson 6 years ago
parent
commit
46d57c6864
  1. 8
      src/core/coreav.cpp
  2. 2
      src/core/coreav.h
  3. 15
      src/core/toxcall.cpp
  4. 5
      src/core/toxcall.h
  5. 25
      src/widget/form/groupchatform.cpp
  6. 1
      src/widget/form/groupchatform.h

8
src/core/coreav.cpp

@ -535,17 +535,17 @@ VideoSource* CoreAV::getVideoSourceFromCall(int friendNum) const
* @note Call from the GUI thread. * @note Call from the GUI thread.
* @param groupId Id of group to join * @param groupId Id of group to join
*/ */
void CoreAV::joinGroupCall(int groupId) void CoreAV::joinGroupCall(const Group& group)
{ {
QWriteLocker locker{&callsLock}; QWriteLocker locker{&callsLock};
qDebug() << QString("Joining group call %1").arg(groupId); qDebug() << QString("Joining group call %1").arg(group.getId());
// Audio backend must be set before starting a call // Audio backend must be set before starting a call
assert(audio != nullptr); assert(audio != nullptr);
ToxGroupCallPtr groupcall = ToxGroupCallPtr(new ToxGroupCall{groupId, *this, *audio}); ToxGroupCallPtr groupcall = ToxGroupCallPtr(new ToxGroupCall{group, *this, *audio});
assert(groupcall != nullptr); assert(groupcall != nullptr);
auto ret = groupCalls.emplace(groupId, std::move(groupcall)); auto ret = groupCalls.emplace(group.getId(), std::move(groupcall));
if (ret.second == false) { if (ret.second == false) {
qWarning() << "This group call already exists, not joining!"; qWarning() << "This group call already exists, not joining!";
return; return;

2
src/core/coreav.h

@ -68,7 +68,7 @@ public:
VideoSource* getVideoSourceFromCall(int callNumber) const; VideoSource* getVideoSourceFromCall(int callNumber) const;
void sendNoVideo(); void sendNoVideo();
void joinGroupCall(int groupNum); void joinGroupCall(const Group& group);
void leaveGroupCall(int groupNum); void leaveGroupCall(int groupNum);
void muteCallInput(const Group* g, bool mute); void muteCallInput(const Group* g, bool mute);
void muteCallOutput(const Group* g, bool mute); void muteCallOutput(const Group* g, bool mute);

15
src/core/toxcall.cpp

@ -23,6 +23,7 @@
#include "src/persistence/settings.h" #include "src/persistence/settings.h"
#include "src/video/camerasource.h" #include "src/video/camerasource.h"
#include "src/video/corevideosource.h" #include "src/video/corevideosource.h"
#include "src/model/group.h"
#include <QTimer> #include <QTimer>
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
@ -205,15 +206,18 @@ void ToxFriendCall::playAudioBuffer(const int16_t* data, int samples, unsigned c
} }
} }
ToxGroupCall::ToxGroupCall(int GroupNum, CoreAV& av, IAudioControl& audio) ToxGroupCall::ToxGroupCall(const Group& group, CoreAV& av, IAudioControl& audio)
: ToxCall(false, av, audio) : ToxCall(false, av, audio)
, groupId{GroupNum} , group{group}
{ {
// register audio // register audio
audioInConn = audioInConn =
QObject::connect(audioSource.get(), &IAudioSource::frameAvailable, QObject::connect(audioSource.get(), &IAudioSource::frameAvailable,
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) { [this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
this->av->sendGroupCallAudio(this->groupId, pcm, samples, chans, rate); if (this->group.getPeersCount() <= 1)
return;
this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate);
}); });
if (!audioInConn) { if (!audioInConn) {
@ -237,7 +241,10 @@ void ToxGroupCall::onAudioSourceInvalidated()
audioInConn = audioInConn =
QObject::connect(audioSource.get(), &IAudioSource::frameAvailable, QObject::connect(audioSource.get(), &IAudioSource::frameAvailable,
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) { [this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
this->av->sendGroupCallAudio(this->groupId, pcm, samples, chans, rate); if (this->group.getPeersCount() <= 1)
return;
this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate);
}); });
audioSource = std::move(newSrc); audioSource = std::move(newSrc);

5
src/core/toxcall.h

@ -37,6 +37,7 @@ class QTimer;
class AudioFilterer; class AudioFilterer;
class CoreVideoSource; class CoreVideoSource;
class CoreAV; class CoreAV;
class Group;
class ToxCall : public QObject class ToxCall : public QObject
{ {
@ -117,7 +118,7 @@ class ToxGroupCall : public ToxCall
{ {
public: public:
ToxGroupCall() = delete; ToxGroupCall() = delete;
ToxGroupCall(int GroupNum, CoreAV& av, IAudioControl& audio); ToxGroupCall(const Group& group, CoreAV& av, IAudioControl& audio);
ToxGroupCall(ToxGroupCall&& other) = delete; ToxGroupCall(ToxGroupCall&& other) = delete;
~ToxGroupCall(); ~ToxGroupCall();
@ -134,7 +135,7 @@ private:
std::map<ToxPk, std::unique_ptr<IAudioSink>> peers; std::map<ToxPk, std::unique_ptr<IAudioSink>> peers;
std::map<ToxPk, QMetaObject::Connection> sinkInvalid; std::map<ToxPk, QMetaObject::Connection> sinkInvalid;
int groupId; const Group& group;
void onAudioSourceInvalidated(); void onAudioSourceInvalidated();
void onAudioSinkInvalidated(ToxPk peerId); void onAudioSinkInvalidated(ToxPk peerId);

25
src/widget/form/groupchatform.cpp

@ -325,18 +325,14 @@ void GroupChatForm::onVolMuteToggle()
void GroupChatForm::onCallClicked() void GroupChatForm::onCallClicked()
{ {
CoreAV* av = Core::getInstance()->getAv(); CoreAV* av = Core::getInstance()->getAv();
if (!inCall) { if (!inCall) {
av->joinGroupCall(group->getId()); joinGroupCall();
audioInputFlag = true;
audioOutputFlag = true;
inCall = true;
} else { } else {
leaveGroupCall(); leaveGroupCall();
} }
const int peersCount = group->getPeersCount(); headWidget->updateCallButtons(true, inCall);
const bool online = peersCount > 1;
headWidget->updateCallButtons(online, inCall);
const bool inMute = av->isGroupCallInputMuted(group); const bool inMute = av->isGroupCallInputMuted(group);
headWidget->updateMuteMicButton(inCall, inMute); headWidget->updateMuteMicButton(inCall, inMute);
@ -373,11 +369,7 @@ void GroupChatForm::keyReleaseEvent(QKeyEvent* ev)
void GroupChatForm::updateUserCount(int numPeers) void GroupChatForm::updateUserCount(int numPeers)
{ {
nusersLabel->setText(tr("%n user(s) in chat", "Number of users in chat", numPeers)); nusersLabel->setText(tr("%n user(s) in chat", "Number of users in chat", numPeers));
const bool online = numPeers > 1; headWidget->updateCallButtons(true, inCall);
headWidget->updateCallButtons(online, inCall);
if (inCall && (!online || !group->isAvGroupchat())) {
leaveGroupCall();
}
} }
void GroupChatForm::retranslateUi() void GroupChatForm::retranslateUi()
@ -442,6 +434,15 @@ void GroupChatForm::onLabelContextMenuRequested(const QPoint& localPos)
} }
} }
void GroupChatForm::joinGroupCall()
{
CoreAV* av = Core::getInstance()->getAv();
av->joinGroupCall(*group);
audioInputFlag = true;
audioOutputFlag = true;
inCall = true;
}
void GroupChatForm::leaveGroupCall() void GroupChatForm::leaveGroupCall()
{ {
CoreAV* av = Core::getInstance()->getAv(); CoreAV* av = Core::getInstance()->getAv();

1
src/widget/form/groupchatform.h

@ -67,6 +67,7 @@ private:
void retranslateUi(); void retranslateUi();
void updateUserCount(int numPeers); void updateUserCount(int numPeers);
void updateUserNames(); void updateUserNames();
void joinGroupCall();
void leaveGroupCall(); void leaveGroupCall();
private: private:

Loading…
Cancel
Save