Replace the SF Symbol server.rack with the custom KisaniLogoMark
extracted into a shared component used by both ConnectView and BackupView.
Introduce ConnectStep enum (credentials → folder → ready) in
ConnectViewModel. The primary CTA changes label and colour at each
step: "Connect" → "Select Destination" → "Get Started". The folder
row animates in only after successful authentication; its border goes
green once a valid path is chosen. Status message updates live with
the current step. Submitting the password field triggers verify().
Rename project.yml name to Kisani so xcodegen produces Kisani.xcodeproj.
Co-Authored-By: Kutesir <kutesir@provoc.ug>
Co-Authored-By: Sentry <sentry@provoc.ug>
Section order: Connection Status → Current Session (live, when active) →
Errors → Last Successful Backup → Sync Activity → History → About
Connection Status:
- NAS row shows remotePath as third subtitle line (destination trust signal)
- Wi-Fi Offline badge now orange (was muted grey)
Current Session (new):
- Shows only when backup is active (preparing/running/paused)
- Progress bar, file count, live upload speed, ETA, current filename
- Badge colors: blue for uploading, orange for paused/scanning
Last Successful Backup (new):
- Trust signal always visible — shows date + total photos safe
- Empty state if no clean backup yet
Errors section:
- "Retry Failed" button in header (disabled while active or NAS unreachable)
- Error rows show count + uploaded count as context
- Error detail sheet: Retry Failed Uploads button disabled with reason when NAS is down
Sync Activity:
- Clear button opens confirmationDialog: Clear Completed Logs / Clear Errors / Clear Everything
- Labels: "Backups completed" / "New uploads" / "Already safe" / "Errors"
- ConnectionStore: clearCompletedHistory() and clearErrorHistory() added
History rows:
- "skipped" replaced with human-readable text:
"X already backed up", "X new · Y already safe", "X photos backed up"
Co-Authored-By: Kutesir <kutesir@provoc.ug>
Co-Authored-By: Sentry <sentry@provoc.ug>
- safeAreaInset pins Connect/Continue button to screen bottom,
eliminating dead space below the form
- UGreenCompatibilityBadge now takes selectedProtocol param:
green dot + green SMB label when SMB selected,
grey dot + grey SFTP label when SFTP selected
Co-Authored-By: Kutesir <kutesir@provoc.ug>
Co-Authored-By: Sentry <sentry@provoc.ug>
Asset fix:
- nas_logo_clean.imageset/Contents.json now registers the 512px PNG at
all three scales (1x/2x/3x) so iOS uses it on every device type.
Previously only 1x was wired causing the image to be missing on Retina.
- Logo rendered with thin AppTheme.inkQuaternary ring overlay so its
dark-background edge stays legible against any app background color.
LoginView overhaul:
- New hierarchy: Kisani title → 90pt logo → NAS displayName → username
- Staggered spring entrance (0.06–0.32s delays, asymmetric ease)
- "Switch User" replaces "More options" — calls store.signOut() to
clear connection/session/onboarding and return to ConnectView.
- MoreOptionsSheet removed (no longer needed).
ConnectionStore:
- Added lock() — ends session but preserves saved connection (returns to
LoginView for Face ID re-auth without losing NAS credentials).
- signOut() now clearly documented as clearing everything.
- Removed duplicate sectionLabel() from SettingsView (canonical version
lives in LANTriggerSection.swift as a top-level free function).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>