diff --git a/app/build.gradle b/app/build.gradle
index b0c1397c..2eec33c0 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -120,7 +120,7 @@ dependencies {
implementation "androidx.appcompat:appcompat:$appCompatVer"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
- implementation 'com.google.android.material:material:1.9.0-alpha02'
+ implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.core:core:1.9.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cb071837..3e366f27 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -65,6 +65,16 @@
+
+
+
+
+
+
{
if (lastFragment === historyFragment) {
- historyFragment.scrollToTop()
+ val intent = Intent(context, DownloadQueueActivity::class.java)
+ startActivity(intent)
} else {
this.title = getString(R.string.downloads)
}
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt
index d6786dd8..cc82153b 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt
@@ -1,56 +1,48 @@
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.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
+import com.deniscerri.ytdlnis.database.models.DownloadItem
+import com.deniscerri.ytdlnis.util.FileUtil
import com.google.android.material.button.MaterialButton
import com.google.android.material.card.MaterialCardView
+import com.google.android.material.progressindicator.LinearProgressIndicator
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(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
- private val checkedItems: ArrayList
+class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
private val onItemClickListener: OnItemClickListener
private val activity: Activity
+ private val fileUtil: FileUtil
init {
- checkedItems = ArrayList()
this.onItemClickListener = onItemClickListener
this.activity = activity
+ fileUtil = FileUtil()
}
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
val cardView: MaterialCardView
init {
- cardView = itemView.findViewById(R.id.downloads_card_view)
+ cardView = itemView.findViewById(R.id.active_download_card_view)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val cardView = LayoutInflater.from(parent.context)
- .inflate(R.layout.history_card, parent, false)
+ .inflate(R.layout.active_download_card, parent, false)
return ViewHolder(cardView, onItemClickListener)
}
@@ -58,7 +50,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
val item = getItem(position)
val card = holder.cardView
// THUMBNAIL ----------------------------------
- val thumbnail = card.findViewById(R.id.downloads_image_view)
+ val thumbnail = card.findViewById(R.id.image_view)
val imageURL = item!!.thumb
val uiHandler = Handler(Looper.getMainLooper())
if (imageURL.isNotEmpty()) {
@@ -68,126 +60,76 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
}
thumbnail.setColorFilter(Color.argb(95, 0, 0, 0))
+ // PROGRESS BAR ----------------------------------------------------
+ val progressBar = card.findViewById(R.id.progress)
+ progressBar.tag = "${item.id}##progress"
+ progressBar.progress = 0
+ progressBar.isIndeterminate = true
+
// TITLE ----------------------------------
- val itemTitle = card.findViewById(R.id.downloads_title)
+ val itemTitle = card.findViewById(R.id.title)
var title = item.title
if (title.length > 100) {
title = title.substring(0, 40) + "..."
}
itemTitle.text = title
- // Bottom Info ----------------------------------
- val bottomInfo = card.findViewById(R.id.downloads_info_bottom)
+ // Author ----------------------------------
+ val author = card.findViewById(R.id.author)
var info = item.author
if (item.duration.isNotEmpty()) {
if (item.author.isNotEmpty()) info += " • "
info += item.duration
}
- bottomInfo.text = info
+ author.text = info
- // TIME DOWNLOADED ----------------------------------
- val datetime = card.findViewById(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(R.id.downloads_download_button_layout)
- val btn = buttonLayout.findViewById(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 == DownloadViewModel.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)
+ val formatNote = card.findViewById(R.id.format_note)
+ formatNote.text = item.format.format_note
+ val codec = card.findViewById(R.id.codec)
+ val codecText =
+ if (item.format.encoding != "") {
+ item.format.encoding.uppercase()
+ }else if (item.format.vcodec != "none" && item.format.vcodec != ""){
+ item.format.vcodec.uppercase()
} else {
- onItemClickListener.onCardClick(item.id, finalFilePresent)
+ item.format.acodec.uppercase()
}
+ if (codecText == "" || codecText == "none"){
+ codec.visibility = View.GONE
+ }else{
+ codec.visibility = View.VISIBLE
+ codec.text = codecText
+ }
+
+ val fileSize = card.findViewById(R.id.file_size)
+ fileSize.text = fileUtil.convertFileSize(item.format.filesize)
+
+ //OUTPUT
+ val output = card.findViewById(R.id.output)
+ output.tag = "${item.id}##output"
+
+
+ // CANCEL BUTTON ----------------------------------
+ val cancelButton = card.findViewById(R.id.active_download_cancel)
+ if (cancelButton.hasOnClickListeners()) cancelButton.setOnClickListener(null)
+
+ cancelButton.setOnClickListener {
+ onItemClickListener.onCancelClick(item.id)
}
}
-
- 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()
+ fun onCancelClick(itemID: Long)
}
companion object {
- private val DIFF_CALLBACK: DiffUtil.ItemCallback = object : DiffUtil.ItemCallback() {
- override fun areItemsTheSame(oldItem: HistoryItem, newItem: HistoryItem): Boolean {
+ private val DIFF_CALLBACK: DiffUtil.ItemCallback = object : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: DownloadItem, newItem: DownloadItem): 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
+ override fun areContentsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
+ return oldItem.id == newItem.id
}
}
}
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/QueuedDownloadAdapter.kt b/app/src/main/java/com/deniscerri/ytdlnis/adapter/QueuedDownloadAdapter.kt
index a2264328..c3674386 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/QueuedDownloadAdapter.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/QueuedDownloadAdapter.kt
@@ -7,6 +7,7 @@ import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.os.Handler
import android.os.Looper
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -19,38 +20,40 @@ 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.DownloadItem
import com.deniscerri.ytdlnis.database.models.HistoryItem
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
+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 org.w3c.dom.Text
import java.io.File
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
-class QueuedDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
- private val checkedItems: ArrayList
+class QueuedDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
private val onItemClickListener: OnItemClickListener
private val activity: Activity
+ private var fileUtil: FileUtil
init {
- checkedItems = ArrayList()
this.onItemClickListener = onItemClickListener
this.activity = activity
+ fileUtil = FileUtil()
}
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
val cardView: MaterialCardView
-
init {
- cardView = itemView.findViewById(R.id.downloads_card_view)
+ cardView = itemView.findViewById(R.id.queued_download_card_view)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val cardView = LayoutInflater.from(parent.context)
- .inflate(R.layout.history_card, parent, false)
+ .inflate(R.layout.queued_download_card, parent, false)
return ViewHolder(cardView, onItemClickListener)
}
@@ -58,7 +61,7 @@ class QueuedDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
val item = getItem(position)
val card = holder.cardView
// THUMBNAIL ----------------------------------
- val thumbnail = card.findViewById(R.id.downloads_image_view)
+ val thumbnail = card.findViewById(R.id.image_view)
val imageURL = item!!.thumb
val uiHandler = Handler(Looper.getMainLooper())
if (imageURL.isNotEmpty()) {
@@ -69,29 +72,48 @@ class QueuedDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
thumbnail.setColorFilter(Color.argb(95, 0, 0, 0))
// TITLE ----------------------------------
- val itemTitle = card.findViewById(R.id.downloads_title)
+ val itemTitle = card.findViewById(R.id.title)
var title = item.title
if (title.length > 100) {
title = title.substring(0, 40) + "..."
}
itemTitle.text = title
- // Bottom Info ----------------------------------
- val bottomInfo = card.findViewById(R.id.downloads_info_bottom)
+ // Author ----------------------------------
+ val author = card.findViewById(R.id.author)
var info = item.author
if (item.duration.isNotEmpty()) {
if (item.author.isNotEmpty()) info += " • "
info += item.duration
}
- bottomInfo.text = info
+ author.text = info
- // TIME DOWNLOADED ----------------------------------
- val datetime = card.findViewById(R.id.downloads_info_time)
- val time = item.time
- val downloadedTime: String
+ val formatNote = card.findViewById(R.id.format_note)
+ formatNote.text = item.format.format_note
+ val codec = card.findViewById(R.id.codec)
+ val codecText =
+ if (item.format.encoding != "") {
+ item.format.encoding.uppercase()
+ }else if (item.format.vcodec != "none" && item.format.vcodec != ""){
+ item.format.vcodec.uppercase()
+ } else {
+ item.format.acodec.uppercase()
+ }
+ if (codecText == "" || codecText == "none"){
+ codec.visibility = View.GONE
+ }else{
+ codec.visibility = View.VISIBLE
+ codec.text = codecText
+ }
+
+ val fileSize = card.findViewById(R.id.file_size)
+ fileSize.text = fileUtil.convertFileSize(item.format.filesize)
+ val downloadStartTime = card.findViewById(R.id.time)
+ val time = item.downloadStartTime
if (time == 0L) {
- downloadedTime = activity.getString(R.string.currently_downloading) + " " + item.type
+ downloadStartTime.visibility = View.GONE
} else {
+ downloadStartTime.visibility = View.VISIBLE
val cal = Calendar.getInstance()
val date = Date(time * 1000L)
cal.time = date
@@ -100,94 +122,31 @@ class QueuedDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
val year = cal[Calendar.YEAR]
val formatter: DateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
val timeString = formatter.format(date)
- downloadedTime = "$day $month $year - $timeString"
+ downloadStartTime.text = "$day $month $year - $timeString"
}
- datetime.text = downloadedTime
- // BUTTON ----------------------------------
- val buttonLayout = card.findViewById(R.id.downloads_download_button_layout)
- val btn = buttonLayout.findViewById(R.id.downloads_download_button_type)
- var filePresent = true
+ // CANCEL BUTTON ----------------------------------
+ val cancelButton = card.findViewById(R.id.queued_download_cancel)
+ if (cancelButton.hasOnClickListeners()) cancelButton.setOnClickListener(null)
- //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 == DownloadViewModel.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)
- }
+ cancelButton.setOnClickListener {
+ onItemClickListener.onQueuedCancelClick(item.id)
}
+
}
-
- 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()
+ fun onQueuedCancelClick(itemID: Long)
}
companion object {
- private val DIFF_CALLBACK: DiffUtil.ItemCallback = object : DiffUtil.ItemCallback() {
- override fun areItemsTheSame(oldItem: HistoryItem, newItem: HistoryItem): Boolean {
+ private val DIFF_CALLBACK: DiffUtil.ItemCallback = object : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: DownloadItem, newItem: DownloadItem): 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
+ override fun areContentsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
+ return oldItem.url == newItem.url && oldItem.format.format_id == newItem.format.format_id
}
}
}
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/DownloadQueueActivity.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/DownloadQueueActivity.kt
new file mode 100644
index 00000000..c3a6a94f
--- /dev/null
+++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/DownloadQueueActivity.kt
@@ -0,0 +1,176 @@
+package com.deniscerri.ytdlnis.ui
+
+import android.content.Context
+import android.os.Bundle
+import android.util.Log
+import android.view.MenuItem
+import android.view.View
+import android.widget.LinearLayout
+import android.widget.RelativeLayout
+import android.widget.TextView
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import androidx.work.WorkManager
+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.viewmodel.DownloadViewModel
+import com.deniscerri.ytdlnis.util.NotificationUtil
+import com.google.android.material.appbar.MaterialToolbar
+import com.google.android.material.progressindicator.LinearProgressIndicator
+import com.yausername.youtubedl_android.YoutubeDL
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
+
+
+class DownloadQueueActivity : AppCompatActivity(), ActiveDownloadAdapter.OnItemClickListener, QueuedDownloadAdapter.OnItemClickListener {
+ private lateinit var activeRecyclerView: RecyclerView
+ private lateinit var activeDownloads: ActiveDownloadAdapter
+ private lateinit var queuedRecyclerView: RecyclerView
+ private lateinit var queuedDownloads: QueuedDownloadAdapter
+ private lateinit var noResults: RelativeLayout
+ private lateinit var downloadViewModel: DownloadViewModel
+ private lateinit var topAppBar: MaterialToolbar
+ private lateinit var notificationUtil: NotificationUtil
+
+ private lateinit var runningLayout: LinearLayout
+ private lateinit var queuedLayout: LinearLayout
+ var context: Context? = null
+
+ public override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_download_queue)
+ context = baseContext
+ val view : View = window.decorView.findViewById(android.R.id.content)
+
+
+ topAppBar = findViewById(R.id.logs_toolbar)
+ topAppBar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }
+
+ activeDownloads =
+ ActiveDownloadAdapter(
+ this,
+ this@DownloadQueueActivity
+ )
+
+ queuedDownloads =
+ QueuedDownloadAdapter(
+ this,
+ this@DownloadQueueActivity
+ )
+
+
+ activeRecyclerView = findViewById(R.id.active_recyclerview)
+ activeRecyclerView.layoutManager = LinearLayoutManager(context)
+ activeRecyclerView.adapter = activeDownloads
+
+ queuedRecyclerView = findViewById(R.id.queued_recyclerview)
+ queuedRecyclerView.layoutManager = LinearLayoutManager(context)
+ queuedRecyclerView.adapter = queuedDownloads
+
+ noResults = findViewById(R.id.no_results)
+ noResults.visibility = View.GONE
+
+ runningLayout = findViewById(R.id.running_layout)
+ queuedLayout = findViewById(R.id.queued_layout)
+
+ downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
+ notificationUtil = NotificationUtil(this)
+
+
+ //active downloads livedata
+ downloadViewModel.activeDownloads.observe(this) {
+ activeDownloads.submitList(it)
+ if (it.isEmpty()){
+ if (queuedLayout.visibility == View.GONE) noResults.visibility = View.VISIBLE
+ runningLayout.visibility = View.GONE
+ }else{
+ noResults.visibility = View.GONE
+ runningLayout.visibility = View.VISIBLE
+
+ it.forEach{item ->
+ WorkManager.getInstance(this)
+ .getWorkInfosForUniqueWorkLiveData(item.id.toString())
+ .observe(this){ list ->
+ list.forEach {work ->
+ if (work == null) return@observe
+ val id = work.progress.getLong("id", 0L)
+ if(id == 0L) return@observe
+
+ val progress = work.progress.getInt("progress", 0)
+ val output = work.progress.getString("output")
+
+ val progressBar = view.findViewWithTag("$id##progress")
+ val outputText = view.findViewWithTag("$id##output")
+
+ runOnUiThread {
+ progressBar.setProgressCompat(progress, true)
+ outputText.text = output
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //queued downloads livedata
+ downloadViewModel.queuedDownloads.observe(this) {
+ queuedDownloads.submitList(it)
+ if (it.isEmpty()){
+ if (runningLayout.visibility == View.GONE) noResults.visibility = View.VISIBLE
+ queuedLayout.visibility = View.GONE
+ }else{
+ noResults.visibility = View.GONE
+ queuedLayout.visibility = View.VISIBLE
+ }
+ }
+ }
+
+ private fun initMenu(logFolder: File) {
+ topAppBar.setOnMenuItemClickListener { m: MenuItem ->
+ val itemId = m.itemId
+ if (itemId == R.id.remove_logs) {
+ try{
+ logFolder.listFiles()!!.forEach {
+ it.delete()
+ }
+ }catch (e: Exception){
+ Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
+ }
+ }
+ true
+ }
+ }
+
+
+ companion object {
+ private const val TAG = "DownloadQueueActivity"
+ }
+
+ override fun onCancelClick(itemID: Long) {
+ cancelDownload(itemID)
+ }
+
+ override fun onQueuedCancelClick(itemID: Long) {
+ lifecycleScope.launch{
+ withContext(Dispatchers.IO){
+ downloadViewModel.deleteDownload(downloadViewModel.getItemByID(itemID))
+ }
+ }
+ cancelDownload(itemID)
+ }
+
+ private fun cancelDownload(itemID: Long){
+ val id = itemID.toInt()
+ YoutubeDL.getInstance().destroyProcessById(id.toString())
+ WorkManager.getInstance(this).cancelUniqueWork(id.toString())
+ notificationUtil.cancelDownloadNotification(id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
index 760588bb..1f382ecc 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
@@ -184,15 +184,10 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
}
try {
Handler(Looper.getMainLooper()).post {
-
// DOWNLOAD ALL BUTTON
if (resultsList!!.size > 1 || inputQueriesLength > 1) {
downloadAllFabCoordinator!!.visibility = VISIBLE
}
-// databaseManager = DatabaseManager(context)
-// databaseManager!!.clearResults()
-// for (v in resultsList!!) v!!.isPlaylistItem = 1
-// databaseManager!!.addToResults(resultsList)
}
} catch (ignored: Exception) {
}
@@ -202,14 +197,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
resultViewModel.checkTrending()
}
- WorkManager.getInstance(requireContext())
- .getWorkInfosByTagLiveData("download")
- .observe(viewLifecycleOwner){ list ->
- list.forEach {
- //Toast.makeText(context, """${it.progress.getInt("progress", 0)} ${it.progress.getString("output")}""", Toast.LENGTH_SHORT).show()
- }
- }
-
// fragmentView!!.post{
// if (shimmerCards!!.visibility == VISIBLE) return@post
// val clipboard = requireContext().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt b/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt
index 5b488d76..8494009c 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt
@@ -209,10 +209,8 @@ class DownloadWorker(
"Format: ${downloadItem.format}\n\n")
}
-
YoutubeDL.getInstance().execute(request, downloadItem.id.toString()){ progress, _, line ->
- setProgressAsync(workDataOf("progress" to progress.toInt()))
- setProgressAsync(workDataOf("output" to line))
+ setProgressAsync(workDataOf("progress" to progress.toInt(), "output" to line, "id" to downloadItem.id))
val title: String = downloadItem.title
notificationUtil.updateDownloadNotification(
downloadItem.id.toInt(),
diff --git a/app/src/main/res/layout/active_download_card.xml b/app/src/main/res/layout/active_download_card.xml
new file mode 100644
index 00000000..447e093a
--- /dev/null
+++ b/app/src/main/res/layout/active_download_card.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_command_templates.xml b/app/src/main/res/layout/activity_command_templates.xml
new file mode 100644
index 00000000..dc343f64
--- /dev/null
+++ b/app/src/main/res/layout/activity_command_templates.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_download_queue.xml b/app/src/main/res/layout/activity_download_queue.xml
new file mode 100644
index 00000000..9342b836
--- /dev/null
+++ b/app/src/main/res/layout/activity_download_queue.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/queued_download_card.xml b/app/src/main/res/layout/queued_download_card.xml
new file mode 100644
index 00000000..ddf93874
--- /dev/null
+++ b/app/src/main/res/layout/queued_download_card.xml
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index a22e401e..8ac5d0a1 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -4,5 +4,5 @@
#000000
#323232
#A6A6A6
- @android:color/background_light
+ @android:color/background_dark
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 032595a4..b707589e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -181,4 +181,6 @@
Log Downloads
Create a log file for each download
New Update
+ Download Queue
+ Running
\ No newline at end of file
diff --git a/app/src/main/res/xml/more_preferences.xml b/app/src/main/res/xml/more_preferences.xml
index d21694c7..2ec4e2f1 100644
--- a/app/src/main/res/xml/more_preferences.xml
+++ b/app/src/main/res/xml/more_preferences.xml
@@ -41,6 +41,15 @@
+
+
+
+
+