mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 22:54:01 +02:00
Update API: support "All Chats" reordering.
This commit is contained in:
parent
73bacfc650
commit
fe91887ea2
13 changed files with 113 additions and 36 deletions
|
@ -1183,6 +1183,7 @@ bankCardOpenUrl#f568028a url:string name:string = BankCardOpenUrl;
|
|||
payments.bankCardData#3e24e573 title:string open_urls:Vector<BankCardOpenUrl> = payments.BankCardData;
|
||||
|
||||
dialogFilter#7438f7e8 flags:# contacts:flags.0?true non_contacts:flags.1?true groups:flags.2?true broadcasts:flags.3?true bots:flags.4?true exclude_muted:flags.11?true exclude_read:flags.12?true exclude_archived:flags.13?true id:int title:string emoticon:flags.25?string pinned_peers:Vector<InputPeer> include_peers:Vector<InputPeer> exclude_peers:Vector<InputPeer> = DialogFilter;
|
||||
dialogFilterDefault#363293ae = DialogFilter;
|
||||
|
||||
dialogFilterSuggested#77744d4a filter:DialogFilter description:string = DialogFilterSuggested;
|
||||
|
||||
|
@ -1786,6 +1787,7 @@ payments.getSavedInfo#227d824b = payments.SavedInfo;
|
|||
payments.clearSavedInfo#d83d70c1 flags:# credentials:flags.0?true info:flags.1?true = Bool;
|
||||
payments.getBankCardData#2e79d779 number:string = payments.BankCardData;
|
||||
payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoice;
|
||||
payments.assignAppStoreTransaction#6299a12f transaction_id:string = Updates;
|
||||
|
||||
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
|
||||
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
|
||||
|
|
|
@ -57,6 +57,8 @@ void ChangeFilterById(
|
|||
FilterId filterId,
|
||||
not_null<History*> history,
|
||||
bool add) {
|
||||
Expects(filterId != 0);
|
||||
|
||||
const auto list = history->owner().chatsFilters().list();
|
||||
const auto i = ranges::find(list, filterId, &Data::ChatFilter::id);
|
||||
if (i != end(list)) {
|
||||
|
@ -99,7 +101,7 @@ ChooseFilterValidator::ChooseFilterValidator(not_null<History*> history)
|
|||
|
||||
bool ChooseFilterValidator::canAdd() const {
|
||||
for (const auto &filter : _history->owner().chatsFilters().list()) {
|
||||
if (!filter.contains(_history)) {
|
||||
if (filter.id() && !filter.contains(_history)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +109,8 @@ bool ChooseFilterValidator::canAdd() const {
|
|||
}
|
||||
|
||||
bool ChooseFilterValidator::canRemove(FilterId filterId) const {
|
||||
Expects(filterId != 0);
|
||||
|
||||
const auto list = _history->owner().chatsFilters().list();
|
||||
const auto i = ranges::find(list, filterId, &Data::ChatFilter::id);
|
||||
if (i != end(list)) {
|
||||
|
@ -118,6 +122,8 @@ bool ChooseFilterValidator::canRemove(FilterId filterId) const {
|
|||
}
|
||||
|
||||
bool ChooseFilterValidator::limitReached(FilterId filterId) const {
|
||||
Expects(filterId != 0);
|
||||
|
||||
const auto list = _history->owner().chatsFilters().list();
|
||||
const auto i = ranges::find(list, filterId, &Data::ChatFilter::id);
|
||||
const auto limit = _history->owner().pinnedChatsLimit(nullptr, filterId);
|
||||
|
@ -142,6 +148,10 @@ void FillChooseFilterMenu(
|
|||
const auto validator = ChooseFilterValidator(history);
|
||||
for (const auto &filter : history->owner().chatsFilters().list()) {
|
||||
const auto id = filter.id();
|
||||
if (!id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto contains = filter.contains(history);
|
||||
const auto action = menu->addAction(filter.title(), [=] {
|
||||
if (filter.contains(history)) {
|
||||
|
|
|
@ -668,6 +668,8 @@ void EditFilterBox(
|
|||
void EditExistingFilter(
|
||||
not_null<Window::SessionController*> window,
|
||||
FilterId id) {
|
||||
Expects(id != 0);
|
||||
|
||||
const auto session = &window->session();
|
||||
const auto &list = session->data().chatsFilters().list();
|
||||
const auto i = ranges::find(list, id, &Data::ChatFilter::id);
|
||||
|
|
|
@ -107,6 +107,8 @@ ChatFilter ChatFilter::FromTL(
|
|||
std::move(list),
|
||||
std::move(pinned),
|
||||
{ never.begin(), never.end() });
|
||||
}, [](const MTPDdialogFilterDefault &d) {
|
||||
return ChatFilter();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -220,6 +222,7 @@ bool ChatFilter::contains(not_null<History*> history) const {
|
|||
}
|
||||
|
||||
ChatFilters::ChatFilters(not_null<Session*> owner) : _owner(owner) {
|
||||
_list.emplace_back();
|
||||
crl::on_main(&owner->session(), [=] { load(); });
|
||||
}
|
||||
|
||||
|
@ -295,6 +298,9 @@ void ChatFilters::received(const QVector<MTPDialogFilter> &list) {
|
|||
applyRemove(position);
|
||||
changed = true;
|
||||
}
|
||||
if (!ranges::contains(begin(_list), end(_list), 0, &ChatFilter::id)) {
|
||||
_list.insert(begin(_list), ChatFilter());
|
||||
}
|
||||
if (changed || !_loaded) {
|
||||
_loaded = true;
|
||||
_listChanged.fire({});
|
||||
|
@ -352,6 +358,16 @@ void ChatFilters::remove(FilterId id) {
|
|||
_listChanged.fire({});
|
||||
}
|
||||
|
||||
void ChatFilters::moveAllToFront() {
|
||||
const auto i = ranges::find(_list, FilterId(), &ChatFilter::id);
|
||||
if (!_list.empty() && i == begin(_list)) {
|
||||
return;
|
||||
} else if (i != end(_list)) {
|
||||
_list.erase(i);
|
||||
}
|
||||
_list.insert(begin(_list), ChatFilter());
|
||||
}
|
||||
|
||||
void ChatFilters::applyRemove(int position) {
|
||||
Expects(position >= 0 && position < _list.size());
|
||||
|
||||
|
@ -518,6 +534,10 @@ const std::vector<ChatFilter> &ChatFilters::list() const {
|
|||
return _list;
|
||||
}
|
||||
|
||||
bool ChatFilters::has() const {
|
||||
return _list.size() > 1;
|
||||
}
|
||||
|
||||
rpl::producer<> ChatFilters::changed() const {
|
||||
return _listChanged.events();
|
||||
}
|
||||
|
|
|
@ -99,8 +99,10 @@ public:
|
|||
void apply(const MTPUpdate &update);
|
||||
void set(ChatFilter filter);
|
||||
void remove(FilterId id);
|
||||
void moveAllToFront();
|
||||
[[nodiscard]] const std::vector<ChatFilter> &list() const;
|
||||
[[nodiscard]] rpl::producer<> changed() const;
|
||||
[[nodiscard]] bool has() const;
|
||||
|
||||
bool loadNextExceptions(bool chatsListLoaded);
|
||||
|
||||
|
|
|
@ -268,7 +268,7 @@ Session::Session(not_null<Main::Session*> session)
|
|||
|
||||
_chatsFilters->changed(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto enabled = !_chatsFilters->list().empty();
|
||||
const auto enabled = _chatsFilters->has();
|
||||
if (enabled != session->settings().dialogsFiltersEnabled()) {
|
||||
session->settings().setDialogsFiltersEnabled(enabled);
|
||||
session->saveSettingsDelayed();
|
||||
|
|
|
@ -2706,7 +2706,7 @@ bool InnerWidget::chooseCollapsedRow() {
|
|||
}
|
||||
|
||||
void InnerWidget::switchToFilter(FilterId filterId) {
|
||||
const auto found = ranges::contains(
|
||||
const auto found = filterId && ranges::contains(
|
||||
session().data().chatsFilters().list(),
|
||||
filterId,
|
||||
&Data::ChatFilter::id);
|
||||
|
@ -3204,16 +3204,16 @@ void InnerWidget::setupShortcuts() {
|
|||
return false;
|
||||
});
|
||||
|
||||
const auto filters = &session().data().chatsFilters().list();
|
||||
if (const auto filtersCount = int(filters->size())) {
|
||||
if (session().data().chatsFilters().has()) {
|
||||
const auto filters = &session().data().chatsFilters().list();
|
||||
const auto filtersCount = int(filters->size());
|
||||
auto &&folders = ranges::views::zip(
|
||||
Shortcuts::kShowFolder,
|
||||
ranges::views::ints(0, ranges::unreachable));
|
||||
|
||||
for (const auto [command, index] : folders) {
|
||||
const auto select = (command == Command::ShowFolderLast)
|
||||
? filtersCount
|
||||
: std::clamp(index, 0, filtersCount);
|
||||
: std::clamp(index, 0, int(filtersCount));
|
||||
request->check(command) && request->handle([=] {
|
||||
if (select <= filtersCount) {
|
||||
_controller->setActiveChatsFilter((select > 0)
|
||||
|
@ -3256,15 +3256,16 @@ void InnerWidget::setupShortcuts() {
|
|||
const auto nearFolder = [=](bool isNext) {
|
||||
const auto id = _controller->activeChatsFilterCurrent();
|
||||
const auto list = &session().data().chatsFilters().list();
|
||||
const auto index = (id != 0)
|
||||
? int(ranges::find(*list, id, &Data::ChatFilter::id)
|
||||
- begin(*list))
|
||||
: -1;
|
||||
const auto index = int(ranges::find(
|
||||
*list,
|
||||
id,
|
||||
&Data::ChatFilter::id
|
||||
) - begin(*list));
|
||||
if (index == list->size() && id != 0) {
|
||||
return false;
|
||||
}
|
||||
const auto changed = index + (isNext ? 1 : -1);
|
||||
if (changed >= int(list->size()) || changed < -1) {
|
||||
if (changed >= int(list->size()) || changed < 0) {
|
||||
return false;
|
||||
}
|
||||
_controller->setActiveChatsFilter((changed >= 0)
|
||||
|
|
|
@ -424,7 +424,9 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
|
|||
};
|
||||
const auto &list = session->data().chatsFilters().list();
|
||||
for (const auto &filter : list) {
|
||||
addFilter(filter);
|
||||
if (filter.id()) {
|
||||
addFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
AddButton(
|
||||
|
|
|
@ -289,7 +289,7 @@ void SetupSections(
|
|||
st::settingsButton,
|
||||
{ &st::settingsIconFolders, kIconDarkBlue }))
|
||||
)->setDuration(0);
|
||||
if (!controller->session().data().chatsFilters().list().empty()
|
||||
if (controller->session().data().chatsFilters().has()
|
||||
|| controller->session().settings().dialogsFiltersEnabled()) {
|
||||
slided->show(anim::type::instant);
|
||||
preload();
|
||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "data/data_chat_filters.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_user.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/filter_icons.h"
|
||||
#include "ui/wrap/vertical_layout_reorder.h"
|
||||
|
@ -103,9 +104,16 @@ void FiltersMenu::setup() {
|
|||
_container->move(0, 0);
|
||||
}, _outer.lifetime());
|
||||
|
||||
auto premium = _session->session().user()->flagsValue(
|
||||
) | rpl::filter([=](UserData::Flags::Change change) {
|
||||
return (change.diff & UserDataFlag::Premium);
|
||||
}) | rpl::map([=] {
|
||||
return _session->session().user()->isPremium();
|
||||
});
|
||||
const auto filters = &_session->session().data().chatsFilters();
|
||||
rpl::single(rpl::empty) | rpl::then(
|
||||
filters->changed()
|
||||
rpl::combine(
|
||||
rpl::single(rpl::empty) | rpl::then(filters->changed()),
|
||||
std::move(premium)
|
||||
) | rpl::start_with_next([=] {
|
||||
refresh();
|
||||
}, _outer.lifetime());
|
||||
|
@ -118,7 +126,7 @@ void FiltersMenu::setup() {
|
|||
const auto i = _filters.find(_activeFilterId);
|
||||
if (i != end(_filters)) {
|
||||
i->second->setActive(false);
|
||||
} else if (!_activeFilterId) {
|
||||
} else if (!_activeFilterId && _all) {
|
||||
_all->setActive(false);
|
||||
}
|
||||
_activeFilterId = id;
|
||||
|
@ -126,7 +134,7 @@ void FiltersMenu::setup() {
|
|||
if (j != end(_filters)) {
|
||||
j->second->setActive(true);
|
||||
scrollToButton(j->second);
|
||||
} else if (!_activeFilterId) {
|
||||
} else if (!_activeFilterId && _all) {
|
||||
_all->setActive(true);
|
||||
scrollToButton(_all);
|
||||
}
|
||||
|
@ -178,17 +186,24 @@ void FiltersMenu::scrollToButton(not_null<Ui::RpWidget*> widget) {
|
|||
|
||||
void FiltersMenu::refresh() {
|
||||
const auto filters = &_session->session().data().chatsFilters();
|
||||
if (filters->list().empty() || _ignoreRefresh) {
|
||||
if (!filters->has() || _ignoreRefresh) {
|
||||
return;
|
||||
}
|
||||
const auto oldTop = _scroll.scrollTop();
|
||||
|
||||
const auto reorderAll = premium();
|
||||
if (!_list) {
|
||||
setupList();
|
||||
} else if (reorderAll && _all) {
|
||||
_all = nullptr;
|
||||
} else if (!reorderAll && !_all) {
|
||||
_all = prepareAll();
|
||||
}
|
||||
_reorder->cancel();
|
||||
auto now = base::flat_map<int, base::unique_qptr<Ui::SideBarButton>>();
|
||||
for (const auto &filter : filters->list()) {
|
||||
if (!reorderAll && !filter.id()) {
|
||||
continue;
|
||||
}
|
||||
now.emplace(
|
||||
filter.id(),
|
||||
prepareButton(
|
||||
|
@ -206,15 +221,14 @@ void FiltersMenu::refresh() {
|
|||
// so we have to restore it.
|
||||
_scroll.scrollToY(oldTop);
|
||||
const auto i = _filters.find(_activeFilterId);
|
||||
scrollToButton((i != end(_filters)) ? i->second : _all);
|
||||
const auto button = ((i != end(_filters)) ? i->second : _all).get();
|
||||
if (button) {
|
||||
scrollToButton(button);
|
||||
}
|
||||
}
|
||||
|
||||
void FiltersMenu::setupList() {
|
||||
_all = prepareButton(
|
||||
_container,
|
||||
0,
|
||||
tr::lng_filters_all(tr::now),
|
||||
Ui::FilterIcon::All);
|
||||
_all = premium() ? nullptr : prepareAll();
|
||||
_list = _container->add(object_ptr<Ui::VerticalLayout>(_container));
|
||||
_setup = prepareButton(
|
||||
_container,
|
||||
|
@ -239,18 +253,32 @@ void FiltersMenu::setupList() {
|
|||
}, _outer.lifetime());
|
||||
}
|
||||
|
||||
bool FiltersMenu::premium() const {
|
||||
return _session->session().user()->isPremium();
|
||||
}
|
||||
|
||||
base::unique_qptr<Ui::SideBarButton> FiltersMenu::prepareAll() {
|
||||
return prepareButton(_container, 0, {}, Ui::FilterIcon::All, true);
|
||||
}
|
||||
|
||||
base::unique_qptr<Ui::SideBarButton> FiltersMenu::prepareButton(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
FilterId id,
|
||||
const QString &title,
|
||||
Ui::FilterIcon icon) {
|
||||
auto button = base::unique_qptr<Ui::SideBarButton>(container->add(
|
||||
object_ptr<Ui::SideBarButton>(
|
||||
container,
|
||||
title,
|
||||
st::windowFiltersButton)));
|
||||
Ui::FilterIcon icon,
|
||||
bool toBeginning) {
|
||||
auto prepared = object_ptr<Ui::SideBarButton>(
|
||||
container,
|
||||
id ? title : tr::lng_filters_all(tr::now),
|
||||
st::windowFiltersButton);
|
||||
auto added = toBeginning
|
||||
? container->insert(0, std::move(prepared))
|
||||
: container->add(std::move(prepared));
|
||||
auto button = base::unique_qptr<Ui::SideBarButton>(std::move(added));
|
||||
const auto raw = button.get();
|
||||
const auto &icons = Ui::LookupFilterIcon(icon);
|
||||
const auto &icons = Ui::LookupFilterIcon(id
|
||||
? icon
|
||||
: Ui::FilterIcon::All);
|
||||
raw->setIconOverride(icons.normal, icons.active);
|
||||
if (id >= 0) {
|
||||
UnreadStateValue(
|
||||
|
@ -372,6 +400,13 @@ void FiltersMenu::applyReorder(
|
|||
|
||||
const auto filters = &_session->session().data().chatsFilters();
|
||||
const auto &list = filters->list();
|
||||
if (_all) {
|
||||
if (list[0].id() != FilterId()) {
|
||||
filters->moveAllToFront();
|
||||
}
|
||||
++oldPosition;
|
||||
++newPosition;
|
||||
}
|
||||
Assert(oldPosition >= 0 && oldPosition < list.size());
|
||||
Assert(newPosition >= 0 && newPosition < list.size());
|
||||
const auto id = list[oldPosition].id();
|
||||
|
|
|
@ -41,11 +41,14 @@ private:
|
|||
not_null<Ui::RpWidget*> widget,
|
||||
int oldPosition,
|
||||
int newPosition);
|
||||
[[nodiscard]] bool premium() const;
|
||||
[[nodiscard]] base::unique_qptr<Ui::SideBarButton> prepareAll();
|
||||
[[nodiscard]] base::unique_qptr<Ui::SideBarButton> prepareButton(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
FilterId id,
|
||||
const QString &title,
|
||||
Ui::FilterIcon icon);
|
||||
Ui::FilterIcon icon,
|
||||
bool toBeginning = false);
|
||||
void setupMainMenuIcon();
|
||||
void showMenu(QPoint position, FilterId id);
|
||||
void showEditBox(FilterId id);
|
||||
|
|
|
@ -419,7 +419,7 @@ void Filler::addInfo() {
|
|||
void Filler::addToggleFolder() {
|
||||
const auto controller = _controller;
|
||||
const auto history = _request.key.history();
|
||||
if (!history || history->owner().chatsFilters().list().empty()) {
|
||||
if (!history || !history->owner().chatsFilters().has()) {
|
||||
return;
|
||||
}
|
||||
_addAction(PeerMenuCallback::Args{
|
||||
|
|
|
@ -764,7 +764,7 @@ void SessionController::toggleFiltersMenu(bool enabled) {
|
|||
}
|
||||
|
||||
void SessionController::refreshFiltersMenu() {
|
||||
toggleFiltersMenu(!session().data().chatsFilters().list().empty());
|
||||
toggleFiltersMenu(session().data().chatsFilters().has());
|
||||
}
|
||||
|
||||
rpl::producer<> SessionController::filtersMenuChanged() const {
|
||||
|
|
Loading…
Add table
Reference in a new issue