mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-28 16:00:31 +05:30
commit
ddd31aa859
@ -79,28 +79,28 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
// hide the trending page if enabled
|
// hide the trending page if enabled
|
||||||
val hideTrendingPage = PreferenceHelper.getBoolean(this, "hide_trending_page", false)
|
val hideTrendingPage = PreferenceHelper.getBoolean(this, "hide_trending_page", false)
|
||||||
if (hideTrendingPage) bottomNavigationView.menu.findItem(R.id.home2).isVisible = false
|
if (hideTrendingPage) bottomNavigationView.menu.findItem(R.id.homeFragment).isVisible = false
|
||||||
|
|
||||||
// navigate to the default start tab
|
// navigate to the default start tab
|
||||||
when (PreferenceHelper.getString(this, "default_tab", "home")) {
|
when (PreferenceHelper.getString(this, "default_tab", "home")) {
|
||||||
"home" -> navController.navigate(R.id.home2)
|
"home" -> navController.navigate(R.id.homeFragment)
|
||||||
"subscriptions" -> navController.navigate(R.id.subscriptions)
|
"subscriptions" -> navController.navigate(R.id.subscriptionsFragment)
|
||||||
"library" -> navController.navigate(R.id.library)
|
"library" -> navController.navigate(R.id.libraryFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.bottomNav.setOnItemSelectedListener {
|
binding.bottomNav.setOnItemSelectedListener {
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.home2 -> {
|
R.id.homeFragment -> {
|
||||||
navController.backQueue.clear()
|
navController.backQueue.clear()
|
||||||
navController.navigate(R.id.home2)
|
navController.navigate(R.id.homeFragment)
|
||||||
}
|
}
|
||||||
R.id.subscriptions -> {
|
R.id.subscriptionsFragment -> {
|
||||||
// navController.backQueue.clear()
|
// navController.backQueue.clear()
|
||||||
navController.navigate(R.id.subscriptions)
|
navController.navigate(R.id.subscriptionsFragment)
|
||||||
}
|
}
|
||||||
R.id.library -> {
|
R.id.libraryFragment -> {
|
||||||
// navController.backQueue.clear()
|
// navController.backQueue.clear()
|
||||||
navController.navigate(R.id.library)
|
navController.navigate(R.id.libraryFragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
@ -176,7 +176,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
channel = channel!!.replace("/c/", "")
|
channel = channel!!.replace("/c/", "")
|
||||||
channel = channel.replace("/user/", "")
|
channel = channel.replace("/user/", "")
|
||||||
val bundle = bundleOf("channel_id" to channel)
|
val bundle = bundleOf("channel_id" to channel)
|
||||||
navController.navigate(R.id.channel, bundle)
|
navController.navigate(R.id.channelFragment, bundle)
|
||||||
} else if (data.path!!.contains("/playlist")) {
|
} else if (data.path!!.contains("/playlist")) {
|
||||||
Log.i(TAG, "URI Type: Playlist")
|
Log.i(TAG, "URI Type: Playlist")
|
||||||
var playlist = data.query!!
|
var playlist = data.query!!
|
||||||
|
@ -69,7 +69,7 @@ class CommentsAdapter(
|
|||||||
commentorImage.setOnClickListener {
|
commentorImage.setOnClickListener {
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to comment.commentorUrl)
|
val bundle = bundleOf("channel_id" to comment.commentorUrl)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
try {
|
try {
|
||||||
val mainMotionLayout =
|
val mainMotionLayout =
|
||||||
activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
||||||
|
@ -61,7 +61,7 @@ class RepliesAdapter(
|
|||||||
commentorImage.setOnClickListener {
|
commentorImage.setOnClickListener {
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to reply.commentorUrl)
|
val bundle = bundleOf("channel_id" to reply.commentorUrl)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
try {
|
try {
|
||||||
val mainMotionLayout =
|
val mainMotionLayout =
|
||||||
activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
||||||
|
@ -117,7 +117,7 @@ class SearchViewHolder(
|
|||||||
channelImage.setOnClickListener {
|
channelImage.setOnClickListener {
|
||||||
val activity = v.context as MainActivity
|
val activity = v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to item.uploaderUrl)
|
val bundle = bundleOf("channel_id" to item.uploaderUrl)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ class SearchViewHolder(
|
|||||||
v.setOnClickListener {
|
v.setOnClickListener {
|
||||||
val activity = v.context as MainActivity
|
val activity = v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to item.url)
|
val bundle = bundleOf("channel_id" to item.url)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
}
|
}
|
||||||
// todo sub button
|
// todo sub button
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ class SubscriptionAdapter(
|
|||||||
channelImage.setOnClickListener {
|
channelImage.setOnClickListener {
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to trending.uploaderUrl)
|
val bundle = bundleOf("channel_id" to trending.uploaderUrl)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
try {
|
try {
|
||||||
val mainMotionLayout =
|
val mainMotionLayout =
|
||||||
activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
||||||
|
@ -48,7 +48,7 @@ class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscrip
|
|||||||
root.setOnClickListener {
|
root.setOnClickListener {
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to subscription.url)
|
val bundle = bundleOf("channel_id" to subscription.url)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
}
|
}
|
||||||
subscriptionSubscribe.setOnClickListener {
|
subscriptionSubscribe.setOnClickListener {
|
||||||
if (!isLoading) {
|
if (!isLoading) {
|
||||||
|
@ -53,7 +53,7 @@ class TrendingAdapter(
|
|||||||
channelImage.setOnClickListener {
|
channelImage.setOnClickListener {
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to trending.uploaderUrl)
|
val bundle = bundleOf("channel_id" to trending.uploaderUrl)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
try {
|
try {
|
||||||
val mainMotionLayout =
|
val mainMotionLayout =
|
||||||
activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
||||||
|
@ -0,0 +1,96 @@
|
|||||||
|
package com.github.libretube.adapters
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.format.DateUtils
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||||
|
import androidx.core.os.bundleOf
|
||||||
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.github.libretube.R
|
||||||
|
import com.github.libretube.activities.MainActivity
|
||||||
|
import com.github.libretube.databinding.WatchHistoryRowBinding
|
||||||
|
import com.github.libretube.dialogs.VideoOptionsDialog
|
||||||
|
import com.github.libretube.fragments.PlayerFragment
|
||||||
|
import com.github.libretube.obj.WatchHistoryItem
|
||||||
|
import com.squareup.picasso.Picasso
|
||||||
|
|
||||||
|
class WatchHistoryAdapter(
|
||||||
|
private val watchHistory: MutableList<WatchHistoryItem>,
|
||||||
|
private val childFragmentManager: FragmentManager
|
||||||
|
) :
|
||||||
|
RecyclerView.Adapter<WatchHistoryViewHolder>() {
|
||||||
|
private val TAG = "WatchHistoryAdapter"
|
||||||
|
private lateinit var binding: WatchHistoryRowBinding
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
val size = watchHistory.size
|
||||||
|
watchHistory.clear()
|
||||||
|
notifyItemRangeRemoved(0, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WatchHistoryViewHolder {
|
||||||
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
|
binding = WatchHistoryRowBinding.inflate(layoutInflater, parent, false)
|
||||||
|
return WatchHistoryViewHolder(binding.root)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: WatchHistoryViewHolder, position: Int) {
|
||||||
|
val video = watchHistory[position]
|
||||||
|
binding.apply {
|
||||||
|
videoTitle.text = video.title
|
||||||
|
channelName.text = video.uploader
|
||||||
|
uploadDate.text = video.uploadDate
|
||||||
|
thumbnailDuration.text = DateUtils.formatElapsedTime(video.duration?.toLong()!!)
|
||||||
|
Picasso.get().load(video.thumbnailUrl).into(thumbnail)
|
||||||
|
Picasso.get().load(video.uploaderAvatar).into(channelImage)
|
||||||
|
|
||||||
|
channelImage.setOnClickListener {
|
||||||
|
val activity = holder.v.context as MainActivity
|
||||||
|
val bundle = bundleOf("channel_id" to video.uploaderUrl)
|
||||||
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
|
try {
|
||||||
|
val mainMotionLayout =
|
||||||
|
activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
||||||
|
if (mainMotionLayout.progress == 0.toFloat()) {
|
||||||
|
mainMotionLayout.transitionToEnd()
|
||||||
|
activity.findViewById<MotionLayout>(R.id.playerMotionLayout)
|
||||||
|
.transitionToEnd()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
root.setOnClickListener {
|
||||||
|
var bundle = Bundle()
|
||||||
|
bundle.putString("videoId", video.videoId)
|
||||||
|
var frag = PlayerFragment()
|
||||||
|
frag.arguments = bundle
|
||||||
|
val activity = holder.v.context as AppCompatActivity
|
||||||
|
activity.supportFragmentManager.beginTransaction()
|
||||||
|
.remove(PlayerFragment())
|
||||||
|
.commit()
|
||||||
|
activity.supportFragmentManager.beginTransaction()
|
||||||
|
.replace(R.id.container, frag)
|
||||||
|
.commitNow()
|
||||||
|
}
|
||||||
|
root.setOnLongClickListener {
|
||||||
|
VideoOptionsDialog(video.videoId!!, holder.v.context)
|
||||||
|
.show(childFragmentManager, VideoOptionsDialog.TAG)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return watchHistory.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WatchHistoryViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
|
||||||
|
init {
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import android.view.ViewGroup
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.github.libretube.R
|
import com.github.libretube.R
|
||||||
import com.github.libretube.adapters.PlaylistsAdapter
|
import com.github.libretube.adapters.PlaylistsAdapter
|
||||||
@ -43,6 +44,17 @@ class LibraryFragment : Fragment() {
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding.playlistRecView.layoutManager = LinearLayoutManager(view.context)
|
binding.playlistRecView.layoutManager = LinearLayoutManager(view.context)
|
||||||
token = PreferenceHelper.getToken(requireContext())
|
token = PreferenceHelper.getToken(requireContext())
|
||||||
|
|
||||||
|
// hide watch history button of history disabled
|
||||||
|
val watchHistoryEnabled = PreferenceHelper.getBoolean(requireContext(), "watch_history_toggle", true)
|
||||||
|
if (!watchHistoryEnabled) {
|
||||||
|
binding.showWatchHistory.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.showWatchHistory.setOnClickListener {
|
||||||
|
findNavController().navigate(R.id.watchHistoryFragment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (token != "") {
|
if (token != "") {
|
||||||
binding.boogh.visibility = View.GONE
|
binding.boogh.visibility = View.GONE
|
||||||
binding.textLike.visibility = View.GONE
|
binding.textLike.visibility = View.GONE
|
||||||
|
@ -455,6 +455,11 @@ class PlayerFragment : Fragment() {
|
|||||||
if (!relatedStreamsEnabled) toggleComments()
|
if (!relatedStreamsEnabled) toggleComments()
|
||||||
// prepare for autoplay
|
// prepare for autoplay
|
||||||
initAutoPlay()
|
initAutoPlay()
|
||||||
|
val watchHistoryEnabled =
|
||||||
|
PreferenceHelper.getBoolean(requireContext(), "Watch_history_toggle", true)
|
||||||
|
if (watchHistoryEnabled) {
|
||||||
|
PreferenceHelper.addToWatchHistory(requireContext(), videoId!!, response)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -742,7 +747,7 @@ class PlayerFragment : Fragment() {
|
|||||||
binding.playerChannel.setOnClickListener {
|
binding.playerChannel.setOnClickListener {
|
||||||
val activity = view.context as MainActivity
|
val activity = view.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to response.uploaderUrl)
|
val bundle = bundleOf("channel_id" to response.uploaderUrl)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
activity.binding.mainMotionLayout.transitionToEnd()
|
activity.binding.mainMotionLayout.transitionToEnd()
|
||||||
binding.playerMotionLayout.transitionToEnd()
|
binding.playerMotionLayout.transitionToEnd()
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.github.libretube.fragments
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.github.libretube.adapters.WatchHistoryAdapter
|
||||||
|
import com.github.libretube.databinding.FragmentWatchHistoryBinding
|
||||||
|
import com.github.libretube.util.PreferenceHelper
|
||||||
|
|
||||||
|
class WatchHistoryFragment : Fragment() {
|
||||||
|
private val TAG = "WatchHistoryFragment"
|
||||||
|
private lateinit var binding: FragmentWatchHistoryBinding
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentWatchHistoryBinding.inflate(layoutInflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val watchHistory = PreferenceHelper.getWatchHistory(requireContext())
|
||||||
|
val watchHistoryAdapter = WatchHistoryAdapter(watchHistory, childFragmentManager)
|
||||||
|
binding.watchHistoryRecView.adapter = watchHistoryAdapter
|
||||||
|
|
||||||
|
binding.clearHistory.setOnClickListener {
|
||||||
|
PreferenceHelper.removePreference(requireContext(), "watch_history")
|
||||||
|
watchHistoryAdapter.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverse order
|
||||||
|
val linearLayoutManager = LinearLayoutManager(view.context)
|
||||||
|
linearLayoutManager.reverseLayout = true
|
||||||
|
linearLayoutManager.stackFromEnd = true
|
||||||
|
|
||||||
|
binding.watchHistoryRecView.layoutManager = linearLayoutManager
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.github.libretube.obj
|
||||||
|
|
||||||
|
data class WatchHistoryItem(
|
||||||
|
val videoId: String?,
|
||||||
|
val title: String?,
|
||||||
|
val uploadDate: String?,
|
||||||
|
val uploader: String?,
|
||||||
|
val uploaderUrl: String?,
|
||||||
|
val uploaderAvatar: String?,
|
||||||
|
val thumbnailUrl: String?,
|
||||||
|
val duration: Int?
|
||||||
|
)
|
@ -18,12 +18,20 @@ class AdvancedSettings : PreferenceFragmentCompat() {
|
|||||||
val settingsActivity = activity as SettingsActivity
|
val settingsActivity = activity as SettingsActivity
|
||||||
settingsActivity.binding.topBarTextView.text = getString(R.string.advanced)
|
settingsActivity.binding.topBarTextView.text = getString(R.string.advanced)
|
||||||
|
|
||||||
|
// clear search history
|
||||||
val clearHistory = findPreference<Preference>("clear_history")
|
val clearHistory = findPreference<Preference>("clear_history")
|
||||||
clearHistory?.setOnPreferenceClickListener {
|
clearHistory?.setOnPreferenceClickListener {
|
||||||
PreferenceHelper.removePreference(requireContext(), "search_history")
|
PreferenceHelper.removePreference(requireContext(), "search_history")
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clear watch history
|
||||||
|
val clearWatchHistory = findPreference<Preference>("clear_watch_history")
|
||||||
|
clearWatchHistory?.setOnPreferenceClickListener {
|
||||||
|
PreferenceHelper.removePreference(requireContext(), "watch_history")
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
val resetSettings = findPreference<Preference>("reset_settings")
|
val resetSettings = findPreference<Preference>("reset_settings")
|
||||||
resetSettings?.setOnPreferenceClickListener {
|
resetSettings?.setOnPreferenceClickListener {
|
||||||
showResetDialog()
|
showResetDialog()
|
||||||
|
@ -4,11 +4,15 @@ import android.content.Context
|
|||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.github.libretube.obj.CustomInstance
|
import com.github.libretube.obj.CustomInstance
|
||||||
|
import com.github.libretube.obj.Streams
|
||||||
|
import com.github.libretube.obj.WatchHistoryItem
|
||||||
import com.google.common.reflect.TypeToken
|
import com.google.common.reflect.TypeToken
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import java.lang.reflect.Type
|
import java.lang.reflect.Type
|
||||||
|
|
||||||
object PreferenceHelper {
|
object PreferenceHelper {
|
||||||
|
private val TAG = "PreferenceHelper"
|
||||||
|
|
||||||
fun setString(context: Context, key: String?, value: String?) {
|
fun setString(context: Context, key: String?, value: String?) {
|
||||||
val editor = getDefaultSharedPreferencesEditor(context)
|
val editor = getDefaultSharedPreferencesEditor(context)
|
||||||
editor.putString(key, value)
|
editor.putString(key, value)
|
||||||
@ -122,6 +126,48 @@ object PreferenceHelper {
|
|||||||
editor.putStringSet("search_history", set).apply()
|
editor.putStringSet("search_history", set).apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addToWatchHistory(context: Context, videoId: String, streams: Streams) {
|
||||||
|
val editor = getDefaultSharedPreferencesEditor(context)
|
||||||
|
val gson = Gson()
|
||||||
|
|
||||||
|
val watchHistoryItem = WatchHistoryItem(
|
||||||
|
videoId,
|
||||||
|
streams.title,
|
||||||
|
streams.uploadDate,
|
||||||
|
streams.uploader,
|
||||||
|
streams.uploaderUrl?.replace("/channel/", ""),
|
||||||
|
streams.uploaderAvatar,
|
||||||
|
streams.thumbnailUrl,
|
||||||
|
streams.duration
|
||||||
|
)
|
||||||
|
|
||||||
|
val watchHistory = getWatchHistory(context)
|
||||||
|
|
||||||
|
// delete entries that have the same videoId
|
||||||
|
var indexToRemove = Int.MAX_VALUE
|
||||||
|
watchHistory.forEachIndexed { index, item ->
|
||||||
|
if (item.videoId == videoId) indexToRemove = index
|
||||||
|
}
|
||||||
|
if (indexToRemove != Int.MAX_VALUE) watchHistory.removeAt(indexToRemove)
|
||||||
|
|
||||||
|
watchHistory += watchHistoryItem
|
||||||
|
|
||||||
|
val json = gson.toJson(watchHistory)
|
||||||
|
editor.putString("watch_history", json).apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getWatchHistory(context: Context): ArrayList<WatchHistoryItem> {
|
||||||
|
val settings = getDefaultSharedPreferences(context)
|
||||||
|
val gson = Gson()
|
||||||
|
val json: String = settings.getString("watch_history", "")!!
|
||||||
|
val type: Type = object : TypeToken<List<WatchHistoryItem?>?>() {}.type
|
||||||
|
return try {
|
||||||
|
gson.fromJson(json, type)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
arrayListOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getDefaultSharedPreferences(context: Context): SharedPreferences {
|
private fun getDefaultSharedPreferences(context: Context): SharedPreferences {
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
return PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,27 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".fragments.LibraryFragment">
|
tools:context=".fragments.LibraryFragment">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/showWatchHistory"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/watch_history"
|
||||||
|
android:textSize="20sp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/loginOrRegister2"
|
android:id="@+id/loginOrRegister2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -64,6 +85,8 @@
|
|||||||
</ScrollView>
|
</ScrollView>
|
||||||
</com.github.libretube.util.CustomSwipeToRefresh>
|
</com.github.libretube.util.CustomSwipeToRefresh>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/create_playlist"
|
android:id="@+id/create_playlist"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
36
app/src/main/res/layout/fragment_watch_history.xml
Normal file
36
app/src/main/res/layout/fragment_watch_history.xml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingHorizontal="8dp"
|
||||||
|
android:layout_marginBottom="8dp" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/watch_history"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/clearHistory"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:src="@drawable/ic_trash"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/watchHistoryRecView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:nestedScrollingEnabled="false"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
106
app/src/main/res/layout/watch_history_row.xml
Normal file
106
app/src/main/res/layout/watch_history_row.xml
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/video_search"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:background="?android:attr/selectableItemBackground">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintGuide_percent=".45" />
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/thumbnail_card"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintDimensionRatio="16:9"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/guideline"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.0"
|
||||||
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/thumbnail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:srcCompat="@tools:sample/backgrounds/scenic" />
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:layout_marginBottom="3dp"
|
||||||
|
app:cardBackgroundColor="@color/duration_background_color"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:cardElevation="0dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/thumbnail_duration"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="6dp"
|
||||||
|
android:paddingTop="2dp"
|
||||||
|
android:paddingEnd="6dp"
|
||||||
|
android:paddingBottom="2dp"
|
||||||
|
android:textColor="@color/duration_text_color"
|
||||||
|
android:textSize="11sp"
|
||||||
|
tools:text="05:36" />
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/video_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/thumbnail_card"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/upload_date"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/thumbnail_card"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/video_title" />
|
||||||
|
|
||||||
|
<de.hdodenhof.circleimageview.CircleImageView
|
||||||
|
android:id="@+id/channel_image"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/upload_date" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/channel_name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/channel_image"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/upload_date" />
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -2,15 +2,15 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/home2"
|
android:id="@+id/homeFragment"
|
||||||
android:icon="@drawable/ic_home"
|
android:icon="@drawable/ic_home"
|
||||||
android:title="@string/startpage" />
|
android:title="@string/startpage" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/subscriptions"
|
android:id="@+id/subscriptionsFragment"
|
||||||
android:icon="@drawable/ic_subscriptions"
|
android:icon="@drawable/ic_subscriptions"
|
||||||
android:title="@string/subscriptions" />
|
android:title="@string/subscriptions" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/library"
|
android:id="@+id/libraryFragment"
|
||||||
android:icon="@drawable/ic_library"
|
android:icon="@drawable/ic_library"
|
||||||
android:title="@string/library" />
|
android:title="@string/library" />
|
||||||
|
|
||||||
|
@ -3,20 +3,20 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/nav"
|
android:id="@+id/nav"
|
||||||
app:startDestination="@id/home2">
|
app:startDestination="@id/homeFragment">
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/home2"
|
android:id="@+id/homeFragment"
|
||||||
android:name="com.github.libretube.fragments.HomeFragment"
|
android:name="com.github.libretube.fragments.HomeFragment"
|
||||||
android:label="fragment_home"
|
android:label="fragment_home"
|
||||||
tools:layout="@layout/fragment_home" />
|
tools:layout="@layout/fragment_home" />
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/subscriptions"
|
android:id="@+id/subscriptionsFragment"
|
||||||
android:name="com.github.libretube.fragments.SubscriptionsFragment"
|
android:name="com.github.libretube.fragments.SubscriptionsFragment"
|
||||||
android:label="fragment_subscriptions"
|
android:label="fragment_subscriptions"
|
||||||
tools:layout="@layout/fragment_subscriptions" />
|
tools:layout="@layout/fragment_subscriptions" />
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/library"
|
android:id="@+id/libraryFragment"
|
||||||
android:name="com.github.libretube.fragments.LibraryFragment"
|
android:name="com.github.libretube.fragments.LibraryFragment"
|
||||||
android:label="fragment_library"
|
android:label="fragment_library"
|
||||||
tools:layout="@layout/fragment_library"></fragment>
|
tools:layout="@layout/fragment_library"></fragment>
|
||||||
@ -26,7 +26,7 @@
|
|||||||
android:label="fragment_search"
|
android:label="fragment_search"
|
||||||
tools:layout="@layout/fragment_search" />
|
tools:layout="@layout/fragment_search" />
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/channel"
|
android:id="@+id/channelFragment"
|
||||||
android:name="com.github.libretube.fragments.ChannelFragment"
|
android:name="com.github.libretube.fragments.ChannelFragment"
|
||||||
android:label="channel"
|
android:label="channel"
|
||||||
tools:layout="@layout/fragment_channel">
|
tools:layout="@layout/fragment_channel">
|
||||||
@ -44,7 +44,8 @@
|
|||||||
app:argType="string" />
|
app:argType="string" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/settings"
|
android:id="@+id/watchHistoryFragment"
|
||||||
android:name="com.github.libretube.SettingsActivity$SettingsFragment"
|
android:name="com.github.libretube.fragments.WatchHistoryFragment"
|
||||||
android:label="Settings" />
|
android:label="@string/watch_history"
|
||||||
|
tools:layout="@layout/fragment_watch_history"/>
|
||||||
</navigation>
|
</navigation>
|
@ -79,7 +79,7 @@
|
|||||||
<string name="okay">OK</string>
|
<string name="okay">OK</string>
|
||||||
<string name="history">History</string>
|
<string name="history">History</string>
|
||||||
<string name="search_history">Search History</string>
|
<string name="search_history">Search History</string>
|
||||||
<string name="clear_history">Clear History</string>
|
<string name="clear_history">Clear history</string>
|
||||||
<string name="music_songs">YT Music Songs</string>
|
<string name="music_songs">YT Music Songs</string>
|
||||||
<string name="music_videos">YT Music Videos</string>
|
<string name="music_videos">YT Music Videos</string>
|
||||||
<string name="music_albums">YT Music Albums</string>
|
<string name="music_albums">YT Music Albums</string>
|
||||||
@ -207,4 +207,5 @@
|
|||||||
<string name="deleteAccount_summary">Delete your Piped account</string>
|
<string name="deleteAccount_summary">Delete your Piped account</string>
|
||||||
<string name="account">Account</string>
|
<string name="account">Account</string>
|
||||||
<string name="restore">Restore</string>
|
<string name="restore">Restore</string>
|
||||||
|
<string name="watch_history">Watch history</string>
|
||||||
</resources>
|
</resources>
|
@ -46,6 +46,21 @@
|
|||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory app:title="@string/watch_history">
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:icon="@drawable/ic_history_filled"
|
||||||
|
app:key="watch_history_toggle"
|
||||||
|
app:title="@string/watch_history" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:icon="@drawable/ic_trash"
|
||||||
|
app:key="clear_watch_history"
|
||||||
|
app:title="@string/clear_history" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory>
|
<PreferenceCategory>
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
|
Loading…
x
Reference in New Issue
Block a user