code
Clone this repository
https://tangled.org/bretton.dev/coves-mobile
git@knot.bretton.dev:bretton.dev/coves-mobile
For self-hosted knots, clone URLs may differ based on your setup.
Addresses code quality checks from CODE_QUALITY_GUIDE.md:
- Use cascade notation where appropriate (cascade_invocations)
- Put control body on separate line (always_put_control_body_on_new_line)
- Break long string to stay under 80 chars (lines_longer_than_80_chars)
- Apply dart format to all changed files
All files now pass:
- dart format --output=none --set-exit-if-changed
- flutter analyze (0 issues)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates provider registration to use MultiFeedProvider instead of
FeedProvider. The new provider is initialized with:
- CovesApiService for API calls
- AuthProvider for auth state and session identity
- VoteProvider for vote state initialization from feed responses
Also includes pubspec.lock updates from dependency resolution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates widget tests for the new MultiFeedProvider architecture:
- FakeMultiFeedProvider replaces FakeFeedProvider
- Supports per-feed state management (FeedType parameter)
- Uses sentinel-compatible copyWith for state mutations
- Tests cover both authenticated and unauthenticated flows
- Tests for PageView swipe navigation when authenticated
- Tests for single-feed display when not authenticated
Removes orphaned test/providers/feed_provider_test.dart that
referenced the deleted FeedProvider.
Updates test/widget_test.dart counter test with provider setup.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Refactors FeedScreen to work with MultiFeedProvider and adds several
UX and reliability improvements:
PageView for feed switching:
- Authenticated users can swipe between Discover and For You
- Unauthenticated users see only Discover (no PageView)
- Per-feed ScrollControllers with position restoration
Auth state synchronization:
- Listens to AuthProvider changes
- Jumps PageController to page 0 on sign-out to match provider state
- Prevents tab/page mismatch after re-authentication
Lazy feed loading (_ensureFeedLoaded):
- Triggers initial load when switching to an unloaded feed
- Handles case where user signs in after app start and taps For You
- Called from both tab tap and swipe navigation
This fixes issues where:
- For You tab showed empty state after signing in mid-session
- PageController stayed on page 1 after sign-out while provider
switched to Discover, causing misalignment on re-auth
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extracts feed rendering logic into a reusable FeedPage widget that
handles all feed states:
- Loading: Centered CircularProgressIndicator
- Error: User-friendly message with Retry button
- Empty: Contextual message based on auth state
- Posts: ListView.builder with pagination support
Key improvements:
- Empty state now wrapped in RefreshIndicator with CustomScrollView
and SliverFillRemaining, allowing pull-to-refresh when feed is empty
- Error messages are user-friendly (maps technical errors to readable text)
- Loading more indicator at list bottom during pagination
- Proper scroll controller integration for infinite scroll
This fixes an issue where unauthenticated users with an empty Discover
feed had no way to retry without restarting the app.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaces FeedProvider with MultiFeedProvider that manages separate
state for Discover and For You feeds. Key improvements:
Architecture:
- Per-feed state management using Map<FeedType, FeedState>
- Centralized _fetchFeed helper eliminates code duplication
- Auth-aware feed switching (For You requires authentication)
- Minute-based time updates for relative timestamps
Security (cross-session data leak prevention):
- Captures session DID before fetch to detect auth changes
- Discards For You responses if session changed during fetch
- Guards both success and error paths to prevent stale data
- Removes feed state entirely on session change (not copyWith)
This prevents scenarios where:
- User signs out during fetch → old data reappears
- User A signs out, User B signs in → User A's feed shown to B
- Fetch errors after sign-out → stale posts restored
Removes the old single-feed FeedProvider.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces FeedState as an immutable state container for per-feed data
(Discover and For You feeds). Key features:
- Holds posts, cursor, loading states, error, scroll position, and
last refresh time
- Uses sentinel pattern for copyWith to distinguish "not provided"
from "explicitly set to null" for nullable fields (cursor, error,
lastRefreshTime)
- Enables proper clearing of fields on refresh/error recovery
The sentinel pattern fixes a bug where nullable fields couldn't be
cleared back to null through copyWith - critical for pagination
cursor handling when reaching the end of a feed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>