Commit Graph

17 Commits

Author SHA1 Message Date
inventory69
68584461b3 feat(v1.8.0): IMPL_02 Display Settings - Grid as Default
- Change DEFAULT_DISPLAY_MODE from 'list' to 'grid'
- Update display_mode_info strings (EN + DE)
- Remove outdated 'full width' reference from info text
- New description reflects actual two-column grid layout

Only affects new installations - existing users keep their preference.
Grid view provides better overview and cleaner visual hierarchy.
2026-02-10 14:19:11 +01:00
inventory69
881c0fd0fa feat(v1.8.0): IMPL_01 Language Settings - Smooth Language Switching
- Prevent activity recreate during language changes via configChanges
- Add onConfigurationChanged() handler in ComposeSettingsActivity
- Simplify setAppLanguage() - let system handle locale change smoothly
- Update language_info strings to reflect smooth transition
- Remove unused Activity parameter and imports

Fixes flicker during language switching by handling configuration
changes instead of recreating the entire activity. Compose recomposes
automatically when locale changes, providing seamless UX.
2026-02-10 14:02:42 +01:00
inventory69
1da1a63566 chore(v1.8.0): Resolve all Detekt code quality warnings
Fixes 22 Detekt warnings across the codebase:

- Remove 7 unused imports from UI components
- Add @Suppress annotations for 4 preview functions
- Define constants for 5 magic numbers
- Optimize state reads with derivedStateOf (2 fixes)
- Add @Suppress for long parameter list
- Move WidgetSizeClass to separate file
- Reformat long line in NoteEditorScreen
- Suppress unused parameter and property annotations
- Suppress WebDavSyncService method length/complexity with TODO for v1.9.0 refactoring

Test results:
- detekt: 0 warnings
- lintFdroidDebug: 0 errors
- Build successful

Progress v1.8.0: 0 Lint errors + 0 Detekt warnings complete
2026-02-10 12:44:14 +01:00
inventory69
96c819b154 feat(v1.8.0): IMPL_020 Note & Checklist Sorting
- Add SortOption enum for note sorting (Updated, Created, Title, Type)
- Add SortDirection enum with ASCENDING/DESCENDING and toggle()
- Add ChecklistSortOption enum for in-editor sorting (Manual, Alphabetical, Unchecked/Checked First)
- Implement persistent note sort preferences in SharedPreferences
- Add SortDialog for main screen with sort option and direction selection
- Add ChecklistSortDialog for editor screen with current sort option state
- Implement sort logic in MainViewModel with combined sortedNotes StateFlow
- Implement sort logic in NoteEditorViewModel with auto-sort for MANUAL and UNCHECKED_FIRST
- Add separator display logic for MANUAL and UNCHECKED_FIRST sort options
- Add 16 sorting-related strings (English and German)
- Update Constants.kt with sort preference keys
- Update MainScreen.kt, NoteEditorScreen.kt with sort UI integration
2026-02-10 11:30:06 +01:00
inventory69
539987f2ed feat(v1.8.0): IMPL_019 Homescreen Widgets Implementation
Complete Jetpack Glance Widget Framework
- Implement NoteWidget with 5 responsive size classes
- Support TEXT and CHECKLIST note types
- Material You dynamic colors integration
- Interactive checklist checkboxes in large layouts
- Read-only mode for locked widgets

Widget Configuration System
- NoteWidgetConfigActivity for placement and reconfiguration (Android 12+)
- NoteWidgetConfigScreen with note selection and settings
- Lock widget toggle to prevent accidental edits
- Background opacity slider with 0-100% range
- Auto-save on back navigation plus Save FAB

Widget State Management
- NoteWidgetState keys for per-instance persistence via DataStore
- NoteWidgetActionKeys for type-safe parameter passing
- Five top-level ActionCallback classes
  * ToggleChecklistItemAction (updates checklist and marks for sync)
  * ToggleLockAction (toggle read-only mode)
  * ShowOptionsAction (show permanent options bar)
  * RefreshAction (reload from storage)
  * OpenConfigAction (launch widget config activity)

Responsive Layout System
- SMALL (110x80dp): Title only
- NARROW_MEDIUM (110x110dp): Preview or compact checklist
- NARROW_TALL (110x250dp): Full content display
- WIDE_MEDIUM (250x110dp): Preview layout
- WIDE_TALL (250x250dp): Interactive checklist

Interactive Widget Features
- Tap content to open editor (unlock) or show options (lock)
- Checklist checkboxes with immediate state sync
- Options bar with Lock/Unlock, Refresh, Settings, Open in App buttons
- Per-widget background transparency control

