* bug fixes  (#127)

* yeah @realdoomsboygaming fault

* fixes

* freaky ahh update

---------

Co-authored-by: Seiike <122684677+Seeike@users.noreply.github.com>
This commit is contained in:
cranci 2025-05-24 20:38:13 +02:00 committed by GitHub
parent 92061e868a
commit 0d042cc3e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 41 additions and 16 deletions

View file

@ -14,6 +14,10 @@ struct ContentView: View {
.tabItem { .tabItem {
Label("Library", systemImage: "books.vertical") Label("Library", systemImage: "books.vertical")
} }
DownloadView()
.tabItem {
Label("Downloads", systemImage: "arrow.down.app.fill")
}
SearchView() SearchView()
.tabItem { .tabItem {
Label("Search", systemImage: "magnifyingglass") Label("Search", systemImage: "magnifyingglass")

View file

@ -26,22 +26,40 @@ class ContinueWatchingManager {
} }
var items = fetchItems() var items = fetchItems()
if let index = items.firstIndex(where: { $0.streamUrl == item.streamUrl && $0.episodeNumber == item.episodeNumber }) {
items[index] = item items.removeAll { existing in
} else { existing.fullUrl == item.fullUrl &&
items.append(item) existing.episodeNumber == item.episodeNumber &&
existing.module.metadata.sourceName == item.module.metadata.sourceName
} }
items.append(item)
if let data = try? JSONEncoder().encode(items) { if let data = try? JSONEncoder().encode(items) {
UserDefaults.standard.set(data, forKey: storageKey) UserDefaults.standard.set(data, forKey: storageKey)
} }
} }
func fetchItems() -> [ContinueWatchingItem] { func fetchItems() -> [ContinueWatchingItem] {
if let data = UserDefaults.standard.data(forKey: storageKey), guard
let items = try? JSONDecoder().decode([ContinueWatchingItem].self, from: data) { let data = UserDefaults.standard.data(forKey: storageKey),
return items let raw = try? JSONDecoder().decode([ContinueWatchingItem].self, from: data)
else {
return []
} }
return []
var seen = Set<String>()
let unique = raw.reversed().filter { item in
let key = "\(item.fullUrl)|\(item.module.metadata.sourceName)|\(item.episodeNumber)"
if seen.contains(key) {
return false
} else {
seen.insert(key)
return true
}
}.reversed()
return Array(unique)
} }
func remove(item: ContinueWatchingItem) { func remove(item: ContinueWatchingItem) {

View file

@ -110,6 +110,7 @@ struct EpisodeCell: View {
Spacer() Spacer()
CircularProgressBar(progress: currentProgress) CircularProgressBar(progress: currentProgress)
.frame(width: 40, height: 40) .frame(width: 40, height: 40)
.padding(.trailing, 8)
} }
.contentShape(Rectangle()) .contentShape(Rectangle())
.background(isMultiSelectMode && isSelected ? Color.accentColor.opacity(0.1) : Color.clear) .background(isMultiSelectMode && isSelected ? Color.accentColor.opacity(0.1) : Color.clear)
@ -120,8 +121,11 @@ struct EpisodeCell: View {
.onAppear { .onAppear {
updateProgress() updateProgress()
updateDownloadStatus() updateDownloadStatus()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
fetchEpisodeDetails() if let type = module.metadata.type?.lowercased(), type == "anime" {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
fetchAnimeEpisodeDetails()
}
} }
if let totalEpisodes = totalEpisodes, episodeID + 1 < totalEpisodes { if let totalEpisodes = totalEpisodes, episodeID + 1 < totalEpisodes {
@ -168,11 +172,7 @@ struct EpisodeCell: View {
private var episodeThumbnail: some View { private var episodeThumbnail: some View {
ZStack { ZStack {
if let url = URL(string: episodeImageUrl.isEmpty ? defaultBannerImage : episodeImageUrl) { if let url = URL(string: episodeImageUrl.isEmpty ? defaultBannerImage : episodeImageUrl) {
KFImage.optimizedEpisodeThumbnail(url: url) KFImage(url)
.setProcessor(DownsamplingImageProcessor(size: CGSize(width: 100, height: 56)))
.memoryCacheExpiration(.seconds(600))
.cacheOriginalImage()
.fade(duration: 0.1)
.onFailure { error in .onFailure { error in
Logger.shared.log("Failed to load episode image: \(error)", type: "Error") Logger.shared.log("Failed to load episode image: \(error)", type: "Error")
} }

View file

@ -18,6 +18,9 @@ struct SettingsView: View {
NavigationLink(destination: SettingsViewPlayer()) { NavigationLink(destination: SettingsViewPlayer()) {
Text("Media Player") Text("Media Player")
} }
NavigationLink(destination: SettingsViewDownloads().environmentObject(JSController.shared)) {
Text("Downloads")
}
NavigationLink(destination: SettingsViewModule()) { NavigationLink(destination: SettingsViewModule()) {
Text("Modules") Text("Modules")
} }