Переглянути джерело

feat: auto-import toggle and remove deprecated status banner (chunk 7)

Add auto-import toggle to Settings (default on). When disabled, files
download but ChadMusic rescan is skipped. Remove SoulseekStatusBanner
that depended on deprecated SoulseekOrchestrator — download status is
now shown in UnifiedSearchResultsView and DownloadsView.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
aldiss 2 місяців тому
батько
коміт
0a0f60d566

+ 11 - 1
Sources/Services/UnifiedSearchCoordinator.swift

@@ -322,8 +322,18 @@ final class UnifiedSearchCoordinator {
             try await Task.sleep(for: .seconds(downloadPollInterval))
         }
 
-        // Step 3: Trigger ChadMusic import
+        // Step 3: Trigger ChadMusic import (if auto-import enabled)
         try Task.checkCancellation()
+
+        let autoImport = UserDefaults.standard.bool(forKey: "slskd.autoImport")
+        // Default to true when key hasn't been set
+        let shouldImport = UserDefaults.standard.object(forKey: "slskd.autoImport") == nil ? true : autoImport
+
+        guard shouldImport else {
+            downloadPhase = .complete(albumName: albumName)
+            return
+        }
+
         downloadPhase = .importing
 
         try await chadMusic.triggerRescan()

+ 0 - 64
Sources/Views/CloudBrowserView.swift

@@ -19,7 +19,6 @@ struct CloudBrowserView: View {
     @EnvironmentObject private var theme: AppTheme
     @State private var apiClient = ChadMusicAPIClient.shared
     @State private var uploadService = UploadService.shared
-    @State private var orchestrator = SoulseekOrchestrator.shared
     @State private var navStack: [CloudNavDestination] = []
 
     init(initialDestination: LibraryDestination? = nil) {
@@ -57,9 +56,6 @@ struct CloudBrowserView: View {
                 } else {
                     CategoryListView(apiClient: apiClient, uploadService: uploadService, navStack: $navStack)
                 }
-
-                // Soulseek status banner — appears at bottom during active pipeline
-                SoulseekStatusBanner(orchestrator: orchestrator)
             }
             .onAppear {
                 if let dest = initialDestination {
@@ -1071,63 +1067,3 @@ private struct CloudTrackRow: View {
         .padding(.vertical, 2)
     }
 }
-
-// MARK: - Soulseek Status Banner
-
-/// Persistent overlay at the bottom of CloudBrowserView showing Soulseek pipeline status.
-private struct SoulseekStatusBanner: View {
-    let orchestrator: SoulseekOrchestrator
-
-    var body: some View {
-        let state = orchestrator.state
-        if state != .idle {
-            HStack(spacing: 10) {
-                // Progress indicator
-                if state.isActive {
-                    if case .downloading(let progress) = state {
-                        ProgressView(value: progress)
-                            .progressViewStyle(.circular)
-                            .controlSize(.small)
-                    } else {
-                        ProgressView()
-                            .controlSize(.small)
-                    }
-                } else if case .complete = state {
-                    Image(systemName: "checkmark.circle.fill")
-                        .foregroundStyle(.green)
-                } else if case .failed = state {
-                    Image(systemName: "exclamationmark.triangle.fill")
-                        .foregroundStyle(.red)
-                }
-
-                // Status text
-                Text(state.statusText)
-                    .font(.system(size: 12))
-                    .foregroundStyle(state.isActive ? .primary : .secondary)
-                    .lineLimit(1)
-
-                Spacer()
-
-                // Action button
-                if state.isActive {
-                    Button("Cancel") {
-                        orchestrator.cancel()
-                    }
-                    .buttonStyle(.bordered)
-                    .controlSize(.small)
-                } else {
-                    Button("Dismiss") {
-                        orchestrator.dismiss()
-                    }
-                    .buttonStyle(.bordered)
-                    .controlSize(.small)
-                }
-            }
-            .padding(.horizontal, 12)
-            .padding(.vertical, 8)
-            .background(.ultraThinMaterial)
-            .transition(.move(edge: .bottom).combined(with: .opacity))
-            .animation(.easeInOut(duration: 0.3), value: state != .idle)
-        }
-    }
-}

+ 12 - 0
Sources/Views/SettingsView.swift

@@ -694,6 +694,7 @@ private struct SlskdSettings: View {
     @State private var connectionStatus: SlskdConnectionStatus = .unknown
     @State private var isTesting = false
     @AppStorage("slskd.qualityThreshold") private var qualityThreshold: Int = 80
+    @AppStorage("slskd.autoImport") private var autoImport: Bool = true
     /// H-6: Track whether credentials have unsaved changes.
     @State private var hasUnsavedCredentials = false
     /// H-6: Debounce timer to avoid saving on every keystroke.
@@ -753,6 +754,17 @@ private struct SlskdSettings: View {
                     .foregroundStyle(.secondary)
             }
 
+            // Auto-import toggle
+            Toggle(isOn: $autoImport) {
+                VStack(alignment: .leading, spacing: 2) {
+                    Text("Auto-import to ChadMusic")
+                        .font(.headline)
+                    Text("Automatically trigger a library rescan after Soulseek downloads complete.")
+                        .font(.caption)
+                        .foregroundStyle(.secondary)
+                }
+            }
+
             Divider()
 
             // Connection test (both modes)