2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-27 21:07:09 +00:00

731 lines
20 KiB
C++
Raw Normal View History

2020-03-10 16:41:12 +04:00
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "settings/settings_folders.h"
2020-03-10 16:41:12 +04:00
#include "boxes/filters/edit_filter_box.h"
2020-03-10 16:41:12 +04:00
#include "data/data_session.h"
#include "data/data_folder.h"
#include "data/data_peer.h"
#include "data/data_chat_filters.h"
#include "history/history.h"
2020-03-10 16:41:12 +04:00
#include "main/main_session.h"
2020-07-02 03:34:22 +03:00
#include "main/main_account.h"
2020-03-10 16:41:12 +04:00
#include "window/window_session_controller.h"
#include "window/window_controller.h"
2020-08-16 03:48:17 +03:00
#include "ui/toast/toast.h"
2020-03-10 16:41:12 +04:00
#include "ui/layers/generic_box.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
2020-03-10 16:41:12 +04:00
#include "ui/text/text_utilities.h"
2020-03-10 16:51:23 +04:00
#include "ui/wrap/slide_wrap.h"
#include "ui/painter.h"
#include "ui/filter_icons.h"
2020-04-21 06:20:14 +03:00
#include "kotato/json_settings.h"
2020-03-10 16:41:12 +04:00
#include "settings/settings_common.h"
#include "lang/lang_keys.h"
#include "apiwrap.h"
#include "app.h"
2020-03-10 16:41:12 +04:00
#include "styles/style_settings.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_window.h"
2020-03-10 16:41:12 +04:00
namespace Settings {
2020-03-10 16:41:12 +04:00
namespace {
constexpr auto kFiltersLimit = 10;
auto currentDefaultRemoved = false;
auto localNewFilterId = kFiltersLimit;
using Flag = Data::ChatFilter::Flag;
using Flags = Data::ChatFilter::Flags;
2020-03-10 16:41:12 +04:00
class FilterRowButton final : public Ui::RippleButton {
public:
FilterRowButton(
not_null<QWidget*> parent,
not_null<Main::Session*> session,
const Data::ChatFilter &filter);
FilterRowButton(
not_null<QWidget*> parent,
const Data::ChatFilter &filter,
const QString &description);
void setRemoved(bool removed);
void updateData(const Data::ChatFilter &filter);
void updateCount(const Data::ChatFilter &filter);
2020-03-10 16:41:12 +04:00
[[nodiscard]] rpl::producer<> removeRequests() const;
[[nodiscard]] rpl::producer<> restoreRequests() const;
[[nodiscard]] rpl::producer<> addRequests() const;
private:
enum class State {
Suggested,
Removed,
Normal,
};
FilterRowButton(
not_null<QWidget*> parent,
Main::Session *session,
2020-03-10 16:41:12 +04:00
const Data::ChatFilter &filter,
const QString &description,
State state);
void paintEvent(QPaintEvent *e) override;
void setup(const Data::ChatFilter &filter, const QString &status);
void setState(State state, bool force = false);
void updateButtonsVisibility();
Main::Session *_session = nullptr;
2020-03-10 16:41:12 +04:00
Ui::IconButton _remove;
Ui::RoundButton _restore;
Ui::RoundButton _add;
Ui::Text::String _title;
QString _status;
Ui::FilterIcon _icon = Ui::FilterIcon();
2020-03-10 16:41:12 +04:00
State _state = State::Normal;
};
struct FilterRow {
not_null<FilterRowButton*> button;
Data::ChatFilter filter;
bool removed = false;
bool added = false;
bool postponedCountUpdate = false;
};
2020-03-10 16:41:12 +04:00
[[nodiscard]] int CountFilterChats(
not_null<Main::Session*> session,
const Data::ChatFilter &filter) {
auto result = 0;
const auto addList = [&](not_null<Dialogs::MainList*> list) {
for (const auto &entry : list->indexed()->all()) {
if (const auto history = entry->history()) {
if (filter.contains(history)) {
++result;
}
}
}
};
addList(session->data().chatsList());
const auto folderId = Data::Folder::kId;
if (const auto folder = session->data().folderLoaded(folderId)) {
addList(folder->chatsList());
}
return result;
}
[[nodiscard]] int ComputeCount(
not_null<Main::Session*> session,
const Data::ChatFilter &filter,
bool check = false) {
2020-03-10 16:41:12 +04:00
const auto &list = session->data().chatsFilters().list();
const auto id = filter.id();
const auto i = ranges::find(list, id, &Data::ChatFilter::id);
if (i != end(list)
&& (!check
|| (i->flags() == filter.flags()
&& i->always() == filter.always()
&& i->never() == filter.never()))) {
2020-03-10 16:41:12 +04:00
const auto chats = session->data().chatsFilters().chatsList(id);
return chats->indexed()->size();
}
return CountFilterChats(session, filter);
}
[[nodiscard]] QString ComputeCountString(
not_null<Main::Session*> session,
const Data::ChatFilter &filter,
bool check = false) {
const auto count = ComputeCount(session, filter, check);
2020-08-16 03:48:17 +03:00
return (count
? tr::lng_filters_chats_count(tr::now, lt_count_short, count)
: tr::lng_filters_no_chats(tr::now))
+ ", "
+ (filter.isLocal()
? tr::ktg_filters_local(tr::now)
: tr::ktg_filters_cloud(tr::now));
2020-03-10 16:41:12 +04:00
}
FilterRowButton::FilterRowButton(
not_null<QWidget*> parent,
not_null<Main::Session*> session,
const Data::ChatFilter &filter)
: FilterRowButton(
parent,
session,
2020-03-10 16:41:12 +04:00
filter,
ComputeCountString(session, filter),
State::Normal) {
}
FilterRowButton::FilterRowButton(
not_null<QWidget*> parent,
const Data::ChatFilter &filter,
const QString &description)
: FilterRowButton(parent, nullptr, filter, description, State::Suggested) {
2020-03-10 16:41:12 +04:00
}
FilterRowButton::FilterRowButton(
not_null<QWidget*> parent,
Main::Session *session,
2020-03-10 16:41:12 +04:00
const Data::ChatFilter &filter,
const QString &status,
State state)
: RippleButton(parent, st::defaultRippleAnimation)
, _session(session)
2020-03-10 16:41:12 +04:00
, _remove(this, st::filtersRemove)
, _restore(this, tr::lng_filters_restore(), st::stickersUndoRemove)
, _add(this, tr::lng_filters_recommended_add(), st::stickersTrendingAdd)
, _state(state) {
setup(filter, status);
}
void FilterRowButton::setRemoved(bool removed) {
setState(removed ? State::Removed : State::Normal);
}
void FilterRowButton::updateData(const Data::ChatFilter &filter) {
Expects(_session != nullptr);
_title.setText(st::contactsNameStyle, filter.title());
_icon = Ui::ComputeFilterIcon(filter);
updateCount(filter);
}
void FilterRowButton::updateCount(const Data::ChatFilter &filter) {
_status = ComputeCountString(_session, filter, true);
update();
}
2020-03-10 16:41:12 +04:00
void FilterRowButton::setState(State state, bool force) {
if (!force && _state == state) {
return;
}
_state = state;
setPointerCursor(_state == State::Normal);
setDisabled(_state != State::Normal);
updateButtonsVisibility();
update();
}
void FilterRowButton::setup(
const Data::ChatFilter &filter,
const QString &status) {
resize(width(), st::defaultPeerListItem.height);
_title.setText(st::contactsNameStyle, filter.title());
_status = status;
_icon = Ui::ComputeFilterIcon(filter);
2020-03-10 16:41:12 +04:00
setState(_state, true);
sizeValue(
) | rpl::start_with_next([=](QSize size) {
const auto right = st::contactsPadding.right()
+ st::contactsCheckPosition.x();
const auto width = size.width();
const auto height = size.height();
_restore.moveToRight(right, (height - _restore.height()) / 2, width);
_add.moveToRight(right, (height - _add.height()) / 2, width);
const auto skipped = right - st::stickersRemoveSkip;
_remove.moveToRight(skipped, (height - _remove.height()) / 2, width);
}, lifetime());
}
void FilterRowButton::updateButtonsVisibility() {
_remove.setVisible(_state == State::Normal);
_restore.setVisible(_state == State::Removed);
_add.setVisible(_state == State::Suggested);
}
rpl::producer<> FilterRowButton::removeRequests() const {
return _remove.clicks() | rpl::to_empty;
2020-03-10 16:41:12 +04:00
}
rpl::producer<> FilterRowButton::restoreRequests() const {
return _restore.clicks() | rpl::to_empty;
2020-03-10 16:41:12 +04:00
}
rpl::producer<> FilterRowButton::addRequests() const {
return _add.clicks() | rpl::to_empty;
2020-03-10 16:41:12 +04:00
}
void FilterRowButton::paintEvent(QPaintEvent *e) {
auto p = Painter(this);
const auto over = isOver() || isDown();
2020-03-10 16:41:12 +04:00
if (_state == State::Normal) {
if (over) {
2020-03-10 16:41:12 +04:00
p.fillRect(e->rect(), st::windowBgOver);
}
RippleButton::paintRipple(p, 0, 0);
} else if (_state == State::Removed) {
p.setOpacity(st::stickersRowDisabledOpacity);
}
const auto left = (_state == State::Suggested)
? st::settingsSubsectionTitlePadding.left()
: st::settingsFilterIconSkip;
2020-03-10 16:41:12 +04:00
const auto buttonsLeft = std::min(
_add.x(),
std::min(_remove.x(), _restore.x()));
const auto availableWidth = buttonsLeft - left;
p.setPen(st::contactsNameFg);
_title.drawLeftElided(
p,
left,
st::contactsPadding.top() + st::contactsNameTop,
availableWidth,
width());
p.setFont(st::contactsStatusFont);
p.setPen(st::contactsStatusFg);
p.drawTextLeft(
left,
st::contactsPadding.top() + st::contactsStatusTop,
width(),
_status);
if (_state != State::Suggested) {
const auto icon = Ui::LookupFilterIcon(_icon).normal;
icon->paint(
p,
st::settingsFilterIconLeft,
(height() - icon->height()) / 2,
width(),
(over ? st::menuIconFgOver : st::menuIconFg)->c);
}
2020-03-10 16:41:12 +04:00
}
[[nodiscard]] Fn<void()> SetupFoldersContent(
not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container) {
auto &lifetime = container->lifetime();
2020-07-02 03:34:22 +03:00
const auto session = &controller->session();
const auto account = &session->account();
const auto currentDefaultId = account->defaultFilterId();
localNewFilterId = kFiltersLimit;
2020-08-16 03:48:17 +03:00
const auto generateNewId = [=] {
const auto filters = &controller->session().data().chatsFilters();
do {
localNewFilterId++;
} while (ranges::contains(filters->list(), localNewFilterId, &Data::ChatFilter::id));
return localNewFilterId;
};
currentDefaultRemoved = false;
2020-03-10 16:41:12 +04:00
AddSkip(container, st::settingsSectionSkip);
AddSubsectionTitle(container, tr::lng_filters_subtitle());
2020-03-10 16:41:12 +04:00
const auto rows = lifetime.make_state<std::vector<FilterRow>>();
const auto rowsCount = lifetime.make_state<rpl::variable<int>>();
2020-03-10 16:41:12 +04:00
const auto find = [=](not_null<FilterRowButton*> button) {
const auto i = ranges::find(*rows, button, &FilterRow::button);
Assert(i != end(*rows));
return &*i;
};
2020-08-16 03:48:17 +03:00
const auto toast = Ui::Toast::Config{
.text = { tr::ktg_filters_cloud_limit(tr::now) },
.st = &st::windowArchiveToast,
.multiline = true,
};
const auto showLimitReached = [=] {
2020-08-16 03:48:17 +03:00
const auto removed = ranges::count_if(*rows, [](FilterRow row) {
return row.removed || row.filter.isLocal();
});
if (rows->size() < kFiltersLimit + removed) {
return false;
}
2020-08-16 03:48:17 +03:00
Ui::Toast::Show(toast);
return true;
2020-03-10 16:41:12 +04:00
};
2020-08-16 03:48:17 +03:00
const auto newCloudButton = AddButton(
container,
tr::ktg_filters_create_cloud(),
st::settingsChatButton,
&st::settingsIconCloud,
st::settingsChatIconLeft
);
const auto newLocalButton = AddButton(
container,
tr::ktg_filters_create_local(),
st::settingsChatButton,
&st::settingsIconFolders,
st::settingsChatIconLeft
);
const auto wrap = container->add(object_ptr<Ui::VerticalLayout>(
container));
2020-03-10 16:41:12 +04:00
const auto addFilter = [=](const Data::ChatFilter &filter) {
2020-08-16 03:48:17 +03:00
if (rows->size() == 0) {
AddSkip(wrap);
AddDivider(wrap);
AddSkip(wrap);
}
2020-03-10 16:41:12 +04:00
const auto button = wrap->add(
object_ptr<FilterRowButton>(wrap, session, filter));
button->removeRequests(
) | rpl::start_with_next([=] {
button->setRemoved(true);
2020-07-02 03:34:22 +03:00
if (find(button)->filter.id() == account->defaultFilterId()) {
currentDefaultRemoved = true;
}
2020-03-10 16:41:12 +04:00
find(button)->removed = true;
}, button->lifetime());
button->restoreRequests(
) | rpl::start_with_next([=] {
if (showLimitReached()) {
return;
2020-03-10 16:41:12 +04:00
}
2020-07-02 03:34:22 +03:00
if (find(button)->filter.id() == account->defaultFilterId()) {
currentDefaultRemoved = false;
}
button->setRemoved(false);
find(button)->removed = false;
2020-03-10 16:41:12 +04:00
}, button->lifetime());
button->setClickedCallback([=] {
const auto found = find(button);
if (found->removed) {
return;
}
const auto doneCallback = [=](const Data::ChatFilter &result) {
find(button)->filter = result;
2020-07-02 03:34:22 +03:00
const auto isCurrentDefault = result.id() == account->defaultFilterId();
if ((isCurrentDefault && !result.isDefault())
|| (!isCurrentDefault && result.isDefault())) {
2020-07-02 03:34:22 +03:00
account->setDefaultFilterId(result.isDefault() ? result.id() : 0);
}
button->updateData(result);
};
controller->window().show(Box(
EditFilterBox,
controller,
found->filter,
crl::guard(button, doneCallback)));
});
2020-03-10 16:41:12 +04:00
rows->push_back({ button, filter });
*rowsCount = rows->size();
2020-03-18 14:07:11 +04:00
const auto filters = &controller->session().data().chatsFilters();
const auto id = filter.id();
if (ranges::contains(filters->list(), id, &Data::ChatFilter::id)) {
filters->chatsList(id)->fullSize().changes(
) | rpl::start_with_next([=] {
const auto found = find(button);
if (found->postponedCountUpdate) {
return;
}
found->postponedCountUpdate = true;
Ui::PostponeCall(button, [=] {
const auto &list = filters->list();
const auto i = ranges::find(
list,
id,
&Data::ChatFilter::id);
if (i == end(list)) {
return;
}
const auto found = find(button);
const auto &real = *i;
const auto &now = found->filter;
if ((i->flags() != found->filter.flags())
|| (i->always() != found->filter.always())
|| (i->never() != found->filter.never())) {
return;
}
button->updateCount(found->filter);
found->postponedCountUpdate = false;
});
}, button->lifetime());
}
wrap->resizeToWidth(container->width());
2020-03-10 16:41:12 +04:00
};
const auto &list = session->data().chatsFilters().list();
for (const auto &filter : list) {
addFilter(filter);
}
2020-08-16 03:48:17 +03:00
newCloudButton->setClickedCallback([=] {
if (showLimitReached()) {
return;
}
const auto doneCallback = [=](const Data::ChatFilter &result) {
if (result.isDefault()) {
2020-07-02 03:34:22 +03:00
account->setDefaultFilterId(result.id());
}
addFilter(result);
};
controller->window().show(Box(
EditFilterBox,
controller,
2020-08-16 03:48:17 +03:00
Data::ChatFilter(generateNewId()),
crl::guard(container, doneCallback)));
});
newLocalButton->setClickedCallback([=] {
const auto doneCallback = [=](const Data::ChatFilter &result) {
if (result.isDefault()) {
account->setDefaultFilterId(result.id());
}
addFilter(result);
};
controller->window().show(Box(
EditFilterBox,
controller,
Data::ChatFilter(generateNewId(), true),
crl::guard(container, doneCallback)));
});
AddSkip(container);
const auto emptyAbout = container->add(
2020-03-10 16:51:23 +04:00
object_ptr<Ui::SlideWrap<Ui::FlatLabel>>(
container,
2020-03-10 16:41:12 +04:00
object_ptr<Ui::FlatLabel>(
container,
2020-08-16 03:48:17 +03:00
tr::ktg_filters_description(),
2020-03-10 16:41:12 +04:00
st::boxDividerLabel),
2020-03-10 16:51:23 +04:00
st::settingsDividerLabelPadding)
)->setDuration(0);
const auto nonEmptyAbout = container->add(
2020-03-10 16:51:23 +04:00
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
container,
object_ptr<Ui::VerticalLayout>(container))
2020-03-10 16:51:23 +04:00
)->setDuration(0);
const auto aboutRows = nonEmptyAbout->entity();
2020-08-16 03:48:17 +03:00
AddDividerText(aboutRows, tr::ktg_filters_description());
AddSkip(aboutRows);
AddSubsectionTitle(aboutRows, tr::lng_filters_recommended());
2020-03-10 16:51:23 +04:00
const auto changed = lifetime.make_state<bool>();
const auto suggested = lifetime.make_state<rpl::variable<int>>();
rpl::single(
rpl::empty_value()
) | rpl::then(
session->data().chatsFilters().suggestedUpdated()
) | rpl::map([=] {
return session->data().chatsFilters().suggestedFilters();
}) | rpl::filter([=](const std::vector<Data::SuggestedFilter> &list) {
return !list.empty();
}) | rpl::take(
1
) | rpl::start_with_next([=](
const std::vector<Data::SuggestedFilter> &suggestions) {
for (const auto &suggestion : suggestions) {
const auto &filter = suggestion.filter;
if (ranges::contains(*rows, filter, &FilterRow::filter)) {
continue;
}
*suggested = suggested->current() + 1;
const auto button = aboutRows->add(object_ptr<FilterRowButton>(
aboutRows,
filter,
suggestion.description));
button->addRequests(
) | rpl::start_with_next([=] {
if (showLimitReached()) {
return;
}
addFilter(filter);
*suggested = suggested->current() - 1;
delete button;
}, button->lifetime());
}
aboutRows->resizeToWidth(container->width());
AddSkip(aboutRows, st::settingsSectionSkip);
}, aboutRows->lifetime());
2020-03-10 16:41:12 +04:00
2020-03-10 16:51:23 +04:00
using namespace rpl::mappers;
auto showSuggestions = rpl::combine(
suggested->value(),
rowsCount->value()
) | rpl::map(_1 > 0 && _2 < kFiltersLimit);
emptyAbout->toggleOn(rpl::duplicate(
showSuggestions
) | rpl::map(!_1));
nonEmptyAbout->toggleOn(std::move(showSuggestions));
2020-03-10 16:51:23 +04:00
2020-03-10 16:41:12 +04:00
const auto prepareGoodIdsForNewFilters = [=] {
const auto &list = session->data().chatsFilters().list();
2020-03-18 14:07:11 +04:00
auto localId = 1;
2020-03-10 16:41:12 +04:00
const auto chooseNextId = [&] {
2020-03-18 14:07:11 +04:00
++localId;
2020-03-10 16:41:12 +04:00
while (ranges::contains(list, localId, &Data::ChatFilter::id)) {
++localId;
}
return localId;
};
2020-03-18 14:25:41 +04:00
auto result = base::flat_map<not_null<FilterRowButton*>, FilterId>();
2020-03-10 16:41:12 +04:00
for (auto &row : *rows) {
const auto id = row.filter.id();
2020-08-16 03:48:17 +03:00
if (row.removed || row.filter.isLocal()) {
continue;
} else if (!ranges::contains(list, id, &Data::ChatFilter::id)) {
result.emplace(row.button, chooseNextId());
if (account->defaultFilterId() == id) {
account->setDefaultFilterId(localId);
}
}
}
// We're prioritizing cloud IDs before local.
localId = kFiltersLimit;
for (auto &row : *rows) {
const auto id = row.filter.id();
if (row.removed || !row.filter.isLocal()) {
2020-03-10 16:41:12 +04:00
continue;
} else if (!ranges::contains(list, id, &Data::ChatFilter::id)) {
2020-03-18 14:25:41 +04:00
result.emplace(row.button, chooseNextId());
2020-07-02 03:34:22 +03:00
if (account->defaultFilterId() == id) {
account->setDefaultFilterId(localId);
}
2020-03-10 16:41:12 +04:00
}
}
return result;
};
return [=] {
2020-03-10 16:41:12 +04:00
auto ids = prepareGoodIdsForNewFilters();
2020-08-16 03:48:17 +03:00
bool needSave = false;
2020-03-10 16:41:12 +04:00
using Requests = std::vector<MTPmessages_UpdateDialogFilter>;
auto addRequests = Requests(), removeRequests = Requests();
2020-03-10 16:41:12 +04:00
auto &realFilters = session->data().chatsFilters();
const auto &list = realFilters.list();
2020-08-16 03:48:17 +03:00
auto &localFolders = cRefLocalFolders();
2020-03-20 16:48:52 +04:00
auto order = std::vector<FilterId>();
order.reserve(rows->size());
2020-08-16 03:48:17 +03:00
auto localFoldersAdded = false;
2020-03-10 16:41:12 +04:00
for (const auto &row : *rows) {
const auto id = row.filter.id();
const auto removed = row.removed;
const auto i = ranges::find(list, id, &Data::ChatFilter::id);
if (removed && i == end(list)) {
continue;
} else if (!removed && i != end(list) && *i == row.filter) {
2020-03-20 16:48:52 +04:00
order.push_back(id);
2020-03-10 16:41:12 +04:00
continue;
}
2020-08-16 03:48:17 +03:00
if (row.filter.isLocal()) {
const auto j = ranges::find_if(localFolders, [id, account](LocalFolder localFolder) {
return (id == localFolder.id
&& account->isCurrent(localFolder.ownerId));
});
if (j == end(localFolders)) {
if (removed) {
continue;
} else {
localFolders.push_back(row.filter.toLocal(kFiltersLimit));
realFilters.set(row.filter);
order.push_back(id);
needSave = true;
localFoldersAdded = true;
}
} else {
if (removed) {
localFolders.erase(j);
realFilters.remove(id);
needSave = true;
} else {
const auto cloudOrder = (*j).cloudOrder;
*j = row.filter.toLocal(cloudOrder);
realFilters.set(row.filter);
order.push_back(id);
needSave = true;
localFoldersAdded = true;
}
}
2020-03-10 16:41:12 +04:00
} else {
2020-08-16 03:48:17 +03:00
const auto newId = ids.take(row.button).value_or(id);
const auto tl = removed
? MTPDialogFilter()
: row.filter.tl(newId);
const auto request = MTPmessages_UpdateDialogFilter(
MTP_flags(removed
? MTPmessages_UpdateDialogFilter::Flag(0)
: MTPmessages_UpdateDialogFilter::Flag::f_filter),
MTP_int(newId),
tl);
if (removed) {
removeRequests.push_back(request);
} else {
addRequests.push_back(request);
order.push_back(newId);
}
realFilters.apply(MTP_updateDialogFilter(
MTP_flags(removed
? MTPDupdateDialogFilter::Flag(0)
: MTPDupdateDialogFilter::Flag::f_filter),
MTP_int(newId),
tl));
2020-03-10 16:41:12 +04:00
}
}
auto previousId = mtpRequestId(0);
auto &&requests = ranges::views::concat(removeRequests, addRequests);
2020-03-10 16:41:12 +04:00
for (auto &request : requests) {
previousId = session->api().request(
std::move(request)
).afterRequest(previousId).send();
}
2020-08-16 03:48:17 +03:00
if (!order.empty() && (!addRequests.empty() || localFoldersAdded)) {
2020-03-20 16:48:52 +04:00
realFilters.saveOrder(order, previousId);
2020-03-10 16:41:12 +04:00
}
if (currentDefaultRemoved) {
2020-07-02 03:34:22 +03:00
account->setDefaultFilterId(0);
controller->setActiveChatsFilter(0);
}
2020-07-02 03:34:22 +03:00
if (currentDefaultId != account->defaultFilterId()) {
2020-08-16 03:48:17 +03:00
needSave = true;
}
if (needSave) {
2020-04-21 06:20:14 +03:00
Kotato::JsonSettings::Write();
}
2020-03-10 16:41:12 +04:00
};
}
} // namespace
Folders::Folders(
QWidget *parent,
not_null<Window::SessionController*> controller)
: Section(parent) {
setupContent(controller);
}
Folders::~Folders() {
if (!App::quitting()) {
_save();
}
}
void Folders::setupContent(not_null<Window::SessionController*> controller) {
controller->session().data().chatsFilters().requestSuggested();
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
_save = SetupFoldersContent(controller, content);
Ui::ResizeFitChild(this, content);
}
} // namespace Settings