mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 21:43:41 +00:00
Add setting "Keep channels with unwatched videos on top of subscriptions list"
This commit is contained in:
parent
6856506834
commit
e5f137a2d2
@ -23,6 +23,7 @@ final class SubscribedChannelsModel: ObservableObject, CacheModel {
|
|||||||
@Published var error: RequestError?
|
@Published var error: RequestError?
|
||||||
|
|
||||||
var accounts: AccountsModel { .shared }
|
var accounts: AccountsModel { .shared }
|
||||||
|
var unwatchedFeedCount: UnwatchedFeedCountModel { .shared }
|
||||||
|
|
||||||
var resource: Resource? {
|
var resource: Resource? {
|
||||||
accounts.api.subscriptions
|
accounts.api.subscriptions
|
||||||
@ -32,6 +33,19 @@ final class SubscribedChannelsModel: ObservableObject, CacheModel {
|
|||||||
channels.sorted { $0.name.lowercased() < $1.name.lowercased() }
|
channels.sorted { $0.name.lowercased() < $1.name.lowercased() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var allByUnwatchedCount: [Channel] {
|
||||||
|
if let account = accounts.current {
|
||||||
|
return all.sorted { c1, c2 in
|
||||||
|
let c1HasUnwatched = (unwatchedFeedCount.unwatchedByChannel[account]?[c1.id] ?? -1) > 0
|
||||||
|
let c2HasUnwatched = (unwatchedFeedCount.unwatchedByChannel[account]?[c2.id] ?? -1) > 0
|
||||||
|
let nameIncreasing = c1.name.lowercased() < c2.name.lowercased()
|
||||||
|
|
||||||
|
return c1HasUnwatched ? (c2HasUnwatched ? nameIncreasing : true) : (c2HasUnwatched ? false : nameIncreasing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return all
|
||||||
|
}
|
||||||
|
|
||||||
func subscribe(_ channelID: String, onSuccess: @escaping () -> Void = {}) {
|
func subscribe(_ channelID: String, onSuccess: @escaping () -> Void = {}) {
|
||||||
accounts.api.subscribe(channelID) {
|
accounts.api.subscribe(channelID) {
|
||||||
self.scheduleLoad(onSuccess: onSuccess)
|
self.scheduleLoad(onSuccess: onSuccess)
|
||||||
|
@ -51,6 +51,7 @@ extension Defaults.Keys {
|
|||||||
static let lockPortraitWhenBrowsing = Key<Bool>("lockPortraitWhenBrowsing", default: UIDevice.current.userInterfaceIdiom == .phone)
|
static let lockPortraitWhenBrowsing = Key<Bool>("lockPortraitWhenBrowsing", default: UIDevice.current.userInterfaceIdiom == .phone)
|
||||||
#endif
|
#endif
|
||||||
static let showUnwatchedFeedBadges = Key<Bool>("showUnwatchedFeedBadges", default: false)
|
static let showUnwatchedFeedBadges = Key<Bool>("showUnwatchedFeedBadges", default: false)
|
||||||
|
static let keepChannelsWithUnwatchedFeedOnTop = Key<Bool>("keepChannelsWithUnwatchedFeedOnTop", default: true)
|
||||||
static let showToggleWatchedStatusButton = Key<Bool>("showToggleWatchedStatusButton", default: false)
|
static let showToggleWatchedStatusButton = Key<Bool>("showToggleWatchedStatusButton", default: false)
|
||||||
static let expandChannelDescription = Key<Bool>("expandChannelDescription", default: false)
|
static let expandChannelDescription = Key<Bool>("expandChannelDescription", default: false)
|
||||||
static let channelOnThumbnail = Key<Bool>("channelOnThumbnail", default: false)
|
static let channelOnThumbnail = Key<Bool>("channelOnThumbnail", default: false)
|
||||||
|
@ -8,6 +8,7 @@ struct BrowsingSettings: View {
|
|||||||
#endif
|
#endif
|
||||||
@Default(.accountPickerDisplaysAnonymousAccounts) private var accountPickerDisplaysAnonymousAccounts
|
@Default(.accountPickerDisplaysAnonymousAccounts) private var accountPickerDisplaysAnonymousAccounts
|
||||||
@Default(.showUnwatchedFeedBadges) private var showUnwatchedFeedBadges
|
@Default(.showUnwatchedFeedBadges) private var showUnwatchedFeedBadges
|
||||||
|
@Default(.keepChannelsWithUnwatchedFeedOnTop) private var keepChannelsWithUnwatchedFeedOnTop
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@Default(.lockPortraitWhenBrowsing) private var lockPortraitWhenBrowsing
|
@Default(.lockPortraitWhenBrowsing) private var lockPortraitWhenBrowsing
|
||||||
@Default(.showDocuments) private var showDocuments
|
@Default(.showDocuments) private var showDocuments
|
||||||
@ -180,10 +181,12 @@ struct BrowsingSettings: View {
|
|||||||
FeedModel.shared.calculateUnwatchedFeed()
|
FeedModel.shared.calculateUnwatchedFeed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Toggle("Open channels with description expanded", isOn: $expandChannelDescription)
|
Toggle("Open channels with description expanded", isOn: $expandChannelDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Toggle("Keep channels with unwatched videos on top of subscriptions list", isOn: $keepChannelsWithUnwatchedFeedOnTop)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var thumbnailsSettings: some View {
|
private var thumbnailsSettings: some View {
|
||||||
|
@ -11,20 +11,28 @@ struct ChannelsView: View {
|
|||||||
|
|
||||||
@Default(.showCacheStatus) private var showCacheStatus
|
@Default(.showCacheStatus) private var showCacheStatus
|
||||||
@Default(.showUnwatchedFeedBadges) private var showUnwatchedFeedBadges
|
@Default(.showUnwatchedFeedBadges) private var showUnwatchedFeedBadges
|
||||||
|
@Default(.keepChannelsWithUnwatchedFeedOnTop) private var keepChannelsWithUnwatchedFeedOnTop
|
||||||
|
|
||||||
|
@State private var channelLinkActive = false
|
||||||
|
@State private var channelForLink: Channel?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
List {
|
||||||
Section(header: header) {
|
Section(header: header) {
|
||||||
ForEach(subscriptions.all) { channel in
|
ForEach(channels) { channel in
|
||||||
let label = HStack {
|
let label = HStack {
|
||||||
if let url = channel.thumbnailURLOrCached {
|
if let url = channel.thumbnailURLOrCached {
|
||||||
ThumbnailView(url: url)
|
ThumbnailView(url: url)
|
||||||
.frame(width: 35, height: 35)
|
.frame(width: 35, height: 35)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 35))
|
.clipShape(RoundedRectangle(cornerRadius: 35))
|
||||||
Text(channel.name)
|
|
||||||
} else {
|
} else {
|
||||||
Label(channel.name, systemImage: RecentsModel.symbolSystemImage(channel.name))
|
Image(systemName: RecentsModel.symbolSystemImage(channel.name))
|
||||||
|
.imageScale(.large)
|
||||||
|
.foregroundColor(.accentColor)
|
||||||
|
.frame(width: 35, height: 35)
|
||||||
}
|
}
|
||||||
|
Text(channel.name)
|
||||||
|
.lineLimit(1)
|
||||||
}
|
}
|
||||||
.backport
|
.backport
|
||||||
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedByChannelText(channel) : nil)
|
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedByChannelText(channel) : nil)
|
||||||
@ -37,9 +45,15 @@ struct ChannelsView: View {
|
|||||||
label
|
label
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
NavigationLink(destination: ChannelVideosView(channel: channel)) {
|
Button {
|
||||||
|
channelForLink = channel
|
||||||
|
channelLinkActive = channelForLink != nil
|
||||||
|
} label: {
|
||||||
label
|
label
|
||||||
|
.contentShape(Rectangle())
|
||||||
|
.foregroundColor(.primary)
|
||||||
}
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
.contextMenu {
|
.contextMenu {
|
||||||
@ -63,6 +77,9 @@ struct ChannelsView: View {
|
|||||||
.listRowSeparator(false)
|
.listRowSeparator(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.background(
|
||||||
|
NavigationLink(destination: ChannelVideosView(channel: channelForLink), isActive: $channelLinkActive, label: EmptyView.init)
|
||||||
|
)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
subscriptions.load()
|
subscriptions.load()
|
||||||
}
|
}
|
||||||
@ -99,6 +116,10 @@ struct ChannelsView: View {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var channels: [Channel] {
|
||||||
|
keepChannelsWithUnwatchedFeedOnTop ? subscriptions.allByUnwatchedCount : subscriptions.all
|
||||||
|
}
|
||||||
|
|
||||||
var header: some View {
|
var header: some View {
|
||||||
HStack {
|
HStack {
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
|
Loading…
Reference in New Issue
Block a user