Connection Leak Fixes (Part of IMPL_019)
- Override put/delete/createDirectory in SafeSardineWrapper with response.use{}
- Proper resource cleanup in exportAllNotesToMarkdown and syncMarkdownFiles
- Use modern OkHttp APIs (toMediaTypeOrNull, toRequestBody)

UI Improvements (Part of IMPL_019)
- Checkbox toggle includes KEY_LAST_UPDATED to force Glance recomposition
- Note selection in config is visual-only (separate from save)
- Config uses moveTaskToBack() plus FLAG_ACTIVITY_CLEAR_TASK
- Proper options bar with standard Material icons

Resources and Configuration
- 8 drawable icons for widget controls
- Widget metadata file (note_widget_info.xml)
- Widget preview layout for Android 12+ widget picker
- Multi-language strings (English and German)
- Glance Jetpack dependencies version 1.1.1

System Integration
- SyncWorker updates all widgets after sync completion
- NoteEditorViewModel reloads checklist state on resume
- ComposeNoteEditorActivity reflects widget edits
- WebDavSyncService maintains clean connections
- AndroidManifest declares widget receiver and config activity

Complete v1.8.0 Widget Feature Set
- Fully responsive design for phones, tablets and foldables
- Seamless Material Design 3 integration
- Production-ready error handling
- Zero connection leaks
- Immediate UI feedback for all interactions
2026-02-10 10:42:40 +01:00
inventory69
900dad76fe feat(v1.8.0): IMPL_017 Checklist Separator & Sorting - Unchecked/Checked Separation
- Separator component: Visual divider between unchecked and checked items
  * Shows count of completed items with denominator styling
  * Prevents accidental drag across group boundaries
  * Smooth transitions with fade/slide animations

- Sorting logic: Maintains unchecked items first, checked items last
  * Stable sort: Relative order within groups is preserved
  * Auto-updates on item toggle and reordering
  * Validates drag moves to same-group only

- UI improvements: Enhanced LazyColumn animations
  * AnimatedVisibility for smooth item transitions
  * Added animateItem() for LazyColumn layout changes
  * Item elevation during drag state

- Comprehensive test coverage
  * 9 unit tests for sorting logic validation
  * Edge cases: empty lists, single items, mixed groups
  * Verifies order reassignment and group separation

Affected components:
- CheckedItemsSeparator: New UI component for visual separation
- NoteEditorViewModel: sortChecklistItems() method with validation
- NoteEditorScreen: Separator integration & animation setup
- ChecklistSortingTest: Complete test suite with 9 test cases
- Localizations: German & English plurals
2026-02-09 14:09:18 +01:00
inventory69
df37d2a47c feat(v1.8.0): IMPL_006 Sync Progress UI - Complete Implementation
- Add SyncProgress.kt: Data class for entire sync lifecycle UI state
- Add SyncPhase enum: IDLE, PREPARING, UPLOADING, DOWNLOADING, IMPORTING_MARKDOWN, COMPLETED, ERROR
- Rewrite SyncStateManager.kt: SyncProgress (StateFlow) is single source of truth
- Remove pre-set phases: CHECKING_SERVER and SAVING cause flickering
- UPLOADING phase only set when actual uploads happen
- DOWNLOADING phase only set when actual downloads happen
- IMPORTING_MARKDOWN phase only set when feature enabled
- Add onProgress callback to uploadLocalNotes() with uploadedCount/totalToUpload
- Add onProgress callback to downloadRemoteNotes() for actual downloads only
- Progress display: x/y for uploads (known total), count for downloads (unknown)
- Add SyncProgressBanner.kt: Unified banner (replaces dual system)
- Update SyncStatusBanner.kt: Kept for legacy compatibility, only COMPLETED/ERROR
- Update MainViewModel.kt: Remove _syncMessage, add syncProgress StateFlow
- Update MainScreen.kt: Use only SyncProgressBanner (unified)
- Update ComposeMainActivity.kt: Auto-hide COMPLETED (2s), ERROR (4s) via lifecycle
- Add strings.xml (DE+EN): sync_phase_* and sync_wifi_only_error
- Banner appears instantly on sync button click (PREPARING phase)
- Silent auto-sync (onResume) completely silent, errors always shown
- No misleading counters when nothing to sync

Closes #IMPL_006
2026-02-09 10:38:47 +01:00
inventory69
bf7a74ec30 feat(v1.8.0): IMPL_022 Multi-Client Deletion Enhancement
Defensive improvements for server deletion detection:

