mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
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:
parent
e1babcf69a
commit
3a1f8459e2
4 changed files with 154 additions and 35 deletions
|
@ -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();
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue