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
|
feat: Kisani rebrand, step-based onboarding flow, dark mode fixes
- Rename app to Kisani in all UI text and Face ID prompt
- Replace flat 2-state RootView with 5-step flow: ConnectView →
LoginView → FolderSetupView → PhotoPermissionView → MainTabView
- Remove NavigationStack from LoginView (was causing nested-stack crash);
drive navigation via ConnectionStore.isSessionActive
- Add FolderSetupView and PhotoPermissionView onboarding screens with
step indicator (2/3, 3/3), spring entrance animations, and UGreen
connection chip
- Fix dark mode button invisibility: PrimaryButtonStyle and PillButtonStyle
now use AppTheme.inkInverse; GhostButtonStyle border uses ink.opacity(0.25)
- Add AppTheme.inkInverse adaptive token (dark bg ink on dark, white on light)
- Add ConnectionStore.isSessionActive (non-persisted) and
onboardingPhotoShown (UserDefaults-persisted)
- Add os_log logging in LoginViewModel at auth start/success/failure
- Remove dead Help button from ConnectView
- UGreenCompatibilityBadge, KeychainStore, SavedConnections, extensions,
PrivacyInfo.xcprivacy, unit test target and test stubs
- AppTheme: full UIColor dynamic provider tokens for dark/light adaptive color
- AppearanceMode enum + segmented picker in SettingsView
- BackupView: enlarged ring, removed options card and linear progress bar
- HistoryView: duration and bytes formatting, improved typography hierarchy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:20:53 +03:00
|
|
|
import UIKit
|
|
|
|
|
|
|
|
|
|
// MARK: — Appearance preference
|
|
|
|
|
|
|
|
|
|
enum AppearanceMode: String, CaseIterable {
|
|
|
|
|
case system, light, dark
|
|
|
|
|
|
|
|
|
|
var resolvedScheme: ColorScheme? {
|
|
|
|
|
switch self {
|
|
|
|
|
case .system: return nil
|
|
|
|
|
case .light: return .light
|
|
|
|
|
case .dark: return .dark
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var label: String {
|
|
|
|
|
switch self {
|
|
|
|
|
case .system: return "System"
|
|
|
|
|
case .light: return "Light"
|
|
|
|
|
case .dark: return "Dark"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var icon: String {
|
|
|
|
|
switch self {
|
|
|
|
|
case .system: return "circle.lefthalf.filled"
|
|
|
|
|
case .light: return "sun.max"
|
|
|
|
|
case .dark: return "moon"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
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
|
|
|
|
|
|
|
|
enum AppTheme {
|
2026-05-16 00:43:31 +03:00
|
|
|
// MARK: — Surfaces
|
feat: Kisani rebrand, step-based onboarding flow, dark mode fixes
- Rename app to Kisani in all UI text and Face ID prompt
- Replace flat 2-state RootView with 5-step flow: ConnectView →
LoginView → FolderSetupView → PhotoPermissionView → MainTabView
- Remove NavigationStack from LoginView (was causing nested-stack crash);
drive navigation via ConnectionStore.isSessionActive
- Add FolderSetupView and PhotoPermissionView onboarding screens with
step indicator (2/3, 3/3), spring entrance animations, and UGreen
connection chip
- Fix dark mode button invisibility: PrimaryButtonStyle and PillButtonStyle
now use AppTheme.inkInverse; GhostButtonStyle border uses ink.opacity(0.25)
- Add AppTheme.inkInverse adaptive token (dark bg ink on dark, white on light)
- Add ConnectionStore.isSessionActive (non-persisted) and
onboardingPhotoShown (UserDefaults-persisted)
- Add os_log logging in LoginViewModel at auth start/success/failure
- Remove dead Help button from ConnectView
- UGreenCompatibilityBadge, KeychainStore, SavedConnections, extensions,
PrivacyInfo.xcprivacy, unit test target and test stubs
- AppTheme: full UIColor dynamic provider tokens for dark/light adaptive color
- AppearanceMode enum + segmented picker in SettingsView
- BackupView: enlarged ring, removed options card and linear progress bar
- HistoryView: duration and bytes formatting, improved typography hierarchy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:20:53 +03:00
|
|
|
static let background = Color(UIColor.systemBackground)
|
|
|
|
|
static let surfaceRaised = Color(UIColor.systemBackground)
|
|
|
|
|
static let surfaceSunken = Color(UIColor { t in
|
|
|
|
|
t.userInterfaceStyle == .dark
|
|
|
|
|
? UIColor(white: 0.11, alpha: 1)
|
|
|
|
|
: UIColor(white: 0.961, alpha: 1)
|
|
|
|
|
})
|
2026-05-16 00:43:31 +03:00
|
|
|
|
|
|
|
|
// MARK: — Ink
|
feat: Kisani rebrand, step-based onboarding flow, dark mode fixes
- Rename app to Kisani in all UI text and Face ID prompt
- Replace flat 2-state RootView with 5-step flow: ConnectView →
LoginView → FolderSetupView → PhotoPermissionView → MainTabView
- Remove NavigationStack from LoginView (was causing nested-stack crash);
drive navigation via ConnectionStore.isSessionActive
- Add FolderSetupView and PhotoPermissionView onboarding screens with
step indicator (2/3, 3/3), spring entrance animations, and UGreen
connection chip
- Fix dark mode button invisibility: PrimaryButtonStyle and PillButtonStyle
now use AppTheme.inkInverse; GhostButtonStyle border uses ink.opacity(0.25)
- Add AppTheme.inkInverse adaptive token (dark bg ink on dark, white on light)
- Add ConnectionStore.isSessionActive (non-persisted) and
onboardingPhotoShown (UserDefaults-persisted)
- Add os_log logging in LoginViewModel at auth start/success/failure
- Remove dead Help button from ConnectView
- UGreenCompatibilityBadge, KeychainStore, SavedConnections, extensions,
PrivacyInfo.xcprivacy, unit test target and test stubs
- AppTheme: full UIColor dynamic provider tokens for dark/light adaptive color
- AppearanceMode enum + segmented picker in SettingsView
- BackupView: enlarged ring, removed options card and linear progress bar
- HistoryView: duration and bytes formatting, improved typography hierarchy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:20:53 +03:00
|
|
|
static let ink = Color(UIColor { t in
|
|
|
|
|
t.userInterfaceStyle == .dark
|
|
|
|
|
? UIColor(white: 0.93, alpha: 1)
|
|
|
|
|
: UIColor(red: 0.059, green: 0.059, blue: 0.059, alpha: 1)
|
|
|
|
|
})
|
|
|
|
|
static let inkSecondary = Color(UIColor { t in
|
|
|
|
|
t.userInterfaceStyle == .dark
|
|
|
|
|
? UIColor(white: 0.58, alpha: 1)
|
|
|
|
|
: UIColor(white: 0.42, alpha: 1)
|
|
|
|
|
})
|
|
|
|
|
static let inkTertiary = Color(UIColor { t in
|
|
|
|
|
t.userInterfaceStyle == .dark
|
|
|
|
|
? UIColor(white: 0.40, alpha: 1)
|
|
|
|
|
: UIColor(white: 0.67, alpha: 1)
|
|
|
|
|
})
|
|
|
|
|
static let inkQuaternary = Color(UIColor { t in
|
|
|
|
|
t.userInterfaceStyle == .dark
|
|
|
|
|
? UIColor(white: 0.22, alpha: 1)
|
|
|
|
|
: UIColor(white: 0.83, alpha: 1)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Readable on AppTheme.ink background in both color schemes
|
|
|
|
|
static let inkInverse = Color(UIColor { t in
|
|
|
|
|
t.userInterfaceStyle == .dark
|
|
|
|
|
? UIColor(red: 0.059, green: 0.059, blue: 0.059, alpha: 1)
|
|
|
|
|
: UIColor(white: 1.0, alpha: 1)
|
|
|
|
|
})
|
2026-05-16 00:43:31 +03:00
|
|
|
|
|
|
|
|
// MARK: — Semantic
|
feat: Kisani rebrand, step-based onboarding flow, dark mode fixes
- Rename app to Kisani in all UI text and Face ID prompt
- Replace flat 2-state RootView with 5-step flow: ConnectView →
LoginView → FolderSetupView → PhotoPermissionView → MainTabView
- Remove NavigationStack from LoginView (was causing nested-stack crash);
drive navigation via ConnectionStore.isSessionActive
- Add FolderSetupView and PhotoPermissionView onboarding screens with
step indicator (2/3, 3/3), spring entrance animations, and UGreen
connection chip
- Fix dark mode button invisibility: PrimaryButtonStyle and PillButtonStyle
now use AppTheme.inkInverse; GhostButtonStyle border uses ink.opacity(0.25)
- Add AppTheme.inkInverse adaptive token (dark bg ink on dark, white on light)
- Add ConnectionStore.isSessionActive (non-persisted) and
onboardingPhotoShown (UserDefaults-persisted)
- Add os_log logging in LoginViewModel at auth start/success/failure
- Remove dead Help button from ConnectView
- UGreenCompatibilityBadge, KeychainStore, SavedConnections, extensions,
PrivacyInfo.xcprivacy, unit test target and test stubs
- AppTheme: full UIColor dynamic provider tokens for dark/light adaptive color
- AppearanceMode enum + segmented picker in SettingsView
- BackupView: enlarged ring, removed options card and linear progress bar
- HistoryView: duration and bytes formatting, improved typography hierarchy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:20:53 +03:00
|
|
|
static let positive = Color(hex: "#16A34A")
|
|
|
|
|
static let destructive = Color(hex: "#DC2626")
|
|
|
|
|
static let interactive = Color(hex: "#2563EB")
|
2026-05-16 00:43:31 +03:00
|
|
|
|
|
|
|
|
// MARK: — Chrome
|
feat: Kisani rebrand, step-based onboarding flow, dark mode fixes
- Rename app to Kisani in all UI text and Face ID prompt
- Replace flat 2-state RootView with 5-step flow: ConnectView →
LoginView → FolderSetupView → PhotoPermissionView → MainTabView
- Remove NavigationStack from LoginView (was causing nested-stack crash);
drive navigation via ConnectionStore.isSessionActive
- Add FolderSetupView and PhotoPermissionView onboarding screens with
step indicator (2/3, 3/3), spring entrance animations, and UGreen
connection chip
- Fix dark mode button invisibility: PrimaryButtonStyle and PillButtonStyle
now use AppTheme.inkInverse; GhostButtonStyle border uses ink.opacity(0.25)
- Add AppTheme.inkInverse adaptive token (dark bg ink on dark, white on light)
- Add ConnectionStore.isSessionActive (non-persisted) and
onboardingPhotoShown (UserDefaults-persisted)
- Add os_log logging in LoginViewModel at auth start/success/failure
- Remove dead Help button from ConnectView
- UGreenCompatibilityBadge, KeychainStore, SavedConnections, extensions,
PrivacyInfo.xcprivacy, unit test target and test stubs
- AppTheme: full UIColor dynamic provider tokens for dark/light adaptive color
- AppearanceMode enum + segmented picker in SettingsView
- BackupView: enlarged ring, removed options card and linear progress bar
- HistoryView: duration and bytes formatting, improved typography hierarchy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:20:53 +03:00
|
|
|
static let separator = Color(UIColor.separator)
|
|
|
|
|
static let cardShadow = Color(UIColor { t in
|
|
|
|
|
t.userInterfaceStyle == .dark
|
|
|
|
|
? UIColor.clear
|
|
|
|
|
: UIColor.black.withAlphaComponent(0.048)
|
|
|
|
|
})
|
|
|
|
|
static let cardBorderColor = Color(UIColor.separator)
|
2026-05-16 00:43:31 +03:00
|
|
|
|
|
|
|
|
// MARK: — Metrics
|
feat: Kisani rebrand, step-based onboarding flow, dark mode fixes
- Rename app to Kisani in all UI text and Face ID prompt
- Replace flat 2-state RootView with 5-step flow: ConnectView →
LoginView → FolderSetupView → PhotoPermissionView → MainTabView
- Remove NavigationStack from LoginView (was causing nested-stack crash);
drive navigation via ConnectionStore.isSessionActive
- Add FolderSetupView and PhotoPermissionView onboarding screens with
step indicator (2/3, 3/3), spring entrance animations, and UGreen
connection chip
- Fix dark mode button invisibility: PrimaryButtonStyle and PillButtonStyle
now use AppTheme.inkInverse; GhostButtonStyle border uses ink.opacity(0.25)
- Add AppTheme.inkInverse adaptive token (dark bg ink on dark, white on light)
- Add ConnectionStore.isSessionActive (non-persisted) and
onboardingPhotoShown (UserDefaults-persisted)
- Add os_log logging in LoginViewModel at auth start/success/failure
- Remove dead Help button from ConnectView
- UGreenCompatibilityBadge, KeychainStore, SavedConnections, extensions,
PrivacyInfo.xcprivacy, unit test target and test stubs
- AppTheme: full UIColor dynamic provider tokens for dark/light adaptive color
- AppearanceMode enum + segmented picker in SettingsView
- BackupView: enlarged ring, removed options card and linear progress bar
- HistoryView: duration and bytes formatting, improved typography hierarchy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:20:53 +03:00
|
|
|
static let radius: CGFloat = 14
|
|
|
|
|
static let radiusLarge: CGFloat = 18
|
|
|
|
|
static let hPad: CGFloat = 20
|
|
|
|
|
static let cardPad: CGFloat = 16
|
|
|
|
|
static let sectionGap: CGFloat = 28
|
2026-05-16 00:43:31 +03:00
|
|
|
|
|
|
|
|
// MARK: — Typography
|
|
|
|
|
static func display(_ size: CGFloat = 32) -> Font {
|
|
|
|
|
.system(size: size, weight: .semibold, design: .default)
|
|
|
|
|
}
|
feat: Kisani rebrand, step-based onboarding flow, dark mode fixes
- Rename app to Kisani in all UI text and Face ID prompt
- Replace flat 2-state RootView with 5-step flow: ConnectView →
LoginView → FolderSetupView → PhotoPermissionView → MainTabView
- Remove NavigationStack from LoginView (was causing nested-stack crash);
drive navigation via ConnectionStore.isSessionActive
- Add FolderSetupView and PhotoPermissionView onboarding screens with
step indicator (2/3, 3/3), spring entrance animations, and UGreen
connection chip
- Fix dark mode button invisibility: PrimaryButtonStyle and PillButtonStyle
now use AppTheme.inkInverse; GhostButtonStyle border uses ink.opacity(0.25)
- Add AppTheme.inkInverse adaptive token (dark bg ink on dark, white on light)
- Add ConnectionStore.isSessionActive (non-persisted) and
onboardingPhotoShown (UserDefaults-persisted)
- Add os_log logging in LoginViewModel at auth start/success/failure
- Remove dead Help button from ConnectView
- UGreenCompatibilityBadge, KeychainStore, SavedConnections, extensions,
PrivacyInfo.xcprivacy, unit test target and test stubs
- AppTheme: full UIColor dynamic provider tokens for dark/light adaptive color
- AppearanceMode enum + segmented picker in SettingsView
- BackupView: enlarged ring, removed options card and linear progress bar
- HistoryView: duration and bytes formatting, improved typography hierarchy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:20:53 +03:00
|
|
|
static func title(_ size: CGFloat = 20) -> Font { .system(size: size, weight: .semibold) }
|
|
|
|
|
static func headline(_ size: CGFloat = 15) -> Font { .system(size: size, weight: .medium) }
|
|
|
|
|
static func body(_ size: CGFloat = 15) -> Font { .system(size: size, weight: .regular) }
|
|
|
|
|
static func caption(_ size: CGFloat = 13) -> Font { .system(size: size, weight: .regular) }
|
|
|
|
|
static func micro(_ size: CGFloat = 11) -> Font { .system(size: size, weight: .medium) }
|
2026-05-16 00:43:31 +03:00
|
|
|
|
feat: Kisani rebrand, step-based onboarding flow, dark mode fixes
- Rename app to Kisani in all UI text and Face ID prompt
- Replace flat 2-state RootView with 5-step flow: ConnectView →
LoginView → FolderSetupView → PhotoPermissionView → MainTabView
- Remove NavigationStack from LoginView (was causing nested-stack crash);
drive navigation via ConnectionStore.isSessionActive
- Add FolderSetupView and PhotoPermissionView onboarding screens with
step indicator (2/3, 3/3), spring entrance animations, and UGreen
connection chip
- Fix dark mode button invisibility: PrimaryButtonStyle and PillButtonStyle
now use AppTheme.inkInverse; GhostButtonStyle border uses ink.opacity(0.25)
- Add AppTheme.inkInverse adaptive token (dark bg ink on dark, white on light)
- Add ConnectionStore.isSessionActive (non-persisted) and
onboardingPhotoShown (UserDefaults-persisted)
- Add os_log logging in LoginViewModel at auth start/success/failure
- Remove dead Help button from ConnectView
- UGreenCompatibilityBadge, KeychainStore, SavedConnections, extensions,
PrivacyInfo.xcprivacy, unit test target and test stubs
- AppTheme: full UIColor dynamic provider tokens for dark/light adaptive color
- AppearanceMode enum + segmented picker in SettingsView
- BackupView: enlarged ring, removed options card and linear progress bar
- HistoryView: duration and bytes formatting, improved typography hierarchy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:20:53 +03:00
|
|
|
// MARK: — Back-compat aliases
|
2026-05-16 00:43:31 +03:00
|
|
|
static let blue = interactive
|
|
|
|
|
static let green = positive
|
|
|
|
|
static let red = destructive
|
|
|
|
|
static let textPrimary = ink
|
|
|
|
|
static let textSecondary = inkSecondary
|
|
|
|
|
static let textTertiary = inkTertiary
|
|
|
|
|
static let cardBorder = cardBorderColor
|
|
|
|
|
static let connectedBorder = positive
|
|
|
|
|
static let lanBorder = interactive
|
|
|
|
|
static let cardCornerRadius = radius
|
|
|
|
|
static let cardBackground = surfaceRaised
|
|
|
|
|
static let titleFont = Font.system(size: 28, weight: .bold)
|
|
|
|
|
static let headlineFont = Font.system(size: 17, weight: .semibold)
|
|
|
|
|
static let bodyFont = Font.system(size: 15, weight: .regular)
|
|
|
|
|
static let captionFont = Font.system(size: 13, weight: .regular)
|
|
|
|
|
static let smallFont = Font.system(size: 11, weight: .medium)
|
|
|
|
|
static let sectionSpacing: CGFloat = 28
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MARK: — Card modifier
|
|
|
|
|
struct CardStyle: ViewModifier {
|
|
|
|
|
var padded: Bool = true
|
|
|
|
|
func body(content: Content) -> some View {
|
|
|
|
|
content
|
|
|
|
|
.if(padded) { $0.padding(AppTheme.cardPad) }
|
|
|
|
|
.background(AppTheme.surfaceRaised)
|
|
|
|
|
.clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous))
|
|
|
|
|
.shadow(color: AppTheme.cardShadow, radius: 12, x: 0, y: 2)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension View {
|
feat: Kisani rebrand, step-based onboarding flow, dark mode fixes
- Rename app to Kisani in all UI text and Face ID prompt
- Replace flat 2-state RootView with 5-step flow: ConnectView →
LoginView → FolderSetupView → PhotoPermissionView → MainTabView
- Remove NavigationStack from LoginView (was causing nested-stack crash);
drive navigation via ConnectionStore.isSessionActive
- Add FolderSetupView and PhotoPermissionView onboarding screens with
step indicator (2/3, 3/3), spring entrance animations, and UGreen
connection chip
- Fix dark mode button invisibility: PrimaryButtonStyle and PillButtonStyle
now use AppTheme.inkInverse; GhostButtonStyle border uses ink.opacity(0.25)
- Add AppTheme.inkInverse adaptive token (dark bg ink on dark, white on light)
- Add ConnectionStore.isSessionActive (non-persisted) and
onboardingPhotoShown (UserDefaults-persisted)
- Add os_log logging in LoginViewModel at auth start/success/failure
- Remove dead Help button from ConnectView
- UGreenCompatibilityBadge, KeychainStore, SavedConnections, extensions,
PrivacyInfo.xcprivacy, unit test target and test stubs
- AppTheme: full UIColor dynamic provider tokens for dark/light adaptive color
- AppearanceMode enum + segmented picker in SettingsView
- BackupView: enlarged ring, removed options card and linear progress bar
- HistoryView: duration and bytes formatting, improved typography hierarchy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:20:53 +03:00
|
|
|
func card(padded: Bool = true) -> some View { modifier(CardStyle(padded: padded)) }
|
2026-05-16 00:43:31 +03:00
|
|
|
|
|
|
|
|
@ViewBuilder func `if`<T: View>(_ condition: Bool, transform: (Self) -> T) -> some View {
|
|
|
|
|
if condition { transform(self) } else { self }
|
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension Color {
|
|
|
|
|
init(hex: String) {
|
|
|
|
|
var h = hex.trimmingCharacters(in: .init(charactersIn: "#"))
|
|
|
|
|
if h.count == 3 { h = h.map { "\($0)\($0)" }.joined() }
|
|
|
|
|
let n = UInt64(h, radix: 16) ?? 0
|
2026-05-16 00:43:31 +03:00
|
|
|
self.init(
|
|
|
|
|
red: Double((n >> 16) & 0xFF) / 255,
|
|
|
|
|
green: Double((n >> 8) & 0xFF) / 255,
|
|
|
|
|
blue: Double( n & 0xFF) / 255
|
|
|
|
|
)
|
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
|
|
|
}
|
|
|
|
|
}
|