added context app bar for cancelled and errored downloads
This commit is contained in:
parent
a6a4754bb2
commit
d24b56835f
16 changed files with 384 additions and 51 deletions
|
|
@ -1,5 +1,6 @@
|
|||
package com.deniscerri.ytdlnis.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
|
@ -15,24 +16,29 @@ import androidx.recyclerview.widget.ListAdapter
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.squareup.picasso.Picasso
|
||||
import java.util.ArrayList
|
||||
|
||||
class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<DownloadItem?, GenericDownloadAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||
private val onItemClickListener: OnItemClickListener
|
||||
private val activity: Activity
|
||||
private var fileUtil: FileUtil
|
||||
private val checkedItems: ArrayList<Long>
|
||||
|
||||
init {
|
||||
checkedItems = ArrayList()
|
||||
this.onItemClickListener = onItemClickListener
|
||||
this.activity = activity
|
||||
fileUtil = FileUtil()
|
||||
}
|
||||
|
||||
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
|
||||
val cardView: FrameLayout
|
||||
val cardView: MaterialCardView
|
||||
init {
|
||||
cardView = itemView.findViewById(R.id.download_card_view)
|
||||
}
|
||||
|
|
@ -116,15 +122,75 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
|
|||
actionButton.setOnClickListener {
|
||||
onItemClickListener.onActionButtonClick(item.id)
|
||||
}
|
||||
|
||||
if (checkedItems.contains(item.id)) {
|
||||
card.isChecked = true
|
||||
card.strokeWidth = 5
|
||||
} else {
|
||||
card.isChecked = false
|
||||
card.strokeWidth = 0
|
||||
}
|
||||
card.setOnClickListener {
|
||||
onItemClickListener.onCardClick(item.id)
|
||||
if (checkedItems.size > 0) {
|
||||
checkCard(card, item.id)
|
||||
} else {
|
||||
onItemClickListener.onCardClick(item.id)
|
||||
}
|
||||
}
|
||||
|
||||
card.setOnLongClickListener {
|
||||
checkCard(card, item.id)
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun clearCheckeditems() {
|
||||
for (i in 0 until itemCount){
|
||||
val item = getItem(i)
|
||||
if (checkedItems.find { it == item?.id } != null){
|
||||
checkedItems.remove(item?.id)
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
}
|
||||
|
||||
checkedItems.clear()
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun checkAll(items: List<DownloadItem?>?){
|
||||
checkedItems.clear()
|
||||
checkedItems.addAll(items!!.map { it!!.id })
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun invertSelected(items: List<DownloadItem?>?){
|
||||
val invertedList = mutableListOf<Long>()
|
||||
items?.forEach {
|
||||
if (!checkedItems.contains(it!!.id)) invertedList.add(it.id)
|
||||
}
|
||||
checkedItems.clear()
|
||||
checkedItems.addAll(invertedList)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun checkCard(card: MaterialCardView, itemID: Long) {
|
||||
if (card.isChecked) {
|
||||
card.strokeWidth = 0
|
||||
checkedItems.remove(itemID)
|
||||
} else {
|
||||
card.strokeWidth = 5
|
||||
checkedItems.add(itemID)
|
||||
}
|
||||
card.isChecked = !card.isChecked
|
||||
onItemClickListener.onCardSelect(itemID, card.isChecked)
|
||||
}
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onActionButtonClick(itemID: Long)
|
||||
fun onCardClick(itemID: Long)
|
||||
fun onCardSelect(itemID: Long, isChecked: Boolean)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
|||
}
|
||||
|
||||
suspend fun parseQuery(inputQuery: String, resetResults: Boolean) : ArrayList<ResultItem?> {
|
||||
if (resetResults) loadingItems.postValue(true)
|
||||
if (resetResults)
|
||||
loadingItems.postValue(true)
|
||||
val type = getQueryType(inputQuery)
|
||||
var res = arrayListOf<ResultItem?>()
|
||||
return withContext(Dispatchers.IO){
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ class CancelDownloadNotificationReceiver : BroadcastReceiver() {
|
|||
val notificationUtil = NotificationUtil(c)
|
||||
|
||||
YoutubeDL.getInstance().destroyProcessById(id.toString())
|
||||
WorkManager.getInstance(c).cancelUniqueWork(id.toString())
|
||||
notificationUtil.cancelDownloadNotification(id)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,6 +191,13 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
downloadAllFab.tag = "downloadAll"
|
||||
downloadAllFab.setOnClickListener(this)
|
||||
|
||||
if (arguments?.getString("url") != null){
|
||||
val url = requireArguments().getString("url")
|
||||
if (inputQueries == null) inputQueries = mutableListOf()
|
||||
searchBar?.text = url
|
||||
inputQueries!!.add(url!!)
|
||||
}
|
||||
|
||||
if (inputQueries != null) {
|
||||
resultViewModel.deleteAll()
|
||||
lifecycleScope.launch(Dispatchers.IO){
|
||||
|
|
@ -470,7 +477,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
}
|
||||
}else{
|
||||
resultViewModel.parseQueries(queryList)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -654,6 +660,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
super.onStop()
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private const val TAG = "HomeFragment"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import android.widget.LinearLayout
|
|||
import android.widget.Toast
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.deniscerri.ytdlnis.R
|
||||
|
|
@ -195,19 +196,23 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
|
|||
if (quickDownload) {
|
||||
(updateItem.parent as LinearLayout).visibility = View.VISIBLE
|
||||
updateItem.setOnClickListener {
|
||||
lifecycleScope.launch(Dispatchers.IO){
|
||||
if (activity is ShareActivity) {
|
||||
val intent = Intent(context, ShareActivity::class.java)
|
||||
intent.action = Intent.ACTION_SEND
|
||||
intent.type = "text/plain"
|
||||
intent.putExtra(Intent.EXTRA_TEXT, resultItem.url)
|
||||
intent.putExtra("quick_download", false)
|
||||
startActivity(intent)
|
||||
dismiss()
|
||||
}else{
|
||||
resultViewModel.parseQueries(listOf(resultItem.url))
|
||||
dismiss()
|
||||
}
|
||||
if (activity is ShareActivity) {
|
||||
val intent = Intent(context, ShareActivity::class.java)
|
||||
intent.action = Intent.ACTION_SEND
|
||||
intent.type = "text/plain"
|
||||
intent.putExtra(Intent.EXTRA_TEXT, resultItem.url)
|
||||
intent.putExtra("quick_download", false)
|
||||
startActivity(intent)
|
||||
dismiss()
|
||||
}else{
|
||||
dismiss()
|
||||
val bundle = Bundle()
|
||||
bundle.putString("url", resultItem.url)
|
||||
findNavController().popBackStack(R.id.homeFragment, true)
|
||||
findNavController().navigate(
|
||||
R.id.homeFragment,
|
||||
bundle
|
||||
)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
|
|
|||
|
|
@ -126,16 +126,16 @@ class ActiveDownloadsFragment() : Fragment(), ActiveDownloadAdapter.OnItemClickL
|
|||
}
|
||||
|
||||
private fun cancelDownload(itemID: Long){
|
||||
val id = itemID.toInt()
|
||||
YoutubeDL.getInstance().destroyProcessById(id.toString())
|
||||
WorkManager.getInstance(requireContext()).cancelUniqueWork(id.toString())
|
||||
notificationUtil.cancelDownloadNotification(id)
|
||||
|
||||
list.find { it.id == itemID }?.let {
|
||||
it.status = DownloadRepository.Status.Cancelled.toString()
|
||||
downloadViewModel.updateDownload(it)
|
||||
}
|
||||
|
||||
|
||||
val id = itemID.toInt()
|
||||
YoutubeDL.getInstance().destroyProcessById(id.toString())
|
||||
WorkManager.getInstance(requireContext()).cancelUniqueWork(id.toString())
|
||||
notificationUtil.cancelDownloadNotification(id)
|
||||
}
|
||||
|
||||
override fun onClick(p0: View?) {
|
||||
|
|
|
|||
|
|
@ -7,22 +7,25 @@ import android.graphics.Canvas
|
|||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.view.*
|
||||
import android.widget.Button
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.forEach
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.GenericDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog
|
||||
|
|
@ -35,7 +38,11 @@ import com.google.android.material.color.MaterialColors
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import it.xabaras.android.recyclerview.swipedecorator.RecyclerViewSwipeDecorator
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.ArrayList
|
||||
|
||||
|
||||
class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener {
|
||||
|
|
@ -45,6 +52,8 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
|
|||
private lateinit var downloadViewModel : DownloadViewModel
|
||||
private lateinit var cancelledRecyclerView : RecyclerView
|
||||
private lateinit var cancelledDownloads : GenericDownloadAdapter
|
||||
private var selectedObjects: ArrayList<DownloadItem>? = null
|
||||
private var actionMode : ActionMode? = null
|
||||
private lateinit var items : MutableList<DownloadItem>
|
||||
private lateinit var fileUtil: FileUtil
|
||||
private lateinit var uiUtil : UiUtil
|
||||
|
|
@ -57,6 +66,7 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
|
|||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
||||
activity = getActivity()
|
||||
selectedObjects = arrayListOf()
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
items = mutableListOf()
|
||||
fileUtil = FileUtil()
|
||||
|
|
@ -213,6 +223,26 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
|
|||
)
|
||||
}
|
||||
|
||||
override fun onCardSelect(itemID: Long, isChecked: Boolean) {
|
||||
val item = items.find { it.id == itemID }
|
||||
if (isChecked) {
|
||||
selectedObjects!!.add(item!!)
|
||||
if (actionMode == null){
|
||||
actionMode = (getActivity() as AppCompatActivity?)!!.startSupportActionMode(contextualActionBar)
|
||||
|
||||
}else{
|
||||
actionMode!!.title = "${selectedObjects!!.size} ${getString(R.string.selected)}"
|
||||
}
|
||||
}
|
||||
else {
|
||||
selectedObjects!!.remove(item)
|
||||
actionMode?.title = "${selectedObjects!!.size} ${getString(R.string.selected)}"
|
||||
if (selectedObjects!!.isEmpty()){
|
||||
actionMode?.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun removeItem(item: DownloadItem, bottomSheet: BottomSheetDialog?){
|
||||
bottomSheet?.hide()
|
||||
|
|
@ -225,6 +255,80 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
|
|||
deleteDialog.show()
|
||||
}
|
||||
|
||||
|
||||
private val contextualActionBar = object : ActionMode.Callback {
|
||||
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
|
||||
mode!!.menuInflater.inflate(R.menu.cancelled_downloads_menu_context, menu)
|
||||
mode.title = "${selectedObjects!!.size} ${getString(R.string.selected)}"
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(
|
||||
mode: ActionMode?,
|
||||
menu: Menu?
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onActionItemClicked(
|
||||
mode: ActionMode?,
|
||||
item: MenuItem?
|
||||
): Boolean {
|
||||
return when (item!!.itemId) {
|
||||
R.id.delete_results -> {
|
||||
val deleteDialog = MaterialAlertDialogBuilder(requireContext())
|
||||
deleteDialog.setTitle(getString(R.string.you_are_going_to_delete_multiple_items))
|
||||
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||
for (obj in selectedObjects!!){
|
||||
downloadViewModel.deleteDownload(obj)
|
||||
}
|
||||
clearCheckedItems()
|
||||
actionMode?.finish()
|
||||
}
|
||||
deleteDialog.show()
|
||||
true
|
||||
}
|
||||
R.id.redownload -> {
|
||||
runBlocking {
|
||||
downloadViewModel.queueDownloads(selectedObjects!!.toMutableList())
|
||||
actionMode?.finish()
|
||||
}
|
||||
true
|
||||
}
|
||||
R.id.select_all -> {
|
||||
cancelledDownloads.checkAll(items)
|
||||
selectedObjects?.clear()
|
||||
items.forEach { selectedObjects?.add(it) }
|
||||
mode?.title = getString(R.string.all_items_selected)
|
||||
true
|
||||
}
|
||||
R.id.invert_selected -> {
|
||||
cancelledDownloads.invertSelected(items)
|
||||
val invertedList = arrayListOf<DownloadItem>()
|
||||
items.forEach {
|
||||
if (!selectedObjects?.contains(it)!!) invertedList.add(it)
|
||||
}
|
||||
selectedObjects?.clear()
|
||||
selectedObjects?.addAll(invertedList)
|
||||
actionMode!!.title = "${selectedObjects!!.size} ${getString(R.string.selected)}"
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
actionMode = null
|
||||
clearCheckedItems()
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearCheckedItems(){
|
||||
cancelledDownloads.clearCheckeditems()
|
||||
selectedObjects?.clear()
|
||||
}
|
||||
|
||||
private var simpleCallback: ItemTouchHelper.SimpleCallback =
|
||||
object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
|
||||
override fun onMove(recyclerView: RecyclerView,viewHolder: RecyclerView.ViewHolder,target: RecyclerView.ViewHolder
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@ import android.graphics.Canvas
|
|||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.view.*
|
||||
import android.widget.AdapterView
|
||||
import android.widget.AdapterView.OnItemClickListener
|
||||
import android.widget.Button
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
|
@ -40,6 +39,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|||
import com.google.android.material.snackbar.Snackbar
|
||||
import it.xabaras.android.recyclerview.swipedecorator.RecyclerViewSwipeDecorator
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.util.ArrayList
|
||||
|
||||
|
||||
class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener, OnItemClickListener {
|
||||
|
|
@ -50,6 +50,8 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
|
|||
private lateinit var erroredRecyclerView : RecyclerView
|
||||
private lateinit var erroredDownloads : GenericDownloadAdapter
|
||||
private lateinit var items : MutableList<DownloadItem>
|
||||
private var selectedObjects: ArrayList<DownloadItem>? = null
|
||||
private var actionMode : ActionMode? = null
|
||||
private lateinit var fileUtil: FileUtil
|
||||
private lateinit var uiUtil : UiUtil
|
||||
override fun onCreateView(
|
||||
|
|
@ -62,6 +64,7 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
|
|||
activity = getActivity()
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
items = mutableListOf()
|
||||
selectedObjects = arrayListOf()
|
||||
fileUtil = FileUtil()
|
||||
uiUtil = UiUtil(fileUtil)
|
||||
return fragmentView
|
||||
|
|
@ -213,6 +216,26 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
|
|||
)
|
||||
}
|
||||
|
||||
override fun onCardSelect(itemID: Long, isChecked: Boolean) {
|
||||
val item = items.find { it.id == itemID }
|
||||
if (isChecked) {
|
||||
selectedObjects!!.add(item!!)
|
||||
if (actionMode == null){
|
||||
actionMode = (getActivity() as AppCompatActivity?)!!.startSupportActionMode(contextualActionBar)
|
||||
|
||||
}else{
|
||||
actionMode!!.title = "${selectedObjects!!.size} ${getString(R.string.selected)}"
|
||||
}
|
||||
}
|
||||
else {
|
||||
selectedObjects!!.remove(item)
|
||||
actionMode?.title = "${selectedObjects!!.size} ${getString(R.string.selected)}"
|
||||
if (selectedObjects!!.isEmpty()){
|
||||
actionMode?.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeItem(item: DownloadItem, bottomSheet: BottomSheetDialog?){
|
||||
bottomSheet?.hide()
|
||||
val deleteDialog = MaterialAlertDialogBuilder(requireContext())
|
||||
|
|
@ -228,6 +251,81 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
|
|||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
|
||||
|
||||
private val contextualActionBar = object : ActionMode.Callback {
|
||||
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
|
||||
mode!!.menuInflater.inflate(R.menu.cancelled_downloads_menu_context, menu)
|
||||
mode.title = "${selectedObjects!!.size} ${getString(R.string.selected)}"
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(
|
||||
mode: ActionMode?,
|
||||
menu: Menu?
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onActionItemClicked(
|
||||
mode: ActionMode?,
|
||||
item: MenuItem?
|
||||
): Boolean {
|
||||
return when (item!!.itemId) {
|
||||
R.id.delete_results -> {
|
||||
val deleteDialog = MaterialAlertDialogBuilder(requireContext())
|
||||
deleteDialog.setTitle(getString(R.string.you_are_going_to_delete_multiple_items))
|
||||
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||
for (obj in selectedObjects!!){
|
||||
downloadViewModel.deleteDownload(obj)
|
||||
}
|
||||
clearCheckedItems()
|
||||
actionMode?.finish()
|
||||
}
|
||||
deleteDialog.show()
|
||||
true
|
||||
}
|
||||
R.id.redownload -> {
|
||||
runBlocking {
|
||||
downloadViewModel.queueDownloads(selectedObjects!!.toMutableList())
|
||||
actionMode?.finish()
|
||||
}
|
||||
true
|
||||
}
|
||||
R.id.select_all -> {
|
||||
erroredDownloads.checkAll(items)
|
||||
selectedObjects?.clear()
|
||||
items.forEach { selectedObjects?.add(it) }
|
||||
mode?.title = getString(R.string.all_items_selected)
|
||||
true
|
||||
}
|
||||
R.id.invert_selected -> {
|
||||
erroredDownloads.invertSelected(items)
|
||||
val invertedList = arrayListOf<DownloadItem>()
|
||||
items.forEach {
|
||||
if (!selectedObjects?.contains(it)!!) invertedList.add(it)
|
||||
}
|
||||
selectedObjects?.clear()
|
||||
selectedObjects?.addAll(invertedList)
|
||||
actionMode!!.title = "${selectedObjects!!.size} ${getString(R.string.selected)}"
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
actionMode = null
|
||||
clearCheckedItems()
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearCheckedItems(){
|
||||
erroredDownloads.clearCheckeditems()
|
||||
selectedObjects?.clear()
|
||||
}
|
||||
|
||||
private var simpleCallback: ItemTouchHelper.SimpleCallback =
|
||||
object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
|
||||
override fun onMove(recyclerView: RecyclerView,viewHolder: RecyclerView.ViewHolder,target: RecyclerView.ViewHolder
|
||||
|
|
|
|||
|
|
@ -241,6 +241,10 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
|
|||
)
|
||||
}
|
||||
|
||||
override fun onCardSelect(itemID: Long, isChecked: Boolean) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun removeItem(itemID: Long){
|
||||
val item = items.find { it.id == itemID }
|
||||
val deleteDialog = MaterialAlertDialogBuilder(requireContext())
|
||||
|
|
|
|||
|
|
@ -613,8 +613,10 @@ class InfoUtil(private val context: Context) {
|
|||
author = jsonObject.getString("uploader")
|
||||
}
|
||||
var duration = ""
|
||||
if (jsonObject.has("duration")) {
|
||||
duration = formatIntegerDuration(jsonObject.getInt("duration"), Locale.getDefault())
|
||||
runCatching {
|
||||
if (jsonObject.has("duration")) {
|
||||
duration = formatIntegerDuration(jsonObject.getInt("duration"), Locale.getDefault())
|
||||
}
|
||||
}
|
||||
val url = jsonObject.getString("webpage_url")
|
||||
var thumb: String? = ""
|
||||
|
|
|
|||
|
|
@ -388,6 +388,12 @@ class DownloadWorker(
|
|||
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
override fun onStopped() {
|
||||
YoutubeDL.getInstance().destroyProcessById(itemId.toInt().toString())
|
||||
super.onStopped()
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun moveFile(originDir: File, downLocation: String, progress: (progress: Int) -> Unit) : String{
|
||||
val fileUtil = FileUtil()
|
||||
|
|
|
|||
|
|
@ -131,6 +131,11 @@ class TerminalDownloadWorker(
|
|||
return Result.success()
|
||||
|
||||
}
|
||||
override fun onStopped() {
|
||||
YoutubeDL.getInstance().destroyProcessById(DownloadWorker.itemId.toInt().toString())
|
||||
super.onStopped()
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun moveFile(originDir: File, downLocation: String, progress: (progress: Int) -> Unit) : String{
|
||||
val fileUtil = FileUtil()
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<FrameLayout
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/download_card_view"
|
||||
android:layout_width="0dp"
|
||||
app:shapeAppearance="@style/ShapeAppearanceOverlay.Avatar"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:paddingVertical="10dp"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:checkable="true"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
|
|
@ -193,6 +193,6 @@
|
|||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</FrameLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
<LinearLayout android:layout_width="match_parent"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="horizontal"
|
||||
|
|
@ -6,28 +7,33 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/materialButton"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
app:iconSize="50dp"
|
||||
android:padding="0dp"
|
||||
app:iconTint="@null"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:insetBottom="0dp"
|
||||
android:insetLeft="0dp"
|
||||
android:insetTop="0dp"
|
||||
android:insetRight="0dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:icon="@drawable/ic_app_icon" />
|
||||
android:insetBottom="0dp"
|
||||
android:padding="0dp"
|
||||
app:icon="@drawable/ic_app_icon"
|
||||
app:iconSize="50dp"
|
||||
app:iconTint="@null"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="?attr/textAppearanceHeadlineSmall"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:text="@string/app_name" />
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/materialButton"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
29
app/src/main/res/menu/cancelled_downloads_menu_context.xml
Normal file
29
app/src/main/res/menu/cancelled_downloads_menu_context.xml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<menu 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"
|
||||
tools:context=".MainActivity" >
|
||||
|
||||
<item
|
||||
android:id="@+id/delete_results"
|
||||
android:title="@string/remove_results"
|
||||
android:icon="@drawable/baseline_delete_24"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/redownload"
|
||||
android:title="@string/redownload"
|
||||
android:icon="@drawable/ic_refresh"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/select_all"
|
||||
android:title="@string/select_all"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/invert_selected"
|
||||
android:title="@string/invert_selected"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
||||
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<external-path name="external_files" path="."/>
|
||||
<root-path name="external_files" path="/storage/" />
|
||||
<cache-path
|
||||
name="cache"
|
||||
path="." />
|
||||
|
|
|
|||
Loading…
Reference in a new issue