mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-13 04:37:11 +02:00
Changed engine of chats filters in forward box with restoring state.
This commit is contained in:
parent
2dfa58aae2
commit
e70f50d837
1 changed files with 57 additions and 147 deletions
|
@ -2061,7 +2061,17 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
|
|||
|
||||
class ListBox final : public PeerListBox {
|
||||
public:
|
||||
using PeerListBox::PeerListBox;
|
||||
ListBox(
|
||||
QWidget *parent,
|
||||
std::unique_ptr<PeerListController> controller,
|
||||
Fn<void(not_null<ListBox*>)> init)
|
||||
: PeerListBox(
|
||||
parent,
|
||||
std::move(controller),
|
||||
[=](not_null<PeerListBox*> box) {
|
||||
init(static_cast<ListBox*>(box.get()));
|
||||
}) {
|
||||
}
|
||||
|
||||
void setBottomSkip(int bottomSkip) {
|
||||
PeerListBox::setInnerBottomSkip(bottomSkip);
|
||||
|
@ -2086,9 +2096,21 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
|
|||
_forwardOptions = forwardOptions;
|
||||
}
|
||||
|
||||
not_null<PeerListContent*> peerListContent() const {
|
||||
return PeerListBox::content();
|
||||
}
|
||||
|
||||
void setFilterId(FilterId filterId) {
|
||||
_filterId = filterId;
|
||||
}
|
||||
[[nodiscard]] FilterId filterId() const {
|
||||
return _filterId;
|
||||
}
|
||||
|
||||
private:
|
||||
rpl::event_stream<> _focusRequests;
|
||||
Ui::ForwardOptions _forwardOptions;
|
||||
FilterId _filterId = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -2106,6 +2128,12 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
|
|||
}) {
|
||||
}
|
||||
|
||||
std::unique_ptr<PeerListRow> createRestoredRow(
|
||||
not_null<PeerData*> peer) override final {
|
||||
return ChooseRecipientBoxController::createRow(
|
||||
peer->owner().history(peer));
|
||||
}
|
||||
|
||||
using PeerListController::setSearchNoResultsText;
|
||||
|
||||
void rowClicked(not_null<PeerListRow*> row) override final {
|
||||
|
@ -2158,166 +2186,48 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
|
|||
base::unique_qptr<Ui::PopupMenu> menu;
|
||||
};
|
||||
|
||||
const auto applyFilter = [=](not_null<PeerListBox*> box, FilterId id) {
|
||||
const auto applyFilter = [=](not_null<ListBox*> box, FilterId id) {
|
||||
box->scrollToY(0);
|
||||
auto &filters = session->data().chatsFilters();
|
||||
const auto &list = filters.list();
|
||||
if (list.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
const auto pinnedList = [&](
|
||||
not_null<Dialogs::MainList*> list,
|
||||
bool foundSelf) {
|
||||
const auto pinned = list->pinned()->order();
|
||||
auto peers = std::vector<not_null<PeerData*>>();
|
||||
peers.reserve(pinned.size());
|
||||
for (const auto &pin : pinned) {
|
||||
if (!foundSelf && pin.peer()->isSelf()) {
|
||||
peers.insert(peers.begin(), pin.peer());
|
||||
foundSelf = true;
|
||||
} else {
|
||||
peers.push_back(pin.peer());
|
||||
}
|
||||
}
|
||||
if (!foundSelf) {
|
||||
peers.insert(peers.begin(), session->user());
|
||||
}
|
||||
return peers;
|
||||
};
|
||||
const auto folder = session->data().folderLoaded(
|
||||
Data::Folder::kId);
|
||||
const auto pinned = pinnedList(
|
||||
id
|
||||
? filters.chatsList(id)
|
||||
: session->data().chatsList(nullptr),
|
||||
!!id);
|
||||
const auto pinnedInFolder = (!id && folder)
|
||||
? pinnedList(folder->chatsList(), true)
|
||||
: std::vector<not_null<PeerData*>>();
|
||||
box->peerListSortRows([&](
|
||||
const PeerListRow &r1,
|
||||
const PeerListRow &r2) {
|
||||
{ // Pinned to top.
|
||||
auto it1 = pinned.end();
|
||||
auto it2 = pinned.end();
|
||||
for (auto it = pinned.begin(); it != pinned.end(); ++it) {
|
||||
if ((*it) == r1.peer()) {
|
||||
it1 = it;
|
||||
}
|
||||
if ((*it) == r2.peer()) {
|
||||
it2 = it;
|
||||
}
|
||||
if (it1 != pinned.end() && it2 != pinned.end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it1 == pinned.end() && it2 != pinned.end()) {
|
||||
return false;
|
||||
} else if (it2 == pinned.end() && it1 != pinned.end()) {
|
||||
return true;
|
||||
} else if (it1 != pinned.end() && it2 != pinned.end()) {
|
||||
return it1 < it2;
|
||||
}
|
||||
}
|
||||
{ // Pinned to bottom.
|
||||
const auto &indexed = session->data().contactsNoChatsList();
|
||||
auto it1 = indexed->end();
|
||||
auto it2 = indexed->end();
|
||||
for (auto it = indexed->begin(); it != indexed->end(); ++it) {
|
||||
if (it->get()->key().peer() == r1.peer()) {
|
||||
it1 = it;
|
||||
}
|
||||
if (it->get()->key().peer() == r2.peer()) {
|
||||
it2 = it;
|
||||
}
|
||||
if (it1 != indexed->end() && it2 != indexed->end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it1 == indexed->end() && it2 != indexed->end()) {
|
||||
return true;
|
||||
} else if (it2 == indexed->end() && it1 != indexed->end()) {
|
||||
return false;
|
||||
} else if (it1 != indexed->end() && it2 != indexed->end()) {
|
||||
return it1 > it2;
|
||||
}
|
||||
}
|
||||
if (folder) {
|
||||
const auto pinned1 = ranges::find(pinnedInFolder, r1.peer());
|
||||
const auto pinned2 = ranges::find(pinnedInFolder, r2.peer());
|
||||
const auto isPinned1 = pinned1 != pinnedInFolder.end();
|
||||
const auto isPinned2 = pinned2 != pinnedInFolder.end();
|
||||
if (isPinned1 && isPinned2) {
|
||||
return pinned1 < pinned2;
|
||||
}
|
||||
|
||||
const auto &indexed = folder->chatsList()->indexed();
|
||||
auto it1 = indexed->end();
|
||||
auto it2 = indexed->end();
|
||||
for (auto it = indexed->begin(); it != indexed->end(); ++it) {
|
||||
if (it->get()->key().peer() == r1.peer()) {
|
||||
it1 = it;
|
||||
}
|
||||
if (it->get()->key().peer() == r2.peer()) {
|
||||
it2 = it;
|
||||
}
|
||||
if (it1 != indexed->end() && it2 != indexed->end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const auto isFoldered1 = it1 != indexed->end();
|
||||
const auto isFoldered2 = it2 != indexed->end();
|
||||
if (isPinned1 && !isPinned2) {
|
||||
return isFoldered2;
|
||||
}
|
||||
if (isPinned2 && !isPinned1) {
|
||||
return !isFoldered1;
|
||||
}
|
||||
if (!isPinned1 && !isPinned2) {
|
||||
if (!isFoldered1 && isFoldered2) {
|
||||
return true;
|
||||
} else if (!isFoldered2 && isFoldered1) {
|
||||
return false;
|
||||
} else if (isFoldered1 && isFoldered2) {
|
||||
return it1 < it2;
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto history1 = session->data().history(r1.peer());
|
||||
const auto history2 = session->data().history(r2.peer());
|
||||
const auto date1 = history1->lastMessage()
|
||||
? history1->lastMessage()->date()
|
||||
: TimeId(0);
|
||||
const auto date2 = history2->lastMessage()
|
||||
? history2->lastMessage()->date()
|
||||
: TimeId(0);
|
||||
return date1 > date2;
|
||||
});
|
||||
const auto filter = ranges::find(
|
||||
list,
|
||||
id,
|
||||
&Data::ChatFilter::id);
|
||||
if (filter == list.end()) {
|
||||
if (box->filterId() == id) {
|
||||
return;
|
||||
}
|
||||
box->peerListPartitionRows([&](const PeerListRow &row) {
|
||||
const auto rowPtr = const_cast<PeerListRow*>(&row);
|
||||
if (!filter->id()) {
|
||||
box->peerListSetRowHidden(rowPtr, false);
|
||||
} else {
|
||||
const auto result = filter->contains(
|
||||
session->data().history(row.peer()));
|
||||
box->peerListSetRowHidden(rowPtr, !result);
|
||||
box->setFilterId(id);
|
||||
|
||||
using SavedState = PeerListController::SavedStateBase;
|
||||
auto state = std::make_unique<PeerListState>();
|
||||
state->controllerState = std::make_unique<SavedState>();
|
||||
|
||||
const auto addList = [&](auto chats) {
|
||||
for (const auto &row : chats->all()) {
|
||||
if (const auto history = row->history()) {
|
||||
state->list.push_back(history->peer);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
box->peerListRefreshRows();
|
||||
};
|
||||
|
||||
if (!id) {
|
||||
state->list.push_back(session->user());
|
||||
addList(session->data().chatsList()->indexed());
|
||||
const auto folderId = Data::Folder::kId;
|
||||
if (const auto folder = session->data().folderLoaded(folderId)) {
|
||||
addList(folder->chatsList()->indexed());
|
||||
}
|
||||
addList(session->data().contactsNoChatsList());
|
||||
} else {
|
||||
addList(session->data().chatsFilters().chatsList(id)->indexed());
|
||||
}
|
||||
box->peerListContent()->restoreState(std::move(state));
|
||||
};
|
||||
|
||||
const auto state = [&] {
|
||||
auto controller = std::make_unique<Controller>(session);
|
||||
const auto controllerRaw = controller.get();
|
||||
auto init = [=](not_null<PeerListBox*> box) {
|
||||
auto init = [=](not_null<ListBox*> box) {
|
||||
controllerRaw->setSearchNoResultsText(
|
||||
tr::lng_bot_chats_not_found(tr::now));
|
||||
box->setSpecialTabMode(true);
|
||||
|
|
Loading…
Add table
Reference in a new issue