Merge pull request #2119 from Bnyro/master

Indicator the the feed got caught up for subscriptions
This commit is contained in:
Bnyro 2022-11-27 19:51:55 +01:00 committed by GitHub
commit 04a9340eec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 115 additions and 7 deletions

View File

@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class ContentItem(
var url: String? = null,
val type: String? = null,
var thumbnail: String? = null,
var uploaderName: String? = null,
var uploaded: Long? = null,
@ -16,6 +17,7 @@ data class ContentItem(
var uploadedDate: String? = null,
var duration: Long? = null,
var views: Long? = null,
var isShort: Boolean? = null,
var uploaderVerified: Boolean? = null,
// Channel and Playlist attributes
var name: String? = null,

View File

@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class StreamItem(
var url: String? = null,
val type: String? = null,
var title: String? = null,
var thumbnail: String? = null,
var uploaderName: String? = null,
@ -15,5 +16,6 @@ data class StreamItem(
var views: Long? = null,
var uploaderVerified: Boolean? = null,
var uploaded: Long? = null,
var shortDescription: String? = null
var shortDescription: String? = null,
val isShort: Boolean = false
)

View File

@ -100,12 +100,17 @@ object PreferenceKeys {
const val NOTIFICATION_ENABLED = "notification_toggle"
const val CHECKING_FREQUENCY = "checking_frequency"
const val REQUIRED_NETWORK = "required_network"
const val LAST_STREAM_VIDEO_ID = "last_stream_video_id"
const val IGNORED_NOTIFICATION_CHANNELS = "ignored_notification_channels"
const val NOTIFICATION_TIME_ENABLED = "notification_time"
const val NOTIFICATION_START_TIME = "notification_start_time"
const val NOTIFICATION_END_TIME = "notification_end_time"
/**
* Subscriptions
*/
const val LAST_STREAM_VIDEO_ID = "last_stream_video_id"
const val LAST_WATCHED_FEED_TIME = "last_watched_feed_time"
/**
* Advanced
*/

View File

@ -71,10 +71,10 @@ class SearchAdapter(
}
override fun getItemViewType(position: Int): Int {
return when {
searchItems[position].url!!.startsWith("/watch", false) -> 0
searchItems[position].url!!.startsWith("/channel", false) -> 1
searchItems[position].url!!.startsWith("/playlist", false) -> 2
return when (searchItems[position].type) {
"stream" -> 0
"channel" -> 1
"playlist" -> 2
else -> 3
}
}

View File

@ -13,6 +13,7 @@ import androidx.recyclerview.widget.RecyclerView.LayoutManager
import com.github.libretube.R
import com.github.libretube.api.obj.StreamItem
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.AllCaughtUpRowBinding
import com.github.libretube.databinding.TrendingRowBinding
import com.github.libretube.databinding.VideoRowBinding
import com.github.libretube.extensions.formatShort
@ -44,6 +45,10 @@ class VideosAdapter(
}
}
override fun getItemViewType(position: Int): Int {
return if (streamItems[position].type == "caught") CAUGHT_UP_TYPE else NORMAL_TYPE
}
fun updateItems() {
val oldSize = index
index += 10
@ -59,6 +64,7 @@ class VideosAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VideosViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return when {
viewType == CAUGHT_UP_TYPE -> VideosViewHolder(AllCaughtUpRowBinding.inflate(layoutInflater, parent, false))
forceMode in listOf(ForceMode.TRENDING, ForceMode.RELATED, ForceMode.HOME) -> VideosViewHolder(TrendingRowBinding.inflate(layoutInflater, parent, false))
forceMode == ForceMode.CHANNEL -> VideosViewHolder(VideoRowBinding.inflate(layoutInflater, parent, false))
PreferenceHelper.getBoolean(
@ -74,7 +80,7 @@ class VideosAdapter(
val video = streamItems[position]
// hide the item if there was an extractor error
if (video.title == null) {
if (video.title == null && video.type != "caught") {
holder.itemView.visibility = View.GONE
holder.itemView.layoutParams = RecyclerView.LayoutParams(0, 0)
return
@ -191,5 +197,8 @@ class VideosAdapter(
)
}
}
private const val NORMAL_TYPE = 0
private const val CAUGHT_UP_TYPE = 1
}
}

View File

@ -10,6 +10,7 @@ import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R
import com.github.libretube.api.obj.StreamItem
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.FragmentSubscriptionsBinding
import com.github.libretube.ui.adapters.LegacySubscriptionAdapter
@ -144,6 +145,15 @@ class SubscriptionsFragment : BaseFragment() {
4 -> feed.sortedBy { it.uploaderName }
5 -> feed.sortedBy { it.uploaderName }.reversed()
else -> feed
}.toMutableList()
// add an "all caught up item"
if (sortOrder == 0) {
val lastCheckedFeedTime = PreferenceHelper.getLastCheckedFeedTime()
val caughtUpIndex = feed.indexOfFirst { (it.uploaded ?: 0L) / 1000 < lastCheckedFeedTime }
if (caughtUpIndex > 0) {
sortedFeed.add(caughtUpIndex, StreamItem(type = "caught"))
}
}
binding.subChannelsContainer.visibility = View.GONE
@ -158,6 +168,8 @@ class SubscriptionsFragment : BaseFragment() {
showAllAtOnce = false
)
binding.subFeed.adapter = subscriptionAdapter
PreferenceHelper.updateLastFeedWatchedTime()
}
private fun showSubscriptions() {

View File

@ -1,12 +1,14 @@
package com.github.libretube.ui.viewholders
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.AllCaughtUpRowBinding
import com.github.libretube.databinding.TrendingRowBinding
import com.github.libretube.databinding.VideoRowBinding
class VideosViewHolder : RecyclerView.ViewHolder {
var trendingRowBinding: TrendingRowBinding? = null
var videoRowBinding: VideoRowBinding? = null
var allCaughtUpBinding: AllCaughtUpRowBinding? = null
constructor(binding: TrendingRowBinding) : super(binding.root) {
trendingRowBinding = binding
@ -15,4 +17,8 @@ class VideosViewHolder : RecyclerView.ViewHolder {
constructor(binding: VideoRowBinding) : super(binding.root) {
videoRowBinding = binding
}
constructor(binding: AllCaughtUpRowBinding) : super(binding.root) {
allCaughtUpBinding = binding
}
}

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager
import com.github.libretube.constants.PreferenceKeys
import java.time.Instant
object PreferenceHelper {
/**
@ -45,6 +46,10 @@ object PreferenceHelper {
editor.putFloat(key, value).commit()
}
fun putLong(key: String, value: Long) {
editor.putLong(key, value).commit()
}
fun getString(key: String?, defValue: String): String {
return settings.getString(key, defValue) ?: defValue
}
@ -57,6 +62,10 @@ object PreferenceHelper {
return settings.getInt(key, defValue)
}
fun getLong(key: String?, defValue: Long): Long {
return settings.getLong(key, defValue)
}
fun getFloat(key: String?, defValue: Float): Float {
return settings.getFloat(key, defValue)
}
@ -89,6 +98,14 @@ object PreferenceHelper {
return getString(PreferenceKeys.LAST_STREAM_VIDEO_ID, "")
}
fun updateLastFeedWatchedTime() {
putLong(PreferenceKeys.LAST_WATCHED_FEED_TIME, Instant.now().epochSecond)
}
fun getLastCheckedFeedTime(): Long {
return getLong(PreferenceKeys.LAST_WATCHED_FEED_TIME, 0)
}
fun saveErrorLog(log: String) {
editor.putString(PreferenceKeys.ERROR_LOG, log).commit()
}

View File

@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="400"
android:viewportHeight="400">
<path
android:fillColor="#FF000000"
android:pathData="M200,15.89C98.47,15.89 15.89,98.48 15.89,200 15.89,301.52 98.47,384.11 200,384.11 301.52,384.11 384.11,301.52 384.11,200 384.11,98.48 301.52,15.89 200,15.89ZM200,359.97C111.79,359.97 40.03,288.2 40.03,200c0,-88.21 71.76,-159.96 159.96,-159.96 88.21,0 159.97,71.76 159.97,159.96 0,88.2 -71.76,159.97 -159.97,159.97z"
android:strokeWidth="27"
android:strokeColor="#000000" />
<path
android:fillColor="#FF000000"
android:pathData="m266.65,139.73 l-94.94,94.93 -38.38,-38.37c-4.72,-4.71 -12.36,-4.71 -17.07,0 -4.72,4.72 -4.72,12.36 0,17.07l46.91,46.91c2.36,2.35 5.45,3.53 8.53,3.53 3.09,0 6.19,-1.18 8.54,-3.54 0.01,-0.01 0.01,-0.02 0.02,-0.03L283.73,156.8c4.72,-4.71 4.72,-12.36 0,-17.07 -4.72,-4.72 -12.36,-4.72 -17.07,0z"
android:strokeWidth="27"
android:strokeColor="#000000" />
</vector>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingVertical="50dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:src="@drawable/ic_done"
android:tint="?attr/colorPrimary"
tools:ignore="UseAppTint" />
<TextView
android:layout_width="wrap_content"
android:layout_marginTop="10dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/all_caught_up"
android:textColor="?android:attr/textColorPrimary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:textSize="13sp"
android:text="@string/all_caught_up_summary"
android:textColor="?attr/colorControlNormal" />
</LinearLayout>

View File

@ -401,6 +401,8 @@
<string name="captions_size">Captions size</string>
<string name="double_tap_seek">Double tap to seek</string>
<string name="double_tap_seek_summary">Tap twice at the left or right to rewind or forward the player position.</string>
<string name="all_caught_up">You\'re all caught up</string>
<string name="all_caught_up_summary">You\'ve seen all new videos</string>
<!-- Notification channel strings -->
<string name="download_channel_name">Download Service</string>