| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- import SwiftData
- import SwiftUI
- /// MixBoard iOS — A mobile music player and mix preparation tool.
- /// Listen to your own MP3/FLAC files, build playlists, and sync them to the Mac app for DAW export.
- @main
- struct MixBoardApp: App {
- @State private var playerVM = PlayerViewModel()
- @State private var playlistVM = PlaylistViewModel()
- @StateObject private var libraryManager = LibraryManager()
- @StateObject private var theme = AppTheme()
- @StateObject private var syncManager = SyncManager()
- let modelContainer: ModelContainer
- init() {
- // One-time database reset to clear corrupted Track/p2 data + add cloud fields
- let needsReset = !UserDefaults.standard.bool(forKey: "dbResetV7")
- if needsReset {
- // Nuclear option: find and delete ALL .store and .sqlite files in the app container
- let fm = FileManager.default
- let home = fm.urls(for: .libraryDirectory, in: .userDomainMask).first!
- .deletingLastPathComponent() // gets the app container root
-
- if let enumerator = fm.enumerator(at: home, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles]) {
- for case let fileURL as URL in enumerator {
- let name = fileURL.lastPathComponent
- if name == "default.store" || name == "default.store-shm" || name == "default.store-wal"
- || name.hasSuffix(".sqlite") || name.hasSuffix(".sqlite-shm") || name.hasSuffix(".sqlite-wal") {
- try? fm.removeItem(at: fileURL)
- }
- }
- }
- UserDefaults.standard.set(true, forKey: "dbResetV7")
- }
- do {
- modelContainer = try ModelContainer(for: Track.self, CuePoint.self, Playlist.self, PlaylistEntry.self, PlaylistFolder.self)
- } catch {
- fatalError("Failed to create ModelContainer: \(error)")
- }
- // Clean up leftover mock state for non-mock UI tests
- if ProcessInfo.processInfo.arguments.contains("-UITesting") && !ProcessInfo.processInfo.arguments.contains("-MockNetwork") {
- UserDefaults.standard.removeObject(forKey: "chadMusic.serverURL")
- KeychainService.deleteAPIKey()
- }
- // Register mock URL protocol for CI/UI testing with stubbed network
- if ProcessInfo.processInfo.arguments.contains("-MockNetwork") {
- MockURLProtocol.registerMockResponses()
- // Set dummy server config so the API client considers itself configured
- UserDefaults.standard.set("http://localhost:9999", forKey: "chadMusic.serverURL")
- try? KeychainService.saveAPIKey("mock-test-key")
- }
- }
- var body: some Scene {
- WindowGroup {
- ContentView()
- .environment(playerVM)
- .environment(playlistVM)
- .environmentObject(libraryManager)
- .environmentObject(theme)
- .environmentObject(syncManager)
- .preferredColorScheme(theme.preferredColorScheme)
- .onAppear {
- MediaKeyHandler.shared.register(playerVM: playerVM)
- }
- }
- .modelContainer(modelContainer)
- }
- }
|