feat: added sorting method in downloads (#6194)

Co-authored-by: Bnyro <bnyro@tutanota.com>
This commit is contained in:
Amandeep Singh 2024-07-14 17:01:36 +05:30 committed by GitHub
parent 6383ee1bee
commit 483e49b2cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 79 additions and 13 deletions

View File

@ -140,4 +140,5 @@ object PreferenceKeys {
const val AUTH_PREF_FILE = "auth" const val AUTH_PREF_FILE = "auth"
const val IMAGE_PROXY_URL = "image_proxy_url" const val IMAGE_PROXY_URL = "image_proxy_url"
const val SELECTED_CHANNEL_GROUP = "selected_channel_group" const val SELECTED_CHANNEL_GROUP = "selected_channel_group"
const val SELECTED_DOWNLOAD_SORT_TYPE = "selected_download_sort_type"
} }

View File

@ -19,6 +19,7 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.FragmentDownloadsBinding import com.github.libretube.databinding.FragmentDownloadsBinding
import com.github.libretube.db.DatabaseHolder.Database import com.github.libretube.db.DatabaseHolder.Database
import com.github.libretube.db.obj.DownloadWithItems import com.github.libretube.db.obj.DownloadWithItems
@ -26,11 +27,13 @@ import com.github.libretube.extensions.ceilHalf
import com.github.libretube.extensions.formatAsFileSize import com.github.libretube.extensions.formatAsFileSize
import com.github.libretube.helpers.BackgroundHelper import com.github.libretube.helpers.BackgroundHelper
import com.github.libretube.helpers.DownloadHelper import com.github.libretube.helpers.DownloadHelper
import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.obj.DownloadStatus import com.github.libretube.obj.DownloadStatus
import com.github.libretube.receivers.DownloadReceiver import com.github.libretube.receivers.DownloadReceiver
import com.github.libretube.services.DownloadService import com.github.libretube.services.DownloadService
import com.github.libretube.ui.adapters.DownloadsAdapter import com.github.libretube.ui.adapters.DownloadsAdapter
import com.github.libretube.ui.base.DynamicLayoutManagerFragment import com.github.libretube.ui.base.DynamicLayoutManagerFragment
import com.github.libretube.ui.sheets.BaseBottomSheet
import com.github.libretube.ui.viewholders.DownloadsViewHolder import com.github.libretube.ui.viewholders.DownloadsViewHolder
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -43,7 +46,7 @@ import kotlin.io.path.fileSize
class DownloadsFragment : DynamicLayoutManagerFragment() { class DownloadsFragment : DynamicLayoutManagerFragment() {
private var _binding: FragmentDownloadsBinding? = null private var _binding: FragmentDownloadsBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private lateinit var adapter: DownloadsAdapter
private var binder: DownloadService.LocalBinder? = null private var binder: DownloadService.LocalBinder? = null
private val downloads = mutableListOf<DownloadWithItems>() private val downloads = mutableListOf<DownloadWithItems>()
private val downloadReceiver = DownloadReceiver() private val downloadReceiver = DownloadReceiver()
@ -85,6 +88,23 @@ class DownloadsFragment : DynamicLayoutManagerFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
binding.deleteAll.isInvisible = true binding.deleteAll.isInvisible = true
var selectedSortType =
PreferenceHelper.getInt(PreferenceKeys.SELECTED_DOWNLOAD_SORT_TYPE, 0)
val filterOptions = resources.getStringArray(R.array.downloadSortOptions)
binding.sortType.text = filterOptions[selectedSortType]
binding.sortType.setOnClickListener {
BaseBottomSheet().setSimpleItems(filterOptions.toList()) { index ->
binding.sortType.text = filterOptions[index]
if (::adapter.isInitialized) {
sortDownloadList(index, selectedSortType)
}
selectedSortType = index
PreferenceHelper.putInt(
PreferenceKeys.SELECTED_DOWNLOAD_SORT_TYPE,
index
)
}.show(childFragmentManager)
}
val dbDownloads = runBlocking(Dispatchers.IO) { val dbDownloads = runBlocking(Dispatchers.IO) {
Database.downloadDao().getAll() Database.downloadDao().getAll()
@ -92,10 +112,9 @@ class DownloadsFragment : DynamicLayoutManagerFragment() {
downloads.clear() downloads.clear()
downloads.addAll(dbDownloads) downloads.addAll(dbDownloads)
binding.downloadsEmpty.isGone = true binding.downloadsEmpty.isGone = true
binding.downloads.isVisible = true binding.downloads.isVisible = true
val adapter = DownloadsAdapter(requireContext(), downloads) { adapter = DownloadsAdapter(requireContext(), downloads) {
var isDownloading = false var isDownloading = false
val ids = it.downloadItems val ids = it.downloadItems
.filter { item -> item.path.fileSize() < item.downloadSize } .filter { item -> item.path.fileSize() < item.downloadSize }
@ -120,7 +139,7 @@ class DownloadsFragment : DynamicLayoutManagerFragment() {
} }
return@DownloadsAdapter isDownloading.not() return@DownloadsAdapter isDownloading.not()
} }
sortDownloadList(selectedSortType)
binding.downloads.adapter = adapter binding.downloads.adapter = adapter
val itemTouchCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) { val itemTouchCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
@ -168,6 +187,17 @@ class DownloadsFragment : DynamicLayoutManagerFragment() {
} }
} }
private fun sortDownloadList(sortType: Int, previousSortType: Int? = null) {
if (previousSortType == null && sortType == 1) {
downloads.reverse()
adapter.notifyDataSetChanged()
}
if (previousSortType != null && sortType != previousSortType) {
downloads.reverse()
adapter.notifyDataSetChanged()
}
}
private fun showDeleteAllDialog(context: Context, adapter: DownloadsAdapter) { private fun showDeleteAllDialog(context: Context, adapter: DownloadsAdapter) {
MaterialAlertDialogBuilder(context) MaterialAlertDialogBuilder(context)
.setTitle(R.string.delete_all) .setTitle(R.string.delete_all)
@ -237,7 +267,7 @@ class DownloadsFragment : DynamicLayoutManagerFragment() {
if (progressBar.isIndeterminate) return if (progressBar.isIndeterminate) return
progressBar.incrementProgressBy(status.progress.toInt()) progressBar.incrementProgressBy(status.progress.toInt())
val progressInfo = progressBar.progress.formatAsFileSize() + val progressInfo = progressBar.progress.formatAsFileSize() +
" /\n" + progressBar.max.formatAsFileSize() " /\n" + progressBar.max.formatAsFileSize()
fileSize.text = progressInfo fileSize.text = progressInfo
} }

View File

@ -1,16 +1,38 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?android:attr/colorBackground"> android:background="?android:attr/colorBackground">
<TextView
android:id="@+id/sort_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:paddingVertical="5dp"
android:focusable="true"
android:fontFamily="@font/roboto"
android:text="@string/sort_by"
android:clickable="true"
android:textSize="15sp"
android:textStyle="bold"
android:drawablePadding="10dp"
app:drawableEndCompat="@drawable/ic_sort"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<LinearLayout <LinearLayout
android:id="@+id/downloads_empty" android:id="@+id/downloads_empty"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:orientation="vertical"> android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView <ImageView
android:layout_width="100dp" android:layout_width="100dp"
@ -31,19 +53,25 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/downloads" android:id="@+id/downloads"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:visibility="gone" /> android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sort_type" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/delete_all" android:id="@+id/delete_all"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_marginBottom="80dp"
android:layout_marginEnd="18dp" android:layout_marginEnd="18dp"
android:layout_marginBottom="80dp"
android:contentDescription="@string/shuffle" android:contentDescription="@string/shuffle"
android:src="@drawable/ic_delete" android:src="@drawable/ic_delete"
android:tooltipText="@string/delete" android:tooltipText="@string/delete"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:targetApi="o" /> tools:targetApi="o" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
@ -51,10 +79,12 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_margin="16dp" android:layout_margin="18dp"
android:contentDescription="@string/shuffle" android:contentDescription="@string/shuffle"
android:src="@drawable/ic_shuffle" android:src="@drawable/ic_shuffle"
android:tooltipText="@string/shuffle" android:tooltipText="@string/shuffle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:targetApi="o" /> tools:targetApi="o" />
</FrameLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -312,6 +312,11 @@
<item>@string/alphabetic_reversed</item> <item>@string/alphabetic_reversed</item>
</string-array> </string-array>
<string-array name="downloadSortOptions">
<item>@string/least_recent</item>
<item>@string/most_recent</item>
</string-array>
<string-array name="filterOptions"> <string-array name="filterOptions">
<item>@string/all</item> <item>@string/all</item>
<item>@string/videos</item> <item>@string/videos</item>