mirror of https://github.com/qTox/qTox.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
6.0 KiB
211 lines
6.0 KiB
/* |
|
Copyright © 2014-2018 by The qTox Project Contributors |
|
|
|
This file is part of qTox, a Qt-based graphical interface for Tox. |
|
|
|
qTox is libre software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
qTox is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with qTox. If not, see <http://www.gnu.org/licenses/>. |
|
*/ |
|
|
|
#include "group.h" |
|
#include "friend.h" |
|
#include "src/core/contactid.h" |
|
#include "src/core/core.h" |
|
#include "src/core/coreav.h" |
|
#include "src/core/groupid.h" |
|
#include "src/core/toxpk.h" |
|
#include "src/friendlist.h" |
|
#include "src/persistence/settings.h" |
|
#include "src/widget/form/groupchatform.h" |
|
#include "src/widget/groupwidget.h" |
|
#include <QDebug> |
|
|
|
static const int MAX_GROUP_TITLE_LENGTH = 128; |
|
|
|
Group::Group(int groupId, const GroupId persistentGroupId, const QString& name, bool isAvGroupchat, |
|
const QString& selfName) |
|
: selfName{selfName} |
|
, title{name} |
|
, toxGroupNum(groupId) |
|
, groupId{persistentGroupId} |
|
, avGroupchat{isAvGroupchat} |
|
{ |
|
// in groupchats, we only notify on messages containing your name <-- dumb |
|
// sound notifications should be on all messages, but system popup notification |
|
// on naming is appropriate |
|
hasNewMessages = 0; |
|
userWasMentioned = 0; |
|
regeneratePeerList(); |
|
} |
|
|
|
void Group::setName(const QString& newTitle) |
|
{ |
|
const QString shortTitle = newTitle.left(MAX_GROUP_TITLE_LENGTH); |
|
if (!shortTitle.isEmpty() && title != shortTitle) { |
|
title = shortTitle; |
|
emit displayedNameChanged(title); |
|
emit titleChangedByUser(title); |
|
emit titleChanged(selfName, title); |
|
} |
|
} |
|
|
|
void Group::setTitle(const QString& author, const QString& newTitle) |
|
{ |
|
const QString shortTitle = newTitle.left(MAX_GROUP_TITLE_LENGTH); |
|
if (!shortTitle.isEmpty() && title != shortTitle) { |
|
title = shortTitle; |
|
emit displayedNameChanged(title); |
|
emit titleChanged(author, title); |
|
} |
|
} |
|
|
|
QString Group::getName() const |
|
{ |
|
return title; |
|
} |
|
|
|
QString Group::getDisplayedName() const |
|
{ |
|
return getName(); |
|
} |
|
|
|
void Group::regeneratePeerList() |
|
{ |
|
// NOTE: there's a bit of a race here. Core emits a signal for both groupPeerlistChanged and |
|
// groupPeerNameChanged back-to-back when a peer joins our group. If we get both before we |
|
// process this slot, core->getGroupPeerNames will contain the new peer name, and we'll ignore |
|
// the name changed signal, and emit a single userJoined with the correct name. But, if we |
|
// receive the name changed signal a little later, we will emit userJoined before we have their |
|
// username, using just their ToxPk, then shortly after emit another peerNameChanged signal. |
|
// This can cause double-updated to UI and chatlog, but is unavoidable given the API of toxcore. |
|
const Core* core = Core::getInstance(); |
|
QStringList peers = core->getGroupPeerNames(toxGroupNum); |
|
const auto oldPeerNames = peerDisplayNames; |
|
peerDisplayNames.clear(); |
|
const int nPeers = peers.size(); |
|
for (int i = 0; i < nPeers; ++i) { |
|
const auto pk = core->getGroupPeerPk(toxGroupNum, i); |
|
if (pk == core->getSelfPublicKey()) |
|
peerDisplayNames[pk] = core->getUsername(); |
|
peerDisplayNames[pk] = FriendList::decideNickname(pk, peers[i]); |
|
} |
|
for (const auto& pk : oldPeerNames.keys()) { |
|
if (!peerDisplayNames.contains(pk)) { |
|
emit userLeft(pk, oldPeerNames.value(pk)); |
|
stopAudioOfDepartedPeers(pk); |
|
} |
|
} |
|
for (const auto& pk : peerDisplayNames.keys()) { |
|
if (!oldPeerNames.contains(pk)) { |
|
emit userJoined(pk, peerDisplayNames.value(pk)); |
|
} |
|
} |
|
for (const auto& pk : peerDisplayNames.keys()) { |
|
if (oldPeerNames.contains(pk) && oldPeerNames.value(pk) != peerDisplayNames.value(pk)) { |
|
emit peerNameChanged(pk, oldPeerNames.value(pk), peerDisplayNames.value(pk)); |
|
} |
|
} |
|
if (oldPeerNames.size() != nPeers) { |
|
emit numPeersChanged(nPeers); |
|
} |
|
} |
|
|
|
void Group::updateUsername(ToxPk pk, const QString newName) |
|
{ |
|
const QString displayName = FriendList::decideNickname(pk, newName); |
|
assert(peerDisplayNames.contains(pk)); |
|
if (peerDisplayNames[pk] != displayName) { |
|
// there could be no actual change even if their username changed due to an alias being set |
|
const auto oldName = peerDisplayNames[pk]; |
|
peerDisplayNames[pk] = displayName; |
|
emit peerNameChanged(pk, oldName, displayName); |
|
} |
|
} |
|
|
|
bool Group::isAvGroupchat() const |
|
{ |
|
return avGroupchat; |
|
} |
|
|
|
uint32_t Group::getId() const |
|
{ |
|
return toxGroupNum; |
|
} |
|
|
|
const GroupId& Group::getPersistentId() const |
|
{ |
|
return groupId; |
|
} |
|
|
|
int Group::getPeersCount() const |
|
{ |
|
return peerDisplayNames.size(); |
|
} |
|
|
|
/** |
|
* @brief Gets the PKs and names of all peers |
|
* @return PKs and names of all peers, including our own PK and name |
|
*/ |
|
const QMap<ToxPk, QString>& Group::getPeerList() const |
|
{ |
|
return peerDisplayNames; |
|
} |
|
|
|
void Group::setEventFlag(bool f) |
|
{ |
|
hasNewMessages = f; |
|
} |
|
|
|
bool Group::getEventFlag() const |
|
{ |
|
return hasNewMessages; |
|
} |
|
|
|
void Group::setMentionedFlag(bool f) |
|
{ |
|
userWasMentioned = f; |
|
} |
|
|
|
bool Group::getMentionedFlag() const |
|
{ |
|
return userWasMentioned; |
|
} |
|
|
|
QString Group::resolveToxId(const ToxPk& id) const |
|
{ |
|
auto it = peerDisplayNames.find(id); |
|
|
|
if (it != peerDisplayNames.end()) { |
|
return *it; |
|
} |
|
|
|
return QString(); |
|
} |
|
|
|
void Group::setSelfName(const QString& name) |
|
{ |
|
selfName = name; |
|
} |
|
|
|
QString Group::getSelfName() const |
|
{ |
|
return selfName; |
|
} |
|
|
|
void Group::stopAudioOfDepartedPeers(const ToxPk& peerPk) |
|
{ |
|
if (avGroupchat) { |
|
Core* core = Core::getInstance(); |
|
core->getAv()->invalidateGroupCallPeerSource(toxGroupNum, peerPk); |
|
} |
|
}
|
|
|