diff --git a/Sora.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate b/Sora.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate index 9cb787d..77fa72a 100644 Binary files a/Sora.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate and b/Sora.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Sora/Views/MediaViews/EpisodesCell/EpisodeCell.swift b/Sora/Views/MediaViews/EpisodesCell/EpisodeCell.swift index 12d1195..c384f49 100644 --- a/Sora/Views/MediaViews/EpisodesCell/EpisodeCell.swift +++ b/Sora/Views/MediaViews/EpisodesCell/EpisodeCell.swift @@ -7,6 +7,7 @@ import SwiftUI import Kingfisher +import SwiftyJSON struct EpisodeCell: View { let episode: String @@ -59,6 +60,7 @@ struct EpisodeCell: View { if let cachedData = UserDefaults.standard.data(forKey: cacheKey) { parseEpisodeDetails(data: cachedData) + return } guard let url = URL(string: "https://api.ani.zip/mappings?anilist_id=\(itemID)") else { @@ -90,12 +92,10 @@ struct EpisodeCell: View { func parseEpisodeDetails(data: Data) { do { - let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) - guard let json = jsonObject as? [String: Any], - let episodes = json["episodes"] as? [String: Any], - let episodeDetails = episodes["\(episodeID + 1)"] as? [String: Any], - let title = episodeDetails["title"] as? [String: String], - let image = episodeDetails["image"] as? String else { + let json = try JSON(data: data) + guard let episodeDetails = json["episodes"]["\(episodeID + 1)"].dictionary, + let title = episodeDetails["title"]?.dictionary, + let image = episodeDetails["image"]?.string else { print("Invalid response format") DispatchQueue.main.async { self.isLoading = false @@ -104,7 +104,7 @@ struct EpisodeCell: View { } DispatchQueue.main.async { - self.episodeTitle = title["en"] ?? "" + self.episodeTitle = title["en"]?.string ?? "" self.episodeImageUrl = image self.isLoading = false } diff --git a/Sora/Views/MediaViews/MediaExtraction.swift b/Sora/Views/MediaViews/MediaExtraction.swift index 66c7896..6d43ec5 100644 --- a/Sora/Views/MediaViews/MediaExtraction.swift +++ b/Sora/Views/MediaViews/MediaExtraction.swift @@ -193,6 +193,16 @@ extension MediaView { let uniqueSubURLs = Array(Set(subURLs)) let uniqueDubURLs = Array(Set(dubURLs)) + if uniqueSubURLs.count == 1 && uniqueDubURLs.isEmpty { + self.playStream(urlString: uniqueSubURLs.first, fullURL: fullURL) + return + } + + if uniqueDubURLs.count == 1 && uniqueSubURLs.isEmpty { + self.playStream(urlString: uniqueDubURLs.first, fullURL: fullURL) + return + } + let alert = UIAlertController(title: "Select Stream", message: "Choose the audio type", preferredStyle: .actionSheet) if !uniqueDubURLs.isEmpty { diff --git a/Sora/Views/MediaViews/MediaView.swift b/Sora/Views/MediaViews/MediaView.swift index 71d84f6..b53d50f 100644 --- a/Sora/Views/MediaViews/MediaView.swift +++ b/Sora/Views/MediaViews/MediaView.swift @@ -8,6 +8,7 @@ import AVKit import SwiftUI import Kingfisher +import SwiftyJSON import SafariServices struct MediaView: View { @@ -331,7 +332,7 @@ struct MediaView: View { Logger.shared.log("Unable to open the stream: 'streamUrl'") } - private func fetchItemID(byTitle title: String, completion: @escaping (Result) -> Void) { + func fetchItemID(byTitle title: String, completion: @escaping (Result) -> Void) { let query = """ query { Media(search: "\(title)", type: ANIME) { @@ -363,17 +364,11 @@ struct MediaView: View { return } - do { - if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], - let data = json["data"] as? [String: Any], - let media = data["Media"] as? [String: Any], - let id = media["id"] as? Int { - completion(.success(id)) - } else { - let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Invalid response"]) - completion(.failure(error)) - } - } catch { + let json = JSON(data) + if let id = json["data"]["Media"]["id"].int { + completion(.success(id)) + } else { + let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Invalid response"]) completion(.failure(error)) } }.resume() diff --git a/Sora/Views/SettingsViews/SubPages/SettingsAboutView.swift b/Sora/Views/SettingsViews/SubPages/SettingsAboutView.swift index bc54812..c9f1b02 100644 --- a/Sora/Views/SettingsViews/SubPages/SettingsAboutView.swift +++ b/Sora/Views/SettingsViews/SubPages/SettingsAboutView.swift @@ -214,6 +214,78 @@ struct AboutView: View { .foregroundColor(.blue) } } + Button(action: { + if let url = URL(string: "https://github.com/ipavlidakis/OpenCastSwift") { + UIApplication.shared.open(url) + } + }) { + HStack { + KFImage(URL(string: "https://avatars.githubusercontent.com/u/575802?v=4")) + .resizable() + .frame(width: 40, height: 40) + .clipShape(Circle()) + + VStack(alignment: .leading) { + Text("OpenCastSwift") + .font(.headline) + .foregroundColor(.green) + Text("Casting support") + .font(.subheadline) + .foregroundColor(.secondary) + } + Spacer() + Image(systemName: "safari") + .foregroundColor(.green) + } + } + Button(action: { + if let url = URL(string: "https://github.com/SwiftyJSON/SwiftyJSON") { + UIApplication.shared.open(url) + } + }) { + HStack { + KFImage(URL(string: "https://avatars.githubusercontent.com/u/8858017?s=200&v=4")) + .resizable() + .frame(width: 40, height: 40) + .clipShape(Circle()) + + VStack(alignment: .leading) { + Text("SwiftyJSON") + .font(.headline) + .foregroundColor(.orange) + Text("Opencast dependency") + .font(.subheadline) + .foregroundColor(.secondary) + } + Spacer() + Image(systemName: "safari") + .foregroundColor(.orange) + } + } + Button(action: { + if let url = URL(string: "https://github.com/apple/swift-protobuf") { + UIApplication.shared.open(url) + } + }) { + HStack { + KFImage(URL(string: "https://avatars.githubusercontent.com/u/10639145?s=200&v=4")) + .resizable() + .frame(width: 40, height: 40) + .clipShape(Circle()) + + VStack(alignment: .leading) { + Text("Swift Protobuf") + .font(.headline) + .foregroundColor(.purple) + Text("Opencast dependency") + .font(.subheadline) + .foregroundColor(.secondary) + } + Spacer() + Image(systemName: "safari") + .foregroundColor(.purple) + } + } } } .navigationTitle("About")