fix: SMB share enumeration, BrowseView polish, sign out, Login branding
- Fix "Bad Network Name": BrowseView at root "/" for SMB now calls listShares() instead of listDirectory with empty share name. SMBClient.listShares() filters IPC/admin/hidden ($) shares. - Add listShares() to NASTransferProtocol; implement in SMB (filters ipc/special/$-suffix) and SFTP (returns []). - BrowseView: premium error state (wifi.exclamationmark icon + Retry button with ScaleButtonStyle), empty state, safeAreaInset bottom bar replacing toolbar bottomBar (shows current path chip + compact Select button), proper disabled state for root selection on SMB. - FolderRow: replace hardcoded .white with AppTheme.inkInverse for dark mode correctness; use folder.fill icon; ScaleButtonStyle for tap feedback. - LoginView: larger logo (80pt), bolder "Kisani" wordmark (32pt bold), tagline, staggered spring entrance animations (0.08-0.36s delay). - SettingsView: Sign Out button in ACCOUNT section with confirmationDialog (destructive, clears connection + resets session). - ConnectionStore: signOut() resets isSessionActive, onboardingPhotoShown, and clears savedConnection (triggers Keychain delete). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import SwiftUI
|
||||
struct SettingsView: View {
|
||||
@EnvironmentObject var store: ConnectionStore
|
||||
@EnvironmentObject var lanMonitor: LANMonitor
|
||||
@State private var showSignOutConfirm = false
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
@@ -17,6 +18,7 @@ struct SettingsView: View {
|
||||
connectivitySection
|
||||
remoteAccessSection
|
||||
notificationSection
|
||||
signOutSection
|
||||
}
|
||||
.padding(.horizontal, AppTheme.hPad)
|
||||
.padding(.top, 20)
|
||||
@@ -25,6 +27,16 @@ struct SettingsView: View {
|
||||
}
|
||||
.navigationTitle("Settings")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.confirmationDialog(
|
||||
"Sign out of Kisani?",
|
||||
isPresented: $showSignOutConfirm,
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Sign Out & Forget NAS", role: .destructive) { store.signOut() }
|
||||
Button("Cancel", role: .cancel) {}
|
||||
} message: {
|
||||
Text("Your NAS connection and backup settings will be removed from this device.")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: — Appearance
|
||||
@@ -305,4 +317,38 @@ struct SettingsView: View {
|
||||
.frame(height: 0.5)
|
||||
.padding(.leading, AppTheme.cardPad)
|
||||
}
|
||||
|
||||
// MARK: — Sign Out
|
||||
|
||||
private var signOutSection: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
sectionLabel("ACCOUNT")
|
||||
|
||||
Button(action: { showSignOutConfirm = true }) {
|
||||
HStack(spacing: 12) {
|
||||
Image(systemName: "rectangle.portrait.and.arrow.right")
|
||||
.font(.system(size: 14, weight: .regular))
|
||||
.foregroundStyle(AppTheme.destructive)
|
||||
.frame(width: 20)
|
||||
Text("Sign Out")
|
||||
.font(AppTheme.body())
|
||||
.foregroundStyle(AppTheme.destructive)
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, AppTheme.cardPad)
|
||||
.padding(.vertical, 14)
|
||||
.background(AppTheme.surfaceRaised)
|
||||
.clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous))
|
||||
.shadow(color: AppTheme.cardShadow, radius: 12, x: 0, y: 2)
|
||||
}
|
||||
.buttonStyle(ScaleButtonStyle())
|
||||
}
|
||||
}
|
||||
|
||||
private func sectionLabel(_ text: String) -> some View {
|
||||
Text(text)
|
||||
.font(AppTheme.micro())
|
||||
.foregroundStyle(AppTheme.inkTertiary)
|
||||
.padding(.leading, 4)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user