diff --git a/README.md b/README.md index b3cda4b..3d358db 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ Additionally, you can install the app using Xcode or using the .ipa file, which Frameworks: - [Drops](https://github.com/omaralbeik/Drops) - MIT License - [NukeUI](https://github.com/kean/NukeUI) - MIT License +- [SoraCore](https://github.com/cranci1/SoraCore) - Custom License - [MarqueeLabel](https://github.com/cbpowell/MarqueeLabel) - MIT License Misc: diff --git a/Sora/Views/MediaInfoView/MediaInfoView.swift b/Sora/Views/MediaInfoView/MediaInfoView.swift index d280b32..e0d57d9 100644 --- a/Sora/Views/MediaInfoView/MediaInfoView.swift +++ b/Sora/Views/MediaInfoView/MediaInfoView.swift @@ -92,8 +92,8 @@ struct MediaInfoView: View { }() private var metadataProvidersOrder: [String] { - get { (try? JSONDecoder().decode([String].self, from: metadataProvidersOrderData)) ?? ["AniList","TMDB"] } - set { metadataProvidersOrderData = try! JSONEncoder().encode(newValue) } + get { (try? JSONDecoder().decode([String].self, from: metadataProvidersOrderData)) ?? ["AniList","TMDB"] } + set { metadataProvidersOrderData = try! JSONEncoder().encode(newValue) } } private var isGroupedBySeasons: Bool { @@ -657,7 +657,7 @@ struct MediaInfoView: View { .sheet(isPresented: $isMatchingPresented) { AnilistMatchPopupView(seriesTitle: title) { selectedID in handleAniListMatch(selectedID: selectedID) - fetchMetadataIDIfNeeded() // ← use your new async re-try loop + fetchMetadataIDIfNeeded() } } .sheet(isPresented: $isTMDBMatchingPresented) { @@ -671,7 +671,6 @@ struct MediaInfoView: View { @ViewBuilder private var menuContent: some View { Group { - // Show which provider “won” if let active = activeProvider { Text("Provider: \(active)") .font(.caption) @@ -680,7 +679,6 @@ struct MediaInfoView: View { Divider() } - Text("Matched ID: \(itemID ?? 0)") .font(.caption2) .foregroundColor(.secondary) @@ -697,14 +695,12 @@ struct MediaInfoView: View { Label("Open in AniList", systemImage: "link") } } - // TMDB branch: only match else if activeProvider == "TMDB" { Button("Match with TMDB") { isTMDBMatchingPresented = true } } - // Keep all of your existing poster & debug options posterMenuOptions Divider() @@ -714,7 +710,6 @@ struct MediaInfoView: View { } } } - @ViewBuilder private var posterMenuOptions: some View { @@ -1189,58 +1184,69 @@ struct MediaInfoView: View { private func fetchMetadataIDIfNeeded() { let order = metadataProvidersOrder let cleanedTitle = cleanTitle(title) - + itemID = nil tmdbID = nil activeProvider = nil isError = false - - fetchItemID(byTitle: cleanedTitle) { result in - switch result { - case .success(let id): - DispatchQueue.main.async { self.itemID = id } - case .failure(let error): - Logger.shared.log("Failed to fetch AniList ID for tracking: \(error)", type: "Error") + + func fetchAniList(completion: @escaping (Bool) -> Void) { + fetchItemID(byTitle: cleanedTitle) { result in + switch result { + case .success(let id): + DispatchQueue.main.async { + self.itemID = id + self.activeProvider = "AniList" + UserDefaults.standard.set("AniList", forKey: "metadataProviders") + completion(true) + } + case .failure(let error): + Logger.shared.log("Failed to fetch AniList ID for tracking: \(error)", type: "Error") + completion(false) + } } } - - func tryNext(_ index: Int) { + + func fetchTMDB(completion: @escaping (Bool) -> Void) { + tmdbFetcher.fetchBestMatchID(for: cleanedTitle) { id, type in + DispatchQueue.main.async { + if let id = id, let type = type { + self.tmdbID = id + self.tmdbType = type + self.activeProvider = "TMDB" + UserDefaults.standard.set("TMDB", forKey: "metadataProviders") + completion(true) + } else { + completion(false) + } + } + } + } + + func tryProviders(_ index: Int) { guard index < order.count else { isError = true return } let provider = order[index] - if provider == "TMDB" { - tmdbFetcher.fetchBestMatchID(for: cleanedTitle) { id, type in - DispatchQueue.main.async { - if let id = id, let type = type { - self.tmdbID = id - self.tmdbType = type - self.activeProvider = "TMDB" - UserDefaults.standard.set("TMDB", forKey: "metadataProviders") - } else { - tryNext(index + 1) - } + if provider == "AniList" { + fetchAniList { success in + if !success { + tryProviders(index + 1) } } - } else if provider == "AniList" { - fetchItemID(byTitle: cleanedTitle) { result in - switch result { - case .success: - DispatchQueue.main.async { - self.activeProvider = "AniList" - UserDefaults.standard.set("AniList", forKey: "metadataProviders") - } - case .failure: - tryNext(index + 1) + } else if provider == "TMDB" { + fetchTMDB { success in + if !success { + tryProviders(index + 1) } } } else { - tryNext(index + 1) + tryProviders(index + 1) } } - - tryNext(0) + + tryProviders(0) } private func fetchItemID(byTitle title: String, completion: @escaping (Result) -> Void) { diff --git a/Sulfur.xcodeproj/project.pbxproj b/Sulfur.xcodeproj/project.pbxproj index 1fe17f0..17f705a 100644 --- a/Sulfur.xcodeproj/project.pbxproj +++ b/Sulfur.xcodeproj/project.pbxproj @@ -370,8 +370,8 @@ 133D7C7F2D2BE2630075467E /* MediaInfoView */ = { isa = PBXGroup; children = ( - 1EDA48F32DFAC374002A4EC3 /* TMDBMatchPopupView.swift */, 138AA1B52D2D66EC0021F9DF /* EpisodeCell */, + 1EDA48F32DFAC374002A4EC3 /* TMDBMatchPopupView.swift */, 133D7C802D2BE2630075467E /* MediaInfoView.swift */, 1E47859A2DEBC5960095BF2F /* AnilistMatchPopupView.swift */, );