From d491f4f5857429d1d5a157dfa30692249d814a1b Mon Sep 17 00:00:00 2001 From: Seiike <122684677+Seeike@users.noreply.github.com> Date: Fri, 14 Mar 2025 00:40:35 +0100 Subject: [PATCH] Mark all previous watched option added didnt get to doing the ui cus... cus --- .../CustomPlayer/CustomPlayer.swift | 1 + Sora/Views/LibraryView/LibraryView.swift | 8 +- .../EpisodeCell/EpisodeCell.swift | 76 +++++++++++-------- Sora/Views/MediaInfoView/MediaInfoView.swift | 32 +++++++- 4 files changed, 78 insertions(+), 39 deletions(-) diff --git a/Sora/Utils/MediaPlayer/CustomPlayer/CustomPlayer.swift b/Sora/Utils/MediaPlayer/CustomPlayer/CustomPlayer.swift index b3a2ad5..612039f 100644 --- a/Sora/Utils/MediaPlayer/CustomPlayer/CustomPlayer.swift +++ b/Sora/Utils/MediaPlayer/CustomPlayer/CustomPlayer.swift @@ -758,3 +758,4 @@ class CustomMediaPlayerViewController: UIViewController { // yes? Like the plural of the famous american rapper ye? -IBHRAD // low taper fade the meme is massive -cranci +// cranci still doesnt have a job -seiike diff --git a/Sora/Views/LibraryView/LibraryView.swift b/Sora/Views/LibraryView/LibraryView.swift index f5fcf09..7bd8130 100644 --- a/Sora/Views/LibraryView/LibraryView.swift +++ b/Sora/Views/LibraryView/LibraryView.swift @@ -32,9 +32,9 @@ struct LibraryView: View { Image(systemName: "play.circle") .font(.largeTitle) .foregroundColor(.secondary) - Text("No items to continue watching") + Text("No items to continue watching.") .font(.headline) - Text("Recently watched content will appear here") + Text("Recently watched content will appear here.") .font(.caption) .foregroundColor(.secondary) } @@ -58,9 +58,9 @@ struct LibraryView: View { Image(systemName: "magazine") .font(.largeTitle) .foregroundColor(.secondary) - Text("No Items saved") + Text("You have no items saved.") .font(.headline) - Text("Bookmark items for easy access later") + Text("Bookmark items for an easier access later.") .font(.caption) .foregroundColor(.secondary) } diff --git a/Sora/Views/MediaInfoView/EpisodeCell/EpisodeCell.swift b/Sora/Views/MediaInfoView/EpisodeCell/EpisodeCell.swift index 908acc7..5bbb2aa 100644 --- a/Sora/Views/MediaInfoView/EpisodeCell/EpisodeCell.swift +++ b/Sora/Views/MediaInfoView/EpisodeCell/EpisodeCell.swift @@ -15,44 +15,31 @@ struct EpisodeLink: Identifiable { } struct EpisodeCell: View { + let episodeIndex: Int let episode: String let episodeID: Int let progress: Double let itemID: Int + + let onTap: (String) -> Void + let onMarkAllPrevious: () -> Void @State private var episodeTitle: String = "" @State private var episodeImageUrl: String = "" @State private var isLoading: Bool = true @State private var currentProgress: Double = 0.0 - let onTap: (String) -> Void - - private func markAsWatched() { - UserDefaults.standard.set(99999999.0, forKey: "lastPlayedTime_\(episode)") - UserDefaults.standard.set(99999999.0, forKey: "totalTime_\(episode)") - updateProgress() - } - - private func resetProgress() { - UserDefaults.standard.set(0.0, forKey: "lastPlayedTime_\(episode)") - UserDefaults.standard.set(0.0, forKey: "totalTime_\(episode)") - updateProgress() - } - - private func updateProgress() { - let lastPlayedTime = UserDefaults.standard.double(forKey: "lastPlayedTime_\(episode)") - let totalTime = UserDefaults.standard.double(forKey: "totalTime_\(episode)") - currentProgress = totalTime > 0 ? lastPlayedTime / totalTime : 0 - } - + var body: some View { HStack { ZStack { - KFImage(URL(string: episodeImageUrl.isEmpty ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" : episodeImageUrl)) - .resizable() - .aspectRatio(16/9, contentMode: .fill) - .frame(width: 100, height: 56) - .cornerRadius(8) - + KFImage(URL(string: episodeImageUrl.isEmpty + ? "https://raw.githubusercontent.com/cranci1/Sora/refs/heads/main/assets/banner2.png" + : episodeImageUrl)) + .resizable() + .aspectRatio(16/9, contentMode: .fill) + .frame(width: 100, height: 56) + .cornerRadius(8) + if isLoading { ProgressView() .progressViewStyle(CircularProgressViewStyle()) @@ -76,31 +63,56 @@ struct EpisodeCell: View { } .contentShape(Rectangle()) .contextMenu { - if currentProgress <= 0.9 { + if progress <= 0.9 { Button(action: markAsWatched) { Label("Mark as Watched", systemImage: "checkmark.circle") } } - if currentProgress != 0 { + // Only show reset if progress is nonzero + if progress != 0 { Button(action: resetProgress) { Label("Reset Progress", systemImage: "arrow.counterclockwise") } } + + if episodeIndex > 0 { + Button(action: onMarkAllPrevious) { + Label("Mark All Previous Watched", systemImage: "checkmark.circle.fill") + } + } } .onAppear { - if UserDefaults.standard.object(forKey: "fetchEpisodeMetadata") == nil || - UserDefaults.standard.bool(forKey: "fetchEpisodeMetadata") { + if UserDefaults.standard.object(forKey: "fetchEpisodeMetadata") == nil + || UserDefaults.standard.bool(forKey: "fetchEpisodeMetadata") { fetchEpisodeDetails() } - updateProgress() + currentProgress = progress } .onTapGesture { onTap(episodeImageUrl) } } - func fetchEpisodeDetails() { + private func markAsWatched() { + UserDefaults.standard.set(99999999.0, forKey: "lastPlayedTime_\(episode)") + UserDefaults.standard.set(99999999.0, forKey: "totalTime_\(episode)") + updateProgress() + } + + private func resetProgress() { + UserDefaults.standard.set(0.0, forKey: "lastPlayedTime_\(episode)") + UserDefaults.standard.set(0.0, forKey: "totalTime_\(episode)") + updateProgress() + } + + private func updateProgress() { + let lastPlayedTime = UserDefaults.standard.double(forKey: "lastPlayedTime_\(episode)") + let totalTime = UserDefaults.standard.double(forKey: "totalTime_\(episode)") + currentProgress = totalTime > 0 ? lastPlayedTime / totalTime : 0 + } + + private func fetchEpisodeDetails() { guard let url = URL(string: "https://api.ani.zip/mappings?anilist_id=\(itemID)") else { isLoading = false return diff --git a/Sora/Views/MediaInfoView/MediaInfoView.swift b/Sora/Views/MediaInfoView/MediaInfoView.swift index bf948f9..f8f5cd3 100644 --- a/Sora/Views/MediaInfoView/MediaInfoView.swift +++ b/Sora/Views/MediaInfoView/MediaInfoView.swift @@ -34,6 +34,8 @@ struct MediaInfoView: View { @State var isRefetching: Bool = true @State var isFetchingEpisode: Bool = false + @State private var refreshTrigger: Bool = false + @State private var selectedEpisodeNumber: Int = 0 @State private var selectedEpisodeImage: String = "" @@ -54,6 +56,8 @@ struct MediaInfoView: View { } else { ScrollView { VStack(alignment: .leading, spacing: 16) { + + // MARK: - Top media info HStack(alignment: .top, spacing: 10) { KFImage(URL(string: imageUrl)) .placeholder { @@ -121,6 +125,7 @@ struct MediaInfoView: View { } } + // MARK: - Synopsis section if !synopsis.isEmpty { VStack(alignment: .leading, spacing: 2) { HStack(alignment: .center) { @@ -144,6 +149,7 @@ struct MediaInfoView: View { } } + // MARK: - Action buttons HStack { Button(action: { playFirstUnwatchedEpisode() @@ -204,21 +210,41 @@ struct MediaInfoView: View { } } + //MARK: - Mark all prevoius logic ForEach(episodeLinks.indices.filter { selectedRange.contains($0) }, 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, onTap: { imageUrl in + EpisodeCell( + episodeIndex: i, + episode: ep.href, + episodeID: ep.number - 1, + progress: progress, + itemID: itemID ?? 0, + onTap: { imageUrl in if !isFetchingEpisode { selectedEpisodeNumber = ep.number selectedEpisodeImage = imageUrl fetchStream(href: ep.href) - AnalyticsManager.shared.sendEvent(event: "watch", additionalData: ["title": title, "episode": ep.number]) + AnalyticsManager.shared.sendEvent( + event: "watch", + additionalData: ["title": title, "episode": ep.number] + ) } + }, + onMarkAllPrevious: { + for idx in 0..