quick fix
This commit is contained in:
parent
d32d63a749
commit
92a5a54b8d
3 changed files with 58 additions and 0 deletions
|
|
@ -538,6 +538,8 @@ class CompanionPushClient: ObservableObject {
|
|||
// Notify ConflictManager to refresh — use NotificationCenter to avoid
|
||||
// a cross-module dependency between Foundation and SwiftUI layers.
|
||||
NotificationCenter.default.post(name: .companionConflictsUpdated, object: nil, userInfo: msg.data)
|
||||
case "tags_cleaned":
|
||||
NotificationCenter.default.post(name: .companionTagsCleaned, object: nil, userInfo: msg.data)
|
||||
case "profile":
|
||||
if let path = msg.data?["path"] as? String,
|
||||
let jsonData = try? JSONSerialization.data(withJSONObject: msg.data ?? [:]),
|
||||
|
|
@ -595,6 +597,7 @@ extension Notification.Name {
|
|||
static let companionArtistPhotoUpdated = Notification.Name("companionArtistPhotoUpdated")
|
||||
static let companionLibraryChanged = Notification.Name("companionLibraryChanged")
|
||||
static let companionConflictsUpdated = Notification.Name("companionConflictsUpdated")
|
||||
static let companionTagsCleaned = Notification.Name("companionTagsCleaned")
|
||||
}
|
||||
|
||||
// MARK: - Conflict Models
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ struct CompanionSettingsView: View {
|
|||
@State private var analyzeMessage: String?
|
||||
@State private var fixLibraryStatus: AnalyzeStatus = .idle
|
||||
@State private var fixLibraryMessage: String?
|
||||
@State private var cleanTagsStatus: AnalyzeStatus = .idle
|
||||
@State private var cleanTagsMessage: String?
|
||||
|
||||
private let accentPink = Color(red: 1.0, green: 0.176, blue: 0.333)
|
||||
|
||||
|
|
@ -122,6 +124,26 @@ struct CompanionSettingsView: View {
|
|||
}
|
||||
}
|
||||
|
||||
Button(action: triggerCleanTags) {
|
||||
HStack {
|
||||
Image(systemName: "tag.slash")
|
||||
.foregroundColor(cleanTagsStatus == .done ? .green : cleanTagsStatus == .failed ? .red : .orange)
|
||||
.symbolEffect(.pulse, isActive: cleanTagsStatus == .analyzing)
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("Clean Picard Tags").foregroundColor(.white)
|
||||
Text("Remove MusicBrainz IDs, AcoustID, and other Picard-only tags from every file.")
|
||||
.font(.caption).foregroundColor(.gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
.disabled(cleanTagsStatus == .analyzing)
|
||||
|
||||
if let msg = cleanTagsMessage {
|
||||
Text(msg)
|
||||
.font(.caption)
|
||||
.foregroundColor(cleanTagsStatus == .done ? .green : cleanTagsStatus == .failed ? .red : .gray)
|
||||
}
|
||||
|
||||
Button(action: triggerFixLibrary) {
|
||||
HStack {
|
||||
Image(systemName: "folder.badge.gearshape")
|
||||
|
|
@ -142,6 +164,10 @@ struct CompanionSettingsView: View {
|
|||
.foregroundColor(fixLibraryStatus == .done ? .green : fixLibraryStatus == .failed ? .red : .gray)
|
||||
}
|
||||
} header: { Text("Server Actions") }
|
||||
.onReceive(NotificationCenter.default.publisher(for: .companionTagsCleaned)) { _ in
|
||||
cleanTagsStatus = .done
|
||||
cleanTagsMessage = "✓ Tag cleaning complete"
|
||||
}
|
||||
|
||||
Section {
|
||||
Button(action: { triggerPreAnalyze(force: false) }) {
|
||||
|
|
@ -183,6 +209,33 @@ struct CompanionSettingsView: View {
|
|||
.navigationBarTitleDisplayMode(.inline)
|
||||
}
|
||||
|
||||
// MARK: - Clean Picard Tags
|
||||
|
||||
private func triggerCleanTags() {
|
||||
cleanTagsStatus = .analyzing
|
||||
cleanTagsMessage = "Cleaning tags on server… this may take a minute."
|
||||
Task {
|
||||
do {
|
||||
guard let base = CompanionSettings.shared.baseURL else { return }
|
||||
var req = URLRequest(url: base.appendingPathComponent("library/clean-tags"))
|
||||
req.httpMethod = "POST"
|
||||
req.timeoutInterval = 15
|
||||
let (data, _) = try await URLSession.shared.data(for: req)
|
||||
let msg = (try? JSONDecoder().decode([String: String].self, from: data))?["message"] ?? "Started"
|
||||
await MainActor.run {
|
||||
cleanTagsStatus = .analyzing
|
||||
cleanTagsMessage = "⏳ \(msg)"
|
||||
}
|
||||
DebugLogger.shared.log("Clean Picard tags triggered", category: "Companion")
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
cleanTagsStatus = .failed
|
||||
cleanTagsMessage = "✗ \(error.localizedDescription)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Trigger Server Scan
|
||||
|
||||
private func triggerScan() {
|
||||
|
|
|
|||
|
|
@ -1019,6 +1019,7 @@ extension LibraryConflict {
|
|||
case "orphaned_tracks": return "link.badge.plus"
|
||||
case "duplicate_track": return "music.note.list"
|
||||
case "stale_companion_paths": return "externaldrive.badge.xmark"
|
||||
case "album_reassigned": return "arrow.triangle.2.circlepath.circle.fill"
|
||||
default: return "exclamationmark.circle"
|
||||
}
|
||||
}
|
||||
|
|
@ -1266,6 +1267,7 @@ struct LibraryConflictsView: View {
|
|||
case "fix_picard_tags": return "Fix Tags"
|
||||
case "fix_stale_paths": return "Rescan Library"
|
||||
case "fix_orphaned_tracks": return "Trigger Rescan"
|
||||
case "fix_album_reassigned": return "Reapply Tags"
|
||||
default: return "Fix"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue