1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

feat(chat): add UI option to mute group peers

Implements #4596, #4626, #1007

Adds a context menu to every peer label in group chat with an
option to mute chosen peers, which adds them to the blacklist.
Mutes audio of blacklisted group peers.
This commit is contained in:
tox-user 2018-05-13 09:20:57 +00:00
parent afe7914bb7
commit 2fae2a30f7
No known key found for this signature in database
GPG Key ID: 7C132143C1A3A7D4
4 changed files with 112 additions and 16 deletions

View File

@ -483,6 +483,13 @@ void CoreAV::groupCallCallback(void* tox, uint32_t group, uint32_t peer, const i
Q_UNUSED(tox); Q_UNUSED(tox);
Core* c = static_cast<Core*>(core); Core* c = static_cast<Core*>(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(); CoreAV* cav = c->getAv();
auto it = cav->groupCalls.find(group); auto it = cav->groupCalls.find(group);

View File

@ -44,6 +44,15 @@
#include <QTimer> #include <QTimer>
#include <QToolButton> #include <QToolButton>
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 * @brief Edit name for correct representation if it is needed
* @param name Editing string * @param name Editing string
@ -242,16 +251,20 @@ void GroupChatForm::updateUserNames()
label->setToolTip(fullName); label->setToolTip(fullName);
} }
label->setTextFormat(Qt::PlainText); label->setTextFormat(Qt::PlainText);
label->setContextMenuPolicy(Qt::CustomContextMenu);
const Settings& s = Settings::getInstance(); const Settings& s = Settings::getInstance();
connect(label, &QLabel::customContextMenuRequested, this, &GroupChatForm::onLabelContextMenuRequested);
if (peerPk == selfPk) { if (peerPk == selfPk) {
label->setStyleSheet(QStringLiteral("QLabel {color : green;}")); label->setProperty("peerType", LABEL_PEER_TYPE_OUR);
} else if (s.getBlackList().contains(peerPk.toString())) { } else if (s.getBlackList().contains(peerPk.toString())) {
label->setStyleSheet(QStringLiteral("QLabel {color : darkRed;}")); label->setProperty("peerType", LABEL_PEER_TYPE_MUTED);
} else if (netcam != nullptr) { } else if (netcam != nullptr) {
static_cast<GroupNetCamView*>(netcam)->addPeer(peerPk, fullName); static_cast<GroupNetCamView*>(netcam)->addPeer(peerPk, fullName);
} }
label->setStyleSheet(Style::getStylesheet(PEER_LABEL_STYLE_SHEET_PATH));
peerLabels.insert(peerPk, label); peerLabels.insert(peerPk, label);
} }
@ -279,7 +292,7 @@ void GroupChatForm::updateUserNames()
void GroupChatForm::peerAudioPlaying(ToxPk peerPk) 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 // TODO(sudden6): check if this can ever be false, cause [] default constructs
if (!peerAudioTimers[peerPk]) { if (!peerAudioTimers[peerPk]) {
peerAudioTimers[peerPk] = new QTimer(this); peerAudioTimers[peerPk] = new QTimer(this);
@ -289,7 +302,7 @@ void GroupChatForm::peerAudioPlaying(ToxPk peerPk)
static_cast<GroupNetCamView*>(netcam)->removePeer(peerPk); static_cast<GroupNetCamView*>(netcam)->removePeer(peerPk);
} }
peerLabels[peerPk]->setStyleSheet(""); peerLabels[peerPk]->setProperty("playingAudio", LABEL_PEER_NOT_PLAYING_AUDIO);
delete peerAudioTimers[peerPk]; delete peerAudioTimers[peerPk];
peerAudioTimers[peerPk] = nullptr; peerAudioTimers[peerPk] = nullptr;
}); });
@ -300,6 +313,8 @@ void GroupChatForm::peerAudioPlaying(ToxPk peerPk)
static_cast<GroupNetCamView*>(netcam)->addPeer(peerPk, nameIt.value()); static_cast<GroupNetCamView*>(netcam)->addPeer(peerPk, nameIt.value());
} }
} }
peerLabels[peerPk]->setStyleSheet(Style::getStylesheet(PEER_LABEL_STYLE_SHEET_PATH));
peerAudioTimers[peerPk]->start(500); peerAudioTimers[peerPk]->start(500);
} }
@ -429,3 +444,60 @@ void GroupChatForm::retranslateUi()
{ {
updateUserCount(); updateUserCount();
} }
void GroupChatForm::onLabelContextMenuRequested(const QPoint& localPos)
{
QLabel* label = static_cast<QLabel*>(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);
}
}

View File

@ -52,6 +52,7 @@ private slots:
void onTitleChanged(uint32_t groupId, const QString& author, const QString& title); void onTitleChanged(uint32_t groupId, const QString& author, const QString& title);
void onSearchUp(const QString& phrase) override; void onSearchUp(const QString& phrase) override;
void onSearchDown(const QString& phrase) override; void onSearchDown(const QString& phrase) override;
void onLabelContextMenuRequested(const QPoint& localPos);
protected: protected:
virtual GenericNetCamView* createNetcam() final override; virtual GenericNetCamView* createNetcam() final override;

View File

@ -1,23 +1,39 @@
QLineEdit { QLineEdit {
color: @black; color: @black;
background: white; background: white;
border: 0px; border: 0px;
} }
#nameLabel { #nameLabel {
color: @black; color: @black;
font: @mediumBold; font: @mediumBold;
font-size:12px; font-size:12px;
} }
#statusLabel { #statusLabel {
color: @mediumGrey; color: @mediumGrey;
font: @medium; font: @medium;
font-size:12px; font-size:12px;
} }
#peersLabel { #peersLabel {
color: @mediumGrey; color: @mediumGrey;
font: @medium; font: @medium;
font-size:12px; font-size:12px;
}
QLabel[peerType="our"] {
color: green;
}
QLabel[peerType="muted"] {
color: darkred;
}
QLabel[playingAudio="true"] {
font-weight: bold;
}
QMenu:disabled {
color: gray;
} }