From 8dc01197a1f8bcd76d54c3b0eaabff9086f979cf Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sat, 1 Mar 2025 12:26:05 +0100 Subject: [PATCH] fix(Feed): extract shorts uploadDate from feedInfo Shorts extracted from the Shorts tab do not have an uploadDate. They are currently saved with their uploadDate set to -1. This results in them to appear at the end of the feed. To fix this, we can use the generic FeedInfo that contains the uploadDate. This also fixes an issue, where old shorts were fetched on every refresh. Ref: https://github.com/libre-tube/LibreTube/pull/7111 --- .../github/libretube/api/StreamsExtractor.kt | 46 +++++++++++-------- .../libretube/repo/LocalFeedRepository.kt | 13 ++++-- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/github/libretube/api/StreamsExtractor.kt b/app/src/main/java/com/github/libretube/api/StreamsExtractor.kt index 955da92d95..25a249eb58 100644 --- a/app/src/main/java/com/github/libretube/api/StreamsExtractor.kt +++ b/app/src/main/java/com/github/libretube/api/StreamsExtractor.kt @@ -62,25 +62,33 @@ fun AudioStream.toPipedStream() = PipedStream( ) fun StreamInfoItem.toStreamItem( - uploaderAvatarUrl: String? = null -) = StreamItem( - type = StreamItem.TYPE_STREAM, - url = url.toID(), - title = name, - uploaded = uploadDate?.offsetDateTime()?.toEpochSecond()?.times(1000) ?: -1, - uploadedDate = textualUploadDate ?: uploadDate?.offsetDateTime()?.toLocalDateTime() - ?.toLocalDate() - ?.toString(), - uploaderName = uploaderName, - uploaderUrl = uploaderUrl.toID(), - uploaderAvatar = uploaderAvatarUrl ?: uploaderAvatars.maxByOrNull { it.height }?.url, - thumbnail = thumbnails.maxByOrNull { it.height }?.url, - duration = duration, - views = viewCount, - uploaderVerified = isUploaderVerified, - shortDescription = shortDescription, - isShort = isShortFormContent -) + uploaderAvatarUrl: String? = null, + feedInfo: StreamInfoItem? = null, +): StreamItem { + val uploadDate = uploadDate ?: feedInfo?.uploadDate + val textualUploadDate = textualUploadDate ?: feedInfo?.textualUploadDate + + return StreamItem( + type = StreamItem.TYPE_STREAM, + url = url.toID(), + title = name, + uploaded = uploadDate?.offsetDateTime()?.toEpochSecond()?.times(1000) + ?: -1, + uploadedDate = textualUploadDate ?: uploadDate + ?.offsetDateTime()?.toLocalDateTime() + ?.toLocalDate() + ?.toString(), + uploaderName = uploaderName, + uploaderUrl = uploaderUrl.toID(), + uploaderAvatar = uploaderAvatarUrl ?: uploaderAvatars.maxByOrNull { it.height }?.url, + thumbnail = thumbnails.maxByOrNull { it.height }?.url, + duration = duration, + views = viewCount, + uploaderVerified = isUploaderVerified, + shortDescription = shortDescription, + isShort = isShortFormContent + ) +} object StreamsExtractor { suspend fun extractStreams(videoId: String): Streams = withContext(Dispatchers.IO) { diff --git a/app/src/main/java/com/github/libretube/repo/LocalFeedRepository.kt b/app/src/main/java/com/github/libretube/repo/LocalFeedRepository.kt index 5bf8679f8f..07959a2f24 100644 --- a/app/src/main/java/com/github/libretube/repo/LocalFeedRepository.kt +++ b/app/src/main/java/com/github/libretube/repo/LocalFeedRepository.kt @@ -96,6 +96,7 @@ class LocalFeedRepository : FeedRepository { ): List { val channelUrl = "$YOUTUBE_FRONTEND_URL/channel/${channelId}" val feedInfo = FeedInfo.getInfo(channelUrl) + val feedInfoItems = feedInfo.relatedItems.associateBy { it.url } val mostRecentChannelVideo = feedInfo.relatedItems.maxBy { it.uploadDate?.offsetDateTime()?.toInstant()?.toEpochMilli() ?: 0 @@ -122,13 +123,15 @@ class LocalFeedRepository : FeedRepository { }.getOrElse { emptyList() } }.flatten().filterIsInstance() + val channelAvatar = channelInfo.avatars.maxByOrNull { it.height }?.url return related.map { item -> // avatar is not always included in these info items, thus must be taken from channel info response - item.toStreamItem(channelInfo.avatars.maxByOrNull { it.height }?.url) - }.filter { - // shorts don't have upload dates apparently - it.isShort || it.uploaded > minimumDateMillis - } + item.toStreamItem( + channelAvatar, + // shorts fetched via the shorts tab don't have upload dates so we fall back to the feedInfo + feedInfoItems[item.url] + ) + }.filter { it.uploaded > minimumDateMillis } } companion object {