From 1f37db3c63aeb6107b31912d59e503093257c6eb Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 8 Jul 2024 22:36:19 -0600 Subject: [PATCH] Add a deselect all button and move child handling to view model --- .../ui/download/DownloadAdapter.kt | 10 ++-- .../ui/download/DownloadChildFragment.kt | 48 ++++++++----------- .../ui/download/DownloadFragment.kt | 11 +++++ .../ui/download/DownloadViewModel.kt | 47 +++++++++++++++++- .../res/layout/fragment_child_downloads.xml | 10 ++++ .../main/res/layout/fragment_downloads.xml | 10 ++++ app/src/main/res/values/strings.xml | 1 + 7 files changed, 105 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadAdapter.kt index c13f8cd9..81e3476f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadAdapter.kt @@ -315,13 +315,11 @@ class DownloadAdapter( } } - @SuppressLint("NotifyDataSetChanged") fun setIsMultiDeleteState(value: Boolean) { if (isMultiDeleteState == value) return isMultiDeleteState = value if (!value) { - selectedIds.clear() - notifyDataSetChanged() + clearSelectedItems() } else notifyItemRangeChanged(0, itemCount) } @@ -335,6 +333,12 @@ class DownloadAdapter( } } + @SuppressLint("NotifyDataSetChanged") + fun clearSelectedItems() { + selectedIds.clear() + notifyDataSetChanged() + } + private fun toggleIsChecked(checkbox: CheckBox, item: VisualDownloadCached) { val isChecked = !checkbox.isChecked checkbox.isChecked = isChecked diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt index c4657618..f03b32de 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt @@ -60,31 +60,6 @@ class DownloadChildFragment : Fragment() { return localBinding.root } - private fun updateList(folder: String) = main { - context?.let { ctx -> - val data = withContext(Dispatchers.IO) { ctx.getKeys(folder) } - val eps = withContext(Dispatchers.IO) { - data.mapNotNull { key -> - context?.getKey(key) - }.mapNotNull { - val info = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(ctx, it.id) - ?: return@mapNotNull null - VisualDownloadCached.Child( - currentBytes = info.fileLength, - totalBytes = info.totalBytes, - data = it, - ) - } - }.sortedBy { it.data.episode + (it.data.season ?: 0) * 100000 } - if (eps.isEmpty()) { - activity?.onBackPressedDispatcher?.onBackPressed() - return@main - } - - (binding?.downloadChildList?.adapter as? DownloadAdapter)?.submitList(eps) - } - } - private var downloadDeleteEventListener: ((Int) -> Unit)? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -113,6 +88,14 @@ class DownloadChildFragment : Fragment() { setAppBarNoScrollFlagsOnTV() } + observe(downloadsViewModel.childCards) { + if (it.isEmpty()) { + activity?.onBackPressedDispatcher?.onBackPressed() + return@observe + } + + (binding?.downloadChildList?.adapter as? DownloadAdapter)?.submitList(it) + } observe(downloadsViewModel.isMultiDeleteState) { isMultiDeleteState -> val adapter = binding?.downloadChildList?.adapter as? DownloadAdapter adapter?.setIsMultiDeleteState(isMultiDeleteState) @@ -158,7 +141,7 @@ class DownloadChildFragment : Fragment() { ) } - updateList(folder) + downloadsViewModel.updateChildList(requireContext(), folder) } private fun handleSelectedChange(selected: MutableList) { @@ -174,11 +157,22 @@ class DownloadChildFragment : Fragment() { downloadsViewModel.setIsMultiDeleteState(false) } + binding?.btnSelectAll?.isVisible = !downloadsViewModel.isAllSelected() + binding?.btnDeselectAll?.isVisible = downloadsViewModel.isAllSelected() + binding?.btnSelectAll?.setOnClickListener { (binding?.downloadChildList?.adapter as? DownloadAdapter)?.selectAllItems() downloadsViewModel.selectAllItems() } + binding?.btnDeselectAll?.setOnClickListener { + (binding?.downloadChildList?.adapter as? DownloadAdapter)?.clearSelectedItems() + downloadsViewModel.clearSelectedItems() + + binding?.btnSelectAll?.isVisible = true + binding?.btnDeselectAll?.isVisible = false + } + downloadsViewModel.setIsMultiDeleteState(true) } } @@ -187,7 +181,7 @@ class DownloadChildFragment : Fragment() { downloadDeleteEventListener = { id: Int -> val list = (binding?.downloadChildList?.adapter as? DownloadAdapter)?.currentList if (list?.any { it.data.id == id } == true) { - updateList(folder) + context?.let { downloadsViewModel.updateChildList(it, folder) } } } downloadDeleteEventListener?.let { VideoDownloadManager.downloadDeleteEvent += it } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt index 246549fc..3ab3721f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt @@ -213,11 +213,22 @@ class DownloadFragment : Fragment() { downloadsViewModel.setIsMultiDeleteState(false) } + binding?.btnSelectAll?.isVisible = !downloadsViewModel.isAllSelected() + binding?.btnDeselectAll?.isVisible = downloadsViewModel.isAllSelected() + binding?.btnSelectAll?.setOnClickListener { (binding?.downloadList?.adapter as? DownloadAdapter)?.selectAllItems() downloadsViewModel.selectAllItems() } + binding?.btnDeselectAll?.setOnClickListener { + (binding?.downloadList?.adapter as? DownloadAdapter)?.clearSelectedItems() + downloadsViewModel.clearSelectedItems() + + binding?.btnSelectAll?.isVisible = true + binding?.btnDeselectAll?.isVisible = false + } + downloadsViewModel.setIsMultiDeleteState(true) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt index 1cab548f..429ce903 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt @@ -31,6 +31,10 @@ class DownloadViewModel : ViewModel() { MutableLiveData>().apply { listOf() } val headerCards: LiveData> = _headerCards + private val _childCards = + MutableLiveData>().apply { listOf() } + val childCards: LiveData> = _childCards + private val _usedBytes = MutableLiveData() val usedBytes: LiveData = _usedBytes @@ -46,7 +50,7 @@ class DownloadViewModel : ViewModel() { private val _selectedItems = MutableLiveData>(mutableListOf()) val selectedItems: LiveData> = _selectedItems - private var previousVisual: List? = null + private var previousVisual: List? = null fun setIsMultiDeleteState(value: Boolean) { _isMultiDeleteState.postValue(value) @@ -69,7 +73,8 @@ class DownloadViewModel : ViewModel() { fun selectAllItems() { val currentSelected = selectedItems.value ?: mutableListOf() - val items = headerCards.value ?: return + val items = (headerCards.value ?: emptyList()) + (childCards.value ?: emptyList()) + if(items.isEmpty()) return items.forEach { item -> if (!currentSelected.contains(item)) { currentSelected.add(item) @@ -82,6 +87,22 @@ class DownloadViewModel : ViewModel() { _selectedItems.postValue(mutableListOf()) } + fun isAllSelected(): Boolean { + val currentSelected = selectedItems.value ?: return false + val headerItems = headerCards.value + val childItems = childCards.value + + val isAllHeadersSelected = headerItems != null && + headerItems.count() == currentSelected.count() && + headerItems.containsAll(currentSelected) + + val isAllChildrenSelected = childItems != null && + childItems.count() == currentSelected.count() && + childItems.containsAll(currentSelected) + + return isAllHeadersSelected || isAllChildrenSelected + } + fun updateList(context: Context) = viewModelScope.launchSafe { val children = withContext(Dispatchers.IO) { context.getKeys(DOWNLOAD_EPISODE_CACHE) @@ -153,6 +174,28 @@ class DownloadViewModel : ViewModel() { } } + fun updateChildList(context: Context, folder: String) = viewModelScope.launchSafe { + val data = withContext(Dispatchers.IO) { context.getKeys(folder) } + val visual = withContext(Dispatchers.IO) { + data.mapNotNull { key -> + context.getKey(key) + }.mapNotNull { + val info = getDownloadFileInfoAndUpdateSettings(context, it.id) + ?: return@mapNotNull null + VisualDownloadCached.Child( + currentBytes = info.fileLength, + totalBytes = info.totalBytes, + data = it, + ) + } + }.sortedBy { it.data.episode + (it.data.season ?: 0) * 100000 } + + if (previousVisual != visual) { + previousVisual = visual + _childCards.postValue(visual) + } + } + private fun updateStorageStats(visual: List) { try { val stat = StatFs(Environment.getExternalStorageDirectory().path) diff --git a/app/src/main/res/layout/fragment_child_downloads.xml b/app/src/main/res/layout/fragment_child_downloads.xml index f97744b6..228d5127 100644 --- a/app/src/main/res/layout/fragment_child_downloads.xml +++ b/app/src/main/res/layout/fragment_child_downloads.xml @@ -70,6 +70,16 @@ android:text="@string/select_all" android:textColor="@android:color/white" android:layout_marginEnd="8dp" /> + +