Skip to content

feat: add media sync and Talk parity foundations - #159

Merged
veryCrunchy merged 5 commits into
mainfrom
feat/61-media-sync-talk-foundation
Jul 24, 2026
Merged

feat: add media sync and Talk parity foundations#159
veryCrunchy merged 5 commits into
mainfrom
feat/61-media-sync-talk-foundation

Conversation

@veryCrunchy

@veryCrunchy veryCrunchy commented Jul 24, 2026

Copy link
Copy Markdown
Member

Summary

  • discover Android camera, screenshot, image, video, and mixed media folders through MediaStore
  • support both full-library and Android selected-media access without moving originals
  • add exact-revision backup receipt and reclaim eligibility modeling
  • make file sync network and power policies update real WorkManager constraints
  • paginate Talk history with X-Chat-Last-Given and preserve replies, threads, reactions, edit/delete, silent, expiry, and scheduling metadata
  • keep the desktop workspace shell visible on detail screens and refine launcher icon alignment

Tracking

Refs #61, #62, #107, #127, #128, #154.

Validation

  • bash tools/check-repository.sh
  • cargo test --locked
  • ./gradlew --no-daemon :contractAcquisition:test :ui:desktopTest :androidApp:testDebugUnitTest :ui:createDistributable :androidApp:assembleDebug
  • verified full-library and selected-media folder discovery on a physical Android device
  • verified live Talk pagination through the beginning of a long conversation
  • checked the installed launcher icon on the physical device

Progresses #61.

Progresses #62.

Progresses #107.

Progresses #127.

Progresses #128.

Progresses #154.

Add Android media folder discovery, verified backup receipt modeling, configurable WorkManager constraints, Talk history pagination, and richer native message metadata.

Refs #61, #62, #107, #127, #128
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
veryCrunchy marked this pull request as ready for review July 24, 2026 17:12
Copilot AI review requested due to automatic review settings July 24, 2026 17:12
@veryCrunchy
veryCrunchy merged commit e17f174 into main Jul 24, 2026
4 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  • expiresAt is parsed on TalkMessage but 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,
@veryCrunchy veryCrunchy added priority:P0 Required for a trustworthy mobile replacement or prevents data loss area:media Media backup, MediaStore, storage reclaim, and sharing area:files-sync Files, offline storage, transfer, and synchronization area:talk Talk messaging, calling, and conversation features area:ux Navigation, accessibility, responsive design, and interaction type:feature New product capability platform:android Android-specific implementation or validation platform:desktop Desktop-specific implementation or validation labels Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:files-sync Files, offline storage, transfer, and synchronization area:media Media backup, MediaStore, storage reclaim, and sharing area:talk Talk messaging, calling, and conversation features area:ux Navigation, accessibility, responsive design, and interaction platform:android Android-specific implementation or validation platform:desktop Desktop-specific implementation or validation priority:P0 Required for a trustworthy mobile replacement or prevents data loss type:feature New product capability

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants