mirror of
https://github.com/cranci1/Sora.git
synced 2026-01-11 20:10:24 +00:00
thank god man thank god
Some checks are pending
Build and Release IPA / Build IPA (push) Waiting to run
Some checks are pending
Build and Release IPA / Build IPA (push) Waiting to run
This commit is contained in:
parent
3ebf986424
commit
ac66da899c
3 changed files with 107 additions and 18 deletions
|
|
@ -70,9 +70,9 @@ class JSController: ObservableObject {
|
|||
}.resume()
|
||||
}
|
||||
|
||||
func fetchDetails(url: String, completion: @escaping ([MediaItem]) -> Void) {
|
||||
func fetchDetails(url: String, completion: @escaping ([MediaItem], [EpisodeLink]) -> Void) {
|
||||
guard let url = URL(string: url) else {
|
||||
completion([])
|
||||
completion([], [])
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -81,31 +81,43 @@ class JSController: ObservableObject {
|
|||
|
||||
if let error = error {
|
||||
print("Network error: \(error)")
|
||||
DispatchQueue.main.async { completion([]) }
|
||||
DispatchQueue.main.async { completion([], []) }
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = data, let html = String(data: data, encoding: .utf8) else {
|
||||
print("Failed to decode HTML")
|
||||
DispatchQueue.main.async { completion([]) }
|
||||
DispatchQueue.main.async { completion([], []) }
|
||||
return
|
||||
}
|
||||
|
||||
var resultItems: [MediaItem] = []
|
||||
var episodeLinks: [EpisodeLink] = []
|
||||
|
||||
if let parseFunction = self.context.objectForKeyedSubscript("extractDetails"),
|
||||
let results = parseFunction.call(withArguments: [html]).toArray() as? [[String: String]] {
|
||||
let resultItems = results.map { item in
|
||||
resultItems = results.map { item in
|
||||
MediaItem(
|
||||
description: item["description"] ?? "",
|
||||
aliases: item["aliases"] ?? "",
|
||||
airdate: item["airdate"] ?? ""
|
||||
)
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
completion(resultItems)
|
||||
}
|
||||
} else {
|
||||
print("Failed to parse results")
|
||||
DispatchQueue.main.async { completion([]) }
|
||||
}
|
||||
|
||||
if let fetchEpisodesFunction = self.context.objectForKeyedSubscript("extractEpisodes"),
|
||||
let episodesResult = fetchEpisodesFunction.call(withArguments: [html]).toArray() as? [[String: String]] {
|
||||
for episodeData in episodesResult {
|
||||
if let num = episodeData["number"], let link = episodeData["href"], let number = Int(num) {
|
||||
episodeLinks.append(EpisodeLink(number: number, href: link))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
completion(resultItems, episodeLinks)
|
||||
}
|
||||
}.resume()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,15 @@
|
|||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct EpisodeLink: Identifiable {
|
||||
let id = UUID()
|
||||
let number: Int
|
||||
let href: String
|
||||
}
|
||||
|
||||
struct EpisodeCell: View {
|
||||
let episode: String
|
||||
let episodeID: Int
|
||||
let imageUrl: String
|
||||
let progress: Double
|
||||
let itemID: Int
|
||||
|
||||
|
|
|
|||
|
|
@ -24,9 +24,8 @@ struct MediaInfoView: View {
|
|||
@State var aliases: String = ""
|
||||
@State var synopsis: String = ""
|
||||
@State var airdate: String = ""
|
||||
@State var genres: [String] = []
|
||||
@State var episodes: [String] = []
|
||||
|
||||
@State var episodeLinks: [EpisodeLink] = []
|
||||
@State var itemID: Int?
|
||||
@State var isLoading: Bool = true
|
||||
@State var showFullSynopsis: Bool = false
|
||||
|
||||
|
|
@ -132,32 +131,57 @@ struct MediaInfoView: View {
|
|||
.frame(width: 20, height: 27)
|
||||
}
|
||||
}
|
||||
|
||||
if !episodeLinks.isEmpty {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
Text("Episodes")
|
||||
.font(.system(size: 18))
|
||||
.fontWeight(.bold)
|
||||
|
||||
ForEach(episodeLinks.indices, id: \.self) { i in
|
||||
let ep = episodeLinks[i]
|
||||
let lastPlayedTime = UserDefaults.standard.double(forKey: "lastPlayedTime_\(ep.href)")
|
||||
let totalTime = UserDefaults.standard.double(forKey: "totalTime_\(ep.href)")
|
||||
let progress = totalTime > 0 ? lastPlayedTime / totalTime : 0
|
||||
|
||||
EpisodeCell(episode: ep.href, episodeID: ep.number - 1, progress: progress, itemID: itemID ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationBarTitle(title)
|
||||
.navigationBarTitle("")
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
getDetails()
|
||||
fetchDetails()
|
||||
fetchItemID(byTitle: title) { result in
|
||||
switch result {
|
||||
case .success(let id):
|
||||
itemID = id
|
||||
case .failure(let error):
|
||||
print("Failed to fetch Item ID: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getDetails() {
|
||||
func fetchDetails() {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
Task {
|
||||
do {
|
||||
let jsContent = try moduleManager.getModuleContent(module)
|
||||
jsController.loadScript(jsContent)
|
||||
jsController.fetchDetails(url: href) { items in
|
||||
jsController.fetchDetails(url: href) { items, episodes in
|
||||
if let item = items.first {
|
||||
print("Fetched item: \(item)")
|
||||
self.synopsis = item.description
|
||||
self.aliases = item.aliases
|
||||
self.airdate = item.airdate
|
||||
}
|
||||
self.episodeLinks = episodes
|
||||
self.isLoading = false
|
||||
}
|
||||
} catch {
|
||||
|
|
@ -167,4 +191,52 @@ struct MediaInfoView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchItemID(byTitle title: String, completion: @escaping (Result<Int, Error>) -> Void) {
|
||||
let query = """
|
||||
query {
|
||||
Media(search: "\(title)", type: ANIME) {
|
||||
id
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
guard let url = URL(string: "https://graphql.anilist.co") else {
|
||||
completion(.failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"])))
|
||||
return
|
||||
}
|
||||
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "POST"
|
||||
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
|
||||
let parameters: [String: Any] = ["query": query]
|
||||
request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)
|
||||
|
||||
URLSession.custom.dataTask(with: request) { data, _, error in
|
||||
if let error = error {
|
||||
completion(.failure(error))
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = data else {
|
||||
completion(.failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "No data received"])))
|
||||
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 {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}.resume()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue