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.
Added Bluesky-inspired UI components and fixed feed provider issues.
**New Components**:
- AnimatedHeartIcon: Animated like button with burst effect
- 3-phase animation: shrink → expand → settle
- Particle burst at peak expansion
- Bluesky-style filled/outline states
- ReplyIcon: Reply icon with filled/outline states
- ShareIcon: Share/upload icon with Bluesky styling
- SignInDialog: Reusable authentication prompt dialog
- Shows when unauthenticated users try to interact
- Provides clear call-to-action for sign-in
**Feed Provider Fixes**:
- Fixed duplicate API calls on failed sign-in attempt
- Track auth state transitions instead of current state
- Only reload feed when transitioning authenticated → unauthenticated
- Prevents unnecessary API calls and improves performance
**API Exception Enhancements**:
- Enhanced error hierarchy with specific exception types
- Better error message extraction from API responses
- Improved Dio integration for network errors
**Configuration**:
- Added EnvironmentConfig for centralized app settings
- Updated OAuth config with better documentation
**Testing**:
- Added AnimatedHeartIcon widget tests
- Added SignInDialog widget tests
- Updated feed provider tests for auth transition logic
- Removed obsolete mock files
All tests passing, flutter analyze clean (12 info-level style suggestions).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Refactored voting/like feature to follow proper atProto architecture where
mobile clients write directly to user's Personal Data Server (PDS) instead
of through a backend proxy.
**Architecture Change**:
- Before: Mobile → Backend API → User's PDS (incorrect ❌)
- After: Mobile → User's PDS → Jetstream → Backend AppView (correct ✅)
**Key Changes**:
- VoteService: Complete rewrite to use XRPC endpoints:
- com.atproto.repo.createRecord (create vote)
- com.atproto.repo.deleteRecord (delete vote)
- com.atproto.repo.listRecords (find existing votes)
- VoteProvider: Updated to pass postCid for strong references
- AuthProvider: Added getPdsUrl() method to get user's PDS URL
- PostCard: Updated to pass post.cid to vote calls
- VoteState: Added rkey field for record deletion
**Vote Record Schema**:
Collection: social.coves.interaction.vote
Fields: $type, subject (uri+cid), direction, createdAt
**Testing**:
- 109 tests passing (24 vote provider, 19 vote service tests)
- flutter analyze: 0 errors, 0 warnings (12 info-level style suggestions)
- All tests updated to include postCid parameter
**Known TODO**:
DPoP authentication not yet implemented. atProto PDSs require DPoP
(Demonstrating Proof of Possession) tokens, not Bearer tokens. Current
implementation is a placeholder that won't work with real PDSs until DPoP
support is added to atproto_oauth_flutter package.
**Benefits**:
✅ User owns their data on their PDS
✅ Backend only indexes public data (read-only)
✅ Works across entire atProto federation
✅ Follows Bluesky/atProto architecture pattern
See DEVELOPMENT_SUMMARY.md for complete implementation details.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add custom icon widgets recreating Bluesky's social interaction icons:
- Animated heart icon with dramatic 5-phase animation sequence
- Reply/comment icon (speech bubble design)
- Share icon (arrow out of box design)
Heart Animation Features:
- Phase 1: Heart shrinks to nothing
- Phase 2: Red hollow circle expands outward
- Phase 3: Small heart grows from center
- Phase 4: Heart pops to 1.3x with 7-particle burst
- Phase 5: Elastic settle back to 1x
Technical Details:
- Pure Flutter CustomPainter (no external dependencies)
- Uses OverflowBox to prevent layout shift during animation
- SVG path data extracted from Bluesky's Heart2, Reply, and ArrowOutOfBox icons
- All icons use fill style (paths are pre-stroked)
- Bright red color (#FF0033) for liked state
- 800ms animation duration with overlapping phases
Updates PostCard to use new icons and adds temporary like state for testing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Apply dart format to existing modified files
- Include auth, API service, and widget improvements
- Ensure consistency across codebase
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update feed_screen_test to expect @handle format
- Remove expectation for share button count
- Update test expectations for new UI structure
- All 15 FeedScreen widget tests passing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Use extracted PostCard widget
- Replace all hardcoded colors with AppColors constants
- Pass currentTime from FeedProvider to PostCard
- Remove 263 lines of PostCard implementation
- Reduced from 618 to 310 lines (-50% reduction)
Addresses PR comment: Use const for color values
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Extract 263-line _PostCard widget from feed_screen.dart
- Use centralized AppColors constants
- Use DateTimeUtils for time/count formatting
- Accept currentTime parameter for testable timestamps
- Improved touch targets (padding 10/7 → 12/10)
- Clean Bluesky-inspired icons (ios_share, chat_bubble_outline, favorite_border)
- Always display @handle (atproto standard)
- Remove share count (no share metric available)
Benefits:
- Improved testability (can test PostCard in isolation)
- Better code organization and reusability
- Reduced feed_screen.dart complexity (618→310 lines)
Addresses PR comments:
- Extract _PostCard widget
- Button touch targets too small
- Use const for color values
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>