mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
chore: rewrite settings to new builder & support settings links from android version
This commit is contained in:
@@ -141,6 +141,8 @@ set(ayugram_files
|
|||||||
ayu/ui/utils/palette.h
|
ayu/ui/utils/palette.h
|
||||||
ayu/ui/utils/itunes_search.cpp
|
ayu/ui/utils/itunes_search.cpp
|
||||||
ayu/ui/utils/itunes_search.h
|
ayu/ui/utils/itunes_search.h
|
||||||
|
ayu/ui/settings/ayu_builder.cpp
|
||||||
|
ayu/ui/settings/ayu_builder.h
|
||||||
ayu/ui/settings/settings_appearance.cpp
|
ayu/ui/settings/settings_appearance.cpp
|
||||||
ayu/ui/settings/settings_appearance.h
|
ayu/ui/settings/settings_appearance.h
|
||||||
ayu/ui/settings/settings_ayu_utils.cpp
|
ayu/ui/settings/settings_ayu_utils.cpp
|
||||||
|
|||||||
@@ -466,7 +466,7 @@ void AyuSettings::validate() {
|
|||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
validateRange(_wideMultiplier, 0.5, 3.0, defaults._wideMultiplier);
|
validateRange(_wideMultiplier, 0.5, 4.0, defaults._wideMultiplier);
|
||||||
validateRange(_recentStickersCount, 1, 200, defaults._recentStickersCount);
|
validateRange(_recentStickersCount, 1, 200, defaults._recentStickersCount);
|
||||||
|
|
||||||
const auto embeddedType = _messageShotSettings._embeddedThemeType.current();
|
const auto embeddedType = _messageShotSettings._embeddedThemeType.current();
|
||||||
|
|||||||
@@ -6,22 +6,20 @@
|
|||||||
// Copyright @Radolyn, 2026
|
// Copyright @Radolyn, 2026
|
||||||
#include "ayu/ayu_url_handlers.h"
|
#include "ayu/ayu_url_handlers.h"
|
||||||
|
|
||||||
#include "base/qthelp_url.h"
|
#include <QDesktopServices>
|
||||||
|
|
||||||
#include "lang_auto.h"
|
#include "lang_auto.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "ayu/ui/settings/settings_main.h"
|
||||||
#include "ayu/utils/telegram_helpers.h"
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
|
#include "base/qthelp_url.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
|
||||||
|
|
||||||
#include <QDesktopServices>
|
|
||||||
|
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "settings/settings_builder.h"
|
||||||
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "ui/boxes/donate_info_box.h"
|
#include "ui/boxes/donate_info_box.h"
|
||||||
#include "ui/settings/settings_main.h"
|
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
|
|
||||||
namespace AyuUrlHandlers {
|
namespace AyuUrlHandlers {
|
||||||
@@ -146,6 +144,46 @@ bool HandleSupport(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ::Settings::Type SectionForSetting(
|
||||||
|
const QString &controlId,
|
||||||
|
not_null<::Main::Session*> session) {
|
||||||
|
const auto ®istry = ::Settings::Builder::SearchRegistry::Instance();
|
||||||
|
const auto entries = registry.collectAll(session);
|
||||||
|
for (const auto &entry : entries) {
|
||||||
|
if (entry.id == controlId && entry.section) {
|
||||||
|
return entry.section;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ::Settings::AyuMain::Id();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HandleAyuSettings(
|
||||||
|
Window::SessionController *controller,
|
||||||
|
const Match &match,
|
||||||
|
const QVariant &context) {
|
||||||
|
if (!controller) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto params = url_parse_params(
|
||||||
|
match->captured(1),
|
||||||
|
qthelp::UrlParamNameTransform::ToLower);
|
||||||
|
const auto settingName = params.value(u"s"_q);
|
||||||
|
|
||||||
|
if (settingName.isEmpty()) {
|
||||||
|
controller->showSettings(::Settings::AyuMain::Id());
|
||||||
|
} else {
|
||||||
|
const auto controlId = u"ayu/"_q + settingName;
|
||||||
|
controller->window().setHighlightControlId(controlId);
|
||||||
|
const auto section = SectionForSetting(
|
||||||
|
controlId,
|
||||||
|
&controller->session());
|
||||||
|
controller->showSettings(section);
|
||||||
|
}
|
||||||
|
controller->window().activate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool TryHandleSpotify(const QString &url) {
|
bool TryHandleSpotify(const QString &url) {
|
||||||
if (!url.contains("spotify.com")) {
|
if (!url.contains("spotify.com")) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ bool HandleSupport(
|
|||||||
const Match &match,
|
const Match &match,
|
||||||
const QVariant &context);
|
const QVariant &context);
|
||||||
|
|
||||||
|
bool HandleAyuSettings(
|
||||||
|
Window::SessionController *controller,
|
||||||
|
const Match &match,
|
||||||
|
const QVariant &context);
|
||||||
|
|
||||||
bool TryHandleSpotify(const QString &url);
|
bool TryHandleSpotify(const QString &url);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,251 @@
|
|||||||
|
// 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, 2026
|
||||||
|
#include "ayu/ui/settings/ayu_builder.h"
|
||||||
|
|
||||||
|
#include "ayu/ayu_settings.h"
|
||||||
|
#include "ayu/ui/settings/settings_ayu_utils.h"
|
||||||
|
#include "settings/settings_common.h"
|
||||||
|
#include "styles/style_ayu_styles.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
#include "ui/boxes/single_choice_box.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/widgets/continuous_sliders.h"
|
||||||
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
|
namespace Settings::AyBuilder {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] QString ResolveTitle(rpl::producer<QString> title) {
|
||||||
|
auto result = QString();
|
||||||
|
auto lifetime = rpl::lifetime();
|
||||||
|
std::move(title).start(
|
||||||
|
[&](QString value) { result = std::move(value); },
|
||||||
|
[](auto&&) {},
|
||||||
|
[] {},
|
||||||
|
lifetime);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
AyuSectionBuilder::AyuSectionBuilder(Builder::SectionBuilder &builder)
|
||||||
|
: _builder(builder) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder::SectionBuilder &AyuSectionBuilder::base() {
|
||||||
|
return _builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ui::SettingsButton *AyuSectionBuilder::addSettingToggle(
|
||||||
|
SettingToggleArgs &&args) {
|
||||||
|
auto getter = [g = args.getter] {
|
||||||
|
return (AyuSettings::getInstance().*g)();
|
||||||
|
};
|
||||||
|
auto setter = [s = args.setter](bool v) {
|
||||||
|
(AyuSettings::getInstance().*s)(v);
|
||||||
|
};
|
||||||
|
return addToggle({
|
||||||
|
.id = std::move(args.id),
|
||||||
|
.title = std::move(args.title),
|
||||||
|
.getter = std::move(getter),
|
||||||
|
.setter = std::move(setter),
|
||||||
|
.icon = std::move(args.icon),
|
||||||
|
.keywords = std::move(args.keywords),
|
||||||
|
.shown = std::move(args.shown),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ui::SettingsButton *AyuSectionBuilder::addToggle(ToggleArgs &&args) {
|
||||||
|
auto getter = std::move(args.getter);
|
||||||
|
auto setter = std::move(args.setter);
|
||||||
|
const auto initialValue = getter();
|
||||||
|
|
||||||
|
const auto button = _builder.addButton({
|
||||||
|
.id = std::move(args.id),
|
||||||
|
.title = std::move(args.title),
|
||||||
|
.st = args.icon.icon ? nullptr : &st::settingsButtonNoIcon,
|
||||||
|
.icon = std::move(args.icon),
|
||||||
|
.toggled = rpl::single(initialValue),
|
||||||
|
.keywords = std::move(args.keywords),
|
||||||
|
.shown = std::move(args.shown),
|
||||||
|
});
|
||||||
|
if (button) {
|
||||||
|
button->toggledValue(
|
||||||
|
) | rpl::filter(
|
||||||
|
[=](bool enabled) {
|
||||||
|
return (enabled != getter());
|
||||||
|
}
|
||||||
|
) | rpl::on_next(
|
||||||
|
[=](bool enabled) {
|
||||||
|
setter(enabled);
|
||||||
|
},
|
||||||
|
button->lifetime());
|
||||||
|
}
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fn<void()> AyuSectionBuilder::addCollapsibleToggle(
|
||||||
|
CollapsibleToggleArgs &&args) {
|
||||||
|
auto resolvedTitle = ResolveTitle(rpl::duplicate(args.title));
|
||||||
|
auto checkboxes = std::move(args.checkboxes);
|
||||||
|
auto toggledWhenAll = args.toggledWhenAll;
|
||||||
|
auto id = std::move(args.id);
|
||||||
|
auto keywords = std::move(args.keywords);
|
||||||
|
|
||||||
|
Fn<void()> result;
|
||||||
|
|
||||||
|
_builder.add([&](const Builder::BuildContext &ctx) {
|
||||||
|
v::match(ctx, [&](const Builder::WidgetContext &wctx) {
|
||||||
|
result = AddCollapsibleToggle(
|
||||||
|
wctx.container,
|
||||||
|
std::move(args.title),
|
||||||
|
std::move(checkboxes),
|
||||||
|
toggledWhenAll);
|
||||||
|
}, [&](const Builder::SearchContext &sctx) {
|
||||||
|
if (!id.isEmpty()) {
|
||||||
|
sctx.entries->push_back({
|
||||||
|
.id = id,
|
||||||
|
.title = resolvedTitle,
|
||||||
|
.keywords = keywords,
|
||||||
|
.section = sctx.sectionId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (const auto &cb : checkboxes) {
|
||||||
|
if (!cb.checkboxLabel.isEmpty()) {
|
||||||
|
sctx.entries->push_back({
|
||||||
|
.id = id + u"/"_q + cb.checkboxLabel,
|
||||||
|
.title = cb.checkboxLabel,
|
||||||
|
.section = sctx.sectionId,
|
||||||
|
.checkIcon = cb.getter()
|
||||||
|
? Builder::SearchEntryCheckIcon::Checked
|
||||||
|
: Builder::SearchEntryCheckIcon::Unchecked,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AyuSectionBuilder::addChooseButton(ChooseButtonArgs &&args) {
|
||||||
|
auto options = std::move(args.options);
|
||||||
|
auto setter = std::move(args.setter);
|
||||||
|
auto initialSelection = args.initialSelection;
|
||||||
|
auto id = std::move(args.id);
|
||||||
|
auto keywords = std::move(args.keywords);
|
||||||
|
auto icon = std::move(args.icon);
|
||||||
|
auto resolvedTitle = ResolveTitle(rpl::duplicate(args.title));
|
||||||
|
|
||||||
|
_builder.add([&](const Builder::BuildContext &ctx) {
|
||||||
|
v::match(ctx, [&](const Builder::WidgetContext &wctx) {
|
||||||
|
AddChooseButtonWithIconAndRightTextInner(
|
||||||
|
wctx.container,
|
||||||
|
wctx.controller,
|
||||||
|
initialSelection,
|
||||||
|
options,
|
||||||
|
std::move(args.title),
|
||||||
|
std::move(args.boxTitle),
|
||||||
|
icon.icon ? st::settingsButton : st::settingsButtonNoIcon,
|
||||||
|
std::move(icon),
|
||||||
|
setter);
|
||||||
|
}, [&](const Builder::SearchContext &sctx) {
|
||||||
|
if (!id.isEmpty()) {
|
||||||
|
sctx.entries->push_back({
|
||||||
|
.id = id,
|
||||||
|
.title = resolvedTitle,
|
||||||
|
.keywords = keywords,
|
||||||
|
.section = sctx.sectionId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AyuSectionBuilder::addSlider(SliderArgs &&args) {
|
||||||
|
auto id = std::move(args.id);
|
||||||
|
auto keywords = std::move(args.keywords);
|
||||||
|
auto resolvedTitle = ResolveTitle(rpl::duplicate(args.title));
|
||||||
|
|
||||||
|
_builder.add([&](const Builder::BuildContext &ctx) {
|
||||||
|
v::match(ctx, [&](const Builder::WidgetContext &wctx) {
|
||||||
|
const auto container = wctx.container;
|
||||||
|
container->add(
|
||||||
|
object_ptr<Button>(container,
|
||||||
|
std::move(args.title),
|
||||||
|
st::settingsButtonNoIcon)
|
||||||
|
)->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
|
auto sliderWithLabel = MakeSliderWithLabel(
|
||||||
|
container,
|
||||||
|
st::autoDownloadLimitSlider,
|
||||||
|
st::settingsScaleLabel,
|
||||||
|
0,
|
||||||
|
st::settingsScaleLabel.style.font->width("8%%%"));
|
||||||
|
container->add(
|
||||||
|
std::move(sliderWithLabel.widget),
|
||||||
|
st::recentStickersLimitPadding);
|
||||||
|
const auto slider = sliderWithLabel.slider;
|
||||||
|
const auto label = sliderWithLabel.label;
|
||||||
|
|
||||||
|
auto formatLabel = std::move(args.formatLabel);
|
||||||
|
auto indexToValue = std::move(args.indexToValue);
|
||||||
|
auto onChanged = std::move(args.onChanged);
|
||||||
|
auto onFinalChanged = std::move(args.onFinalChanged);
|
||||||
|
|
||||||
|
if (formatLabel) {
|
||||||
|
label->setText(formatLabel(args.current));
|
||||||
|
}
|
||||||
|
|
||||||
|
slider->setPseudoDiscrete(
|
||||||
|
args.steps,
|
||||||
|
[=](int index) {
|
||||||
|
return indexToValue ? indexToValue(index) : index;
|
||||||
|
},
|
||||||
|
args.current,
|
||||||
|
[=](int value) {
|
||||||
|
if (formatLabel) {
|
||||||
|
label->setText(formatLabel(value));
|
||||||
|
}
|
||||||
|
if (onChanged) {
|
||||||
|
onChanged(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[=](int value) {
|
||||||
|
if (formatLabel) {
|
||||||
|
label->setText(formatLabel(value));
|
||||||
|
}
|
||||||
|
if (onFinalChanged) {
|
||||||
|
onFinalChanged(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [&](const Builder::SearchContext &sctx) {
|
||||||
|
if (!id.isEmpty()) {
|
||||||
|
sctx.entries->push_back({
|
||||||
|
.id = id,
|
||||||
|
.title = resolvedTitle,
|
||||||
|
.keywords = keywords,
|
||||||
|
.section = sctx.sectionId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AyuSectionBuilder::addBetaBadge(not_null<Ui::SettingsButton*> button) {
|
||||||
|
AddBetaBadge(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AyuSectionBuilder::addSectionDivider() {
|
||||||
|
_builder.addSkip();
|
||||||
|
_builder.addDivider();
|
||||||
|
_builder.addSkip();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Settings::AyBuilder
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
// 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, 2026
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ayu/ayu_settings.h"
|
||||||
|
#include "ayu/ui/settings/settings_ayu_utils.h"
|
||||||
|
#include "settings/settings_builder.h"
|
||||||
|
#include "settings/settings_common.h"
|
||||||
|
|
||||||
|
namespace Settings::AyBuilder {
|
||||||
|
|
||||||
|
class AyuSectionBuilder {
|
||||||
|
public:
|
||||||
|
explicit AyuSectionBuilder(Builder::SectionBuilder &builder);
|
||||||
|
|
||||||
|
[[nodiscard]] Builder::SectionBuilder &base();
|
||||||
|
|
||||||
|
struct SettingToggleArgs {
|
||||||
|
QString id;
|
||||||
|
rpl::producer<QString> title;
|
||||||
|
BoolGetter getter;
|
||||||
|
BoolSetter setter;
|
||||||
|
IconDescriptor icon;
|
||||||
|
QStringList keywords;
|
||||||
|
rpl::producer<bool> shown;
|
||||||
|
};
|
||||||
|
Ui::SettingsButton *addSettingToggle(SettingToggleArgs &&args);
|
||||||
|
|
||||||
|
struct ToggleArgs {
|
||||||
|
QString id;
|
||||||
|
rpl::producer<QString> title;
|
||||||
|
Fn<bool()> getter;
|
||||||
|
Fn<void(bool)> setter;
|
||||||
|
IconDescriptor icon;
|
||||||
|
QStringList keywords;
|
||||||
|
rpl::producer<bool> shown;
|
||||||
|
};
|
||||||
|
Ui::SettingsButton *addToggle(ToggleArgs &&args);
|
||||||
|
|
||||||
|
struct CollapsibleToggleArgs {
|
||||||
|
QString id;
|
||||||
|
rpl::producer<QString> title;
|
||||||
|
std::vector<NestedEntry> checkboxes;
|
||||||
|
bool toggledWhenAll = true;
|
||||||
|
QStringList keywords;
|
||||||
|
};
|
||||||
|
Fn<void()> addCollapsibleToggle(CollapsibleToggleArgs &&args);
|
||||||
|
|
||||||
|
struct ChooseButtonArgs {
|
||||||
|
QString id;
|
||||||
|
rpl::producer<QString> title;
|
||||||
|
rpl::producer<QString> boxTitle;
|
||||||
|
int initialSelection;
|
||||||
|
std::vector<QString> options;
|
||||||
|
Fn<void(int)> setter;
|
||||||
|
IconDescriptor icon;
|
||||||
|
QStringList keywords;
|
||||||
|
};
|
||||||
|
void addChooseButton(ChooseButtonArgs &&args);
|
||||||
|
|
||||||
|
struct SliderArgs {
|
||||||
|
QString id;
|
||||||
|
rpl::producer<QString> title;
|
||||||
|
int steps;
|
||||||
|
int current;
|
||||||
|
Fn<int(int)> indexToValue;
|
||||||
|
Fn<void(int)> onChanged;
|
||||||
|
Fn<void(int)> onFinalChanged;
|
||||||
|
Fn<QString(int)> formatLabel;
|
||||||
|
QStringList keywords;
|
||||||
|
};
|
||||||
|
void addSlider(SliderArgs &&args);
|
||||||
|
|
||||||
|
void addBetaBadge(not_null<Ui::SettingsButton*> button);
|
||||||
|
|
||||||
|
void addSectionDivider();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Builder::SectionBuilder &_builder;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Settings::AyBuilder
|
||||||
@@ -10,20 +10,24 @@
|
|||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
#include "ayu/ui/boxes/font_selector.h"
|
#include "ayu/ui/boxes/font_selector.h"
|
||||||
#include "ayu/ui/components/icon_picker.h"
|
#include "ayu/ui/components/icon_picker.h"
|
||||||
#include "ayu/ui/settings/settings_ayu_utils.h"
|
#include "ayu/ui/settings/ayu_builder.h"
|
||||||
|
#include "ayu/ui/settings/settings_main.h"
|
||||||
#include "inline_bots/bot_attach_web_view.h"
|
#include "inline_bots/bot_attach_web_view.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "settings/settings_builder.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "styles/style_ayu_icons.h"
|
#include "styles/style_ayu_icons.h"
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_menu_icons.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "ui/vertical_list.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
|
using namespace Builder;
|
||||||
|
using namespace AyBuilder;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool HasDrawerBots(not_null<Window::SessionController*> controller) {
|
bool HasDrawerBots(not_null<Window::SessionController*> controller) {
|
||||||
@@ -33,15 +37,274 @@ bool HasDrawerBots(not_null<Window::SessionController*> controller) {
|
|||||||
if (!bot.inMainMenu || !bot.media) {
|
if (!bot.inMainMenu || !bot.media) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BuildAppIcon(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/appIcon"_q,
|
||||||
|
.title = tr::ayu_AppIconHeader(),
|
||||||
|
.keywords = { u"icon"_q, u"app"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.add([](const WidgetContext &ctx) -> SectionBuilder::WidgetToAdd {
|
||||||
|
return {
|
||||||
|
.widget = object_ptr<IconPicker>(ctx.container),
|
||||||
|
.margin = st::settingsCheckboxPadding,
|
||||||
|
};
|
||||||
|
}, [] {
|
||||||
|
return SearchEntry{
|
||||||
|
.id = u"ayu/iconPicker"_q,
|
||||||
|
.title = tr::ayu_AppIconHeader(tr::now),
|
||||||
|
.keywords = { u"icon"_q, u"app"_q, u"logo"_q },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
builder.addDivider();
|
||||||
|
builder.addSkip();
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/hideNotificationBadge"_q,
|
||||||
|
.title = tr::ayu_HideNotificationBadge(),
|
||||||
|
.getter = &AyuSettings::hideNotificationBadge,
|
||||||
|
.setter = &AyuSettings::setHideNotificationBadge,
|
||||||
|
.keywords = { u"notification"_q, u"badge"_q },
|
||||||
|
});
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addDividerText(tr::ayu_HideNotificationBadgeDescription());
|
||||||
|
builder.addSkip();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BuildAppearance(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/appearanceSection"_q,
|
||||||
|
.title = tr::ayu_CategoryAppearance(),
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/newSwitchStyle"_q,
|
||||||
|
.title = tr::ayu_MaterialSwitches(),
|
||||||
|
.getter = &AyuSettings::materialSwitches,
|
||||||
|
.setter = &AyuSettings::setMaterialSwitches,
|
||||||
|
.keywords = { u"material"_q, u"switch"_q, u"toggle"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/removeMessageTail"_q,
|
||||||
|
.title = tr::ayu_RemoveMessageTail(),
|
||||||
|
.getter = &AyuSettings::removeMessageTail,
|
||||||
|
.setter = &AyuSettings::setRemoveMessageTail,
|
||||||
|
.keywords = { u"tail"_q, u"bubble"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/disableCustomBackgrounds"_q,
|
||||||
|
.title = tr::ayu_DisableCustomBackgrounds(),
|
||||||
|
.getter = &AyuSettings::disableCustomBackgrounds,
|
||||||
|
.setter = &AyuSettings::setDisableCustomBackgrounds,
|
||||||
|
.keywords = { u"background"_q, u"wallpaper"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto controller = builder.controller();
|
||||||
|
builder.addButton({
|
||||||
|
.id = u"ayu/monoFont"_q,
|
||||||
|
.title = tr::ayu_MonospaceFont(),
|
||||||
|
.st = &st::settingsButtonNoIcon,
|
||||||
|
.label = rpl::single(
|
||||||
|
settings->monoFont().isEmpty()
|
||||||
|
? tr::ayu_FontDefault(tr::now)
|
||||||
|
: settings->monoFont()),
|
||||||
|
.onClick = [=] {
|
||||||
|
AyuUi::FontSelectorBox::Show(
|
||||||
|
controller,
|
||||||
|
[=](const QString &font) {
|
||||||
|
AyuSettings::getInstance().setMonoFont(font);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.keywords = { u"font"_q, u"monospace"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildChatFolders(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/chatFolders"_q,
|
||||||
|
.title = tr::ayu_ChatFoldersHeader(),
|
||||||
|
.keywords = { u"folders"_q, u"tabs"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/hideNotificationCounters"_q,
|
||||||
|
.title = tr::ayu_HideNotificationCounters(),
|
||||||
|
.getter = &AyuSettings::hideNotificationCounters,
|
||||||
|
.setter = &AyuSettings::setHideNotificationCounters,
|
||||||
|
.keywords = { u"notification"_q, u"counter"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/hideAllChats"_q,
|
||||||
|
.title = tr::ayu_HideAllChats(),
|
||||||
|
.getter = &AyuSettings::hideAllChatsFolder,
|
||||||
|
.setter = &AyuSettings::setHideAllChatsFolder,
|
||||||
|
.keywords = { u"all chats"_q, u"folder"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildTrayElements(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/trayElements"_q,
|
||||||
|
.title = tr::ayu_TrayElementsHeader(),
|
||||||
|
.keywords = { u"tray"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/ghostToggleInTray"_q,
|
||||||
|
.title = tr::ayu_EnableGhostModeTray(),
|
||||||
|
.getter = &AyuSettings::showGhostToggleInTray,
|
||||||
|
.setter = &AyuSettings::setShowGhostToggleInTray,
|
||||||
|
.keywords = { u"ghost"_q, u"tray"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/streamerToggleInTray"_q,
|
||||||
|
.title = tr::ayu_EnableStreamerModeTray(),
|
||||||
|
.getter = &AyuSettings::showStreamerToggleInTray,
|
||||||
|
.setter = &AyuSettings::setShowStreamerToggleInTray,
|
||||||
|
.keywords = { u"streamer"_q, u"tray"_q },
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildDrawerElements(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/drawerElements"_q,
|
||||||
|
.title = tr::ayu_DrawerElementsHeader(),
|
||||||
|
.keywords = { u"drawer"_q, u"menu"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/myProfileInDrawer"_q,
|
||||||
|
.title = tr::lng_menu_my_profile(),
|
||||||
|
.getter = &AyuSettings::showMyProfileInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowMyProfileInDrawer,
|
||||||
|
.icon = { &st::menuIconProfile },
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto controller = builder.controller();
|
||||||
|
if (controller && HasDrawerBots(controller)) {
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/botsInDrawer"_q,
|
||||||
|
.title = tr::lng_filters_type_bots(),
|
||||||
|
.getter = &AyuSettings::showBotsInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowBotsInDrawer,
|
||||||
|
.icon = { &st::menuIconBot },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/newGroupInDrawer"_q,
|
||||||
|
.title = tr::lng_create_group_title(),
|
||||||
|
.getter = &AyuSettings::showNewGroupInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowNewGroupInDrawer,
|
||||||
|
.icon = { &st::menuIconGroups },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/newChannelInDrawer"_q,
|
||||||
|
.title = tr::lng_create_channel_title(),
|
||||||
|
.getter = &AyuSettings::showNewChannelInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowNewChannelInDrawer,
|
||||||
|
.icon = { &st::menuIconChannel },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/contactsInDrawer"_q,
|
||||||
|
.title = tr::lng_menu_contacts(),
|
||||||
|
.getter = &AyuSettings::showContactsInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowContactsInDrawer,
|
||||||
|
.icon = { &st::menuIconUserShow },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/callsInDrawer"_q,
|
||||||
|
.title = tr::lng_menu_calls(),
|
||||||
|
.getter = &AyuSettings::showCallsInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowCallsInDrawer,
|
||||||
|
.icon = { &st::menuIconPhone },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/savedMessagesInDrawer"_q,
|
||||||
|
.title = tr::lng_saved_messages(),
|
||||||
|
.getter = &AyuSettings::showSavedMessagesInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowSavedMessagesInDrawer,
|
||||||
|
.icon = { &st::menuIconSavedMessages },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/lreadToggleInDrawer"_q,
|
||||||
|
.title = tr::ayu_LReadMessages(),
|
||||||
|
.getter = &AyuSettings::showLReadToggleInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowLReadToggleInDrawer,
|
||||||
|
.icon = { &st::ayuLReadMenuIcon },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/sreadToggleInDrawer"_q,
|
||||||
|
.title = tr::ayu_SReadMessages(),
|
||||||
|
.getter = &AyuSettings::showSReadToggleInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowSReadToggleInDrawer,
|
||||||
|
.icon = { &st::ayuSReadMenuIcon },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/nightModeToggleInDrawer"_q,
|
||||||
|
.title = tr::lng_menu_night_mode(),
|
||||||
|
.getter = &AyuSettings::showNightModeToggleInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowNightModeToggleInDrawer,
|
||||||
|
.icon = { &st::menuIconNightMode },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/ghostToggleInDrawer"_q,
|
||||||
|
.title = tr::ayu_GhostModeToggle(),
|
||||||
|
.getter = &AyuSettings::showGhostToggleInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowGhostToggleInDrawer,
|
||||||
|
.icon = { &st::ayuGhostIcon },
|
||||||
|
});
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/streamerToggleInDrawer"_q,
|
||||||
|
.title = tr::ayu_StreamerModeToggle(),
|
||||||
|
.getter = &AyuSettings::showStreamerToggleInDrawer,
|
||||||
|
.setter = &AyuSettings::setShowStreamerToggleInDrawer,
|
||||||
|
.icon = { &st::ayuStreamerModeMenuIcon },
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto kMeta = BuildHelper({
|
||||||
|
.id = AyuAppearance::Id(),
|
||||||
|
.parentId = AyuMain::Id(),
|
||||||
|
.title = &tr::ayu_CategoryAppearance,
|
||||||
|
.icon = &st::menuIconPalette,
|
||||||
|
}, [](SectionBuilder &builder) {
|
||||||
|
auto ayu = AyuSectionBuilder(builder);
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
BuildAppIcon(builder, ayu);
|
||||||
|
BuildAppearance(builder, ayu);
|
||||||
|
BuildChatFolders(builder, ayu);
|
||||||
|
BuildTrayElements(builder, ayu);
|
||||||
|
BuildDrawerElements(builder, ayu);
|
||||||
|
builder.addSkip();
|
||||||
|
});
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
rpl::producer<QString> AyuAppearance::title() {
|
rpl::producer<QString> AyuAppearance::title() {
|
||||||
return tr::ayu_CategoryAppearance();
|
return tr::ayu_CategoryAppearance();
|
||||||
}
|
}
|
||||||
@@ -49,118 +312,18 @@ rpl::producer<QString> AyuAppearance::title() {
|
|||||||
AyuAppearance::AyuAppearance(
|
AyuAppearance::AyuAppearance(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller)
|
||||||
: Section(parent, controller) {
|
: Section(parent, controller) {
|
||||||
setupContent(controller);
|
setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupAppIcon(not_null<Ui::VerticalLayout*> container) {
|
void AyuAppearance::setupContent() {
|
||||||
AddSubsectionTitle(container, tr::ayu_AppIconHeader());
|
|
||||||
container->add(
|
|
||||||
object_ptr<IconPicker>(container),
|
|
||||||
st::settingsCheckboxPadding);
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
AddDivider(container);
|
|
||||||
AddSkip(container);
|
|
||||||
AddSettingToggle(container, tr::ayu_HideNotificationBadge(), &AyuSettings::hideNotificationBadge, &AyuSettings::setHideNotificationBadge);
|
|
||||||
AddSkip(container);
|
|
||||||
AddDividerText(container, tr::ayu_HideNotificationBadgeDescription());
|
|
||||||
AddSkip(container);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupAppearance(not_null<Ui::VerticalLayout*> container, not_null<Window::SessionController*> controller) {
|
|
||||||
auto *settings = &AyuSettings::getInstance();
|
|
||||||
|
|
||||||
AddSubsectionTitle(container, tr::ayu_CategoryAppearance());
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_MaterialSwitches(), &AyuSettings::materialSwitches, &AyuSettings::setMaterialSwitches);
|
|
||||||
AddSettingToggle(container, tr::ayu_RemoveMessageTail(), &AyuSettings::removeMessageTail, &AyuSettings::setRemoveMessageTail);
|
|
||||||
AddSettingToggle(container, tr::ayu_DisableCustomBackgrounds(), &AyuSettings::disableCustomBackgrounds, &AyuSettings::setDisableCustomBackgrounds);
|
|
||||||
|
|
||||||
const auto monoButton = AddButtonWithLabel(
|
|
||||||
container,
|
|
||||||
tr::ayu_MonospaceFont(),
|
|
||||||
rpl::single(
|
|
||||||
settings->monoFont().isEmpty() ? tr::ayu_FontDefault(tr::now) : settings->monoFont()
|
|
||||||
),
|
|
||||||
st::settingsButtonNoIcon);
|
|
||||||
const auto monoGuard = Ui::CreateChild<base::binary_guard>(monoButton.get());
|
|
||||||
|
|
||||||
monoButton->addClickHandler(
|
|
||||||
[=]
|
|
||||||
{
|
|
||||||
*monoGuard = AyuUi::FontSelectorBox::Show(
|
|
||||||
controller,
|
|
||||||
[=](const QString& font)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setMonoFont(font);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
AddSectionDivider(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupChatFolders(not_null<Ui::VerticalLayout*> container) {
|
|
||||||
AddSubsectionTitle(container, tr::ayu_ChatFoldersHeader());
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_HideNotificationCounters(), &AyuSettings::hideNotificationCounters, &AyuSettings::setHideNotificationCounters);
|
|
||||||
AddSettingToggle(container, tr::ayu_HideAllChats(), &AyuSettings::hideAllChatsFolder, &AyuSettings::setHideAllChatsFolder);
|
|
||||||
|
|
||||||
AddSectionDivider(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupDrawerElements(not_null<Ui::VerticalLayout*> container, not_null<Window::SessionController*> controller) {
|
|
||||||
AddSubsectionTitle(container, tr::ayu_DrawerElementsHeader());
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::lng_menu_my_profile(), &AyuSettings::showMyProfileInDrawer, &AyuSettings::setShowMyProfileInDrawer, st::menuIconProfile);
|
|
||||||
|
|
||||||
if (HasDrawerBots(controller)) {
|
|
||||||
AddSettingToggle(container, tr::lng_filters_type_bots(), &AyuSettings::showBotsInDrawer, &AyuSettings::setShowBotsInDrawer, st::menuIconBot);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::lng_create_group_title(), &AyuSettings::showNewGroupInDrawer, &AyuSettings::setShowNewGroupInDrawer, st::menuIconGroups);
|
|
||||||
AddSettingToggle(container, tr::lng_create_channel_title(), &AyuSettings::showNewChannelInDrawer, &AyuSettings::setShowNewChannelInDrawer, st::menuIconChannel);
|
|
||||||
AddSettingToggle(container, tr::lng_menu_contacts(), &AyuSettings::showContactsInDrawer, &AyuSettings::setShowContactsInDrawer, st::menuIconUserShow);
|
|
||||||
AddSettingToggle(container, tr::lng_menu_calls(), &AyuSettings::showCallsInDrawer, &AyuSettings::setShowCallsInDrawer, st::menuIconPhone);
|
|
||||||
AddSettingToggle(container, tr::lng_saved_messages(), &AyuSettings::showSavedMessagesInDrawer, &AyuSettings::setShowSavedMessagesInDrawer, st::menuIconSavedMessages);
|
|
||||||
AddSettingToggle(container, tr::ayu_LReadMessages(), &AyuSettings::showLReadToggleInDrawer, &AyuSettings::setShowLReadToggleInDrawer, st::ayuLReadMenuIcon);
|
|
||||||
AddSettingToggle(container, tr::ayu_SReadMessages(), &AyuSettings::showSReadToggleInDrawer, &AyuSettings::setShowSReadToggleInDrawer, st::ayuSReadMenuIcon);
|
|
||||||
AddSettingToggle(container, tr::lng_menu_night_mode(), &AyuSettings::showNightModeToggleInDrawer, &AyuSettings::setShowNightModeToggleInDrawer, st::menuIconNightMode);
|
|
||||||
AddSettingToggle(container, tr::ayu_GhostModeToggle(), &AyuSettings::showGhostToggleInDrawer, &AyuSettings::setShowGhostToggleInDrawer, st::ayuGhostIcon);
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
AddSettingToggle(container, tr::ayu_StreamerModeToggle(), &AyuSettings::showStreamerToggleInDrawer, &AyuSettings::setShowStreamerToggleInDrawer, st::ayuStreamerModeMenuIcon);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AddSkip(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupTrayElements(not_null<Ui::VerticalLayout*> container) {
|
|
||||||
AddSubsectionTitle(container, tr::ayu_TrayElementsHeader());
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_EnableGhostModeTray(), &AyuSettings::showGhostToggleInTray, &AyuSettings::setShowGhostToggleInTray);
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
AddSettingToggle(container, tr::ayu_EnableStreamerModeTray(), &AyuSettings::showStreamerToggleInTray, &AyuSettings::setShowStreamerToggleInTray);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AddSectionDivider(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AyuAppearance::setupContent(not_null<Window::SessionController*> controller) {
|
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
build(content, kMeta.build);
|
||||||
AddSkip(content);
|
Ui::ResizeFitChild(this, content);
|
||||||
|
|
||||||
SetupAppIcon(content);
|
|
||||||
SetupAppearance(content, controller);
|
|
||||||
SetupChatFolders(content);
|
|
||||||
SetupTrayElements(content);
|
|
||||||
SetupDrawerElements(content, controller);
|
|
||||||
AddSkip(content);
|
|
||||||
|
|
||||||
ResizeFitChild(this, content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
Type AyuAppearanceId() {
|
||||||
|
return AyuAppearance::Id();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|||||||
@@ -15,15 +15,16 @@ class SessionController;
|
|||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class AyuAppearance : public Section<AyuAppearance>
|
class AyuAppearance : public Section<AyuAppearance> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
AyuAppearance(QWidget *parent, not_null<Window::SessionController*> controller);
|
AyuAppearance(QWidget *parent, not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> title() override;
|
[[nodiscard]] rpl::producer<QString> title() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupContent(not_null<Window::SessionController*> controller);
|
void setupContent();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Settings
|
[[nodiscard]] Type AyuAppearanceId();
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|||||||
@@ -9,19 +9,21 @@
|
|||||||
#include "lang_auto.h"
|
#include "lang_auto.h"
|
||||||
#include "settings_ayu_utils.h"
|
#include "settings_ayu_utils.h"
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
|
#include "ayu/ui/settings/ayu_builder.h"
|
||||||
|
#include "ayu/ui/settings/settings_main.h"
|
||||||
#include "boxes/peer_list_box.h"
|
#include "boxes/peer_list_box.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "filters/settings_filters_list.h"
|
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "main/main_domain.h"
|
#include "main/main_domain.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "settings/settings_builder.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "styles/style_ayu_styles.h"
|
#include "styles/style_ayu_styles.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_info.h"
|
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
#include "styles/style_menu_icons.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
#include "ui/vertical_list.h"
|
#include "ui/vertical_list.h"
|
||||||
@@ -35,6 +37,11 @@
|
|||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
|
using namespace Builder;
|
||||||
|
using namespace AyBuilder;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
struct GhostPickerState {
|
struct GhostPickerState {
|
||||||
rpl::variable<uint64> selectedUserId;
|
rpl::variable<uint64> selectedUserId;
|
||||||
base::unique_qptr<Ui::PopupMenu> menu;
|
base::unique_qptr<Ui::PopupMenu> menu;
|
||||||
@@ -243,256 +250,349 @@ void selectGhostProfile(GhostPickerState *state, uint64 userId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupGhostEssentials(
|
void BuildGhostEssentials(SectionBuilder &builder) {
|
||||||
not_null<Ui::VerticalLayout*> container,
|
builder.add([](const BuildContext &ctx) {
|
||||||
not_null<Window::SessionController*> controller) {
|
v::match(ctx, [&](const WidgetContext &wctx) {
|
||||||
auto activeCount = 0;
|
const auto container = wctx.container;
|
||||||
for (const auto &account : Core::App().domain().orderedAccounts()) {
|
const auto controller = wctx.controller;
|
||||||
if (account->sessionExists()) {
|
|
||||||
++activeCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activeCount <= 1 && !AyuSettings::getInstance().useGlobalGhostMode()) {
|
auto activeCount = 0;
|
||||||
auto userId = controller->session().userId().bare;
|
for (const auto &account : Core::App().domain().orderedAccounts()) {
|
||||||
auto &src = AyuSettings::ghost(userId);
|
if (account->sessionExists()) {
|
||||||
auto &dst = AyuSettings::ghost(0);
|
++activeCount;
|
||||||
dst.setSendReadMessages(src.sendReadMessages());
|
}
|
||||||
dst.setSendReadStories(src.sendReadStories());
|
|
||||||
dst.setSendOnlinePackets(src.sendOnlinePackets());
|
|
||||||
dst.setSendUploadProgress(src.sendUploadProgress());
|
|
||||||
dst.setSendOfflinePacketAfterOnline(src.sendOfflinePacketAfterOnline());
|
|
||||||
dst.setMarkReadAfterAction(src.markReadAfterAction());
|
|
||||||
dst.setUseScheduledMessages(src.useScheduledMessages());
|
|
||||||
dst.setSendWithoutSound(src.sendWithoutSound());
|
|
||||||
dst.setSendReadMessagesLocked(src.sendReadMessagesLocked());
|
|
||||||
dst.setSendReadStoriesLocked(src.sendReadStoriesLocked());
|
|
||||||
dst.setSendOnlinePacketsLocked(src.sendOnlinePacketsLocked());
|
|
||||||
dst.setSendUploadProgressLocked(src.sendUploadProgressLocked());
|
|
||||||
dst.setSendOfflinePacketAfterOnlineLocked(src.sendOfflinePacketAfterOnlineLocked());
|
|
||||||
AyuSettings::getInstance().setUseGlobalGhostMode(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto isGlobal = AyuSettings::getInstance().useGlobalGhostMode();
|
|
||||||
auto initialUserId = isGlobal
|
|
||||||
? uint64(0)
|
|
||||||
: controller->session().userId().bare;
|
|
||||||
|
|
||||||
const auto state = container->lifetime().make_state<GhostPickerState>();
|
|
||||||
state->selectedUserId = initialUserId;
|
|
||||||
|
|
||||||
const auto title = AddSubsectionTitle(container, tr::ayu_GhostEssentialsHeader());
|
|
||||||
|
|
||||||
const auto pickerButton = Ui::CreateChild<Ui::LinkButton>(
|
|
||||||
container.get(),
|
|
||||||
PickerLabel(initialUserId),
|
|
||||||
st::ghostPickerButton);
|
|
||||||
state->pickerButton = pickerButton;
|
|
||||||
|
|
||||||
const auto arrow = Ui::CreateChild<Ui::AbstractButton>(container.get());
|
|
||||||
{
|
|
||||||
const auto &icon = st::ghostPickerArrow;
|
|
||||||
arrow->resize(icon.size());
|
|
||||||
arrow->paintRequest(
|
|
||||||
) | rpl::on_next([=, &icon] {
|
|
||||||
auto p = QPainter(arrow);
|
|
||||||
icon.paint(p, 0, 0, arrow->width());
|
|
||||||
}, arrow->lifetime());
|
|
||||||
}
|
|
||||||
arrow->setCursor(style::cur_pointer);
|
|
||||||
|
|
||||||
const auto showPicker = activeCount > 1;
|
|
||||||
pickerButton->setVisible(showPicker);
|
|
||||||
arrow->setVisible(showPicker);
|
|
||||||
|
|
||||||
rpl::combine(
|
|
||||||
title->geometryValue(),
|
|
||||||
container->widthValue(),
|
|
||||||
pickerButton->naturalWidthValue()
|
|
||||||
) | rpl::on_next([=](QRect r, int width, int natural) {
|
|
||||||
pickerButton->resizeToNaturalWidth(width / 2);
|
|
||||||
pickerButton->moveToRight(
|
|
||||||
st::defaultSubsectionTitlePadding.right() + arrow->width() + st::normalFont->spacew / 2,
|
|
||||||
r.y() + (r.height() - pickerButton->height()) / 2,
|
|
||||||
width);
|
|
||||||
arrow->moveToLeft(
|
|
||||||
pickerButton->x() + pickerButton->width() + st::normalFont->spacew / 2,
|
|
||||||
r.y() + (r.height() - arrow->height()) / 2);
|
|
||||||
}, pickerButton->lifetime());
|
|
||||||
|
|
||||||
std::vector checkboxes{
|
|
||||||
NestedEntry{
|
|
||||||
tr::ayu_DontReadMessages(tr::now),
|
|
||||||
[state] { return !AyuSettings::ghost(state->selectedUserId.current()).sendReadMessages(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendReadMessages(!v); },
|
|
||||||
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendReadMessagesLocked(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendReadMessagesLocked(v); }
|
|
||||||
},
|
|
||||||
NestedEntry{
|
|
||||||
tr::ayu_DontReadStories(tr::now),
|
|
||||||
[state] { return !AyuSettings::ghost(state->selectedUserId.current()).sendReadStories(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendReadStories(!v); },
|
|
||||||
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendReadStoriesLocked(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendReadStoriesLocked(v); }
|
|
||||||
},
|
|
||||||
NestedEntry{
|
|
||||||
tr::ayu_DontSendOnlinePackets(tr::now),
|
|
||||||
[state] { return !AyuSettings::ghost(state->selectedUserId.current()).sendOnlinePackets(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendOnlinePackets(!v); },
|
|
||||||
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendOnlinePacketsLocked(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendOnlinePacketsLocked(v); }
|
|
||||||
},
|
|
||||||
NestedEntry{
|
|
||||||
tr::ayu_DontSendUploadProgress(tr::now),
|
|
||||||
[state] { return !AyuSettings::ghost(state->selectedUserId.current()).sendUploadProgress(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendUploadProgress(!v); },
|
|
||||||
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendUploadProgressLocked(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendUploadProgressLocked(v); }
|
|
||||||
},
|
|
||||||
NestedEntry{
|
|
||||||
tr::ayu_SendOfflinePacketAfterOnline(tr::now),
|
|
||||||
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendOfflinePacketAfterOnline(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendOfflinePacketAfterOnline(v); },
|
|
||||||
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendOfflinePacketAfterOnlineLocked(); },
|
|
||||||
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendOfflinePacketAfterOnlineLocked(v); }
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
state->refreshCheckboxes = AddCollapsibleToggle(
|
|
||||||
container, tr::ayu_GhostModeToggle(), std::move(checkboxes), true);
|
|
||||||
|
|
||||||
AddButtonWithIcon(
|
|
||||||
container,
|
|
||||||
tr::ayu_MarkReadAfterAction(),
|
|
||||||
st::settingsButtonNoIcon
|
|
||||||
)->toggleOn(
|
|
||||||
state->selectedUserId.value()
|
|
||||||
| rpl::map([](uint64 id) {
|
|
||||||
return AyuSettings::ghost(id).markReadAfterActionChanges();
|
|
||||||
}) | rpl::flatten_latest()
|
|
||||||
)->toggledValue(
|
|
||||||
) | rpl::filter(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
return enabled != AyuSettings::ghost(state->selectedUserId.current()).markReadAfterAction();
|
|
||||||
}) | on_next(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
auto &ghost = AyuSettings::ghost(state->selectedUserId.current());
|
|
||||||
ghost.setMarkReadAfterAction(enabled);
|
|
||||||
if (enabled) {
|
|
||||||
ghost.setUseScheduledMessages(false);
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
container->lifetime());
|
|
||||||
AddSkip(container);
|
|
||||||
AddDividerText(container, tr::ayu_MarkReadAfterActionDescription());
|
|
||||||
|
|
||||||
AddSkip(container);
|
if (activeCount <= 1 && !AyuSettings::getInstance().useGlobalGhostMode()) {
|
||||||
AddButtonWithIcon(
|
auto userId = controller->session().userId().bare;
|
||||||
container,
|
auto &src = AyuSettings::ghost(userId);
|
||||||
tr::ayu_UseScheduledMessages(),
|
auto &dst = AyuSettings::ghost(0);
|
||||||
st::settingsButtonNoIcon
|
dst.setSendReadMessages(src.sendReadMessages());
|
||||||
)->toggleOn(
|
dst.setSendReadStories(src.sendReadStories());
|
||||||
state->selectedUserId.value()
|
dst.setSendOnlinePackets(src.sendOnlinePackets());
|
||||||
| rpl::map([](uint64 id) {
|
dst.setSendUploadProgress(src.sendUploadProgress());
|
||||||
return AyuSettings::ghost(id).useScheduledMessagesChanges();
|
dst.setSendOfflinePacketAfterOnline(src.sendOfflinePacketAfterOnline());
|
||||||
}) | rpl::flatten_latest()
|
dst.setMarkReadAfterAction(src.markReadAfterAction());
|
||||||
)->toggledValue(
|
dst.setUseScheduledMessages(src.useScheduledMessages());
|
||||||
) | rpl::filter(
|
dst.setSendWithoutSound(src.sendWithoutSound());
|
||||||
[=](bool enabled)
|
dst.setSendReadMessagesLocked(src.sendReadMessagesLocked());
|
||||||
{
|
dst.setSendReadStoriesLocked(src.sendReadStoriesLocked());
|
||||||
return enabled != AyuSettings::ghost(state->selectedUserId.current()).useScheduledMessages();
|
dst.setSendOnlinePacketsLocked(src.sendOnlinePacketsLocked());
|
||||||
}) | on_next(
|
dst.setSendUploadProgressLocked(src.sendUploadProgressLocked());
|
||||||
[=](bool enabled)
|
dst.setSendOfflinePacketAfterOnlineLocked(src.sendOfflinePacketAfterOnlineLocked());
|
||||||
{
|
AyuSettings::getInstance().setUseGlobalGhostMode(true);
|
||||||
auto &ghost = AyuSettings::ghost(state->selectedUserId.current());
|
|
||||||
ghost.setUseScheduledMessages(enabled);
|
|
||||||
if (enabled) {
|
|
||||||
ghost.setMarkReadAfterAction(false);
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
container->lifetime());
|
|
||||||
AddSkip(container);
|
|
||||||
AddDividerText(container, tr::ayu_UseScheduledMessagesDescription());
|
|
||||||
|
|
||||||
AddSkip(container);
|
const auto isGlobal = AyuSettings::getInstance().useGlobalGhostMode();
|
||||||
AddButtonWithIcon(
|
auto initialUserId = isGlobal
|
||||||
container,
|
? uint64(0)
|
||||||
tr::ayu_SendWithoutSoundByDefault(),
|
: controller->session().userId().bare;
|
||||||
st::settingsButtonNoIcon
|
|
||||||
)->toggleOn(
|
|
||||||
state->selectedUserId.value()
|
|
||||||
| rpl::map([](uint64 id) {
|
|
||||||
return AyuSettings::ghost(id).sendWithoutSoundChanges();
|
|
||||||
}) | rpl::flatten_latest()
|
|
||||||
)->toggledValue(
|
|
||||||
) | rpl::filter(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
return enabled != AyuSettings::ghost(state->selectedUserId.current()).sendWithoutSound();
|
|
||||||
}) | on_next(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
AyuSettings::ghost(state->selectedUserId.current()).setSendWithoutSound(enabled);
|
|
||||||
},
|
|
||||||
container->lifetime());
|
|
||||||
AddSkip(container);
|
|
||||||
AddDividerText(container, tr::ayu_SendWithoutSoundByDefaultDescription());
|
|
||||||
|
|
||||||
auto showMenu = [=] {
|
const auto state = container->lifetime().make_state<GhostPickerState>();
|
||||||
state->menu = base::make_unique_q<Ui::PopupMenu>(
|
state->selectedUserId = initialUserId;
|
||||||
pickerButton,
|
|
||||||
st::defaultPopupMenu);
|
|
||||||
|
|
||||||
state->menu->addAction(
|
const auto title = AddSubsectionTitle(container, tr::ayu_GhostEssentialsHeader());
|
||||||
base::make_unique_q<GlobalAction>(
|
|
||||||
state->menu->menu(),
|
|
||||||
st::defaultPopupMenu.menu,
|
|
||||||
tr::ayu_GhostModeGlobalSettings(tr::now),
|
|
||||||
[=] { selectGhostProfile(state, 0); }));
|
|
||||||
|
|
||||||
for (const auto &account : Core::App().domain().orderedAccounts()) {
|
const auto pickerButton = Ui::CreateChild<Ui::LinkButton>(
|
||||||
if (!account->sessionExists()) {
|
container.get(),
|
||||||
continue;
|
PickerLabel(initialUserId),
|
||||||
|
st::ghostPickerButton);
|
||||||
|
state->pickerButton = pickerButton;
|
||||||
|
|
||||||
|
const auto arrow = Ui::CreateChild<Ui::AbstractButton>(container.get());
|
||||||
|
{
|
||||||
|
const auto &icon = st::ghostPickerArrow;
|
||||||
|
arrow->resize(icon.size());
|
||||||
|
arrow->paintRequest(
|
||||||
|
) | rpl::on_next([=, &icon] {
|
||||||
|
auto p = QPainter(arrow);
|
||||||
|
icon.paint(p, 0, 0, arrow->width());
|
||||||
|
}, arrow->lifetime());
|
||||||
}
|
}
|
||||||
auto user = account->session().user();
|
arrow->setCursor(style::cur_pointer);
|
||||||
auto id = account->session().userId().bare;
|
|
||||||
state->menu->addAction(
|
|
||||||
base::make_unique_q<AccountAction>(
|
|
||||||
state->menu->menu(),
|
|
||||||
st::defaultPopupMenu.menu,
|
|
||||||
user,
|
|
||||||
[=] { selectGhostProfile(state, id); }));
|
|
||||||
}
|
|
||||||
|
|
||||||
state->menu->popup(
|
const auto showPicker = activeCount > 1;
|
||||||
pickerButton->mapToGlobal(
|
pickerButton->setVisible(showPicker);
|
||||||
QPoint(pickerButton->width(), pickerButton->height())));
|
arrow->setVisible(showPicker);
|
||||||
};
|
|
||||||
pickerButton->setClickedCallback(showMenu);
|
rpl::combine(
|
||||||
arrow->setClickedCallback(showMenu);
|
title->geometryValue(),
|
||||||
|
container->widthValue(),
|
||||||
|
pickerButton->naturalWidthValue()
|
||||||
|
) | rpl::on_next([=](QRect r, int width, int natural) {
|
||||||
|
pickerButton->resizeToNaturalWidth(width / 2);
|
||||||
|
pickerButton->moveToRight(
|
||||||
|
st::defaultSubsectionTitlePadding.right() + arrow->width() + st::normalFont->spacew / 2,
|
||||||
|
r.y() + (r.height() - pickerButton->height()) / 2,
|
||||||
|
width);
|
||||||
|
arrow->moveToLeft(
|
||||||
|
pickerButton->x() + pickerButton->width() + st::normalFont->spacew / 2,
|
||||||
|
r.y() + (r.height() - arrow->height()) / 2);
|
||||||
|
}, pickerButton->lifetime());
|
||||||
|
|
||||||
|
std::vector checkboxes{
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_DontReadMessages(tr::now),
|
||||||
|
[state] { return !AyuSettings::ghost(state->selectedUserId.current()).sendReadMessages(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendReadMessages(!v); },
|
||||||
|
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendReadMessagesLocked(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendReadMessagesLocked(v); }
|
||||||
|
},
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_DontReadStories(tr::now),
|
||||||
|
[state] { return !AyuSettings::ghost(state->selectedUserId.current()).sendReadStories(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendReadStories(!v); },
|
||||||
|
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendReadStoriesLocked(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendReadStoriesLocked(v); }
|
||||||
|
},
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_DontSendOnlinePackets(tr::now),
|
||||||
|
[state] { return !AyuSettings::ghost(state->selectedUserId.current()).sendOnlinePackets(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendOnlinePackets(!v); },
|
||||||
|
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendOnlinePacketsLocked(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendOnlinePacketsLocked(v); }
|
||||||
|
},
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_DontSendUploadProgress(tr::now),
|
||||||
|
[state] { return !AyuSettings::ghost(state->selectedUserId.current()).sendUploadProgress(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendUploadProgress(!v); },
|
||||||
|
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendUploadProgressLocked(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendUploadProgressLocked(v); }
|
||||||
|
},
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_SendOfflinePacketAfterOnline(tr::now),
|
||||||
|
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendOfflinePacketAfterOnline(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendOfflinePacketAfterOnline(v); },
|
||||||
|
[state] { return AyuSettings::ghost(state->selectedUserId.current()).sendOfflinePacketAfterOnlineLocked(); },
|
||||||
|
[state](bool v) { AyuSettings::ghost(state->selectedUserId.current()).setSendOfflinePacketAfterOnlineLocked(v); }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
state->refreshCheckboxes = AddCollapsibleToggle(
|
||||||
|
container, tr::ayu_GhostModeToggle(), std::move(checkboxes), true);
|
||||||
|
|
||||||
|
AddButtonWithIcon(
|
||||||
|
container,
|
||||||
|
tr::ayu_MarkReadAfterAction(),
|
||||||
|
st::settingsButtonNoIcon
|
||||||
|
)->toggleOn(
|
||||||
|
state->selectedUserId.value()
|
||||||
|
| rpl::map([](uint64 id) {
|
||||||
|
return AyuSettings::ghost(id).markReadAfterActionChanges();
|
||||||
|
}) | rpl::flatten_latest()
|
||||||
|
)->toggledValue(
|
||||||
|
) | rpl::filter(
|
||||||
|
[=](bool enabled) {
|
||||||
|
return enabled != AyuSettings::ghost(state->selectedUserId.current()).markReadAfterAction();
|
||||||
|
}
|
||||||
|
) | on_next(
|
||||||
|
[=](bool enabled) {
|
||||||
|
auto &ghost = AyuSettings::ghost(state->selectedUserId.current());
|
||||||
|
ghost.setMarkReadAfterAction(enabled);
|
||||||
|
if (enabled) {
|
||||||
|
ghost.setUseScheduledMessages(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
container->lifetime());
|
||||||
|
AddSkip(container);
|
||||||
|
AddDividerText(container, tr::ayu_MarkReadAfterActionDescription());
|
||||||
|
|
||||||
|
AddSkip(container);
|
||||||
|
AddButtonWithIcon(
|
||||||
|
container,
|
||||||
|
tr::ayu_UseScheduledMessages(),
|
||||||
|
st::settingsButtonNoIcon
|
||||||
|
)->toggleOn(
|
||||||
|
state->selectedUserId.value()
|
||||||
|
| rpl::map([](uint64 id) {
|
||||||
|
return AyuSettings::ghost(id).useScheduledMessagesChanges();
|
||||||
|
}) | rpl::flatten_latest()
|
||||||
|
)->toggledValue(
|
||||||
|
) | rpl::filter(
|
||||||
|
[=](bool enabled) {
|
||||||
|
return enabled != AyuSettings::ghost(state->selectedUserId.current()).useScheduledMessages();
|
||||||
|
}
|
||||||
|
) | on_next(
|
||||||
|
[=](bool enabled) {
|
||||||
|
auto &ghost = AyuSettings::ghost(state->selectedUserId.current());
|
||||||
|
ghost.setUseScheduledMessages(enabled);
|
||||||
|
if (enabled) {
|
||||||
|
ghost.setMarkReadAfterAction(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
container->lifetime());
|
||||||
|
AddSkip(container);
|
||||||
|
AddDividerText(container, tr::ayu_UseScheduledMessagesDescription());
|
||||||
|
|
||||||
|
AddSkip(container);
|
||||||
|
AddButtonWithIcon(
|
||||||
|
container,
|
||||||
|
tr::ayu_SendWithoutSoundByDefault(),
|
||||||
|
st::settingsButtonNoIcon
|
||||||
|
)->toggleOn(
|
||||||
|
state->selectedUserId.value()
|
||||||
|
| rpl::map([](uint64 id) {
|
||||||
|
return AyuSettings::ghost(id).sendWithoutSoundChanges();
|
||||||
|
}) | rpl::flatten_latest()
|
||||||
|
)->toggledValue(
|
||||||
|
) | rpl::filter(
|
||||||
|
[=](bool enabled) {
|
||||||
|
return enabled != AyuSettings::ghost(state->selectedUserId.current()).sendWithoutSound();
|
||||||
|
}
|
||||||
|
) | on_next(
|
||||||
|
[=](bool enabled) {
|
||||||
|
AyuSettings::ghost(state->selectedUserId.current()).setSendWithoutSound(enabled);
|
||||||
|
},
|
||||||
|
container->lifetime());
|
||||||
|
AddSkip(container);
|
||||||
|
AddDividerText(container, tr::ayu_SendWithoutSoundByDefaultDescription());
|
||||||
|
|
||||||
|
auto showMenu = [=] {
|
||||||
|
state->menu = base::make_unique_q<Ui::PopupMenu>(
|
||||||
|
pickerButton,
|
||||||
|
st::defaultPopupMenu);
|
||||||
|
|
||||||
|
state->menu->addAction(
|
||||||
|
base::make_unique_q<GlobalAction>(
|
||||||
|
state->menu->menu(),
|
||||||
|
st::defaultPopupMenu.menu,
|
||||||
|
tr::ayu_GhostModeGlobalSettings(tr::now),
|
||||||
|
[=] { selectGhostProfile(state, 0); }));
|
||||||
|
|
||||||
|
for (const auto &account : Core::App().domain().orderedAccounts()) {
|
||||||
|
if (!account->sessionExists()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto user = account->session().user();
|
||||||
|
auto id = account->session().userId().bare;
|
||||||
|
state->menu->addAction(
|
||||||
|
base::make_unique_q<AccountAction>(
|
||||||
|
state->menu->menu(),
|
||||||
|
st::defaultPopupMenu.menu,
|
||||||
|
user,
|
||||||
|
[=] { selectGhostProfile(state, id); }));
|
||||||
|
}
|
||||||
|
|
||||||
|
state->menu->popup(
|
||||||
|
pickerButton->mapToGlobal(
|
||||||
|
QPoint(pickerButton->width(), pickerButton->height())));
|
||||||
|
};
|
||||||
|
pickerButton->setClickedCallback(showMenu);
|
||||||
|
arrow->setClickedCallback(showMenu);
|
||||||
|
}, [&](const SearchContext &sctx) {
|
||||||
|
sctx.entries->push_back({
|
||||||
|
.id = u"ayu/ghostModeToggle"_q,
|
||||||
|
.title = tr::ayu_GhostModeToggle(tr::now),
|
||||||
|
.keywords = { u"ghost"_q, u"read"_q, u"online"_q, u"stealth"_q },
|
||||||
|
.section = sctx.sectionId,
|
||||||
|
});
|
||||||
|
sctx.entries->push_back({
|
||||||
|
.id = u"ayu/markReadAfterAction"_q,
|
||||||
|
.title = tr::ayu_MarkReadAfterAction(tr::now),
|
||||||
|
.section = sctx.sectionId,
|
||||||
|
});
|
||||||
|
sctx.entries->push_back({
|
||||||
|
.id = u"ayu/useScheduledMessages"_q,
|
||||||
|
.title = tr::ayu_UseScheduledMessages(tr::now),
|
||||||
|
.keywords = { u"schedule"_q },
|
||||||
|
.section = sctx.sectionId,
|
||||||
|
});
|
||||||
|
sctx.entries->push_back({
|
||||||
|
.id = u"ayu/sendWithoutSound"_q,
|
||||||
|
.title = tr::ayu_SendWithoutSoundByDefault(tr::now),
|
||||||
|
.keywords = { u"silent"_q, u"sound"_q },
|
||||||
|
.section = sctx.sectionId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupSpyEssentials(not_null<Ui::VerticalLayout*> container) {
|
void BuildSpyEssentials(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
AddSubsectionTitle(container, tr::ayu_SpyEssentialsHeader());
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/spyEssentials"_q,
|
||||||
|
.title = tr::ayu_SpyEssentialsHeader(),
|
||||||
|
.keywords = { u"spy"_q, u"save"_q },
|
||||||
|
});
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_SaveDeletedMessages(), &AyuSettings::saveDeletedMessages, &AyuSettings::setSaveDeletedMessages);
|
ayu.addSettingToggle({
|
||||||
AddSettingToggle(container, tr::ayu_SaveMessagesHistory(), &AyuSettings::saveMessagesHistory, &AyuSettings::setSaveMessagesHistory);
|
.id = u"ayu/saveDeletedMessages"_q,
|
||||||
|
.title = tr::ayu_SaveDeletedMessages(),
|
||||||
|
.getter = &AyuSettings::saveDeletedMessages,
|
||||||
|
.setter = &AyuSettings::setSaveDeletedMessages,
|
||||||
|
.keywords = { u"deleted"_q, u"save"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/saveMessagesHistory"_q,
|
||||||
|
.title = tr::ayu_SaveMessagesHistory(),
|
||||||
|
.getter = &AyuSettings::saveMessagesHistory,
|
||||||
|
.setter = &AyuSettings::setSaveMessagesHistory,
|
||||||
|
.keywords = { u"history"_q, u"edit"_q },
|
||||||
|
});
|
||||||
|
|
||||||
AddSectionDivider(container);
|
ayu.addSectionDivider();
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_MessageSavingSaveForBots(), &AyuSettings::saveForBots, &AyuSettings::setSaveForBots);
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/saveForBots"_q,
|
||||||
|
.title = tr::ayu_MessageSavingSaveForBots(),
|
||||||
|
.getter = &AyuSettings::saveForBots,
|
||||||
|
.setter = &AyuSettings::setSaveForBots,
|
||||||
|
.keywords = { u"bots"_q },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupOther(not_null<Ui::VerticalLayout*> container) {
|
void BuildOther(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
AddSubsectionTitle(container, tr::ayu_MessageSavingOtherHeader());
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/ghostOther"_q,
|
||||||
|
.title = tr::ayu_MessageSavingOtherHeader(),
|
||||||
|
});
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_LocalPremium(), &AyuSettings::localPremium, &AyuSettings::setLocalPremium);
|
ayu.addSettingToggle({
|
||||||
AddSettingToggle(container, tr::ayu_DisableAds(), &AyuSettings::disableAds, &AyuSettings::setDisableAds);
|
.id = u"ayu/localPremium"_q,
|
||||||
AddBetaBadge(AddSettingToggle(container, tr::ayu_SemiTransparentDeletedMessages(), &AyuSettings::semiTransparentDeletedMessages, &AyuSettings::setSemiTransparentDeletedMessages));
|
.title = tr::ayu_LocalPremium(),
|
||||||
|
.getter = &AyuSettings::localPremium,
|
||||||
|
.setter = &AyuSettings::setLocalPremium,
|
||||||
|
.keywords = { u"premium"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/disableAds"_q,
|
||||||
|
.title = tr::ayu_DisableAds(),
|
||||||
|
.getter = &AyuSettings::disableAds,
|
||||||
|
.setter = &AyuSettings::setDisableAds,
|
||||||
|
.keywords = { u"ads"_q, u"sponsored"_q },
|
||||||
|
});
|
||||||
|
const auto semiTransparent = ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/translucentDeletedMessages"_q,
|
||||||
|
.title = tr::ayu_SemiTransparentDeletedMessages(),
|
||||||
|
.getter = &AyuSettings::semiTransparentDeletedMessages,
|
||||||
|
.setter = &AyuSettings::setSemiTransparentDeletedMessages,
|
||||||
|
.keywords = { u"semi-transparent"_q, u"transcluent"_q },
|
||||||
|
});
|
||||||
|
if (semiTransparent) {
|
||||||
|
ayu.addBetaBadge(semiTransparent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto kMeta = BuildHelper({
|
||||||
|
.id = AyuGhost::Id(),
|
||||||
|
.parentId = AyuMain::Id(),
|
||||||
|
.title = &tr::ayu_AyuPreferences,
|
||||||
|
.icon = &st::menuIconGroupReactions,
|
||||||
|
}, [](SectionBuilder &builder) {
|
||||||
|
auto ayu = AyuSectionBuilder(builder);
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
BuildGhostEssentials(builder);
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
BuildSpyEssentials(builder, ayu);
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
BuildOther(builder, ayu);
|
||||||
|
builder.addSkip();
|
||||||
|
});
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
rpl::producer<QString> AyuGhost::title() {
|
rpl::producer<QString> AyuGhost::title() {
|
||||||
return rpl::single(QString("AyuGram"));
|
return rpl::single(QString("AyuGram"));
|
||||||
}
|
}
|
||||||
@@ -500,27 +600,19 @@ rpl::producer<QString> AyuGhost::title() {
|
|||||||
AyuGhost::AyuGhost(
|
AyuGhost::AyuGhost(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller)
|
||||||
: Section(parent, controller)
|
: Section(parent, controller)
|
||||||
, _controller(controller) {
|
, _controller(controller) {
|
||||||
setupContent(controller);
|
setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AyuGhost::setupContent(not_null<Window::SessionController*> controller) {
|
void AyuGhost::setupContent() {
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
build(content, kMeta.build);
|
||||||
|
Ui::ResizeFitChild(this, content);
|
||||||
|
}
|
||||||
|
|
||||||
AddSkip(content);
|
Type AyuGhostId() {
|
||||||
|
return AyuGhost::Id();
|
||||||
SetupGhostEssentials(content, controller);
|
|
||||||
|
|
||||||
AddSkip(content);
|
|
||||||
SetupSpyEssentials(content);
|
|
||||||
|
|
||||||
AddSectionDivider(content);
|
|
||||||
|
|
||||||
SetupOther(content);
|
|
||||||
AddSkip(content);
|
|
||||||
|
|
||||||
ResizeFitChild(this, content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|||||||
@@ -15,17 +15,18 @@ class SessionController;
|
|||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class AyuGhost : public Section<AyuGhost>
|
class AyuGhost : public Section<AyuGhost> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
AyuGhost(QWidget *parent, not_null<Window::SessionController*> controller);
|
AyuGhost(QWidget *parent, not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> title() override;
|
[[nodiscard]] rpl::producer<QString> title() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupContent(not_null<Window::SessionController*> controller);
|
void setupContent();
|
||||||
|
|
||||||
not_null<Window::SessionController*> _controller;
|
not_null<Window::SessionController*> _controller;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Settings
|
[[nodiscard]] Type AyuGhostId();
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|||||||
@@ -6,28 +6,439 @@
|
|||||||
// Copyright @Radolyn, 2026
|
// Copyright @Radolyn, 2026
|
||||||
#include "settings_chats.h"
|
#include "settings_chats.h"
|
||||||
|
|
||||||
#include <styles/style_ayu_icons.h>
|
|
||||||
|
|
||||||
#include "lang_auto.h"
|
#include "lang_auto.h"
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
#include "ayu/ui/boxes/edit_mark_box.h"
|
#include "ayu/ui/boxes/edit_mark_box.h"
|
||||||
|
#include "ayu/ui/settings/ayu_builder.h"
|
||||||
#include "ayu/ui/settings/settings_ayu_utils.h"
|
#include "ayu/ui/settings/settings_ayu_utils.h"
|
||||||
|
#include "ayu/ui/settings/settings_main.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
#include "settings/settings_builder.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "styles/style_ayu_styles.h"
|
#include "styles/style_ayu_icons.h"
|
||||||
#include "styles/style_boxes.h"
|
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_menu_icons.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "ui/vertical_list.h"
|
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "ui/widgets/continuous_sliders.h"
|
#include "ui/widgets/continuous_sliders.h"
|
||||||
#include "ui/widgets/labels.h"
|
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
|
using namespace Builder;
|
||||||
|
using namespace AyBuilder;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void BuildStickersAndEmoji(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/stickersEmoji"_q,
|
||||||
|
.title = tr::lng_settings_stickers_emoji(),
|
||||||
|
.keywords = { u"stickers"_q, u"emoji"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/showOnlyAddedEmojis"_q,
|
||||||
|
.title = tr::ayu_ShowOnlyAddedEmojisAndStickers(),
|
||||||
|
.getter = &AyuSettings::showOnlyAddedEmojisAndStickers,
|
||||||
|
.setter = &AyuSettings::setShowOnlyAddedEmojisAndStickers,
|
||||||
|
.keywords = { u"emoji"_q, u"stickers"_q, u"added"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addCollapsibleToggle({
|
||||||
|
.id = u"ayu/hideReactions"_q,
|
||||||
|
.title = tr::ayu_HideReactions(),
|
||||||
|
.checkboxes = {
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_HideReactionsInChannels(tr::now),
|
||||||
|
[] { return !AyuSettings::getInstance().showChannelReactions(); },
|
||||||
|
[](bool v) { AyuSettings::getInstance().setShowChannelReactions(!v); }
|
||||||
|
},
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_HideReactionsInGroups(tr::now),
|
||||||
|
[] { return !AyuSettings::getInstance().showGroupReactions(); },
|
||||||
|
[](bool v) { AyuSettings::getInstance().setShowGroupReactions(!v); }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.toggledWhenAll = false,
|
||||||
|
.keywords = { u"reactions"_q, u"hide"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildRecentStickersLimit(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
|
ayu.addSlider({
|
||||||
|
.id = u"ayu/recentStickersCount"_q,
|
||||||
|
.title = tr::ayu_SettingsRecentStickersCount(),
|
||||||
|
.steps = 200 + 1,
|
||||||
|
.current = settings->recentStickersCount(),
|
||||||
|
.indexToValue = [](int index) { return index; },
|
||||||
|
.onChanged = nullptr,
|
||||||
|
.onFinalChanged = [](int amount) {
|
||||||
|
AyuSettings::getInstance().setRecentStickersCount(amount);
|
||||||
|
},
|
||||||
|
.formatLabel = [](int amount) { return QString::number(amount); },
|
||||||
|
.keywords = { u"stickers"_q, u"recent"_q, u"limit"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildGroupsAndChannels(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/groupsChannels"_q,
|
||||||
|
.title = tr::lng_premium_double_limits_subtitle_channels(),
|
||||||
|
.keywords = { u"groups"_q, u"channels"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addChooseButton({
|
||||||
|
.id = u"ayu/bottomButton"_q,
|
||||||
|
.title = tr::ayu_ChannelBottomButton(),
|
||||||
|
.boxTitle = tr::ayu_ChannelBottomButton(),
|
||||||
|
.initialSelection = static_cast<int>(settings->channelBottomButton()),
|
||||||
|
.options = {
|
||||||
|
tr::ayu_ChannelBottomButtonHide(tr::now),
|
||||||
|
tr::ayu_ChannelBottomButtonMute(tr::now),
|
||||||
|
tr::ayu_ChannelBottomButtonDiscuss(tr::now),
|
||||||
|
},
|
||||||
|
.setter = [](int index) {
|
||||||
|
AyuSettings::getInstance().setChannelBottomButton(
|
||||||
|
static_cast<ChannelBottomButton>(index));
|
||||||
|
},
|
||||||
|
.keywords = { u"channel"_q, u"bottom"_q, u"button"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/adminShortcuts"_q,
|
||||||
|
.title = tr::ayu_QuickAdminShortcuts(),
|
||||||
|
.getter = &AyuSettings::quickAdminShortcuts,
|
||||||
|
.setter = &AyuSettings::setQuickAdminShortcuts,
|
||||||
|
.keywords = { u"admin"_q, u"shortcuts"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/showMessageShot"_q,
|
||||||
|
.title = tr::ayu_SettingsShowMessageShot(),
|
||||||
|
.getter = &AyuSettings::showMessageShot,
|
||||||
|
.setter = &AyuSettings::setShowMessageShot,
|
||||||
|
.keywords = { u"screenshot"_q, u"shot"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addDividerText(tr::ayu_SettingsShowMessageShotDescription());
|
||||||
|
builder.addSkip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildMarks(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/messages"_q,
|
||||||
|
.title = tr::lng_settings_messages(),
|
||||||
|
.keywords = { u"messages"_q, u"marks"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addButton({
|
||||||
|
.id = u"ayu/deletedMark"_q,
|
||||||
|
.title = tr::ayu_DeletedMarkText(),
|
||||||
|
.st = &st::settingsButtonNoIcon,
|
||||||
|
.label = AyuSettings::getInstance().deletedMarkChanges(),
|
||||||
|
.onClick = [=] {
|
||||||
|
auto box = Box<EditMarkBox>(
|
||||||
|
tr::ayu_DeletedMarkText(),
|
||||||
|
settings->deletedMark(),
|
||||||
|
QString("🧹"),
|
||||||
|
[=](const QString &value) {
|
||||||
|
AyuSettings::getInstance().setDeletedMark(value);
|
||||||
|
});
|
||||||
|
Ui::show(std::move(box));
|
||||||
|
},
|
||||||
|
.keywords = { u"deleted"_q, u"mark"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addButton({
|
||||||
|
.id = u"ayu/editedMark"_q,
|
||||||
|
.title = tr::ayu_EditedMarkText(),
|
||||||
|
.st = &st::settingsButtonNoIcon,
|
||||||
|
.label = AyuSettings::getInstance().editedMarkChanges(),
|
||||||
|
.onClick = [=] {
|
||||||
|
auto box = Box<EditMarkBox>(
|
||||||
|
tr::ayu_EditedMarkText(),
|
||||||
|
settings->editedMark(),
|
||||||
|
tr::lng_edited(tr::now),
|
||||||
|
[=](const QString &value) {
|
||||||
|
AyuSettings::getInstance().setEditedMark(value);
|
||||||
|
});
|
||||||
|
Ui::show(std::move(box));
|
||||||
|
},
|
||||||
|
.keywords = { u"edited"_q, u"mark"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/replaceEditedWithIcon"_q,
|
||||||
|
.title = tr::ayu_ReplaceMarksWithIcons(),
|
||||||
|
.getter = &AyuSettings::replaceBottomInfoWithIcons,
|
||||||
|
.setter = &AyuSettings::setReplaceBottomInfoWithIcons,
|
||||||
|
.keywords = { u"icons"_q, u"marks"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/hideShareButton"_q,
|
||||||
|
.title = tr::ayu_HideShareButton(),
|
||||||
|
.getter = &AyuSettings::hideFastShare,
|
||||||
|
.setter = &AyuSettings::setHideFastShare,
|
||||||
|
.keywords = { u"share"_q, u"forward"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/disableColorfulReplies"_q,
|
||||||
|
.title = tr::ayu_SimpleQuotesAndReplies(),
|
||||||
|
.getter = &AyuSettings::simpleQuotesAndReplies,
|
||||||
|
.setter = &AyuSettings::setSimpleQuotesAndReplies,
|
||||||
|
.keywords = { u"quotes"_q, u"replies"_q, u"simple"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildWideMessagesMultiplier(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
|
constexpr auto kSizeAmount = 61; // (4.00 - 1.00) / 0.05 + 1
|
||||||
|
constexpr auto kMinSize = 1.00;
|
||||||
|
constexpr auto kStep = 0.05;
|
||||||
|
|
||||||
|
const auto valueToIndex = [=](double value) {
|
||||||
|
return static_cast<int>(std::round((value - kMinSize) / kStep));
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto controller = builder.controller();
|
||||||
|
ayu.addSlider({
|
||||||
|
.id = u"ayu/wideMultiplier"_q,
|
||||||
|
.title = tr::ayu_SettingsWideMultiplier(),
|
||||||
|
.steps = kSizeAmount,
|
||||||
|
.current = valueToIndex(settings->wideMultiplier()),
|
||||||
|
.indexToValue = [](int index) { return index; },
|
||||||
|
.onChanged = nullptr,
|
||||||
|
.onFinalChanged = [=](int index) {
|
||||||
|
AyuSettings::getInstance().setWideMultiplier(
|
||||||
|
kMinSize + index * kStep);
|
||||||
|
crl::on_main([=] {
|
||||||
|
controller->show(Ui::MakeConfirmBox({
|
||||||
|
.text = tr::lng_settings_need_restart(),
|
||||||
|
.confirmed = [] { Core::Restart(); },
|
||||||
|
.confirmText = tr::lng_settings_restart_now(),
|
||||||
|
.cancelText = tr::lng_settings_restart_later(),
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.formatLabel = [=](int index) {
|
||||||
|
return QString::number(kMinSize + index * kStep, 'f', 2);
|
||||||
|
},
|
||||||
|
.keywords = { u"wide"_q, u"multiplier"_q, u"width"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addDividerText(tr::ayu_SettingsWideMultiplierDescription());
|
||||||
|
builder.addSkip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildContextMenuElements(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/contextMenu"_q,
|
||||||
|
.title = tr::ayu_ContextMenuElementsHeader(),
|
||||||
|
.keywords = { u"context"_q, u"menu"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto options = std::vector{
|
||||||
|
tr::ayu_SettingsContextMenuItemHidden(tr::now),
|
||||||
|
tr::ayu_SettingsContextMenuItemShown(tr::now),
|
||||||
|
tr::ayu_SettingsContextMenuItemExtended(tr::now),
|
||||||
|
};
|
||||||
|
|
||||||
|
ayu.addChooseButton({
|
||||||
|
.id = u"ayu/contextReactionsPanel"_q,
|
||||||
|
.title = tr::ayu_SettingsContextMenuReactionsPanel(),
|
||||||
|
.boxTitle = tr::ayu_SettingsContextMenuTitle(),
|
||||||
|
.initialSelection = static_cast<int>(settings->showReactionsPanelInContextMenu()),
|
||||||
|
.options = options,
|
||||||
|
.setter = [](int i) { AyuSettings::getInstance().setShowReactionsPanelInContextMenu(static_cast<ContextMenuVisibility>(i)); },
|
||||||
|
.icon = { &st::menuIconReactions },
|
||||||
|
.keywords = { u"reactions"_q, u"panel"_q },
|
||||||
|
});
|
||||||
|
ayu.addChooseButton({
|
||||||
|
.id = u"ayu/contextViewsPanel"_q,
|
||||||
|
.title = tr::ayu_SettingsContextMenuViewsPanel(),
|
||||||
|
.boxTitle = tr::ayu_SettingsContextMenuTitle(),
|
||||||
|
.initialSelection = static_cast<int>(settings->showViewsPanelInContextMenu()),
|
||||||
|
.options = options,
|
||||||
|
.setter = [](int i) { AyuSettings::getInstance().setShowViewsPanelInContextMenu(static_cast<ContextMenuVisibility>(i)); },
|
||||||
|
.icon = { &st::menuIconShowInChat },
|
||||||
|
.keywords = { u"views"_q, u"panel"_q },
|
||||||
|
});
|
||||||
|
ayu.addChooseButton({
|
||||||
|
.id = u"ayu/contextHideMessage"_q,
|
||||||
|
.title = tr::ayu_ContextHideMessage(),
|
||||||
|
.boxTitle = tr::ayu_SettingsContextMenuTitle(),
|
||||||
|
.initialSelection = static_cast<int>(settings->showHideMessageInContextMenu()),
|
||||||
|
.options = options,
|
||||||
|
.setter = [](int i) { AyuSettings::getInstance().setShowHideMessageInContextMenu(static_cast<ContextMenuVisibility>(i)); },
|
||||||
|
.icon = { &st::menuIconClear },
|
||||||
|
.keywords = { u"hide"_q, u"message"_q },
|
||||||
|
});
|
||||||
|
ayu.addChooseButton({
|
||||||
|
.id = u"ayu/contextUserMessages"_q,
|
||||||
|
.title = tr::ayu_UserMessagesMenuText(),
|
||||||
|
.boxTitle = tr::ayu_SettingsContextMenuTitle(),
|
||||||
|
.initialSelection = static_cast<int>(settings->showUserMessagesInContextMenu()),
|
||||||
|
.options = options,
|
||||||
|
.setter = [](int i) { AyuSettings::getInstance().setShowUserMessagesInContextMenu(static_cast<ContextMenuVisibility>(i)); },
|
||||||
|
.icon = { &st::menuIconTTL },
|
||||||
|
.keywords = { u"user"_q, u"messages"_q },
|
||||||
|
});
|
||||||
|
ayu.addChooseButton({
|
||||||
|
.id = u"ayu/contextMessageDetails"_q,
|
||||||
|
.title = tr::ayu_MessageDetailsPC(),
|
||||||
|
.boxTitle = tr::ayu_SettingsContextMenuTitle(),
|
||||||
|
.initialSelection = static_cast<int>(settings->showMessageDetailsInContextMenu()),
|
||||||
|
.options = options,
|
||||||
|
.setter = [](int i) { AyuSettings::getInstance().setShowMessageDetailsInContextMenu(static_cast<ContextMenuVisibility>(i)); },
|
||||||
|
.icon = { &st::menuIconInfo },
|
||||||
|
.keywords = { u"details"_q, u"info"_q },
|
||||||
|
});
|
||||||
|
ayu.addChooseButton({
|
||||||
|
.id = u"ayu/contextRepeatMessage"_q,
|
||||||
|
.title = tr::ayu_RepeatMessage(),
|
||||||
|
.boxTitle = tr::ayu_SettingsContextMenuTitle(),
|
||||||
|
.initialSelection = static_cast<int>(settings->showRepeatMessageInContextMenu()),
|
||||||
|
.options = options,
|
||||||
|
.setter = [](int i) { AyuSettings::getInstance().setShowRepeatMessageInContextMenu(static_cast<ContextMenuVisibility>(i)); },
|
||||||
|
.icon = { &st::menuIconRestore },
|
||||||
|
.keywords = { u"repeat"_q, u"resend"_q },
|
||||||
|
});
|
||||||
|
if (settings->filtersEnabled()) {
|
||||||
|
ayu.addChooseButton({
|
||||||
|
.id = u"ayu/contextAddFilter"_q,
|
||||||
|
.title = tr::ayu_RegexFilterQuickAdd(),
|
||||||
|
.boxTitle = tr::ayu_SettingsContextMenuTitle(),
|
||||||
|
.initialSelection = static_cast<int>(settings->showAddFilterInContextMenu()),
|
||||||
|
.options = options,
|
||||||
|
.setter = [](int i) { AyuSettings::getInstance().setShowAddFilterInContextMenu(static_cast<ContextMenuVisibility>(i)); },
|
||||||
|
.icon = { &st::menuIconAddToFolder },
|
||||||
|
.keywords = { u"filter"_q, u"add"_q },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addDividerText(tr::ayu_SettingsContextMenuDescription());
|
||||||
|
builder.addSkip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildMessageFieldElements(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/messageField"_q,
|
||||||
|
.title = tr::ayu_MessageFieldElementsHeader(),
|
||||||
|
.keywords = { u"message"_q, u"field"_q, u"compose"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/showAttachButton"_q,
|
||||||
|
.title = tr::ayu_MessageFieldElementAttach(),
|
||||||
|
.getter = &AyuSettings::showAttachButtonInMessageField,
|
||||||
|
.setter = &AyuSettings::setShowAttachButtonInMessageField,
|
||||||
|
.icon = { &st::messageFieldAttachIcon },
|
||||||
|
.keywords = { u"attach"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/showCommandsButton"_q,
|
||||||
|
.title = tr::ayu_MessageFieldElementCommands(),
|
||||||
|
.getter = &AyuSettings::showCommandsButtonInMessageField,
|
||||||
|
.setter = &AyuSettings::setShowCommandsButtonInMessageField,
|
||||||
|
.icon = { &st::messageFieldCommandsIcon },
|
||||||
|
.keywords = { u"commands"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/showAutoDeleteButton"_q,
|
||||||
|
.title = tr::ayu_MessageFieldElementTTL(),
|
||||||
|
.getter = &AyuSettings::showAutoDeleteButtonInMessageField,
|
||||||
|
.setter = &AyuSettings::setShowAutoDeleteButtonInMessageField,
|
||||||
|
.icon = { &st::messageFieldTTLIcon },
|
||||||
|
.keywords = { u"auto delete"_q, u"ttl"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/showEmojiButton"_q,
|
||||||
|
.title = tr::ayu_MessageFieldElementEmoji(),
|
||||||
|
.getter = &AyuSettings::showEmojiButtonInMessageField,
|
||||||
|
.setter = &AyuSettings::setShowEmojiButtonInMessageField,
|
||||||
|
.icon = { &st::messageFieldEmojiIcon },
|
||||||
|
.keywords = { u"emoji"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/showMicrophoneButton"_q,
|
||||||
|
.title = tr::ayu_MessageFieldElementVoice(),
|
||||||
|
.getter = &AyuSettings::showMicrophoneButtonInMessageField,
|
||||||
|
.setter = &AyuSettings::setShowMicrophoneButtonInMessageField,
|
||||||
|
.icon = { &st::messageFieldVoiceIcon },
|
||||||
|
.keywords = { u"voice"_q, u"microphone"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildMessageFieldPopups(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/messageFieldPopups"_q,
|
||||||
|
.title = tr::ayu_MessageFieldPopupsHeader(),
|
||||||
|
.keywords = { u"popup"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/showAttachPopup"_q,
|
||||||
|
.title = tr::ayu_MessageFieldElementAttach(),
|
||||||
|
.getter = &AyuSettings::showAttachPopup,
|
||||||
|
.setter = &AyuSettings::setShowAttachPopup,
|
||||||
|
.icon = { &st::messageFieldAttachIcon },
|
||||||
|
.keywords = { u"attach"_q, u"popup"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/showEmojiPopup"_q,
|
||||||
|
.title = tr::ayu_MessageFieldElementEmoji(),
|
||||||
|
.getter = &AyuSettings::showEmojiPopup,
|
||||||
|
.setter = &AyuSettings::setShowEmojiPopup,
|
||||||
|
.icon = { &st::messageFieldEmojiIcon },
|
||||||
|
.keywords = { u"emoji"_q, u"popup"_q },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto kMeta = BuildHelper({
|
||||||
|
.id = AyuChats::Id(),
|
||||||
|
.parentId = AyuMain::Id(),
|
||||||
|
.title = &tr::ayu_CategoryChats,
|
||||||
|
.icon = &st::menuIconChatBubble,
|
||||||
|
}, [](SectionBuilder &builder) {
|
||||||
|
auto ayu = AyuSectionBuilder(builder);
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
BuildStickersAndEmoji(builder, ayu);
|
||||||
|
BuildRecentStickersLimit(builder, ayu);
|
||||||
|
BuildGroupsAndChannels(builder, ayu);
|
||||||
|
BuildMarks(builder, ayu);
|
||||||
|
BuildWideMessagesMultiplier(builder, ayu);
|
||||||
|
BuildContextMenuElements(builder, ayu);
|
||||||
|
BuildMessageFieldElements(builder, ayu);
|
||||||
|
BuildMessageFieldPopups(builder, ayu);
|
||||||
|
builder.addSkip();
|
||||||
|
});
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
rpl::producer<QString> AyuChats::title() {
|
rpl::producer<QString> AyuChats::title() {
|
||||||
return tr::ayu_CategoryChats();
|
return tr::ayu_CategoryChats();
|
||||||
}
|
}
|
||||||
@@ -35,382 +446,18 @@ rpl::producer<QString> AyuChats::title() {
|
|||||||
AyuChats::AyuChats(
|
AyuChats::AyuChats(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller)
|
||||||
: Section(parent, controller) {
|
: Section(parent, controller) {
|
||||||
setupContent(controller);
|
setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupStickersAndEmojiSettings(not_null<Ui::VerticalLayout*> container) {
|
void AyuChats::setupContent() {
|
||||||
AddSubsectionTitle(container, tr::lng_settings_stickers_emoji()/*rpl::single(QString("Stickers and Emoji"))*/);
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_ShowOnlyAddedEmojisAndStickers(), &AyuSettings::showOnlyAddedEmojisAndStickers, &AyuSettings::setShowOnlyAddedEmojisAndStickers);
|
|
||||||
|
|
||||||
std::vector checkboxes = {
|
|
||||||
NestedEntry{
|
|
||||||
tr::ayu_HideReactionsInChannels(tr::now),
|
|
||||||
[] { return !AyuSettings::getInstance().showChannelReactions(); },
|
|
||||||
[](bool v) { AyuSettings::getInstance().setShowChannelReactions(!v); }
|
|
||||||
},
|
|
||||||
NestedEntry{
|
|
||||||
tr::ayu_HideReactionsInGroups(tr::now),
|
|
||||||
[] { return !AyuSettings::getInstance().showGroupReactions(); },
|
|
||||||
[](bool v) { AyuSettings::getInstance().setShowGroupReactions(!v); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AddCollapsibleToggle(container, tr::ayu_HideReactions(), checkboxes, false);
|
|
||||||
|
|
||||||
AddSectionDivider(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupRecentStickersLimit(not_null<Ui::VerticalLayout*> container) {
|
|
||||||
auto *settings = &AyuSettings::getInstance();
|
|
||||||
|
|
||||||
container->add(
|
|
||||||
object_ptr<Button>(container,
|
|
||||||
tr::ayu_SettingsRecentStickersCount(),
|
|
||||||
st::settingsButtonNoIcon)
|
|
||||||
)->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
|
|
||||||
auto recentStickersLimitSlider = MakeSliderWithLabel(
|
|
||||||
container,
|
|
||||||
st::autoDownloadLimitSlider,
|
|
||||||
st::settingsScaleLabel,
|
|
||||||
0,
|
|
||||||
st::settingsScaleLabel.style.font->width("8%%"));
|
|
||||||
container->add(std::move(recentStickersLimitSlider.widget), st::recentStickersLimitPadding);
|
|
||||||
const auto slider = recentStickersLimitSlider.slider;
|
|
||||||
const auto label = recentStickersLimitSlider.label;
|
|
||||||
|
|
||||||
const auto updateLabel = [=](int amount)
|
|
||||||
{
|
|
||||||
label->setText(QString::number(amount));
|
|
||||||
};
|
|
||||||
updateLabel(settings->recentStickersCount());
|
|
||||||
|
|
||||||
slider->setPseudoDiscrete(
|
|
||||||
200 + 1,
|
|
||||||
[=](int amount)
|
|
||||||
{
|
|
||||||
return amount;
|
|
||||||
},
|
|
||||||
settings->recentStickersCount(),
|
|
||||||
[=](int amount)
|
|
||||||
{
|
|
||||||
updateLabel(amount);
|
|
||||||
},
|
|
||||||
[=](int amount)
|
|
||||||
{
|
|
||||||
updateLabel(amount);
|
|
||||||
AyuSettings::getInstance().setRecentStickersCount(amount);
|
|
||||||
});
|
|
||||||
|
|
||||||
AddSectionDivider(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupGroupsAndChannels(not_null<Ui::VerticalLayout*> container, not_null<Window::SessionController*> controller) {
|
|
||||||
auto *settings = &AyuSettings::getInstance();
|
|
||||||
|
|
||||||
AddSubsectionTitle(container,
|
|
||||||
tr::lng_premium_double_limits_subtitle_channels()
|
|
||||||
/*rpl::single(QString("Groups and Channels"))*/);
|
|
||||||
|
|
||||||
const auto options = std::vector{
|
|
||||||
tr::ayu_ChannelBottomButtonHide(tr::now),
|
|
||||||
tr::ayu_ChannelBottomButtonMute(tr::now),
|
|
||||||
tr::ayu_ChannelBottomButtonDiscuss(tr::now),
|
|
||||||
};
|
|
||||||
|
|
||||||
AddChooseButtonWithIconAndRightText(
|
|
||||||
container,
|
|
||||||
controller,
|
|
||||||
static_cast<int>(settings->channelBottomButton()),
|
|
||||||
options,
|
|
||||||
tr::ayu_ChannelBottomButton(),
|
|
||||||
tr::ayu_ChannelBottomButton(),
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setChannelBottomButton(static_cast<ChannelBottomButton>(index));
|
|
||||||
});
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_QuickAdminShortcuts(), &AyuSettings::quickAdminShortcuts, &AyuSettings::setQuickAdminShortcuts);
|
|
||||||
AddSettingToggle(container, tr::ayu_SettingsShowMessageShot(), &AyuSettings::showMessageShot, &AyuSettings::setShowMessageShot);
|
|
||||||
|
|
||||||
AddSkip(container);
|
|
||||||
AddDividerText(container, tr::ayu_SettingsShowMessageShotDescription());
|
|
||||||
AddSkip(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupMarks(not_null<Ui::VerticalLayout*> container) {
|
|
||||||
auto *settings = &AyuSettings::getInstance();
|
|
||||||
|
|
||||||
AddSubsectionTitle(container, tr::lng_settings_messages()/*rpl::single(QString("Messages"))*/);
|
|
||||||
|
|
||||||
AddButtonWithLabel(
|
|
||||||
container,
|
|
||||||
tr::ayu_DeletedMarkText(),
|
|
||||||
AyuSettings::getInstance().deletedMarkChanges(),
|
|
||||||
st::settingsButtonNoIcon
|
|
||||||
)->addClickHandler(
|
|
||||||
[=]()
|
|
||||||
{
|
|
||||||
auto box = Box<EditMarkBox>(
|
|
||||||
tr::ayu_DeletedMarkText(),
|
|
||||||
settings->deletedMark(),
|
|
||||||
QString("🧹"),
|
|
||||||
[=](const QString &value)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setDeletedMark(value);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Ui::show(std::move(box));
|
|
||||||
});
|
|
||||||
|
|
||||||
AddButtonWithLabel(
|
|
||||||
container,
|
|
||||||
tr::ayu_EditedMarkText(),
|
|
||||||
AyuSettings::getInstance().editedMarkChanges(),
|
|
||||||
st::settingsButtonNoIcon
|
|
||||||
)->addClickHandler(
|
|
||||||
[=]()
|
|
||||||
{
|
|
||||||
auto box = Box<EditMarkBox>(
|
|
||||||
tr::ayu_EditedMarkText(),
|
|
||||||
settings->editedMark(),
|
|
||||||
tr::lng_edited(tr::now),
|
|
||||||
[=](const QString &value)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setEditedMark(value);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Ui::show(std::move(box));
|
|
||||||
});
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_ReplaceMarksWithIcons(), &AyuSettings::replaceBottomInfoWithIcons, &AyuSettings::setReplaceBottomInfoWithIcons);
|
|
||||||
|
|
||||||
AddSectionDivider(container);
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_HideShareButton(), &AyuSettings::hideFastShare, &AyuSettings::setHideFastShare);
|
|
||||||
AddSettingToggle(container, tr::ayu_SimpleQuotesAndReplies(), &AyuSettings::simpleQuotesAndReplies, &AyuSettings::setSimpleQuotesAndReplies);
|
|
||||||
|
|
||||||
AddSectionDivider(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupWideMessagesMultiplier(not_null<Ui::VerticalLayout*> container,
|
|
||||||
not_null<Window::SessionController*> controller) {
|
|
||||||
auto *settings = &AyuSettings::getInstance();
|
|
||||||
|
|
||||||
container->add(
|
|
||||||
object_ptr<Button>(container,
|
|
||||||
tr::ayu_SettingsWideMultiplier(),
|
|
||||||
st::settingsButtonNoIcon)
|
|
||||||
)->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
|
|
||||||
auto wideMultiplierSlider = MakeSliderWithLabel(
|
|
||||||
container,
|
|
||||||
st::autoDownloadLimitSlider,
|
|
||||||
st::settingsScaleLabel,
|
|
||||||
0,
|
|
||||||
st::settingsScaleLabel.style.font->width("8%%%"));
|
|
||||||
container->add(std::move(wideMultiplierSlider.widget), st::recentStickersLimitPadding);
|
|
||||||
const auto slider = wideMultiplierSlider.slider;
|
|
||||||
const auto label = wideMultiplierSlider.label;
|
|
||||||
|
|
||||||
const auto updateLabel = [=](double val)
|
|
||||||
{
|
|
||||||
label->setText(QString::number(val, 'f', 2));
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr auto kSizeAmount = 61; // (4.00 - 1.00) / 0.05 + 1
|
|
||||||
constexpr auto kMinSize = 1.00;
|
|
||||||
constexpr auto kStep = 0.05;
|
|
||||||
|
|
||||||
const auto valueToIndex = [=](double value)
|
|
||||||
{
|
|
||||||
return static_cast<int>(std::round((value - kMinSize) / kStep));
|
|
||||||
};
|
|
||||||
const auto indexToValue = [=](int index)
|
|
||||||
{
|
|
||||||
return kMinSize + index * kStep;
|
|
||||||
};
|
|
||||||
|
|
||||||
updateLabel(settings->wideMultiplier());
|
|
||||||
|
|
||||||
slider->setPseudoDiscrete(
|
|
||||||
kSizeAmount,
|
|
||||||
[=](int index) { return index; },
|
|
||||||
valueToIndex(settings->wideMultiplier()),
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
updateLabel(indexToValue(index));
|
|
||||||
},
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
updateLabel(indexToValue(index));
|
|
||||||
AyuSettings::getInstance().setWideMultiplier(indexToValue(index));
|
|
||||||
|
|
||||||
// fix slider
|
|
||||||
crl::on_main([=]
|
|
||||||
{
|
|
||||||
controller->show(Ui::MakeConfirmBox({
|
|
||||||
.text = tr::lng_settings_need_restart(),
|
|
||||||
.confirmed = []
|
|
||||||
{
|
|
||||||
Core::Restart();
|
|
||||||
},
|
|
||||||
.confirmText = tr::lng_settings_restart_now(),
|
|
||||||
.cancelText = tr::lng_settings_restart_later(),
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
AddSkip(container);
|
|
||||||
AddDividerText(container, tr::ayu_SettingsWideMultiplierDescription());
|
|
||||||
AddSkip(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupContextMenuElements(not_null<Ui::VerticalLayout*> container,
|
|
||||||
not_null<Window::SessionController*> controller) {
|
|
||||||
auto *settings = &AyuSettings::getInstance();
|
|
||||||
|
|
||||||
AddSubsectionTitle(container, tr::ayu_ContextMenuElementsHeader());
|
|
||||||
|
|
||||||
const auto options = std::vector{
|
|
||||||
tr::ayu_SettingsContextMenuItemHidden(tr::now),
|
|
||||||
tr::ayu_SettingsContextMenuItemShown(tr::now),
|
|
||||||
tr::ayu_SettingsContextMenuItemExtended(tr::now),
|
|
||||||
};
|
|
||||||
|
|
||||||
AddChooseButtonWithIconAndRightText(
|
|
||||||
container,
|
|
||||||
controller,
|
|
||||||
static_cast<int>(settings->showReactionsPanelInContextMenu()),
|
|
||||||
options,
|
|
||||||
tr::ayu_SettingsContextMenuReactionsPanel(),
|
|
||||||
tr::ayu_SettingsContextMenuTitle(),
|
|
||||||
st::menuIconReactions,
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setShowReactionsPanelInContextMenu(static_cast<ContextMenuVisibility>(index));
|
|
||||||
});
|
|
||||||
AddChooseButtonWithIconAndRightText(
|
|
||||||
container,
|
|
||||||
controller,
|
|
||||||
static_cast<int>(settings->showViewsPanelInContextMenu()),
|
|
||||||
options,
|
|
||||||
tr::ayu_SettingsContextMenuViewsPanel(),
|
|
||||||
tr::ayu_SettingsContextMenuTitle(),
|
|
||||||
st::menuIconShowInChat,
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setShowViewsPanelInContextMenu(static_cast<ContextMenuVisibility>(index));
|
|
||||||
});
|
|
||||||
|
|
||||||
AddChooseButtonWithIconAndRightText(
|
|
||||||
container,
|
|
||||||
controller,
|
|
||||||
static_cast<int>(settings->showHideMessageInContextMenu()),
|
|
||||||
options,
|
|
||||||
tr::ayu_ContextHideMessage(),
|
|
||||||
tr::ayu_SettingsContextMenuTitle(),
|
|
||||||
st::menuIconClear,
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setShowHideMessageInContextMenu(static_cast<ContextMenuVisibility>(index));
|
|
||||||
});
|
|
||||||
AddChooseButtonWithIconAndRightText(
|
|
||||||
container,
|
|
||||||
controller,
|
|
||||||
static_cast<int>(settings->showUserMessagesInContextMenu()),
|
|
||||||
options,
|
|
||||||
tr::ayu_UserMessagesMenuText(),
|
|
||||||
tr::ayu_SettingsContextMenuTitle(),
|
|
||||||
st::menuIconTTL,
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setShowUserMessagesInContextMenu(static_cast<ContextMenuVisibility>(index));
|
|
||||||
});
|
|
||||||
AddChooseButtonWithIconAndRightText(
|
|
||||||
container,
|
|
||||||
controller,
|
|
||||||
static_cast<int>(settings->showMessageDetailsInContextMenu()),
|
|
||||||
options,
|
|
||||||
tr::ayu_MessageDetailsPC(),
|
|
||||||
tr::ayu_SettingsContextMenuTitle(),
|
|
||||||
st::menuIconInfo,
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setShowMessageDetailsInContextMenu(static_cast<ContextMenuVisibility>(index));
|
|
||||||
});
|
|
||||||
AddChooseButtonWithIconAndRightText(
|
|
||||||
container,
|
|
||||||
controller,
|
|
||||||
static_cast<int>(settings->showRepeatMessageInContextMenu()),
|
|
||||||
options,
|
|
||||||
tr::ayu_RepeatMessage(),
|
|
||||||
tr::ayu_SettingsContextMenuTitle(),
|
|
||||||
st::menuIconRestore,
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setShowRepeatMessageInContextMenu(static_cast<ContextMenuVisibility>(index));
|
|
||||||
});
|
|
||||||
if (settings->filtersEnabled()) {
|
|
||||||
AddChooseButtonWithIconAndRightText(
|
|
||||||
container,
|
|
||||||
controller,
|
|
||||||
static_cast<int>(settings->showAddFilterInContextMenu()),
|
|
||||||
options,
|
|
||||||
tr::ayu_RegexFilterQuickAdd(),
|
|
||||||
tr::ayu_SettingsContextMenuTitle(),
|
|
||||||
st::menuIconAddToFolder,
|
|
||||||
[=](int index)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setShowAddFilterInContextMenu(static_cast<ContextMenuVisibility>(index));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
AddSkip(container);
|
|
||||||
AddDividerText(container, tr::ayu_SettingsContextMenuDescription());
|
|
||||||
AddSkip(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupMessageFieldElements(not_null<Ui::VerticalLayout*> container) {
|
|
||||||
AddSubsectionTitle(container, tr::ayu_MessageFieldElementsHeader());
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_MessageFieldElementAttach(), &AyuSettings::showAttachButtonInMessageField, &AyuSettings::setShowAttachButtonInMessageField, st::messageFieldAttachIcon);
|
|
||||||
AddSettingToggle(container, tr::ayu_MessageFieldElementCommands(), &AyuSettings::showCommandsButtonInMessageField, &AyuSettings::setShowCommandsButtonInMessageField, st::messageFieldCommandsIcon);
|
|
||||||
AddSettingToggle(container, tr::ayu_MessageFieldElementTTL(), &AyuSettings::showAutoDeleteButtonInMessageField, &AyuSettings::setShowAutoDeleteButtonInMessageField, st::messageFieldTTLIcon);
|
|
||||||
AddSettingToggle(container, tr::ayu_MessageFieldElementEmoji(), &AyuSettings::showEmojiButtonInMessageField, &AyuSettings::setShowEmojiButtonInMessageField, st::messageFieldEmojiIcon);
|
|
||||||
AddSettingToggle(container, tr::ayu_MessageFieldElementVoice(), &AyuSettings::showMicrophoneButtonInMessageField, &AyuSettings::setShowMicrophoneButtonInMessageField, st::messageFieldVoiceIcon);
|
|
||||||
|
|
||||||
AddSectionDivider(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupMessageFieldPopups(not_null<Ui::VerticalLayout*> container) {
|
|
||||||
AddSubsectionTitle(container, tr::ayu_MessageFieldPopupsHeader());
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_MessageFieldElementAttach(), &AyuSettings::showAttachPopup, &AyuSettings::setShowAttachPopup, st::messageFieldAttachIcon);
|
|
||||||
AddSettingToggle(container, tr::ayu_MessageFieldElementEmoji(), &AyuSettings::showEmojiPopup, &AyuSettings::setShowEmojiPopup, st::messageFieldEmojiIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AyuChats::setupContent(not_null<Window::SessionController*> controller) {
|
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
build(content, kMeta.build);
|
||||||
|
Ui::ResizeFitChild(this, content);
|
||||||
|
}
|
||||||
|
|
||||||
AddSkip(content);
|
Type AyuChatsId() {
|
||||||
SetupStickersAndEmojiSettings(content);
|
return AyuChats::Id();
|
||||||
SetupRecentStickersLimit(content);
|
|
||||||
|
|
||||||
SetupGroupsAndChannels(content, controller);
|
|
||||||
|
|
||||||
SetupMarks(content);
|
|
||||||
SetupWideMessagesMultiplier(content, controller);
|
|
||||||
|
|
||||||
SetupContextMenuElements(content, controller);
|
|
||||||
SetupMessageFieldElements(content);
|
|
||||||
|
|
||||||
SetupMessageFieldPopups(content);
|
|
||||||
AddSkip(content);
|
|
||||||
|
|
||||||
ResizeFitChild(this, content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|||||||
@@ -15,15 +15,16 @@ class SessionController;
|
|||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class AyuChats : public Section<AyuChats>
|
class AyuChats : public Section<AyuChats> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
AyuChats(QWidget *parent, not_null<Window::SessionController*> controller);
|
AyuChats(QWidget *parent, not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> title() override;
|
[[nodiscard]] rpl::producer<QString> title() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupContent(not_null<Window::SessionController*> controller);
|
void setupContent();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Settings
|
[[nodiscard]] Type AyuChatsId();
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
#include "ayu/data/ayu_database.h"
|
#include "ayu/data/ayu_database.h"
|
||||||
#include "ayu/features/filters/filters_cache_controller.h"
|
#include "ayu/features/filters/filters_cache_controller.h"
|
||||||
#include "ayu/ui/boxes/import_filters_box.h"
|
#include "ayu/ui/boxes/import_filters_box.h"
|
||||||
#include "ayu/ui/settings/settings_ayu_utils.h"
|
#include "ayu/ui/settings/ayu_builder.h"
|
||||||
|
#include "ayu/ui/settings/settings_main.h"
|
||||||
#include "ayu/utils/telegram_helpers.h"
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "boxes/peer_list_box.h"
|
#include "boxes/peer_list_box.h"
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
#include "filters/per_dialog_filter.h"
|
#include "filters/per_dialog_filter.h"
|
||||||
#include "filters/settings_filters_list.h"
|
#include "filters/settings_filters_list.h"
|
||||||
#include "inline_bots/bot_attach_web_view.h"
|
#include "inline_bots/bot_attach_web_view.h"
|
||||||
|
#include "settings/settings_builder.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_menu_icons.h"
|
||||||
@@ -34,6 +36,161 @@
|
|||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
|
using namespace Builder;
|
||||||
|
using namespace AyBuilder;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void BuildFiltersSettings(SectionBuilder &builder) {
|
||||||
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/regexFilters"_q,
|
||||||
|
.title = tr::ayu_RegexFilters(),
|
||||||
|
.keywords = { u"regex"_q, u"filters"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto enabledButton = builder.addButton({
|
||||||
|
.id = u"ayu/filtersEnabled"_q,
|
||||||
|
.title = tr::ayu_RegexFiltersEnable(),
|
||||||
|
.st = &st::settingsButtonNoIcon,
|
||||||
|
.toggled = rpl::single(settings->filtersEnabled()),
|
||||||
|
.keywords = { u"regex"_q, u"enable"_q },
|
||||||
|
});
|
||||||
|
if (enabledButton) {
|
||||||
|
enabledButton->toggledValue(
|
||||||
|
) | rpl::filter([=](bool enabled) {
|
||||||
|
return (enabled != settings->filtersEnabled());
|
||||||
|
}) | on_next([=](bool enabled) {
|
||||||
|
AyuSettings::getInstance().setFiltersEnabled(enabled);
|
||||||
|
FiltersCacheController::rebuildCache();
|
||||||
|
FiltersCacheController::fireUpdate();
|
||||||
|
}, enabledButton->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto sharedButton = builder.addButton({
|
||||||
|
.id = u"ayu/filtersInChats"_q,
|
||||||
|
.title = tr::ayu_RegexFiltersEnableSharedInChats(),
|
||||||
|
.st = &st::settingsButtonNoIcon,
|
||||||
|
.toggled = rpl::single(settings->filtersEnabledInChats()),
|
||||||
|
.keywords = { u"shared"_q, u"chats"_q },
|
||||||
|
});
|
||||||
|
if (sharedButton) {
|
||||||
|
sharedButton->toggledValue(
|
||||||
|
) | rpl::filter([=](bool enabled) {
|
||||||
|
return (enabled != settings->filtersEnabledInChats());
|
||||||
|
}) | on_next([=](bool enabled) {
|
||||||
|
AyuSettings::getInstance().setFiltersEnabledInChats(enabled);
|
||||||
|
FiltersCacheController::rebuildCache();
|
||||||
|
FiltersCacheController::fireUpdate();
|
||||||
|
}, sharedButton->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto blockedButton = builder.addButton({
|
||||||
|
.id = u"ayu/hideFromBlocked"_q,
|
||||||
|
.title = tr::ayu_FiltersHideFromBlocked(),
|
||||||
|
.st = &st::settingsButtonNoIcon,
|
||||||
|
.toggled = rpl::single(settings->hideFromBlocked()),
|
||||||
|
.keywords = { u"blocked"_q, u"hide"_q },
|
||||||
|
});
|
||||||
|
if (blockedButton) {
|
||||||
|
blockedButton->toggledValue(
|
||||||
|
) | rpl::filter([=](bool enabled) {
|
||||||
|
return (enabled != settings->hideFromBlocked());
|
||||||
|
}) | on_next([=](bool enabled) {
|
||||||
|
AyuSettings::getInstance().setHideFromBlocked(enabled);
|
||||||
|
FiltersCacheController::rebuildCache();
|
||||||
|
FiltersCacheController::fireUpdate();
|
||||||
|
}, blockedButton->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildShared(SectionBuilder &builder) {
|
||||||
|
builder.addDivider();
|
||||||
|
builder.addSkip();
|
||||||
|
|
||||||
|
const auto controller = builder.controller();
|
||||||
|
builder.addButton({
|
||||||
|
.id = u"ayu/sharedFilters"_q,
|
||||||
|
.title = tr::ayu_RegexFiltersShared(),
|
||||||
|
.st = &st::settingsButtonNoIcon,
|
||||||
|
.onClick = [=] {
|
||||||
|
controller->dialogId = std::nullopt;
|
||||||
|
controller->showExclude = false;
|
||||||
|
controller->showSettings(AyuFiltersList::Id());
|
||||||
|
},
|
||||||
|
.keywords = { u"shared"_q, u"filters"_q },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildShadowBan(SectionBuilder &builder) {
|
||||||
|
const auto controller = builder.controller();
|
||||||
|
|
||||||
|
builder.addButton({
|
||||||
|
.id = u"ayu/shadowBanList"_q,
|
||||||
|
.title = tr::ayu_FiltersShadowBan(),
|
||||||
|
.st = &st::settingsButtonNoIcon,
|
||||||
|
.onClick = [=] {
|
||||||
|
controller->dialogId = std::nullopt;
|
||||||
|
controller->showExclude = false;
|
||||||
|
controller->shadowBan = true;
|
||||||
|
controller->showSettings(AyuFiltersList::Id());
|
||||||
|
},
|
||||||
|
.keywords = { u"shadow"_q, u"ban"_q },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildPerDialog(SectionBuilder &builder) {
|
||||||
|
builder.add([](const BuildContext &ctx) {
|
||||||
|
v::match(ctx, [&](const WidgetContext &wctx) {
|
||||||
|
if (!AyuDatabase::hasPerDialogFilters()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto container = wctx.container;
|
||||||
|
const auto controller = wctx.controller;
|
||||||
|
|
||||||
|
AddSkip(container);
|
||||||
|
AddDivider(container);
|
||||||
|
|
||||||
|
auto ctrl = container->lifetime().make_state<PerDialogFiltersListController>(
|
||||||
|
&controller->session(),
|
||||||
|
controller);
|
||||||
|
|
||||||
|
auto list = object_ptr<Ui::PaddingWrap<PeerListContent>>(
|
||||||
|
container,
|
||||||
|
object_ptr<PeerListContent>(
|
||||||
|
container,
|
||||||
|
ctrl),
|
||||||
|
QMargins(0, -st::peerListBox.padding.top(), 0, -st::peerListBox.padding.bottom()));
|
||||||
|
AddSkip(container);
|
||||||
|
const auto content = container->add(std::move(list));
|
||||||
|
AddSkip(container);
|
||||||
|
auto delegate = container->lifetime().make_state<PeerListContentDelegateSimple>();
|
||||||
|
delegate->setContent(content->entity());
|
||||||
|
ctrl->setDelegate(delegate);
|
||||||
|
}, [&](const SearchContext &) {
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto kMeta = BuildHelper({
|
||||||
|
.id = AyuFilters::Id(),
|
||||||
|
.parentId = AyuMain::Id(),
|
||||||
|
.title = &tr::ayu_CategoryFilters,
|
||||||
|
.icon = &st::menuIconTagFilter,
|
||||||
|
}, [](SectionBuilder &builder) {
|
||||||
|
BuildFiltersSettings(builder);
|
||||||
|
BuildShared(builder);
|
||||||
|
BuildShadowBan(builder);
|
||||||
|
BuildPerDialog(builder);
|
||||||
|
});
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
rpl::producer<QString> AyuFilters::title() {
|
rpl::producer<QString> AyuFilters::title() {
|
||||||
return tr::ayu_CategoryFilters();
|
return tr::ayu_CategoryFilters();
|
||||||
}
|
}
|
||||||
@@ -41,8 +198,7 @@ rpl::producer<QString> AyuFilters::title() {
|
|||||||
void AyuFilters::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
void AyuFilters::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
||||||
addAction(
|
addAction(
|
||||||
tr::ayu_FiltersMenuSelectChat(tr::now),
|
tr::ayu_FiltersMenuSelectChat(tr::now),
|
||||||
[=]
|
[=] {
|
||||||
{
|
|
||||||
if (const auto window = Core::App().activeWindow()) {
|
if (const auto window = Core::App().activeWindow()) {
|
||||||
if (const auto controller = window->sessionController()) {
|
if (const auto controller = window->sessionController()) {
|
||||||
auto types = InlineBots::PeerTypes();
|
auto types = InlineBots::PeerTypes();
|
||||||
@@ -52,8 +208,7 @@ void AyuFilters::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
|||||||
|
|
||||||
Window::ShowChooseRecipientBox(
|
Window::ShowChooseRecipientBox(
|
||||||
controller,
|
controller,
|
||||||
[=](not_null<Data::Thread*> thread)
|
[=](not_null<Data::Thread*> thread) {
|
||||||
{
|
|
||||||
const auto peer = thread->peer();
|
const auto peer = thread->peer();
|
||||||
controller->dialogId = getDialogIdFromPeer(peer);
|
controller->dialogId = getDialogIdFromPeer(peer);
|
||||||
controller->showExclude = true;
|
controller->showExclude = true;
|
||||||
@@ -62,19 +217,15 @@ void AyuFilters::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
|||||||
},
|
},
|
||||||
tr::ayu_FiltersMenuSelectChat(),
|
tr::ayu_FiltersMenuSelectChat(),
|
||||||
nullptr,
|
nullptr,
|
||||||
types
|
types);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&st::menuIconSearch);
|
&st::menuIconSearch);
|
||||||
addAction({
|
addAction({ .isSeparator = true });
|
||||||
.isSeparator = true
|
|
||||||
});
|
|
||||||
addAction(
|
addAction(
|
||||||
tr::ayu_FiltersMenuImport(tr::now),
|
tr::ayu_FiltersMenuImport(tr::now),
|
||||||
[=]
|
[=] {
|
||||||
{
|
|
||||||
auto box = Box(Ui::FillImportFiltersBox, true);
|
auto box = Box(Ui::FillImportFiltersBox, true);
|
||||||
Ui::show(std::move(box));
|
Ui::show(std::move(box));
|
||||||
},
|
},
|
||||||
@@ -82,29 +233,23 @@ void AyuFilters::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
|||||||
if (AyuDatabase::hasFilters()) {
|
if (AyuDatabase::hasFilters()) {
|
||||||
addAction(
|
addAction(
|
||||||
tr::ayu_FiltersMenuExport(tr::now),
|
tr::ayu_FiltersMenuExport(tr::now),
|
||||||
[=]
|
[=] {
|
||||||
{
|
|
||||||
auto box = Box(Ui::FillImportFiltersBox, false);
|
auto box = Box(Ui::FillImportFiltersBox, false);
|
||||||
Ui::show(std::move(box));
|
Ui::show(std::move(box));
|
||||||
},
|
},
|
||||||
&st::menuIconUnarchive);
|
&st::menuIconUnarchive);
|
||||||
}
|
}
|
||||||
addAction({
|
addAction({ .isSeparator = true });
|
||||||
.isSeparator = true
|
|
||||||
});
|
|
||||||
addAction(
|
addAction(
|
||||||
tr::ayu_FiltersMenuClear(tr::now),
|
tr::ayu_FiltersMenuClear(tr::now),
|
||||||
[=]
|
[=] {
|
||||||
{
|
auto callback = [=](Fn<void()> &&close) {
|
||||||
auto callback = [=](Fn<void()> &&close)
|
|
||||||
{
|
|
||||||
AyuDatabase::deleteAllFilters();
|
AyuDatabase::deleteAllFilters();
|
||||||
AyuDatabase::deleteAllExclusions();
|
AyuDatabase::deleteAllExclusions();
|
||||||
FiltersCacheController::rebuildCache();
|
FiltersCacheController::rebuildCache();
|
||||||
FiltersCacheController::fireUpdate();
|
FiltersCacheController::fireUpdate();
|
||||||
close();
|
close();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto box = Ui::MakeConfirmBox({
|
auto box = Ui::MakeConfirmBox({
|
||||||
.text = tr::ayu_FiltersClearPopupText(),
|
.text = tr::ayu_FiltersClearPopupText(),
|
||||||
.confirmed = callback,
|
.confirmed = callback,
|
||||||
@@ -118,159 +263,18 @@ void AyuFilters::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
|||||||
AyuFilters::AyuFilters(
|
AyuFilters::AyuFilters(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller)
|
||||||
: Section(parent, controller) {
|
: Section(parent, controller) {
|
||||||
setupContent(controller);
|
setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupFiltersSettings(not_null<Ui::VerticalLayout*> container) {
|
void AyuFilters::setupContent() {
|
||||||
auto *settings = &AyuSettings::getInstance();
|
|
||||||
|
|
||||||
AddSkip(container);
|
|
||||||
AddSubsectionTitle(container, tr::ayu_RegexFilters());
|
|
||||||
|
|
||||||
AddButtonWithIcon(
|
|
||||||
container,
|
|
||||||
tr::ayu_RegexFiltersEnable(),
|
|
||||||
st::settingsButtonNoIcon
|
|
||||||
)->toggleOn(
|
|
||||||
rpl::single(settings->filtersEnabled())
|
|
||||||
)->toggledValue(
|
|
||||||
) | rpl::filter(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
return (enabled != settings->filtersEnabled());
|
|
||||||
}) | on_next(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setFiltersEnabled(enabled);
|
|
||||||
|
|
||||||
FiltersCacheController::rebuildCache();
|
|
||||||
FiltersCacheController::fireUpdate();
|
|
||||||
},
|
|
||||||
container->lifetime());
|
|
||||||
|
|
||||||
AddButtonWithIcon(
|
|
||||||
container,
|
|
||||||
tr::ayu_RegexFiltersEnableSharedInChats(),
|
|
||||||
st::settingsButtonNoIcon
|
|
||||||
)->toggleOn(
|
|
||||||
rpl::single(settings->filtersEnabledInChats())
|
|
||||||
)->toggledValue(
|
|
||||||
) | rpl::filter(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
return (enabled != settings->filtersEnabledInChats());
|
|
||||||
}) | on_next(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setFiltersEnabledInChats(enabled);
|
|
||||||
|
|
||||||
FiltersCacheController::rebuildCache();
|
|
||||||
FiltersCacheController::fireUpdate();
|
|
||||||
},
|
|
||||||
container->lifetime());
|
|
||||||
|
|
||||||
|
|
||||||
AddButtonWithIcon(
|
|
||||||
container,
|
|
||||||
tr::ayu_FiltersHideFromBlocked(),
|
|
||||||
st::settingsButtonNoIcon
|
|
||||||
)->toggleOn(
|
|
||||||
rpl::single(settings->hideFromBlocked())
|
|
||||||
)->toggledValue(
|
|
||||||
) | rpl::filter(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
return (enabled != settings->hideFromBlocked());
|
|
||||||
}) | on_next(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setHideFromBlocked(enabled);
|
|
||||||
|
|
||||||
FiltersCacheController::rebuildCache();
|
|
||||||
FiltersCacheController::fireUpdate();
|
|
||||||
},
|
|
||||||
container->lifetime());
|
|
||||||
AddSkip(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupShared(not_null<Window::SessionController*> controller,
|
|
||||||
Ui::VerticalLayout *container) {
|
|
||||||
Ui::AddSkip(container);
|
|
||||||
|
|
||||||
auto button = container->add(object_ptr<Ui::SettingsButton>(
|
|
||||||
container,
|
|
||||||
tr::ayu_RegexFiltersShared()
|
|
||||||
));
|
|
||||||
button->addClickHandler([=]
|
|
||||||
{
|
|
||||||
controller->dialogId = std::nullopt; // ensure we're handling shared filters
|
|
||||||
controller->showExclude = false;
|
|
||||||
controller->showSettings(AyuFiltersList::Id());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupShadowBan(not_null<Window::SessionController*> controller,
|
|
||||||
Ui::VerticalLayout *container) {
|
|
||||||
auto button = container->add(object_ptr<Ui::SettingsButton>(
|
|
||||||
container,
|
|
||||||
tr::ayu_FiltersShadowBan()
|
|
||||||
));
|
|
||||||
button->addClickHandler([=]
|
|
||||||
{
|
|
||||||
controller->dialogId = std::nullopt;
|
|
||||||
controller->showExclude = false;
|
|
||||||
controller->shadowBan = true;
|
|
||||||
controller->showSettings(AyuFiltersList::Id());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupPerDialog(
|
|
||||||
not_null<Window::SessionController*> controller,
|
|
||||||
not_null<Ui::VerticalLayout*> container
|
|
||||||
) {
|
|
||||||
auto ctrl = container->lifetime().make_state<PerDialogFiltersListController>(
|
|
||||||
&controller->session(),
|
|
||||||
controller
|
|
||||||
);
|
|
||||||
|
|
||||||
auto list = object_ptr<Ui::PaddingWrap<PeerListContent>>(
|
|
||||||
container,
|
|
||||||
object_ptr<PeerListContent>(
|
|
||||||
container,
|
|
||||||
ctrl),
|
|
||||||
QMargins(0, -st::peerListBox.padding.top(), 0, -st::peerListBox.padding.bottom()));
|
|
||||||
AddSkip(container);
|
|
||||||
const auto content = container->add(std::move(list));
|
|
||||||
AddSkip(container);
|
|
||||||
auto delegate = container->lifetime().make_state<PeerListContentDelegateSimple>();
|
|
||||||
delegate->setContent(content->entity());
|
|
||||||
ctrl->setDelegate(delegate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupMessageFilters(not_null<Ui::VerticalLayout*> container) {
|
|
||||||
AddSubsectionTitle(container, tr::ayu_RegexFilters());
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_FiltersHideFromBlocked(), &AyuSettings::hideFromBlocked, &AyuSettings::setHideFromBlocked);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AyuFilters::setupContent(not_null<Window::SessionController*> controller) {
|
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
build(content, kMeta.build);
|
||||||
|
Ui::ResizeFitChild(this, content);
|
||||||
|
}
|
||||||
|
|
||||||
SetupFiltersSettings(content);
|
Type AyuFiltersId() {
|
||||||
|
return AyuFilters::Id();
|
||||||
AddDivider(content);
|
|
||||||
|
|
||||||
SetupShared(controller, content);
|
|
||||||
SetupShadowBan(controller, content);
|
|
||||||
|
|
||||||
if (AyuDatabase::hasPerDialogFilters()) {
|
|
||||||
AddSkip(content);
|
|
||||||
AddDivider(content);
|
|
||||||
SetupPerDialog(controller, content);
|
|
||||||
}
|
|
||||||
|
|
||||||
ResizeFitChild(this, content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ class SessionController;
|
|||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class AyuFilters : public Section<AyuFilters>
|
class AyuFilters : public Section<AyuFilters> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
AyuFilters(QWidget *parent, not_null<Window::SessionController*> controller);
|
AyuFilters(QWidget *parent, not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
@@ -24,7 +23,9 @@ public:
|
|||||||
void fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) override;
|
void fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupContent(not_null<Window::SessionController*> controller);
|
void setupContent();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Settings
|
[[nodiscard]] Type AyuFiltersId();
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|||||||
@@ -7,94 +7,83 @@
|
|||||||
#include "settings_general.h"
|
#include "settings_general.h"
|
||||||
|
|
||||||
#include "lang_auto.h"
|
#include "lang_auto.h"
|
||||||
#include "settings_ayu_utils.h"
|
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
|
#include "ayu/ui/settings/ayu_builder.h"
|
||||||
|
#include "ayu/ui/settings/settings_ayu_utils.h"
|
||||||
|
#include "ayu/ui/settings/settings_main.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
#include "settings/settings_builder.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
|
#include "styles/style_menu_icons.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "ui/vertical_list.h"
|
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "ui/boxes/single_choice_box.h"
|
#include "ui/boxes/single_choice_box.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
rpl::producer<QString> AyuGeneral::title() {
|
using namespace Builder;
|
||||||
return tr::ayu_CategoryGeneral();
|
using namespace AyBuilder;
|
||||||
}
|
|
||||||
|
|
||||||
AyuGeneral::AyuGeneral(
|
namespace {
|
||||||
QWidget *parent,
|
|
||||||
not_null<Window::SessionController*> controller)
|
void BuildTranslator(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
: Section(parent, controller) {
|
builder.addSubsectionTitle(tr::lng_translate_settings_subtitle());
|
||||||
setupContent(controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupTranslator(not_null<Ui::VerticalLayout*> container,
|
|
||||||
not_null<Window::SessionController*> controller) {
|
|
||||||
auto *settings = &AyuSettings::getInstance();
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
AddSubsectionTitle(container, tr::lng_translate_settings_subtitle()/*rpl::single(QString("Translate Messages"))*/);
|
|
||||||
|
|
||||||
const auto options = std::vector{
|
const auto options = std::vector{
|
||||||
QString("Telegram"),
|
QString("Telegram"),
|
||||||
QString("Google"),
|
QString("Google"),
|
||||||
QString("Yandex")
|
QString("Yandex")
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto getIndex = [=](const QString &val)
|
const auto getIndex = [=](const QString &val) {
|
||||||
{
|
if (val == "telegram") return 0;
|
||||||
if (val == "telegram") {
|
if (val == "google") return 1;
|
||||||
return 0;
|
if (val == "yandex") return 2;
|
||||||
}
|
|
||||||
if (val == "google") {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (val == "yandex") {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto currentVal = AyuSettings::getInstance().translationProviderChanges() | rpl::map(getIndex) | rpl::map(
|
auto currentVal = AyuSettings::getInstance().translationProviderChanges()
|
||||||
[=](int val)
|
| rpl::map(getIndex)
|
||||||
{
|
| rpl::map([=](int val) { return options[val]; });
|
||||||
return options[val];
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto button = AddButtonWithLabel(
|
const auto button = builder.addButton({
|
||||||
container,
|
.id = u"ayu/translationProvider"_q,
|
||||||
tr::ayu_TranslationProvider(),
|
.title = tr::ayu_TranslationProvider(),
|
||||||
currentVal,
|
.st = &st::settingsButtonNoIcon,
|
||||||
st::settingsButtonNoIcon);
|
.label = std::move(currentVal),
|
||||||
AddBetaBadge(button);
|
.onClick = [=] {
|
||||||
button->addClickHandler(
|
if (const auto controller = Core::App().activeWindow()->sessionController()) {
|
||||||
[=]
|
controller->show(Box(
|
||||||
{
|
[=](not_null<Ui::GenericBox*> box) {
|
||||||
controller->show(Box(
|
const auto save = [=](int index) {
|
||||||
[=](not_null<Ui::GenericBox*> box)
|
const auto provider = (index == 0)
|
||||||
{
|
? "telegram"
|
||||||
const auto save = [=](int index)
|
: (index == 1) ? "google" : "yandex";
|
||||||
{
|
AyuSettings::getInstance().setTranslationProvider(provider);
|
||||||
const auto provider = (index == 0) ? "telegram" : (index == 1) ? "google" : "yandex";
|
};
|
||||||
|
SingleChoiceBox(box, {
|
||||||
AyuSettings::getInstance().setTranslationProvider(provider);
|
.title = tr::ayu_TranslationProvider(),
|
||||||
};
|
.options = options,
|
||||||
SingleChoiceBox(box,
|
.initialSelection = getIndex(settings->translationProvider()),
|
||||||
{
|
.callback = save,
|
||||||
.title = tr::ayu_TranslationProvider(),
|
});
|
||||||
.options = options,
|
}));
|
||||||
.initialSelection = getIndex(settings->translationProvider()),
|
}
|
||||||
.callback = save,
|
},
|
||||||
});
|
.keywords = { u"translate"_q, u"translation"_q, u"provider"_q },
|
||||||
}));
|
});
|
||||||
});
|
if (button) {
|
||||||
|
ayu.addBetaBadge(button);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupShowPeerId(not_null<Ui::VerticalLayout*> container,
|
void BuildShowPeerId(SectionBuilder &builder) {
|
||||||
not_null<Window::SessionController*> controller) {
|
|
||||||
auto *settings = &AyuSettings::getInstance();
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
const auto options = std::vector{
|
const auto options = std::vector{
|
||||||
@@ -103,144 +92,229 @@ void SetupShowPeerId(not_null<Ui::VerticalLayout*> container,
|
|||||||
QString("Bot API")
|
QString("Bot API")
|
||||||
};
|
};
|
||||||
|
|
||||||
auto currentVal = AyuSettings::getInstance().showPeerIdChanges() | rpl::map(
|
auto currentVal = AyuSettings::getInstance().showPeerIdChanges()
|
||||||
[=](PeerIdDisplay val)
|
| rpl::map([=](PeerIdDisplay val) {
|
||||||
{
|
|
||||||
return options[static_cast<int>(val)];
|
return options[static_cast<int>(val)];
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto button = AddButtonWithLabel(
|
const auto controller = builder.controller();
|
||||||
container,
|
builder.addButton({
|
||||||
tr::ayu_SettingsShowID(),
|
.id = u"ayu/showIdAndDc"_q,
|
||||||
currentVal,
|
.title = tr::ayu_SettingsShowID(),
|
||||||
st::settingsButtonNoIcon);
|
.st = &st::settingsButtonNoIcon,
|
||||||
button->addClickHandler(
|
.label = std::move(currentVal),
|
||||||
[=]
|
.onClick = [=] {
|
||||||
{
|
|
||||||
controller->show(Box(
|
controller->show(Box(
|
||||||
[=](not_null<Ui::GenericBox*> box)
|
[=](not_null<Ui::GenericBox*> box) {
|
||||||
{
|
const auto save = [=](int index) {
|
||||||
const auto save = [=](int index)
|
AyuSettings::getInstance().setShowPeerId(
|
||||||
{
|
static_cast<PeerIdDisplay>(index));
|
||||||
AyuSettings::getInstance().setShowPeerId(static_cast<PeerIdDisplay>(index));
|
|
||||||
};
|
};
|
||||||
SingleChoiceBox(box,
|
SingleChoiceBox(box, {
|
||||||
{
|
.title = tr::ayu_SettingsShowID(),
|
||||||
.title = tr::ayu_SettingsShowID(),
|
.options = options,
|
||||||
.options = options,
|
.initialSelection = static_cast<int>(settings->showPeerId()),
|
||||||
.initialSelection = static_cast<int>(settings->showPeerId()),
|
.callback = save,
|
||||||
.callback = save,
|
});
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
});
|
},
|
||||||
|
.keywords = { u"peer"_q, u"id"_q },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupQoLToggles(not_null<Ui::VerticalLayout*> container, not_null<Window::SessionController*> controller) {
|
void BuildQoLToggles(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
auto *settings = &AyuSettings::getInstance();
|
auto *settings = &AyuSettings::getInstance();
|
||||||
|
|
||||||
SetupTranslator(container, controller);
|
BuildTranslator(builder, ayu);
|
||||||
AddSectionDivider(container);
|
ayu.addSectionDivider();
|
||||||
|
|
||||||
AddSubsectionTitle(container, tr::ayu_CategoryGeneral());
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/generalSection"_q,
|
||||||
|
.title = tr::ayu_CategoryGeneral(),
|
||||||
|
});
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_DisableStories(), &AyuSettings::disableStories, &AyuSettings::setDisableStories);
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/hideStories"_q,
|
||||||
|
.title = tr::ayu_DisableStories(),
|
||||||
|
.getter = &AyuSettings::disableStories,
|
||||||
|
.setter = &AyuSettings::setDisableStories,
|
||||||
|
.keywords = { u"stories"_q },
|
||||||
|
});
|
||||||
|
|
||||||
std::vector checkboxes = {
|
ayu.addCollapsibleToggle({
|
||||||
NestedEntry{
|
.id = u"ayu/similarChannels"_q,
|
||||||
tr::ayu_CollapseSimilarChannels(tr::now),
|
.title = tr::ayu_DisableSimilarChannels(),
|
||||||
[] { return AyuSettings::getInstance().collapseSimilarChannels(); },
|
.checkboxes = {
|
||||||
[](bool v) { AyuSettings::getInstance().setCollapseSimilarChannels(v); }
|
NestedEntry{
|
||||||
|
tr::ayu_CollapseSimilarChannels(tr::now),
|
||||||
|
[] { return AyuSettings::getInstance().collapseSimilarChannels(); },
|
||||||
|
[](bool v) { AyuSettings::getInstance().setCollapseSimilarChannels(v); }
|
||||||
|
},
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_HideSimilarChannelsTab(tr::now),
|
||||||
|
[] { return AyuSettings::getInstance().hideSimilarChannels(); },
|
||||||
|
[](bool v) { AyuSettings::getInstance().setHideSimilarChannels(v); }
|
||||||
|
}
|
||||||
},
|
},
|
||||||
NestedEntry{
|
.toggledWhenAll = true,
|
||||||
tr::ayu_HideSimilarChannelsTab(tr::now),
|
.keywords = { u"similar"_q, u"channels"_q },
|
||||||
[] { return AyuSettings::getInstance().hideSimilarChannels(); },
|
});
|
||||||
[](bool v) { AyuSettings::getInstance().setHideSimilarChannels(v); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AddCollapsibleToggle(container, tr::ayu_DisableSimilarChannels(), checkboxes, true);
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/disableNotificationsDelay"_q,
|
||||||
|
.title = tr::ayu_DisableNotificationsDelay(),
|
||||||
|
.getter = &AyuSettings::disableNotificationsDelay,
|
||||||
|
.setter = &AyuSettings::setDisableNotificationsDelay,
|
||||||
|
.keywords = { u"notifications"_q, u"delay"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSectionDivider();
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_DisableNotificationsDelay(), &AyuSettings::disableNotificationsDelay, &AyuSettings::setDisableNotificationsDelay);
|
const auto controller = builder.controller();
|
||||||
|
const auto zalgoButton = builder.addButton({
|
||||||
|
.id = u"ayu/filterZalgo"_q,
|
||||||
|
.title = tr::ayu_FilterZalgo(),
|
||||||
|
.st = &st::settingsButtonNoIcon,
|
||||||
|
.toggled = rpl::single(settings->filterZalgo()),
|
||||||
|
.keywords = { u"zalgo"_q, u"filter"_q },
|
||||||
|
});
|
||||||
|
if (zalgoButton) {
|
||||||
|
zalgoButton->toggledValue(
|
||||||
|
) | rpl::filter(
|
||||||
|
[=](bool enabled) {
|
||||||
|
return (enabled != settings->filterZalgo());
|
||||||
|
}
|
||||||
|
) | on_next(
|
||||||
|
[=](bool enabled) {
|
||||||
|
AyuSettings::getInstance().setFilterZalgo(enabled);
|
||||||
|
controller->show(Ui::MakeConfirmBox({
|
||||||
|
.text = tr::lng_settings_need_restart(),
|
||||||
|
.confirmed = [] { Core::Restart(); },
|
||||||
|
.confirmText = tr::lng_settings_restart_now(),
|
||||||
|
.cancelText = tr::lng_settings_restart_later(),
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
zalgoButton->lifetime());
|
||||||
|
ayu.addBetaBadge(zalgoButton);
|
||||||
|
}
|
||||||
|
|
||||||
AddSectionDivider(container);
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/improveLinkPreviews"_q,
|
||||||
|
.title = tr::ayu_ImproveLinkPreviews(),
|
||||||
|
.getter = &AyuSettings::improveLinkPreviews,
|
||||||
|
.setter = &AyuSettings::setImproveLinkPreviews,
|
||||||
|
.keywords = { u"link"_q, u"preview"_q },
|
||||||
|
});
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/formatTimeWithSeconds"_q,
|
||||||
|
.title = tr::ayu_SettingsShowMessageSeconds(),
|
||||||
|
.getter = &AyuSettings::showMessageSeconds,
|
||||||
|
.setter = &AyuSettings::setShowMessageSeconds,
|
||||||
|
.keywords = { u"seconds"_q, u"time"_q },
|
||||||
|
});
|
||||||
|
|
||||||
const auto button = AddButtonWithIcon(
|
BuildShowPeerId(builder);
|
||||||
container,
|
|
||||||
tr::ayu_FilterZalgo(),
|
|
||||||
st::settingsButtonNoIcon
|
|
||||||
)->toggleOn(
|
|
||||||
rpl::single(settings->filterZalgo())
|
|
||||||
);
|
|
||||||
button->toggledValue(
|
|
||||||
) | rpl::filter(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
return (enabled != settings->filterZalgo());
|
|
||||||
}) | on_next(
|
|
||||||
[=](bool enabled)
|
|
||||||
{
|
|
||||||
AyuSettings::getInstance().setFilterZalgo(enabled);
|
|
||||||
|
|
||||||
// restart because hooks for filter are in Peer::setName which can be updated only on restart
|
ayu.addSectionDivider();
|
||||||
// same for HistoryItem::setText
|
|
||||||
controller->show(Ui::MakeConfirmBox({
|
builder.addSubsectionTitle({
|
||||||
.text = tr::lng_settings_need_restart(),
|
.id = u"ayu/webviewSection"_q,
|
||||||
.confirmed = []
|
.title = rpl::single(QString("Webview")),
|
||||||
{
|
.keywords = { u"webview"_q },
|
||||||
Core::Restart();
|
});
|
||||||
},
|
|
||||||
.confirmText = tr::lng_settings_restart_now(),
|
ayu.addSettingToggle({
|
||||||
.cancelText = tr::lng_settings_restart_later(),
|
.id = u"ayu/spoofWebviewAsAndroid"_q,
|
||||||
}));
|
.title = tr::ayu_SettingsSpoofWebviewAsAndroid(),
|
||||||
|
.getter = &AyuSettings::spoofWebviewAsAndroid,
|
||||||
|
.setter = &AyuSettings::setSpoofWebviewAsAndroid,
|
||||||
|
.keywords = { u"webview"_q, u"android"_q, u"spoof"_q },
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addCollapsibleToggle({
|
||||||
|
.id = u"ayu/biggerWindow"_q,
|
||||||
|
.title = tr::ayu_SettingsBiggerWindow(),
|
||||||
|
.checkboxes = {
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_SettingsIncreaseWebviewHeight(tr::now),
|
||||||
|
[] { return AyuSettings::getInstance().increaseWebviewHeight(); },
|
||||||
|
[](bool v) { AyuSettings::getInstance().setIncreaseWebviewHeight(v); }
|
||||||
|
},
|
||||||
|
NestedEntry{
|
||||||
|
tr::ayu_SettingsIncreaseWebviewWidth(tr::now),
|
||||||
|
[] { return AyuSettings::getInstance().increaseWebviewWidth(); },
|
||||||
|
[](bool v) { AyuSettings::getInstance().setIncreaseWebviewWidth(v); }
|
||||||
|
}
|
||||||
},
|
},
|
||||||
container->lifetime());
|
.toggledWhenAll = false,
|
||||||
AddBetaBadge(button);
|
.keywords = { u"webview"_q, u"window"_q, u"size"_q },
|
||||||
|
});
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_ImproveLinkPreviews(), &AyuSettings::improveLinkPreviews, &AyuSettings::setImproveLinkPreviews);
|
ayu.addSectionDivider();
|
||||||
AddSettingToggle(container, tr::ayu_SettingsShowMessageSeconds(), &AyuSettings::showMessageSeconds, &AyuSettings::setShowMessageSeconds);
|
|
||||||
|
|
||||||
SetupShowPeerId(container, controller);
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/confirmationsSection"_q,
|
||||||
|
.title = tr::ayu_ConfirmationsTitle(),
|
||||||
|
.keywords = { u"confirmation"_q },
|
||||||
|
});
|
||||||
|
|
||||||
AddSectionDivider(container);
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/stickerConfirmation"_q,
|
||||||
AddSubsectionTitle(container, rpl::single(QString("Webview")));
|
.title = tr::ayu_StickerConfirmation(),
|
||||||
|
.getter = &AyuSettings::stickerConfirmation,
|
||||||
AddSettingToggle(container, tr::ayu_SettingsSpoofWebviewAsAndroid(), &AyuSettings::spoofWebviewAsAndroid, &AyuSettings::setSpoofWebviewAsAndroid);
|
.setter = &AyuSettings::setStickerConfirmation,
|
||||||
|
.keywords = { u"sticker"_q, u"confirmation"_q },
|
||||||
std::vector webviewCheckboxes = {
|
});
|
||||||
NestedEntry{
|
ayu.addSettingToggle({
|
||||||
tr::ayu_SettingsIncreaseWebviewHeight(tr::now),
|
.id = u"ayu/gifConfirmation"_q,
|
||||||
[] { return AyuSettings::getInstance().increaseWebviewHeight(); },
|
.title = tr::ayu_GIFConfirmation(),
|
||||||
[](bool v) { AyuSettings::getInstance().setIncreaseWebviewHeight(v); }
|
.getter = &AyuSettings::gifConfirmation,
|
||||||
},
|
.setter = &AyuSettings::setGifConfirmation,
|
||||||
NestedEntry{
|
.keywords = { u"gif"_q, u"confirmation"_q },
|
||||||
tr::ayu_SettingsIncreaseWebviewWidth(tr::now),
|
});
|
||||||
[] { return AyuSettings::getInstance().increaseWebviewWidth(); },
|
ayu.addSettingToggle({
|
||||||
[](bool v) { AyuSettings::getInstance().setIncreaseWebviewWidth(v); }
|
.id = u"ayu/voiceConfirmation"_q,
|
||||||
}
|
.title = tr::ayu_VoiceConfirmation(),
|
||||||
};
|
.getter = &AyuSettings::voiceConfirmation,
|
||||||
|
.setter = &AyuSettings::setVoiceConfirmation,
|
||||||
AddCollapsibleToggle(container, tr::ayu_SettingsBiggerWindow(), webviewCheckboxes, false);
|
.keywords = { u"voice"_q, u"confirmation"_q },
|
||||||
|
});
|
||||||
AddSectionDivider(container);
|
|
||||||
|
|
||||||
// todo: move into a single checkbox with dropdown
|
|
||||||
AddSubsectionTitle(container, tr::ayu_ConfirmationsTitle());
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_StickerConfirmation(), &AyuSettings::stickerConfirmation, &AyuSettings::setStickerConfirmation);
|
|
||||||
AddSettingToggle(container, tr::ayu_GIFConfirmation(), &AyuSettings::gifConfirmation, &AyuSettings::setGifConfirmation);
|
|
||||||
AddSettingToggle(container, tr::ayu_VoiceConfirmation(), &AyuSettings::voiceConfirmation, &AyuSettings::setVoiceConfirmation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AyuGeneral::setupContent(not_null<Window::SessionController*> controller) {
|
const auto kMeta = BuildHelper({
|
||||||
|
.id = AyuGeneral::Id(),
|
||||||
|
.parentId = AyuMain::Id(),
|
||||||
|
.title = &tr::ayu_CategoryGeneral,
|
||||||
|
.icon = &st::menuIconShowAll,
|
||||||
|
}, [](SectionBuilder &builder) {
|
||||||
|
auto ayu = AyuSectionBuilder(builder);
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
BuildQoLToggles(builder, ayu);
|
||||||
|
builder.addSkip();
|
||||||
|
});
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
rpl::producer<QString> AyuGeneral::title() {
|
||||||
|
return tr::ayu_CategoryGeneral();
|
||||||
|
}
|
||||||
|
|
||||||
|
AyuGeneral::AyuGeneral(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Window::SessionController*> controller)
|
||||||
|
: Section(parent, controller) {
|
||||||
|
setupContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AyuGeneral::setupContent() {
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
build(content, kMeta.build);
|
||||||
AddSkip(content);
|
Ui::ResizeFitChild(this, content);
|
||||||
SetupQoLToggles(content, controller);
|
|
||||||
AddSkip(content);
|
|
||||||
|
|
||||||
ResizeFitChild(this, content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
Type AyuGeneralId() {
|
||||||
|
return AyuGeneral::Id();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|||||||
@@ -15,15 +15,16 @@ class SessionController;
|
|||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class AyuGeneral : public Section<AyuGeneral>
|
class AyuGeneral : public Section<AyuGeneral> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
AyuGeneral(QWidget *parent, not_null<Window::SessionController*> controller);
|
AyuGeneral(QWidget *parent, not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> title() override;
|
[[nodiscard]] rpl::producer<QString> title() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupContent(not_null<Window::SessionController*> controller);
|
void setupContent();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] Type AyuGeneralId();
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|||||||
@@ -7,27 +7,25 @@
|
|||||||
#include "settings_main.h"
|
#include "settings_main.h"
|
||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <styles/style_ayu_icons.h>
|
|
||||||
|
|
||||||
|
#include "settings/sections/settings_main.h"
|
||||||
#include "lang_auto.h"
|
#include "lang_auto.h"
|
||||||
#include "settings_appearance.h"
|
#include "settings_appearance.h"
|
||||||
#include "settings_ayu.h"
|
#include "settings_ayu.h"
|
||||||
#include "settings_ayu_utils.h"
|
|
||||||
#include "settings_chats.h"
|
#include "settings_chats.h"
|
||||||
#include "settings_filters.h"
|
#include "settings_filters.h"
|
||||||
#include "settings_general.h"
|
#include "settings_general.h"
|
||||||
#include "settings_other.h"
|
#include "settings_other.h"
|
||||||
|
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
#include "ayu/ui/ayu_logo.h"
|
#include "ayu/ui/ayu_logo.h"
|
||||||
#include "core/version.h"
|
#include "core/version.h"
|
||||||
|
#include "settings/settings_builder.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "styles/style_ayu_settings.h"
|
#include "styles/style_ayu_settings.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_menu_icons.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
#include "ui/vertical_list.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
@@ -36,6 +34,176 @@
|
|||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
|
using namespace Builder;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void BuildLogo(SectionBuilder &builder) {
|
||||||
|
builder.add([](const WidgetContext &ctx) -> SectionBuilder::WidgetToAdd {
|
||||||
|
auto logo = object_ptr<Ui::RpWidget>(ctx.container);
|
||||||
|
const auto logoRaw = logo.data();
|
||||||
|
logoRaw->resize(
|
||||||
|
QSize(st::settingsCloudPasswordIconSize,
|
||||||
|
st::settingsCloudPasswordIconSize));
|
||||||
|
logoRaw->setNaturalWidth(st::settingsCloudPasswordIconSize);
|
||||||
|
logoRaw->paintRequest(
|
||||||
|
) | rpl::on_next([=] {
|
||||||
|
auto p = QPainter(logoRaw);
|
||||||
|
const auto image = AyuAssets::currentAppLogoPad();
|
||||||
|
if (!image.isNull()) {
|
||||||
|
const auto size = st::settingsCloudPasswordIconSize;
|
||||||
|
const auto scaled = image.scaled(
|
||||||
|
size * style::DevicePixelRatio(),
|
||||||
|
size * style::DevicePixelRatio(),
|
||||||
|
Qt::KeepAspectRatio,
|
||||||
|
Qt::SmoothTransformation);
|
||||||
|
p.drawImage(QRect(0, 0, size, size), scaled);
|
||||||
|
}
|
||||||
|
}, logoRaw->lifetime());
|
||||||
|
return { .widget = std::move(logo), .align = style::al_top };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildVersionInfo(SectionBuilder &builder) {
|
||||||
|
builder.add([](const WidgetContext &ctx) -> SectionBuilder::WidgetToAdd {
|
||||||
|
return {
|
||||||
|
.widget = object_ptr<Ui::FlatLabel>(
|
||||||
|
ctx.container,
|
||||||
|
rpl::single(
|
||||||
|
QString("AyuGram Desktop v")
|
||||||
|
+ QString::fromLatin1(AppVersionStr)),
|
||||||
|
st::boxTitle),
|
||||||
|
.align = style::al_top,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
|
||||||
|
builder.add([](const WidgetContext &ctx) -> SectionBuilder::WidgetToAdd {
|
||||||
|
return {
|
||||||
|
.widget = object_ptr<Ui::FlatLabel>(
|
||||||
|
ctx.container,
|
||||||
|
tr::ayu_SettingsDescription(),
|
||||||
|
st::centeredBoxLabel),
|
||||||
|
.align = style::al_top,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildCategories(SectionBuilder &builder) {
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addDivider();
|
||||||
|
builder.addSkip();
|
||||||
|
|
||||||
|
builder.addSubsectionTitle(tr::ayu_CategoriesHeader());
|
||||||
|
|
||||||
|
builder.addSectionButton({
|
||||||
|
.title = rpl::single(QString("AyuGram")),
|
||||||
|
.targetSection = AyuGhost::Id(),
|
||||||
|
.icon = { &st::menuIconGroupReactions },
|
||||||
|
.keywords = { u"ghost"_q, u"ayugram"_q },
|
||||||
|
});
|
||||||
|
builder.addSectionButton({
|
||||||
|
.title = tr::ayu_CategoryFilters(),
|
||||||
|
.targetSection = AyuFilters::Id(),
|
||||||
|
.icon = { &st::menuIconTagFilter },
|
||||||
|
.keywords = { u"filters"_q, u"regex"_q },
|
||||||
|
});
|
||||||
|
builder.addSectionButton({
|
||||||
|
.title = tr::ayu_CategoryGeneral(),
|
||||||
|
.targetSection = AyuGeneral::Id(),
|
||||||
|
.icon = { &st::menuIconShowAll },
|
||||||
|
.keywords = { u"general"_q },
|
||||||
|
});
|
||||||
|
builder.addSectionButton({
|
||||||
|
.title = tr::ayu_CategoryAppearance(),
|
||||||
|
.targetSection = AyuAppearance::Id(),
|
||||||
|
.icon = { &st::menuIconPalette },
|
||||||
|
.keywords = { u"appearance"_q, u"theme"_q },
|
||||||
|
});
|
||||||
|
builder.addSectionButton({
|
||||||
|
.title = tr::ayu_CategoryChats(),
|
||||||
|
.targetSection = AyuChats::Id(),
|
||||||
|
.icon = { &st::menuIconChatBubble },
|
||||||
|
.keywords = { u"chats"_q, u"messages"_q },
|
||||||
|
});
|
||||||
|
builder.addSectionButton({
|
||||||
|
.title = tr::ayu_CategoryOther(),
|
||||||
|
.targetSection = AyuOther::Id(),
|
||||||
|
.icon = { &st::menuIconFave },
|
||||||
|
.keywords = { u"other"_q, u"donate"_q },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildLinks(SectionBuilder &builder) {
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addDivider();
|
||||||
|
builder.addSkip();
|
||||||
|
|
||||||
|
builder.addSubsectionTitle(tr::ayu_LinksHeader());
|
||||||
|
|
||||||
|
const auto controller = builder.controller();
|
||||||
|
|
||||||
|
builder.addButton({
|
||||||
|
.title = tr::ayu_LinksChannel(),
|
||||||
|
.icon = { &st::menuIconChannel },
|
||||||
|
.label = rpl::single(QString("@ayugram")),
|
||||||
|
.onClick = [=] {
|
||||||
|
controller->showPeerByLink(Window::PeerByLinkInfo{
|
||||||
|
.usernameOrId = QString("ayugram"),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
builder.addButton({
|
||||||
|
.title = tr::ayu_LinksChats(),
|
||||||
|
.icon = { &st::menuIconChats },
|
||||||
|
.label = rpl::single(QString("@ayugramchat")),
|
||||||
|
.onClick = [=] {
|
||||||
|
controller->showPeerByLink(Window::PeerByLinkInfo{
|
||||||
|
.usernameOrId = QString("ayugramchat"),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
builder.addButton({
|
||||||
|
.title = tr::ayu_LinksTranslate(),
|
||||||
|
.icon = { &st::menuIconTranslate },
|
||||||
|
.label = rpl::single(QString("Crowdin")),
|
||||||
|
.onClick = [=] {
|
||||||
|
QDesktopServices::openUrl(
|
||||||
|
QString("https://translate.ayugram.one"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
builder.addButton({
|
||||||
|
.title = tr::ayu_LinksDocumentation(),
|
||||||
|
.icon = { &st::menuIconIpAddress },
|
||||||
|
.label = rpl::single(QString("docs.ayugram.one")),
|
||||||
|
.onClick = [=] {
|
||||||
|
QDesktopServices::openUrl(
|
||||||
|
QString("https://docs.ayugram.one"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto kMeta = BuildHelper({
|
||||||
|
.id = AyuMain::Id(),
|
||||||
|
.parentId = MainId(),
|
||||||
|
.title = &tr::ayu_AyuPreferences,
|
||||||
|
.icon = &st::menuIconPremium,
|
||||||
|
}, [](SectionBuilder &builder) {
|
||||||
|
BuildLogo(builder);
|
||||||
|
builder.addSkip();
|
||||||
|
BuildVersionInfo(builder);
|
||||||
|
BuildCategories(builder);
|
||||||
|
BuildLinks(builder);
|
||||||
|
});
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
rpl::producer<QString> AyuMain::title() {
|
rpl::producer<QString> AyuMain::title() {
|
||||||
return rpl::single(QString(""));
|
return rpl::single(QString(""));
|
||||||
}
|
}
|
||||||
@@ -43,179 +211,18 @@ rpl::producer<QString> AyuMain::title() {
|
|||||||
AyuMain::AyuMain(
|
AyuMain::AyuMain(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller)
|
||||||
: Section(parent, controller) {
|
: Section(parent, controller) {
|
||||||
setupContent(controller);
|
setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupAppLogo(not_null<Ui::VerticalLayout*> container) {
|
void AyuMain::setupContent() {
|
||||||
const auto logo = container->add(
|
|
||||||
object_ptr<Ui::RpWidget>(container),
|
|
||||||
style::al_top);
|
|
||||||
|
|
||||||
logo->resize(QSize(st::settingsCloudPasswordIconSize, st::settingsCloudPasswordIconSize));
|
|
||||||
logo->setNaturalWidth(st::settingsCloudPasswordIconSize);
|
|
||||||
|
|
||||||
logo->paintRequest(
|
|
||||||
) | rpl::on_next([=](QRect clip)
|
|
||||||
{
|
|
||||||
auto p = QPainter(logo);
|
|
||||||
const auto image = AyuAssets::currentAppLogoPad();
|
|
||||||
if (!image.isNull()) {
|
|
||||||
const auto size = st::settingsCloudPasswordIconSize;
|
|
||||||
const auto scaled = image.scaled(
|
|
||||||
size * style::DevicePixelRatio(),
|
|
||||||
size * style::DevicePixelRatio(),
|
|
||||||
Qt::KeepAspectRatio,
|
|
||||||
Qt::SmoothTransformation);
|
|
||||||
p.drawImage(
|
|
||||||
QRect(0, 0, size, size),
|
|
||||||
scaled);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
logo->lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupCategories(
|
|
||||||
not_null<Ui::VerticalLayout*> container,
|
|
||||||
not_null<Window::SessionController*> controller,
|
|
||||||
Fn<void(Type)> showOther) {
|
|
||||||
struct CategoryInfo
|
|
||||||
{
|
|
||||||
QString name;
|
|
||||||
const style::icon *icon;
|
|
||||||
std::function<void()> handler;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto categories = std::vector<CategoryInfo>{
|
|
||||||
{QString("AyuGram"), &st::menuIconGroupReactions, [=] { showOther(AyuGhost::Id()); }},
|
|
||||||
{tr::ayu_CategoryFilters(tr::now), &st::menuIconTagFilter, [=] { showOther(AyuFilters::Id()); }},
|
|
||||||
{tr::ayu_CategoryGeneral(tr::now), &st::menuIconShowAll, [=] { showOther(AyuGeneral::Id()); }},
|
|
||||||
{tr::ayu_CategoryAppearance(tr::now), &st::menuIconPalette, [=] { showOther(AyuAppearance::Id()); }},
|
|
||||||
{tr::ayu_CategoryChats(tr::now), &st::menuIconChatBubble, [=] { showOther(AyuChats::Id()); }},
|
|
||||||
{tr::ayu_CategoryOther(tr::now), &st::menuIconFave, [=] { showOther(AyuOther::Id()); }},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const auto &category : categories) {
|
|
||||||
AddButtonWithIcon(
|
|
||||||
container,
|
|
||||||
rpl::single(category.name),
|
|
||||||
st::settingsButton,
|
|
||||||
{category.icon}
|
|
||||||
)->setClickedCallback([=]
|
|
||||||
{
|
|
||||||
if (category.handler) {
|
|
||||||
category.handler();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupLinks(
|
|
||||||
not_null<Ui::VerticalLayout*> container,
|
|
||||||
not_null<Window::SessionController*> controller) {
|
|
||||||
struct LinkInfo
|
|
||||||
{
|
|
||||||
QString name;
|
|
||||||
QString value;
|
|
||||||
const style::icon *icon;
|
|
||||||
std::function<void()> handler;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto links = std::vector<LinkInfo>{
|
|
||||||
{
|
|
||||||
tr::ayu_LinksChannel(tr::now),
|
|
||||||
QString("@ayugram"),
|
|
||||||
&st::menuIconChannel,
|
|
||||||
[=]
|
|
||||||
{
|
|
||||||
controller->showPeerByLink(Window::PeerByLinkInfo{
|
|
||||||
.usernameOrId = QString("ayugram"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tr::ayu_LinksChats(tr::now),
|
|
||||||
QString("@ayugramchat"),
|
|
||||||
&st::menuIconChats,
|
|
||||||
[=]
|
|
||||||
{
|
|
||||||
controller->showPeerByLink(Window::PeerByLinkInfo{
|
|
||||||
.usernameOrId = QString("ayugramchat"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tr::ayu_LinksTranslate(tr::now),
|
|
||||||
QString("Crowdin"),
|
|
||||||
&st::menuIconTranslate,
|
|
||||||
[=]
|
|
||||||
{
|
|
||||||
QDesktopServices::openUrl(QString("https://translate.ayugram.one"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tr::ayu_LinksDocumentation(tr::now),
|
|
||||||
QString("docs.ayugram.one"),
|
|
||||||
&st::menuIconIpAddress,
|
|
||||||
[=]
|
|
||||||
{
|
|
||||||
QDesktopServices::openUrl(QString("https://docs.ayugram.one"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const auto &link : links) {
|
|
||||||
AddButtonWithLabel(
|
|
||||||
container,
|
|
||||||
rpl::single(link.name),
|
|
||||||
rpl::single(link.value),
|
|
||||||
st::settingsButton,
|
|
||||||
{link.icon}
|
|
||||||
)->setClickedCallback(link.handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AyuMain::setupContent(not_null<Window::SessionController*> controller) {
|
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
build(content, kMeta.build);
|
||||||
|
Ui::ResizeFitChild(this, content);
|
||||||
|
}
|
||||||
|
|
||||||
SetupAppLogo(content);
|
Type AyuMainId() {
|
||||||
|
return AyuMain::Id();
|
||||||
AddSkip(content);
|
|
||||||
|
|
||||||
content->add(
|
|
||||||
object_ptr<Ui::FlatLabel>(
|
|
||||||
content,
|
|
||||||
rpl::single(QString("AyuGram Desktop v") + QString::fromLatin1(AppVersionStr)),
|
|
||||||
st::boxTitle),
|
|
||||||
style::al_top);
|
|
||||||
|
|
||||||
AddSkip(content);
|
|
||||||
|
|
||||||
content->add(
|
|
||||||
object_ptr<Ui::FlatLabel>(
|
|
||||||
content,
|
|
||||||
tr::ayu_SettingsDescription(),
|
|
||||||
st::centeredBoxLabel),
|
|
||||||
style::al_top);
|
|
||||||
|
|
||||||
AddSkip(content);
|
|
||||||
AddSkip(content);
|
|
||||||
AddSkip(content);
|
|
||||||
AddSkip(content);
|
|
||||||
AddDivider(content);
|
|
||||||
AddSkip(content);
|
|
||||||
|
|
||||||
AddSubsectionTitle(content, tr::ayu_CategoriesHeader());
|
|
||||||
SetupCategories(content, controller, showOtherMethod());
|
|
||||||
|
|
||||||
AddSectionDivider(content);
|
|
||||||
|
|
||||||
AddSubsectionTitle(content, tr::ayu_LinksHeader());
|
|
||||||
SetupLinks(content, controller);
|
|
||||||
|
|
||||||
AddSkip(content);
|
|
||||||
|
|
||||||
ResizeFitChild(this, content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|||||||
@@ -9,24 +9,23 @@
|
|||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "settings/settings_common_session.h"
|
#include "settings/settings_common_session.h"
|
||||||
|
|
||||||
class BoxContent;
|
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
class Controller;
|
class Controller;
|
||||||
class SessionController;
|
class SessionController;
|
||||||
}
|
} // namespace Window
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class AyuMain : public Section<AyuMain>
|
class AyuMain : public Section<AyuMain> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
AyuMain(QWidget *parent, not_null<Window::SessionController*> controller);
|
AyuMain(QWidget *parent, not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> title() override;
|
[[nodiscard]] rpl::producer<QString> title() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupContent(not_null<Window::SessionController*> controller);
|
void setupContent();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
[[nodiscard]] Type AyuMainId();
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|||||||
@@ -13,11 +13,14 @@
|
|||||||
#include "lang_auto.h"
|
#include "lang_auto.h"
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
#include "ayu/ui/boxes/donate_qr_box.h"
|
#include "ayu/ui/boxes/donate_qr_box.h"
|
||||||
|
#include "ayu/ui/settings/ayu_builder.h"
|
||||||
#include "ayu/ui/settings/settings_ayu_utils.h"
|
#include "ayu/ui/settings/settings_ayu_utils.h"
|
||||||
|
#include "ayu/ui/settings/settings_main.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "lang/lang_text_entity.h"
|
#include "lang/lang_text_entity.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "settings/settings_builder.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_menu_icons.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
@@ -33,10 +36,13 @@
|
|||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
|
using namespace Builder;
|
||||||
|
using namespace AyBuilder;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct Asset
|
struct Asset {
|
||||||
{
|
|
||||||
QString icon;
|
QString icon;
|
||||||
QColor background;
|
QColor background;
|
||||||
};
|
};
|
||||||
@@ -78,7 +84,9 @@ QImage getImage(const QString &name) {
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] not_null<Ui::SettingsButton*> AddDonate(not_null<Ui::SettingsButton*> button, const QString &name) {
|
[[nodiscard]] not_null<Ui::SettingsButton*> AddDonate(
|
||||||
|
not_null<Ui::SettingsButton*> button,
|
||||||
|
const QString &name) {
|
||||||
const auto btnContainer = Ui::CreateChild<Ui::RpWidget>(button);
|
const auto btnContainer = Ui::CreateChild<Ui::RpWidget>(button);
|
||||||
const auto &buttonSt = button->st();
|
const auto &buttonSt = button->st();
|
||||||
const auto fullHeight = buttonSt.height
|
const auto fullHeight = buttonSt.height
|
||||||
@@ -89,40 +97,38 @@ QImage getImage(const QString &name) {
|
|||||||
auto icon = getImage(name);
|
auto icon = getImage(name);
|
||||||
iconWidget->resize(icon.size() / style::DevicePixelRatio());
|
iconWidget->resize(icon.size() / style::DevicePixelRatio());
|
||||||
iconWidget->paintRequest(
|
iconWidget->paintRequest(
|
||||||
) | rpl::on_next([=]
|
) | rpl::on_next([=] {
|
||||||
{
|
auto p = QPainter(iconWidget);
|
||||||
auto p = QPainter(iconWidget);
|
p.drawImage(0, 0, icon);
|
||||||
p.drawImage(0, 0, icon);
|
}, iconWidget->lifetime());
|
||||||
},
|
|
||||||
iconWidget->lifetime());
|
|
||||||
|
|
||||||
button->sizeValue(
|
button->sizeValue(
|
||||||
) | rpl::on_next([=](const QSize &s)
|
) | rpl::on_next([=](const QSize &s) {
|
||||||
{
|
iconWidget->moveToLeft(
|
||||||
iconWidget->moveToLeft(
|
button->st().iconLeft
|
||||||
button->st().iconLeft
|
+ (st::menuIconShop.width() - iconWidget->width()) / 2,
|
||||||
+ (st::menuIconShop.width() - iconWidget->width()) / 2,
|
(s.height() - iconWidget->height()) / 2);
|
||||||
(s.height() - iconWidget->height()) / 2);
|
btnContainer->moveToLeft(
|
||||||
btnContainer->moveToLeft(
|
iconWidget->x() - (fullHeight - iconWidget->height()) / 2,
|
||||||
iconWidget->x() - (fullHeight - iconWidget->height()) / 2,
|
0);
|
||||||
0);
|
}, iconWidget->lifetime());
|
||||||
},
|
|
||||||
iconWidget->lifetime());
|
|
||||||
|
|
||||||
btnContainer->resize(fullHeight, fullHeight);
|
btnContainer->resize(fullHeight, fullHeight);
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddCryptoDonate(const QString &name, const QString &address, not_null<Ui::VerticalLayout*> container) {
|
void AddCryptoDonate(
|
||||||
|
const QString &name,
|
||||||
|
const QString &address,
|
||||||
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
const auto button = AddDonate(
|
const auto button = AddDonate(
|
||||||
AddButtonWithIcon(
|
AddButtonWithIcon(
|
||||||
container,
|
container,
|
||||||
rpl::single(name),
|
rpl::single(name),
|
||||||
st::settingsButton),
|
st::settingsButton),
|
||||||
name);
|
name);
|
||||||
button->setClickedCallback([=]
|
button->setClickedCallback([=] {
|
||||||
{
|
|
||||||
auto box = Box(
|
auto box = Box(
|
||||||
Ui::FillDonateQrBox,
|
Ui::FillDonateQrBox,
|
||||||
address,
|
address,
|
||||||
@@ -131,8 +137,117 @@ void AddCryptoDonate(const QString &name, const QString &address, not_null<Ui::V
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BuildDonations(SectionBuilder &builder) {
|
||||||
|
builder.add([](const BuildContext &ctx) {
|
||||||
|
v::match(ctx, [&](const WidgetContext &wctx) {
|
||||||
|
const auto container = wctx.container;
|
||||||
|
|
||||||
|
AddSubsectionTitle(container, tr::ayu_SupportHeader());
|
||||||
|
AddDonate(
|
||||||
|
AddButtonWithIcon(
|
||||||
|
container,
|
||||||
|
rpl::single(QString("Boosty")),
|
||||||
|
st::settingsButton),
|
||||||
|
"boosty"
|
||||||
|
)->setClickedCallback([=] {
|
||||||
|
QDesktopServices::openUrl(QString("https://boosty.to/alexeyzavar"));
|
||||||
|
});
|
||||||
|
AddCryptoDonate("TON", QString("UQA4i8U8vP3mYUZSV3KqDQEHPwmhninEqCkkKc7BITQ652de"), container);
|
||||||
|
AddCryptoDonate("Bitcoin", QString("bc1qdk6qq4mzq5yap3fpy0qau3246w3m3uwac9f0xd"), container);
|
||||||
|
AddCryptoDonate("Ethereum", QString("0x405589857C8DFAb45B2027c68ad1e58877FDa347"), container);
|
||||||
|
AddCryptoDonate("Solana", QString("8ZHQpPxpsdRjsWoBcF1dmvRM5dB6zEhJ3jMBFZjYfyHs"), container);
|
||||||
|
AddCryptoDonate("Tron", QString("TRpbajq38qU8joThgAfKJLyEPbNjzsdPJ1"), container);
|
||||||
|
AddSkip(container);
|
||||||
|
|
||||||
|
AddDividerText(container,
|
||||||
|
tr::ayu_SupportDescription2(
|
||||||
|
lt_item,
|
||||||
|
rpl::single(
|
||||||
|
Ui::Text::Link(tr::ayu_SupportDescription1(tr::now), QString("tg://support"))
|
||||||
|
),
|
||||||
|
tr::marked));
|
||||||
|
}, [&](const SearchContext &sctx) {
|
||||||
|
sctx.entries->push_back({
|
||||||
|
.id = u"ayu/donate"_q,
|
||||||
|
.title = tr::ayu_SupportHeader(tr::now),
|
||||||
|
.keywords = { u"donate"_q, u"support"_q, u"boosty"_q, u"crypto"_q },
|
||||||
|
.section = sctx.sectionId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BuildCrashReporting(SectionBuilder &builder, AyuSectionBuilder &ayu) {
|
||||||
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addSubsectionTitle({
|
||||||
|
.id = u"ayu/otherSection"_q,
|
||||||
|
.title = tr::ayu_CategoryOther(),
|
||||||
|
});
|
||||||
|
|
||||||
|
ayu.addSettingToggle({
|
||||||
|
.id = u"ayu/crashlytics"_q,
|
||||||
|
.title = tr::ayu_CrashReporting(),
|
||||||
|
.getter = &AyuSettings::crashReporting,
|
||||||
|
.setter = &AyuSettings::setCrashReporting,
|
||||||
|
.icon = { &st::menuIconReport },
|
||||||
|
.keywords = { u"crash"_q, u"report"_q },
|
||||||
|
});
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addDividerText(tr::ayu_CrashReportingDescription());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildOtherThings(SectionBuilder &builder) {
|
||||||
|
const auto controller = builder.controller();
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
builder.addButton({
|
||||||
|
.id = u"ayu/registerUrlScheme"_q,
|
||||||
|
.title = tr::ayu_RegisterURLScheme(),
|
||||||
|
.icon = { &st::menuIconLink },
|
||||||
|
.onClick = [=] {
|
||||||
|
Core::Application::RegisterUrlScheme();
|
||||||
|
controller->showToast(tr::lng_box_done(tr::now));
|
||||||
|
},
|
||||||
|
.keywords = { u"url"_q, u"scheme"_q, u"register"_q },
|
||||||
|
});
|
||||||
|
builder.addButton({
|
||||||
|
.id = u"ayu/resetSettings"_q,
|
||||||
|
.title = tr::ayu_ResetSettings(),
|
||||||
|
.icon = { &st::menuIconRestore },
|
||||||
|
.onClick = [=] {
|
||||||
|
controller->show(Ui::MakeConfirmBox({
|
||||||
|
.text = tr::ayu_ResetSettingsConfirmation(tr::rich),
|
||||||
|
.confirmed = [=](Fn<void()> &&close) {
|
||||||
|
AyuSettings::reset();
|
||||||
|
controller->showToast(tr::lng_box_done(tr::now));
|
||||||
|
close();
|
||||||
|
},
|
||||||
|
.confirmText = tr::lng_box_yes(),
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
.keywords = { u"reset"_q, u"settings"_q },
|
||||||
|
});
|
||||||
|
builder.addSkip();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto kMeta = BuildHelper({
|
||||||
|
.id = AyuOther::Id(),
|
||||||
|
.parentId = AyuMain::Id(),
|
||||||
|
.title = &tr::ayu_CategoryOther,
|
||||||
|
.icon = &st::menuIconFave,
|
||||||
|
}, [](SectionBuilder &builder) {
|
||||||
|
auto ayu = AyuSectionBuilder(builder);
|
||||||
|
|
||||||
|
builder.addSkip();
|
||||||
|
BuildDonations(builder);
|
||||||
|
BuildCrashReporting(builder, ayu);
|
||||||
|
BuildOtherThings(builder);
|
||||||
|
});
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
rpl::producer<QString> AyuOther::title() {
|
rpl::producer<QString> AyuOther::title() {
|
||||||
return tr::ayu_CategoryOther();
|
return tr::ayu_CategoryOther();
|
||||||
}
|
}
|
||||||
@@ -140,93 +255,18 @@ rpl::producer<QString> AyuOther::title() {
|
|||||||
AyuOther::AyuOther(
|
AyuOther::AyuOther(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller)
|
||||||
: Section(parent, controller) {
|
: Section(parent, controller) {
|
||||||
setupContent(controller);
|
setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupDonations(not_null<Ui::VerticalLayout*> container, not_null<Window::SessionController*> controller) {
|
void AyuOther::setupContent() {
|
||||||
AddSubsectionTitle(container, tr::ayu_SupportHeader());
|
|
||||||
AddDonate(
|
|
||||||
AddButtonWithIcon(
|
|
||||||
container,
|
|
||||||
rpl::single(QString("Boosty")),
|
|
||||||
st::settingsButton),
|
|
||||||
"boosty"
|
|
||||||
)->setClickedCallback([=]
|
|
||||||
{
|
|
||||||
QDesktopServices::openUrl(QString("https://boosty.to/alexeyzavar"));
|
|
||||||
});
|
|
||||||
AddCryptoDonate("TON", QString("UQA4i8U8vP3mYUZSV3KqDQEHPwmhninEqCkkKc7BITQ652de"), container);
|
|
||||||
AddCryptoDonate("Bitcoin", QString("bc1qdk6qq4mzq5yap3fpy0qau3246w3m3uwac9f0xd"), container);
|
|
||||||
AddCryptoDonate("Ethereum", QString("0x405589857C8DFAb45B2027c68ad1e58877FDa347"), container);
|
|
||||||
AddCryptoDonate("Solana", QString("8ZHQpPxpsdRjsWoBcF1dmvRM5dB6zEhJ3jMBFZjYfyHs"), container);
|
|
||||||
AddCryptoDonate("Tron", QString("TRpbajq38qU8joThgAfKJLyEPbNjzsdPJ1"), container);
|
|
||||||
AddSkip(container);
|
|
||||||
|
|
||||||
AddDividerText(container,
|
|
||||||
tr::ayu_SupportDescription2(
|
|
||||||
lt_item,
|
|
||||||
rpl::single(
|
|
||||||
Ui::Text::Link(tr::ayu_SupportDescription1(tr::now), QString("tg://support"))
|
|
||||||
),
|
|
||||||
tr::marked
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupCrashReporting(not_null<Ui::VerticalLayout*> container) {
|
|
||||||
AddSkip(container);
|
|
||||||
AddSubsectionTitle(container, tr::ayu_CategoryOther());
|
|
||||||
|
|
||||||
AddSettingToggle(container, tr::ayu_CrashReporting(), &AyuSettings::crashReporting, &AyuSettings::setCrashReporting, st::menuIconReport);
|
|
||||||
AddSkip(container);
|
|
||||||
AddDividerText(container, tr::ayu_CrashReportingDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupOtherThings(not_null<Ui::VerticalLayout*> container, not_null<Window::SessionController*> controller) {
|
|
||||||
AddSkip(container);
|
|
||||||
AddButtonWithIcon(
|
|
||||||
container,
|
|
||||||
tr::ayu_RegisterURLScheme(),
|
|
||||||
st::settingsButton,
|
|
||||||
{&st::menuIconLink}
|
|
||||||
)->setClickedCallback([=]
|
|
||||||
{
|
|
||||||
Core::Application::RegisterUrlScheme();
|
|
||||||
controller->showToast(tr::lng_box_done(tr::now));
|
|
||||||
});
|
|
||||||
AddButtonWithIcon(
|
|
||||||
container,
|
|
||||||
tr::ayu_ResetSettings(),
|
|
||||||
st::settingsButton,
|
|
||||||
{&st::menuIconRestore}
|
|
||||||
)->setClickedCallback([=]
|
|
||||||
{
|
|
||||||
controller->show(Ui::MakeConfirmBox({
|
|
||||||
.text = tr::ayu_ResetSettingsConfirmation(tr::rich),
|
|
||||||
.confirmed = [=](Fn<void()> &&close)
|
|
||||||
{
|
|
||||||
AyuSettings::reset();
|
|
||||||
controller->showToast(tr::lng_box_done(tr::now));
|
|
||||||
close();
|
|
||||||
},
|
|
||||||
.confirmText = tr::lng_box_yes(),
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
AddSkip(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AyuOther::setupContent(not_null<Window::SessionController*> controller) {
|
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
build(content, kMeta.build);
|
||||||
AddSkip(content);
|
Ui::ResizeFitChild(this, content);
|
||||||
SetupDonations(content, controller);
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
|
||||||
SetupCrashReporting(content);
|
|
||||||
#endif
|
|
||||||
SetupOtherThings(content, controller);
|
|
||||||
|
|
||||||
ResizeFitChild(this, content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
Type AyuOtherId() {
|
||||||
|
return AyuOther::Id();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|||||||
@@ -15,15 +15,16 @@ class SessionController;
|
|||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class AyuOther : public Section<AyuOther>
|
class AyuOther : public Section<AyuOther> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
AyuOther(QWidget *parent, not_null<Window::SessionController*> controller);
|
AyuOther(QWidget *parent, not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> title() override;
|
[[nodiscard]] rpl::producer<QString> title() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupContent(not_null<Window::SessionController*> controller);
|
void setupContent();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Settings
|
[[nodiscard]] Type AyuOtherId();
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|||||||
@@ -1733,6 +1733,14 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
|
|||||||
u"^chat\\?(.+)(#|$)"_q,
|
u"^chat\\?(.+)(#|$)"_q,
|
||||||
AyuUrlHandlers::ResolveChat
|
AyuUrlHandlers::ResolveChat
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
u"^ayusettings/?\\?(.+)(#|$)"_q,
|
||||||
|
AyuUrlHandlers::HandleAyuSettings
|
||||||
|
},
|
||||||
|
{
|
||||||
|
u"^ayusettings/?$"_q,
|
||||||
|
AyuUrlHandlers::HandleAyuSettings
|
||||||
|
},
|
||||||
{
|
{
|
||||||
u"^ayu(/?.+)?(#|$)"_q,
|
u"^ayu(/?.+)?(#|$)"_q,
|
||||||
AyuUrlHandlers::HandleAyu
|
AyuUrlHandlers::HandleAyu
|
||||||
@@ -1929,6 +1937,9 @@ QString TryConvertUrlToLocal(QString url) {
|
|||||||
added = u"&post="_q + postMatch->captured(1);
|
added = u"&post="_q + postMatch->captured(1);
|
||||||
}
|
}
|
||||||
return base + added + (params.isEmpty() ? QString() : '&' + params);
|
return base + added + (params.isEmpty() ? QString() : '&' + params);
|
||||||
|
} else if (const auto ayuSettingsMatch = regex_match(
|
||||||
|
u"^(?:ayuSettings|exteraSettings)/?\\?(.+)$"_q, query, matchOptions)) {
|
||||||
|
return u"tg://ayusettings?"_q + ayuSettingsMatch->captured(1);
|
||||||
} else if (const auto usernameMatch = regex_match(u"^"
|
} else if (const auto usernameMatch = regex_match(u"^"
|
||||||
"([a-zA-Z0-9\\.\\_]+)"
|
"([a-zA-Z0-9\\.\\_]+)"
|
||||||
"("
|
"("
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ bool HasMenu(Type type) {
|
|||||||
return (type == ::Settings::CloudPasswordEmailConfirmId())
|
return (type == ::Settings::CloudPasswordEmailConfirmId())
|
||||||
|| (type == MainId())
|
|| (type == MainId())
|
||||||
|| (type == ChatId())
|
|| (type == ChatId())
|
||||||
|| (type == AyuFilters::Id());
|
|| (type == AyuFiltersId());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|||||||
Reference in New Issue
Block a user