feat: add media sync and Talk parity foundations - #159
Merged
Conversation
Keep desktop navigation and identity chrome in place while opening app and detail destinations, while preserving root-only shell behavior on adaptive mobile layouts. Refs #154
Update the Android density assets and desktop icon so the cloud mark remains centered and crisp at launcher sizes.
veryCrunchy
marked this pull request as ready for review
July 24, 2026 17:12
This was referenced Jul 24, 2026
There was a problem hiding this comment.
Pull request overview
This PR lays the groundwork for Android media sync (MediaStore folder discovery + backup receipt/reclaim modeling), improves file sync policy enforcement by mapping network/power settings into WorkManager constraints, and advances Talk parity by parsing and rendering additional message metadata while refining desktop/adaptive shell behavior.
Changes:
- Add Android MediaStore-based media folder discovery (with permission gating) and expose suggestions in the offline/sync UI.
- Introduce media backup receipt + reclaim eligibility modeling, and extend file sync configuration with network/power policies persisted in snapshots.
- Expand Talk message parsing/rendering to preserve threads/replies/reactions/edit/delete/silent/expiry/scheduling metadata, and adjust desktop/adaptive root shell persistence rules.
Reviewed changes
Copilot reviewed 24 out of 30 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/src/commonTest/kotlin/dev/obiente/nextcloudnative/app/TalkMessagesTest.kt | Adds tests asserting Talk metadata preservation (threads/replies/reactions/edit/silent/expiry/scheduling). |
| ui/src/commonTest/kotlin/dev/obiente/nextcloudnative/app/MediaBackupLedgerTest.kt | Adds unit tests for receipt-based backup status and reclaim eligibility. |
| ui/src/commonTest/kotlin/dev/obiente/nextcloudnative/app/FileSyncCoordinatorSnapshotTest.kt | Updates snapshot tests to include new network/power policies. |
| ui/src/commonTest/kotlin/dev/obiente/nextcloudnative/app/design/DesktopShellLayoutTest.kt | Adds tests for root shell persistence rules across presentations. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/TalkMessages.kt | Extends Talk JSON parsing to include reactions/threads/quotes/edit/delete/silent/expiry/scheduling fields. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/TalkMessageRenderModel.kt | Treats messages as deleted if the new deleted flag is set. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/TalkMessageCards.kt | Renders reply previews, reactions, and footer context for Talk messages. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/NextcloudPlatform.kt | Adds MediaLibrary capability, Talk metadata types, and media discovery + root-hint APIs. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/NextcloudNativeApp.kt | Keeps desktop shell visible for detail screens; adjusts header layout for desktop workspace. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/MediaBackupLedger.kt | Introduces LocalMediaObject/MediaBackupReceipt and backup/reclaim resolution helpers. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/FileSyncPlanning.kt | Adds network/power policy enums to FileSyncConfiguration. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/FileSyncCoordinatorSnapshot.kt | Persists/restores new sync configuration fields with defaults for backward compatibility. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/FileSyncCenter.kt | Adds shared types for media folder discovery suggestions and support states. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/FileOfflineCenterScreen.kt | Surfaces media folder suggestions, permission prompts, and config selection for sync pairs. |
| ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/design/DesktopShellLayout.kt | Adds shouldUseNextcloudRootShell policy helper. |
| androidApp/src/test/kotlin/dev/obiente/nextcloudnative/AndroidPlatformCapabilitiesTest.kt | Tests MediaLibrary permission mapping and “selected media” access recognition. |
| androidApp/src/test/kotlin/dev/obiente/nextcloudnative/AndroidMediaSyncFolderDetectorTest.kt | Tests media folder suggestion ranking/classification and remote path mapping. |
| androidApp/src/main/kotlin/dev/obiente/nextcloudnative/AndroidPlatformCapabilities.kt | Implements MediaLibrary permissions + access checks and labels/descriptions. |
| androidApp/src/main/kotlin/dev/obiente/nextcloudnative/AndroidNextcloudServices.kt | Adds Talk pagination via X-Chat-Last-Given and implements media discovery + root hint support. |
| androidApp/src/main/kotlin/dev/obiente/nextcloudnative/AndroidMediaSyncFolderDetector.kt | Implements MediaStore scanning and suggestion building for camera/screenshots/images/videos/mixed folders. |
| androidApp/src/main/kotlin/dev/obiente/nextcloudnative/AndroidFileSyncScheduler.kt | Maps sync network/power policies into WorkManager constraints and updates unique periodic work policy. |
| androidApp/src/main/kotlin/dev/obiente/nextcloudnative/AndroidFileSyncRootPicker.kt | Supports passing an initial tree URI hint to OpenDocumentTree. |
| androidApp/src/main/kotlin/dev/obiente/nextcloudnative/AndroidFileSyncEngine.kt | Schedules WorkManager jobs with per-pair policies and updates schedule description text. |
| androidApp/src/main/AndroidManifest.xml | Declares Android 13+/14 media permissions for MediaLibrary capability. |
Comments suppressed due to low confidence (1)
ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/TalkMessageCards.kt:250
expiresAtis parsed onTalkMessagebut never added to the footer context list, so even when the footer shows, expiration status isn't rendered.
val context = buildList {
if (message.editedAt != null) add("Edited")
if (message.silent) add("Silent")
if (message.scheduledAt != null) add("Scheduled")
if (message.isThread || message.threadId != null) {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| local: LocalMediaObject?, | ||
| receipt: MediaBackupReceipt?, | ||
| ): MediaReclaimEligibility { | ||
| if (local == null) return MediaReclaimEligibility.AlreadyCloudOnly |
| id = longValue("id") ?: 0L, | ||
| actorDisplayName = stringValue("actorDisplayName").orEmpty().ifBlank { "Nextcloud" }, | ||
| summary = summary.ifBlank { "Message" }, | ||
| deleted = booleanValue("deleted") ?: false, |
Comment on lines
+212
to
+219
| if ( | ||
| message.reactions.isEmpty() && | ||
| message.editedAt == null && | ||
| !message.silent && | ||
| !message.isThread && | ||
| message.threadId == null && | ||
| message.scheduledAt == null | ||
| ) { |
| workManager.enqueueUniquePeriodicWork( | ||
| workName(pairId), | ||
| ExistingPeriodicWorkPolicy.KEEP, | ||
| ExistingPeriodicWorkPolicy.UPDATE, |
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.
Summary
X-Chat-Last-Givenand preserve replies, threads, reactions, edit/delete, silent, expiry, and scheduling metadataTracking
Refs #61, #62, #107, #127, #128, #154.
Validation
bash tools/check-repository.shcargo test --locked./gradlew --no-daemon :contractAcquisition:test :ui:desktopTest :androidApp:testDebugUnitTest :ui:createDistributable :androidApp:assembleDebugProgresses #61.
Progresses #62.
Progresses #107.
Progresses #127.
Progresses #128.
Progresses #154.