From 9d5ed16e37c929656c2b15119ac6ff4d867cc815 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Sat, 2 Jul 2022 19:04:19 +0200 Subject: [PATCH] remember watch position --- .../libretube/fragments/PlayerFragment.kt | 29 ++++++++++ .../com/github/libretube/obj/WatchPosition.kt | 6 +++ .../libretube/preferences/AdvancedSettings.kt | 3 +- .../libretube/preferences/PreferenceHelper.kt | 54 ++++++++++++++++++- app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/advanced_settings.xml | 7 +++ 6 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/com/github/libretube/obj/WatchPosition.kt diff --git a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt index b44f803f5..ccc8763fa 100644 --- a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt @@ -371,6 +371,7 @@ class PlayerFragment : Fragment() { override fun onDestroy() { super.onDestroy() try { + saveWatchPosition() mediaSession.isActive = false mediaSession.release() mediaSessionConnector.setPlayer(null) @@ -384,6 +385,25 @@ class PlayerFragment : Fragment() { } } + // save the watch position if video isn't finished and option enabled + private fun saveWatchPosition() { + val watchPositionsEnabled = PreferenceHelper.getBoolean( + requireContext(), + "watch_positions_toggle", + true + ) + if (watchPositionsEnabled && exoPlayer.currentPosition != exoPlayer.duration) { + PreferenceHelper.saveWatchPosition( + requireContext(), + videoId!!, + exoPlayer.currentPosition + ) + } else if (watchPositionsEnabled) { + // delete watch position if video has ended + PreferenceHelper.removeWatchPosition(requireContext(), videoId!!) + } + } + private fun checkForSegments() { if (!exoPlayer.isPlaying || !sponsorBlockPrefs.sponsorBlockEnabled) return @@ -445,6 +465,7 @@ class PlayerFragment : Fragment() { val position = arguments?.getLong("timeStamp")!! * 1000 exoPlayer.seekTo(position) } + seekToWatchPosition() exoPlayer.play() exoPlayerView.useController = true initializePlayerNotification(requireContext()) @@ -464,6 +485,14 @@ class PlayerFragment : Fragment() { run() } + // seek to saved watch position if available + private fun seekToWatchPosition() { + val watchPositions = PreferenceHelper.getWatchPositions(requireContext()) + watchPositions.forEach { + if (it.videoId == videoId) exoPlayer.seekTo(it.position) + } + } + // the function is working recursively private fun initAutoPlay() { // save related streams for autoplay diff --git a/app/src/main/java/com/github/libretube/obj/WatchPosition.kt b/app/src/main/java/com/github/libretube/obj/WatchPosition.kt new file mode 100644 index 000000000..b7b000310 --- /dev/null +++ b/app/src/main/java/com/github/libretube/obj/WatchPosition.kt @@ -0,0 +1,6 @@ +package com.github.libretube.obj + +data class WatchPosition( + val videoId: String, + val position: Long +) diff --git a/app/src/main/java/com/github/libretube/preferences/AdvancedSettings.kt b/app/src/main/java/com/github/libretube/preferences/AdvancedSettings.kt index a0b656815..b8f4dbdef 100644 --- a/app/src/main/java/com/github/libretube/preferences/AdvancedSettings.kt +++ b/app/src/main/java/com/github/libretube/preferences/AdvancedSettings.kt @@ -25,10 +25,11 @@ class AdvancedSettings : PreferenceFragmentCompat() { true } - // clear watch history + // clear watch history and positions val clearWatchHistory = findPreference("clear_watch_history") clearWatchHistory?.setOnPreferenceClickListener { PreferenceHelper.removePreference(requireContext(), "watch_history") + PreferenceHelper.removePreference(requireContext(), "watch_positions") true } diff --git a/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt b/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt index e6b5808d2..1e00a7fd2 100644 --- a/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt +++ b/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt @@ -6,6 +6,7 @@ import androidx.preference.PreferenceManager import com.github.libretube.obj.CustomInstance import com.github.libretube.obj.Streams import com.github.libretube.obj.WatchHistoryItem +import com.github.libretube.obj.WatchPosition import com.google.common.reflect.TypeToken import com.google.gson.Gson import java.lang.reflect.Type @@ -144,11 +145,11 @@ object PreferenceHelper { val watchHistory = getWatchHistory(context) // delete entries that have the same videoId - var indexToRemove = Int.MAX_VALUE + var indexToRemove: Int? = null watchHistory.forEachIndexed { index, item -> if (item.videoId == videoId) indexToRemove = index } - if (indexToRemove != Int.MAX_VALUE) watchHistory.removeAt(indexToRemove) + if (indexToRemove != null) watchHistory.removeAt(indexToRemove!!) watchHistory += watchHistoryItem @@ -168,6 +169,55 @@ object PreferenceHelper { } } + fun saveWatchPosition(context: Context, videoId: String, position: Long) { + val editor = getDefaultSharedPreferencesEditor(context) + + val watchPositions = getWatchPositions(context) + val watchPositionItem = WatchPosition(videoId, position) + + var indexToRemove: Int? = null + watchPositions.forEachIndexed { index, item -> + if (item.videoId == videoId) indexToRemove = index + } + + if (indexToRemove != null) watchPositions.removeAt(indexToRemove!!) + + watchPositions += watchPositionItem + + val gson = Gson() + val json = gson.toJson(watchPositions) + editor.putString("watch_positions", json).commit() + } + + fun removeWatchPosition(context: Context, videoId: String) { + val editor = getDefaultSharedPreferencesEditor(context) + + val watchPositions = getWatchPositions(context) + + var indexToRemove: Int? = null + watchPositions.forEachIndexed { index, item -> + if (item.videoId == videoId) indexToRemove = index + } + + if (indexToRemove != null) watchPositions.removeAt(indexToRemove!!) + + val gson = Gson() + val json = gson.toJson(watchPositions) + editor.putString("watch_positions", json).commit() + } + + fun getWatchPositions(context: Context): ArrayList { + val settings = getDefaultSharedPreferences(context) + val gson = Gson() + val json: String = settings.getString("watch_positions", "")!! + val type: Type = object : TypeToken?>() {}.type + return try { + gson.fromJson(json, type) + } catch (e: Exception) { + arrayListOf() + } + } + private fun getDefaultSharedPreferences(context: Context): SharedPreferences { return PreferenceManager.getDefaultSharedPreferences(context) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ae2a5b946..d4c981d68 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -208,4 +208,6 @@ Account Restore Watch History + Remember position + Remember the watch position and automatically seek to it. \ No newline at end of file diff --git a/app/src/main/res/xml/advanced_settings.xml b/app/src/main/res/xml/advanced_settings.xml index 7fb5eb34d..19720126b 100644 --- a/app/src/main/res/xml/advanced_settings.xml +++ b/app/src/main/res/xml/advanced_settings.xml @@ -54,6 +54,13 @@ app:key="watch_history_toggle" app:title="@string/watch_history" /> + +