mirror of https://github.com/deniscerri/ytdlnis
implemented work calls after processing downloads
parent
5e47c98ec5
commit
544a8eab14
@ -0,0 +1,195 @@
|
||||
package com.deniscerri.ytdlnis.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorMatrix
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.squareup.picasso.Picasso
|
||||
import java.io.File
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<HistoryItem?, ActiveDownloadAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||
private val checkedItems: ArrayList<Long>
|
||||
private val onItemClickListener: OnItemClickListener
|
||||
private val activity: Activity
|
||||
|
||||
init {
|
||||
checkedItems = ArrayList()
|
||||
this.onItemClickListener = onItemClickListener
|
||||
this.activity = activity
|
||||
}
|
||||
|
||||
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
|
||||
val cardView: MaterialCardView
|
||||
|
||||
init {
|
||||
cardView = itemView.findViewById(R.id.downloads_card_view)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val cardView = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.history_card, parent, false)
|
||||
return ViewHolder(cardView, onItemClickListener)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
val card = holder.cardView
|
||||
// THUMBNAIL ----------------------------------
|
||||
val thumbnail = card.findViewById<ImageView>(R.id.downloads_image_view)
|
||||
val imageURL = item!!.thumb
|
||||
val uiHandler = Handler(Looper.getMainLooper())
|
||||
if (imageURL.isNotEmpty()) {
|
||||
uiHandler.post { Picasso.get().load(imageURL).into(thumbnail) }
|
||||
} else {
|
||||
uiHandler.post { Picasso.get().load(R.color.black).into(thumbnail) }
|
||||
}
|
||||
thumbnail.setColorFilter(Color.argb(95, 0, 0, 0))
|
||||
|
||||
// TITLE ----------------------------------
|
||||
val itemTitle = card.findViewById<TextView>(R.id.downloads_title)
|
||||
var title = item.title
|
||||
if (title.length > 100) {
|
||||
title = title.substring(0, 40) + "..."
|
||||
}
|
||||
itemTitle.text = title
|
||||
|
||||
// Bottom Info ----------------------------------
|
||||
val bottomInfo = card.findViewById<TextView>(R.id.downloads_info_bottom)
|
||||
var info = item.author
|
||||
if (item.duration.isNotEmpty()) {
|
||||
if (item.author.isNotEmpty()) info += " • "
|
||||
info += item.duration
|
||||
}
|
||||
bottomInfo.text = info
|
||||
|
||||
// TIME DOWNLOADED ----------------------------------
|
||||
val datetime = card.findViewById<TextView>(R.id.downloads_info_time)
|
||||
val time = item.time
|
||||
val downloadedTime: String
|
||||
if (time == 0L) {
|
||||
downloadedTime = activity.getString(R.string.currently_downloading) + " " + item.type
|
||||
} else {
|
||||
val cal = Calendar.getInstance()
|
||||
val date = Date(time * 1000L)
|
||||
cal.time = date
|
||||
val day = cal[Calendar.DAY_OF_MONTH]
|
||||
val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault())
|
||||
val year = cal[Calendar.YEAR]
|
||||
val formatter: DateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val timeString = formatter.format(date)
|
||||
downloadedTime = "$day $month $year - $timeString"
|
||||
}
|
||||
datetime.text = downloadedTime
|
||||
|
||||
// BUTTON ----------------------------------
|
||||
val buttonLayout = card.findViewById<LinearLayout>(R.id.downloads_download_button_layout)
|
||||
val btn = buttonLayout.findViewById<MaterialButton>(R.id.downloads_download_button_type)
|
||||
var filePresent = true
|
||||
|
||||
//IS IN THE FILE SYSTEM?
|
||||
val path = item.downloadPath
|
||||
val file = File(path)
|
||||
if (!file.exists() && path.isNotEmpty()) {
|
||||
filePresent = false
|
||||
thumbnail.colorFilter = ColorMatrixColorFilter(object : ColorMatrix() {
|
||||
init {
|
||||
setSaturation(0f)
|
||||
}
|
||||
})
|
||||
thumbnail.alpha = 0.7f
|
||||
}
|
||||
if (item.type.isNotEmpty()) {
|
||||
if (item.type == "audio") {
|
||||
if (filePresent) btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded) else btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_music)
|
||||
} else {
|
||||
if (filePresent) btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded) else btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video)
|
||||
}
|
||||
}
|
||||
if (btn.hasOnClickListeners()) btn.setOnClickListener(null)
|
||||
if (checkedItems.contains(item.id)) {
|
||||
card.isChecked = true
|
||||
card.strokeWidth = 5
|
||||
} else {
|
||||
card.isChecked = false
|
||||
card.strokeWidth = 0
|
||||
}
|
||||
val finalFilePresent = filePresent
|
||||
card.setOnLongClickListener {
|
||||
checkCard(card, item.id)
|
||||
true
|
||||
}
|
||||
card.setOnClickListener {
|
||||
if (checkedItems.size > 0) {
|
||||
checkCard(card, item.id)
|
||||
} else {
|
||||
onItemClickListener.onCardClick(item.id, finalFilePresent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 onCardClick(itemID: Long, isPresent: Boolean)
|
||||
fun onCardSelect(itemID: Long, isChecked: Boolean)
|
||||
fun onButtonClick(position: Int)
|
||||
}
|
||||
|
||||
@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()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DIFF_CALLBACK: DiffUtil.ItemCallback<HistoryItem> = object : DiffUtil.ItemCallback<HistoryItem>() {
|
||||
override fun areItemsTheSame(oldItem: HistoryItem, newItem: HistoryItem): Boolean {
|
||||
val ranged = arrayListOf(oldItem.id, newItem.id)
|
||||
return ranged[0] == ranged[1]
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: HistoryItem, newItem: HistoryItem): Boolean {
|
||||
return oldItem.time == newItem.time
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,195 @@
|
||||
package com.deniscerri.ytdlnis.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorMatrix
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.squareup.picasso.Picasso
|
||||
import java.io.File
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class QueuedDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<HistoryItem?, QueuedDownloadAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||
private val checkedItems: ArrayList<Long>
|
||||
private val onItemClickListener: OnItemClickListener
|
||||
private val activity: Activity
|
||||
|
||||
init {
|
||||
checkedItems = ArrayList()
|
||||
this.onItemClickListener = onItemClickListener
|
||||
this.activity = activity
|
||||
}
|
||||
|
||||
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
|
||||
val cardView: MaterialCardView
|
||||
|
||||
init {
|
||||
cardView = itemView.findViewById(R.id.downloads_card_view)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val cardView = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.history_card, parent, false)
|
||||
return ViewHolder(cardView, onItemClickListener)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
val card = holder.cardView
|
||||
// THUMBNAIL ----------------------------------
|
||||
val thumbnail = card.findViewById<ImageView>(R.id.downloads_image_view)
|
||||
val imageURL = item!!.thumb
|
||||
val uiHandler = Handler(Looper.getMainLooper())
|
||||
if (imageURL.isNotEmpty()) {
|
||||
uiHandler.post { Picasso.get().load(imageURL).into(thumbnail) }
|
||||
} else {
|
||||
uiHandler.post { Picasso.get().load(R.color.black).into(thumbnail) }
|
||||
}
|
||||
thumbnail.setColorFilter(Color.argb(95, 0, 0, 0))
|
||||
|
||||
// TITLE ----------------------------------
|
||||
val itemTitle = card.findViewById<TextView>(R.id.downloads_title)
|
||||
var title = item.title
|
||||
if (title.length > 100) {
|
||||
title = title.substring(0, 40) + "..."
|
||||
}
|
||||
itemTitle.text = title
|
||||
|
||||
// Bottom Info ----------------------------------
|
||||
val bottomInfo = card.findViewById<TextView>(R.id.downloads_info_bottom)
|
||||
var info = item.author
|
||||
if (item.duration.isNotEmpty()) {
|
||||
if (item.author.isNotEmpty()) info += " • "
|
||||
info += item.duration
|
||||
}
|
||||
bottomInfo.text = info
|
||||
|
||||
// TIME DOWNLOADED ----------------------------------
|
||||
val datetime = card.findViewById<TextView>(R.id.downloads_info_time)
|
||||
val time = item.time
|
||||
val downloadedTime: String
|
||||
if (time == 0L) {
|
||||
downloadedTime = activity.getString(R.string.currently_downloading) + " " + item.type
|
||||
} else {
|
||||
val cal = Calendar.getInstance()
|
||||
val date = Date(time * 1000L)
|
||||
cal.time = date
|
||||
val day = cal[Calendar.DAY_OF_MONTH]
|
||||
val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault())
|
||||
val year = cal[Calendar.YEAR]
|
||||
val formatter: DateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val timeString = formatter.format(date)
|
||||
downloadedTime = "$day $month $year - $timeString"
|
||||
}
|
||||
datetime.text = downloadedTime
|
||||
|
||||
// BUTTON ----------------------------------
|
||||
val buttonLayout = card.findViewById<LinearLayout>(R.id.downloads_download_button_layout)
|
||||
val btn = buttonLayout.findViewById<MaterialButton>(R.id.downloads_download_button_type)
|
||||
var filePresent = true
|
||||
|
||||
//IS IN THE FILE SYSTEM?
|
||||
val path = item.downloadPath
|
||||
val file = File(path)
|
||||
if (!file.exists() && path.isNotEmpty()) {
|
||||
filePresent = false
|
||||
thumbnail.colorFilter = ColorMatrixColorFilter(object : ColorMatrix() {
|
||||
init {
|
||||
setSaturation(0f)
|
||||
}
|
||||
})
|
||||
thumbnail.alpha = 0.7f
|
||||
}
|
||||
if (item.type.isNotEmpty()) {
|
||||
if (item.type == "audio") {
|
||||
if (filePresent) btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded) else btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_music)
|
||||
} else {
|
||||
if (filePresent) btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded) else btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video)
|
||||
}
|
||||
}
|
||||
if (btn.hasOnClickListeners()) btn.setOnClickListener(null)
|
||||
if (checkedItems.contains(item.id)) {
|
||||
card.isChecked = true
|
||||
card.strokeWidth = 5
|
||||
} else {
|
||||
card.isChecked = false
|
||||
card.strokeWidth = 0
|
||||
}
|
||||
val finalFilePresent = filePresent
|
||||
card.setOnLongClickListener {
|
||||
checkCard(card, item.id)
|
||||
true
|
||||
}
|
||||
card.setOnClickListener {
|
||||
if (checkedItems.size > 0) {
|
||||
checkCard(card, item.id)
|
||||
} else {
|
||||
onItemClickListener.onCardClick(item.id, finalFilePresent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 onCardClick(itemID: Long, isPresent: Boolean)
|
||||
fun onCardSelect(itemID: Long, isChecked: Boolean)
|
||||
fun onButtonClick(position: Int)
|
||||
}
|
||||
|
||||
@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()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DIFF_CALLBACK: DiffUtil.ItemCallback<HistoryItem> = object : DiffUtil.ItemCallback<HistoryItem>() {
|
||||
override fun areItemsTheSame(oldItem: HistoryItem, newItem: HistoryItem): Boolean {
|
||||
val ranged = arrayListOf(oldItem.id, newItem.id)
|
||||
return ranged[0] == ranged[1]
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: HistoryItem, newItem: HistoryItem): Boolean {
|
||||
return oldItem.time == newItem.time
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,282 @@
|
||||
package com.deniscerri.ytdlnis.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.*
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.*
|
||||
import android.view.View.*
|
||||
import android.widget.*
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.ActiveDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.adapter.QueuedDownloadAdapter
|
||||
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.FragmentHistoryBinding
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.facebook.shimmer.ShimmerFrameLayout
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* A fragment representing a list of Items.
|
||||
*/
|
||||
class DownloadFragment : Fragment(), ActiveDownloadAdapter.OnItemClickListener, QueuedDownloadAdapter.OnItemClickListener,
|
||||
OnClickListener, OnLongClickListener {
|
||||
private lateinit var downloadViewModel : DownloadViewModel
|
||||
|
||||
private var downloading = false
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
private var mainActivity: MainActivity? = null
|
||||
private var fragmentContext: Context? = null
|
||||
private var layoutinflater: LayoutInflater? = null
|
||||
private var shimmerCards: ShimmerFrameLayout? = null
|
||||
private var topAppBar: MaterialToolbar? = null
|
||||
private var activeRecyclerView: RecyclerView? = null
|
||||
private var othersRecyclerView: RecyclerView? = null
|
||||
private var downloadsAdapter: ActiveDownloadAdapter? = null
|
||||
private var queuedDownloadsAdapter: QueuedDownloadAdapter? = null
|
||||
private var bottomSheet: BottomSheetDialog? = null
|
||||
private var sortSheet: BottomSheetDialog? = null
|
||||
private var uiHandler: Handler? = null
|
||||
private var noResults: RelativeLayout? = null
|
||||
private var websiteGroup: ChipGroup? = null
|
||||
private var downloadsList: List<DownloadItem?>? = null
|
||||
private var allDownloadsList: List<DownloadItem?>? = null
|
||||
private var selectedObjects: ArrayList<DownloadItem>? = null
|
||||
private var deleteFab: ExtendedFloatingActionButton? = null
|
||||
private var fileUtil: FileUtil? = null
|
||||
|
||||
private var _binding : FragmentHistoryBinding? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentHistoryBinding.inflate(inflater, container, false)
|
||||
fragmentView = inflater.inflate(R.layout.fragment_downloads, container, false)
|
||||
activity = getActivity()
|
||||
mainActivity = activity as MainActivity?
|
||||
|
||||
return fragmentView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
fragmentContext = context
|
||||
layoutinflater = LayoutInflater.from(context)
|
||||
topAppBar = view.findViewById(R.id.downloads_toolbar)
|
||||
noResults = view.findViewById(R.id.no_results)
|
||||
websiteGroup = view.findViewById(R.id.website_chip_group)
|
||||
deleteFab = view.findViewById(R.id.delete_selected_fab)
|
||||
fileUtil = FileUtil()
|
||||
deleteFab?.tag = "deleteSelected"
|
||||
deleteFab?.setOnClickListener(this)
|
||||
uiHandler = Handler(Looper.getMainLooper())
|
||||
selectedObjects = ArrayList()
|
||||
downloading = mainActivity!!.isDownloadServiceRunning()
|
||||
|
||||
|
||||
downloadsList = mutableListOf()
|
||||
allDownloadsList = mutableListOf()
|
||||
|
||||
downloadsAdapter =
|
||||
ActiveDownloadAdapter(
|
||||
this,
|
||||
requireActivity()
|
||||
)
|
||||
activeRecyclerView = view.findViewById(R.id.recyclerviewactivedownloads)
|
||||
activeRecyclerView?.layoutManager = LinearLayoutManager(context)
|
||||
activeRecyclerView?.adapter = downloadsAdapter
|
||||
|
||||
queuedDownloadsAdapter =
|
||||
QueuedDownloadAdapter(
|
||||
this,
|
||||
requireActivity()
|
||||
)
|
||||
othersRecyclerView = view.findViewById(R.id.recyclerviewotherdownloads)
|
||||
othersRecyclerView?.layoutManager = LinearLayoutManager(context)
|
||||
othersRecyclerView?.adapter = queuedDownloadsAdapter
|
||||
|
||||
noResults?.visibility = GONE
|
||||
shimmerCards?.visibility = GONE
|
||||
|
||||
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
downloadViewModel.activeDownloads.observe(viewLifecycleOwner){
|
||||
// update active
|
||||
}
|
||||
downloadViewModel.queuedDownloads.observe(viewLifecycleOwner){
|
||||
// update queued
|
||||
}
|
||||
}
|
||||
|
||||
fun scrollToTop() {
|
||||
activeRecyclerView!!.scrollToPosition(0)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
(topAppBar!!.parent as AppBarLayout).setExpanded(
|
||||
true,
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLongClick(v: View): Boolean {
|
||||
val id = v.id
|
||||
if (id == R.id.bottom_sheet_link) {
|
||||
copyLinkToClipBoard(v.tag as Long)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun removeSelectedItems() {
|
||||
// if (bottomSheet != null) bottomSheet!!.hide()
|
||||
// val deleteFile = booleanArrayOf(false)
|
||||
// val deleteDialog = MaterialAlertDialogBuilder(fragmentContext!!)
|
||||
// deleteDialog.setTitle(getString(R.string.you_are_going_to_delete_multiple_items))
|
||||
// deleteDialog.setMultiChoiceItems(
|
||||
// arrayOf(getString(R.string.delete_files_too)),
|
||||
// booleanArrayOf(false)
|
||||
// ) { _: DialogInterface?, _: Int, b: Boolean -> deleteFile[0] = b }
|
||||
// deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||
// deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||
// for (item in selectedObjects!!){
|
||||
// historyViewModel.delete(item, deleteFile[0])
|
||||
// }
|
||||
// selectedObjects = ArrayList()
|
||||
// historyAdapter!!.clearCheckeditems()
|
||||
// deleteFab!!.visibility = GONE
|
||||
// }
|
||||
// deleteDialog.show()
|
||||
}
|
||||
|
||||
private fun removeItem(id: Long) {
|
||||
// if (bottomSheet != null) bottomSheet!!.hide()
|
||||
// val deleteFile = booleanArrayOf(false)
|
||||
// val v = findItem(id)
|
||||
// val deleteDialog = MaterialAlertDialogBuilder(fragmentContext!!)
|
||||
// deleteDialog.setTitle(getString(R.string.you_are_going_to_delete) + " \"" + v!!.title + "\"!")
|
||||
// deleteDialog.setMultiChoiceItems(
|
||||
// arrayOf(getString(R.string.delete_file_too)),
|
||||
// booleanArrayOf(false)
|
||||
// ) { _: DialogInterface?, _: Int, b: Boolean -> deleteFile[0] = b }
|
||||
// deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||
// deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||
// historyViewModel.delete(v, deleteFile[0])
|
||||
// }
|
||||
// deleteDialog.show()
|
||||
}
|
||||
|
||||
private fun copyLinkToClipBoard(id: Long) {
|
||||
val url = findItem(id)?.url
|
||||
val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText(getString(R.string.url), url)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
if (bottomSheet != null) bottomSheet!!.hide()
|
||||
Toast.makeText(context, getString(R.string.link_copied_to_clipboard), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun openLinkIntent(id: Long) {
|
||||
val url = findItem(id)?.url
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.data = Uri.parse(url)
|
||||
if (bottomSheet != null) bottomSheet!!.hide()
|
||||
startActivity(i)
|
||||
}
|
||||
|
||||
private fun openFileIntent(id: Long) {
|
||||
val downloadPath = findItem(id)!!.downloadPath
|
||||
val file = File(downloadPath)
|
||||
val uri = FileProvider.getUriForFile(
|
||||
fragmentContext!!,
|
||||
fragmentContext!!.packageName + ".fileprovider",
|
||||
file
|
||||
)
|
||||
val mime = mainActivity!!.contentResolver.getType(uri)
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.setDataAndType(uri, mime)
|
||||
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
startActivity(i)
|
||||
}
|
||||
|
||||
override fun onCardClick(videoID: Long, isPresent: Boolean) {
|
||||
bottomSheet = BottomSheetDialog(fragmentContext!!)
|
||||
bottomSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet!!.setContentView(R.layout.history_item_details_bottom_sheet)
|
||||
val video = findItem(videoID)
|
||||
val title = bottomSheet!!.findViewById<TextView>(R.id.bottom_sheet_title)
|
||||
title!!.text = video!!.title
|
||||
val author = bottomSheet!!.findViewById<TextView>(R.id.bottom_sheet_author)
|
||||
author!!.text = video.author
|
||||
val link = bottomSheet!!.findViewById<Button>(R.id.bottom_sheet_link)
|
||||
val url = video.url
|
||||
link!!.text = url
|
||||
link.tag = videoID
|
||||
link.setOnClickListener(this)
|
||||
link.setOnLongClickListener(this)
|
||||
val remove = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_remove_button)
|
||||
remove!!.tag = videoID
|
||||
remove.setOnClickListener(this)
|
||||
val openFile = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_open_file_button)
|
||||
openFile!!.tag = videoID
|
||||
openFile.setOnClickListener(this)
|
||||
if (!isPresent) openFile.visibility = GONE
|
||||
bottomSheet!!.show()
|
||||
bottomSheet!!.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCardSelect(videoID: Long, isChecked: Boolean) {
|
||||
val item = findItem(videoID)
|
||||
if (isChecked) selectedObjects!!.add(item!!)
|
||||
else selectedObjects!!.remove(item)
|
||||
if (selectedObjects!!.size > 1) {
|
||||
deleteFab!!.visibility = VISIBLE
|
||||
} else {
|
||||
deleteFab!!.visibility = GONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onButtonClick(position: Int) {
|
||||
// val vid = downloadsObjects!![position]
|
||||
// try {
|
||||
// //mainActivity!!.removeItemFromDownloadQueue(vid, vid!!.downloadedType)
|
||||
// } catch (e: Exception) {
|
||||
// val info = DownloadInfo()
|
||||
// info.video = vid
|
||||
// info.downloadType = vid!!.downloadedType
|
||||
// }
|
||||
}
|
||||
|
||||
private fun findItem(id : Long): DownloadItem? {
|
||||
return downloadsList?.find { it?.id == id }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "downloadsFragment"
|
||||
}
|
||||
|
||||
override fun onClick(p0: View?) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
package com.deniscerri.ytdlnis.work
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.SystemClock
|
||||
import android.provider.DocumentsContract
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.ForegroundInfo
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import java.io.File
|
||||
|
||||
class FileTransferWorker(
|
||||
private val context: Context,
|
||||
workerParams: WorkerParameters
|
||||
) : CoroutineWorker(context, workerParams) {
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
val originDir = File(inputData.getString(originDir)!!)
|
||||
val downLocation = inputData.getString(downLocation)
|
||||
val fileTitle = inputData.getString(title) ?: ""
|
||||
val destDir = Uri.parse(downLocation).run {
|
||||
DocumentsContract.buildChildDocumentsUriUsingTree(this, DocumentsContract.getTreeDocumentId(this))
|
||||
}
|
||||
|
||||
val fileUtil = FileUtil()
|
||||
|
||||
val notificationUtil = NotificationUtil(context)
|
||||
val intent = Intent(context, MainActivity::class.java)
|
||||
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
|
||||
val title = "Moving $fileTitle to ${fileUtil.formatPath(downLocation!!)}"
|
||||
val id : Int = SystemClock.uptimeMillis().toInt()
|
||||
val notification = notificationUtil.createFileTransferNotification(pendingIntent, title)
|
||||
val foregroundInfo = ForegroundInfo(id, notification)
|
||||
setForeground(foregroundInfo)
|
||||
|
||||
fileUtil.moveFile(originDir, context, destDir){ progress ->
|
||||
setProgressAsync(workDataOf("progress" to progress))
|
||||
notificationUtil.updateFileTransferNotification(id, progress)
|
||||
}
|
||||
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
const val downLocation = "downLocation"
|
||||
const val originDir = "originDir"
|
||||
const val title = "title"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/downloadscoordinator"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/downloads_appbarlayout"
|
||||
app:liftOnScroll="false"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/downloads_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap"
|
||||
app:title="@string/downloads"
|
||||
android:theme="@style/Toolbar"
|
||||
/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="10dp"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerviewactivedownloads"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="150dp"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager">
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerviewotherdownloads"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="150dp"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager">
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/delete_selected_coordinator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/delete_selected_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:visibility="gone"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:text="@string/delete_selected"
|
||||
app:icon="@drawable/ic_delete_all"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
|
||||
<include layout="@layout/history_no_results"
|
||||
android:visibility="gone" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
Loading…
Reference in New Issue