Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
import SwiftUI
|
|
|
|
|
import Photos
|
|
|
|
|
|
|
|
|
|
struct BackupView: View {
|
|
|
|
|
@EnvironmentObject var engine: BackupEngine
|
|
|
|
|
@EnvironmentObject var store: ConnectionStore
|
|
|
|
|
@StateObject private var vm = BackupViewModel()
|
|
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
|
ZStack {
|
|
|
|
|
Color.white.ignoresSafeArea()
|
|
|
|
|
|
|
|
|
|
ScrollView {
|
2026-05-16 00:43:31 +03:00
|
|
|
VStack(spacing: AppTheme.sectionGap) {
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
ringSection
|
2026-05-16 00:43:31 +03:00
|
|
|
nasRow
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
optionsCard
|
|
|
|
|
actionButton
|
|
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
.padding(.horizontal, AppTheme.hPad)
|
|
|
|
|
.padding(.top, 24)
|
|
|
|
|
.padding(.bottom, 48)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
.task { vm.loadPhotoCount(filter: store.backupFilter) }
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
// MARK: — Ring
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
|
|
|
|
|
private var ringSection: some View {
|
2026-05-16 00:43:31 +03:00
|
|
|
VStack(spacing: 20) {
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
ZStack {
|
|
|
|
|
ProgressRing(
|
|
|
|
|
progress: engine.job.progress,
|
2026-05-16 00:43:31 +03:00
|
|
|
lineWidth: 8,
|
|
|
|
|
size: 180,
|
|
|
|
|
color: ringColor,
|
|
|
|
|
backgroundColor: Color(hex: "#EBEBEB")
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
)
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
VStack(spacing: 3) {
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Text(percentText)
|
2026-05-16 00:43:31 +03:00
|
|
|
.font(.system(size: 40, weight: .semibold, design: .rounded))
|
|
|
|
|
.foregroundStyle(AppTheme.ink)
|
|
|
|
|
.contentTransition(.numericText())
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
|
|
|
|
|
if case .running = engine.job.status {
|
2026-05-16 00:43:31 +03:00
|
|
|
Text("\(engine.job.uploadedFiles + engine.job.skippedFiles) of \(engine.job.totalFiles)")
|
|
|
|
|
.font(AppTheme.caption())
|
|
|
|
|
.foregroundStyle(AppTheme.inkSecondary)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
if let eta = engine.job.eta {
|
2026-05-16 00:43:31 +03:00
|
|
|
Text("~\(etaString(eta)) remaining")
|
|
|
|
|
.font(.system(size: 11, weight: .regular))
|
|
|
|
|
.foregroundStyle(AppTheme.inkTertiary)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Text("\(vm.totalPhotoCount) photos")
|
2026-05-16 00:43:31 +03:00
|
|
|
.font(AppTheme.caption())
|
|
|
|
|
.foregroundStyle(AppTheme.inkSecondary)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Completion summary
|
|
|
|
|
if case .completed = engine.job.status {
|
2026-05-16 00:43:31 +03:00
|
|
|
HStack(spacing: 0) {
|
|
|
|
|
statCell("\(engine.job.uploadedFiles)", label: "uploaded")
|
|
|
|
|
dividerLine
|
|
|
|
|
statCell("\(engine.job.skippedFiles)", label: "skipped")
|
|
|
|
|
dividerLine
|
|
|
|
|
statCell("\(engine.job.failedFiles)", label: "errors",
|
|
|
|
|
color: engine.job.failedFiles > 0 ? AppTheme.destructive : AppTheme.inkTertiary)
|
|
|
|
|
}
|
|
|
|
|
.background(AppTheme.surfaceSunken)
|
|
|
|
|
.clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous))
|
|
|
|
|
.transition(.opacity.combined(with: .scale(scale: 0.95)))
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
// Progress detail
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
if case .running = engine.job.status {
|
2026-05-16 00:43:31 +03:00
|
|
|
VStack(spacing: 8) {
|
|
|
|
|
GeometryReader { geo in
|
|
|
|
|
ZStack(alignment: .leading) {
|
|
|
|
|
RoundedRectangle(cornerRadius: 2, style: .continuous)
|
|
|
|
|
.fill(Color(hex: "#EBEBEB"))
|
|
|
|
|
.frame(height: 3)
|
|
|
|
|
RoundedRectangle(cornerRadius: 2, style: .continuous)
|
|
|
|
|
.fill(AppTheme.ink)
|
|
|
|
|
.frame(width: geo.size.width * engine.job.progress, height: 3)
|
|
|
|
|
.animation(.spring(response: 0.4, dampingFraction: 0.8), value: engine.job.progress)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.frame(height: 3)
|
|
|
|
|
|
|
|
|
|
HStack {
|
|
|
|
|
Text(engine.job.currentFileName)
|
|
|
|
|
.font(.system(size: 12, weight: .regular))
|
|
|
|
|
.foregroundStyle(AppTheme.inkSecondary)
|
|
|
|
|
.lineLimit(1)
|
|
|
|
|
.truncationMode(.middle)
|
|
|
|
|
Spacer()
|
|
|
|
|
Text(formatSpeed(engine.job.speedBytesPerSecond))
|
|
|
|
|
.font(.system(size: 12, weight: .regular))
|
|
|
|
|
.foregroundStyle(AppTheme.inkTertiary)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.transition(.opacity)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
.animation(.spring(response: 0.4, dampingFraction: 0.8), value: engine.job.status == .completed)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private var ringColor: Color {
|
|
|
|
|
switch engine.job.status {
|
2026-05-16 00:43:31 +03:00
|
|
|
case .completed: return AppTheme.positive
|
|
|
|
|
case .failed: return AppTheme.destructive
|
|
|
|
|
default: return AppTheme.ink
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
private var percentText: String { "\(Int(engine.job.progress * 100))%" }
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
private func statCell(_ value: String, label: String, color: Color = AppTheme.ink) -> some View {
|
|
|
|
|
VStack(spacing: 2) {
|
|
|
|
|
Text(value)
|
|
|
|
|
.font(.system(size: 18, weight: .semibold))
|
|
|
|
|
.foregroundStyle(color)
|
|
|
|
|
Text(label)
|
|
|
|
|
.font(AppTheme.micro())
|
|
|
|
|
.foregroundStyle(AppTheme.inkTertiary)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
.frame(maxWidth: .infinity)
|
|
|
|
|
.padding(.vertical, 14)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
private var dividerLine: some View {
|
|
|
|
|
Rectangle()
|
|
|
|
|
.fill(AppTheme.separator)
|
|
|
|
|
.frame(width: 0.5)
|
|
|
|
|
.padding(.vertical, 12)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
// MARK: — NAS row
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
private var nasRow: some View {
|
|
|
|
|
HStack(spacing: 10) {
|
|
|
|
|
ZStack {
|
|
|
|
|
Circle()
|
|
|
|
|
.fill(AppTheme.surfaceSunken)
|
|
|
|
|
.frame(width: 32, height: 32)
|
|
|
|
|
Image(systemName: "externaldrive")
|
|
|
|
|
.font(.system(size: 13, weight: .medium))
|
|
|
|
|
.foregroundStyle(AppTheme.inkSecondary)
|
|
|
|
|
}
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
|
|
|
|
|
if let conn = store.savedConnection {
|
2026-05-16 00:43:31 +03:00
|
|
|
VStack(alignment: .leading, spacing: 1) {
|
|
|
|
|
Text(conn.host)
|
|
|
|
|
.font(AppTheme.headline())
|
|
|
|
|
.foregroundStyle(AppTheme.ink)
|
|
|
|
|
Text(conn.username)
|
|
|
|
|
.font(AppTheme.caption())
|
|
|
|
|
.foregroundStyle(AppTheme.inkSecondary)
|
|
|
|
|
}
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Spacer()
|
2026-05-16 00:43:31 +03:00
|
|
|
|
|
|
|
|
HStack(spacing: 5) {
|
|
|
|
|
Circle()
|
|
|
|
|
.fill(AppTheme.positive)
|
|
|
|
|
.frame(width: 6, height: 6)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Text("Live")
|
2026-05-16 00:43:31 +03:00
|
|
|
.font(AppTheme.micro())
|
|
|
|
|
.foregroundStyle(AppTheme.positive)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.padding(14)
|
2026-05-16 00:43:31 +03:00
|
|
|
.background(AppTheme.surfaceSunken)
|
|
|
|
|
.clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous))
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
// MARK: — Options
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
|
|
|
|
|
private var optionsCard: some View {
|
|
|
|
|
VStack(spacing: 0) {
|
2026-05-16 00:43:31 +03:00
|
|
|
optionRow(icon: "camera", label: "What to back up") {}
|
|
|
|
|
hairline
|
|
|
|
|
optionRow(icon: "doc.badge.clock", label: "New files only") {}
|
|
|
|
|
hairline
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Button(action: { Task { await vm.requestPhotosAccess() } }) {
|
|
|
|
|
HStack {
|
|
|
|
|
Image(systemName: "photo.on.rectangle")
|
2026-05-16 00:43:31 +03:00
|
|
|
.font(.system(size: 14, weight: .regular))
|
|
|
|
|
.foregroundStyle(vm.photosAuthStatus == .authorized
|
|
|
|
|
? AppTheme.inkSecondary : AppTheme.destructive)
|
|
|
|
|
.frame(width: 20)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Text("Photos access")
|
2026-05-16 00:43:31 +03:00
|
|
|
.font(AppTheme.body())
|
|
|
|
|
.foregroundStyle(AppTheme.ink)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Spacer()
|
2026-05-16 00:43:31 +03:00
|
|
|
Text(photosLabel)
|
|
|
|
|
.font(AppTheme.caption())
|
|
|
|
|
.foregroundStyle(vm.photosAuthStatus == .authorized
|
|
|
|
|
? AppTheme.positive : AppTheme.destructive)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Image(systemName: "chevron.right")
|
2026-05-16 00:43:31 +03:00
|
|
|
.font(.system(size: 12, weight: .medium))
|
|
|
|
|
.foregroundStyle(AppTheme.inkQuaternary)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
.padding(.horizontal, 16)
|
|
|
|
|
.padding(.vertical, 14)
|
|
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
.buttonStyle(ScaleButtonStyle())
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
.background(Color.white)
|
2026-05-16 00:43:31 +03:00
|
|
|
.clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous))
|
|
|
|
|
.shadow(color: AppTheme.cardShadow, radius: 12, x: 0, y: 2)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
private var photosLabel: String {
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
switch vm.photosAuthStatus {
|
|
|
|
|
case .authorized: return "Full access"
|
|
|
|
|
case .limited: return "Limited"
|
|
|
|
|
case .denied: return "Denied"
|
|
|
|
|
default: return "Not set"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
private var hairline: some View {
|
|
|
|
|
Rectangle()
|
|
|
|
|
.fill(AppTheme.separator)
|
|
|
|
|
.frame(height: 0.5)
|
|
|
|
|
.padding(.leading, 36)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func optionRow(icon: String, label: String, action: @escaping () -> Void) -> some View {
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Button(action: action) {
|
|
|
|
|
HStack {
|
|
|
|
|
Image(systemName: icon)
|
2026-05-16 00:43:31 +03:00
|
|
|
.font(.system(size: 14, weight: .regular))
|
|
|
|
|
.foregroundStyle(AppTheme.inkSecondary)
|
|
|
|
|
.frame(width: 20)
|
|
|
|
|
Text(label)
|
|
|
|
|
.font(AppTheme.body())
|
|
|
|
|
.foregroundStyle(AppTheme.ink)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Spacer()
|
|
|
|
|
Image(systemName: "chevron.right")
|
2026-05-16 00:43:31 +03:00
|
|
|
.font(.system(size: 12, weight: .medium))
|
|
|
|
|
.foregroundStyle(AppTheme.inkQuaternary)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
.padding(.horizontal, 16)
|
|
|
|
|
.padding(.vertical, 14)
|
|
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
.buttonStyle(ScaleButtonStyle())
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-16 00:43:31 +03:00
|
|
|
// MARK: — Action button
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
|
|
|
|
|
private var actionButton: some View {
|
|
|
|
|
Group {
|
|
|
|
|
switch engine.job.status {
|
|
|
|
|
case .idle, .completed, .failed, .cancelled:
|
|
|
|
|
Button(action: startBackup) {
|
|
|
|
|
Text(engine.job.status == .completed ? "Back up again" : "Start backup")
|
|
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
.buttonStyle(PrimaryButtonStyle(
|
|
|
|
|
color: engine.job.status == .completed ? AppTheme.positive : AppTheme.ink
|
|
|
|
|
))
|
|
|
|
|
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
case .running:
|
2026-05-16 00:43:31 +03:00
|
|
|
Button { engine.pause() } label: { Text("Pause") }
|
|
|
|
|
.buttonStyle(GhostButtonStyle())
|
|
|
|
|
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
case .paused:
|
2026-05-16 00:43:31 +03:00
|
|
|
HStack(spacing: 10) {
|
|
|
|
|
Button { engine.resume() } label: { Text("Resume") }
|
|
|
|
|
.buttonStyle(PrimaryButtonStyle())
|
|
|
|
|
Button { engine.cancel() } label: { Text("Cancel") }
|
|
|
|
|
.buttonStyle(GhostButtonStyle())
|
|
|
|
|
.frame(width: 90)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
case .preparing:
|
2026-05-16 00:43:31 +03:00
|
|
|
HStack(spacing: 8) {
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
ProgressView()
|
2026-05-16 00:43:31 +03:00
|
|
|
.scaleEffect(0.8)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
Text("Preparing…")
|
2026-05-16 00:43:31 +03:00
|
|
|
.font(AppTheme.body())
|
|
|
|
|
.foregroundStyle(AppTheme.inkSecondary)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
.frame(height: 50)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
}
|
2026-05-16 00:43:31 +03:00
|
|
|
.animation(.spring(response: 0.3, dampingFraction: 0.8), value: engine.job.status == .running)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func startBackup() {
|
|
|
|
|
guard let conn = store.savedConnection else { return }
|
2026-05-16 00:43:31 +03:00
|
|
|
Task { _ = try? await engine.run(connection: conn, filter: store.backupFilter) }
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func formatSpeed(_ bps: Double) -> String {
|
2026-05-16 00:43:31 +03:00
|
|
|
bps >= 1_000_000
|
|
|
|
|
? String(format: "%.1f MB/s", bps / 1_000_000)
|
|
|
|
|
: String(format: "%.0f KB/s", bps / 1_000)
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func etaString(_ seconds: TimeInterval) -> String {
|
2026-05-16 00:43:31 +03:00
|
|
|
Int(seconds) / 60 > 0 ? "\(Int(seconds) / 60)m" : "\(Int(seconds))s"
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
}
|
|
|
|
|
}
|