style(feed): fix lint warnings and formatting issues

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>

Changed files
+51 -43
lib
test
+17 -12
lib/main.dart
···
authProvider: authProvider,
),
),
-
ChangeNotifierProxyProvider2<AuthProvider, VoteProvider,
-
MultiFeedProvider>(
+
ChangeNotifierProxyProvider2<
+
AuthProvider,
+
VoteProvider,
+
MultiFeedProvider
+
>(
create:
(context) => MultiFeedProvider(
authProvider,
···
// CommentsProviderCache manages per-post CommentsProvider instances
// with LRU eviction and sign-out cleanup
ProxyProvider2<AuthProvider, VoteProvider, CommentsProviderCache>(
-
create: (context) => CommentsProviderCache(
-
authProvider: authProvider,
-
voteProvider: context.read<VoteProvider>(),
-
commentService: commentService,
-
),
+
create:
+
(context) => CommentsProviderCache(
+
authProvider: authProvider,
+
voteProvider: context.read<VoteProvider>(),
+
commentService: commentService,
+
),
update: (context, auth, vote, previous) {
// Reuse existing cache
-
return previous ?? CommentsProviderCache(
-
authProvider: auth,
-
voteProvider: vote,
-
commentService: commentService,
-
);
+
return previous ??
+
CommentsProviderCache(
+
authProvider: auth,
+
voteProvider: vote,
+
commentService: commentService,
+
);
},
dispose: (_, cache) => cache.dispose(),
),
+4 -3
lib/models/feed_state.dart
···
isLoadingMore: isLoadingMore ?? this.isLoadingMore,
error: error == _sentinel ? this.error : error as String?,
scrollPosition: scrollPosition ?? this.scrollPosition,
-
lastRefreshTime: lastRefreshTime == _sentinel
-
? this.lastRefreshTime
-
: lastRefreshTime as DateTime?,
+
lastRefreshTime:
+
lastRefreshTime == _sentinel
+
? this.lastRefreshTime
+
: lastRefreshTime as DateTime?,
);
}
}
+16 -18
lib/providers/multi_feed_provider.dart
···
// Use injected service (for testing) or create new one (for production)
// Pass token getter, refresh handler, and sign out handler to API service
// for automatic fresh token retrieval and automatic token refresh on 401
-
_apiService = apiService ??
+
_apiService =
+
apiService ??
CovesApiService(
tokenGetter: _authProvider.getAccessToken,
tokenRefresher: _authProvider.refreshToken,
···
try {
if (refresh) {
// Start loading, keep existing data visible
-
_feedStates[type] = currentState.copyWith(
-
isLoading: true,
-
error: null,
-
);
+
_feedStates[type] = currentState.copyWith(isLoading: true, error: null);
} else {
// Pagination
-
_feedStates[type] = currentState.copyWith(
-
isLoadingMore: true,
-
);
+
_feedStates[type] = currentState.copyWith(isLoadingMore: true);
}
notifyListeners();
···
return _fetchFeed(
type: type,
refresh: refresh,
-
fetcher: () => _apiService.getTimeline(
-
sort: _sort,
-
timeframe: _timeframe,
-
cursor: refresh ? null : currentState.cursor,
-
),
+
fetcher:
+
() => _apiService.getTimeline(
+
sort: _sort,
+
timeframe: _timeframe,
+
cursor: refresh ? null : currentState.cursor,
+
),
feedName: 'Timeline',
);
}
···
return _fetchFeed(
type: type,
refresh: refresh,
-
fetcher: () => _apiService.getDiscover(
-
sort: _sort,
-
timeframe: _timeframe,
-
cursor: refresh ? null : currentState.cursor,
-
),
+
fetcher:
+
() => _apiService.getDiscover(
+
sort: _sort,
+
timeframe: _timeframe,
+
cursor: refresh ? null : currentState.cursor,
+
),
feedName: 'Discover',
);
}
+9 -7
lib/screens/home/feed_screen.dart
···
/// Switch to a feed type and animate PageView
void _switchToFeedType(FeedType type, int pageIndex) {
-
final provider = context.read<MultiFeedProvider>();
-
provider.setCurrentFeed(type);
+
context.read<MultiFeedProvider>().setCurrentFeed(type);
// Animate to the corresponding page
_pageController.animateToPage(
···
void _restoreScrollPosition(FeedType type) {
// Wait for the next frame to ensure the controller has clients
WidgetsBinding.instance.addPostFrameCallback((_) {
-
if (!mounted) return;
+
if (!mounted) {
+
return;
+
}
final controller = _scrollControllers[type];
if (controller != null && controller.hasClients) {
···
scrollController: _getOrCreateScrollController(feedType),
onRefresh: () => provider.loadFeed(feedType, refresh: true),
onRetry: () => provider.retry(feedType),
-
onClearErrorAndLoadMore: () {
-
provider.clearError(feedType);
-
provider.loadMore(feedType);
-
},
+
onClearErrorAndLoadMore:
+
() =>
+
provider
+
..clearError(feedType)
+
..loadMore(feedType),
isAuthenticated: isAuthenticated,
currentTime: provider.currentTime,
);
+2 -1
lib/widgets/feed_page.dart
···
const SizedBox(height: 8),
Text(
widget.isAuthenticated
-
? 'Subscribe to communities to see posts in your feed'
+
? 'Subscribe to communities to see '
+
'posts in your feed'
: 'Check back later for new posts',
style: const TextStyle(
fontSize: 14,
+3 -2
test/widgets/feed_screen_test.dart
···
tester,
) async {
fakeAuthProvider.setAuthenticated(value: true);
-
fakeFeedProvider.setPosts(FeedType.discover, [_createMockPost('Post 1')]);
-
fakeFeedProvider.setPosts(FeedType.forYou, [_createMockPost('Post 2')]);
+
fakeFeedProvider
+
..setPosts(FeedType.discover, [_createMockPost('Post 1')])
+
..setPosts(FeedType.forYou, [_createMockPost('Post 2')]);
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();