Initial commit — SyncFlow Android file sync app

Supports WebDAV, SFTP, SFTPGo, Nextcloud, ownCloud, Google Drive,
Dropbox, and OneDrive. Credentials encrypted with Android Keystore.
Biometric app-lock, conflict resolution, and auto-sync via WorkManager.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-22 20:21:20 +00:00
commit cff4233de6
95 changed files with 5381 additions and 0 deletions
@@ -0,0 +1,73 @@
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"),
}
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, SUCCESS, PARTIAL, FAILED, CONFLICT,
}