Main coves client
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(feed): initialize vote state from viewer data in feed response

- Remove VoteService dependency - vote state comes from feed response
- Replace getUserVotes + loadInitialVotes with per-post setInitialVoteState
- Use viewer.vote and viewer.voteUri from backend response
- Call setInitialVoteState for ALL posts to handle cross-device vote removal

This fixes the bug where votes would disappear on feed refresh:
1. Backend now populates viewer state from PDS cache
2. Feed provider initializes VoteProvider state from viewer data
3. Score adjustments are cleared to prevent double-counting

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

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

+13 -18
+13 -18
lib/providers/feed_provider.dart
··· 3 3 import 'package:flutter/foundation.dart'; 4 4 import '../models/post.dart'; 5 5 import '../services/coves_api_service.dart'; 6 - import '../services/vote_service.dart'; 7 6 import 'auth_provider.dart'; 8 7 import 'vote_provider.dart'; 9 8 ··· 20 19 this._authProvider, { 21 20 CovesApiService? apiService, 22 21 VoteProvider? voteProvider, 23 - VoteService? voteService, 24 - }) : _voteProvider = voteProvider, 25 - _voteService = voteService { 22 + }) : _voteProvider = voteProvider { 26 23 // Use injected service (for testing) or create new one (for production) 27 24 // Pass token getter, refresh handler, and sign out handler to API service 28 25 // for automatic fresh token retrieval and automatic token refresh on 401 ··· 68 65 final AuthProvider _authProvider; 69 66 late final CovesApiService _apiService; 70 67 final VoteProvider? _voteProvider; 71 - final VoteService? _voteService; 72 68 73 69 // Track previous auth state to detect transitions 74 70 bool _wasAuthenticated = false; ··· 196 192 debugPrint('✅ $feedName loaded: ${_posts.length} posts total'); 197 193 } 198 194 199 - // Load initial vote state from PDS (only if authenticated) 200 - if (_authProvider.isAuthenticated && 201 - _voteProvider != null && 202 - _voteService != null) { 203 - try { 204 - final userVotes = await _voteService.getUserVotes(); 205 - _voteProvider.loadInitialVotes(userVotes); 206 - } on Exception catch (e) { 207 - if (kDebugMode) { 208 - debugPrint('⚠️ Failed to load vote state: $e'); 209 - } 210 - // Don't fail the feed load if vote loading fails 211 - // Keep silent per PR review discussion 195 + // Initialize vote state from viewer data in feed response 196 + // IMPORTANT: Call setInitialVoteState for ALL feed items, even when 197 + // viewer.vote is null. This ensures that if a user removed their vote 198 + // on another device, the local state is cleared on refresh. 199 + if (_authProvider.isAuthenticated && _voteProvider != null) { 200 + for (final feedItem in response.feed) { 201 + final viewer = feedItem.post.viewer; 202 + _voteProvider.setInitialVoteState( 203 + postUri: feedItem.post.uri, 204 + voteDirection: viewer?.vote, 205 + voteUri: viewer?.voteUri, 206 + ); 212 207 } 213 208 } 214 209 } on Exception catch (e) {