what was this monster 😭
Some checks are pending
Build and Release / Build IPA (push) Waiting to run
Build and Release / Build Mac Catalyst (push) Waiting to run

This commit is contained in:
cranci1 2025-07-07 10:23:25 +02:00
parent bca07c9c46
commit 5607ec70ff

View file

@ -189,12 +189,12 @@ struct MediaInfoView: View {
UserDefaults.standard.set(true, forKey: "isMediaInfoActive") UserDefaults.standard.set(true, forKey: "isMediaInfoActive")
// swipe back // swipe back
/* /*
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first, let window = windowScene.windows.first,
let navigationController = window.rootViewController?.children.first as? UINavigationController { let navigationController = window.rootViewController?.children.first as? UINavigationController {
navigationController.interactivePopGestureRecognizer?.isEnabled = false navigationController.interactivePopGestureRecognizer?.isEnabled = false
} }
*/ */
} }
.onChange(of: selectedRange) { newValue in .onChange(of: selectedRange) { newValue in
UserDefaults.standard.set(newValue.lowerBound, forKey: selectedRangeKey) UserDefaults.standard.set(newValue.lowerBound, forKey: selectedRangeKey)
@ -404,7 +404,7 @@ struct MediaInfoView: View {
.foregroundColor(.secondary) .foregroundColor(.secondary)
.lineLimit(showFullSynopsis ? nil : 3) .lineLimit(showFullSynopsis ? nil : 3)
.animation(nil, value: showFullSynopsis) .animation(nil, value: showFullSynopsis)
HStack { HStack {
Spacer() Spacer()
Text(showFullSynopsis ? NSLocalizedString("LESS", comment: "") : NSLocalizedString("MORE", comment: "")) Text(showFullSynopsis ? NSLocalizedString("LESS", comment: "") : NSLocalizedString("MORE", comment: ""))
@ -487,7 +487,7 @@ struct MediaInfoView: View {
.cornerRadius(15) .cornerRadius(15)
.gradientOutline() .gradientOutline()
} }
Button(action: { openSafariViewController(with: href) }) { Button(action: { openSafariViewController(with: href) }) {
Image(systemName: "safari") Image(systemName: "safari")
.resizable() .resizable()
@ -557,7 +557,7 @@ struct MediaInfoView: View {
} }
} }
} }
@ViewBuilder @ViewBuilder
private var seasonSelectorStyled: some View { private var seasonSelectorStyled: some View {
let seasons = groupedEpisodes() let seasons = groupedEpisodes()
@ -581,7 +581,7 @@ struct MediaInfoView: View {
} }
} }
} }
@ViewBuilder @ViewBuilder
private var rangeSelectorStyled: some View { private var rangeSelectorStyled: some View {
Menu { Menu {
@ -719,17 +719,17 @@ struct MediaInfoView: View {
menuButton menuButton
} }
} }
if chapters.count > chapterChunkSize { if chapters.count > chapterChunkSize {
HStack { HStack {
Spacer() Spacer()
chapterRangeSelectorStyled chapterRangeSelectorStyled
}
.padding(.bottom, 0)
} }
LazyVStack(spacing: 15) { .padding(.bottom, 0)
ForEach(chapters.indices.filter { selectedChapterRange.contains($0) }, id: \..self) { i in }
let chapter = chapters[i] LazyVStack(spacing: 15) {
let _ = refreshTrigger ForEach(chapters.indices.filter { selectedChapterRange.contains($0) }, id: \..self) { i in
let chapter = chapters[i]
let _ = refreshTrigger
if let href = chapter["href"] as? String, if let href = chapter["href"] as? String,
let number = chapter["number"] as? Int, let number = chapter["number"] as? Int,
let title = chapter["title"] as? String { let title = chapter["title"] as? String {
@ -792,7 +792,7 @@ struct MediaInfoView: View {
} }
} }
} }
@ViewBuilder @ViewBuilder
private var chapterRangeSelectorStyled: some View { private var chapterRangeSelectorStyled: some View {
Menu { Menu {
@ -952,7 +952,7 @@ struct MediaInfoView: View {
UserDefaults.standard.set(imageUrl, forKey: "mediaInfoImageUrl_\(module.id.uuidString)") UserDefaults.standard.set(imageUrl, forKey: "mediaInfoImageUrl_\(module.id.uuidString)")
Logger.shared.log("Saved MediaInfoView image URL: \(imageUrl) for module \(module.id.uuidString)", type: "Debug") Logger.shared.log("Saved MediaInfoView image URL: \(imageUrl) for module \(module.id.uuidString)", type: "Debug")
if module.metadata.novel == true { if module.metadata.novel == true {
if !hasFetched { if !hasFetched {
@ -969,11 +969,11 @@ struct MediaInfoView: View {
if let jsContent = jsContent { if let jsContent = jsContent {
jsController.loadScript(jsContent) jsController.loadScript(jsContent)
} }
await withTaskGroup(of: Void.self) { group in await withTaskGroup(of: Void.self) { group in
var chaptersLoaded = false var chaptersLoaded = false
var detailsLoaded = false var detailsLoaded = false
group.addTask { group.addTask {
let fetchedChapters = try? await JSController.shared.extractChapters(moduleId: module.id.uuidString, href: href) let fetchedChapters = try? await JSController.shared.extractChapters(moduleId: module.id.uuidString, href: href)
await MainActor.run { await MainActor.run {
@ -1429,7 +1429,6 @@ struct MediaInfoView: View {
} }
} }
func fetchDetails() { func fetchDetails() {
Logger.shared.log("fetchDetails: called", type: "Debug") Logger.shared.log("fetchDetails: called", type: "Debug")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
@ -1437,88 +1436,15 @@ struct MediaInfoView: View {
do { do {
let jsContent = try moduleManager.getModuleContent(module) let jsContent = try moduleManager.getModuleContent(module)
jsController.loadScript(jsContent) jsController.loadScript(jsContent)
let completion: (Any?, [EpisodeLink]) -> Void = { items, episodes in
self.handleFetchDetailsResponse(items: items, episodes: episodes)
}
if module.metadata.asyncJS == true { if module.metadata.asyncJS == true {
jsController.fetchDetailsJS(url: href) { items, episodes in jsController.fetchDetailsJS(url: href, completion: completion)
Logger.shared.log("fetchDetails: items = \(items)", type: "Debug")
Logger.shared.log("fetchDetails: episodes = \(episodes)", type: "Debug")
if let mediaItems = items as? [MediaItem], let item = mediaItems.first {
self.synopsis = item.description
self.aliases = item.aliases
self.airdate = item.airdate
} else if let str = items as? String {
if let data = str.data(using: .utf8),
let arr = try? JSONSerialization.jsonObject(with: data) as? [[String: Any]],
let dict = arr.first {
self.synopsis = dict["description"] as? String ?? ""
self.aliases = dict["aliases"] as? String ?? ""
self.airdate = dict["airdate"] as? String ?? ""
}
} else if let dict = items as? [String: Any] {
self.synopsis = dict["description"] as? String ?? ""
self.aliases = dict["aliases"] as? String ?? ""
self.airdate = dict["airdate"] as? String ?? ""
} else if let arr = items as? [[String: Any]], let dict = arr.first {
self.synopsis = dict["description"] as? String ?? ""
self.aliases = dict["aliases"] as? String ?? ""
self.airdate = dict["airdate"] as? String ?? ""
} else {
Logger.shared.log("Failed to process items of type: \(type(of: items))", type: "Error")
}
if self.module.metadata.novel ?? false {
Logger.shared.log("fetchDetails: (novel) chapters count = \(self.chapters.count)", type: "Debug")
self.isLoading = false
self.isRefetching = false
} else {
Logger.shared.log("fetchDetails: (episodes) episodes count = \(episodes.count)", type: "Debug")
self.episodeLinks = episodes
self.restoreSelectionState()
self.isLoading = false
self.isRefetching = false
}
}
} else { } else {
jsController.fetchDetails(url: href) { items, episodes in jsController.fetchDetails(url: href, completion: completion)
Logger.shared.log("fetchDetails: items = \(items)", type: "Debug")
Logger.shared.log("fetchDetails: episodes = \(episodes)", type: "Debug")
if let mediaItems = items as? [MediaItem], let item = mediaItems.first {
self.synopsis = item.description
self.aliases = item.aliases
self.airdate = item.airdate
} else if let str = items as? String {
if let data = str.data(using: .utf8),
let arr = try? JSONSerialization.jsonObject(with: data) as? [[String: Any]],
let dict = arr.first {
self.synopsis = dict["description"] as? String ?? ""
self.aliases = dict["aliases"] as? String ?? ""
self.airdate = dict["airdate"] as? String ?? ""
}
} else if let dict = items as? [String: Any] {
self.synopsis = dict["description"] as? String ?? ""
self.aliases = dict["aliases"] as? String ?? ""
self.airdate = dict["airdate"] as? String ?? ""
} else if let arr = items as? [[String: Any]], let dict = arr.first {
self.synopsis = dict["description"] as? String ?? ""
self.aliases = dict["aliases"] as? String ?? ""
self.airdate = dict["airdate"] as? String ?? ""
} else {
Logger.shared.log("Failed to process items of type: \(type(of: items))", type: "Error")
}
if self.module.metadata.novel ?? false {
Logger.shared.log("fetchDetails: (novel) chapters count = \(self.chapters.count)", type: "Debug")
self.isLoading = false
self.isRefetching = false
} else {
Logger.shared.log("fetchDetails: (episodes) episodes count = \(episodes.count)", type: "Debug")
self.episodeLinks = episodes
self.restoreSelectionState()
self.isLoading = false
self.isRefetching = false
}
}
} }
} catch { } catch {
Logger.shared.log("Error loading module: \(error)", type: "Error") Logger.shared.log("Error loading module: \(error)", type: "Error")
@ -1529,6 +1455,53 @@ struct MediaInfoView: View {
} }
} }
private func handleFetchDetailsResponse(items: Any?, episodes: [EpisodeLink]) {
Logger.shared.log("fetchDetails: items = \(items)", type: "Debug")
Logger.shared.log("fetchDetails: episodes = \(episodes)", type: "Debug")
processItemsResponse(items)
if module.metadata.novel ?? false {
Logger.shared.log("fetchDetails: (novel) chapters count = \(chapters.count)", type: "Debug")
} else {
Logger.shared.log("fetchDetails: (episodes) episodes count = \(episodes.count)", type: "Debug")
episodeLinks = episodes
restoreSelectionState()
}
isLoading = false
isRefetching = false
}
private func processItemsResponse(_ items: Any?) {
if let mediaItems = items as? [MediaItem], let item = mediaItems.first {
synopsis = item.description
aliases = item.aliases
airdate = item.airdate
} else if let str = items as? String {
parseStringResponse(str)
} else if let dict = items as? [String: Any] {
extractMetadataFromDict(dict)
} else if let arr = items as? [[String: Any]], let dict = arr.first {
extractMetadataFromDict(dict)
} else {
Logger.shared.log("Failed to process items of type: \(type(of: items))", type: "Error")
}
}
private func parseStringResponse(_ str: String) {
guard let data = str.data(using: .utf8),
let arr = try? JSONSerialization.jsonObject(with: data) as? [[String: Any]],
let dict = arr.first else { return }
extractMetadataFromDict(dict)
}
private func extractMetadataFromDict(_ dict: [String: Any]) {
synopsis = dict["description"] as? String ?? ""
aliases = dict["aliases"] as? String ?? ""
airdate = dict["airdate"] as? String ?? ""
}
private func fetchAniListPosterImageAndSet() { private func fetchAniListPosterImageAndSet() {
guard let listID = itemID, listID > 0 else { return } guard let listID = itemID, listID > 0 else { return }
AniListMutation().fetchCoverImage(animeId: listID) { result in AniListMutation().fetchCoverImage(animeId: listID) { result in
@ -1709,7 +1682,6 @@ struct MediaInfoView: View {
}.resume() }.resume()
} }
func fetchStream(href: String) { func fetchStream(href: String) {
let fetchID = UUID() let fetchID = UUID()
activeFetchID = fetchID activeFetchID = fetchID
@ -1954,7 +1926,6 @@ struct MediaInfoView: View {
} }
} }
private func downloadSingleEpisodeDirectly(episode: EpisodeLink) { private func downloadSingleEpisodeDirectly(episode: EpisodeLink) {
if isSingleEpisodeDownloading { return } if isSingleEpisodeDownloading { return }
@ -2240,7 +2211,6 @@ struct MediaInfoView: View {
}.resume() }.resume()
} }
private func presentAlert(_ alert: UIAlertController) { private func presentAlert(_ alert: UIAlertController) {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first, let window = windowScene.windows.first,
@ -2342,5 +2312,3 @@ struct MediaInfoView: View {
}) })
} }
} }