1. Enhanced logging in detectServerDeletions():
   - Statistics: server/local/synced note counts
   - Summary log when deletions found

2. Explicit documentation:
   - Comment clarifying checklists are included
   - Both Notes and Checklists use same detection mechanism

3. Sync banner now shows deletion count:
   - '3 synced · 2 deleted on server'
   - New strings: sync_deleted_on_server_count (en + de)

4. DELETED_ON_SERVER → PENDING on edit:
   - Verified existing logic works correctly
   - All edited notes → PENDING (re-upload to server)
   - Added comments for clarity

Cross-client analysis confirmed:
-  Android/Desktop/Web deletions detected correctly
- ⚠️ Obsidian .md-only deletions not detected (by design: JSON = source of truth)

IMPL_022_MULTI_CLIENT_DELETION.md
2026-02-09 09:31:27 +01:00
inventory69
07607fc095 feat(v1.8.0): IMPL_021 Sync Status Legend
- New SyncStatusLegendDialog.kt showing all 5 sync status icons with descriptions
- Help button (?) in MainScreen TopAppBar (only visible when sync available)
- Localized strings (English + German) for all 5 status explanations
- Material You design with consistent colors matching NoteCard icons
- Dialog shows: Synced, Pending, Conflict, Local only, Deleted on server

