From a04265764901f26262b71c7d4160f1f92c565bca 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 --- .../api/NewPipeMediaServiceRepository.kt | 44 +++++++++++-------- .../libretube/repo/LocalFeedRepository.kt | 13 +++--- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/github/libretube/api/NewPipeMediaServiceRepository.kt b/app/src/main/java/com/github/libretube/api/NewPipeMediaServiceRepository.kt index 933403f6b..2c1e98170 100644 --- a/app/src/main/java/com/github/libretube/api/NewPipeMediaServiceRepository.kt +++ b/app/src/main/java/com/github/libretube/api/NewPipeMediaServiceRepository.kt @@ -87,25 +87,31 @@ private fun AudioStream.toPipedStream() = PipedStream( ) fun StreamInfoItem.toStreamItem( - uploaderAvatarUrl: String? = null -) = StreamItem( - type = 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 = 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 + ) +} fun InfoItem.toContentItem() = when (this) { is StreamInfoItem -> ContentItem( 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 eaf02db47..49d7eddc4 100644 --- a/app/src/main/java/com/github/libretube/repo/LocalFeedRepository.kt +++ b/app/src/main/java/com/github/libretube/repo/LocalFeedRepository.kt @@ -120,6 +120,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 @@ -146,13 +147,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 {