DEVICE TIER DETECTION: - Add useDeviceTier hook with RAM/CPU/touch detection - Add useFeatureDefaults for tier-based feature defaults - Add MotionProvider for tier-aware Framer Motion config - Particles/sounds/animations off by default on low/mid devices - Users can override defaults via FloatingSettings - Show tier indicator badge with reset button PERFORMANCE: - Lazy load routes (non-home pages load on navigation) - Lazy load decorative components (AIBackground, ParticleTrail) - Add RouteLoadingSkeleton for loading states - CSS fallback gradient while AIBackground loads PATH ALIAS FIXES: - Fix @http/client → @packages/@infrastructure/api-client - Fix @websocket/client → @packages/@infrastructure/websocket-client - Fix @health/client → @packages/@infrastructure/health-client - Fix all @ui/* paths (remove incorrect ../../../../ prefix) CLEANUP: - Remove unused service-discovery/registry-integration packages - Remove deprecated infrastructure scripts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
77 lines
2.4 KiB
Swift
77 lines
2.4 KiB
Swift
import SwiftUI
|
|
|
|
struct SettingsView: View {
|
|
@AppStorage("apiBaseURL") private var apiBaseURL = "http://localhost:3100"
|
|
@State private var showingResetAlert = false
|
|
|
|
var body: some View {
|
|
Form {
|
|
Section {
|
|
TextField("API Server URL", text: $apiBaseURL)
|
|
.textFieldStyle(.roundedBorder)
|
|
} header: {
|
|
Text("Server Configuration")
|
|
} footer: {
|
|
Text("The URL of the Conversation Assistant server")
|
|
.font(.caption)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
|
|
Section {
|
|
Button("Reset All Data", role: .destructive) {
|
|
showingResetAlert = true
|
|
}
|
|
} header: {
|
|
Text("Danger Zone")
|
|
}
|
|
|
|
Section {
|
|
HStack {
|
|
Image(systemName: "bubble.left.and.bubble.right.fill")
|
|
.font(.title)
|
|
.foregroundColor(.accentColor)
|
|
.accessibilityHidden(true)
|
|
VStack(alignment: .leading, spacing: 2) {
|
|
Text("Conversation Assistant")
|
|
.font(.headline)
|
|
Text(AppVersion.fullVersion)
|
|
.font(.caption)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
Spacer()
|
|
}
|
|
} header: {
|
|
Text("About")
|
|
}
|
|
}
|
|
.formStyle(.grouped)
|
|
.frame(width: 400, height: 280)
|
|
.alert("Reset All Data?", isPresented: $showingResetAlert) {
|
|
Button("Cancel", role: .cancel) {}
|
|
Button("Reset", role: .destructive) {
|
|
resetAllData()
|
|
}
|
|
} message: {
|
|
Text("This will remove all saved authentication and sync data. You will need to re-authenticate.")
|
|
}
|
|
}
|
|
|
|
private func resetAllData() {
|
|
// Clear keychain
|
|
let query: [String: Any] = [
|
|
kSecClass as String: kSecClassGenericPassword
|
|
]
|
|
SecItemDelete(query as CFDictionary)
|
|
|
|
// Clear user defaults
|
|
UserDefaults.standard.removeObject(forKey: "deviceId")
|
|
UserDefaults.standard.removeObject(forKey: "lastSync")
|
|
|
|
// Restart app
|
|
NSApplication.shared.terminate(nil)
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
SettingsView()
|
|
}
|