···
/// - Loading, empty, and error states
/// - Automatic comment loading on screen init
class PostDetailScreen extends StatefulWidget {
+
const PostDetailScreen({
+
this.isOptimistic = false,
/// Post to display (passed via route extras)
···
class _PostDetailScreenState extends State<PostDetailScreen> {
+
// ScrollController created lazily with cached scroll position for instant restoration
+
late ScrollController _scrollController;
final GlobalKey _commentsHeaderKey = GlobalKey();
// Cached provider from CommentsProviderCache
···
+
// ScrollController and provider initialization moved to didChangeDependencies
+
// where we have access to context for synchronous provider acquisition
+
void didChangeDependencies() {
+
super.didChangeDependencies();
+
// Initialize provider synchronously on first call (has context access)
+
// This ensures cached data is available for the first build, avoiding
+
// the flash from loading state → content → scroll position jump
+
_initializeProviderSync();
/// Listen for auth state changes to handle sign-out
···
// If user signed out while viewing this screen, navigate back
// The CommentsProviderCache has already disposed our provider
+
if (!authProvider.isAuthenticated &&
+
!_providerInvalidated) {
_providerInvalidated = true;
···
+
/// Initialize provider synchronously from cache
+
/// Called from didChangeDependencies to ensure cached data is available
+
/// for the first build. Creates ScrollController with initialScrollOffset
+
/// set to cached position for instant scroll restoration without flicker.
+
void _initializeProviderSync() {
// Get or create provider from cache
final cache = context.read<CommentsProviderCache>();
···
postCid: widget.post.post.cid,
+
// Create scroll controller with cached position for instant restoration
+
// This avoids the flash: loading → content at top → jump to cached position
+
final cachedScrollPosition = _commentsProvider.scrollPosition;
+
_scrollController = ScrollController(
+
initialScrollOffset: cachedScrollPosition,
+
_scrollController.addListener(_onScroll);
+
if (kDebugMode && cachedScrollPosition > 0) {
+
'📍 Created ScrollController with initial offset: $cachedScrollPosition',
// Listen for changes to trigger rebuilds
_commentsProvider.addListener(_onProviderChanged);
+
// Mark as initialized before triggering any loads
+
// This ensures the first build shows content (not loading) when cached
// Skip loading for optimistic posts (just created, not yet indexed)
if (widget.isOptimistic) {
···
// Don't load comments - there won't be any yet
} else if (_commentsProvider.comments.isNotEmpty) {
+
// Already have cached data - it will render immediately
'📦 Using cached comments (${_commentsProvider.comments.length})',
+
// Background refresh if data is stale (won't cause flicker)
if (_commentsProvider.isStale) {
debugPrint('🔄 Data stale, refreshing in background');
···
// No cached data - load fresh
_commentsProvider.loadComments(refresh: true);
···
/// Handle sort changes from dropdown