IMPL_021_SYNC_STATUS_LEGEND.md
2026-02-09 09:24:15 +01:00
inventory69
24ea7ec59a fix: Android 9 crash - Implement getForegroundInfo() for WorkManager Expedited Work (Issue #15)
This commit fixes the critical crash on Android 9 (API 28) that occurred when using
WorkManager Expedited Work for background sync operations.

## Root Cause
When setExpedited() is used in WorkManager, the CoroutineWorker must implement
getForegroundInfo() to return a ForegroundInfo object with a Foreground Service
notification. On Android 9-11, WorkManager calls this method, but the default
implementation throws: IllegalStateException: Not implemented

## Solution
- Implemented getForegroundInfo() in SyncWorker
- Returns ForegroundInfo with sync progress notification
- Android 10+: Sets FOREGROUND_SERVICE_TYPE_DATA_SYNC for proper service typing
- Added required Foreground Service permissions to AndroidManifest.xml

## Technical Changes
- SyncWorker.kt: Added getForegroundInfo() override
- NotificationHelper.kt: Added createSyncProgressNotification() factory method
- strings.xml: Added sync_in_progress UI strings (EN + DE)
- AndroidManifest.xml: Added FOREGROUND_SERVICE permissions
- Version updated to 1.7.1 (versionCode 18)

## Previously Fixed (in this release)
- Kernel-VPN compatibility (Wireguard interface detection)
- HTTP connection lifecycle optimization (SafeSardineWrapper)
- Stability improvements for sync sessions

## Testing
- Tested on Android 9 (API 28) - No crash on second app start
- Tested on Android 15 (API 35) - No regressions
- WiFi-connect sync working correctly
- Expedited work notifications display properly

Fixes #15
Thanks to @roughnecks for detailed bug report and testing!
2026-02-02 13:09:12 +01:00
inventory69
df4ee4bed0 v1.7.1: Fix Android 9 crash and Kernel-VPN compatibility
- Fix connection leak on Android 9 (close() in finally block)
- Fix VPN detection for Kernel Wireguard (interface name patterns)
- Fix missing files after app data clear (local existence check)
- Update changelogs for v1.7.1 (versionCode 18)

Refs: #15
2026-01-30 16:21:04 +01:00
inventory69
ebab347d4b fix: Notification opens ComposeMainActivity, WiFi-Only toggle in own section
Fixes:
1. Notification click now opens ComposeMainActivity instead of legacy MainActivity
2. WiFi-Only toggle moved to its own 'Network Restriction' section at top of sync settings
3. Added hint explaining WiFi-Connect trigger is not affected by WiFi-Only setting

UI Changes:
- New section header: 'Network Restriction' / 'Netzwerk-Einschränkung'
- WiFi-Only toggle now clearly separated from sync triggers
- Info card shows when WiFi-Only is enabled explaining the exception
2026-01-26 23:21:13 +01:00
inventory69
b70bc4d8f6 debug: v1.7.0 Features - Grid Layout, WiFi-only Sync, VPN Support 2026-01-26 21:19:46 +01:00
inventory69
1d010d0034 Release v1.6.0: Configurable Sync Triggers + Offline Mode
- NEW: Configurable sync triggers (onSave, onResume, WiFi, Periodic, Boot)
- NEW: Offline mode toggle to disable all network features
- Various fixes and UI improvements
- Version bumped to 1.6.0 (code 14)
2026-01-19 23:31:25 +01:00
inventory69
3bf97dbc14 feat(1.5.0): add "Nothing to sync" banner and improve sync UX for v1.5.0
Code changes:
- Show "ℹ️ Nothing to sync" when no notes need syncing (banner instead of toast)
- Add i18n strings for EN/DE

Documentation:
- Improve auto-sync description: mention WiFi reconnect + multi-device sync
- Add 2 new screenshots: server settings & sync status banner

Assets:
- Add screenshots 5 & 6 (server settings & sync banner showcase)
2026-01-16 21:56:42 +01:00
inventory69
67b226a5c3 feat(v1.5.0): icons, batch delete toast, cursor fix, docs refactor
FEATURES
========

Batch Delete Toast Aggregation:
- New deleteMultipleNotesFromServer() method
- Shows single aggregated toast instead of multiple ("3 notes deleted from server")
- Partial success handling ("3 of 5 notes deleted from server")
- Added string resources: snackbar_notes_deleted_from_server, snackbar_notes_deleted_from_server_partial

Text Editor Cursor Fix:
- Fixed cursor jumping to end after every keystroke when editing notes
- Added initialCursorSet flag to only set cursor position on first load
- Cursor now stays at user's position while editing
- Changed LaunchedEffect(content) to LaunchedEffect(Unit) to prevent repeated resets

DOCUMENTATION REFACTOR
======================

Breaking Change: English is now the default language
- README.md: Now English (was German)
- QUICKSTART.md: Now English (was German)
- CHANGELOG.md: Now English (was mixed EN/DE)
- docs/*.md: All English (was German)
- German versions: Use .de.md suffix (README.de.md, QUICKSTART.de.md, etc.)

Updated for v1.5.0:
- CHANGELOG.md: Fully translated to English with v1.5.0 release notes
- CHANGELOG.de.md: Created German version
- FEATURES.md: Added i18n section, Selection Mode, Jetpack Compose updates
- FEATURES.de.md: Updated with v1.5.0 features
- UPCOMING.md: v1.5.0 marked as released, v1.6.0/v1.7.0 roadmap
- UPCOMING.de.md: Updated German version

All language headers updated:
- English: [Deutsch](*.de.md) · **English**
- German: **Deutsch** · [English](*.md)

F-DROID METADATA
================

Changelogs (F-Droid):
- fastlane/metadata/android/en-US/changelogs/13.txt: Created
- fastlane/metadata/android/de-DE/changelogs/13.txt: Created

Descriptions:
- full_description.txt (EN/DE): Updated with v1.5.0 changes
  - Selection Mode instead of Swipe-to-Delete
  - i18n support highlighted
  - Jetpack Compose UI mentioned
  - Silent-Sync Mode added

OTHER FIXES
===========

Code Quality:
- Unused imports removed from multiple files
- maxLineLength fixes
- Detekt config optimized (increased thresholds for v1.5.0)
- AboutScreen: Uses app foreground icon directly
- EmptyState: Shows app icon instead of emoji
- themes.xml: Splash screen uses app foreground icon
2026-01-16 16:31:30 +01:00
inventory69
3af99f31b8 feat(v1.5.0): Complete i18n implementation + Language Selector feature
- Added comprehensive English (strings.xml) and German (strings-de.xml) localization with 400+ strings
- Created new LanguageSettingsScreen with System Default, English, and German options
- Fixed hardcoded German notification toasts in MainActivity and ComposeMainActivity
- Integrated Language selector in Settings as top-level menu item
- Changed ComposeSettingsActivity from ComponentActivity to AppCompatActivity for AppCompatDelegate compatibility
- Added locales_config.xml for Android 13+ Per-App Language support
- Updated Extensions.kt with i18n-aware timestamp formatting (toReadableTime with context)
- Translated all UI strings including settings, toasts, notifications, and error messages
- Added dynamic language display in SettingsMainScreen showing current language

Fixes:
- Notification permission toast now respects system language setting
- Activity correctly restarts when language is changed
- All string formatting with parameters properly localized

Migration:
- MainViewModel: All toast messages now use getString()
- SettingsViewModel: All toast and dialog messages localized
- NotificationHelper: Notification titles and messages translated
- UrlValidator: Error messages now accept Context parameter for translation
- NoteCard, DeleteConfirmationDialog, SyncStatusBanner: All strings externalized

Testing completed on device with both EN and DE locale switching.
Closes #5
2026-01-16 10:39:21 +01:00