mirror of https://github.com/procxx/kepka.git
				
				
				
			Mark [un]read from chats list.
This commit is contained in:
		
							parent
							
								
									372cf275e0
								
							
						
					
					
						commit
						35c759c6bc
					
				| 
						 | 
					@ -1106,6 +1106,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
"lng_context_view_feed_info" = "View feed info";
 | 
					"lng_context_view_feed_info" = "View feed info";
 | 
				
			||||||
"lng_context_pin_to_top" = "Pin to top";
 | 
					"lng_context_pin_to_top" = "Pin to top";
 | 
				
			||||||
"lng_context_unpin_from_top" = "Unpin from top";
 | 
					"lng_context_unpin_from_top" = "Unpin from top";
 | 
				
			||||||
 | 
					"lng_context_mark_unread" = "Mark as unread";
 | 
				
			||||||
 | 
					"lng_context_mark_read" = "Mark as read";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"lng_context_promote_admin" = "Promote to admin";
 | 
					"lng_context_promote_admin" = "Promote to admin";
 | 
				
			||||||
"lng_context_edit_permissions" = "Edit permissions";
 | 
					"lng_context_edit_permissions" = "Edit permissions";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -719,6 +719,18 @@ void ApiWrap::applyFeedDialogs(
 | 
				
			||||||
	_session->data().sendHistoryChangeNotifications();
 | 
						_session->data().sendHistoryChangeNotifications();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ApiWrap::changeDialogUnreadMark(
 | 
				
			||||||
 | 
							not_null<History*> history,
 | 
				
			||||||
 | 
							bool unread) {
 | 
				
			||||||
 | 
						history->setUnreadMark(unread);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						using Flag = MTPmessages_MarkDialogUnread::Flag;
 | 
				
			||||||
 | 
						request(MTPmessages_MarkDialogUnread(
 | 
				
			||||||
 | 
							MTP_flags(unread ? Flag::f_unread : Flag(0)),
 | 
				
			||||||
 | 
							MTP_inputDialogPeer(history->peer->input)
 | 
				
			||||||
 | 
						)).send();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ApiWrap::requestFullPeer(PeerData *peer) {
 | 
					void ApiWrap::requestFullPeer(PeerData *peer) {
 | 
				
			||||||
	if (!peer || _fullPeerRequests.contains(peer)) return;
 | 
						if (!peer || _fullPeerRequests.contains(peer)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4417,6 +4429,9 @@ void ApiWrap::readServerHistory(not_null<History*> history) {
 | 
				
			||||||
	if (history->unreadCount()) {
 | 
						if (history->unreadCount()) {
 | 
				
			||||||
		readServerHistoryForce(history);
 | 
							readServerHistoryForce(history);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (history->unreadMark()) {
 | 
				
			||||||
 | 
							changeDialogUnreadMark(history, false);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ApiWrap::readServerHistoryForce(not_null<History*> history) {
 | 
					void ApiWrap::readServerHistoryForce(not_null<History*> history) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,6 +85,8 @@ public:
 | 
				
			||||||
	//void setFeedChannels(
 | 
						//void setFeedChannels(
 | 
				
			||||||
	//	not_null<Data::Feed*> feed,
 | 
						//	not_null<Data::Feed*> feed,
 | 
				
			||||||
	//	const std::vector<not_null<ChannelData*>> &channels);
 | 
						//	const std::vector<not_null<ChannelData*>> &channels);
 | 
				
			||||||
 | 
						void changeDialogUnreadMark(not_null<History*> history, bool unread);
 | 
				
			||||||
 | 
						//void changeDialogUnreadMark(not_null<Data::Feed*> feed, bool unread); // #feed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void requestFullPeer(PeerData *peer);
 | 
						void requestFullPeer(PeerData *peer);
 | 
				
			||||||
	void requestPeer(PeerData *peer);
 | 
						void requestPeer(PeerData *peer);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -455,6 +455,10 @@ int Feed::chatListUnreadCount() const {
 | 
				
			||||||
	return unreadCount();
 | 
						return unreadCount();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Feed::chatListUnreadMark() const {
 | 
				
			||||||
 | 
						return false; // #feed unread mark
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Feed::chatListMutedBadge() const {
 | 
					bool Feed::chatListMutedBadge() const {
 | 
				
			||||||
	return _unreadCount ? (*_unreadCount <= _unreadMutedCount) : false;
 | 
						return _unreadCount ? (*_unreadCount <= _unreadMutedCount) : false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,7 @@ public:
 | 
				
			||||||
	bool toImportant() const override;
 | 
						bool toImportant() const override;
 | 
				
			||||||
	bool shouldBeInChatList() const override;
 | 
						bool shouldBeInChatList() const override;
 | 
				
			||||||
	int chatListUnreadCount() const override;
 | 
						int chatListUnreadCount() const override;
 | 
				
			||||||
 | 
						bool chatListUnreadMark() const override;
 | 
				
			||||||
	bool chatListMutedBadge() const override;
 | 
						bool chatListMutedBadge() const override;
 | 
				
			||||||
	HistoryItem *chatsListItem() const override;
 | 
						HistoryItem *chatsListItem() const override;
 | 
				
			||||||
	const QString &chatsListName() const override;
 | 
						const QString &chatsListName() const override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,6 +72,7 @@ public:
 | 
				
			||||||
	virtual bool toImportant() const = 0;
 | 
						virtual bool toImportant() const = 0;
 | 
				
			||||||
	virtual bool shouldBeInChatList() const = 0;
 | 
						virtual bool shouldBeInChatList() const = 0;
 | 
				
			||||||
	virtual int chatListUnreadCount() const = 0;
 | 
						virtual int chatListUnreadCount() const = 0;
 | 
				
			||||||
 | 
						virtual bool chatListUnreadMark() const = 0;
 | 
				
			||||||
	virtual bool chatListMutedBadge() const = 0;
 | 
						virtual bool chatListMutedBadge() const = 0;
 | 
				
			||||||
	virtual HistoryItem *chatsListItem() const = 0;
 | 
						virtual HistoryItem *chatsListItem() const = 0;
 | 
				
			||||||
	virtual const QString &chatsListName() const = 0;
 | 
						virtual const QString &chatsListName() const = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -407,10 +407,11 @@ void RowPainter::paint(
 | 
				
			||||||
	const auto history = row->history();
 | 
						const auto history = row->history();
 | 
				
			||||||
	const auto peer = history ? history->peer.get() : nullptr;
 | 
						const auto peer = history ? history->peer.get() : nullptr;
 | 
				
			||||||
	const auto unreadCount = entry->chatListUnreadCount();
 | 
						const auto unreadCount = entry->chatListUnreadCount();
 | 
				
			||||||
 | 
						const auto unreadMark = entry->chatListUnreadMark();
 | 
				
			||||||
	const auto unreadMuted = entry->chatListMutedBadge();
 | 
						const auto unreadMuted = entry->chatListMutedBadge();
 | 
				
			||||||
	const auto item = entry->chatsListItem();
 | 
						const auto item = entry->chatsListItem();
 | 
				
			||||||
	const auto cloudDraft = [&]() -> const Data::Draft*{
 | 
						const auto cloudDraft = [&]() -> const Data::Draft*{
 | 
				
			||||||
		if (history && (!item || !unreadCount)) {
 | 
							if (history && (!item || (!unreadCount && !unreadMark))) {
 | 
				
			||||||
			// Draw item, if there are unread messages.
 | 
								// Draw item, if there are unread messages.
 | 
				
			||||||
			if (const auto draft = history->cloudDraft()) {
 | 
								if (const auto draft = history->cloudDraft()) {
 | 
				
			||||||
				if (!Data::draftIsNull(draft)) {
 | 
									if (!Data::draftIsNull(draft)) {
 | 
				
			||||||
| 
						 | 
					@ -458,11 +459,18 @@ void RowPainter::paint(
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return (unreadCount > 0);
 | 
								return (unreadCount > 0);
 | 
				
			||||||
		}();
 | 
							}();
 | 
				
			||||||
 | 
							const auto displayUnreadMark = !displayUnreadCounter
 | 
				
			||||||
 | 
								&& !displayMentionBadge
 | 
				
			||||||
 | 
								&& history
 | 
				
			||||||
 | 
								&& unreadMark;
 | 
				
			||||||
		const auto displayPinnedIcon = !displayUnreadCounter
 | 
							const auto displayPinnedIcon = !displayUnreadCounter
 | 
				
			||||||
			&& !displayMentionBadge
 | 
								&& !displayMentionBadge
 | 
				
			||||||
 | 
								&& !displayUnreadMark
 | 
				
			||||||
			&& entry->isPinnedDialog();
 | 
								&& entry->isPinnedDialog();
 | 
				
			||||||
		if (displayUnreadCounter) {
 | 
							if (displayUnreadCounter || displayUnreadMark) {
 | 
				
			||||||
			auto counter = QString::number(unreadCount);
 | 
								auto counter = (unreadCount > 0)
 | 
				
			||||||
 | 
									? QString::number(unreadCount)
 | 
				
			||||||
 | 
									: QString();
 | 
				
			||||||
			auto unreadRight = fullWidth - st::dialogsPadding.x();
 | 
								auto unreadRight = fullWidth - st::dialogsPadding.x();
 | 
				
			||||||
			auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
 | 
								auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
 | 
				
			||||||
			auto unreadWidth = 0;
 | 
								auto unreadWidth = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1645,6 +1645,11 @@ int History::unreadCount() const {
 | 
				
			||||||
	return _unreadCount ? *_unreadCount : 0;
 | 
						return _unreadCount ? *_unreadCount : 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int History::historiesUnreadCount() const {
 | 
				
			||||||
 | 
						const auto result = unreadCount();
 | 
				
			||||||
 | 
						return (!result && unreadMark()) ? 1 : result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool History::unreadCountKnown() const {
 | 
					bool History::unreadCountKnown() const {
 | 
				
			||||||
	return !!_unreadCount;
 | 
						return !!_unreadCount;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1673,6 +1678,16 @@ void History::setUnreadCount(int newUnreadCount) {
 | 
				
			||||||
				calculateFirstUnreadMessage();
 | 
									calculateFirstUnreadMessage();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							const auto unreadMarkDelta = [&] {
 | 
				
			||||||
 | 
								if (_unreadMark) {
 | 
				
			||||||
 | 
									const auto was = _unreadCount && (*_unreadCount > 0);
 | 
				
			||||||
 | 
									const auto now = (newUnreadCount > 0);
 | 
				
			||||||
 | 
									if (was != now) {
 | 
				
			||||||
 | 
										return was ? 1 : -1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}();
 | 
				
			||||||
		_unreadCount = newUnreadCount;
 | 
							_unreadCount = newUnreadCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (_unreadBarView) {
 | 
							if (_unreadBarView) {
 | 
				
			||||||
| 
						 | 
					@ -1685,14 +1700,38 @@ void History::setUnreadCount(int newUnreadCount) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (inChatList(Dialogs::Mode::All)) {
 | 
							if (inChatList(Dialogs::Mode::All)) {
 | 
				
			||||||
 | 
								const auto delta = unreadCountDelta
 | 
				
			||||||
 | 
									? *unreadCountDelta
 | 
				
			||||||
 | 
									: newUnreadCount;
 | 
				
			||||||
			App::histories().unreadIncrement(
 | 
								App::histories().unreadIncrement(
 | 
				
			||||||
				unreadCountDelta ? *unreadCountDelta : newUnreadCount,
 | 
									delta + unreadMarkDelta,
 | 
				
			||||||
				mute());
 | 
									mute());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (const auto main = App::main()) {
 | 
							Notify::peerUpdatedDelayed(
 | 
				
			||||||
			main->unreadCountChanged(this);
 | 
								peer,
 | 
				
			||||||
 | 
								Notify::PeerUpdate::Flag::UnreadViewChanged);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void History::setUnreadMark(bool unread) {
 | 
				
			||||||
 | 
						if (_unreadMark != unread) {
 | 
				
			||||||
 | 
							_unreadMark = unread;
 | 
				
			||||||
 | 
							if (!_unreadCount || !*_unreadCount) {
 | 
				
			||||||
 | 
								if (inChatList(Dialogs::Mode::All)) {
 | 
				
			||||||
 | 
									const auto delta = _unreadMark ? 1 : -1;
 | 
				
			||||||
 | 
									App::histories().unreadIncrement(delta, mute());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									updateChatListEntry();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							Notify::peerUpdatedDelayed(
 | 
				
			||||||
 | 
								peer,
 | 
				
			||||||
 | 
								Notify::PeerUpdate::Flag::UnreadViewChanged);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool History::unreadMark() const {
 | 
				
			||||||
 | 
						return _unreadMark;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void History::changeUnreadCount(int delta) {
 | 
					void History::changeUnreadCount(int delta) {
 | 
				
			||||||
| 
						 | 
					@ -1733,8 +1772,8 @@ bool History::changeMute(bool newMute) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (inChatList(Dialogs::Mode::All)) {
 | 
						if (inChatList(Dialogs::Mode::All)) {
 | 
				
			||||||
		if (_unreadCount && *_unreadCount) {
 | 
							if (const auto count = historiesUnreadCount()) {
 | 
				
			||||||
			App::histories().unreadMuteChanged(*_unreadCount, _mute);
 | 
								App::histories().unreadMuteChanged(count, _mute);
 | 
				
			||||||
			Notify::unreadCounterUpdated();
 | 
								Notify::unreadCounterUpdated();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Notify::historyMuteUpdated(this);
 | 
							Notify::historyMuteUpdated(this);
 | 
				
			||||||
| 
						 | 
					@ -1947,8 +1986,7 @@ not_null<HistoryItem*> History::addNewInTheMiddle(
 | 
				
			||||||
	return item;
 | 
						return item;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int History::chatListUnreadCount() const {
 | 
					History *History::migrateSibling() const {
 | 
				
			||||||
	const auto result = unreadCount();
 | 
					 | 
				
			||||||
	const auto addFromId = [&] {
 | 
						const auto addFromId = [&] {
 | 
				
			||||||
		if (const auto from = peer->migrateFrom()) {
 | 
							if (const auto from = peer->migrateFrom()) {
 | 
				
			||||||
			return from->id;
 | 
								return from->id;
 | 
				
			||||||
| 
						 | 
					@ -1957,12 +1995,26 @@ int History::chatListUnreadCount() const {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return PeerId(0);
 | 
							return PeerId(0);
 | 
				
			||||||
	}();
 | 
						}();
 | 
				
			||||||
	if (const auto migrated = App::historyLoaded(addFromId)) {
 | 
						return App::historyLoaded(addFromId);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int History::chatListUnreadCount() const {
 | 
				
			||||||
 | 
						const auto result = unreadCount();
 | 
				
			||||||
 | 
						if (const auto migrated = migrateSibling()) {
 | 
				
			||||||
		return result + migrated->unreadCount();
 | 
							return result + migrated->unreadCount();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool History::chatListUnreadMark() const {
 | 
				
			||||||
 | 
						if (unreadMark()) {
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						} else if (const auto migrated = migrateSibling()) {
 | 
				
			||||||
 | 
							return migrated->unreadMark();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool History::chatListMutedBadge() const {
 | 
					bool History::chatListMutedBadge() const {
 | 
				
			||||||
	return mute();
 | 
						return mute();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2201,6 +2253,7 @@ void History::applyDialog(const MTPDdialog &data) {
 | 
				
			||||||
		data.vread_inbox_max_id.v,
 | 
							data.vread_inbox_max_id.v,
 | 
				
			||||||
		data.vread_outbox_max_id.v);
 | 
							data.vread_outbox_max_id.v);
 | 
				
			||||||
	applyDialogTopMessage(data.vtop_message.v);
 | 
						applyDialogTopMessage(data.vtop_message.v);
 | 
				
			||||||
 | 
						setUnreadMark(data.is_unread_mark());
 | 
				
			||||||
	setUnreadMentionsCount(data.vunread_mentions_count.v);
 | 
						setUnreadMentionsCount(data.vunread_mentions_count.v);
 | 
				
			||||||
	if (const auto channel = peer->asChannel()) {
 | 
						if (const auto channel = peer->asChannel()) {
 | 
				
			||||||
		if (data.has_pts()) {
 | 
							if (data.has_pts()) {
 | 
				
			||||||
| 
						 | 
					@ -2650,10 +2703,11 @@ void History::applyGroupAdminChanges(
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void History::changedInChatListHook(Dialogs::Mode list, bool added) {
 | 
					void History::changedInChatListHook(Dialogs::Mode list, bool added) {
 | 
				
			||||||
	if (list == Dialogs::Mode::All && unreadCount()) {
 | 
						if (list == Dialogs::Mode::All) {
 | 
				
			||||||
		const auto delta = added ? unreadCount() : -unreadCount();
 | 
							if (const auto delta = historiesUnreadCount() * (added ? 1 : -1)) {
 | 
				
			||||||
			App::histories().unreadIncrement(delta, mute());
 | 
								App::histories().unreadIncrement(delta, mute());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void History::changedChatListPinHook() {
 | 
					void History::changedChatListPinHook() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,6 +213,9 @@ public:
 | 
				
			||||||
	bool unreadCountKnown() const;
 | 
						bool unreadCountKnown() const;
 | 
				
			||||||
	void setUnreadCount(int newUnreadCount);
 | 
						void setUnreadCount(int newUnreadCount);
 | 
				
			||||||
	void changeUnreadCount(int delta);
 | 
						void changeUnreadCount(int delta);
 | 
				
			||||||
 | 
						void setUnreadMark(bool unread);
 | 
				
			||||||
 | 
						bool unreadMark() const;
 | 
				
			||||||
 | 
						int historiesUnreadCount() const; // unreadCount || unreadMark ? 1 : 0.
 | 
				
			||||||
	bool mute() const;
 | 
						bool mute() const;
 | 
				
			||||||
	bool changeMute(bool newMute);
 | 
						bool changeMute(bool newMute);
 | 
				
			||||||
	void addUnreadBar();
 | 
						void addUnreadBar();
 | 
				
			||||||
| 
						 | 
					@ -322,6 +325,7 @@ public:
 | 
				
			||||||
	HistoryItemsList validateForwardDraft();
 | 
						HistoryItemsList validateForwardDraft();
 | 
				
			||||||
	void setForwardDraft(MessageIdsList &&items);
 | 
						void setForwardDraft(MessageIdsList &&items);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						History *migrateSibling() const;
 | 
				
			||||||
	bool useProxyPromotion() const override;
 | 
						bool useProxyPromotion() const override;
 | 
				
			||||||
	void updateChatListExistence() override;
 | 
						void updateChatListExistence() override;
 | 
				
			||||||
	bool shouldBeInChatList() const override;
 | 
						bool shouldBeInChatList() const override;
 | 
				
			||||||
| 
						 | 
					@ -329,6 +333,7 @@ public:
 | 
				
			||||||
		return !mute();
 | 
							return !mute();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	int chatListUnreadCount() const override;
 | 
						int chatListUnreadCount() const override;
 | 
				
			||||||
 | 
						bool chatListUnreadMark() const override;
 | 
				
			||||||
	bool chatListMutedBadge() const override;
 | 
						bool chatListMutedBadge() const override;
 | 
				
			||||||
	HistoryItem *chatsListItem() const override;
 | 
						HistoryItem *chatsListItem() const override;
 | 
				
			||||||
	const QString &chatsListName() const override;
 | 
						const QString &chatsListName() const override;
 | 
				
			||||||
| 
						 | 
					@ -492,6 +497,7 @@ private:
 | 
				
			||||||
	base::optional<int> _unreadMentionsCount;
 | 
						base::optional<int> _unreadMentionsCount;
 | 
				
			||||||
	base::flat_set<MsgId> _unreadMentions;
 | 
						base::flat_set<MsgId> _unreadMentions;
 | 
				
			||||||
	base::optional<HistoryItem*> _lastMessage;
 | 
						base::optional<HistoryItem*> _lastMessage;
 | 
				
			||||||
 | 
						bool _unreadMark = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// A pointer to the block that is currently being built.
 | 
						// A pointer to the block that is currently being built.
 | 
				
			||||||
	// We hold this pointer so we can destroy it while building
 | 
						// We hold this pointer so we can destroy it while building
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -641,6 +641,7 @@ HistoryWidget::HistoryWidget(
 | 
				
			||||||
	using UpdateFlag = Notify::PeerUpdate::Flag;
 | 
						using UpdateFlag = Notify::PeerUpdate::Flag;
 | 
				
			||||||
	auto changes = UpdateFlag::ChannelRightsChanged
 | 
						auto changes = UpdateFlag::ChannelRightsChanged
 | 
				
			||||||
		| UpdateFlag::UnreadMentionsChanged
 | 
							| UpdateFlag::UnreadMentionsChanged
 | 
				
			||||||
 | 
							| UpdateFlag::UnreadViewChanged
 | 
				
			||||||
		| UpdateFlag::MigrationChanged
 | 
							| UpdateFlag::MigrationChanged
 | 
				
			||||||
		| UpdateFlag::RestrictionReasonChanged
 | 
							| UpdateFlag::RestrictionReasonChanged
 | 
				
			||||||
		| UpdateFlag::ChannelPinnedChanged
 | 
							| UpdateFlag::ChannelPinnedChanged
 | 
				
			||||||
| 
						 | 
					@ -659,6 +660,9 @@ HistoryWidget::HistoryWidget(
 | 
				
			||||||
			if (update.flags & UpdateFlag::UnreadMentionsChanged) {
 | 
								if (update.flags & UpdateFlag::UnreadMentionsChanged) {
 | 
				
			||||||
				updateUnreadMentionsVisibility();
 | 
									updateUnreadMentionsVisibility();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if (update.flags & UpdateFlag::UnreadViewChanged) {
 | 
				
			||||||
 | 
									unreadCountUpdated();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if (update.flags & UpdateFlag::MigrationChanged) {
 | 
								if (update.flags & UpdateFlag::MigrationChanged) {
 | 
				
			||||||
				if (auto channel = _peer->migrateTo()) {
 | 
									if (auto channel = _peer->migrateTo()) {
 | 
				
			||||||
					Ui::showPeerHistory(channel, ShowAtUnreadMsgId);
 | 
										Ui::showPeerHistory(channel, ShowAtUnreadMsgId);
 | 
				
			||||||
| 
						 | 
					@ -1913,7 +1917,19 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		unreadCountChanged(_history); // set _historyDown badge.
 | 
							if (_history->chatListUnreadMark()) {
 | 
				
			||||||
 | 
								Auth().api().changeDialogUnreadMark(_history, false);
 | 
				
			||||||
 | 
								if (_migrated) {
 | 
				
			||||||
 | 
									Auth().api().changeDialogUnreadMark(_migrated, false);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Must be done before unreadCountUpdated(), or we auto-close.
 | 
				
			||||||
 | 
								_history->setUnreadMark(false);
 | 
				
			||||||
 | 
								if (_migrated) {
 | 
				
			||||||
 | 
									_migrated->setUnreadMark(false);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							unreadCountUpdated(); // set _historyDown badge.
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		_topBar->setActiveChat(Dialogs::Key());
 | 
							_topBar->setActiveChat(Dialogs::Key());
 | 
				
			||||||
		updateTopBarSelection();
 | 
							updateTopBarSelection();
 | 
				
			||||||
| 
						 | 
					@ -2366,8 +2382,15 @@ void HistoryWidget::historyToDown(History *history) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HistoryWidget::unreadCountChanged(not_null<History*> history) {
 | 
					void HistoryWidget::unreadCountUpdated() {
 | 
				
			||||||
	if (history == _history || history == _migrated) {
 | 
						if (_history->chatListUnreadMark()) {
 | 
				
			||||||
 | 
							crl::on_main(this, [=, history = _history] {
 | 
				
			||||||
 | 
								if (history == _history) {
 | 
				
			||||||
 | 
									controller()->showBackFromStack();
 | 
				
			||||||
 | 
									emit cancelled();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		updateHistoryDownVisibility();
 | 
							updateHistoryDownVisibility();
 | 
				
			||||||
		_historyDown->setUnreadCount(_history->chatListUnreadCount());
 | 
							_historyDown->setUnreadCount(_history->chatListUnreadCount());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2376,7 +2399,9 @@ void HistoryWidget::unreadCountChanged(not_null<History*> history) {
 | 
				
			||||||
bool HistoryWidget::messagesFailed(const RPCError &error, mtpRequestId requestId) {
 | 
					bool HistoryWidget::messagesFailed(const RPCError &error, mtpRequestId requestId) {
 | 
				
			||||||
	if (MTP::isDefaultHandledError(error)) return false;
 | 
						if (MTP::isDefaultHandledError(error)) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (error.type() == qstr("CHANNEL_PRIVATE") || error.type() == qstr("CHANNEL_PUBLIC_GROUP_NA") || error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
 | 
						if (error.type() == qstr("CHANNEL_PRIVATE")
 | 
				
			||||||
 | 
							|| error.type() == qstr("CHANNEL_PUBLIC_GROUP_NA")
 | 
				
			||||||
 | 
							|| error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
 | 
				
			||||||
		auto was = _peer;
 | 
							auto was = _peer;
 | 
				
			||||||
		controller()->showBackFromStack();
 | 
							controller()->showBackFromStack();
 | 
				
			||||||
		Ui::show(Box<InformBox>(lang((was && was->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
 | 
							Ui::show(Box<InformBox>(lang((was && was->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -211,7 +211,6 @@ public:
 | 
				
			||||||
		not_null<History*> history,
 | 
							not_null<History*> history,
 | 
				
			||||||
		not_null<HistoryItem*> item);
 | 
							not_null<HistoryItem*> item);
 | 
				
			||||||
	void historyToDown(History *history);
 | 
						void historyToDown(History *history);
 | 
				
			||||||
	void unreadCountChanged(not_null<History*> history);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QRect historyRect() const;
 | 
						QRect historyRect() const;
 | 
				
			||||||
	void pushTabbedSelectorToThirdSection(
 | 
						void pushTabbedSelectorToThirdSection(
 | 
				
			||||||
| 
						 | 
					@ -449,6 +448,7 @@ private:
 | 
				
			||||||
	void forwardItems(MessageIdsList &&items);
 | 
						void forwardItems(MessageIdsList &&items);
 | 
				
			||||||
	void handleHistoryChange(not_null<const History*> history);
 | 
						void handleHistoryChange(not_null<const History*> history);
 | 
				
			||||||
	void refreshAboutProxyPromotion();
 | 
						void refreshAboutProxyPromotion();
 | 
				
			||||||
 | 
						void unreadCountUpdated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void highlightMessage(MsgId universalMessageId);
 | 
						void highlightMessage(MsgId universalMessageId);
 | 
				
			||||||
	void adjustHighlightedMessageToMigrated();
 | 
						void adjustHighlightedMessageToMigrated();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1275,10 +1275,6 @@ Dialogs::IndexedList *MainWidget::contactsNoDialogsList() {
 | 
				
			||||||
	return _dialogs->contactsNoDialogsList();
 | 
						return _dialogs->contactsNoDialogsList();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::unreadCountChanged(not_null<History*> history) {
 | 
					 | 
				
			||||||
	_history->unreadCountChanged(history);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TimeMs MainWidget::highlightStartTime(not_null<const HistoryItem*> item) const {
 | 
					TimeMs MainWidget::highlightStartTime(not_null<const HistoryItem*> item) const {
 | 
				
			||||||
	return _history->highlightStartTime(item);
 | 
						return _history->highlightStartTime(item);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4634,8 +4630,14 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case mtpc_updateDialogUnreadMark: {
 | 
						case mtpc_updateDialogUnreadMark: {
 | 
				
			||||||
		const auto &data = update.c_updateDialogUnreadMark();
 | 
							const auto &data = update.c_updateDialogUnreadMark();
 | 
				
			||||||
		if (data.is_unread()) {
 | 
							const auto history = data.vpeer.match(
 | 
				
			||||||
			// #TODO dialog_unread
 | 
							[&](const MTPDdialogPeer &data) {
 | 
				
			||||||
 | 
								const auto peerId = peerFromMTP(data.vpeer);
 | 
				
			||||||
 | 
								return App::historyLoaded(peerId);
 | 
				
			||||||
 | 
							//}, [&](const MTPDdialogPeerFeed &data) { // #feed
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							if (history) {
 | 
				
			||||||
 | 
								history->setUnreadMark(data.is_unread());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} break;
 | 
						} break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -222,8 +222,6 @@ public:
 | 
				
			||||||
	Dialogs::IndexedList *dialogsList();
 | 
						Dialogs::IndexedList *dialogsList();
 | 
				
			||||||
	Dialogs::IndexedList *contactsNoDialogsList();
 | 
						Dialogs::IndexedList *contactsNoDialogsList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void unreadCountChanged(not_null<History*> history);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// While HistoryInner is not HistoryView::ListWidget.
 | 
						// While HistoryInner is not HistoryView::ListWidget.
 | 
				
			||||||
	TimeMs highlightStartTime(not_null<const HistoryItem*> item) const;
 | 
						TimeMs highlightStartTime(not_null<const HistoryItem*> item) const;
 | 
				
			||||||
	bool historyInSelectionMode() const;
 | 
						bool historyInSelectionMode() const;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,13 +37,14 @@ struct PeerUpdate {
 | 
				
			||||||
		MigrationChanged          = (1 << 6),
 | 
							MigrationChanged          = (1 << 6),
 | 
				
			||||||
		PinnedChanged             = (1 << 7),
 | 
							PinnedChanged             = (1 << 7),
 | 
				
			||||||
		RestrictionReasonChanged  = (1 << 8),
 | 
							RestrictionReasonChanged  = (1 << 8),
 | 
				
			||||||
 | 
							UnreadViewChanged         = (1 << 9),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// For chats and channels
 | 
							// For chats and channels
 | 
				
			||||||
		InviteLinkChanged         = (1 << 9),
 | 
							InviteLinkChanged         = (1 << 10),
 | 
				
			||||||
		MembersChanged            = (1 << 10),
 | 
							MembersChanged            = (1 << 11),
 | 
				
			||||||
		AdminsChanged             = (1 << 11),
 | 
							AdminsChanged             = (1 << 12),
 | 
				
			||||||
		BannedUsersChanged        = (1 << 12),
 | 
							BannedUsersChanged        = (1 << 13),
 | 
				
			||||||
		UnreadMentionsChanged     = (1 << 13),
 | 
							UnreadMentionsChanged     = (1 << 14),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// For users
 | 
							// For users
 | 
				
			||||||
		UserCanShareContact       = (1 << 16),
 | 
							UserCanShareContact       = (1 << 16),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,7 @@ private:
 | 
				
			||||||
	void addPinToggle();
 | 
						void addPinToggle();
 | 
				
			||||||
	void addInfo();
 | 
						void addInfo();
 | 
				
			||||||
	void addSearch();
 | 
						void addSearch();
 | 
				
			||||||
 | 
						void addToggleUnreadMark();
 | 
				
			||||||
	void addUserActions(not_null<UserData*> user);
 | 
						void addUserActions(not_null<UserData*> user);
 | 
				
			||||||
	void addBlockUser(not_null<UserData*> user);
 | 
						void addBlockUser(not_null<UserData*> user);
 | 
				
			||||||
	void addChatActions(not_null<ChatData*> chat);
 | 
						void addChatActions(not_null<ChatData*> chat);
 | 
				
			||||||
| 
						 | 
					@ -229,6 +230,48 @@ void Filler::addSearch() {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Filler::addToggleUnreadMark() {
 | 
				
			||||||
 | 
						const auto peer = _peer;
 | 
				
			||||||
 | 
						const auto isUnread = [](not_null<PeerData*> peer) {
 | 
				
			||||||
 | 
							if (const auto history = App::historyLoaded(peer)) {
 | 
				
			||||||
 | 
								return (history->chatListUnreadCount() > 0)
 | 
				
			||||||
 | 
									|| (history->chatListUnreadMark());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						const auto label = [=](not_null<PeerData*> peer) {
 | 
				
			||||||
 | 
							return lang(isUnread(peer)
 | 
				
			||||||
 | 
								? lng_context_mark_read
 | 
				
			||||||
 | 
								: lng_context_mark_unread);
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						auto action = _addAction(label(peer), [=] {
 | 
				
			||||||
 | 
							const auto markAsRead = isUnread(peer);
 | 
				
			||||||
 | 
							const auto handle = [&](not_null<History*> history) {
 | 
				
			||||||
 | 
								if (markAsRead) {
 | 
				
			||||||
 | 
									Auth().api().readServerHistory(history);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									Auth().api().changeDialogUnreadMark(history, !markAsRead);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							const auto history = App::history(peer);
 | 
				
			||||||
 | 
							handle(history);
 | 
				
			||||||
 | 
							if (markAsRead) {
 | 
				
			||||||
 | 
								if (const auto migrated = history->migrateSibling()) {
 | 
				
			||||||
 | 
									handle(migrated);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto lifetime = Notify::PeerUpdateViewer(
 | 
				
			||||||
 | 
							_peer,
 | 
				
			||||||
 | 
							Notify::PeerUpdate::Flag::UnreadViewChanged
 | 
				
			||||||
 | 
						) | rpl::start_with_next([=] {
 | 
				
			||||||
 | 
							action->setText(label(peer));
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Ui::AttachAsChild(action, std::move(lifetime));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Filler::addBlockUser(not_null<UserData*> user) {
 | 
					void Filler::addBlockUser(not_null<UserData*> user) {
 | 
				
			||||||
	auto blockText = [](not_null<UserData*> user) {
 | 
						auto blockText = [](not_null<UserData*> user) {
 | 
				
			||||||
		return lang(user->isBlocked()
 | 
							return lang(user->isBlocked()
 | 
				
			||||||
| 
						 | 
					@ -401,6 +444,7 @@ void Filler::fill() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (_source == PeerMenuSource::ChatsList) {
 | 
						if (_source == PeerMenuSource::ChatsList) {
 | 
				
			||||||
		addSearch();
 | 
							addSearch();
 | 
				
			||||||
 | 
							addToggleUnreadMark();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (const auto user = _peer->asUser()) {
 | 
						if (const auto user = _peer->asUser()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue