mirror of
https://github.com/cranci1/Sora.git
synced 2026-01-11 20:10:24 +00:00
few bug fixes (#136)
This commit is contained in:
parent
30aa66bf2a
commit
d26f066da0
5 changed files with 78 additions and 44 deletions
|
|
@ -12,7 +12,7 @@ struct ContinueWatchingItem: Codable, Identifiable {
|
|||
let imageUrl: String
|
||||
let episodeNumber: Int
|
||||
let mediaTitle: String
|
||||
let progress: Double
|
||||
var progress: Double
|
||||
let streamUrl: String
|
||||
let fullUrl: String
|
||||
let subtitles: String?
|
||||
|
|
|
|||
|
|
@ -20,25 +20,43 @@ class ContinueWatchingManager {
|
|||
}
|
||||
|
||||
func save(item: ContinueWatchingItem) {
|
||||
if item.progress >= 0.9 {
|
||||
// Read the real playback times
|
||||
let lastKey = "lastPlayedTime_\(item.fullUrl)"
|
||||
let totalKey = "totalTime_\(item.fullUrl)"
|
||||
let lastPlayed = UserDefaults.standard.double(forKey: lastKey)
|
||||
let totalTime = UserDefaults.standard.double(forKey: totalKey)
|
||||
|
||||
// Compute up-to-date progress
|
||||
let actualProgress: Double
|
||||
if totalTime > 0 {
|
||||
actualProgress = min(max(lastPlayed / totalTime, 0), 1)
|
||||
} else {
|
||||
actualProgress = item.progress
|
||||
}
|
||||
|
||||
// If watched ≥ 90%, remove it
|
||||
if actualProgress >= 0.9 {
|
||||
remove(item: item)
|
||||
return
|
||||
}
|
||||
|
||||
var items = fetchItems()
|
||||
// Otherwise update progress and re-save
|
||||
var updatedItem = item
|
||||
updatedItem.progress = actualProgress
|
||||
|
||||
var items = fetchItems()
|
||||
items.removeAll { existing in
|
||||
existing.fullUrl == item.fullUrl &&
|
||||
existing.episodeNumber == item.episodeNumber &&
|
||||
existing.module.metadata.sourceName == item.module.metadata.sourceName
|
||||
}
|
||||
|
||||
items.append(item)
|
||||
items.append(updatedItem)
|
||||
|
||||
if let data = try? JSONEncoder().encode(items) {
|
||||
UserDefaults.standard.set(data, forKey: storageKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func fetchItems() -> [ContinueWatchingItem] {
|
||||
guard
|
||||
|
|
|
|||
|
|
@ -123,17 +123,18 @@ struct DownloadView: View {
|
|||
Image(systemName: "arrow.down.circle")
|
||||
.font(.system(size: 60))
|
||||
.foregroundColor(.gray)
|
||||
.padding()
|
||||
.padding(4)
|
||||
|
||||
Text("No Active Downloads")
|
||||
.font(.title2)
|
||||
.foregroundColor(.gray)
|
||||
.padding(3)
|
||||
|
||||
Text("Download episodes from the episode list")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.gray)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding()
|
||||
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
}
|
||||
|
|
@ -143,17 +144,17 @@ struct DownloadView: View {
|
|||
Image(systemName: "arrow.down.circle")
|
||||
.font(.system(size: 60))
|
||||
.foregroundColor(.gray)
|
||||
.padding()
|
||||
.padding(4)
|
||||
|
||||
Text("No Downloads")
|
||||
.font(.title2)
|
||||
.foregroundColor(.gray)
|
||||
.padding(3)
|
||||
|
||||
Text("Your downloaded assets will appear here")
|
||||
Text("Your downloaded episodes will appear here")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.gray)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding()
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -369,14 +369,27 @@ struct ContinueWatchingCell: View {
|
|||
}
|
||||
|
||||
private func updateProgress() {
|
||||
let lastPlayedTime = UserDefaults.standard.double(forKey: "lastPlayedTime_\(item.fullUrl)")
|
||||
let totalTime = UserDefaults.standard.double(forKey: "totalTime_\(item.fullUrl)")
|
||||
// grab the true playback times
|
||||
let lastPlayed = UserDefaults.standard.double(forKey: "lastPlayedTime_\(item.fullUrl)")
|
||||
let totalTime = UserDefaults.standard.double(forKey: "totalTime_\(item.fullUrl)")
|
||||
|
||||
// compute a clean 0…1 ratio
|
||||
let ratio: Double
|
||||
if totalTime > 0 {
|
||||
let ratio = lastPlayedTime / totalTime
|
||||
currentProgress = max(0, min(ratio, 1))
|
||||
ratio = min(max(lastPlayed / totalTime, 0), 1)
|
||||
} else {
|
||||
currentProgress = max(0, min(item.progress, 1))
|
||||
ratio = min(max(item.progress, 0), 1)
|
||||
}
|
||||
currentProgress = ratio
|
||||
|
||||
if ratio >= 0.9 {
|
||||
// >90% watched? drop it immediately
|
||||
removeItem()
|
||||
} else {
|
||||
// otherwise persist the latest progress
|
||||
var updated = item
|
||||
updated.progress = ratio
|
||||
ContinueWatchingManager.shared.save(item: updated)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ struct SettingsViewData: View {
|
|||
@State private var isImageCachingEnabled: Bool = true
|
||||
@State private var isMemoryOnlyMode: Bool = false
|
||||
|
||||
enum ActiveAlert { case eraseData, removeDocs, removeMovPkg }
|
||||
|
||||
@State private var showAlert = false
|
||||
@State private var activeAlert: ActiveAlert = .eraseData
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
// New section for cache settings
|
||||
|
|
@ -86,7 +91,8 @@ struct SettingsViewData: View {
|
|||
|
||||
HStack {
|
||||
Button(action: {
|
||||
showRemoveDocumentsAlert = true
|
||||
activeAlert = .removeDocs
|
||||
showAlert = true
|
||||
}) {
|
||||
Text("Remove All Files in Documents")
|
||||
}
|
||||
|
|
@ -109,7 +115,8 @@ struct SettingsViewData: View {
|
|||
}
|
||||
|
||||
Button(action: {
|
||||
showEraseAppDataAlert = true
|
||||
activeAlert = .eraseData
|
||||
showAlert = true
|
||||
}) {
|
||||
Text("Erase all App Data")
|
||||
}
|
||||
|
|
@ -125,37 +132,32 @@ struct SettingsViewData: View {
|
|||
calculateCacheSize()
|
||||
updateSizes()
|
||||
}
|
||||
.alert(isPresented: $showEraseAppDataAlert) {
|
||||
Alert(
|
||||
title: Text("Erase App Data"),
|
||||
message: Text("Are you sure you want to erase all app data? This action cannot be undone."),
|
||||
primaryButton: .destructive(Text("Erase")) {
|
||||
eraseAppData()
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
.alert(isPresented: $showAlert) {
|
||||
switch activeAlert {
|
||||
case .eraseData:
|
||||
return Alert(
|
||||
title: Text("Erase App Data"),
|
||||
message: Text("Are you sure you want to erase all app data? This action cannot be undone."),
|
||||
primaryButton: .destructive(Text("Erase")) { eraseAppData() },
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
.alert(isPresented: $showRemoveDocumentsAlert) {
|
||||
Alert(
|
||||
title: Text("Remove Documents"),
|
||||
message: Text("Are you sure you want to remove all files in the Documents folder? This will remove all modules."),
|
||||
primaryButton: .destructive(Text("Remove")) {
|
||||
removeAllFilesInDocuments()
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
case .removeDocs:
|
||||
return Alert(
|
||||
title: Text("Remove Documents"),
|
||||
message: Text("Are you sure you want to remove all files in the Documents folder? This will remove all modules."),
|
||||
primaryButton: .destructive(Text("Remove")) { removeAllFilesInDocuments() },
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
.alert(isPresented: $showRemoveMovPkgAlert) {
|
||||
Alert(
|
||||
title: Text("Remove Downloads"),
|
||||
message: Text("Are you sure you want to remove all Downloads?"),
|
||||
primaryButton: .destructive(Text("Remove")) {
|
||||
removeMovPkgFiles()
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
case .removeMovPkg:
|
||||
return Alert(
|
||||
title: Text("Remove Downloads"),
|
||||
message: Text("Are you sure you want to remove all Downloads?"),
|
||||
primaryButton: .destructive(Text("Remove")) { removeMovPkgFiles() },
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate and update the combined cache size
|
||||
func calculateCacheSize() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue