quick fix

This commit is contained in:
Dallas Groot 2026-04-11 01:52:16 -07:00
parent 01baf8792f
commit 12dab4cc37
3 changed files with 66 additions and 59 deletions

View file

@ -644,6 +644,60 @@ struct ConflictsResponse: Codable {
let issues: [LibraryConflict]
}
// MARK: - Conflict Manager
// Defined here (in CompanionAPIService.swift) so it compiles before
// DownloadsSettingsView.swift and LibraryConflictsView.swift reference it.
@MainActor
class ConflictManager: ObservableObject {
static let shared = ConflictManager()
@Published var conflicts: ConflictsResponse?
@Published var isLoading = false
@Published var lastError: String?
@Published var isFixing: String? = nil
private let api = CompanionAPIService()
var badgeCount: Int { conflicts?.errors ?? 0 }
var totalCount: Int { conflicts?.total ?? 0 }
init() {
NotificationCenter.default.addObserver(
forName: .companionConflictsUpdated,
object: nil,
queue: .main
) { [weak self] _ in
Task { await self?.refresh() }
}
}
func refresh() async {
guard CompanionSettings.shared.isEnabled else { return }
isLoading = true
lastError = nil
do {
conflicts = try await api.fetchConflicts()
} catch {
lastError = error.localizedDescription
}
isLoading = false
}
func fix(_ conflict: LibraryConflict) async {
guard let action = conflict.fix_action else { return }
isFixing = conflict.id
do {
try await api.fixConflict(action: action, fixData: conflict.fix_data)
try? await Task.sleep(for: .seconds(2))
await refresh()
} catch {
lastError = error.localizedDescription
}
isFixing = nil
}
}
// MARK: - Library Fetch (Phase 1)
extension CompanionAPIService {

View file

@ -22,59 +22,6 @@ extension LibraryConflict {
}
}
// MARK: - Conflict Manager
@MainActor
class ConflictManager: ObservableObject {
static let shared = ConflictManager()
@Published var conflicts: ConflictsResponse?
@Published var isLoading = false
@Published var lastError: String?
@Published var isFixing: String? = nil
private let api = CompanionAPIService()
var badgeCount: Int { conflicts?.errors ?? 0 }
var totalCount: Int { conflicts?.total ?? 0 }
init() {
// Listen for conflicts_updated WebSocket events broadcast via NotificationCenter
NotificationCenter.default.addObserver(
forName: .companionConflictsUpdated,
object: nil,
queue: .main
) { [weak self] _ in
Task { await self?.refresh() }
}
}
func refresh() async {
guard CompanionSettings.shared.isEnabled else { return }
isLoading = true
lastError = nil
do {
conflicts = try await api.fetchConflicts()
} catch {
lastError = error.localizedDescription
}
isLoading = false
}
func fix(_ conflict: LibraryConflict) async {
guard let action = conflict.fix_action else { return }
isFixing = conflict.id
do {
try await api.fixConflict(action: action, fixData: conflict.fix_data)
try? await Task.sleep(for: .seconds(2))
await refresh()
} catch {
lastError = error.localizedDescription
}
isFixing = nil
}
}
// MARK: - Issues & Conflicts View
struct LibraryConflictsView: View {

View file

@ -502,10 +502,11 @@ struct SettingsView: View {
@EnvironmentObject var serverManager: ServerManager
@ObservedObject var quality = StreamingQuality.shared
@ObservedObject var debugLogger = DebugLogger.shared
@ObservedObject private var conflictManager = ConflictManager.shared
@State private var showVisualizerSettings = false
@State private var cacheSizeText = "..."
@State private var conflictErrorCount = 0
@State private var conflictTotalCount = 0
private let accentPink = Color(red: 1.0, green: 0.176, blue: 0.333)
@ -555,17 +556,16 @@ struct SettingsView: View {
HStack {
Text("Issues & Conflicts")
Spacer()
let count = ConflictManager.shared.badgeCount
if count > 0 {
Text("\(count)")
if conflictErrorCount > 0 {
Text("\(conflictErrorCount)")
.font(.system(size: 12, weight: .bold))
.foregroundColor(.white)
.padding(.horizontal, 7)
.padding(.vertical, 2)
.background(Color(red: 1, green: 0.176, blue: 0.333))
.clipShape(Capsule())
} else if ConflictManager.shared.totalCount > 0 {
Text("\(ConflictManager.shared.totalCount)")
} else if conflictTotalCount > 0 {
Text("\(conflictTotalCount)")
.font(.system(size: 12))
.foregroundColor(.gray)
}
@ -738,6 +738,12 @@ struct SettingsView: View {
}
.onAppear {
cacheSizeText = computeCacheSize()
conflictErrorCount = ConflictManager.shared.badgeCount
conflictTotalCount = ConflictManager.shared.totalCount
}
.onReceive(NotificationCenter.default.publisher(for: .companionConflictsUpdated)) { _ in
conflictErrorCount = ConflictManager.shared.badgeCount
conflictTotalCount = ConflictManager.shared.totalCount
}
}
}