mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-01-07 18:10:31 +05:30
refactor: unify views string formatting logic to avoid bugs
This commit is contained in:
parent
4098b33021
commit
23edd3b5d9
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user