mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
Opening a mobile thread could blank the original message while the app positioned replies. This affected empty and populated threads, including links to a specific reply. Keep one original-message widget mounted and usable throughout positioning. It follows a measured placeholder in the reply list, which becomes visible only at its final position. This preserves media and reaction ownership, supports scrolling through tall originals, and excludes the head from input and accessibility when it leaves the viewport. ### Validation - Added production-path frame regressions for empty, short, long, and deep-linked threads; two video lifecycle cases verify exactly one initialization and disposal, including completion after navigation away. - Added coverage for dragging, mouse-wheel and accessibility scrolling, removal of offscreen and app-bar-covered head semantics, and scrolling to the interactive bottom of a 70-line original message. Removing the accessibility exclusion or restoring the raw viewport-top boundary fails both long-thread regressions; restoring the duplicated head fails the lifecycle test. - Mobile dependency setup, analysis, the full mobile test suite, and unconfigured-push tests passed. The native iOS simulator debug build passed after integrating main, including the conflict resolution for the new Buzz icon API. The current tree passed 3,076 mobile tests (four skipped) and three unconfigured-push tests, and the updated native simulator build passed. - Exercised empty, three-reply, forty-reply, and older-reply deep-link flows on an iPhone 17 Pro simulator against an isolated local relay with a disposable identity. Confirmed correct head accessibility coordinates and absence when offscreen. The local posterless-video fixture rendered its attachment fallback; native decoding success is not claimed. Resource ownership is covered through the production preview-loader seam. [Updated simulator captures](https://github.com/block/buzz/pull/8134#issuecomment-6047098230). - Added delayed-hydration regressions for mouse-wheel and explicit accessibility scrolling through the persistent head. Both preserve a visible reading anchor across hydration and viewport resizing; removing the user-scroll lifecycle callbacks makes both fail. Repeated empty, populated, and older-reply deep-link opening with the updated native build against the retained isolated relay. - Entered and sent a reply from the disposable simulator identity against the isolated local relay. The app displayed the reply and cleared the composer, and the relay database confirmed persistence. Software keyboard open/close remains unverified because the simulator did not display it. - Agent review feedback was addressed. Personal mobile testing is not applicable under the author's standing exception. Post-merge validation: repeat empty, populated, and deep-linked thread opening in the integrated mobile candidate, including keyboard open/close and sending a reply before release. buzz-review-completed --------- Signed-off-by: Tom Brow <tomb@block.xyz>
25 lines
706 B
Dart
25 lines
706 B
Dart
part of '../thread_detail_page.dart';
|
|
|
|
void _useThreadReplyReadState(
|
|
WidgetRef ref,
|
|
String threadHeadId,
|
|
List<TimelineMessage> replies,
|
|
) {
|
|
final readState = ref.watch(readStateProvider);
|
|
final visibleReplyReadKey = replies
|
|
.map((reply) => '${reply.id}:${reply.createdAt}')
|
|
.join(',');
|
|
|
|
useEffect(() {
|
|
if (!readState.isReady || replies.isEmpty) return null;
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
for (final reply in replies) {
|
|
ref
|
|
.read(readStateProvider.notifier)
|
|
.markContextRead(msgContextKey(reply.id), reply.createdAt);
|
|
}
|
|
});
|
|
return null;
|
|
}, [threadHeadId, readState.isReady, visibleReplyReadKey]);
|
|
}
|