Implement list layout design with sort and layout modes#14
Merged
Conversation
Add three switchable layout modes (Card, Magazine, List) and a sort menu to the bookmark list screen. Both preferences persist across sessions via SettingsDataStore. Changes: - Add SortOption and LayoutMode enums in domain/model - Update BookmarkListItem with readingTime, created, and wordCount fields - Update database layer (BookmarkListItemEntity, BookmarkDao) to support new fields - Add sort parameter to repository queries - Update SettingsDataStore to persist layout and sort preferences - Add layout and sort state management in BookmarkListViewModel - Implement 3-dot menu with layout and sort dialogs in BookmarkListScreen - Create BookmarkMagazineView and BookmarkListItemView composables - Update BookmarkListView to switch between three layout modes https://claude.ai/code/session_01NyGWeTy5DKb2hCTbeAbBWB
- Change BookmarkListItem.created from java.time.LocalDateTime to kotlinx.datetime.LocalDateTime - Update BookmarkRepositoryImpl conversions to use kotlinx.datetime.TimeZone - Fix preview data to properly convert Instant to LocalDateTime - Add missing Row import to BookmarkListScreen https://claude.ai/code/session_01NyGWeTy5DKb2hCTbeAbBWB
- Replace forEach with LazyColumn + items for proper Compose composition context - Add clickable import to BookmarkListScreen - Add layoutMode parameter to BookmarkListView preview This resolves the @composable invocation errors by using LazyColumn which is the idiomatic Compose pattern for rendering lists of composables. https://claude.ai/code/session_01NyGWeTy5DKb2hCTbeAbBWB
Replace direct toLocalDateTime() calls on Instant with the correct pattern: Clock.System.now().atZone(TimeZone.currentSystemDefault()).toLocalDateTime() Add missing TimeZone imports to BookmarkCard.kt and BookmarkListScreen.kt. This resolves the unresolved reference errors for toLocalDateTime in preview and sample bookmark initialization code. https://claude.ai/code/session_01NyGWeTy5DKb2hCTbeAbBWB
Add kotlinx.datetime.atZone and kotlinx.datetime.toLocalDateTime imports to: - BookmarkCard.kt - BookmarkListScreen.kt These imports are required for the Instant.atZone().toLocalDateTime() pattern used in the preview/sample bookmark initialization code. https://claude.ai/code/session_01NyGWeTy5DKb2hCTbeAbBWB
Replace LayoutMode.values() and SortOption.values() with .entries to use the modern Kotlin enum API (Kotlin 1.9+). This resolves deprecation warnings in the layout and sort picker dialogs. https://claude.ai/code/session_01J7dvgRBFWvDt9HBKuz92wCH
Replace incorrect java.time API usage with proper kotlinx.datetime API: - Remove non-existent imports: kotlinx.datetime.atZone, kotlinx.datetime.toLocalDateTime - Change from: Clock.System.now().atZone(TimeZone.currentSystemDefault()).toLocalDateTime() - Change to: Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) This fixes compilation errors where: 1. atZone() was being treated as private (it's from java.time, not kotlinx.datetime) 2. Result was java.time.LocalDateTime instead of kotlinx.datetime.LocalDateTime 3. Type mismatch in BookmarkListItem constructor Fixes errors in: - BookmarkCard.kt preview (line 571) - BookmarkListScreen.kt preview (line 710) https://claude.ai/code/session_01J7dvgRBFWvDt9HBKuz92wCH
Menu Changes: - Replace 3-dot overflow menu with individual icon buttons - Add Sort icon (first), Layout icon (second), Search icon (third) - Convert AlertDialogs to DropdownMenus for better UX - Add icons to layout menu items (Grid/Compact/Mosaic) Enum Updates: - Rename LayoutMode: MAGAZINE→GRID, LIST→COMPACT, CARD→MOSAIC - Add displayName property to LayoutMode - Update SortOption with 8 new options aligned to Readeck: * Added (newest/oldest first) * Title (A-Z, Z-A) * Site Name (A-Z, Z-A) * Duration (shortest/longest first) - Remove old options (Read Progress) Layout Mapping: - GRID → BookmarkMagazineView (to be updated) - COMPACT → BookmarkListItemView (to be updated) - MOSAIC → BookmarkCard (to be updated) Note: Layout composable visual updates pending in next commit. Published date sort options deferred until field is added. https://claude.ai/code/session_01J7dvgRBFWvDt9HBKuz92wCH
Add kotlinx.datetime.toLocalDateTime extension function import to both BookmarkCard.kt and BookmarkListScreen.kt preview composables. This resolves the "Unresolved reference 'toLocalDateTime'" compilation errors that were occurring when calling: Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) The import was previously removed in error when fixing other datetime API issues, but the extension function import is required for the method to be available. https://claude.ai/code/session_01J7dvgRBFWvDt9HBKuz92wCH
Update default values to use new enum names: - LayoutMode.CARD → LayoutMode.GRID (new default) - SortOption.NEWEST_ADDED → SortOption.ADDED_NEWEST This resolves "Unresolved reference" compilation errors after enum refactoring. https://claude.ai/code/session_01J7dvgRBFWvDt9HBKuz92wCH
**Grid Layout (BookmarkMagazineView):** - Reordered elements: Title → Site row → Labels → Actions - Progress indicator positioned on thumbnail top-right - Labels row added with icon and comma-separated list **Compact Layout (BookmarkListItemView):** - Complete restructure from Row to Column layout - Favicon aligned with top line of title - Theme-aware progress indicator (dark grey in light theme, light grey in dark theme) - Progress indicator positioned left of site name - Labels row below site with left indent - Action buttons (Favorite, Archive, Open, Delete) in Grid arrangement below labels **Mosaic Layout (BookmarkCard):** - Thumbnail now fills full card height (300dp) - Removed site name row entirely - Text and icons overlaid at bottom in white for visibility - Action buttons remain at bottom All changes align with Readeck design patterns while maintaining existing functionality. https://claude.ai/code/session_b9ff78c9-03ed-4752-a5c4-dcc2bbcd6d12
- Reduced card height from 300dp to 270dp (10% reduction) - Added vertical gradient overlay from transparent to black (70% opacity) - Gradient covers full card height, providing better text readability - Text and icons remain white and overlaid at bottom https://claude.ai/code/session_b9ff78c9-03ed-4752-a5c4-dcc2bbcd6d12
**Data Models:**
- Added `published: Instant?` field to BookmarkDto (API response)
- Added `published: Instant?` field to BookmarkEntity (database)
- Added `published: Instant?` field to BookmarkListItemEntity (query entity)
- Added `published: LocalDateTime?` field to Bookmark (domain model)
- Added `published: LocalDateTime?` field to BookmarkListItem (UI model)
**Mappers:**
- Updated BookmarkMapper to handle published field conversions between Instant and LocalDateTime
- Updated BookmarkRepositoryImpl to map published field in observeBookmarkListItems and searchBookmarkListItems
**Database:**
- Updated BookmarkDao SQL queries to include published field in SELECT statements for both getBookmarkListItemsByFilters and searchBookmarkListItems
**Sort Options:**
- Added PUBLISHED_NEWEST ("Published, newest first") - published DESC
- Added PUBLISHED_OLDEST ("Published, oldest first") - published ASC
**Tests:**
- Updated BookmarkListViewModelTest to include all required fields (readingTime, created, wordCount, published)
- Updated BookmarkCard preview composable to include published field
https://claude.ai/code/session_b9ff78c9-03ed-4752-a5c4-dcc2bbcd6d12
Add missing background import and published field to preview https://claude.ai/code/session_b9ff78c9-03ed-4752-a5c4-dcc2bbcd6d12
**Sort and Layout Menus:** - Current selection now displayed in bold font weight in dropdown menus - Sort menu shows selected option in bold - Layout menu shows selected mode in bold **Bookmark Details Debug Info:** - Added debugInfo field to ViewModel Bookmark data class - Created buildDebugInfo() function to generate comprehensive debug dump - Added DebugInfoSection composable with scrollable monospace text view - Debug info includes: - ID, State, Loaded status, Has Article, Is Deleted flags - Timestamps (Created, Updated, Published) - All URLs and resource paths (Article, Icon, Image, Thumbnail, Log, Props) - Content info (Type, Document Type, Language, Word Count, Reading Time, etc.) - Metadata (Authors, Labels, Marked/Archived status) - Resource dimensions for images - Debug section appears at bottom of bookmark details dialog - Scrollable 300dp height card with horizontal scroll support This helps diagnose blank page issues by showing internal state, resource URLs, and all bookmark metadata except content. https://claude.ai/code/session_b9ff78c9-03ed-4752-a5c4-dcc2bbcd6d12
**Error Placeholder Image:** - Changed from light gray (jarring) to subtle dark gray (#2C2C2C) - Updated icon tint to slightly lighter gray (#505050) - Blends better with dark UI theme - Less visually distracting when thumbnails fail to load **Progress Indicator Backgrounds:** - Added light grey circular background behind all progress indicators - Mosaic layout: 28dp circle with 24dp indicator/checkmark - Grid layout: 28dp circle with 20dp progress arc - Compact layout: 20dp circle with 14dp progress arc (lighter alpha 0.3f) - All use semi-transparent grey (alpha 0.5f except Compact at 0.3f) - Improves visibility and provides consistent visual treatment https://claude.ai/code/session_b9ff78c9-03ed-4752-a5c4-dcc2bbcd6d12
**Debug Info Actions:** - Added copy button (ContentCopy icon) to copy debug info to clipboard - Added share button (Share icon) to share debug info via Android share sheet - Buttons positioned in header row next to "Debug Info" label - Both use primary theme color for better visibility - Copy uses LocalClipboardManager for clipboard access - Share creates ACTION_SEND intent with text/plain type This allows users to easily extract debug information when diagnosing blank page issues - can copy to paste elsewhere or share directly to email, messaging apps, etc. https://claude.ai/code/session_b9ff78c9-03ed-4752-a5c4-dcc2bbcd6d12
**Root Cause:** BatchArticleLoadWorker had `.setRequiresBatteryNotLow(true)` constraint, which prevented it from running when battery is low (<15%). This blocked ALL article content downloads when battery was low, leaving users with bookmark metadata but no content to read. **Symptoms:** - Sync status showing 0/7 instead of 7/7 - "Has Article: true" but "Has Article Content: false" in debug info - Logs show "Batch article loader enqueued successfully" but no BatchArticleLoadWorker execution logs - Articles visible in Readeck PWA but not in Android app **Fix:** - Removed `.setRequiresBatteryNotLow(true)` from both: - LoadBookmarksUseCase.enqueueBatchArticleLoader() - BatchArticleLoadWorker.enqueue() - Now only requires network connectivity, no battery level restriction - Article content will sync regardless of battery level Users can now sync and read articles even when battery is low. The network constraint remains to prevent excessive data usage without connectivity. https://claude.ai/code/session_b9ff78c9-03ed-4752-a5c4-dcc2bbcd6d12
**Issue Summary:** Comprehensive documentation of the battery constraint issue that blocked article content sync when battery was <15%. Includes diagnosis process, immediate fix, research findings, and recommendations for future battery-aware sync improvements. **Contents:** - Problem summary with symptoms and root cause analysis - Diagnosis process with evidence from logs, debug info, and device state - Immediate fix (removal of battery constraint) - Research on industry best practices (2025-2026 patterns) - Four recommended options for future enhancement: 1. Hybrid strategy (user-initiated vs background sync) 2. UI status indicators 3. Adaptive batch sync with battery-aware strategies 4. Smart notifications for deferred syncs - Code examples for implementation - Testing checklist - Implementation priority roadmap **Key Recommendations:** - User-initiated actions should bypass battery constraints - Background batch operations can use adaptive strategies - UI transparency is critical to avoid silent failures - Runtime battery checking preferred over rigid constraints **Research Sources:** - WorkManager best practices (2025-2026) - Android battery monitoring documentation - Adaptive sync patterns from industry leaders This document serves as a reference for future battery-aware sync implementation while maintaining current fix that ensures content always syncs. https://claude.ai/code/session_b9ff78c9-03ed-4752-a5c4-dcc2bbcd6d12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add three switchable layout modes (Card, Magazine, List) and a sort menu to
the bookmark list screen. Both preferences persist across sessions via
SettingsDataStore.
Changes:
https://claude.ai/code/session_01NyGWeTy5DKb2hCTbeAbBWB