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:
parent
afe7914bb7
commit
2fae2a30f7
|
@ -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*>(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);
|
||||
|
|
|
@ -44,6 +44,15 @@
|
|||
#include <QTimer>
|
||||
#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
|
||||
* @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<GroupNetCamView*>(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<GroupNetCamView*>(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<GroupNetCamView*>(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<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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user