mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 22:30:30 +05:30
Merge pull request #4415 from Bnyro/master
feat(queue): options to mark as (un)watched, and remove watched videos
This commit is contained in:
commit
aa2f9aef4d
@ -5,6 +5,9 @@ import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @param position: Position in milliseconds
|
||||
*/
|
||||
@Serializable
|
||||
@Entity(tableName = "watchPosition")
|
||||
data class WatchPosition(
|
||||
|
@ -17,7 +17,7 @@ import kotlinx.coroutines.withContext
|
||||
/**
|
||||
* Dialog with different options for a selected video.
|
||||
*
|
||||
* Needs the [videoId] to load the content from the right video.
|
||||
* Needs the [channelId] to load the content from the right video.
|
||||
*/
|
||||
class ChannelOptionsBottomSheet(
|
||||
private val channelId: String,
|
||||
|
@ -10,21 +10,30 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.databinding.QueueBottomSheetBinding
|
||||
import com.github.libretube.db.DatabaseHelper
|
||||
import com.github.libretube.db.DatabaseHolder
|
||||
import com.github.libretube.db.obj.WatchPosition
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.ui.adapters.PlayingQueueAdapter
|
||||
import com.github.libretube.ui.dialogs.AddToPlaylistDialog
|
||||
import com.github.libretube.util.PlayingQueue
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.lang.IllegalArgumentException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class PlayingQueueSheet : ExpandedBottomSheet() {
|
||||
private lateinit var binding: QueueBottomSheetBinding
|
||||
private var _binding: QueueBottomSheetBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = QueueBottomSheetBinding.inflate(layoutInflater)
|
||||
_binding = QueueBottomSheetBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@ -89,6 +98,10 @@ class PlayingQueueSheet : ExpandedBottomSheet() {
|
||||
dialog?.dismiss()
|
||||
}
|
||||
|
||||
binding.watchPositionsOptions.setOnClickListener {
|
||||
showWatchPositionsOptions()
|
||||
}
|
||||
|
||||
val callback = object : ItemTouchHelper.SimpleCallback(
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN,
|
||||
ItemTouchHelper.LEFT
|
||||
@ -141,7 +154,60 @@ class PlayingQueueSheet : ExpandedBottomSheet() {
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
PlayingQueue.setStreams(newQueue)
|
||||
binding.optionsRecycler.adapter?.notifyDataSetChanged()
|
||||
_binding?.optionsRecycler?.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun showWatchPositionsOptions() {
|
||||
val options = arrayOf(
|
||||
getString(R.string.mark_as_watched),
|
||||
getString(R.string.mark_as_unwatched),
|
||||
getString(R.string.remove_watched_videos)
|
||||
)
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.watch_positions)
|
||||
.setItems(options) { _, index ->
|
||||
when (index) {
|
||||
0 -> {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
PlayingQueue.getStreams().forEach {
|
||||
val videoId = it.url.orEmpty().toID()
|
||||
val duration = it.duration ?: 0
|
||||
val watchPosition = WatchPosition(videoId, duration * 1000)
|
||||
DatabaseHolder.Database.watchPositionDao().insert(watchPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1 -> {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
PlayingQueue.getStreams().forEach {
|
||||
DatabaseHolder.Database.watchPositionDao()
|
||||
.deleteByVideoId(it.url.orEmpty().toID())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2 -> {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val currentStream = PlayingQueue.getCurrent()
|
||||
val streams = DatabaseHelper
|
||||
.filterUnwatched(PlayingQueue.getStreams())
|
||||
.toMutableList()
|
||||
if (currentStream != null &&
|
||||
streams.none { it.url?.toID() == currentStream.url?.toID() }
|
||||
) {
|
||||
streams.add(0, currentStream)
|
||||
}
|
||||
PlayingQueue.setStreams(streams)
|
||||
withContext(Dispatchers.Main) {
|
||||
_binding?.optionsRecycler?.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
10
app/src/main/res/drawable/ic_eye.xml
Normal file
10
app/src/main/res/drawable/ic_eye.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z" />
|
||||
</vector>
|
@ -39,64 +39,42 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/repeat"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="5dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="5dp"
|
||||
style="@style/QueueSheetOption"
|
||||
android:src="@drawable/ic_repeat" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/shuffle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="5dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="5dp"
|
||||
style="@style/QueueSheetOption"
|
||||
android:src="@drawable/ic_shuffle" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/reverse"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="5dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="5dp"
|
||||
style="@style/QueueSheetOption"
|
||||
android:src="@drawable/ic_reverse" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/add_to_playlist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="5dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="5dp"
|
||||
style="@style/QueueSheetOption"
|
||||
android:src="@drawable/ic_playlist_add" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sort"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="5dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="5dp"
|
||||
style="@style/QueueSheetOption"
|
||||
android:src="@drawable/ic_sort" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/watch_positions_options"
|
||||
style="@style/QueueSheetOption"
|
||||
android:src="@drawable/ic_eye" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/clear_queue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="5dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="5dp"
|
||||
style="@style/QueueSheetOption"
|
||||
android:src="@drawable/ic_close" />
|
||||
|
||||
<ImageView
|
||||
style="@style/QueueSheetOption"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
android:paddingVertical="5dp"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/ic_arrow_down" />
|
||||
|
||||
|
@ -439,6 +439,7 @@
|
||||
<string name="sort_by">Sort by</string>
|
||||
<string name="uploader_name">Uploader name</string>
|
||||
<string name="duration_span">Duration: %1$s</string>
|
||||
<string name="remove_watched_videos">Remove watched videos</string>
|
||||
|
||||
<!-- Backup & Restore Settings -->
|
||||
<string name="import_subscriptions_from">Import subscriptions from</string>
|
||||
|
@ -248,4 +248,13 @@
|
||||
|
||||
</style>
|
||||
|
||||
<style name="QueueSheetOption">
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:background">?selectableItemBackgroundBorderless</item>
|
||||
<item name="android:layout_marginStart">4dp</item>
|
||||
<item name="android:layout_marginEnd">4dp</item>
|
||||
<item name="android:padding">5dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user