Add options for history: badge color and reset watched status on playing

This commit is contained in:
Arkadiusz Fal 2022-01-02 20:39:19 +01:00
parent 117057dd0e
commit e29982454b
9 changed files with 135 additions and 9 deletions

View File

@ -1,5 +1,6 @@
import CoreData import CoreData
import CoreMedia import CoreMedia
import Defaults
import Foundation import Foundation
extension PlayerModel { extension PlayerModel {
@ -42,6 +43,10 @@ extension PlayerModel {
watch.videoID = id watch.videoID = id
} else { } else {
watch = results?.first watch = results?.first
if !Defaults[.resetWatchedStatusOnPlaying], watch.finished {
return
}
} }
if let seconds = playerItemDuration?.seconds { if let seconds = playerItemDuration?.seconds {

View File

@ -24,6 +24,11 @@ extension Watch {
} }
let progress = (stoppedAt / videoDuration) * 100 let progress = (stoppedAt / videoDuration) * 100
if progress >= Double(watchedThreshold) {
return 100
}
return min(max(progress, 0), 100) return min(max(progress, 0), 100)
} }

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.361",
"green" : "0.200",
"red" : "0.129"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.361",
"green" : "0.200",
"red" : "0.129"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.263",
"green" : "0.290",
"red" : "0.859"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.263",
"green" : "0.290",
"red" : "0.859"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -5,9 +5,9 @@
"color-space" : "display-p3", "color-space" : "display-p3",
"components" : { "components" : {
"alpha" : "1.000", "alpha" : "1.000",
"blue" : "0.263", "blue" : "0.361",
"green" : "0.290", "green" : "0.200",
"red" : "0.859" "red" : "0.129"
} }
}, },
"idiom" : "universal" "idiom" : "universal"

View File

@ -63,7 +63,9 @@ extension Defaults.Keys {
static let showWatchingProgress = Key<Bool>("showWatchingProgress", default: true) static let showWatchingProgress = Key<Bool>("showWatchingProgress", default: true)
static let watchedThreshold = Key<Int>("watchedThreshold", default: 90) static let watchedThreshold = Key<Int>("watchedThreshold", default: 90)
static let watchedVideoStyle = Key<WatchedVideoStyle>("watchedVideoStyle", default: .badge) static let watchedVideoStyle = Key<WatchedVideoStyle>("watchedVideoStyle", default: .badge)
static let watchedVideoBadgeColor = Key<WatchedVideoBadgeColor>("WatchedVideoBadgeColor", default: .red)
static let watchedVideoPlayNowBehavior = Key<WatchedVideoPlayNowBehavior>("watchedVideoPlayNowBehavior", default: .continue) static let watchedVideoPlayNowBehavior = Key<WatchedVideoPlayNowBehavior>("watchedVideoPlayNowBehavior", default: .continue)
static let resetWatchedStatusOnPlaying = Key<Bool>("resetWatchedStatusOnPlaying", default: false)
static let saveRecents = Key<Bool>("saveRecents", default: true) static let saveRecents = Key<Bool>("saveRecents", default: true)
static let trendingCategory = Key<TrendingCategory>("trendingCategory", default: .default) static let trendingCategory = Key<TrendingCategory>("trendingCategory", default: .default)
@ -153,7 +155,11 @@ enum VisibleSection: String, CaseIterable, Comparable, Defaults.Serializable {
} }
enum WatchedVideoStyle: String, Defaults.Serializable { enum WatchedVideoStyle: String, Defaults.Serializable {
case nothing, badge, decreasedOpacity case nothing, badge, decreasedOpacity, both
}
enum WatchedVideoBadgeColor: String, Defaults.Serializable {
case colorSchemeBased, red, blue
} }
enum WatchedVideoPlayNowBehavior: String, Defaults.Serializable { enum WatchedVideoPlayNowBehavior: String, Defaults.Serializable {

View File

@ -13,7 +13,9 @@ struct HistorySettings: View {
@Default(.showWatchingProgress) private var showWatchingProgress @Default(.showWatchingProgress) private var showWatchingProgress
@Default(.watchedThreshold) private var watchedThreshold @Default(.watchedThreshold) private var watchedThreshold
@Default(.watchedVideoStyle) private var watchedVideoStyle @Default(.watchedVideoStyle) private var watchedVideoStyle
@Default(.watchedVideoBadgeColor) private var watchedVideoBadgeColor
@Default(.watchedVideoPlayNowBehavior) private var watchedVideoPlayNowBehavior @Default(.watchedVideoPlayNowBehavior) private var watchedVideoPlayNowBehavior
@Default(.resetWatchedStatusOnPlaying) private var resetWatchedStatusOnPlaying
var body: some View { var body: some View {
Group { Group {
@ -26,14 +28,18 @@ struct HistorySettings: View {
#if !os(tvOS) #if !os(tvOS)
watchedThresholdPicker watchedThresholdPicker
watchedVideoStylePicker watchedVideoStylePicker
watchedVideoBadgeColorPicker
watchedVideoPlayNowBehaviorPicker watchedVideoPlayNowBehaviorPicker
resetWatchedStatusOnPlayingToggle
#endif #endif
} }
#if os(tvOS) #if os(tvOS)
watchedThresholdPicker watchedThresholdPicker
watchedVideoStylePicker watchedVideoStylePicker
watchedVideoBadgeColorPicker
watchedVideoPlayNowBehaviorPicker watchedVideoPlayNowBehaviorPicker
resetWatchedStatusOnPlayingToggle
#endif #endif
#if os(macOS) #if os(macOS)
@ -68,6 +74,7 @@ struct HistorySettings: View {
Text("Nothing").tag(WatchedVideoStyle.nothing) Text("Nothing").tag(WatchedVideoStyle.nothing)
Text("Badge").tag(WatchedVideoStyle.badge) Text("Badge").tag(WatchedVideoStyle.badge)
Text("Decreased opacity").tag(WatchedVideoStyle.decreasedOpacity) Text("Decreased opacity").tag(WatchedVideoStyle.decreasedOpacity)
Text("Badge & Decreased opacity").tag(WatchedVideoStyle.both)
} }
.disabled(!saveHistory) .disabled(!saveHistory)
.labelsHidden() .labelsHidden()
@ -80,6 +87,25 @@ struct HistorySettings: View {
} }
} }
private var watchedVideoBadgeColorPicker: some View {
Section(header: header("Badge color")) {
Picker("Badge color", selection: $watchedVideoBadgeColor) {
Text("Based on system color scheme").tag(WatchedVideoBadgeColor.colorSchemeBased)
Text("Blue").tag(WatchedVideoBadgeColor.blue)
Text("Red").tag(WatchedVideoBadgeColor.red)
}
.disabled(!saveHistory)
.disabled(watchedVideoStyle == .decreasedOpacity)
.labelsHidden()
#if os(iOS)
.pickerStyle(.automatic)
#elseif os(tvOS)
.pickerStyle(.inline)
#endif
}
}
private var watchedVideoPlayNowBehaviorPicker: some View { private var watchedVideoPlayNowBehaviorPicker: some View {
Section(header: header("When partially watched video is played")) { Section(header: header("When partially watched video is played")) {
Picker("When partially watched video is played", selection: $watchedVideoPlayNowBehavior) { Picker("When partially watched video is played", selection: $watchedVideoPlayNowBehavior) {
@ -97,6 +123,10 @@ struct HistorySettings: View {
} }
} }
private var resetWatchedStatusOnPlayingToggle: some View {
Toggle("Reset watched status when playing again", isOn: $resetWatchedStatusOnPlaying)
}
private var clearHistoryButton: some View { private var clearHistoryButton: some View {
Button("Clear History") { Button("Clear History") {
presentingClearHistoryConfirmation = true presentingClearHistoryConfirmation = true

View File

@ -75,7 +75,7 @@ struct SettingsView: View {
.tag(Tabs.updates) .tag(Tabs.updates)
} }
.padding(20) .padding(20)
.frame(width: 400, height: 380) .frame(width: 400, height: 400)
#else #else
NavigationView { NavigationView {
List { List {

View File

@ -21,6 +21,7 @@ struct VideoCell: View {
@Default(.saveHistory) private var saveHistory @Default(.saveHistory) private var saveHistory
@Default(.showWatchingProgress) private var showWatchingProgress @Default(.showWatchingProgress) private var showWatchingProgress
@Default(.watchedVideoStyle) private var watchedVideoStyle @Default(.watchedVideoStyle) private var watchedVideoStyle
@Default(.watchedVideoBadgeColor) private var watchedVideoBadgeColor
@Default(.watchedVideoPlayNowBehavior) private var watchedVideoPlayNowBehavior @Default(.watchedVideoPlayNowBehavior) private var watchedVideoPlayNowBehavior
@FetchRequest private var watchRequest: FetchedResults<Watch> @FetchRequest private var watchRequest: FetchedResults<Watch>
@ -112,7 +113,7 @@ struct VideoCell: View {
private var contentOpacity: Double { private var contentOpacity: Double {
guard saveHistory, guard saveHistory,
!watch.isNil, !watch.isNil,
watchedVideoStyle == .decreasedOpacity watchedVideoStyle == .decreasedOpacity || watchedVideoStyle == .both
else { else {
return 1 return 1
} }
@ -290,7 +291,7 @@ struct VideoCell: View {
thumbnailImage thumbnailImage
if saveHistory, showWatchingProgress, watch?.progress ?? 0 > 0 { if saveHistory, showWatchingProgress, watch?.progress ?? 0 > 0 {
ProgressView(value: watch!.progress, total: 100) ProgressView(value: watch!.progress, total: 100)
.progressViewStyle(LinearProgressViewStyle(tint: Color("WatchProgressBarColor"))) .progressViewStyle(LinearProgressViewStyle(tint: Color("AppRedColor")))
#if os(tvOS) #if os(tvOS)
.padding(.horizontal, 16) .padding(.horizontal, 16)
#else #else
@ -328,11 +329,14 @@ struct VideoCell: View {
HStack(alignment: .center) { HStack(alignment: .center) {
if saveHistory, if saveHistory,
watchedVideoStyle == .badge, watchedVideoStyle == .badge || watchedVideoStyle == .both,
watch?.finished ?? false watch?.finished ?? false
{ {
Image(systemName: "checkmark.circle.fill") Image(systemName: "checkmark.circle.fill")
.foregroundColor(Color("WatchProgressBarColor")) .foregroundColor(Color(
watchedVideoBadgeColor == .colorSchemeBased ? "WatchProgressBarColor" :
watchedVideoBadgeColor == .red ? "AppRedColor" : "AppBlueColor"
))
.background(Color.white) .background(Color.white)
.clipShape(Circle()) .clipShape(Circle())
#if os(tvOS) #if os(tvOS)