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
This commit is contained in:
FineFindus 2025-03-01 12:26:05 +01:00 committed by Bnyro
parent d266f93ec5
commit a042657649
No known key found for this signature in database
2 changed files with 33 additions and 24 deletions

View File

@ -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(

View File

@ -120,6 +120,7 @@ class LocalFeedRepository : FeedRepository {
): List<StreamItem> {
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<StreamInfoItem>()
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 {