Update dialog row height on topic switch.
This commit is contained in:
		
							parent
							
								
									3c799a5cc1
								
							
						
					
					
						commit
						beaea9c57d
					
				
					 14 changed files with 80 additions and 2 deletions
				
			
		| 
						 | 
					@ -197,8 +197,9 @@ struct EntryUpdate {
 | 
				
			||||||
		HasPinnedMessages = (1U << 1),
 | 
							HasPinnedMessages = (1U << 1),
 | 
				
			||||||
		ForwardDraft = (1U << 2),
 | 
							ForwardDraft = (1U << 2),
 | 
				
			||||||
		LocalDraftSet = (1U << 3),
 | 
							LocalDraftSet = (1U << 3),
 | 
				
			||||||
 | 
							Height = (1U << 4),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		LastUsedBit = (1U << 3),
 | 
							LastUsedBit = (1U << 4),
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	using Flags = base::flags<Flag>;
 | 
						using Flags = base::flags<Flag>;
 | 
				
			||||||
	friend inline constexpr auto is_flag_type(Flag) { return true; }
 | 
						friend inline constexpr auto is_flag_type(Flag) { return true; }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,6 +183,12 @@ void ChannelData::setFlags(ChannelDataFlags which) {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (diff & Flag::Forum) {
 | 
								if (diff & Flag::Forum) {
 | 
				
			||||||
				Core::App().notifications().clearFromHistory(history);
 | 
									Core::App().notifications().clearFromHistory(history);
 | 
				
			||||||
 | 
									history->updateChatListEntryHeight();
 | 
				
			||||||
 | 
									if (history->inChatList()) {
 | 
				
			||||||
 | 
										if (const auto forum = this->forum()) {
 | 
				
			||||||
 | 
											forum->preloadTopics();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					} // namespace Dialogs
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -192,6 +192,7 @@ public:
 | 
				
			||||||
		not_null<Row*> row);
 | 
							not_null<Row*> row);
 | 
				
			||||||
	void updateChatListEntry();
 | 
						void updateChatListEntry();
 | 
				
			||||||
	void updateChatListEntryPostponed();
 | 
						void updateChatListEntryPostponed();
 | 
				
			||||||
 | 
						void updateChatListEntryHeight();
 | 
				
			||||||
	[[nodiscard]] bool isPinnedDialog(FilterId filterId) const {
 | 
						[[nodiscard]] bool isPinnedDialog(FilterId filterId) const {
 | 
				
			||||||
		return lookupPinnedIndex(filterId) != 0;
 | 
							return lookupPinnedIndex(filterId) != 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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) {
 | 
					void IndexedList::moveToTop(Key key) {
 | 
				
			||||||
	if (_list.moveToTop(key)) {
 | 
						if (_list.moveToTop(key)) {
 | 
				
			||||||
		for (const auto &ch : key.entry()->chatListFirstLetters()) {
 | 
							for (const auto &ch : key.entry()->chatListFirstLetters()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@ public:
 | 
				
			||||||
	Row *addByName(Key key);
 | 
						Row *addByName(Key key);
 | 
				
			||||||
	void adjustByDate(const RowsByLetter &links);
 | 
						void adjustByDate(const RowsByLetter &links);
 | 
				
			||||||
	void moveToTop(Key key);
 | 
						void moveToTop(Key key);
 | 
				
			||||||
 | 
						void updateHeight(const RowsByLetter &links);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// row must belong to this indexed list all().
 | 
						// row must belong to this indexed list all().
 | 
				
			||||||
	void movePinned(Row *row, int deltaSign);
 | 
						void movePinned(Row *row, int deltaSign);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -285,8 +285,14 @@ InnerWidget::InnerWidget(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	session().changes().entryUpdates(
 | 
						session().changes().entryUpdates(
 | 
				
			||||||
		Data::EntryUpdate::Flag::Repaint
 | 
							Data::EntryUpdate::Flag::Repaint
 | 
				
			||||||
 | 
							| Data::EntryUpdate::Flag::Height
 | 
				
			||||||
	) | rpl::start_with_next([=](const Data::EntryUpdate &update) {
 | 
						) | rpl::start_with_next([=](const Data::EntryUpdate &update) {
 | 
				
			||||||
		const auto entry = update.entry;
 | 
							const auto entry = update.entry;
 | 
				
			||||||
 | 
							if (update.flags & Data::EntryUpdate::Flag::Height) {
 | 
				
			||||||
 | 
								updateFilteredEntryHeight(entry);
 | 
				
			||||||
 | 
								refresh();
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		const auto repaintId = (_state == WidgetState::Default)
 | 
							const auto repaintId = (_state == WidgetState::Default)
 | 
				
			||||||
			? _filterId
 | 
								? _filterId
 | 
				
			||||||
			: 0;
 | 
								: 0;
 | 
				
			||||||
| 
						 | 
					@ -320,6 +326,24 @@ InnerWidget::InnerWidget(
 | 
				
			||||||
	setupShortcuts();
 | 
						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 {
 | 
					Main::Session &InnerWidget::session() const {
 | 
				
			||||||
	return _controller->session();
 | 
						return _controller->session();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -230,6 +230,7 @@ private:
 | 
				
			||||||
	void repaintDialogRow(FilterId filterId, not_null<Row*> row);
 | 
						void repaintDialogRow(FilterId filterId, not_null<Row*> row);
 | 
				
			||||||
	void repaintDialogRow(RowDescriptor row);
 | 
						void repaintDialogRow(RowDescriptor row);
 | 
				
			||||||
	void refreshDialogRow(RowDescriptor row);
 | 
						void refreshDialogRow(RowDescriptor row);
 | 
				
			||||||
 | 
						void updateFilteredEntryHeight(not_null<Entry*> entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void clearMouseSelection(bool clearSelection = false);
 | 
						void clearMouseSelection(bool clearSelection = false);
 | 
				
			||||||
	void mousePressReleased(
 | 
						void mousePressReleased(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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) {
 | 
					bool List::moveToTop(Key key) {
 | 
				
			||||||
	const auto i = _rowByKey.find(key);
 | 
						const auto i = _rowByKey.find(key);
 | 
				
			||||||
	if (i == _rowByKey.cend()) {
 | 
						if (i == _rowByKey.cend()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,7 @@ public:
 | 
				
			||||||
	not_null<Row*> addByName(Key key);
 | 
						not_null<Row*> addByName(Key key);
 | 
				
			||||||
	bool moveToTop(Key key);
 | 
						bool moveToTop(Key key);
 | 
				
			||||||
	void adjustByDate(not_null<Row*> row);
 | 
						void adjustByDate(not_null<Row*> row);
 | 
				
			||||||
 | 
						void updateHeight(not_null<Row*> row);
 | 
				
			||||||
	bool remove(Key key, Row *replacedBy = nullptr);
 | 
						bool remove(Key key, Row *replacedBy = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	using const_iterator = std::vector<not_null<Row*>>::const_iterator;
 | 
						using const_iterator = std::vector<not_null<Row*>>::const_iterator;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,10 @@ void MainList::removeEntry(Key key) {
 | 
				
			||||||
	recomputeFullListSize();
 | 
						recomputeFullListSize();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainList::updateEntryHeight(const RowsByLetter &links) {
 | 
				
			||||||
 | 
						_all.updateHeight(links);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainList::recomputeFullListSize() {
 | 
					void MainList::recomputeFullListSize() {
 | 
				
			||||||
	_fullListSize = std::max(_all.size(), loaded() ? 0 : _cloudListSize);
 | 
						_fullListSize = std::max(_all.size(), loaded() ? 0 : _cloudListSize);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RowsByLetter addEntry(Key key);
 | 
						RowsByLetter addEntry(Key key);
 | 
				
			||||||
	void removeEntry(Key key);
 | 
						void removeEntry(Key key);
 | 
				
			||||||
 | 
						void updateEntryHeight(const RowsByLetter &links);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void unreadStateChanged(
 | 
						void unreadStateChanged(
 | 
				
			||||||
		const UnreadState &wasState,
 | 
							const UnreadState &wasState,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,10 +100,16 @@ void BasicRow::paintUserpic(
 | 
				
			||||||
Row::Row(Key key, int index, int top) : _id(key), _top(top), _index(index) {
 | 
					Row::Row(Key key, int index, int top) : _id(key), _top(top), _index(index) {
 | 
				
			||||||
	if (const auto history = key.history()) {
 | 
						if (const auto history = key.history()) {
 | 
				
			||||||
		updateCornerBadgeShown(history->peer);
 | 
							updateCornerBadgeShown(history->peer);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recountHeight();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Row::recountHeight() {
 | 
				
			||||||
 | 
						if (const auto history = _id.history()) {
 | 
				
			||||||
		_height = history->peer->isForum()
 | 
							_height = history->peer->isForum()
 | 
				
			||||||
			? st::forumDialogRow.height
 | 
								? st::forumDialogRow.height
 | 
				
			||||||
			: st::defaultDialogRow.height;
 | 
								: st::defaultDialogRow.height;
 | 
				
			||||||
	} else if (key.folder()) {
 | 
						} else if (_id.folder()) {
 | 
				
			||||||
		_height = st::defaultDialogRow.height;
 | 
							_height = st::defaultDialogRow.height;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		_height = st::forumTopicRow.height;
 | 
							_height = st::forumTopicRow.height;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,6 +91,7 @@ public:
 | 
				
			||||||
	[[nodiscard]] int height() const {
 | 
						[[nodiscard]] int height() const {
 | 
				
			||||||
		return _height;
 | 
							return _height;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						void recountHeight();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void updateCornerBadgeShown(
 | 
						void updateCornerBadgeShown(
 | 
				
			||||||
		not_null<PeerData*> peer,
 | 
							not_null<PeerData*> peer,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue