Make menus and placeholders display appropriate custom key combos. (#4045)

* Add initial support for finding hotkey display key sequences

* Make neededArguments work

* Implement displaying key combos in SplitHeader main menu

* Make Settings search text dynamic

* Make tab hide notice use a custom hotkeys key sequence

* Make Notebook menus use custom hotkeys key combo lookup for hiding tabs

* shut up changelog ci

* Make NotebookTab menus show custom hotkeys. SCUFFED:
this does not update dynamically!

* Scuffed: Make the show prefs button setting show the key bind

* Scuffed: Make the R9K description refer to hotkeys

* @pajlada, is something like this ok?

Co-authored-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
Mm2PL
2022-10-09 17:20:44 +02:00
committed by GitHub
parent 4e2da540d2
commit e604a36777
10 changed files with 248 additions and 41 deletions
+1
View File
@@ -61,6 +61,7 @@
- Minor: Migrated /ban to Helix API. (#4049) - Minor: Migrated /ban to Helix API. (#4049)
- Minor: Migrated /timeout to Helix API. (#4049) - Minor: Migrated /timeout to Helix API. (#4049)
- Minor: Migrated /w to Helix API. Chat command will continue to be used until February 11th 2023. (#4052) - Minor: Migrated /w to Helix API. Chat command will continue to be used until February 11th 2023. (#4052)
- Minor: Make menus and placeholders display appropriate custom key combos. (#4045)
- Bugfix: Connection to Twitch PubSub now recovers more reliably. (#3643, #3716) - Bugfix: Connection to Twitch PubSub now recovers more reliably. (#3643, #3716)
- Bugfix: Fixed `Smooth scrolling on new messages` setting sometimes hiding messages. (#4028) - Bugfix: Fixed `Smooth scrolling on new messages` setting sometimes hiding messages. (#4028)
- Bugfix: Fixed a crash that can occur when closing and quickly reopening a split, then running a command. (#3852) - Bugfix: Fixed a crash that can occur when closing and quickly reopening a split, then running a command. (#3852)
@@ -1,6 +1,7 @@
#include "controllers/hotkeys/HotkeyController.hpp" #include "controllers/hotkeys/HotkeyController.hpp"
#include "common/QLogging.hpp" #include "common/QLogging.hpp"
#include "controllers/hotkeys/HotkeyCategory.hpp"
#include "controllers/hotkeys/HotkeyModel.hpp" #include "controllers/hotkeys/HotkeyModel.hpp"
#include "singletons/Settings.hpp" #include "singletons/Settings.hpp"
@@ -547,4 +548,40 @@ void HotkeyController::showHotkeyError(const std::shared_ptr<Hotkey> &hotkey,
msgBox->exec(); msgBox->exec();
} }
QKeySequence HotkeyController::getDisplaySequence(
HotkeyCategory category, const QString &action,
const std::optional<std::vector<QString>> &arguments) const
{
const auto &found = this->findLike(category, action, arguments);
if (found != nullptr)
{
return found->keySequence();
}
return {};
}
std::shared_ptr<Hotkey> HotkeyController::findLike(
HotkeyCategory category, const QString &action,
const std::optional<std::vector<QString>> &arguments) const
{
for (auto other : this->hotkeys_)
{
if (other->category() == category && other->action() == action)
{
if (arguments)
{
if (other->arguments() == *arguments)
{
return other;
}
}
else
{
return other;
}
}
}
return nullptr;
}
} // namespace chatterino } // namespace chatterino
@@ -8,6 +8,7 @@
#include <pajlada/signals/signal.hpp> #include <pajlada/signals/signal.hpp>
#include <pajlada/signals/signalholder.hpp> #include <pajlada/signals/signalholder.hpp>
#include <optional>
#include <set> #include <set>
class QShortcut; class QShortcut;
@@ -33,6 +34,17 @@ public:
void save() override; void save() override;
std::shared_ptr<Hotkey> getHotkeyByName(QString name); std::shared_ptr<Hotkey> getHotkeyByName(QString name);
/**
* @brief returns a QKeySequence that perfoms the actions requested.
* Accepted if and only if the category matches, the action matches and arguments match.
* When arguments is present, contents of arguments must match the checked hotkey, otherwise arguments are ignored.
* For example:
* - std::nullopt (or {}) will match any hotkey satisfying category, action values,
* - {{"foo", "bar"}} will only match a hotkey that has these arguments and these arguments only
*/
QKeySequence getDisplaySequence(
HotkeyCategory category, const QString &action,
const std::optional<std::vector<QString>> &arguments = {}) const;
/** /**
* @brief removes the hotkey with the oldName and inserts newHotkey at the end * @brief removes the hotkey with the oldName and inserts newHotkey at the end
@@ -114,6 +126,17 @@ private:
**/ **/
static void showHotkeyError(const std::shared_ptr<Hotkey> &hotkey, static void showHotkeyError(const std::shared_ptr<Hotkey> &hotkey,
QString warning); QString warning);
/**
* @brief finds a Hotkey matching category, action and arguments.
* Accepted if and only if the category matches, the action matches and arguments match.
* When arguments is present, contents of arguments must match the checked hotkey, otherwise arguments are ignored.
* For example:
* - std::nullopt (or {}) will match any hotkey satisfying category, action values,
* - {{"foo", "bar"}} will only match a hotkey that has these arguments and these arguments only
*/
std::shared_ptr<Hotkey> findLike(
HotkeyCategory category, const QString &action,
const std::optional<std::vector<QString>> &arguments = {}) const;
friend class KeyboardSettingsPage; friend class KeyboardSettingsPage;
+58 -8
View File
@@ -2,6 +2,8 @@
#include "Application.hpp" #include "Application.hpp"
#include "common/QLogging.hpp" #include "common/QLogging.hpp"
#include "controllers/hotkeys/HotkeyCategory.hpp"
#include "controllers/hotkeys/HotkeyController.hpp"
#include "singletons/Settings.hpp" #include "singletons/Settings.hpp"
#include "singletons/Theme.hpp" #include "singletons/Theme.hpp"
#include "singletons/WindowManager.hpp" #include "singletons/WindowManager.hpp"
@@ -48,6 +50,11 @@ Notebook::Notebook(QWidget *parent)
[this](bool value) { [this](bool value) {
this->setLockNotebookLayout(value); this->setLockNotebookLayout(value);
}); });
this->showTabsAction_ = new QAction("Toggle visibility of tabs");
QObject::connect(this->showTabsAction_, &QAction::triggered, [this]() {
this->setShowTabs(!this->getShowTabs());
});
this->updateTabVisibilityMenuAction();
this->addNotebookActionsToMenu(&this->menu_); this->addNotebookActionsToMenu(&this->menu_);
@@ -374,12 +381,32 @@ void Notebook::setShowTabs(bool value)
// show a popup upon hiding tabs // show a popup upon hiding tabs
if (!value && getSettings()->informOnTabVisibilityToggle.getValue()) if (!value && getSettings()->informOnTabVisibilityToggle.getValue())
{ {
auto unhideSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::Window, "setTabVisibility", {{}});
if (unhideSeq.isEmpty())
{
unhideSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::Window, "setTabVisibility", {{"toggle"}});
}
if (unhideSeq.isEmpty())
{
unhideSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::Window, "setTabVisibility", {{"on"}});
}
QString hotkeyInfo = "(currently unbound)";
if (!unhideSeq.isEmpty())
{
hotkeyInfo =
"(" +
unhideSeq.toString(QKeySequence::SequenceFormat::NativeText) +
")";
}
QMessageBox msgBox(this->window()); QMessageBox msgBox(this->window());
msgBox.window()->setWindowTitle("Chatterino - hidden tabs"); msgBox.window()->setWindowTitle("Chatterino - hidden tabs");
msgBox.setText("You've just hidden your tabs."); msgBox.setText("You've just hidden your tabs.");
msgBox.setInformativeText( msgBox.setInformativeText(
"You can toggle tabs by using the keyboard shortcut (Ctrl+U by " "You can toggle tabs by using the keyboard shortcut " + hotkeyInfo +
"default) or right-clicking the tab area and selecting \"Toggle " " or right-clicking the tab area and selecting \"Toggle "
"visibility of tabs\"."); "visibility of tabs\".");
msgBox.addButton(QMessageBox::Ok); msgBox.addButton(QMessageBox::Ok);
auto *dsaButton = auto *dsaButton =
@@ -394,6 +421,34 @@ void Notebook::setShowTabs(bool value)
getSettings()->informOnTabVisibilityToggle.setValue(false); getSettings()->informOnTabVisibilityToggle.setValue(false);
} }
} }
updateTabVisibilityMenuAction();
}
void Notebook::updateTabVisibilityMenuAction()
{
auto toggleSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::Window, "setTabVisibility", {{}});
if (toggleSeq.isEmpty())
{
toggleSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::Window, "setTabVisibility", {{"toggle"}});
}
if (toggleSeq.isEmpty())
{
// show contextual shortcuts
if (this->getShowTabs())
{
toggleSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::Window, "setTabVisibility", {{"off"}});
}
else if (!this->getShowTabs())
{
toggleSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::Window, "setTabVisibility", {{"on"}});
}
}
this->showTabsAction_->setShortcut(toggleSeq);
} }
bool Notebook::getShowAddButton() const bool Notebook::getShowAddButton() const
@@ -919,12 +974,7 @@ void Notebook::setLockNotebookLayout(bool value)
void Notebook::addNotebookActionsToMenu(QMenu *menu) void Notebook::addNotebookActionsToMenu(QMenu *menu)
{ {
menu->addAction( menu->addAction(this->showTabsAction_);
"Toggle visibility of tabs",
[this]() {
this->setShowTabs(!this->getShowTabs());
},
QKeySequence("Ctrl+U"));
menu->addAction(this->lockNotebookLayoutAction_); menu->addAction(this->lockNotebookLayoutAction_);
} }
+2
View File
@@ -86,6 +86,7 @@ protected:
} }
private: private:
void updateTabVisibilityMenuAction();
void resizeAddButton(); void resizeAddButton();
bool containsPage(QWidget *page); bool containsPage(QWidget *page);
@@ -111,6 +112,7 @@ private:
bool lockNotebookLayout_ = false; bool lockNotebookLayout_ = false;
NotebookTabLocation tabLocation_ = NotebookTabLocation::Top; NotebookTabLocation tabLocation_ = NotebookTabLocation::Top;
QAction *lockNotebookLayoutAction_; QAction *lockNotebookLayoutAction_;
QAction *showTabsAction_;
}; };
class SplitNotebook : public Notebook class SplitNotebook : public Notebook
+15 -1
View File
@@ -54,6 +54,7 @@ SettingsDialog::SettingsDialog(QWidget *parent)
void SettingsDialog::addShortcuts() void SettingsDialog::addShortcuts()
{ {
this->setSearchPlaceholderText();
HotkeyController::HotkeyMap actions{ HotkeyController::HotkeyMap actions{
{"search", {"search",
[this](std::vector<QString>) -> QString { [this](std::vector<QString>) -> QString {
@@ -71,6 +72,19 @@ void SettingsDialog::addShortcuts()
this->shortcuts_ = getApp()->hotkeys->shortcutsForCategory( this->shortcuts_ = getApp()->hotkeys->shortcutsForCategory(
HotkeyCategory::PopupWindow, actions, this); HotkeyCategory::PopupWindow, actions, this);
} }
void SettingsDialog::setSearchPlaceholderText()
{
QString searchHotkey;
auto searchSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::PopupWindow, "search");
if (!searchSeq.isEmpty())
{
searchHotkey =
"(" + searchSeq.toString(QKeySequence::SequenceFormat::NativeText) +
")";
}
this->ui_.search->setPlaceholderText("Find in settings... " + searchHotkey);
}
void SettingsDialog::initUi() void SettingsDialog::initUi()
{ {
@@ -85,7 +99,7 @@ void SettingsDialog::initUi()
.withoutMargin() .withoutMargin()
.emplace<QLineEdit>() .emplace<QLineEdit>()
.assign(&this->ui_.search); .assign(&this->ui_.search);
edit->setPlaceholderText("Find in settings... (Ctrl+F by default)"); this->setSearchPlaceholderText();
edit->setClearButtonEnabled(true); edit->setClearButtonEnabled(true);
edit->findChild<QAbstractButton *>()->setIcon( edit->findChild<QAbstractButton *>()->setIcon(
QPixmap(":/buttons/clearSearch.png")); QPixmap(":/buttons/clearSearch.png"));
+1
View File
@@ -61,6 +61,7 @@ private:
void onOkClicked(); void onOkClicked();
void onCancelClicked(); void onCancelClicked();
void addShortcuts() override; void addShortcuts() override;
void setSearchPlaceholderText();
struct { struct {
QWidget *tabContainerContainer{}; QWidget *tabContainerContainer{};
+8 -2
View File
@@ -2,6 +2,8 @@
#include "Application.hpp" #include "Application.hpp"
#include "common/Common.hpp" #include "common/Common.hpp"
#include "controllers/hotkeys/HotkeyCategory.hpp"
#include "controllers/hotkeys/HotkeyController.hpp"
#include "singletons/Fonts.hpp" #include "singletons/Fonts.hpp"
#include "singletons/Settings.hpp" #include "singletons/Settings.hpp"
#include "singletons/Theme.hpp" #include "singletons/Theme.hpp"
@@ -60,12 +62,15 @@ NotebookTab::NotebookTab(Notebook *notebook)
this->showRenameDialog(); this->showRenameDialog();
}); });
// XXX: this doesn't update after changing hotkeys
this->menu_.addAction( this->menu_.addAction(
"Close Tab", "Close Tab",
[=]() { [=]() {
this->notebook_->removePage(this->page); this->notebook_->removePage(this->page);
}, },
QKeySequence("Ctrl+Shift+W")); getApp()->hotkeys->getDisplaySequence(HotkeyCategory::Window,
"removeTab"));
this->menu_.addAction( this->menu_.addAction(
"Popup Tab", "Popup Tab",
@@ -75,7 +80,8 @@ NotebookTab::NotebookTab(Notebook *notebook)
container->popup(); container->popup();
} }
}, },
QKeySequence("Ctrl+Shift+N")); getApp()->hotkeys->getDisplaySequence(HotkeyCategory::Window, "popup",
{{"window"}}));
highlightNewMessagesAction_ = highlightNewMessagesAction_ =
new QAction("Mark Tab as Unread on New Messages", &this->menu_); new QAction("Mark Tab as Unread on New Messages", &this->menu_);
+24 -2
View File
@@ -3,6 +3,8 @@
#include "Application.hpp" #include "Application.hpp"
#include "common/QLogging.hpp" #include "common/QLogging.hpp"
#include "common/Version.hpp" #include "common/Version.hpp"
#include "controllers/hotkeys/HotkeyCategory.hpp"
#include "controllers/hotkeys/HotkeyController.hpp"
#include "singletons/Fonts.hpp" #include "singletons/Fonts.hpp"
#include "singletons/NativeMessaging.hpp" #include "singletons/NativeMessaging.hpp"
#include "singletons/Paths.hpp" #include "singletons/Paths.hpp"
@@ -193,7 +195,17 @@ void GeneralPage::initLayout(GeneralPageView &layout)
#endif #endif
if (!BaseWindow::supportsCustomWindowFrame()) if (!BaseWindow::supportsCustomWindowFrame())
{ {
layout.addCheckbox("Show preferences button (Ctrl+P to show)", auto settingsSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::Window, "openSettings");
QString shortcut = " (no key bound to open them otherwise)";
// TODO: maybe prevent the user from locking themselves out of the settings?
if (!settingsSeq.isEmpty())
{
shortcut = QStringLiteral(" (%1 to show)")
.arg(settingsSeq.toString(
QKeySequence::SequenceFormat::NativeText));
}
layout.addCheckbox("Show preferences button" + shortcut,
s.hidePreferencesButton, true); s.hidePreferencesButton, true);
layout.addCheckbox("Show user button", s.hideUserButton, true); layout.addCheckbox("Show user button", s.hideUserButton, true);
} }
@@ -559,8 +571,18 @@ void GeneralPage::initLayout(GeneralPageView &layout)
layout.addCheckbox("Title", s.headerStreamTitle); layout.addCheckbox("Title", s.headerStreamTitle);
layout.addSubtitle("R9K"); layout.addSubtitle("R9K");
auto toggleLocalr9kSeq = getApp()->hotkeys->getDisplaySequence(
HotkeyCategory::Window, "toggleLocalR9K");
QString toggleLocalr9kShortcut =
"an assigned hotkey (Window -> Toggle local R9K)";
if (!toggleLocalr9kSeq.isEmpty())
{
toggleLocalr9kShortcut = toggleLocalr9kSeq.toString(
QKeySequence::SequenceFormat::NativeText);
}
layout.addDescription("Hide similar messages. Toggle hidden " layout.addDescription("Hide similar messages. Toggle hidden "
"messages by pressing Ctrl+H."); "messages by pressing " +
toggleLocalr9kShortcut + ".");
layout.addCheckbox("Hide similar messages", s.similarityEnabled); layout.addCheckbox("Hide similar messages", s.similarityEnabled);
//layout.addCheckbox("Gray out matches", s.colorSimilarDisabled); //layout.addCheckbox("Gray out matches", s.colorSimilarDisabled);
layout.addCheckbox("By the same user", s.hideSimilarBySameUser); layout.addCheckbox("By the same user", s.hideSimilarBySameUser);
+79 -28
View File
@@ -3,6 +3,9 @@
#include "Application.hpp" #include "Application.hpp"
#include "controllers/accounts/AccountController.hpp" #include "controllers/accounts/AccountController.hpp"
#include "controllers/commands/CommandController.hpp" #include "controllers/commands/CommandController.hpp"
#include "controllers/hotkeys/Hotkey.hpp"
#include "controllers/hotkeys/HotkeyCategory.hpp"
#include "controllers/hotkeys/HotkeyController.hpp"
#include "controllers/notifications/NotificationController.hpp" #include "controllers/notifications/NotificationController.hpp"
#include "providers/twitch/TwitchChannel.hpp" #include "providers/twitch/TwitchChannel.hpp"
#include "providers/twitch/TwitchIrcServer.hpp" #include "providers/twitch/TwitchIrcServer.hpp"
@@ -337,21 +340,27 @@ void SplitHeader::initializeLayout()
std::unique_ptr<QMenu> SplitHeader::createMainMenu() std::unique_ptr<QMenu> SplitHeader::createMainMenu()
{ {
// top level menu // top level menu
const auto &h = getApp()->hotkeys;
auto menu = std::make_unique<QMenu>(); auto menu = std::make_unique<QMenu>();
menu->addAction("Change channel", this->split_, &Split::changeChannel, menu->addAction(
QKeySequence("Ctrl+R")); "Change channel", this->split_, &Split::changeChannel,
h->getDisplaySequence(HotkeyCategory::Split, "changeChannel"));
menu->addAction("Close", this->split_, &Split::deleteFromContainer, menu->addAction("Close", this->split_, &Split::deleteFromContainer,
QKeySequence("Ctrl+W")); h->getDisplaySequence(HotkeyCategory::Split, "delete"));
menu->addSeparator(); menu->addSeparator();
menu->addAction("Popup", this->split_, &Split::popup, menu->addAction(
QKeySequence("Ctrl+N")); "Popup", this->split_, &Split::popup,
h->getDisplaySequence(HotkeyCategory::Window, "popup", {{"split"}}));
menu->addAction("Search", this->split_, &Split::showSearch, menu->addAction("Search", this->split_, &Split::showSearch,
QKeySequence("Ctrl+F")); h->getDisplaySequence(HotkeyCategory::Split, "showSearch"));
menu->addAction("Set filters", this->split_, &Split::setFiltersDialog); menu->addAction(
"Set filters", this->split_, &Split::setFiltersDialog,
h->getDisplaySequence(HotkeyCategory::Split, "pickFilters"));
menu->addSeparator(); menu->addSeparator();
#ifdef USEWEBENGINE #ifdef USEWEBENGINE
this->dropdownMenu.addAction("Start watching", this->split_, this->dropdownMenu.addAction(
&Split::startWatching); "Start watching", this->split_, &Split::startWatching;
h->getDisplaySequence(HotkeyCategory::Split, "startWatching"));
#endif #endif
auto *twitchChannel = auto *twitchChannel =
@@ -359,24 +368,31 @@ std::unique_ptr<QMenu> SplitHeader::createMainMenu()
if (twitchChannel) if (twitchChannel)
{ {
menu->addAction(OPEN_IN_BROWSER, this->split_, &Split::openInBrowser); menu->addAction(
OPEN_IN_BROWSER, this->split_, &Split::openInBrowser,
h->getDisplaySequence(HotkeyCategory::Split, "openInBrowser"));
#ifndef USEWEBENGINE #ifndef USEWEBENGINE
menu->addAction(OPEN_PLAYER_IN_BROWSER, this->split_, menu->addAction(OPEN_PLAYER_IN_BROWSER, this->split_,
&Split::openBrowserPlayer); &Split::openBrowserPlayer);
#endif #endif
menu->addAction(OPEN_IN_STREAMLINK, this->split_, menu->addAction(
&Split::openInStreamlink); OPEN_IN_STREAMLINK, this->split_, &Split::openInStreamlink,
h->getDisplaySequence(HotkeyCategory::Split, "openInStreamlink"));
if (!getSettings()->customURIScheme.getValue().isEmpty()) if (!getSettings()->customURIScheme.getValue().isEmpty())
{ {
menu->addAction("Open in custom player", this->split_, menu->addAction("Open in custom player", this->split_,
&Split::openWithCustomScheme); &Split::openWithCustomScheme,
h->getDisplaySequence(HotkeyCategory::Split,
"openInCustomPlayer"));
} }
if (this->split_->getChannel()->hasModRights()) if (this->split_->getChannel()->hasModRights())
{ {
menu->addAction(OPEN_MOD_VIEW_IN_BROWSER, this->split_, menu->addAction(
&Split::openModViewInBrowser); OPEN_MOD_VIEW_IN_BROWSER, this->split_,
&Split::openModViewInBrowser,
h->getDisplaySequence(HotkeyCategory::Split, "openModView"));
} }
menu->addAction( menu->addAction(
@@ -384,7 +400,7 @@ std::unique_ptr<QMenu> SplitHeader::createMainMenu()
[twitchChannel] { [twitchChannel] {
twitchChannel->createClip(); twitchChannel->createClip();
}, },
QKeySequence("Alt+X")) h->getDisplaySequence(HotkeyCategory::Split, "createClip"))
->setVisible(twitchChannel->isLive()); ->setVisible(twitchChannel->isLive());
menu->addSeparator(); menu->addSeparator();
@@ -392,24 +408,35 @@ std::unique_ptr<QMenu> SplitHeader::createMainMenu()
if (this->split_->getChannel()->getType() == Channel::Type::TwitchWhispers) if (this->split_->getChannel()->getType() == Channel::Type::TwitchWhispers)
{ {
menu->addAction(OPEN_WHISPERS_IN_BROWSER, this->split_, menu->addAction(
&Split::openWhispersInBrowser); OPEN_WHISPERS_IN_BROWSER, this->split_,
&Split::openWhispersInBrowser,
h->getDisplaySequence(HotkeyCategory::Split, "openInBrowser"));
menu->addSeparator(); menu->addSeparator();
} }
// reload / reconnect // reload / reconnect
if (this->split_->getChannel()->canReconnect()) if (this->split_->getChannel()->canReconnect())
{ {
menu->addAction("Reconnect", this, SLOT(reconnect()), menu->addAction(
QKeySequence("Ctrl+F5")); "Reconnect", this, SLOT(reconnect()),
h->getDisplaySequence(HotkeyCategory::Split, "reconnect"));
} }
if (twitchChannel) if (twitchChannel)
{ {
auto bothSeq =
h->getDisplaySequence(HotkeyCategory::Split, "reloadEmotes", {{}});
auto channelSeq = h->getDisplaySequence(HotkeyCategory::Split,
"reloadEmotes", {{"channel"}});
auto subSeq = h->getDisplaySequence(HotkeyCategory::Split,
"reloadEmotes", {{"subscriber"}});
menu->addAction("Reload channel emotes", this, menu->addAction("Reload channel emotes", this,
SLOT(reloadChannelEmotes()), QKeySequence("F5")); SLOT(reloadChannelEmotes()),
channelSeq.isEmpty() ? bothSeq : channelSeq);
menu->addAction("Reload subscriber emotes", this, menu->addAction("Reload subscriber emotes", this,
SLOT(reloadSubscriberEmotes()), QKeySequence("F5")); SLOT(reloadSubscriberEmotes()),
subSeq.isEmpty() ? bothSeq : subSeq);
} }
menu->addSeparator(); menu->addSeparator();
@@ -427,9 +454,20 @@ std::unique_ptr<QMenu> SplitHeader::createMainMenu()
// sub menu // sub menu
auto moreMenu = new QMenu("More", this); auto moreMenu = new QMenu("More", this);
moreMenu->addAction("Toggle moderation mode", this->split_, [this]() { auto modModeSeq = h->getDisplaySequence(HotkeyCategory::Split,
this->split_->setModerationMode(!this->split_->getModerationMode()); "setModerationMode", {{"toggle"}});
}); if (modModeSeq.isEmpty())
{
modModeSeq = h->getDisplaySequence(HotkeyCategory::Split,
"setModerationMode", {{}});
// this makes a full std::optional<> with an empty vector inside
}
moreMenu->addAction(
"Toggle moderation mode", this->split_,
[this]() {
this->split_->setModerationMode(!this->split_->getModerationMode());
},
modModeSeq);
if (this->split_->getChannel()->getType() == Channel::Type::TwitchMentions) if (this->split_->getChannel()->getType() == Channel::Type::TwitchMentions)
{ {
@@ -450,8 +488,9 @@ std::unique_ptr<QMenu> SplitHeader::createMainMenu()
if (twitchChannel) if (twitchChannel)
{ {
moreMenu->addAction("Show viewer list", this->split_, moreMenu->addAction(
&Split::showViewerList); "Show viewer list", this->split_, &Split::showViewerList,
h->getDisplaySequence(HotkeyCategory::Split, "openViewerList"));
moreMenu->addAction("Subscribe", this->split_, &Split::openSubPage); moreMenu->addAction("Subscribe", this->split_, &Split::openSubPage);
@@ -459,6 +498,16 @@ std::unique_ptr<QMenu> SplitHeader::createMainMenu()
action->setText("Notify when live"); action->setText("Notify when live");
action->setCheckable(true); action->setCheckable(true);
auto notifySeq = h->getDisplaySequence(
HotkeyCategory::Split, "setChannelNotification", {{"toggle"}});
if (notifySeq.isEmpty())
{
notifySeq = h->getDisplaySequence(HotkeyCategory::Split,
"setChannelNotification", {{}});
// this makes a full std::optional<> with an empty vector inside
}
action->setShortcut(notifySeq);
QObject::connect(moreMenu, &QMenu::aboutToShow, this, [action, this]() { QObject::connect(moreMenu, &QMenu::aboutToShow, this, [action, this]() {
action->setChecked(getApp()->notifications->isChannelNotified( action->setChecked(getApp()->notifications->isChannelNotified(
this->split_->getChannel()->getName(), Platform::Twitch)); this->split_->getChannel()->getName(), Platform::Twitch));
@@ -490,7 +539,9 @@ std::unique_ptr<QMenu> SplitHeader::createMainMenu()
} }
moreMenu->addSeparator(); moreMenu->addSeparator();
moreMenu->addAction("Clear messages", this->split_, &Split::clear); moreMenu->addAction(
"Clear messages", this->split_, &Split::clear,
h->getDisplaySequence(HotkeyCategory::Split, "clearMessages"));
// moreMenu->addSeparator(); // moreMenu->addSeparator();
// moreMenu->addAction("Show changelog", this, // moreMenu->addAction("Show changelog", this,
// SLOT(moreMenuShowChangelog())); // SLOT(moreMenuShowChangelog()));