diff --git a/Yattee/Services/API/YatteeServerAPI.swift b/Yattee/Services/API/YatteeServerAPI.swift index 312c463c..632458ce 100644 --- a/Yattee/Services/API/YatteeServerAPI.swift +++ b/Yattee/Services/API/YatteeServerAPI.swift @@ -402,6 +402,8 @@ struct ServerFeedVideo: Decodable, Sendable { let videoThumbnails: [YatteeThumbnail]? let extractor: String let videoUrl: String? + let isUpcoming: Bool? + let premiereTimestamp: Int64? func toVideo() -> Video? { // Determine content source based on extractor @@ -427,8 +429,8 @@ struct ServerFeedVideo: Decodable, Sendable { likeCount: nil, thumbnails: videoThumbnails?.map { $0.toThumbnail() } ?? [], isLive: false, - isUpcoming: false, - scheduledStartTime: nil + isUpcoming: isUpcoming ?? false, + scheduledStartTime: premiereTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) } ) } } diff --git a/Yattee/Services/BackgroundRefresh/BackgroundFeedRefresher.swift b/Yattee/Services/BackgroundRefresh/BackgroundFeedRefresher.swift index c1cff5f1..210a8867 100644 --- a/Yattee/Services/BackgroundRefresh/BackgroundFeedRefresher.swift +++ b/Yattee/Services/BackgroundRefresh/BackgroundFeedRefresher.swift @@ -122,7 +122,8 @@ final class BackgroundFeedRefresher { let newVideos: [(video: Video, channelName: String)] = response.videos.compactMap { serverVideo in guard let video = serverVideo.toVideo(), let publishedAt = video.publishedAt, - publishedAt > lastCheckDate else { + publishedAt > lastCheckDate, + publishedAt <= Date() else { return nil } dateFilteredCount += 1 @@ -218,9 +219,10 @@ final class BackgroundFeedRefresher { } channelFilteredCount += 1 - // Only include videos published after last check + // Only include videos published after last check and not in the future guard let publishedAt = video.publishedAt, - publishedAt > lastCheckDate else { + publishedAt > lastCheckDate, + publishedAt <= Date() else { return nil } dateFilteredCount += 1 @@ -318,9 +320,10 @@ final class BackgroundFeedRefresher { } channelFilteredCount += 1 - // Only include videos published after last check + // Only include videos published after last check and not in the future guard let publishedAt = video.publishedAt, - publishedAt > lastCheckDate else { + publishedAt > lastCheckDate, + publishedAt <= Date() else { return nil } dateFilteredCount += 1 @@ -377,6 +380,16 @@ final class BackgroundFeedRefresher { var videosToNotify = newVideos + // Filter out upcoming/premiere videos that haven't aired yet + let upcomingCount = videosToNotify.count + videosToNotify = videosToNotify.filter { !$0.video.isUpcoming } + if upcomingCount - videosToNotify.count > 0 { + LoggingService.shared.debug( + "Filtered \(upcomingCount - videosToNotify.count) upcoming/premiere videos from notifications", + category: .notifications + ) + } + // Filter out videos the user has already started or finished watching if let appEnvironment { let watchEntries = appEnvironment.dataManager.watchEntriesMap()