add functionality for watch history items

This commit is contained in:
Bnyro 2022-07-01 19:47:43 +02:00
parent 321887933b
commit 31cf6f608e
8 changed files with 114 additions and 11 deletions

View File

@ -1,20 +1,39 @@
package com.github.libretube.adapters package com.github.libretube.adapters
import android.R.attr.data
import android.os.Bundle
import android.text.format.DateUtils
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup 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 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.databinding.WatchHistoryRowBinding
import com.github.libretube.dialogs.VideoOptionsDialog
import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.obj.WatchHistoryItem import com.github.libretube.obj.WatchHistoryItem
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
class WatchHistoryAdapter( class WatchHistoryAdapter(
private val watchHistory: List<WatchHistoryItem> private val watchHistory: MutableList<WatchHistoryItem>,
private val childFragmentManager: FragmentManager
) : ) :
RecyclerView.Adapter<WatchHistoryViewHolder>() { RecyclerView.Adapter<WatchHistoryViewHolder>() {
private val TAG = "WatchHistoryAdapter" private val TAG = "WatchHistoryAdapter"
private lateinit var binding: WatchHistoryRowBinding private lateinit var binding: WatchHistoryRowBinding
fun clear() {
val size = watchHistory.size
watchHistory.clear()
notifyItemRangeRemoved(0, size)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WatchHistoryViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WatchHistoryViewHolder {
val layoutInflater = LayoutInflater.from(parent.context) val layoutInflater = LayoutInflater.from(parent.context)
binding = WatchHistoryRowBinding.inflate(layoutInflater, parent, false) binding = WatchHistoryRowBinding.inflate(layoutInflater, parent, false)
@ -26,8 +45,45 @@ class WatchHistoryAdapter(
binding.apply { binding.apply {
videoTitle.text = video.title videoTitle.text = video.title
channelName.text = video.uploader 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.thumbnailUrl).into(thumbnail)
Picasso.get().load(video.uploaderAvatar).into(channelImage) 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
}
} }
} }

View File

@ -45,8 +45,14 @@ class LibraryFragment : Fragment() {
binding.playlistRecView.layoutManager = LinearLayoutManager(view.context) binding.playlistRecView.layoutManager = LinearLayoutManager(view.context)
token = PreferenceHelper.getToken(requireContext()) token = PreferenceHelper.getToken(requireContext())
binding.showWatchHistory.setOnClickListener { // hide watch history button of history disabled
findNavController().navigate(R.id.watchHistoryFragment) 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 != "") {

View File

@ -27,7 +27,20 @@ class WatchHistoryFragment : Fragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val watchHistory = PreferenceHelper.getWatchHistory(requireContext()) val watchHistory = PreferenceHelper.getWatchHistory(requireContext())
binding.watchHistoryRecView.adapter = WatchHistoryAdapter(watchHistory) val watchHistoryAdapter = WatchHistoryAdapter(watchHistory, childFragmentManager)
binding.watchHistoryRecView.layoutManager = LinearLayoutManager(view.context) 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
} }
} }

View File

@ -5,8 +5,8 @@ data class WatchHistoryItem(
val title: String?, val title: String?,
val uploadDate: String?, val uploadDate: String?,
val uploader: String?, val uploader: String?,
val uploaderAvatar: String?,
val uploaderUrl: String?, val uploaderUrl: String?,
val uploaderAvatar: String?,
val thumbnailUrl: String?, val thumbnailUrl: String?,
val duration: Int? val duration: Int?
) )

View File

@ -143,6 +143,15 @@ object PreferenceHelper {
) )
val watchHistory = getWatchHistory(context) 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 watchHistory += watchHistoryItem
val json = gson.toJson(watchHistory) val json = gson.toJson(watchHistory)

View File

@ -16,6 +16,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="10dp" android:padding="10dp"
android:background="?attr/selectableItemBackground"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView

View File

@ -4,15 +4,33 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<TextView <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/watch_history" /> 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 <androidx.recyclerview.widget.RecyclerView
android:id="@+id/watchHistoryRecView" android:id="@+id/watchHistoryRecView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="8dp"
android:nestedScrollingEnabled="false"/> android:nestedScrollingEnabled="false"/>
</LinearLayout> </LinearLayout>

View File

@ -73,7 +73,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/video_views" android:id="@+id/upload_date"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
@ -88,7 +88,7 @@
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/video_views" /> app:layout_constraintTop_toBottomOf="@id/upload_date" />
<TextView <TextView
android:id="@+id/channel_name" android:id="@+id/channel_name"
@ -100,7 +100,7 @@
android:maxLines="1" android:maxLines="1"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/channel_image" app:layout_constraintStart_toEndOf="@id/channel_image"
app:layout_constraintTop_toBottomOf="@+id/video_views" /> app:layout_constraintTop_toBottomOf="@id/upload_date" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>