feat: add settings for ReadAfterAction

feat: write formatted config
fix: don't reset config on missing field

the last one is for convenient migrating between versions
This commit is contained in:
ZavaruKitsu 2023-09-21 22:06:17 +03:00
parent e1babcf69a
commit 3a1f8459e2
4 changed files with 154 additions and 35 deletions

View file

@ -6,16 +6,19 @@
// Copyright @Radolyn, 2023 // Copyright @Radolyn, 2023
#include "ayu_settings.h" #include "ayu_settings.h"
#include "rpl/lifetime.h" #include "rpl/lifetime.h"
#include "rpl/producer.h" #include "rpl/producer.h"
#include "rpl/variable.h" #include "rpl/variable.h"
#include <fstream>
using json = nlohmann::json; using json = nlohmann::json;
namespace AyuSettings namespace AyuSettings
{ {
const QString filename = "tdata/ayu_settings.json"; const std::string filename = "tdata/ayu_settings.json";
std::optional<AyuGramSettings> settings = std::nullopt; std::optional<AyuGramSettings> settings = std::nullopt;
@ -130,16 +133,17 @@ AyuGramSettings &getInstance()
void load() void load()
{ {
QFile file(filename); std::ifstream file(filename);
if (!file.exists()) { if (!file.good()) {
return; return;
} }
file.open(QIODevice::ReadOnly);
QByteArray data = file.readAll();
file.close();
initialize(); initialize();
json p = json::parse(data);
json p;
file >> p;
file.close();
try { try {
settings = p.get<AyuGramSettings>(); settings = p.get<AyuGramSettings>();
} }
@ -155,9 +159,9 @@ void save()
json p = settings.value(); json p = settings.value();
QFile file(filename); std::ofstream file;
file.open(QIODevice::WriteOnly); file.open(filename);
file.write(p.dump().c_str()); file << p.dump(4);
file.close(); file.close();
postinitialize(); postinitialize();

View file

@ -145,7 +145,7 @@ public:
void set_voiceConfirmation(bool val); void set_voiceConfirmation(bool val);
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
AyuGramSettings, AyuGramSettings,
sendReadMessages, sendReadMessages,
sendReadStories, sendReadStories,

View file

@ -47,8 +47,6 @@
#include "ui/wrap/vertical_layout.h" #include "ui/wrap/vertical_layout.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
constexpr auto GhostModeOptionsCount = 5;
class PainterHighQualityEnabler; class PainterHighQualityEnabler;
const char kStreamerMode[] = const char kStreamerMode[] =
@ -160,17 +158,19 @@ not_null<Ui::RpWidget *> AddInnerToggle(
(s.height() - checkWidget->height()) / 2); (s.height() - checkWidget->height()) / 2);
}, toggleButton->lifetime()); }, toggleButton->lifetime());
} }
const auto totalInnerChecks = state->innerChecks.size();
state->anyChanges.events_starting_with( state->anyChanges.events_starting_with(
rpl::empty_value() rpl::empty_value()
) | rpl::map(countChecked) | start_with_next([=](int count) ) | rpl::map(countChecked) | start_with_next([=](int count)
{ {
checkView->setChecked(count == GhostModeOptionsCount, checkView->setChecked(count == totalInnerChecks,
anim::type::normal); anim::type::normal);
}, toggleButton->lifetime()); }, toggleButton->lifetime());
checkView->setLocked(locked.has_value()); checkView->setLocked(locked.has_value());
checkView->finishAnimating(); checkView->finishAnimating();
const auto totalInnerChecks = state->innerChecks.size();
const auto label = Ui::CreateChild<Ui::FlatLabel>( const auto label = Ui::CreateChild<Ui::FlatLabel>(
button, button,
combine( combine(
@ -344,12 +344,9 @@ void Ayu::AddPlatformOption(
} }
} }
void Ayu::SetupGhostEssentials(not_null<Ui::VerticalLayout *> container) void Ayu::SetupGhostModeToggle(not_null<Ui::VerticalLayout *> container) {
{
auto settings = &AyuSettings::getInstance(); auto settings = &AyuSettings::getInstance();
AddSubsectionTitle(container, tr::ayu_GhostEssentialsHeader());
const auto widget = object_ptr<Ui::VerticalLayout>(this); const auto widget = object_ptr<Ui::VerticalLayout>(this);
widget->add( widget->add(
@ -372,7 +369,7 @@ void Ayu::SetupGhostEssentials(not_null<Ui::VerticalLayout *> container)
label, label,
isCheckedOrig, isCheckedOrig,
st::settingsCheckbox), st::settingsCheckbox),
st::rightsButton.padding); st::powerSavingButton.padding);
const auto button = Ui::CreateChild<Ui::RippleButton>( const auto button = Ui::CreateChild<Ui::RippleButton>(
verticalLayout.get(), verticalLayout.get(),
st::defaultRippleAnimation); st::defaultRippleAnimation);
@ -467,7 +464,7 @@ void Ayu::SetupGhostEssentials(not_null<Ui::VerticalLayout *> container)
raw->hide(anim::type::instant); raw->hide(anim::type::instant);
AddInnerToggle( AddInnerToggle(
container, container,
st::rightsButton, st::powerSavingButtonNoIcon,
innerChecks, innerChecks,
raw, raw,
tr::ayu_GhostModeToggle(), tr::ayu_GhostModeToggle(),
@ -479,22 +476,136 @@ void Ayu::SetupGhostEssentials(not_null<Ui::VerticalLayout *> container)
{ {
raw->resizeToWidth(w); raw->resizeToWidth(w);
}, raw->lifetime()); }, raw->lifetime());
}
AddButton( void Ayu::SetupReadAfterActionToggle(not_null<Ui::VerticalLayout *> container) {
auto settings = &AyuSettings::getInstance();
const auto widget = object_ptr<Ui::VerticalLayout>(this);
widget->add(
object_ptr<Ui::FlatLabel>(
container,
tr::ayu_MarkReadAfterAction(),
st::rightsHeaderLabel),
st::rightsHeaderMargin);
const auto addCheckbox = [&](
not_null<Ui::VerticalLayout *> verticalLayout,
const QString &label,
const bool isCheckedOrig)
{
const auto checkView = [&]() -> not_null<Ui::AbstractCheckView *>
{
const auto checkbox = verticalLayout->add(
object_ptr<Ui::Checkbox>(
verticalLayout,
label,
isCheckedOrig,
st::settingsCheckbox),
st::powerSavingButton.padding);
const auto button = Ui::CreateChild<Ui::RippleButton>(
verticalLayout.get(),
st::defaultRippleAnimation);
button->stackUnder(checkbox);
combine(
verticalLayout->widthValue(),
checkbox->geometryValue()
) | start_with_next([=](int w, const QRect &r)
{
button->setGeometry(0, r.y(), w, r.height());
}, button->lifetime());
checkbox->setAttribute(Qt::WA_TransparentForMouseEvents);
const auto checkView = checkbox->checkView();
button->setClickedCallback([=]
{
checkView->setChecked(
!checkView->checked(),
anim::type::normal);
});
return checkView;
}();
checkView->checkedChanges(
) | start_with_next([=](bool checked)
{
}, verticalLayout->lifetime());
return checkView;
};
struct NestedEntry
{
QString checkboxLabel;
bool initial;
std::function<void(bool)> callback;
};
std::vector checkboxes{
NestedEntry{
tr::ayu_MarkReadAfterSend(tr::now), false, [=](bool enabled)
{
// settings->set_sendReadMessages(!enabled);
// AyuSettings::save();
}
},
NestedEntry{
tr::ayu_MarkReadAfterReaction(tr::now), false, [=](bool enabled)
{
// settings->set_sendReadStories(!enabled);
// AyuSettings::save();
}
},
NestedEntry{
tr::ayu_MarkReadAfterPoll(tr::now), false, [=](bool enabled)
{
// settings->set_sendOnlinePackets(!enabled);
// AyuSettings::save();
}
},
};
auto wrap = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
container, container,
tr::ayu_MarkReadAfterSend(), object_ptr<Ui::VerticalLayout>(container));
st::settingsButtonNoIcon const auto verticalLayout = wrap->entity();
)->toggleOn( auto innerChecks = std::vector<not_null<Ui::AbstractCheckView *>>();
rpl::single(settings->markReadAfterSend) for (const auto &entry : checkboxes) {
)->toggledValue( const auto c = addCheckbox(verticalLayout, entry.checkboxLabel, entry.initial);
) | rpl::filter([=](bool enabled) c->checkedValue(
{ ) | start_with_next([=](bool enabled)
return (enabled != settings->markReadAfterSend); {
}) | start_with_next([=](bool enabled) entry.callback(enabled);
{ }, container->lifetime());
settings->set_markReadAfterSend(enabled); innerChecks.push_back(c);
AyuSettings::save(); }
}, container->lifetime());
const auto raw = wrap.data();
raw->hide(anim::type::instant);
AddInnerToggle(
container,
st::powerSavingButtonNoIcon,
innerChecks,
raw,
tr::ayu_MarkReadAfterAction(),
std::nullopt,
{});
container->add(std::move(wrap));
container->widthValue(
) | start_with_next([=](int w)
{
raw->resizeToWidth(w);
}, raw->lifetime());
}
void Ayu::SetupGhostEssentials(not_null<Ui::VerticalLayout *> container)
{
auto settings = &AyuSettings::getInstance();
AddSubsectionTitle(container, tr::ayu_GhostEssentialsHeader());
SetupGhostModeToggle(container);
SetupReadAfterActionToggle(container);
AddButton( AddButton(
container, container,

View file

@ -38,6 +38,10 @@ private:
base::options::option<bool> &option, base::options::option<bool> &option,
rpl::producer<> resetClicks); rpl::producer<> resetClicks);
void SetupGhostModeToggle(not_null<Ui::VerticalLayout *> container);
void SetupReadAfterActionToggle(not_null<Ui::VerticalLayout *> container);
void SetupGhostEssentials(not_null<Ui::VerticalLayout *> container); void SetupGhostEssentials(not_null<Ui::VerticalLayout *> container);
void SetupSpyEssentials(not_null<Ui::VerticalLayout *> container); void SetupSpyEssentials(not_null<Ui::VerticalLayout *> container);