mirror of
https://github.com/yattee/yattee.git
synced 2026-10-23 13:12:53 +00:00
Add a Hide Shorts toggle to the view options
Videos carry isShort from Yattee Server and Piped, and Invidious feed entries are taken as Shorts when they arrive with no length and aren't live or upcoming: the feed comes from RSS, which lists Shorts, while lengths come from the Videos tab, which doesn't. Subscriptions, search and instance browse hide videos known to be Shorts when the toggle is on; videos whose source can't tell are always shown.
This commit is contained in:
@@ -592,7 +592,7 @@ actor InvidiousAPI: InstanceAPI {
|
||||
|
||||
// Combine notifications and videos arrays - Invidious returns feed items in notifications
|
||||
let allVideos = (response.notifications ?? []) + response.videos
|
||||
let videos = allVideos.map { $0.toVideo(baseURL: instance.url) }
|
||||
let videos = allVideos.map { $0.toVideo(baseURL: instance.url, isShort: $0.isLikelyFeedShort) }
|
||||
|
||||
LoggingService.shared.debug(
|
||||
"Invidious feed: \(response.notifications?.count ?? 0) notifications + \(response.videos.count) videos = \(videos.count) total",
|
||||
@@ -1199,7 +1199,18 @@ private struct InvidiousVideo: Decodable, Sendable {
|
||||
let isUpcoming: Bool?
|
||||
let premiereTimestamp: Int64?
|
||||
|
||||
nonisolated func toVideo(baseURL: URL) -> Video {
|
||||
/// Whether this subscription-feed entry is most likely a Short.
|
||||
///
|
||||
/// Invidious builds the feed from the channel's RSS, which lists Shorts, and
|
||||
/// takes each video's length from the channel's Videos tab, which doesn't.
|
||||
/// A Short therefore arrives with no length, and so does a stream or
|
||||
/// premiere, which is why those are ruled out. Only meaningful for
|
||||
/// `/api/v1/auth/feed`: other lists give zero length for other reasons.
|
||||
var isLikelyFeedShort: Bool {
|
||||
lengthSeconds == 0 && liveNow != true && isUpcoming != true && premiereTimestamp == nil
|
||||
}
|
||||
|
||||
nonisolated func toVideo(baseURL: URL, isShort: Bool? = nil) -> Video {
|
||||
let publishedReading = InvidiousSentinel.published(
|
||||
published,
|
||||
text: publishedText,
|
||||
@@ -1219,7 +1230,8 @@ private struct InvidiousVideo: Decodable, Sendable {
|
||||
thumbnails: videoThumbnails?.map { $0.toThumbnail(baseURL: baseURL) } ?? [],
|
||||
isLive: liveNow ?? false,
|
||||
isUpcoming: isUpcoming ?? false,
|
||||
scheduledStartTime: premiereTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) }
|
||||
scheduledStartTime: premiereTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) },
|
||||
isShort: isShort
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,7 +884,8 @@ private struct PipedVideo: Decodable, Sendable {
|
||||
thumbnails: Thumbnail.fallbackChain(for: thumbnail.flatMap { URL(string: $0) }),
|
||||
isLive: duration == -1,
|
||||
isUpcoming: false,
|
||||
scheduledStartTime: nil
|
||||
scheduledStartTime: nil,
|
||||
isShort: isShort
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1092,6 +1093,7 @@ private struct PipedSearchItem: Decodable, Sendable {
|
||||
let views: Int64?
|
||||
let videos: Int64?
|
||||
let subscribers: Int64?
|
||||
let isShort: Bool?
|
||||
|
||||
var videoId: String? {
|
||||
url?.replacingOccurrences(of: "/watch?v=", with: "")
|
||||
@@ -1123,7 +1125,8 @@ private struct PipedSearchItem: Decodable, Sendable {
|
||||
thumbnails: Thumbnail.fallbackChain(for: thumbnail.flatMap { URL(string: $0) }),
|
||||
isLive: duration == -1,
|
||||
isUpcoming: false,
|
||||
scheduledStartTime: nil
|
||||
scheduledStartTime: nil,
|
||||
isShort: isShort
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -392,6 +392,7 @@ struct ServerFeedVideo: Decodable, Sendable {
|
||||
let videoUrl: String?
|
||||
let isUpcoming: Bool?
|
||||
let premiereTimestamp: Int64?
|
||||
let isShort: Bool?
|
||||
|
||||
func toVideo() -> Video? {
|
||||
// Determine content source based on extractor
|
||||
@@ -418,7 +419,8 @@ struct ServerFeedVideo: Decodable, Sendable {
|
||||
thumbnails: videoThumbnails?.map { $0.toThumbnail() } ?? [],
|
||||
isLive: false,
|
||||
isUpcoming: isUpcoming ?? false,
|
||||
scheduledStartTime: premiereTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) }
|
||||
scheduledStartTime: premiereTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) },
|
||||
isShort: isShort
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -611,6 +613,7 @@ private struct YatteeVideo: Decodable, Sendable {
|
||||
let liveNow: Bool?
|
||||
let isUpcoming: Bool?
|
||||
let premiereTimestamp: Int64?
|
||||
let isShort: Bool?
|
||||
|
||||
nonisolated func toVideo() -> Video {
|
||||
Video(
|
||||
@@ -626,7 +629,8 @@ private struct YatteeVideo: Decodable, Sendable {
|
||||
thumbnails: videoThumbnails?.map { $0.toThumbnail() } ?? [],
|
||||
isLive: liveNow ?? false,
|
||||
isUpcoming: isUpcoming ?? false,
|
||||
scheduledStartTime: premiereTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) }
|
||||
scheduledStartTime: premiereTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) },
|
||||
isShort: isShort
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user