diff --git a/src/core/coreav.cpp b/src/core/coreav.cpp index b750172ed..6335c4a1c 100644 --- a/src/core/coreav.cpp +++ b/src/core/coreav.cpp @@ -483,6 +483,13 @@ void CoreAV::groupCallCallback(void* tox, uint32_t group, uint32_t peer, const i Q_UNUSED(tox); Core* c = static_cast(core); + const ToxPk peerPk = c->getGroupPeerPk(group, peer); + const Settings& s = Settings::getInstance(); + // don't play the audio if it comes from a muted peer + if (s.getBlackList().contains(peerPk.toString())) { + return; + } + CoreAV* cav = c->getAv(); auto it = cav->groupCalls.find(group); diff --git a/src/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp index 3fe0342c5..38b00bd07 100644 --- a/src/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -44,6 +44,15 @@ #include #include +namespace +{ +const auto LABEL_PEER_TYPE_OUR = QVariant(QStringLiteral("our")); +const auto LABEL_PEER_TYPE_MUTED = QVariant(QStringLiteral("muted")); +const auto LABEL_PEER_PLAYING_AUDIO = QVariant(QStringLiteral("true")); +const auto LABEL_PEER_NOT_PLAYING_AUDIO = QVariant(QStringLiteral("false")); +const auto PEER_LABEL_STYLE_SHEET_PATH = QStringLiteral(":/ui/chatArea/chatHead.css"); +} + /** * @brief Edit name for correct representation if it is needed * @param name Editing string @@ -242,16 +251,20 @@ void GroupChatForm::updateUserNames() label->setToolTip(fullName); } label->setTextFormat(Qt::PlainText); + label->setContextMenuPolicy(Qt::CustomContextMenu); const Settings& s = Settings::getInstance(); + connect(label, &QLabel::customContextMenuRequested, this, &GroupChatForm::onLabelContextMenuRequested); if (peerPk == selfPk) { - label->setStyleSheet(QStringLiteral("QLabel {color : green;}")); + label->setProperty("peerType", LABEL_PEER_TYPE_OUR); } else if (s.getBlackList().contains(peerPk.toString())) { - label->setStyleSheet(QStringLiteral("QLabel {color : darkRed;}")); + label->setProperty("peerType", LABEL_PEER_TYPE_MUTED); } else if (netcam != nullptr) { static_cast(netcam)->addPeer(peerPk, fullName); } + + label->setStyleSheet(Style::getStylesheet(PEER_LABEL_STYLE_SHEET_PATH)); peerLabels.insert(peerPk, label); } @@ -279,7 +292,7 @@ void GroupChatForm::updateUserNames() void GroupChatForm::peerAudioPlaying(ToxPk peerPk) { - peerLabels[peerPk]->setStyleSheet(QStringLiteral("QLabel {color : red;}")); + peerLabels[peerPk]->setProperty("playingAudio", LABEL_PEER_PLAYING_AUDIO); // TODO(sudden6): check if this can ever be false, cause [] default constructs if (!peerAudioTimers[peerPk]) { peerAudioTimers[peerPk] = new QTimer(this); @@ -289,7 +302,7 @@ void GroupChatForm::peerAudioPlaying(ToxPk peerPk) static_cast(netcam)->removePeer(peerPk); } - peerLabels[peerPk]->setStyleSheet(""); + peerLabels[peerPk]->setProperty("playingAudio", LABEL_PEER_NOT_PLAYING_AUDIO); delete peerAudioTimers[peerPk]; peerAudioTimers[peerPk] = nullptr; }); @@ -300,6 +313,8 @@ void GroupChatForm::peerAudioPlaying(ToxPk peerPk) static_cast(netcam)->addPeer(peerPk, nameIt.value()); } } + + peerLabels[peerPk]->setStyleSheet(Style::getStylesheet(PEER_LABEL_STYLE_SHEET_PATH)); peerAudioTimers[peerPk]->start(500); } @@ -429,3 +444,60 @@ void GroupChatForm::retranslateUi() { updateUserCount(); } + +void GroupChatForm::onLabelContextMenuRequested(const QPoint& localPos) +{ + QLabel* label = static_cast(QObject::sender()); + + if (label == nullptr) { + return; + } + + const QPoint pos = label->mapToGlobal(localPos); + const QString muteString = tr("mute"); + const QString unmuteString = tr("unmute"); + Settings& s = Settings::getInstance(); + QStringList blackList = s.getBlackList(); + QMenu* const contextMenu = new QMenu(this); + const ToxPk selfPk = Core::getInstance()->getSelfPublicKey(); + ToxPk peerPk; + + // delete menu after it stops being used + connect(contextMenu, &QMenu::aboutToHide, contextMenu, &QObject::deleteLater); + + peerPk = peerLabels.key(label); + if (peerPk.isEmpty() || peerPk == selfPk) { + return; + } + + const bool isPeerBlocked = blackList.contains(peerPk.toString()); + QString menuTitle = label->text(); + if (menuTitle.endsWith(QLatin1String(", "))) { + menuTitle.chop(2); + } + QAction* menuTitleAction = contextMenu->addAction(menuTitle); + menuTitleAction->setEnabled(false); // make sure the title is not clickable + contextMenu->addSeparator(); + + const QAction* toggleMuteAction; + if (isPeerBlocked) { + toggleMuteAction = contextMenu->addAction(unmuteString); + } else { + toggleMuteAction = contextMenu->addAction(muteString); + } + contextMenu->setStyleSheet(Style::getStylesheet(PEER_LABEL_STYLE_SHEET_PATH)); + + const QAction* selectedItem = contextMenu->exec(pos); + if (selectedItem == toggleMuteAction) { + if (isPeerBlocked) { + const int index = blackList.indexOf(peerPk.toString()); + if (index != -1) { + blackList.removeAt(index); + } + } else { + blackList << peerPk.toString(); + } + + s.setBlackList(blackList); + } +} diff --git a/src/widget/form/groupchatform.h b/src/widget/form/groupchatform.h index c186814a2..81364eaaa 100644 --- a/src/widget/form/groupchatform.h +++ b/src/widget/form/groupchatform.h @@ -52,6 +52,7 @@ private slots: void onTitleChanged(uint32_t groupId, const QString& author, const QString& title); void onSearchUp(const QString& phrase) override; void onSearchDown(const QString& phrase) override; + void onLabelContextMenuRequested(const QPoint& localPos); protected: virtual GenericNetCamView* createNetcam() final override; diff --git a/ui/chatArea/chatHead.css b/ui/chatArea/chatHead.css index 206e09883..d7a3846f0 100644 --- a/ui/chatArea/chatHead.css +++ b/ui/chatArea/chatHead.css @@ -1,23 +1,39 @@ QLineEdit { - color: @black; - background: white; - border: 0px; + color: @black; + background: white; + border: 0px; } #nameLabel { - color: @black; - font: @mediumBold; - font-size:12px; + color: @black; + font: @mediumBold; + font-size:12px; } #statusLabel { - color: @mediumGrey; - font: @medium; - font-size:12px; + color: @mediumGrey; + font: @medium; + font-size:12px; } #peersLabel { - color: @mediumGrey; - font: @medium; - font-size:12px; + color: @mediumGrey; + font: @medium; + font-size:12px; +} + +QLabel[peerType="our"] { + color: green; +} + +QLabel[peerType="muted"] { + color: darkred; +} + +QLabel[playingAudio="true"] { + font-weight: bold; +} + +QMenu:disabled { + color: gray; }