mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-20 08:03:45 +08:00
Derive the pinned bar's topic root from the thread
Task: 2026/08/19/align-replies-thread-shared-media-attribution
This commit is contained in:
@@ -320,7 +320,7 @@ void TopControls::updatePinnedViewer() {
|
||||
const auto fullHistory = !_repliesRootId && !_topic && !_sublist;
|
||||
_minPinnedId = Data::ResolveMinPinnedId(
|
||||
_history->peer,
|
||||
fullHistory ? MsgId(0) : _repliesRootId,
|
||||
activeThread()->topicRootId(),
|
||||
fullHistory ? PeerId(0) : _monoforumPeerId,
|
||||
migrated);
|
||||
}
|
||||
@@ -737,12 +737,13 @@ void TopControls::setupPinnedTracker() {
|
||||
checkPinnedBarState();
|
||||
return;
|
||||
}
|
||||
const auto topicRootId = thread->topicRootId();
|
||||
|
||||
SharedMediaViewer(
|
||||
&_history->session(),
|
||||
Storage::SharedMediaKey(
|
||||
_history->peer->id,
|
||||
_repliesRootId,
|
||||
topicRootId,
|
||||
_monoforumPeerId,
|
||||
Storage::SharedMediaType::Pinned,
|
||||
ServerMaxMsgId - 1),
|
||||
@@ -757,13 +758,13 @@ void TopControls::setupPinnedTracker() {
|
||||
const auto peerId = _history->peer->id;
|
||||
const auto hiddenId = settings.hiddenPinnedMessageId(
|
||||
peerId,
|
||||
_repliesRootId,
|
||||
topicRootId,
|
||||
_monoforumPeerId);
|
||||
const auto last = result.size() ? result[result.size() - 1] : 0;
|
||||
if (hiddenId && hiddenId != last) {
|
||||
settings.setHiddenPinnedMessageId(
|
||||
peerId,
|
||||
_repliesRootId,
|
||||
topicRootId,
|
||||
_monoforumPeerId,
|
||||
0);
|
||||
_history->session().saveSettingsDelayed();
|
||||
@@ -778,7 +779,7 @@ void TopControls::checkPinnedBarState() {
|
||||
|
||||
const auto fullHistory = !_repliesRootId && !_topic && !_sublist;
|
||||
const auto migrated = migratedPeer();
|
||||
const auto topicRootId = fullHistory ? MsgId(0) : _repliesRootId;
|
||||
const auto topicRootId = activeThread()->topicRootId();
|
||||
const auto monoforumPeerId = fullHistory ? PeerId(0) : _monoforumPeerId;
|
||||
const auto hiddenId = _history->peer->canPinMessages()
|
||||
? MsgId(0)
|
||||
@@ -1061,7 +1062,7 @@ void TopControls::hidePinnedMessage() {
|
||||
Window::HidePinnedBar(
|
||||
_controller,
|
||||
_history->peer,
|
||||
fullHistory ? MsgId(0) : _repliesRootId,
|
||||
activeThread()->topicRootId(),
|
||||
fullHistory ? PeerId(0) : _monoforumPeerId,
|
||||
crl::guard(_wrap.get(), [=] {
|
||||
if (_pinnedTracker) {
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# The pinned bar's topic root comes from the active thread
|
||||
|
||||
`HistoryView::Controls::TopControls` built the `Storage::SharedMediaType::Pinned`
|
||||
key triple from its own `_repliesRootId` field. For a channel-comments thread —
|
||||
`ChatWidget` in `Mode::Replies` with no `Data::ForumTopic` — that names
|
||||
`(discussionGroup, repliesRootId, 0)`, a key no `Storage::SharedMedia` list can
|
||||
ever hold, while the messages of that thread are indexed under the whole-peer
|
||||
`(discussionGroup, 0, 0)` list. This takes the root from `activeThread()`
|
||||
instead, the same expression `HistoryView::PinnedTracker` — constructed two lines
|
||||
above — and `HistoryView::PinnedWidget` already use.
|
||||
|
||||
The change is behaviour-neutral for every mode that can reach it today.
|
||||
`Data::Thread::topicRootId()` returns `_topic->rootId()` for a forum topic (equal
|
||||
to `_repliesRootId`, which `ChatWidget::lookupTopic()` resolves the topic from),
|
||||
and zero for a plain `History` or a `Data::SavedSublist` (every `ChatViewId` that
|
||||
sets `.sublist` leaves `repliesRootId` at zero). The monoforum half of the key
|
||||
keeps using `_monoforumPeerId`: that field is
|
||||
`(_sublist && _sublist->parentChat()) ? _sublist->sublistPeer()->id : PeerId()`,
|
||||
which deliberately differs from `Data::Thread::monoforumPeerId()` for a Saved
|
||||
Messages sublist, and shared-media storage supports only the monoforum form —
|
||||
`ApiWrap::sharedMediaDone` discards any slice whose `monoforumPeerId` does not
|
||||
resolve through `PeerData::monoforumSublistFor`, and the self peer is not a
|
||||
channel.
|
||||
|
||||
Two things were established while making this change and are worth recording,
|
||||
because both contradict how the defect was originally described.
|
||||
|
||||
The replies-root list is not stale, it is absent. `Storage::SharedMedia` creates
|
||||
a per-thread list only from `SharedMediaAddExisting` and `SharedMediaAddSlice`;
|
||||
`SharedMediaAddNew` and `SharedMediaRemoveOne` only `find` one. Every writer that
|
||||
can pass a non-zero root takes it from `HistoryItem::topic()` or
|
||||
`ForumTopic::rootId()`, and `ApiWrap::sharedMediaDone` returns before storing
|
||||
when `peer->forumTopicFor(topicRootId)` is null. A non-forum discussion group has
|
||||
no forum, so nothing ever creates that list and no removal can decrement it.
|
||||
|
||||
A channel-comments thread has no pinned bar at all. `setupPinnedTracker()` runs
|
||||
only from `subscribeToPinnedMessages()`, which `ChatWidget` calls only for
|
||||
`Mode::History`, for a topic, and for a sublist — never for `Mode::Replies`
|
||||
without a topic. `_pinnedTracker` therefore stays null there for the widget's
|
||||
whole life, and the three other functions that build this key all require it.
|
||||
That matches the pre-migration code, where `ChatWidget::setupPinnedTracker()`
|
||||
opened with `Expects(_topic || _sublist)`.
|
||||
|
||||
The alternative repair — making `HistoryItem::topicRootId()` report the replies
|
||||
root for a reply in a discussion thread — was rejected. It would not have fixed
|
||||
anything, since nothing creates the list either way, and `topicRootId()` also
|
||||
feeds `FullReplyTo`, the serialized `Data::DraftKey`, and the outgoing
|
||||
`top_msg_id` and `f_forum_topic` fields, so it cannot move without changing
|
||||
persisted and protocol behaviour. The repository already carries
|
||||
`HistoryItem::replyToTop()` for the replies root and discriminates between the
|
||||
two in `ApiWrap::exportDirectMessageLink`.
|
||||
|
||||
Rationale, measurements and follow-ups live in the AI task.
|
||||
Reference in New Issue
Block a user