feat: streamer mode

Co-authored-by: MaxPlays35 <35427519+maxplays35@users.noreply.github.com>
This commit is contained in:
ZavaruKitsu 2023-08-30 20:07:23 +00:00
parent 7fe6ca1f41
commit 8e8719870a
24 changed files with 331 additions and 29 deletions

View file

@ -102,6 +102,8 @@ PRIVATE
ayu/ayu_lang.cpp
ayu/ayu_lang.h
ayu/ayu_constants.h
ayu/utils/telegram_helpers.cpp
ayu/utils/telegram_helpers.h
ayu/ui/ayu_lottie.cpp
ayu/ui/ayu_lottie.h
ayu/ui/utils/ayu_profile_values.cpp
@ -126,8 +128,6 @@ PRIVATE
ayu/sync/utils/ayu_pipe_wrapper.cpp
ayu/sync/utils/ayu_pipe_wrapper.h
ayu/sync/utils/process_utils.hpp
ayu/sync/utils/telegram_helpers.cpp
ayu/sync/utils/telegram_helpers.h
ayu/messages/ayu_messages_controller.cpp
ayu/messages/ayu_messages_controller.h
ayu/libs/pipe.hpp
@ -137,6 +137,9 @@ PRIVATE
ayu/libs/sqlite/sqlite3.c
ayu/libs/sqlite/sqlite3.h
ayu/libs/sqlite/sqlite_orm.h
ayu/features/streamer_mode/streamer_mode_windows.cpp
ayu/features/streamer_mode/streamer_mode_linux.cpp
ayu/features/streamer_mode/streamer_mode.h
ayu/database/entities.h
ayu/database/ayu_database.cpp
ayu/database/ayu_database.h

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -4082,10 +4082,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_AyuSyncStatusTitle" = "Sync status";
"ayu_AyuSyncStatusOk" = "connected";
"ayu_AyuSyncStatusErrorDisconnected" = "disconnected";
"ayu_AyuSyncStatusErrorNotRegistered" = "not registered";
"ayu_AyuSyncStatusErrorNoToken" = "no token";
"ayu_AyuSyncStatusErrorInvalidToken" = "invalid token";
"ayu_AyuSyncStatusErrorNoMVP" = "no MVP";
"ayu_AyuSyncServerURL" = "Server URL";
"ayu_AyuSyncServerToken" = "Access token";
"ayu_AyuSyncEnable" = "Enable synchronization";
@ -4100,6 +4098,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_AyuSyncRegisterStatusCode" = "Register status code";
"ayu_AyuSyncOpenPreferences" = "Open preferences";
"ayu_AyuSyncDownloadAgent" = "Download agent";
"ayu_IconDefault" = "Default";
"ayu_IconAlternative" = "AyuGram Alt";
"ayu_IconNothing" = "Nothing";
"ayu_WALMode" = "Enable WAL mode";
"ayu_ClearAyuDatabase" = "Clear Ayu Database";
"ayu_ClearAyuDatabaseNotification" = "AyuGram database cleared";
@ -4110,17 +4111,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_StickerConfirmation" = "Confirmation when sending stickers";
"ayu_GIFConfirmation" = "Confirmation when sending GIFs";
"ayu_VoiceConfirmation" = "Confirmation when sending voice messages";
"ayu_EnableGhostMode" = "Enable Ghost";
"ayu_DisableGhostMode" = "Disable Ghost";
"ayu_KillApp" = "Kill App";
"ayu_LReadMessages" = "Read on Local";
"ayu_SReadMessages" = "Read on Server";
"ayu_GhostModeToggle" = "Ghost Mode";
"ayu_EnableGhostMode" = "Enable Ghost";
"ayu_DisableGhostMode" = "Disable Ghost";
"ayu_EnableGhostModeTray" = "Enable Ghost Mode";
"ayu_DisableGhostModeTray" = "Disable Ghost Mode";
"ayu_GhostModeEnabled" = "Ghost mode turned on";
"ayu_GhostModeDisabled" = "Ghost mode turned off";
"ayu_StreamerModeToggle" = "Streamer Mode";
"ayu_EnableStreamerModeTray" = "Enable Streamer Mode";
"ayu_DisableStreamerModeTray" = "Disable Streamer Mode";
"ayu_EditsHistoryTitle" = "Edits history";
"ayu_EditsHistoryMenuText" = "History";
"ayu_ReadUntilMenuText" = "Read until";
"ayu_ReadUntilMenuText" = "Read Message";
"ayu_DeleteKeepLocally" = "Keep locally";
"ayu_BoxActionReset" = "Reset";
"ayu_ReadConfirmationBoxQuestion" = "Do you want to read all messages?";
@ -4139,3 +4145,4 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_ContextCopyCallbackData" = "Copy Callback Data";
"ayu_LocalPremiumNotice" = "You're using **local** Telegram Premium.\nIt **won't** give you any benefits, except translator.\n**Enjoy the star near your nickname!**";
"ayu_SettingsWatermark" = "AyuGram developed and maintained by Radolyn Labs.";
"ayu_UtilityRestartRequired" = "App will close in 5 seconds.";

View file

@ -224,6 +224,11 @@ namespace AyuSettings
localPremium = val;
}
void AyuGramSettings::set_copyUsernameAsLink(bool val)
{
copyUsernameAsLink = val;
}
void AyuGramSettings::set_deletedMark(QString val)
{
deletedMark = std::move(val);
@ -277,11 +282,6 @@ namespace AyuSettings
voiceConfirmation = val;
}
void AyuGramSettings::set_copyUsernameAsLink(bool val)
{
copyUsernameAsLink = val;
}
bool get_ghostModeEnabled()
{
return ghostModeEnabled.current();

View file

@ -9,7 +9,7 @@
#include "entities.h"
#include "ayu/libs/sqlite/sqlite_orm.h"
#include "ayu/sync/utils/telegram_helpers.h"
#include "ayu/utils/telegram_helpers.h"
using namespace sqlite_orm;
auto storage = make_storage(

View file

@ -0,0 +1,19 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
#pragma once
#include "ui/rp_widget.h"
namespace AyuFeatures::StreamerMode
{
bool isEnabled();
void enable();
void disable();
void hideWidgetWindow(QWidget* widget);
void showWidgetWindow(QWidget* widget);
}

View file

@ -0,0 +1,43 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
#ifndef WIN32
#include "streamer_mode.h"
#include "core/application.h"
#include "window/window_controller.h"
namespace AyuFeatures::StreamerMode
{
bool isEnabledVal;
bool isEnabled()
{
return isEnabledVal;
}
void enable()
{
isEnabledVal = true;
}
void disable()
{
isEnabledVal = false;
}
void hideWidgetWindow(QWidget* widget) {
}
void showWidgetWindow(QWidget* widget) {
}
}
#endif

View file

@ -0,0 +1,53 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
#ifdef WIN32
#include "streamer_mode.h"
#include "core/application.h"
#include "window/window_controller.h"
namespace AyuFeatures::StreamerMode
{
bool isEnabledVal;
bool isEnabled()
{
return isEnabledVal;
}
void enable()
{
auto handle = Core::App().activeWindow()->widget()->psHwnd();
SetWindowDisplayAffinity(handle, WDA_EXCLUDEFROMCAPTURE);
isEnabledVal = true;
}
void disable()
{
auto handle = Core::App().activeWindow()->widget()->psHwnd();
SetWindowDisplayAffinity(handle, WDA_NONE);
isEnabledVal = false;
}
void hideWidgetWindow(QWidget* widget)
{
auto handle = reinterpret_cast<HWND>(widget->window()->winId());
SetWindowDisplayAffinity(handle, WDA_EXCLUDEFROMCAPTURE);
}
void showWidgetWindow(QWidget* widget)
{
auto handle = reinterpret_cast<HWND>(widget->window()->winId());
SetWindowDisplayAffinity(handle, WDA_NONE);
}
}
#endif

View file

@ -9,7 +9,7 @@
#include "ayu/ayu_constants.h"
#include "ayu/database/ayu_database.h"
#include "ayu/sync/utils/telegram_helpers.h"
#include "ayu/utils/telegram_helpers.h"
#include "base/unixtime.h"

View file

@ -9,7 +9,7 @@
#include "ayu/libs/process.hpp"
#include "ayu/sync/models.h"
#include "ayu/sync/utils/process_utils.hpp"
#include "ayu/sync/utils/telegram_helpers.h"
#include "ayu/utils/telegram_helpers.h"
#include "data/data_session.h"
#include "history/history.h"

View file

@ -5,3 +5,4 @@ ayuGhostIcon: icon {{ "ayu/ghost", menuIconColor }};
ayuMenuIcon: icon {{ "ayu/ayu_menu", menuIconColor }};
ayuLReadMenuIcon: icon {{ "ayu/lread", menuIconColor }};
ayuSReadMenuIcon: icon {{ "ayu/sread", menuIconColor }};
ayuStreamerModeMenuIcon: icon {{ "ayu/streamer", menuIconColor }};

View file

@ -15,11 +15,15 @@
#include "lang_auto.h"
#include "mainwindow.h"
#include "api/api_blocked_peers.h"
#include "ayu/features/streamer_mode/streamer_mode.h"
#include "boxes/connection_box.h"
#include "core/application.h"
#include "data/data_session.h"
#include "lang/lang_instance.h"
#include "main/main_session.h"
#include "media/system_media_controls_manager.h"
#include "platform/platform_specific.h"
#include "settings/settings_common.h"
#include "storage/localstorage.h"
@ -31,6 +35,7 @@
#include "styles/style_widgets.h"
#include "ui/painter.h"
#include "ui/boxes/confirm_box.h"
#include "ui/boxes/single_choice_box.h"
#include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
@ -45,6 +50,17 @@ constexpr auto GhostModeOptionsCount = 5;
class PainterHighQualityEnabler;
const char kStreamerMode[] =
"streamer-mode";
base::options::toggle StreamerMode({
.id = kStreamerMode,
.name = "Show streamer mode toggles",
.description = "Streamer mode completely hides AyuGram windows and notifications from capture apps.",
.scope = base::options::windows,
.restartRequired = true
});
not_null<Ui::RpWidget*> AddInnerToggle(
not_null<Ui::VerticalLayout*> container,
const style::SettingsButton& st,
@ -112,7 +128,7 @@ not_null<Ui::RpWidget*> AddInnerToggle(
) | start_with_next([=](const QRect& r)
{
const auto w = st::rightsButtonToggleWidth;
constexpr auto kLineWidth = static_cast<int>(1);
constexpr auto kLineWidth = 1;
toggleButton->setGeometry(
r.x() + r.width() - w,
r.y(),
@ -267,6 +283,69 @@ namespace Settings
setupContent(controller);
}
void Ayu::AddPlatformOption(
not_null<Window::SessionController*> window,
not_null<Ui::VerticalLayout*> container,
base::options::option<bool>& option,
rpl::producer<> resetClicks)
{
auto& lifetime = container->lifetime();
const auto name = option.name().isEmpty() ? option.id() : option.name();
const auto toggles = lifetime.make_state<rpl::event_stream<bool>>();
std::move(
resetClicks
) | rpl::map_to(
option.defaultValue()
) | start_to_stream(*toggles, lifetime);
const auto button = AddButton(
container,
rpl::single(name),
(option.relevant()
? st::settingsButtonNoIcon
: st::settingsOptionDisabled)
)->toggleOn(toggles->events_starting_with(option.value()));
const auto restarter = (option.relevant() && option.restartRequired())
? button->lifetime().make_state<base::Timer>()
: nullptr;
if (restarter)
{
restarter->setCallback([=]
{
window->show(Ui::MakeConfirmBox({
.text = tr::lng_settings_need_restart(),
.confirmed = [] { Core::Restart(); },
.confirmText = tr::lng_settings_restart_now(),
.cancelText = tr::lng_settings_restart_later(),
}));
});
}
button->toggledChanges(
) | start_with_next([=, &option](bool toggled)
{
if (!option.relevant() && toggled != option.defaultValue())
{
toggles->fire_copy(option.defaultValue());
window->showToast(
tr::lng_settings_experimental_irrelevant(tr::now));
return;
}
option.set(toggled);
if (restarter)
{
restarter->callOnce(st::settingsButtonNoIcon.toggle.duration);
}
}, container->lifetime());
const auto& description = option.description();
if (!description.isEmpty())
{
AddSkip(container);
AddDividerText(container, rpl::single(description));
}
}
void Ayu::SetupGhostEssentials(not_null<Ui::VerticalLayout*> container)
{
auto settings = &AyuSettings::getInstance();
@ -333,11 +412,6 @@ namespace Settings
std::function<void(bool)> callback;
};
struct LabeledEntryGroup
{
std::vector<NestedEntry> nested;
};
std::vector checkboxes{
NestedEntry{
tr::ayu_DontReadMessages(tr::now), !settings->sendReadMessages, [=](bool enabled)
@ -791,6 +865,13 @@ namespace Settings
}, container->lifetime());
}
void Ayu::SetupExperimental(not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionController*> controller)
{
AddSubsectionTitle(container, tr::lng_settings_experimental());
AddPlatformOption(controller, container, StreamerMode, rpl::producer<>());
}
void Ayu::SetupAyuGramSettings(not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionController*> controller)
{
@ -818,7 +899,7 @@ namespace Settings
AddDividerText(container, tr::ayu_SettingsCustomizationHint());
// todo: compilation flag
if (false)
if constexpr (false)
{
AddSkip(container);
SetupAyuSync(container);
@ -831,6 +912,9 @@ namespace Settings
SetupSendConfirmations(container);
AddSkip(container);
AddDivider(container);
SetupExperimental(container, controller);
AddDividerText(container, tr::ayu_SettingsWatermark());
}

View file

@ -7,6 +7,7 @@
#pragma once
#include "base/options.h"
#include "settings/settings_common.h"
class BoxContent;
@ -18,6 +19,9 @@ namespace Window
class SessionController;
} // namespace Window
extern const char kStreamerMode[];
extern base::options::toggle StreamerMode;
namespace Settings
{
class Ayu : public Section<Ayu>
@ -28,6 +32,12 @@ namespace Settings
[[nodiscard]] rpl::producer<QString> title() override;
private:
void AddPlatformOption(
not_null<Window::SessionController*> window,
not_null<Ui::VerticalLayout*> container,
base::options::option<bool>& option,
rpl::producer<> resetClicks);
void SetupGhostEssentials(not_null<Ui::VerticalLayout*> container);
void SetupSpyEssentials(not_null<Ui::VerticalLayout*> container);
@ -45,6 +55,9 @@ namespace Settings
void SetupSendConfirmations(not_null<Ui::VerticalLayout*> container);
void SetupExperimental(not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionController*> controller);
void SetupAyuGramSettings(not_null<Ui::VerticalLayout*> container, not_null<Window::SessionController*> null);
void setupContent(not_null<Window::SessionController*> controller);

View file

@ -22,7 +22,7 @@
Main::Session* getSession(ID userId)
{
for (auto& [index, account] : Core::App().domain().accounts())
for (const auto& [index, account] : Core::App().domain().accounts())
{
if (const auto session = account->maybeSession())
{

View file

@ -28,7 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
// AyuGram includes
#include "ayu/ayu_settings.h"
#include "ayu/sync/utils/telegram_helpers.h"
#include "ayu/utils/telegram_helpers.h"
namespace {

View file

@ -110,6 +110,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <kurlmimedata.h>
// AyuGram includes
#include "ayu/features/streamer_mode/streamer_mode.h"
namespace Media {
namespace View {
namespace {
@ -3250,6 +3254,13 @@ void OverlayWidget::activate() {
setFocus();
QApplication::setActiveWindow(_window);
setFocus();
if (AyuFeatures::StreamerMode::isEnabled())
{
AyuFeatures::StreamerMode::hideWidgetWindow(_window);
} else {
AyuFeatures::StreamerMode::showWidgetWindow(_window);
}
}
void OverlayWidget::show(OpenRequest request) {

View file

@ -42,6 +42,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtGui/QScreen>
#include <QtWidgets/QApplication>
// AyuGram includes
#include "ayu/features/streamer_mode/streamer_mode.h"
namespace Media {
namespace View {
namespace {
@ -957,6 +961,13 @@ void Pip::setupPanel() {
_panel.setPosition(Deserialize(_delegate->pipLoadGeometry()));
_panel.widget()->show();
if (AyuFeatures::StreamerMode::isEnabled())
{
AyuFeatures::StreamerMode::hideWidgetWindow(_panel.widget());
} else {
AyuFeatures::StreamerMode::showWidgetWindow(_panel.widget());
}
_panel.saveGeometryRequests(
) | rpl::start_with_next([=] {
saveGeometry();

View file

@ -13,7 +13,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_specific.h"
#include <QtWidgets/QApplication>
#include <ayu/ayu_settings.h>
// AyuGram includes
#include "ayu/ayu_settings.h"
#include "ayu/ui/settings/settings_ayu.h"
#include "ayu/features/streamer_mode/streamer_mode.h"
namespace Core {
@ -96,10 +101,9 @@ void Tray::rebuildMenu() {
bool ghostModeEnabled = AyuSettings::get_ghostModeEnabled();
return ghostModeEnabled
? tr::ayu_DisableGhostMode(tr::now)
: tr::ayu_EnableGhostMode(tr::now);
? tr::ayu_DisableGhostModeTray(tr::now)
: tr::ayu_EnableGhostModeTray(tr::now);
});
_tray.addAction(std::move(turnGhostModeText), [=]
{
auto settings = &AyuSettings::getInstance();
@ -110,6 +114,24 @@ void Tray::rebuildMenu() {
AyuSettings::save();
});
if (StreamerMode.value()) {
auto turnStreamerModeText = _textUpdates.events(
) | rpl::map([=] {
bool streamerModeEnabled = AyuFeatures::StreamerMode::isEnabled();
return streamerModeEnabled
? tr::ayu_DisableStreamerModeTray(tr::now)
: tr::ayu_EnableStreamerModeTray(tr::now);
});
_tray.addAction(std::move(turnStreamerModeText), [=] {
if (AyuFeatures::StreamerMode::isEnabled()) {
AyuFeatures::StreamerMode::disable();
} else {
AyuFeatures::StreamerMode::enable();
}
});
}
auto quitText = _textUpdates.events(
) | rpl::map([=]
{

View file

@ -43,6 +43,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
// AyuGram includes
#include "ayu/features/streamer_mode/streamer_mode.h"
namespace Window {
namespace Notifications {
namespace Default {
@ -699,6 +703,11 @@ Notification::Notification(
}, lifetime());
show();
if (AyuFeatures::StreamerMode::isEnabled())
{
AyuFeatures::StreamerMode::hideWidgetWindow(this);
}
}
void Notification::updateReplyGeometry() {
@ -1239,6 +1248,11 @@ HideAllButton::HideAllButton(
}, lifetime());
show();
if (AyuFeatures::StreamerMode::isEnabled())
{
AyuFeatures::StreamerMode::hideWidgetWindow(this);
}
}
void HideAllButton::startHiding() {

View file

@ -82,10 +82,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtGui/QGuiApplication>
#include <QtGui/QClipboard>
// AyuGram includes
#include "ayu/ayu_settings.h"
#include "ayu/ui/settings/settings_ayu.h"
#include "ayu/features/streamer_mode/streamer_mode.h"
#include "ayu/ui/boxes/confirmation_box.h"
#include "styles/style_ayu_icons.h"
namespace Window {
namespace {
@ -908,6 +912,22 @@ void MainMenu::setupMenu() {
}, _ghostModeToggle->lifetime());
}
if (StreamerMode.value()) {
_streamerModeToggle = addAction(
tr::ayu_StreamerModeToggle(),
{ &st::ayuStreamerModeMenuIcon }
)->toggleOn(rpl::single(AyuFeatures::StreamerMode::isEnabled()));
_streamerModeToggle->toggledChanges(
) | rpl::start_with_next([=](bool enabled) {
if (enabled) {
AyuFeatures::StreamerMode::enable();
} else {
AyuFeatures::StreamerMode::disable();
}
}, _streamerModeToggle->lifetime());
}
Core::App().settings().systemDarkModeValue(
) | rpl::start_with_next([=](std::optional<bool> darkMode) {
const auto darkModeEnabled

View file

@ -95,7 +95,8 @@ private:
not_null<Ui::FlatLabel*> _telegram;
not_null<Ui::FlatLabel*> _version;
QPointer<Ui::SettingsButton> _nightThemeToggle;
QPointer<Ui::SettingsButton> _ghostModeToggle;
QPointer<Ui::SettingsButton> _ghostModeToggle;
QPointer<Ui::SettingsButton> _streamerModeToggle;
rpl::event_stream<bool> _nightThemeSwitches;
base::Timer _nightThemeSwitch;
base::unique_qptr<Ui::PopupMenu> _contextMenu;