mirror of
https://github.com/yattee/yattee.git
synced 2025-04-25 08:06:31 +00:00
Add options for history: badge color and reset watched status on playing
This commit is contained in:
parent
117057dd0e
commit
e29982454b
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
38
Shared/Assets.xcassets/AppBlueColor.colorset/Contents.json
Normal file
38
Shared/Assets.xcassets/AppBlueColor.colorset/Contents.json
Normal 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
|
||||||
|
}
|
||||||
|
}
|
38
Shared/Assets.xcassets/AppRedColor.colorset/Contents.json
Normal file
38
Shared/Assets.xcassets/AppRedColor.colorset/Contents.json
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -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"
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user