From cabed6def3d4b83b3c10de098bb0defa684583de Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Sat, 22 Dec 2018 02:38:21 +0200 Subject: [PATCH 01/10] feat(core): print a chat log entry when a user joins/leaves the group chat --- src/widget/form/groupchatform.cpp | 52 +++++++++++++++++++++++++++++++ src/widget/form/groupchatform.h | 1 + 2 files changed, 53 insertions(+) diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index 2b521c581..b75498150 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -44,6 +44,9 @@ #include #include +QMap > groups; +QMap > firstTime; + namespace { const auto LABEL_PEER_TYPE_OUR = QVariant(QStringLiteral("our")); @@ -136,6 +139,8 @@ GroupChatForm::GroupChatForm(Group* chatGroup) GroupChatForm::~GroupChatForm() { + groups[group->getId()].clear(); + firstTime[group->getId()].clear(); Translator::unregister(this); } @@ -176,6 +181,7 @@ void GroupChatForm::onUserListChanged() { updateUserCount(); updateUserNames(); + sendJoinLeaveMessages(); // Enable or disable call button const int peersCount = group->getPeersCount(); @@ -307,6 +313,52 @@ void GroupChatForm::updateUserNames() } } +void GroupChatForm::sendJoinLeaveMessages() +{ + const auto peers = group->getPeerList(); + + // no need to do anything without any peers + if (peers.isEmpty()) { + return; + } + + // generate user list from the current group if it's empty + if (!groups.contains(group->getId())) + { + groups[group->getId()] = group->getPeerList(); + return; + } + + auto ¤t = groups[group->getId()]; + auto &ft = firstTime[group->getId()]; + // user joins + for (const auto& peerPk : peers.keys()) { + const QString name = peers.value(peerPk); + // ignore weird issue: when user joins the group, the name is empty, then it's renamed to normal nickname (why?) + // so, just ignore the first insertion + if (!ft.value(peerPk, false)) + { + ft[peerPk] = true; + continue; + } + if (!current.contains(peerPk)) + { + current.insert(peerPk, name); + addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, QDateTime()); + } + } + // user leaves + for (const auto& peerPk : current.keys()) { + const QString name = current.value(peerPk); + if (!peers.contains(peerPk)) + { + current.remove(peerPk); + ft.remove(peerPk); + addSystemInfoMessage(tr("%1 has left the group").arg(name), ChatMessage::INFO, QDateTime()); + } + } +} + void GroupChatForm::peerAudioPlaying(ToxPk peerPk) { peerLabels[peerPk]->setProperty("playingAudio", LABEL_PEER_PLAYING_AUDIO); diff --git a/src/widget/form/groupchatform.h b/src/widget/form/groupchatform.h index 63c1c6e3b..af165e4c7 100644 --- a/src/widget/form/groupchatform.h +++ b/src/widget/form/groupchatform.h @@ -67,6 +67,7 @@ private: void retranslateUi(); void updateUserCount(); void updateUserNames(); + void sendJoinLeaveMessages(); private: Group* group; From 6872ead850eeab5cea2e036cb1701da8e116d51e Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Sat, 22 Dec 2018 02:42:42 +0200 Subject: [PATCH 02/10] fix(core): fixed Timestamps --- src/widget/form/groupchatform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index b75498150..8f3408170 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -344,7 +344,7 @@ void GroupChatForm::sendJoinLeaveMessages() if (!current.contains(peerPk)) { current.insert(peerPk, name); - addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, QDateTime()); + addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); } } // user leaves @@ -354,7 +354,7 @@ void GroupChatForm::sendJoinLeaveMessages() { current.remove(peerPk); ft.remove(peerPk); - addSystemInfoMessage(tr("%1 has left the group").arg(name), ChatMessage::INFO, QDateTime()); + addSystemInfoMessage(tr("%1 has left the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); } } } From 8c239c8ef6d47177cabfcfca79783d188ac9c76b Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Sat, 22 Dec 2018 03:04:38 +0200 Subject: [PATCH 03/10] fix(core): simplify the code --- src/widget/form/groupchatform.cpp | 27 ++++++++++----------------- src/widget/form/groupchatform.h | 2 ++ 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index 8f3408170..0af569188 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -44,9 +44,6 @@ #include #include -QMap > groups; -QMap > firstTime; - namespace { const auto LABEL_PEER_TYPE_OUR = QVariant(QStringLiteral("our")); @@ -139,8 +136,6 @@ GroupChatForm::GroupChatForm(Group* chatGroup) GroupChatForm::~GroupChatForm() { - groups[group->getId()].clear(); - firstTime[group->getId()].clear(); Translator::unregister(this); } @@ -323,37 +318,35 @@ void GroupChatForm::sendJoinLeaveMessages() } // generate user list from the current group if it's empty - if (!groups.contains(group->getId())) + if (groupLast.isEmpty()) { - groups[group->getId()] = group->getPeerList(); + groupLast = group->getPeerList(); return; } - auto ¤t = groups[group->getId()]; - auto &ft = firstTime[group->getId()]; // user joins for (const auto& peerPk : peers.keys()) { const QString name = peers.value(peerPk); // ignore weird issue: when user joins the group, the name is empty, then it's renamed to normal nickname (why?) // so, just ignore the first insertion - if (!ft.value(peerPk, false)) + if (!firstTime.value(peerPk, false)) { - ft[peerPk] = true; + firstTime[peerPk] = true; continue; } - if (!current.contains(peerPk)) + if (!groupLast.contains(peerPk)) { - current.insert(peerPk, name); + groupLast.insert(peerPk, name); addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); } } // user leaves - for (const auto& peerPk : current.keys()) { - const QString name = current.value(peerPk); + for (const auto& peerPk : groupLast.keys()) { + const QString name = groupLast.value(peerPk); if (!peers.contains(peerPk)) { - current.remove(peerPk); - ft.remove(peerPk); + groupLast.remove(peerPk); + firstTime.remove(peerPk); addSystemInfoMessage(tr("%1 has left the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); } } diff --git a/src/widget/form/groupchatform.h b/src/widget/form/groupchatform.h index af165e4c7..0257306ff 100644 --- a/src/widget/form/groupchatform.h +++ b/src/widget/form/groupchatform.h @@ -73,6 +73,8 @@ private: Group* group; QMap peerLabels; QMap peerAudioTimers; + QMap groupLast; + QMap firstTime; FlowLayout* namesListLayout; QLabel* nusersLabel; TabCompleter* tabber; From c136a17ff0f1eb29b7e9e3b56b0fb8f036ab0fbb Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Sun, 23 Dec 2018 02:21:45 +0200 Subject: [PATCH 04/10] fix(core): fix formatting --- src/widget/form/groupchatform.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index 0af569188..113171136 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -318,8 +318,7 @@ void GroupChatForm::sendJoinLeaveMessages() } // generate user list from the current group if it's empty - if (groupLast.isEmpty()) - { + if (groupLast.isEmpty()) { groupLast = group->getPeerList(); return; } @@ -329,13 +328,11 @@ void GroupChatForm::sendJoinLeaveMessages() const QString name = peers.value(peerPk); // ignore weird issue: when user joins the group, the name is empty, then it's renamed to normal nickname (why?) // so, just ignore the first insertion - if (!firstTime.value(peerPk, false)) - { + if (!firstTime.value(peerPk, false)) { firstTime[peerPk] = true; continue; } - if (!groupLast.contains(peerPk)) - { + if (!groupLast.contains(peerPk)) { groupLast.insert(peerPk, name); addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); } @@ -343,8 +340,7 @@ void GroupChatForm::sendJoinLeaveMessages() // user leaves for (const auto& peerPk : groupLast.keys()) { const QString name = groupLast.value(peerPk); - if (!peers.contains(peerPk)) - { + if (!peers.contains(peerPk)) { groupLast.remove(peerPk); firstTime.remove(peerPk); addSystemInfoMessage(tr("%1 has left the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); From 9b261fd870f8a240cdf93c5acc2235efaa7a8116 Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Tue, 25 Dec 2018 19:14:31 +0200 Subject: [PATCH 05/10] fix(core): this fixes displaying nickname refreshes in groups --- src/model/group.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/model/group.cpp b/src/model/group.cpp index e03bd33da..e5c20f861 100644 --- a/src/model/group.cpp +++ b/src/model/group.cpp @@ -46,12 +46,7 @@ void Group::updatePeer(int peerId, QString name) { ToxPk peerKey = Core::getInstance()->getGroupPeerPk(groupId, peerId); toxpks[peerKey] = name; - - Friend* f = FriendList::findFriend(peerKey); - if (f != nullptr) { - // use the displayed name from the friends list - toxpks[peerKey] = f->getDisplayedName(); - } + qDebug() << "name change: " + name; emit userListChanged(groupId, toxpks); } From feee0e767ffa15b2145f82d16da9c47c2d2f580e Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Tue, 25 Dec 2018 22:15:48 +0200 Subject: [PATCH 06/10] fix(core): support user aliases --- src/friendlist.cpp | 10 ++++++++++ src/friendlist.h | 2 ++ src/widget/form/groupchatform.cpp | 12 +++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/friendlist.cpp b/src/friendlist.cpp index e278e5c6e..5198069be 100644 --- a/src/friendlist.cpp +++ b/src/friendlist.cpp @@ -87,3 +87,13 @@ QList FriendList::getAllFriends() { return friendList.values(); } + +QString FriendList::decideNickname(ToxPk peerPk, const QString origName) +{ + Friend* f = FriendList::findFriend(peerPk); + if (f != nullptr && f->hasAlias()) { + return f->getDisplayedName(); + } else { + return origName; + } +} diff --git a/src/friendlist.h b/src/friendlist.h index 63c5e5565..e83de1f7b 100644 --- a/src/friendlist.h +++ b/src/friendlist.h @@ -28,6 +28,7 @@ template class QHash; class Friend; class QByteArray; +class QString; class ToxPk; class FriendList @@ -39,6 +40,7 @@ public: static QList getAllFriends(); static void removeFriend(uint32_t friendId, bool fake = false); static void clear(); + static QString decideNickname(ToxPk peerPk, const QString origName); private: static QHash friendList; diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index 113171136..6323bd563 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -262,7 +262,7 @@ void GroupChatForm::updateUserNames() * and then sort them by their text and add them to the layout in that order */ const auto selfPk = Core::getInstance()->getSelfPublicKey(); for (const auto& peerPk : peers.keys()) { - const QString fullName = peers.value(peerPk); + const QString fullName = FriendList::decideNickname(peerPk, peers.value(peerPk)); const QString editedName = editName(fullName).append(QLatin1String(", ")); QLabel* const label = new QLabel(editedName); if (editedName != fullName) { @@ -325,21 +325,27 @@ void GroupChatForm::sendJoinLeaveMessages() // user joins for (const auto& peerPk : peers.keys()) { - const QString name = peers.value(peerPk); // ignore weird issue: when user joins the group, the name is empty, then it's renamed to normal nickname (why?) // so, just ignore the first insertion if (!firstTime.value(peerPk, false)) { firstTime[peerPk] = true; continue; } + const QString name = FriendList::decideNickname(peerPk, peers.value(peerPk)); if (!groupLast.contains(peerPk)) { groupLast.insert(peerPk, name); addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); } + else { + if (groupLast[peerPk] != name && peers.value(peerPk) == name) { + addSystemInfoMessage(tr("%1 is now known as %2").arg(groupLast[peerPk], name), ChatMessage::INFO, QDateTime::currentDateTime()); + groupLast[peerPk] = name; + } + } } // user leaves for (const auto& peerPk : groupLast.keys()) { - const QString name = groupLast.value(peerPk); + const QString name = FriendList::decideNickname(peerPk, groupLast.value(peerPk)); if (!peers.contains(peerPk)) { groupLast.remove(peerPk); firstTime.remove(peerPk); From 01f79b0d084176c4b6deaa289060f60652bf7428 Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Wed, 26 Dec 2018 18:05:03 +0200 Subject: [PATCH 07/10] fix(core): update group peerLists on local changes --- src/model/friend.cpp | 8 ++++++++ src/model/group.cpp | 6 ++++++ src/model/group.h | 1 + src/nexus.cpp | 1 + src/widget/form/groupchatform.cpp | 7 ++++++- src/widget/widget.cpp | 7 +++++++ src/widget/widget.h | 1 + 7 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/model/friend.cpp b/src/model/friend.cpp index 1c0b43fc4..13481b158 100644 --- a/src/model/friend.cpp +++ b/src/model/friend.cpp @@ -84,6 +84,14 @@ void Friend::setAlias(const QString& alias) if (oldDisplayed != newDisplayed) { emit displayedNameChanged(newDisplayed); } + + for (Group* g : GroupList::getAllGroups()) { + if (userAlias.isEmpty()) { + g->updateUsername(friendPk, userName); + continue; + } + g->updateUsername(friendPk, userAlias); + } } void Friend::setStatusMessage(const QString& message) diff --git a/src/model/group.cpp b/src/model/group.cpp index e5c20f861..3803fa0f7 100644 --- a/src/model/group.cpp +++ b/src/model/group.cpp @@ -119,6 +119,12 @@ void Group::regeneratePeerList() emit userListChanged(groupId, toxpks); } +void Group::updateUsername(ToxPk pk, const QString newName) +{ + toxpks[pk] = newName; + emit userListChanged(groupId, toxpks); +} + bool Group::isAvGroupchat() const { return avGroupchat; diff --git a/src/model/group.h b/src/model/group.h index a30180940..22469ca95 100644 --- a/src/model/group.h +++ b/src/model/group.h @@ -47,6 +47,7 @@ public: bool getMentionedFlag() const; void updatePeer(int peerId, QString newName); + void updateUsername(ToxPk pk, const QString newName); void setName(const QString& newTitle) override; void setTitle(const QString& author, const QString& newTitle); QString getName() const; diff --git a/src/nexus.cpp b/src/nexus.cpp index 611189bf5..a94cf3249 100644 --- a/src/nexus.cpp +++ b/src/nexus.cpp @@ -213,6 +213,7 @@ void Nexus::showMainGUI() connect(core, &Core::friendTypingChanged, widget, &Widget::onFriendTypingChanged); connect(core, &Core::messageSentResult, widget, &Widget::onMessageSendResult); connect(core, &Core::groupSentFailed, widget, &Widget::onGroupSendFailed); + connect(core, &Core::usernameSet, widget, &Widget::refreshPeerListsLocal); connect(widget, &Widget::statusSet, core, &Core::setStatus); connect(widget, &Widget::friendRequested, core, &Core::requestFriendship); diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index 6323bd563..77636161c 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -337,7 +337,12 @@ void GroupChatForm::sendJoinLeaveMessages() addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); } else { - if (groupLast[peerPk] != name && peers.value(peerPk) == name) { + Friend *f = FriendList::findFriend(peerPk); + if (groupLast[peerPk] != name + && peers.value(peerPk) == name + && peerPk != Core::getInstance()->getSelfPublicKey() // ignore myself + && !(f != nullptr && f->hasAlias()) // ignore friends with aliases + ) { addSystemInfoMessage(tr("%1 is now known as %2").arg(groupLast[peerPk], name), ChatMessage::INFO, QDateTime::currentDateTime()); groupLast[peerPk] = name; } diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 1c8887101..e1fc0d774 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -2503,3 +2503,10 @@ void Widget::focusChatInput() } } } + +void Widget::refreshPeerListsLocal(const QString &username) +{ + for (Group* g : GroupList::getAllGroups()) { + g->updateUsername(Core::getInstance()->getSelfPublicKey(), username); + } +} diff --git a/src/widget/widget.h b/src/widget/widget.h index 06d5877bc..2daa4525b 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -182,6 +182,7 @@ public slots: void onFriendDialogShown(const Friend* f); void onGroupDialogShown(Group* g); void toggleFullscreen(); + void refreshPeerListsLocal(const QString &username); signals: void friendRequestAccepted(const ToxPk& friendPk); From 2000bf55f2f7e3c3573df8130e74850b1202b044 Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Wed, 26 Dec 2018 18:32:27 +0200 Subject: [PATCH 08/10] fix(core): fix for users without nicknames --- src/widget/form/groupchatform.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index 77636161c..e2af0193d 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -325,9 +325,10 @@ void GroupChatForm::sendJoinLeaveMessages() // user joins for (const auto& peerPk : peers.keys()) { - // ignore weird issue: when user joins the group, the name is empty, then it's renamed to normal nickname (why?) - // so, just ignore the first insertion if (!firstTime.value(peerPk, false)) { + if (!groupLast.contains(peerPk)) { + addSystemInfoMessage(tr("A new user has connected to the group"), ChatMessage::INFO, QDateTime::currentDateTime()); + } firstTime[peerPk] = true; continue; } From 96ad27f644fd151a608abdffe045ad215db28564 Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Wed, 26 Dec 2018 19:51:32 +0200 Subject: [PATCH 09/10] fix(core): ignore mentioning users with empty nicknames --- src/widget/widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index e1fc0d774..898da58db 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -1742,7 +1742,7 @@ void Widget::onGroupMessageReceived(int groupnumber, int peernumber, const QStri return; } - const auto mention = message.contains(nameMention) || message.contains(sanitizedNameMention); + const auto mention = !core->getUsername().isEmpty() && (message.contains(nameMention) || message.contains(sanitizedNameMention)); const auto targeted = !isSelf && mention; const auto groupId = g->getId(); const auto date = QDateTime::currentDateTime(); From 7a437c74493333bb77f18418059ff329dde55340 Mon Sep 17 00:00:00 2001 From: Monsterovich Date: Thu, 27 Dec 2018 12:48:04 +0200 Subject: [PATCH 10/10] fix(core): fixed syntax --- src/widget/form/groupchatform.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index e2af0193d..6b2e0ce88 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -336,8 +336,7 @@ void GroupChatForm::sendJoinLeaveMessages() if (!groupLast.contains(peerPk)) { groupLast.insert(peerPk, name); addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); - } - else { + } else { Friend *f = FriendList::findFriend(peerPk); if (groupLast[peerPk] != name && peers.value(peerPk) == name