mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
feat: add ghost mode options to macOS bar
This commit is contained in:
@@ -31,6 +31,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
|
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/ayu_settings.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -47,6 +51,9 @@ private:
|
|||||||
void buildAppleMenu(QMenu *main);
|
void buildAppleMenu(QMenu *main);
|
||||||
void buildFileMenu(QMenu *file);
|
void buildFileMenu(QMenu *file);
|
||||||
void buildEditMenu(QMenu *edit);
|
void buildEditMenu(QMenu *edit);
|
||||||
|
|
||||||
|
void buildGhostModeMenu(QMenu *ghostMode);
|
||||||
|
|
||||||
void buildWindowMenu(QMenu *window);
|
void buildWindowMenu(QMenu *window);
|
||||||
void retranslate();
|
void retranslate();
|
||||||
void ensureLanguageBound();
|
void ensureLanguageBound();
|
||||||
@@ -54,6 +61,8 @@ private:
|
|||||||
[[nodiscard]] bool clipboardHasText();
|
[[nodiscard]] bool clipboardHasText();
|
||||||
[[nodiscard]] Window::Controller *resolveActiveWindow() const;
|
[[nodiscard]] Window::Controller *resolveActiveWindow() const;
|
||||||
|
|
||||||
|
[[nodiscard]] GhostModeAccountSettings *resolveGhostSettings() const;
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
void withActiveWindow(Callback callback) {
|
void withActiveWindow(Callback callback) {
|
||||||
const auto window = resolveActiveWindow();
|
const auto window = resolveActiveWindow();
|
||||||
@@ -92,6 +101,12 @@ private:
|
|||||||
QAction *_monospace = nullptr;
|
QAction *_monospace = nullptr;
|
||||||
QAction *_clearFormat = nullptr;
|
QAction *_clearFormat = nullptr;
|
||||||
|
|
||||||
|
QMenu *_ghostModeMenu = nullptr;
|
||||||
|
QAction *_ghostMode = nullptr;
|
||||||
|
QAction *_readOnInteract = nullptr;
|
||||||
|
QAction *_scheduleMessages = nullptr;
|
||||||
|
QAction *_sendWithoutSound = nullptr;
|
||||||
|
|
||||||
NSPasteboard *_pasteboard = nullptr;
|
NSPasteboard *_pasteboard = nullptr;
|
||||||
int _pasteboardChangeCount = -1;
|
int _pasteboardChangeCount = -1;
|
||||||
bool _pasteboardHasText = false;
|
bool _pasteboardHasText = false;
|
||||||
@@ -135,6 +150,15 @@ Window::Controller *Manager::resolveActiveWindow() const {
|
|||||||
return active ? active : Core::App().activePrimaryWindow();
|
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() {
|
bool Manager::clipboardHasText() {
|
||||||
const auto current = static_cast<int>([_pasteboard changeCount]);
|
const auto current = static_cast<int>([_pasteboard changeCount]);
|
||||||
if (_pasteboardChangeCount != current) {
|
if (_pasteboardChangeCount != current) {
|
||||||
@@ -195,6 +219,27 @@ void Manager::retranslate() {
|
|||||||
if (_clearFormat) {
|
if (_clearFormat) {
|
||||||
_clearFormat->setText(tr::lng_menu_formatting_clear(tr::now));
|
_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() {
|
void Manager::ensureLanguageBound() {
|
||||||
@@ -285,6 +330,31 @@ void Manager::recomputeState() {
|
|||||||
_monospace,
|
_monospace,
|
||||||
disabled(Field::kTagPre) || disabled(Field::kTagCode));
|
disabled(Field::kTagPre) || disabled(Field::kTagCode));
|
||||||
ForceDisabled(_clearFormat, markdownState.disabled());
|
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) {
|
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) {
|
void Manager::buildWindowMenu(QMenu *window) {
|
||||||
const auto receiver = _menuBar.get();
|
const auto receiver = _menuBar.get();
|
||||||
_fullScreen = window->addAction(
|
_fullScreen = window->addAction(
|
||||||
@@ -554,6 +689,9 @@ void Manager::buildMenu() {
|
|||||||
buildAppleMenu(_menuBar->addMenu(u"AyuGram"_q));
|
buildAppleMenu(_menuBar->addMenu(u"AyuGram"_q));
|
||||||
buildFileMenu(_menuBar->addMenu(u"File"_q));
|
buildFileMenu(_menuBar->addMenu(u"File"_q));
|
||||||
buildEditMenu(_menuBar->addMenu(u"Edit"_q));
|
buildEditMenu(_menuBar->addMenu(u"Edit"_q));
|
||||||
|
|
||||||
|
buildGhostModeMenu(_menuBar->addMenu(u"Ghost Mode"_q));
|
||||||
|
|
||||||
buildWindowMenu(_menuBar->addMenu(u"Window"_q));
|
buildWindowMenu(_menuBar->addMenu(u"Window"_q));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,6 +719,9 @@ void Manager::destroy() {
|
|||||||
= _bold = _italic = _underline
|
= _bold = _italic = _underline
|
||||||
= _strikeOut = _blockquote = _monospace = _clearFormat
|
= _strikeOut = _blockquote = _monospace = _clearFormat
|
||||||
= nullptr;
|
= nullptr;
|
||||||
|
_ghostModeMenu = nullptr;
|
||||||
|
_ghostMode = _readOnInteract = _scheduleMessages = _sendWithoutSound
|
||||||
|
= nullptr;
|
||||||
_pasteboard = nullptr;
|
_pasteboard = nullptr;
|
||||||
_pasteboardChangeCount = -1;
|
_pasteboardChangeCount = -1;
|
||||||
_pasteboardHasText = false;
|
_pasteboardHasText = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user