Skip to content
Snippets Groups Projects
Commit 2fc2c889 authored by Geoffrey Métais's avatar Geoffrey Métais Committed by Geoffrey Métais
Browse files

Remove dead VideoGroups classes

parent 0492f4f1
No related branches found
No related tags found
1 merge request!269Video grouping refactoring
......@@ -2,13 +2,9 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:vlc="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<import type="android.text.TextUtils" />
<variable
name="media"
type="org.videolan.medialibrary.media.MediaLibraryItem" />
......@@ -83,85 +79,86 @@
vlc:layout_constraintEnd_toEndOf="@+id/ml_item_thumbnail" />
<TextView
android:id="@+id/ml_item_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
vlc:layout_constraintStart_toStartOf="parent"
vlc:layout_constraintEnd_toStartOf="@+id/item_more"
android:layout_marginBottom="8dp"
style="@style/VLC.TextViewTitle"
android:textColor="@color/grey50"
android:layout_marginStart="4dp"
android:text="@{media.title}"
tools:targetApi="jelly_bean"
vlc:layout_constraintBottom_toBottomOf="parent"
android:textSize="14sp"
android:ellipsize="end"
tools:text="Star wars Episode 1"/>
android:id="@+id/ml_item_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
vlc:layout_constraintStart_toStartOf="parent"
vlc:layout_constraintEnd_toStartOf="@+id/item_more"
android:layout_marginBottom="8dp"
style="@style/VLC.TextViewTitle"
android:textColor="@color/grey50"
android:layout_marginStart="4dp"
android:text="@{media.title}"
tools:targetApi="jelly_bean"
vlc:layout_constraintBottom_toBottomOf="parent"
android:textSize="14sp"
android:ellipsize="end"
tools:text="Star wars Episode 1"/>
<TextView
android:id="@+id/ml_item_resolution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/VLC.TextViewDescription"
android:textColor="@color/grey50"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:background="@drawable/rounded_corners_black_more_transparent"
android:text="@{resolution}"
android:visibility="@{resolution == null ? View.GONE : View.VISIBLE, default=gone}"
android:layout_marginTop="4dp"
vlc:layout_constraintTop_toTopOf="parent"
tools:visibility="visible"
tools:text="HD"
android:layout_marginEnd="4dp"
vlc:layout_constraintEnd_toEndOf="parent"
android:textSize="10sp"/>
android:id="@+id/ml_item_resolution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/VLC.TextViewDescription"
android:textColor="@color/grey50"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:background="@drawable/rounded_corners_black_more_transparent"
android:text="@{resolution}"
android:visibility="@{TextUtils.isEmpty(resolution) ? View.GONE : View.VISIBLE, default=gone}"
android:layout_marginTop="4dp"
vlc:layout_constraintTop_toTopOf="parent"
tools:visibility="visible"
tools:text="HD"
android:layout_marginEnd="4dp"
vlc:layout_constraintEnd_toEndOf="parent"
android:textSize="10sp"/>
<TextView
android:id="@+id/ml_item_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/rounded_corners_black_more_transparent"
vlc:layout_constraintStart_toStartOf="parent"
android:ellipsize="end"
android:gravity="start"
style="@style/VLC.TextViewDescription"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:textColor="@color/grey50"
android:text="@{time}"
vlc:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="4dp"
tools:text="32:55"
android:layout_marginStart="4dp"
android:textSize="10sp"/>
android:id="@+id/ml_item_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/rounded_corners_black_more_transparent"
vlc:layout_constraintStart_toStartOf="parent"
android:ellipsize="end"
android:gravity="start"
style="@style/VLC.TextViewDescription"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:textColor="@color/grey50"
android:text="@{time}"
android:visibility="@{TextUtils.isEmpty(time) ? View.GONE : View.VISIBLE}"
vlc:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="4dp"
tools:text="32:55"
android:layout_marginStart="4dp"
android:textSize="10sp"/>
<ImageView
android:id="@+id/ml_item_seen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_seen_normal"
android:visibility="@{seen == 0L ? View.GONE : View.VISIBLE, default=gone}"
vlc:layout_constraintRight_toRightOf="@+id/ml_item_thumbnail"
vlc:layout_constraintTop_toTopOf="@+id/ml_item_thumbnail"
tools:visibility="visible"/>
android:id="@+id/ml_item_seen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_seen_normal"
android:visibility="@{seen == 0L ? View.GONE : View.VISIBLE, default=gone}"
vlc:layout_constraintRight_toRightOf="@+id/ml_item_thumbnail"
vlc:layout_constraintTop_toTopOf="@+id/ml_item_thumbnail"
tools:visibility="visible"/>
<ImageView
android:id="@+id/item_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
vlc:layout_constraintEnd_toEndOf="parent"
android:clickable="true"
android:contentDescription="@string/more_actions"
android:onClick="@{holder::onMoreClick}"
android:scaleType="fitEnd"
vlc:srcCompat="@drawable/ic_more_card"
vlc:layout_constraintBottom_toBottomOf="parent"/>
android:id="@+id/item_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
vlc:layout_constraintEnd_toEndOf="parent"
android:clickable="true"
android:contentDescription="@string/more_actions"
android:onClick="@{holder::onMoreClick}"
android:scaleType="fitEnd"
vlc:srcCompat="@drawable/ic_more_card"
vlc:layout_constraintBottom_toBottomOf="parent"/>
<ProgressBar
android:id="@+id/ml_item_progress"
......
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:vlc="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
xmlns:vlc="http://schemas.android.com/apk/res-auto" >
<data>
<import type="android.view.View" />
<import type="android.text.TextUtils" />
<variable
name="media"
type="org.videolan.medialibrary.media.MediaLibraryItem" />
......@@ -86,19 +84,19 @@
vlc:layout_constraintTop_toTopOf="@+id/ml_item_thumbnail" />
<TextView
android:id="@+id/ml_item_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
vlc:layout_constraintTop_toTopOf="parent"
vlc:layout_constraintStart_toEndOf="@+id/ml_item_thumbnail"
vlc:layout_constraintEnd_toStartOf="@+id/item_more"
vlc:layout_constraintBottom_toTopOf="@+id/ml_item_time"
android:ellipsize="end"
android:gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:text="@{media.title}"
style="@style/VLC.TextViewTitle"/>
android:id="@+id/ml_item_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
vlc:layout_constraintTop_toTopOf="parent"
vlc:layout_constraintStart_toEndOf="@+id/ml_item_thumbnail"
vlc:layout_constraintEnd_toStartOf="@+id/item_more"
vlc:layout_constraintBottom_toTopOf="@+id/ml_item_time"
android:ellipsize="end"
android:gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:text="@{media.title}"
style="@style/VLC.TextViewTitle"/>
<ImageView
android:id="@+id/item_more"
......@@ -123,6 +121,7 @@
android:layout_marginLeft="16dp"
android:gravity="start"
android:text="@{time}"
android:visibility="@{TextUtils.isEmpty(time) ? View.GONE : View.VISIBLE}"
vlc:layout_constraintTop_toBottomOf="@+id/ml_item_title"
vlc:layout_constraintBottom_toTopOf="@+id/ml_item_progress"
vlc:layout_constraintEnd_toStartOf="@+id/item_more"
......
<?xml version="1.0" encoding="utf-8"?>
<layout 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" >
<data>
<variable
name="group"
type="org.videolan.medialibrary.interfaces.media.AbstractVideoGroup" />
<variable
name="bgColor"
type="int" />
<variable
name="cover"
type="android.graphics.drawable.BitmapDrawable" />
<variable
name="holder"
type="org.videolan.vlc.gui.videogroups.VideoGroupsAdapter.ViewHolder" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:background="@{bgColor}"
android:onClick="@{holder::onClick}" >
<ImageView
android:id="@+id/folder_image"
android:layout_width="128dp"
android:layout_height="80dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:media="@{group}"
android:scaleType="centerCrop"
android:src="@{cover}" />
<TextView
android:id="@+id/folder_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toTopOf="@+id/group_desc"
app:layout_constraintEnd_toStartOf="@+id/folder_more"
app:layout_constraintStart_toEndOf="@+id/folder_image"
app:layout_constraintTop_toTopOf="@+id/folder_image"
app:layout_constraintVertical_chainStyle="packed"
android:text="@{group.title}"
app:ellipsizeMode="@{true}"
android:singleLine="true"
android:maxLines="1"
android:textColor="?attr/list_title"
android:textSize="16sp"
android:lineSpacingMultiplier="1.1"/>
<TextView
android:id="@+id/group_desc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="@+id/folder_image"
app:layout_constraintEnd_toStartOf="@+id/folder_more"
app:layout_constraintStart_toEndOf="@+id/folder_image"
app:layout_constraintTop_toBottomOf="@+id/folder_name"
tools:text="Description"
android:maxLines="1"
android:textColor="?attr/list_subtitle"
android:textSize="12sp" />
<ImageView
android:id="@+id/folder_more"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:clickable="true"
android:contentDescription="@string/more_actions"
android:onClick="@{holder::onCtxClick}"
android:scaleType="center"
android:src="@drawable/ic_more" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="empty"
type="boolean" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/button_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<org.videolan.vlc.gui.view.SwipeRefreshLayout
android:id="@+id/swipeLayout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchButton">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/groups_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:fadingEdge="none"
android:fastScrollEnabled="true"
android:gravity="center"
android:numColumns="auto_fit"
android:padding="@dimen/half_default_margin"
android:scrollbarStyle="outsideInset"
android:scrollbars="vertical"
android:stretchMode="none" />
</org.videolan.vlc.gui.view.SwipeRefreshLayout>
<TextView
android:id="@+id/textview_nomedia"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin"
android:drawableBottom="?attr/empty_icon"
android:drawablePadding="@dimen/default_margin"
android:gravity="center"
android:maxWidth="600dp"
android:text="@string/nomedia"
android:textSize="20sp"
android:visibility="@{empty ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<Button
android:id="@+id/button_nomedia"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_medialibrary_preferences"
android:visibility="@{empty ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview_nomedia" />
<TextView
android:id="@+id/loading_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:text="@string/loading"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/loading_flipper"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button_nomedia" />
<ViewFlipper
android:id="@+id/loading_flipper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:autoStart="true"
android:flipInterval="1000"
app:layout_constraintBaseline_toBaselineOf="@+id/loading_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/loading_title">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="@string/empty"
android:textSize="20sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="@string/load_1_period"
android:textSize="20sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="@string/load_2_period"
android:textSize="20sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="@string/load_3_period"
android:textSize="20sp" />
</ViewFlipper>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
\ No newline at end of file
......@@ -43,7 +43,6 @@ import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
import org.videolan.medialibrary.interfaces.media.AbstractVideoGroup
import org.videolan.medialibrary.media.Folder
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.tools.MultiSelectHelper
import org.videolan.tools.isStarted
import org.videolan.vlc.R
......@@ -135,7 +134,7 @@ class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshL
is VideoCtxClick -> {
when (action.item) {
is AbstractFolder, is AbstractVideoGroup -> showContext(requireActivity(), this@VideoGridFragment, action.position, action.item.title, CTX_FOLDER_FLAGS)
is MediaWrapper -> {
is AbstractMediaWrapper -> {
val group = action.item.type == AbstractMediaWrapper.TYPE_GROUP
var flags = if (group) CTX_VIDEO_GOUP_FLAGS else CTX_VIDEO_FLAGS
if (action.item.time != 0L && !group) flags = flags or CTX_PLAY_FROM_START
......@@ -439,7 +438,7 @@ class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshL
VideoGroupingType.NONE -> {
val list = ArrayList<AbstractMediaWrapper>()
for (mw in multiSelectHelper.getSelection()) {
list.add(mw as MediaWrapper)
list.add(mw as AbstractMediaWrapper)
}
if (list.isNotEmpty()) {
when (item.itemId) {
......@@ -538,7 +537,7 @@ class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshL
private val thumbObs = Observer<AbstractMediaWrapper> { media ->
if (!::videoListAdapter.isInitialized) return@Observer
val position = viewModel.provider.pagedList.value?.indexOf(media) ?: return@Observer
val item = videoListAdapter.getItem(position) as? MediaWrapper
val item = videoListAdapter.getItem(position) as? AbstractMediaWrapper
item?.run {
artworkURL = media.artworkURL
videoListAdapter.notifyItemChanged(position)
......
......@@ -50,7 +50,6 @@ import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
import org.videolan.medialibrary.interfaces.media.AbstractVideoGroup
import org.videolan.medialibrary.media.Folder
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.tools.MultiSelectAdapter
import org.videolan.tools.MultiSelectHelper
import org.videolan.vlc.BR
......@@ -78,7 +77,7 @@ class VideoListAdapter internal constructor(
private val thumbObs = Observer<AbstractMediaWrapper> { media ->
val position = currentList?.snapshot()?.indexOf(media) ?: return@Observer
(getItem(position) as? MediaWrapper)?.run {
(getItem(position) as? AbstractMediaWrapper)?.run {
artworkURL = media.artworkURL
notifyItemChanged(position)
}
......@@ -128,7 +127,7 @@ class VideoListAdapter internal constructor(
for (data in payloads) {
when (data as Int) {
UPDATE_THUMB -> loadImage(holder.overlay, media)
UPDATE_TIME, UPDATE_SEEN -> fillView(holder, media as MediaWrapper)
UPDATE_TIME, UPDATE_SEEN -> fillView(holder, media as AbstractMediaWrapper)
UPDATE_SELECTION -> holder.selectView(multiSelectHelper.isSelected(position))
}
}
......@@ -246,14 +245,14 @@ class VideoListAdapter internal constructor(
private object VideoItemDiffCallback : DiffUtil.ItemCallback<MediaLibraryItem>() {
override fun areItemsTheSame(oldItem: MediaLibraryItem, newItem: MediaLibraryItem): Boolean {
return if (oldItem is MediaWrapper && newItem is MediaWrapper)
return if (oldItem is AbstractMediaWrapper && newItem is AbstractMediaWrapper)
oldItem === newItem || oldItem.type == newItem.type && oldItem.equals(newItem)
else oldItem === newItem || oldItem.itemType == newItem.itemType && oldItem.equals(newItem)
}
@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: MediaLibraryItem, newItem: MediaLibraryItem): Boolean {
return if (oldItem is MediaWrapper && newItem is MediaWrapper) oldItem === newItem || (oldItem.displayTime == newItem.displayTime
return if (oldItem is AbstractMediaWrapper && newItem is AbstractMediaWrapper) oldItem === newItem || (oldItem.displayTime == newItem.displayTime
&& TextUtils.equals(oldItem.artworkMrl, newItem.artworkMrl)
&& oldItem.seen == newItem.seen)
else if (oldItem is Folder && newItem is Folder) return oldItem === newItem || (oldItem.title == newItem.title && oldItem.artworkMrl == newItem.artworkMrl)
......@@ -261,7 +260,7 @@ class VideoListAdapter internal constructor(
}
override fun getChangePayload(oldItem: MediaLibraryItem, newItem: MediaLibraryItem) = when {
(oldItem is MediaWrapper && newItem is MediaWrapper) && oldItem.displayTime != newItem.displayTime -> UPDATE_TIME
(oldItem is AbstractMediaWrapper && newItem is AbstractMediaWrapper) && oldItem.displayTime != newItem.displayTime -> UPDATE_TIME
!TextUtils.equals(oldItem.artworkMrl, newItem.artworkMrl) -> UPDATE_THUMB
else -> UPDATE_SEEN
}
......
package org.videolan.vlc.gui.videogroups
import android.annotation.TargetApi
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.channels.SendChannel
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.medialibrary.interfaces.media.AbstractVideoGroup
import org.videolan.tools.MultiSelectAdapter
import org.videolan.tools.MultiSelectHelper
import org.videolan.vlc.BR
import org.videolan.vlc.R
import org.videolan.vlc.databinding.VideogroupItemBinding
import org.videolan.vlc.gui.helpers.SelectorViewHolder
import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.util.UPDATE_SELECTION
class VideoGroupsAdapter (val actor: SendChannel<VideoGroupAction>) : PagedListAdapter<AbstractVideoGroup,
VideoGroupsAdapter.ViewHolder>(DIFF_CALLBACK), MultiSelectAdapter<AbstractVideoGroup>,
CoroutineScope by MainScope() {
private lateinit var inflater: LayoutInflater
val multiSelectHelper = MultiSelectHelper(this, UPDATE_SELECTION)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
if (!this::inflater.isInitialized) inflater = LayoutInflater.from(parent.context)
return ViewHolder(VideogroupItemBinding.inflate(inflater, parent, false))
}
override fun getItem(position: Int) = super.getItem(position)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val group = getItem(position)
holder.binding.group = group
val count = group?.mediaCount() ?: 0
holder.binding.groupDesc.visibility = if (count == 0) View.GONE else View.VISIBLE
if (count > 0) holder.binding.groupDesc.text = holder.itemView.context.resources.getQuantityString(R.plurals.videos_quantity, count, count)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
if (payloads.isNullOrEmpty()) super.onBindViewHolder(holder, position, payloads)
else {
for (payload in payloads) {
when (payload as? Int) {
UPDATE_SELECTION -> holder.selectView(multiSelectHelper.isSelected(position))
}
}
}
}
override fun onViewRecycled(holder: ViewHolder) {
holder.binding.setVariable(BR.cover, UiTools.getDefaultVideoDrawable(holder.itemView.context))
}
@TargetApi(Build.VERSION_CODES.M)
inner class ViewHolder(binding: VideogroupItemBinding) : SelectorViewHolder<VideogroupItemBinding>(binding) {
init {
binding.holder = this
itemView.setOnLongClickListener {
getItem(layoutPosition)?.let { folder -> actor.offer(VideoGroupLongClick(layoutPosition, folder)) }
true
}
if (AndroidUtil.isMarshMallowOrLater) itemView.setOnContextClickListener {
onCtxClick(itemView)
true
}
}
fun onClick(v: View) {
getItem(layoutPosition)?.let { folder -> actor.offer(VideoGroupClick(layoutPosition, folder)) }
}
fun onCtxClick(v: View) {
getItem(layoutPosition)?.let { folder -> actor.offer(VideoGroupCtxClick(layoutPosition, folder)) }
}
}
}
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<AbstractVideoGroup>() {
override fun areItemsTheSame(oldItem: AbstractVideoGroup, newItem: AbstractVideoGroup) = oldItem == newItem
override fun areContentsTheSame(oldItem: AbstractVideoGroup, newItem: AbstractVideoGroup) = true
}
\ No newline at end of file
package org.videolan.vlc.gui.videogroups
import android.content.Intent
import android.os.Bundle
import android.view.*
import androidx.appcompat.view.ActionMode
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.videogroups_fragment.*
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.actor
import org.videolan.medialibrary.interfaces.media.AbstractVideoGroup
import org.videolan.tools.MultiSelectHelper
import org.videolan.tools.isStarted
import org.videolan.vlc.R
import org.videolan.vlc.databinding.VideogroupsFragmentBinding
import org.videolan.vlc.gui.SecondaryActivity
import org.videolan.vlc.gui.browser.MediaBrowserFragment
import org.videolan.vlc.gui.dialogs.CtxActionReceiver
import org.videolan.vlc.gui.dialogs.showContext
import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.media.PlaylistManager
import org.videolan.vlc.media.getAll
import org.videolan.vlc.reloadLibrary
import org.videolan.vlc.util.*
import org.videolan.vlc.viewmodels.mobile.VideogroupsViewModel
import org.videolan.vlc.viewmodels.mobile.getViewModel
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
class VideoGroupsFragment : MediaBrowserFragment<VideogroupsViewModel>(), CtxActionReceiver {
private lateinit var binding: VideogroupsFragmentBinding
private lateinit var adapter: VideoGroupsAdapter
private val actor = actor<VideoGroupAction> {
for (action in channel) when(action) {
is VideoGroupClick -> {
if (actionMode != null) {
adapter.multiSelectHelper.toggleSelection(action.position)
invalidateActionMode()
} else {
val i = Intent(activity, SecondaryActivity::class.java)
i.putExtra("fragment", SecondaryActivity.VIDEO_GROUP_LIST)
i.putExtra(KEY_GROUP, action.group)
activity?.startActivityForResult(i, SecondaryActivity.ACTIVITY_RESULT_SECONDARY)
}
}
is VideoGroupLongClick -> {
adapter.multiSelectHelper.toggleSelection(action.position, true)
if (actionMode == null) {
startActionMode()
}
}
is VideoGroupCtxClick -> {
showContext(requireActivity(), this@VideoGroupsFragment, action.position, action.group.title, CTX_FOLDER_FLAGS)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
adapter = VideoGroupsAdapter(actor)
viewModel = getViewModel()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = VideogroupsFragmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
groups_list.layoutManager = LinearLayoutManager(view.context, RecyclerView.VERTICAL, false)
groups_list.adapter = adapter
swipeRefreshLayout.setOnRefreshListener { activity?.reloadLibrary() }
viewModel.provider.pagedList.observe(requireActivity(), Observer {
swipeRefreshLayout.isRefreshing = false
adapter.submitList(it)
restoreMultiSelectHelper()
updateEmptyView()
})
val empty = viewModel.isEmpty()
binding.loadingFlipper.visibility = if (empty) View.VISIBLE else View.GONE
binding.loadingTitle.visibility = if (empty) View.VISIBLE else View.GONE
binding.empty = empty
binding.buttonNomedia.setOnClickListener {
val activity = requireActivity()
val intent = Intent(activity.applicationContext, SecondaryActivity::class.java)
intent.putExtra("fragment", SecondaryActivity.STORAGE_BROWSER)
startActivity(intent)
activity.setResult(RESULT_RESTART)
}
}
private fun updateEmptyView() {
val empty = viewModel.isEmpty()
val working = mediaLibrary.isWorking
binding.loadingFlipper.visibility = if (empty && working) View.VISIBLE else View.GONE
binding.loadingTitle.visibility = if (empty && working) View.VISIBLE else View.GONE
binding.empty = empty && !working
}
override fun onStart() {
super.onStart()
setFabPlayVisibility(true)
fabPlay?.setImageResource(R.drawable.ic_fab_play)
}
override fun getTitle() = getString(R.string.video)
override fun getMultiHelper(): MultiSelectHelper<VideogroupsViewModel>? = if (::adapter.isInitialized) adapter.multiSelectHelper as? MultiSelectHelper<VideogroupsViewModel> else null
override fun onRefresh() = viewModel.refresh()
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
menu.findItem(R.id.ml_menu_last_playlist)?.isVisible = true
menu.findItem(R.id.ml_menu_video_group).isVisible = true
}
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean {
if (!isStarted()) return false
val selection = adapter.multiSelectHelper.getSelection()
when (item.itemId) {
R.id.action_folder_play -> viewModel.playSelection(selection)
R.id.action_folder_append -> viewModel.appendSelection(selection)
R.id.action_folder_add_playlist -> launch { UiTools.addToPlaylist(requireActivity(), withContext(Dispatchers.Default) { selection.getAll() }) }
else -> return false
}
stopActionMode()
return true
}
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
mode?.apply { menuInflater.inflate(R.menu.action_mode_folder, menu) }
return true
}
override fun onFabPlayClick(view: View) {
MediaUtils.playAllTracks(context, viewModel.provider, 0, false)
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
val count = adapter.multiSelectHelper.getSelectionCount()
if (count == 0) {
stopActionMode()
return false
}
menu.findItem(R.id.action_video_append)?.isVisible = PlaylistManager.hasMedia()
return true
}
override fun onDestroyActionMode(mode: ActionMode?) {
actionMode = null
adapter.multiSelectHelper.clearSelection()
}
override fun onCtxAction(position: Int, option: Int) {
when (option) {
CTX_PLAY -> viewModel.play(position)
CTX_APPEND -> viewModel.append(position)
CTX_ADD_TO_PLAYLIST -> viewModel.addToPlaylist(requireActivity(), position)
}
}
}
sealed class VideoGroupAction
class VideoGroupClick(val position: Int, val group: AbstractVideoGroup) : VideoGroupAction()
class VideoGroupLongClick(val position: Int, val group: AbstractVideoGroup) : VideoGroupAction()
class VideoGroupCtxClick(val position: Int, val group: AbstractVideoGroup) : VideoGroupAction()
\ No newline at end of file
package org.videolan.vlc.viewmodels.mobile
import android.content.Context
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import kotlinx.coroutines.*
import org.videolan.medialibrary.interfaces.media.AbstractVideoGroup
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.tools.isStarted
import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.gui.videogroups.VideoGroupsFragment
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.media.getAll
import org.videolan.vlc.providers.medialibrary.MedialibraryProvider
import org.videolan.vlc.providers.medialibrary.VideoGroupsProvider
import org.videolan.vlc.viewmodels.MedialibraryViewModel
class VideogroupsViewModel(context: Context) : MedialibraryViewModel(context) {
val provider = VideoGroupsProvider(context, this)
override val providers: Array<MedialibraryProvider<out MediaLibraryItem>> = arrayOf(provider)
fun play(position: Int) = launch {
val list = withContext(Dispatchers.IO) { provider.pagedList.value?.get(position)?.getAll() }
list?.let { MediaUtils.openList(context, it, 0) }
}
fun append(position: Int) = launch {
val list = withContext(Dispatchers.IO) { provider.pagedList.value?.get(position)?.getAll() }
list?.let { MediaUtils.appendMedia(context, it) }
}
fun addToPlaylist(activity: FragmentActivity, selection: List<AbstractVideoGroup>) = launch {
val list = withContext(Dispatchers.Default) { selection.getAll() }
if (activity.isStarted()) UiTools.addToPlaylist(activity, list)
}
fun addToPlaylist(activity: FragmentActivity, position: Int) = launch {
provider.pagedList.value?.get(position)?.let {
val list = withContext(Dispatchers.IO) { it.getAll() }
if (activity.isStarted()) UiTools.addToPlaylist(activity, list)
}
}
fun playSelection(selection: List<AbstractVideoGroup>) = launch {
val list = selection.flatMap { it.getAll() }
MediaUtils.openList(context, list, 0)
}
fun appendSelection(selection: List<AbstractVideoGroup>) = launch {
val list = selection.flatMap { it.getAll() }
MediaUtils.appendMedia(context, list)
}
class Factory(val context: Context): ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return VideogroupsViewModel(context.applicationContext) as T
}
}
}
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
internal fun VideoGroupsFragment.getViewModel() = ViewModelProviders.of(requireActivity(), VideogroupsViewModel.Factory(requireContext())).get(VideogroupsViewModel::class.java)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment