diff --git a/Telegram/SourceFiles/platform/mac/global_menu_mac.mm b/Telegram/SourceFiles/platform/mac/global_menu_mac.mm index 5db89e694a..68da50703a 100644 --- a/Telegram/SourceFiles/platform/mac/global_menu_mac.mm +++ b/Telegram/SourceFiles/platform/mac/global_menu_mac.mm @@ -31,6 +31,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include +// AyuGram includes +#include "ayu/ayu_settings.h" + + namespace Platform { namespace { @@ -47,6 +51,9 @@ private: void buildAppleMenu(QMenu *main); void buildFileMenu(QMenu *file); void buildEditMenu(QMenu *edit); + + void buildGhostModeMenu(QMenu *ghostMode); + void buildWindowMenu(QMenu *window); void retranslate(); void ensureLanguageBound(); @@ -54,6 +61,8 @@ private: [[nodiscard]] bool clipboardHasText(); [[nodiscard]] Window::Controller *resolveActiveWindow() const; + [[nodiscard]] GhostModeAccountSettings *resolveGhostSettings() const; + template void withActiveWindow(Callback callback) { const auto window = resolveActiveWindow(); @@ -92,6 +101,12 @@ private: QAction *_monospace = nullptr; QAction *_clearFormat = nullptr; + QMenu *_ghostModeMenu = nullptr; + QAction *_ghostMode = nullptr; + QAction *_readOnInteract = nullptr; + QAction *_scheduleMessages = nullptr; + QAction *_sendWithoutSound = nullptr; + NSPasteboard *_pasteboard = nullptr; int _pasteboardChangeCount = -1; bool _pasteboardHasText = false; @@ -135,6 +150,15 @@ Window::Controller *Manager::resolveActiveWindow() const { return active ? active : Core::App().activePrimaryWindow(); } +GhostModeAccountSettings *Manager::resolveGhostSettings() const { + const auto window = resolveActiveWindow(); + if (!window || window->locked()) { + return nullptr; + } + const auto session = window->maybeSession(); + return session ? &AyuSettings::ghost(session) : nullptr; +} + bool Manager::clipboardHasText() { const auto current = static_cast([_pasteboard changeCount]); if (_pasteboardChangeCount != current) { @@ -195,6 +219,27 @@ void Manager::retranslate() { if (_clearFormat) { _clearFormat->setText(tr::lng_menu_formatting_clear(tr::now)); } + if (_ghostModeMenu) { + _ghostModeMenu->setTitle(tr::ayu_CategoryGhostMode(tr::now)); + } + if (_ghostMode) { + if (const auto ghost = resolveGhostSettings()) { + _ghostMode->setText(ghost->isGhostModeActive() + ? tr::ayu_DisableGhostMode(tr::now) + : tr::ayu_EnableGhostMode(tr::now)); + } else { + _ghostMode->setText(tr::ayu_EnableGhostMode(tr::now)); + } + } + if (_readOnInteract) { + _readOnInteract->setText(tr::ayu_MarkReadAfterAction(tr::now)); + } + if (_scheduleMessages) { + _scheduleMessages->setText(tr::ayu_UseScheduledMessages(tr::now)); + } + if (_sendWithoutSound) { + _sendWithoutSound->setText(tr::ayu_SendWithoutSoundByDefault(tr::now)); + } } void Manager::ensureLanguageBound() { @@ -285,6 +330,31 @@ void Manager::recomputeState() { _monospace, disabled(Field::kTagPre) || disabled(Field::kTagCode)); ForceDisabled(_clearFormat, markdownState.disabled()); + + const auto ghost = resolveGhostSettings(); + const auto ghostInactive = (ghost == nullptr); + ForceDisabled(_ghostMode, ghostInactive); + ForceDisabled(_readOnInteract, ghostInactive); + ForceDisabled(_scheduleMessages, ghostInactive); + ForceDisabled(_sendWithoutSound, ghostInactive); + const auto setChecked = [](QAction *action, bool checked) { + const auto wasBlocked = action->blockSignals(true); + action->setChecked(checked); + action->blockSignals(wasBlocked); + }; + if (ghost) { + _ghostMode->setText(ghost->isGhostModeActive() + ? tr::ayu_DisableGhostMode(tr::now) + : tr::ayu_EnableGhostMode(tr::now)); + setChecked(_readOnInteract, ghost->markReadAfterAction()); + setChecked(_scheduleMessages, ghost->useScheduledMessages()); + setChecked(_sendWithoutSound, ghost->sendWithoutSound()); + } else { + _ghostMode->setText(tr::ayu_EnableGhostMode(tr::now)); + setChecked(_readOnInteract, false); + setChecked(_scheduleMessages, false); + setChecked(_sendWithoutSound, false); + } } void Manager::buildAppleMenu(QMenu *main) { @@ -466,6 +536,71 @@ void Manager::buildEditMenu(QMenu *edit) { } } +void Manager::buildGhostModeMenu(QMenu *ghostMode) { + _ghostModeMenu = ghostMode; + QObject::connect(ghostMode, &QMenu::aboutToShow, ghostMode, [this] { + requestUpdate(); + }); + + const auto addToggle = [&](QString text, auto callback) { + const auto action = ghostMode->addAction(std::move(text)); + action->setCheckable(true); + QObject::connect( + action, + &QAction::triggered, + action, + [this, callback = std::move(callback)](bool checked) { + callback(checked); + requestUpdate(); + }); + return action; + }; + + _ghostMode = ghostMode->addAction(u"Enable Ghost"_q); + QObject::connect( + _ghostMode, + &QAction::triggered, + _ghostMode, + [this] { + if (const auto ghost = resolveGhostSettings()) { + ghost->setGhostModeEnabled(!ghost->isGhostModeActive()); + } + requestUpdate(); + }); + + ghostMode->addSeparator(); + + _readOnInteract = addToggle( + u"Read on Interact"_q, + [this](bool enabled) { + if (const auto ghost = resolveGhostSettings()) { + ghost->setMarkReadAfterAction(enabled); + if (enabled) { + ghost->setUseScheduledMessages(false); + } + } + }); + + _scheduleMessages = addToggle( + u"Schedule Messages"_q, + [this](bool enabled) { + if (const auto ghost = resolveGhostSettings()) { + ghost->setUseScheduledMessages(enabled); + if (enabled) { + ghost->setMarkReadAfterAction(false); + } + } + }); + + _sendWithoutSound = addToggle( + u"Send without Sound"_q, + [this](bool enabled) { + if (const auto ghost = resolveGhostSettings()) { + ghost->setSendWithoutSound(enabled); + } + }); +} + void Manager::buildWindowMenu(QMenu *window) { const auto receiver = _menuBar.get(); _fullScreen = window->addAction( @@ -554,6 +689,9 @@ void Manager::buildMenu() { buildAppleMenu(_menuBar->addMenu(u"AyuGram"_q)); buildFileMenu(_menuBar->addMenu(u"File"_q)); buildEditMenu(_menuBar->addMenu(u"Edit"_q)); + + buildGhostModeMenu(_menuBar->addMenu(u"Ghost Mode"_q)); + buildWindowMenu(_menuBar->addMenu(u"Window"_q)); } @@ -581,6 +719,9 @@ void Manager::destroy() { = _bold = _italic = _underline = _strikeOut = _blockquote = _monospace = _clearFormat = nullptr; + _ghostModeMenu = nullptr; + _ghostMode = _readOnInteract = _scheduleMessages = _sendWithoutSound + = nullptr; _pasteboard = nullptr; _pasteboardChangeCount = -1; _pasteboardHasText = false;