mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 08:20:32 +05:30
Convert watch positions dao to coroutines, fix holes in the feed
This commit is contained in:
parent
06d6c85b25
commit
2d80de9f52
@ -10,20 +10,20 @@ import com.github.libretube.db.obj.WatchPosition
|
||||
@Dao
|
||||
interface WatchPositionDao {
|
||||
@Query("SELECT * FROM watchPosition")
|
||||
fun getAll(): List<WatchPosition>
|
||||
suspend fun getAll(): List<WatchPosition>
|
||||
|
||||
@Query("SELECT * FROM watchPosition WHERE videoId LIKE :videoId LIMIT 1")
|
||||
fun findById(videoId: String): WatchPosition?
|
||||
suspend fun findById(videoId: String): WatchPosition?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertAll(vararg watchPositions: WatchPosition)
|
||||
suspend fun insertAll(vararg watchPositions: WatchPosition)
|
||||
|
||||
@Delete
|
||||
fun delete(watchPosition: WatchPosition)
|
||||
suspend fun delete(watchPosition: WatchPosition)
|
||||
|
||||
@Query("DELETE FROM watchHistoryItem WHERE videoId = :videoId")
|
||||
fun deleteById(videoId: String)
|
||||
suspend fun deleteById(videoId: String)
|
||||
|
||||
@Query("DELETE FROM watchPosition")
|
||||
fun deleteAll()
|
||||
suspend fun deleteAll()
|
||||
}
|
||||
|
@ -25,8 +25,6 @@ import com.github.libretube.constants.PLAYER_NOTIFICATION_ID
|
||||
import com.github.libretube.db.DatabaseHolder.Database
|
||||
import com.github.libretube.db.obj.WatchPosition
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.extensions.awaitQuery
|
||||
import com.github.libretube.extensions.query
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.helpers.PlayerHelper
|
||||
import com.github.libretube.helpers.PlayerHelper.checkForSegments
|
||||
@ -37,8 +35,10 @@ import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.PlaybackException
|
||||
import com.google.android.exoplayer2.Player
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.encodeToString
|
||||
|
||||
@ -154,7 +154,7 @@ class BackgroundMode : LifecycleService() {
|
||||
// indicator that a new video is getting loaded
|
||||
this.streams ?: return@let
|
||||
|
||||
query {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
Database.watchPositionDao().insertAll(watchPosition)
|
||||
}
|
||||
}
|
||||
@ -213,7 +213,7 @@ class BackgroundMode : LifecycleService() {
|
||||
player?.seekTo(seekToPosition)
|
||||
} else if (PlayerHelper.watchPositionsAudio) {
|
||||
runCatching {
|
||||
val watchPosition = awaitQuery {
|
||||
val watchPosition = runBlocking {
|
||||
Database.watchPositionDao().findById(videoId)
|
||||
}
|
||||
streams?.duration?.let {
|
||||
|
@ -33,8 +33,7 @@ import com.github.libretube.util.TextUtils
|
||||
class VideosAdapter(
|
||||
private val streamItems: MutableList<StreamItem>,
|
||||
private val showAllAtOnce: Boolean = true,
|
||||
private val forceMode: ForceMode = ForceMode.NONE,
|
||||
private val hideWatched: Boolean = false
|
||||
private val forceMode: ForceMode = ForceMode.NONE
|
||||
) : RecyclerView.Adapter<VideosViewHolder>() {
|
||||
|
||||
private var visibleCount = minOf(10, streamItems.size)
|
||||
@ -116,13 +115,8 @@ class VideosAdapter(
|
||||
}
|
||||
|
||||
videoId?.let {
|
||||
val shouldHide =
|
||||
(holder.trendingRowBinding?.watchProgress ?: holder.videoRowBinding!!.watchProgress)
|
||||
.setWatchProgressLength(it, video.duration ?: 0L)
|
||||
if (hideWatched && shouldHide) {
|
||||
hideItemView(holder)
|
||||
return
|
||||
}
|
||||
(holder.trendingRowBinding?.watchProgress ?: holder.videoRowBinding!!.watchProgress)
|
||||
.setWatchProgressLength(it, video.duration ?: 0L)
|
||||
}
|
||||
|
||||
// Trending layout
|
||||
|
@ -4,37 +4,34 @@ import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.github.libretube.db.DatabaseHolder.Database
|
||||
import com.github.libretube.extensions.awaitQuery
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
/**
|
||||
* Shows the already watched time under the video
|
||||
* @param videoId The id of the video to inspect
|
||||
* @param duration The duration of the video in seconds
|
||||
* @return Whether the video is already watched more than 90%
|
||||
*/
|
||||
fun View.setWatchProgressLength(videoId: String, duration: Long): Boolean {
|
||||
fun View.setWatchProgressLength(videoId: String, duration: Long) {
|
||||
updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
matchConstraintPercentWidth = 0f
|
||||
}
|
||||
visibility = View.GONE
|
||||
|
||||
val progress = try {
|
||||
awaitQuery {
|
||||
runBlocking {
|
||||
Database.watchPositionDao().findById(videoId)?.position
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
return false
|
||||
return
|
||||
} // divide by 1000 to convert ms to seconds
|
||||
?.toFloat()?.div(1000)
|
||||
|
||||
if (progress == null || duration == 0L) {
|
||||
return false
|
||||
return
|
||||
}
|
||||
|
||||
updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
matchConstraintPercentWidth = progress / duration.toFloat()
|
||||
}
|
||||
visibility = View.VISIBLE
|
||||
|
||||
return progress / duration.toFloat() > 0.9
|
||||
}
|
||||
|
@ -56,10 +56,8 @@ import com.github.libretube.db.DatabaseHolder.Database
|
||||
import com.github.libretube.db.obj.WatchPosition
|
||||
import com.github.libretube.enums.PlayerEvent
|
||||
import com.github.libretube.enums.ShareObjectType
|
||||
import com.github.libretube.extensions.awaitQuery
|
||||
import com.github.libretube.extensions.formatShort
|
||||
import com.github.libretube.extensions.hideKeyboard
|
||||
import com.github.libretube.extensions.query
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.extensions.updateParameters
|
||||
import com.github.libretube.helpers.BackgroundHelper
|
||||
@ -114,6 +112,7 @@ import kotlin.math.abs
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
@ -609,7 +608,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
|
||||
private fun saveWatchPosition() {
|
||||
if (!PlayerHelper.watchPositionsVideo) return
|
||||
val watchPosition = WatchPosition(videoId!!, exoPlayer.currentPosition)
|
||||
query {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
Database.watchPositionDao().insertAll(watchPosition)
|
||||
}
|
||||
}
|
||||
@ -765,7 +764,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
|
||||
private fun seekToWatchPosition() {
|
||||
// browse the watch positions
|
||||
val position = try {
|
||||
awaitQuery {
|
||||
runBlocking {
|
||||
Database.watchPositionDao().findById(videoId!!)?.position
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -13,6 +13,8 @@ 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.db.DatabaseHolder
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.helpers.PreferenceHelper
|
||||
import com.github.libretube.ui.adapters.LegacySubscriptionAdapter
|
||||
import com.github.libretube.ui.adapters.SubscriptionChannelAdapter
|
||||
@ -20,6 +22,8 @@ import com.github.libretube.ui.adapters.VideosAdapter
|
||||
import com.github.libretube.ui.base.BaseFragment
|
||||
import com.github.libretube.ui.models.SubscriptionsViewModel
|
||||
import com.github.libretube.ui.sheets.BaseBottomSheet
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class SubscriptionsFragment : BaseFragment() {
|
||||
private lateinit var binding: FragmentSubscriptionsBinding
|
||||
@ -159,7 +163,16 @@ class SubscriptionsFragment : BaseFragment() {
|
||||
2 -> it.isShort
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
}.let { streams ->
|
||||
runBlocking {
|
||||
if (!PreferenceHelper.getBoolean(PreferenceKeys.HIDE_WATCHED_FROM_FEED, false)) {
|
||||
streams
|
||||
} else {
|
||||
removeWatchVideosFromFeed(streams)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort the feed
|
||||
val sortedFeed = when (selectedSortOrder) {
|
||||
0 -> feed
|
||||
@ -191,14 +204,27 @@ class SubscriptionsFragment : BaseFragment() {
|
||||
binding.subProgress.visibility = View.GONE
|
||||
subscriptionsAdapter = VideosAdapter(
|
||||
sortedFeed.toMutableList(),
|
||||
showAllAtOnce = false,
|
||||
hideWatched = PreferenceHelper.getBoolean(PreferenceKeys.HIDE_WATCHED_FROM_FEED, false)
|
||||
showAllAtOnce = false
|
||||
)
|
||||
binding.subFeed.adapter = subscriptionsAdapter
|
||||
|
||||
PreferenceHelper.updateLastFeedWatchedTime()
|
||||
}
|
||||
|
||||
private fun removeWatchVideosFromFeed(streams: List<StreamItem>): List<StreamItem> {
|
||||
return runBlocking {
|
||||
streams.filter {
|
||||
runBlocking(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val watchPosition = DatabaseHolder.Database.watchPositionDao()
|
||||
.findById(it.url.orEmpty().toID())?.position?.div(1000)
|
||||
(watchPosition ?: 0) < 0.9 * (it.duration ?: 1L)
|
||||
}.getOrDefault(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showSubscriptions() {
|
||||
if (viewModel.subscriptions.value == null) return
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.github.libretube.ui.sheets
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
@ -9,7 +8,6 @@ import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.db.DatabaseHolder
|
||||
import com.github.libretube.db.obj.WatchPosition
|
||||
import com.github.libretube.enums.ShareObjectType
|
||||
import com.github.libretube.extensions.awaitQuery
|
||||
import com.github.libretube.helpers.BackgroundHelper
|
||||
import com.github.libretube.helpers.PlayerHelper
|
||||
import com.github.libretube.helpers.PreferenceHelper
|
||||
@ -102,22 +100,16 @@ class VideoOptionsBottomSheet(
|
||||
}
|
||||
getString(R.string.mark_as_watched) -> {
|
||||
val watchPosition = WatchPosition(videoId, Long.MAX_VALUE)
|
||||
awaitQuery {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
DatabaseHolder.Database.watchPositionDao().insertAll(watchPosition)
|
||||
}
|
||||
if (PreferenceHelper.getBoolean(PreferenceKeys.HIDE_WATCHED_FROM_FEED, false)) {
|
||||
// get the host fragment containing the current fragment
|
||||
val navHostFragment =
|
||||
(context as MainActivity).supportFragmentManager.findFragmentById(
|
||||
R.id.fragment
|
||||
) as NavHostFragment?
|
||||
(context as MainActivity).supportFragmentManager
|
||||
.findFragmentById(R.id.fragment) as NavHostFragment?
|
||||
// get the current fragment
|
||||
val fragment = navHostFragment?.childFragmentManager?.fragments?.firstOrNull()
|
||||
Log.e(
|
||||
"fragments",
|
||||
navHostFragment?.childFragmentManager?.fragments.orEmpty()
|
||||
.joinToString(", ") { it::class.java.name.toString() }
|
||||
)
|
||||
(fragment as? SubscriptionsFragment)?.subscriptionsAdapter?.removeItemById(
|
||||
videoId
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user