feat(comments): initialize vote state from viewer data, remove VoteService dep

main.dart:
- Remove voteService parameter from FeedProvider and CommentsProvider

CommentsProvider:
- Remove VoteService dependency - vote state from response viewer data
- Add _initializeCommentVoteState helper for recursive vote initialization
- On refresh: initialize all comments (server data is truth)
- On pagination: only initialize new comments (preserve optimistic state)

This completes the migration from VoteService.getUserVotes() to using
viewer state from API responses for both feed posts and comments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+30 -21
lib
-4
lib/main.dart
···
(context) => FeedProvider(
authProvider,
voteProvider: context.read<VoteProvider>(),
-
voteService: voteService,
),
update: (context, auth, vote, previous) {
// Reuse existing provider to maintain state across rebuilds
···
FeedProvider(
auth,
voteProvider: vote,
-
voteService: voteService,
);
},
),
···
(context) => CommentsProvider(
authProvider,
voteProvider: context.read<VoteProvider>(),
-
voteService: voteService,
),
update: (context, auth, vote, previous) {
// Reuse existing provider to maintain state across rebuilds
···
CommentsProvider(
auth,
voteProvider: vote,
-
voteService: voteService,
);
},
),
+30 -17
lib/providers/comments_provider.dart
···
import 'package:flutter/foundation.dart';
import '../models/comment.dart';
import '../services/coves_api_service.dart';
-
import '../services/vote_service.dart';
import 'auth_provider.dart';
import 'vote_provider.dart';
···
this._authProvider, {
CovesApiService? apiService,
VoteProvider? voteProvider,
-
VoteService? voteService,
-
}) : _voteProvider = voteProvider,
-
_voteService = voteService {
+
}) : _voteProvider = voteProvider {
// 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
···
final AuthProvider _authProvider;
late final CovesApiService _apiService;
final VoteProvider? _voteProvider;
-
final VoteService? _voteService;
// Track previous auth state to detect transitions
bool _wasAuthenticated = false;
···
debugPrint('✅ Comments loaded: ${_comments.length} comments total');
}
-
// Load initial vote state from PDS (only if authenticated)
-
if (_authProvider.isAuthenticated &&
-
_voteProvider != null &&
-
_voteService != null) {
-
try {
-
final userVotes = await _voteService.getUserVotes();
-
_voteProvider.loadInitialVotes(userVotes);
-
} on Exception catch (e) {
-
if (kDebugMode) {
-
debugPrint('⚠️ Failed to load vote state: $e');
-
}
-
// Don't fail the comments load if vote loading fails
+
// Initialize vote state from viewer data in comments response
+
if (_authProvider.isAuthenticated && _voteProvider != null) {
+
if (refresh) {
+
// On refresh, initialize all comments - server data is truth
+
_comments.forEach(_initializeCommentVoteState);
+
} else {
+
// On pagination, only initialize newly fetched comments to avoid
+
// overwriting optimistic vote state on existing comments
+
response.comments.forEach(_initializeCommentVoteState);
}
}
···
}
rethrow;
}
+
}
+
+
/// Initialize vote state for a comment and its replies recursively
+
///
+
/// Extracts viewer vote data from comment and initializes VoteProvider state.
+
/// Handles nested replies recursively.
+
///
+
/// IMPORTANT: Always calls setInitialVoteState, even when viewer.vote is
+
/// null. This ensures that if a user removed their vote on another device,
+
/// the local state is cleared on refresh.
+
void _initializeCommentVoteState(ThreadViewComment threadComment) {
+
final viewer = threadComment.comment.viewer;
+
_voteProvider!.setInitialVoteState(
+
postUri: threadComment.comment.uri,
+
voteDirection: viewer?.vote,
+
voteUri: viewer?.voteUri,
+
);
+
+
// Recursively initialize vote state for replies
+
threadComment.replies?.forEach(_initializeCommentVoteState);
}
/// Retry loading after error