21b7ffc7b3
New PAUSED status. When a sync is running, the sync button becomes a pause button (⏸). Tapping it cancels the WorkManager job and sets the status to PAUSED (purple). The button then becomes a play button (▶) to resume. Works in both the home screen card and the pair detail screen. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
75 lines
3.4 KiB
Kotlin
75 lines
3.4 KiB
Kotlin
package com.syncflow.domain.model
|
|
|
|
import java.time.Instant
|
|
|
|
data class SyncPair(
|
|
val id: Long = 0,
|
|
val name: String,
|
|
val localPath: String,
|
|
val remotePath: String,
|
|
val accountId: Long,
|
|
// ── Sync behaviour ──────────────────────────────────────────────────────
|
|
val syncDirection: SyncDirection,
|
|
val conflictStrategy: ConflictStrategy,
|
|
val deleteBehavior: DeleteBehavior,
|
|
val recursive: Boolean,
|
|
// ── Schedule ────────────────────────────────────────────────────────────
|
|
val scheduleType: ScheduleType,
|
|
val scheduleIntervalMinutes: Int,
|
|
val scheduleDailyTime: String?, // "HH:mm"
|
|
val scheduleWeekdays: Int, // bitmask Mon=1..Sun=64, 0=every day
|
|
// ── Constraints ─────────────────────────────────────────────────────────
|
|
val wifiOnly: Boolean,
|
|
val wifiSsid: String, // blank = any wifi
|
|
val chargingOnly: Boolean,
|
|
val minBatteryPct: Int, // 0 = no requirement
|
|
// ── File filters ────────────────────────────────────────────────────────
|
|
val excludePatterns: List<String>,
|
|
val includeExtensions: List<String>, // empty = all
|
|
val excludeExtensions: List<String>,
|
|
val skipHiddenFiles: Boolean,
|
|
val minFileSizeKb: Long, // 0 = no limit
|
|
val maxFileSizeKb: Long, // 0 = no limit
|
|
// ── Notifications ───────────────────────────────────────────────────────
|
|
val notifyOnComplete: Boolean,
|
|
val notifyOnError: Boolean,
|
|
// ── State (read-only, managed by engine) ────────────────────────────────
|
|
val isEnabled: Boolean,
|
|
val lastSyncAt: Instant?,
|
|
val lastSyncResult: SyncStatus,
|
|
val pendingConflicts: Int,
|
|
)
|
|
|
|
enum class SyncDirection(val label: String, val description: String) {
|
|
UPLOAD_ONLY("Upload only", "Local → Remote"),
|
|
DOWNLOAD_ONLY("Download only", "Remote → Local"),
|
|
TWO_WAY("Two-way sync", "Bidirectional"),
|
|
}
|
|
|
|
enum class ConflictStrategy(val label: String) {
|
|
KEEP_LOCAL("Keep local file"),
|
|
KEEP_REMOTE("Keep remote file"),
|
|
KEEP_NEWEST("Keep most recently modified"),
|
|
KEEP_LARGEST("Keep largest file"),
|
|
KEEP_BOTH("Keep both (rename copy)"),
|
|
ASK("Ask me each time"),
|
|
}
|
|
|
|
enum class DeleteBehavior(val label: String, val description: String) {
|
|
MIRROR("Mirror deletions", "Delete on target when deleted on source"),
|
|
KEEP("Keep deleted files", "Never delete — only add/update"),
|
|
ARCHIVE("Archive deleted", "Move files deleted from phone to _Deleted/ folder on remote"),
|
|
}
|
|
|
|
enum class ScheduleType(val label: String) {
|
|
MANUAL("Manual only"),
|
|
ON_CHANGE("When files change"),
|
|
INTERVAL("Every N minutes"),
|
|
DAILY("Daily at a set time"),
|
|
WEEKLY("Weekly on set days"),
|
|
}
|
|
|
|
enum class SyncStatus {
|
|
IDLE, SYNCING, PAUSED, SUCCESS, PARTIAL, FAILED, CONFLICT,
|
|
}
|