fix(desktop): hydrate pinned sessions outside recents - #74760
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for tracing the cold-start path; the current main code does leave local pins pending until a matching session row is loaded (apps/desktop/src/store/session-pin-sync.ts:122-137), so the underlying issue is real.
Problems
apps/desktop/src/app/session/hooks/pinned-session-hydration.ts:53converts a realpinned:falseintoundefined. That bypasses the backend-authoritative unpin branch inapps/desktop/src/store/session-pin-sync.ts:84-91; reconciliation then retains the local pin and scheduleswritePin(..., true, ...)at lines 122-137. A stale local browser pin can therefore re-pin a session another app intentionally unpinned.apps/desktop/src/app/session/hooks/use-session-list-actions.ts:189-192omitsresult.messaging.sessions, although messaging sessions are pin-capable (apps/desktop/src/app/chat/sidebar/session-index.ts:6-15). A row already loaded in the messaging slice is re-fetched and appended to recents at line 215.
Suggested changes
- Keep explicit
falseauthoritative; use a clearly bounded migration mechanism if legacy local pins need initial precedence. - Include the messaging slice in the loaded-ID check and cover both cases in the hook path.
This is an automated hermes-sweeper review.
| // the local pin before watchSessionPins can PATCH it true. | ||
| return { | ||
| ...session, | ||
| pinned: session.pinned === true ? true : undefined, |
There was a problem hiding this comment.
false is meaningful server truth: pullRemotePins() currently removes a held local pin for a loaded pinned:false row (apps/desktop/src/store/session-pin-sync.ts:84-91). Rewriting it to undefined skips that branch and lets the pending-push path write pinned:true, reasserting a pin another app may have intentionally removed. Preserve false, or gate legacy migration with explicit one-time state.
| // increase to the normal recents page size. | ||
| const pinIds = $pinnedSessionIds.get() | ||
|
|
||
| const missingPinIds = missingPinnedSessionIds(pinIds, [ |
There was a problem hiding this comment.
Messaging is also a pin-capable sidebar slice, but it is omitted from this loaded-row check. A pin already present in result.messaging.sessions will be fetched again and then merged into the recents store. Include the messaging rows here or retain hydrated rows in their source slice.
|
Superseded by #80711. Pins past the recents page are back-filled by the list endpoint and no longer sliced off on the client. |
Summary
Verification
npm run typecheck --workspace apps/desktopnpm run test:ui --workspace apps/desktop -- --run src/app/session/hooks/pinned-session-hydration.test.ts src/store/session.test.ts src/store/session-pin-sync.test.ts— 48 passednpm run build --workspace apps/desktopLinear: HER-119
No merge or production installation performed.