Update dialog row height on topic switch.

This commit is contained in:
John Preston 2022-11-29 21:36:34 +04:00
parent 3c799a5cc1
commit beaea9c57d
14 changed files with 80 additions and 2 deletions

View file

@ -197,8 +197,9 @@ struct EntryUpdate {
HasPinnedMessages = (1U << 1),
ForwardDraft = (1U << 2),
LocalDraftSet = (1U << 3),
Height = (1U << 4),
LastUsedBit = (1U << 3),
LastUsedBit = (1U << 4),
};
using Flags = base::flags<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }

View file

@ -183,6 +183,12 @@ void ChannelData::setFlags(ChannelDataFlags which) {
}
if (diff & Flag::Forum) {
Core::App().notifications().clearFromHistory(history);
history->updateChatListEntryHeight();
if (history->inChatList()) {
if (const auto forum = this->forum()) {
forum->preloadTopics();
}
}
}
}
}

View file

@ -379,4 +379,15 @@ void Entry::updateChatListEntryPostponed() {
});
}
void Entry::updateChatListEntryHeight() {
auto &filters = _owner->chatsFilters();
for (auto &[filterId, rows] : _chatListLinks) {
const auto list = filterId
? filters.chatsList(filterId)
: _owner->chatsList(folder());
list->updateEntryHeight(rows);
}
session().changes().entryUpdated(this, Data::EntryUpdate::Flag::Height);
}
} // namespace Dialogs

View file

@ -192,6 +192,7 @@ public:
not_null<Row*> row);
void updateChatListEntry();
void updateChatListEntryPostponed();
void updateChatListEntryHeight();
[[nodiscard]] bool isPinnedDialog(FilterId filterId) const {
return lookupPinnedIndex(filterId) != 0;
}

View file

@ -61,6 +61,15 @@ void IndexedList::adjustByDate(const RowsByLetter &links) {
}
}
void IndexedList::updateHeight(const RowsByLetter &links) {
_list.updateHeight(links.main);
for (const auto &[ch, row] : links.letters) {
if (auto it = _index.find(ch); it != _index.cend()) {
it->second.updateHeight(row);
}
}
}
void IndexedList::moveToTop(Key key) {
if (_list.moveToTop(key)) {
for (const auto &ch : key.entry()->chatListFirstLetters()) {

View file

@ -22,6 +22,7 @@ public:
Row *addByName(Key key);
void adjustByDate(const RowsByLetter &links);
void moveToTop(Key key);
void updateHeight(const RowsByLetter &links);
// row must belong to this indexed list all().
void movePinned(Row *row, int deltaSign);

View file

@ -285,8 +285,14 @@ InnerWidget::InnerWidget(
session().changes().entryUpdates(
Data::EntryUpdate::Flag::Repaint
| Data::EntryUpdate::Flag::Height
) | rpl::start_with_next([=](const Data::EntryUpdate &update) {
const auto entry = update.entry;
if (update.flags & Data::EntryUpdate::Flag::Height) {
updateFilteredEntryHeight(entry);
refresh();
return;
}
const auto repaintId = (_state == WidgetState::Default)
? _filterId
: 0;
@ -320,6 +326,24 @@ InnerWidget::InnerWidget(
setupShortcuts();
}
void InnerWidget::updateFilteredEntryHeight(not_null<Entry*> entry) {
auto changing = false;
auto top = 0;
for (auto &result : _filterResults) {
if (changing) {
result.top = top;
}
if (result.row->key().entry() == entry) {
result.row->recountHeight();
changing = true;
top = result.top;
}
if (changing) {
top += result.row->height();
}
}
}
Main::Session &InnerWidget::session() const {
return _controller->session();
}

View file

@ -230,6 +230,7 @@ private:
void repaintDialogRow(FilterId filterId, not_null<Row*> row);
void repaintDialogRow(RowDescriptor row);
void refreshDialogRow(RowDescriptor row);
void updateFilteredEntryHeight(not_null<Entry*> entry);
void clearMouseSelection(bool clearSelection = false);
void mousePressReleased(

View file

@ -103,6 +103,17 @@ void List::adjustByDate(not_null<Row*> row) {
}
}
void List::updateHeight(not_null<Row*> row) {
row->recountHeight();
const auto index = row->index();
auto top = row->top();
for (auto i = _rows.begin() + index, e = _rows.end(); i != e; ++i) {
(*i)->_top = top;
top += (*i)->height();
}
}
bool List::moveToTop(Key key) {
const auto i = _rowByKey.find(key);
if (i == _rowByKey.cend()) {

View file

@ -48,6 +48,7 @@ public:
not_null<Row*> addByName(Key key);
bool moveToTop(Key key);
void adjustByDate(not_null<Row*> row);
void updateHeight(not_null<Row*> row);
bool remove(Key key, Row *replacedBy = nullptr);
using const_iterator = std::vector<not_null<Row*>>::const_iterator;

View file

@ -107,6 +107,10 @@ void MainList::removeEntry(Key key) {
recomputeFullListSize();
}
void MainList::updateEntryHeight(const RowsByLetter &links) {
_all.updateHeight(links);
}
void MainList::recomputeFullListSize() {
_fullListSize = std::max(_all.size(), loaded() ? 0 : _cloudListSize);
}

View file

@ -35,6 +35,7 @@ public:
RowsByLetter addEntry(Key key);
void removeEntry(Key key);
void updateEntryHeight(const RowsByLetter &links);
void unreadStateChanged(
const UnreadState &wasState,

View file

@ -100,10 +100,16 @@ void BasicRow::paintUserpic(
Row::Row(Key key, int index, int top) : _id(key), _top(top), _index(index) {
if (const auto history = key.history()) {
updateCornerBadgeShown(history->peer);
}
recountHeight();
}
void Row::recountHeight() {
if (const auto history = _id.history()) {
_height = history->peer->isForum()
? st::forumDialogRow.height
: st::defaultDialogRow.height;
} else if (key.folder()) {
} else if (_id.folder()) {
_height = st::defaultDialogRow.height;
} else {
_height = st::forumTopicRow.height;

View file

@ -91,6 +91,7 @@ public:
[[nodiscard]] int height() const {
return _height;
}
void recountHeight();
void updateCornerBadgeShown(
not_null<PeerData*> peer,