You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(llc, core, ui): isolate channel state from sub-route wraps and smooth thread-open scroll
A small cluster of related issues that surfaced together while
investigating thread-page UX. All four are independent bugs touching
the LLC, core, and the vendored SPL.
- `Channel.getMessagesById` was merging fetched messages into
`ChannelState.messages` as a side effect. Resolving a thread parent
for an in-channel reply would silently inject the parent into the
loaded channel window, typically at index 0. The fetch is now pure
— callers that want to refresh the loaded window can pipe the
response through `ChannelClientState.updateMessage`.
- `StreamChannel.getMessage` previously hit the network for any
message not in `channel.state.messages`, ignoring thread replies
and pinned messages. Cache lookup now also scans
`channel.state.threads.values` and `channel.state.pinnedMessages`.
- Added `StreamChannel.value` constructor for wrapping an
already-initialized channel purely to expose it via
`StreamChannel.of` to a sub-route or overlay (thread page, channel
info screen, long-press modal, attachment viewer). Skips the
channel-page positioning the default constructor runs, which would
otherwise overwrite the parent route's loaded window.
- `MessageListCore` no longer reloads the parent channel from its
dispose path when the disposing instance is in thread mode — a
thread's lifecycle shouldn't be touching the channel's loaded
window.
- `MessageListCore` no longer refetches thread replies on first
attach when `state.threads[parentId]` is already populated.
WebSocket events keep that cache live; the redundant fetch caused
a merge-rebuild flicker on warm cache.
- `ScrollablePositionedList._startScroll` waits one frame for
`itemPositions` to be published when it's empty. Previously a
`scrollTo` requested from a post-frame callback right after mount
would fall through to the dual-controller teleport path even for
nearby targets, fake-scrolling two screens for what should have
been a short animation. Matches the Compose `LazyListState`
pattern of suspending until first composition before scrolling.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments