refactor: unify views string formatting logic to avoid bugs

This commit is contained in:
Bnyro 2024-10-11 12:23:16 +02:00
parent 4098b33021
commit 23edd3b5d9
6 changed files with 19 additions and 55 deletions

View File

@ -73,16 +73,7 @@ class SearchChannelAdapter : ListAdapter<ContentItem, SearchViewHolder>(SearchCa
ImageHelper.loadImage(item.thumbnail, thumbnail) ImageHelper.loadImage(item.thumbnail, thumbnail)
thumbnailDuration.setFormattedDuration(item.duration, item.isShort) thumbnailDuration.setFormattedDuration(item.duration, item.isShort)
videoTitle.text = item.title videoTitle.text = item.title
videoInfo.text = TextUtils.formatViewsString(root.context, item.views, item.uploaded)
val viewsString = item.views.takeIf { it != -1L }?.formatShort().orEmpty()
val uploadDate = item.uploaded.takeIf { it > 0 }?.let {
" ${TextUtils.SEPARATOR} ${TextUtils.formatRelativeDate(root.context, it)}"
}.orEmpty()
videoInfo.text = root.context.getString(
R.string.normal_views,
viewsString,
uploadDate
)
channelContainer.isGone = true channelContainer.isGone = true

View File

@ -82,16 +82,7 @@ class SearchResultsAdapter(
ImageHelper.loadImage(item.thumbnail, thumbnail) ImageHelper.loadImage(item.thumbnail, thumbnail)
thumbnailDuration.setFormattedDuration(item.duration, item.isShort) thumbnailDuration.setFormattedDuration(item.duration, item.isShort)
videoTitle.text = item.title videoTitle.text = item.title
videoInfo.text = TextUtils.formatViewsString(root.context, item.views, item.uploaded)
val viewsString = item.views.takeIf { it != -1L }?.formatShort().orEmpty()
val uploadDate = item.uploaded.takeIf { it > 0 }?.let {
" ${TextUtils.SEPARATOR} ${TextUtils.formatRelativeDate(root.context, it)}"
}.orEmpty()
videoInfo.text = root.context.getString(
R.string.normal_views,
viewsString,
uploadDate
)
channelName.text = item.uploaderName channelName.text = item.uploaderName
ImageHelper.loadImage(item.uploaderAvatar, channelImage, true) ImageHelper.loadImage(item.uploaderAvatar, channelImage, true)

View File

@ -11,7 +11,6 @@ import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.LayoutManager import androidx.recyclerview.widget.RecyclerView.LayoutManager
import com.github.libretube.R
import com.github.libretube.api.obj.StreamItem import com.github.libretube.api.obj.StreamItem
import com.github.libretube.constants.IntentData import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
@ -20,7 +19,6 @@ import com.github.libretube.databinding.TrendingRowBinding
import com.github.libretube.databinding.VideoRowBinding import com.github.libretube.databinding.VideoRowBinding
import com.github.libretube.extensions.ceilHalf import com.github.libretube.extensions.ceilHalf
import com.github.libretube.extensions.dpToPx import com.github.libretube.extensions.dpToPx
import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.toID import com.github.libretube.extensions.toID
import com.github.libretube.helpers.ImageHelper import com.github.libretube.helpers.ImageHelper
import com.github.libretube.helpers.NavigationHelper import com.github.libretube.helpers.NavigationHelper
@ -102,10 +100,6 @@ class VideosAdapter(
val activity = (context as BaseActivity) val activity = (context as BaseActivity)
val fragmentManager = activity.supportFragmentManager val fragmentManager = activity.supportFragmentManager
val uploadDateStr = video.uploaded.takeIf { it > 0 }
?.let { TextUtils.formatRelativeDate(context, it) }
?.toString()
// Trending layout // Trending layout
holder.trendingRowBinding?.apply { holder.trendingRowBinding?.apply {
// set a fixed width for better visuals // set a fixed width for better visuals
@ -116,16 +110,8 @@ class VideosAdapter(
} }
textViewTitle.text = video.title textViewTitle.text = video.title
textViewChannel.text = if ((video.views ?: 0L) > 0L) { textViewChannel.text = TextUtils.formatViewsString(root.context, video.views ?: -1, video.uploaded, video.uploaderName)
root.context.getString(
R.string.trending_views,
video.uploaderName,
video.views.formatShort(),
uploadDateStr
)
} else {
"${video.uploaderName} ${TextUtils.SEPARATOR} $uploadDateStr"
}
video.duration?.let { thumbnailDuration.setFormattedDuration(it, video.isShort) } video.duration?.let { thumbnailDuration.setFormattedDuration(it, video.isShort) }
channelImage.setOnClickListener { channelImage.setOnClickListener {
NavigationHelper.navigateChannel(root.context, video.uploaderUrl) NavigationHelper.navigateChannel(root.context, video.uploaderUrl)
@ -153,15 +139,9 @@ class VideosAdapter(
// Normal videos row layout // Normal videos row layout
holder.videoRowBinding?.apply { holder.videoRowBinding?.apply {
videoTitle.text = video.title videoTitle.text = video.title
videoInfo.text = TextUtils.formatViewsString(root.context, video.views ?: -1, video.uploaded)
videoInfo.text = root.context.getString(
R.string.normal_views,
video.views.formatShort(),
uploadDateStr?.let { " ${TextUtils.SEPARATOR} $it" }
)
thumbnailDuration.text = video.duration?.let { DateUtils.formatElapsedTime(it) } thumbnailDuration.text = video.duration?.let { DateUtils.formatElapsedTime(it) }
ImageHelper.loadImage(video.thumbnail, thumbnail) ImageHelper.loadImage(video.thumbnail, thumbnail)
if (forceMode != LayoutMode.CHANNEL_ROW) { if (forceMode != LayoutMode.CHANNEL_ROW) {

View File

@ -20,8 +20,6 @@ import com.github.libretube.ui.activities.VideoTagsAdapter
import com.github.libretube.util.HtmlParser import com.github.libretube.util.HtmlParser
import com.github.libretube.util.LinkHandler import com.github.libretube.util.LinkHandler
import com.github.libretube.util.TextUtils import com.github.libretube.util.TextUtils
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import java.util.Locale import java.util.Locale
class DescriptionLayout( class DescriptionLayout(
@ -48,7 +46,7 @@ class DescriptionLayout(
val views = streams.views.formatShort() val views = streams.views.formatShort()
binding.run { binding.run {
playerViewsInfo.text = context.getString(R.string.normal_views, views, localizeDate(streams)) playerViewsInfo.text = context.getString(R.string.normal_views, views, TextUtils.formatRelativeDate(context, streams.uploaded ?: -1L))
textLike.text = streams.likes.formatShort() textLike.text = streams.likes.formatShort()
textDislike.isVisible = streams.dislikes >= 0 textDislike.isVisible = streams.dislikes >= 0
@ -119,7 +117,7 @@ class DescriptionLayout(
// show exact view count // show exact view count
"%,d".format(streams.views) "%,d".format(streams.views)
} }
val viewInfo = context.getString(R.string.normal_views, views, localizeDate(streams)) val viewInfo = context.getString(R.string.normal_views, views, TextUtils.formatRelativeDate(context, streams.uploaded ?: -1L))
if (binding.descLinLayout.isVisible) { if (binding.descLinLayout.isVisible) {
// hide the description and chapters // hide the description and chapters
binding.playerDescriptionArrow.animate().rotation( binding.playerDescriptionArrow.animate().rotation(
@ -147,14 +145,6 @@ class DescriptionLayout(
binding.playerViewsInfo.text = viewInfo binding.playerViewsInfo.text = viewInfo
} }
private fun localizeDate(streams: Streams): String {
if (streams.livestream || streams.uploadTimestamp == null) return ""
val date = streams.uploadTimestamp.toLocalDateTime(TimeZone.currentSystemDefault()).date
return TextUtils.SEPARATOR + TextUtils.localizeDate(date)
}
companion object { companion object {
private const val ANIMATION_DURATION = 250L private const val ANIMATION_DURATION = 250L
} }

View File

@ -7,6 +7,7 @@ import android.os.Build
import android.text.format.DateUtils import android.text.format.DateUtils
import com.github.libretube.BuildConfig import com.github.libretube.BuildConfig
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.extensions.formatShort
import com.google.common.math.IntMath.pow import com.google.common.math.IntMath.pow
import kotlinx.datetime.toJavaLocalDate import kotlinx.datetime.toJavaLocalDate
import java.time.Instant import java.time.Instant
@ -146,4 +147,14 @@ object TextUtils {
fun getUserAgent(context: Context): String { fun getUserAgent(context: Context): String {
return "${context.packageName}/${BuildConfig.VERSION_NAME}" return "${context.packageName}/${BuildConfig.VERSION_NAME}"
} }
fun formatViewsString(context: Context, views: Long, uploaded: Long, uploader: String? = null): String {
val viewsString = views.takeIf { it != -1L }?.formatShort()?.let {
context.getString(R.string.view_count, it)
}
val uploadDate = uploaded.takeIf { it > 0 }?.let {
formatRelativeDate(context, it)
}
return listOfNotNull(uploader, viewsString, uploadDate).joinToString(SEPARATOR)
}
} }

View File

@ -518,6 +518,7 @@
<string name="local_stream_extraction_summary">Directly fetch video playback information from YouTube without using Piped.</string> <string name="local_stream_extraction_summary">Directly fetch video playback information from YouTube without using Piped.</string>
<string name="local_ryd">Local Return Youtube Dislikes</string> <string name="local_ryd">Local Return Youtube Dislikes</string>
<string name="local_ryd_summary">Directly fetch dislike information from https://returnyoutubedislikeapi.com</string> <string name="local_ryd_summary">Directly fetch dislike information from https://returnyoutubedislikeapi.com</string>
<string name="view_count">%1$s views</string>
<!-- Notification channel strings --> <!-- Notification channel strings -->
<string name="download_channel_name">Download Service</string> <string name="download_channel_name">Download Service</string>