added download multiple card
This commit is contained in:
parent
a6b078f95b
commit
ff58bd2dbf
15 changed files with 379 additions and 253 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
"formatVersion": 1,
|
"formatVersion": 1,
|
||||||
"database": {
|
"database": {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"identityHash": "2c0fdec170ca54d97ef928dfe28a6992",
|
"identityHash": "db5c9df3e43ddd5a5131bbd372a7c92b",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"tableName": "results",
|
"tableName": "results",
|
||||||
|
|
@ -74,7 +74,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tableName": "formats",
|
"tableName": "formats",
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `itemId` INTEGER NOT NULL, `format_id` TEXT NOT NULL, `container` TEXT NOT NULL, `filesize` INTEGER NOT NULL, `format_note` TEXT NOT NULL, `encoding` TEXT NOT NULL)",
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `itemId` INTEGER NOT NULL, `format_id` TEXT NOT NULL, `container` TEXT NOT NULL, `filesize` INTEGER NOT NULL, `format_note` TEXT NOT NULL)",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
|
|
@ -111,12 +111,6 @@
|
||||||
"columnName": "format_note",
|
"columnName": "format_note",
|
||||||
"affinity": "TEXT",
|
"affinity": "TEXT",
|
||||||
"notNull": true
|
"notNull": true
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "encoding",
|
|
||||||
"columnName": "encoding",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"primaryKey": {
|
"primaryKey": {
|
||||||
|
|
@ -392,7 +386,7 @@
|
||||||
"views": [],
|
"views": [],
|
||||||
"setupQueries": [
|
"setupQueries": [
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2c0fdec170ca54d97ef928dfe28a6992')"
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'db5c9df3e43ddd5a5131bbd372a7c92b')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,9 @@
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme" >
|
android:enableOnBackInvokedCallback="true"
|
||||||
|
android:theme="@style/AppTheme"
|
||||||
|
tools:targetApi="tiramisu">
|
||||||
<activity android:name=".MainActivity"
|
<activity android:name=".MainActivity"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="adjustResize"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@ import android.app.Activity
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||||
|
|
@ -16,12 +18,13 @@ import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
|
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.card.MaterialCardView
|
import com.google.android.material.card.MaterialCardView
|
||||||
|
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
|
||||||
class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener, activity: Activity) :
|
class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<DownloadItem?, ConfigureMultipleDownloadsAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||||
ListAdapter<DownloadItem?, ConfigureMultipleDownloadsAdapter.ViewHolder?>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
|
||||||
private val onItemClickListener: OnItemClickListener
|
private val onItemClickListener: OnItemClickListener
|
||||||
private val activity: Activity
|
private val activity: Activity
|
||||||
|
|
||||||
|
|
@ -30,18 +33,17 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
|
||||||
this.activity = activity
|
this.activity = activity
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) :
|
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
|
||||||
RecyclerView.ViewHolder(itemView) {
|
|
||||||
val cardView: MaterialCardView
|
val cardView: MaterialCardView
|
||||||
|
|
||||||
init {
|
init {
|
||||||
cardView = itemView.findViewById(R.id.download_multiple_card_view)
|
cardView = itemView.findViewById(R.id.download_card_view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
val cardView = LayoutInflater.from(parent.context)
|
val cardView = LayoutInflater.from(parent.context)
|
||||||
.inflate(R.layout.home_download_multiple_card, parent, false)
|
.inflate(R.layout.download_card, parent, false)
|
||||||
return ViewHolder(cardView, onItemClickListener)
|
return ViewHolder(cardView, onItemClickListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,7 +51,7 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
|
||||||
val item = getItem(position)
|
val item = getItem(position)
|
||||||
val card = holder.cardView
|
val card = holder.cardView
|
||||||
// THUMBNAIL ----------------------------------
|
// THUMBNAIL ----------------------------------
|
||||||
val thumbnail = card.findViewById<ImageView>(R.id.result_image_view)
|
val thumbnail = card.findViewById<ImageView>(R.id.downloads_image_view)
|
||||||
val imageURL = item!!.thumb
|
val imageURL = item!!.thumb
|
||||||
if (imageURL.isNotEmpty()) {
|
if (imageURL.isNotEmpty()) {
|
||||||
val uiHandler = Handler(Looper.getMainLooper())
|
val uiHandler = Handler(Looper.getMainLooper())
|
||||||
|
|
@ -62,7 +64,7 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
|
||||||
}
|
}
|
||||||
|
|
||||||
// TITLE ----------------------------------
|
// TITLE ----------------------------------
|
||||||
val itemTitle = card.findViewById<TextView>(R.id.result_title)
|
val itemTitle = card.findViewById<TextView>(R.id.title)
|
||||||
var title = item.title
|
var title = item.title
|
||||||
if (title.length > 100) {
|
if (title.length > 100) {
|
||||||
title = title.substring(0, 40) + "..."
|
title = title.substring(0, 40) + "..."
|
||||||
|
|
@ -73,20 +75,16 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
|
||||||
val author = card.findViewById<TextView>(R.id.author)
|
val author = card.findViewById<TextView>(R.id.author)
|
||||||
author.text = item.author
|
author.text = item.author
|
||||||
|
|
||||||
// Format
|
// Container ----------------------------------
|
||||||
val format = card.findViewById<TextView>(R.id.format)
|
val container = card.findViewById<TextView>(R.id.container)
|
||||||
format.text = item.ext
|
container.text = item.ext
|
||||||
|
|
||||||
// Quality
|
|
||||||
val quality = card.findViewById<TextView>(R.id.quality)
|
|
||||||
quality.text = item.formatDesc
|
|
||||||
|
|
||||||
// File Size
|
// File Size
|
||||||
val fileSize = card.findViewById<TextView>(R.id.filesize)
|
val fileSize = card.findViewById<TextView>(R.id.filesize)
|
||||||
fileSize.text = item.filesize
|
fileSize.text = item.filesize
|
||||||
|
|
||||||
// Type Icon Button
|
// Type Icon Button
|
||||||
val btn = card.findViewById<MaterialButton>(R.id.download_type)
|
val btn = card.findViewById<MaterialButton>(R.id.downloads_download_button_type)
|
||||||
|
|
||||||
when(item.type) {
|
when(item.type) {
|
||||||
"audio" -> {
|
"audio" -> {
|
||||||
|
|
@ -105,21 +103,20 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface OnItemClickListener {
|
interface OnItemClickListener {
|
||||||
|
fun onButtonClick(videoURL: String, type: String?)
|
||||||
fun onCardClick(itemID: Long)
|
fun onCardClick(itemID: Long)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val DIFF_CALLBACK: DiffUtil.ItemCallback<DownloadItem> =
|
private val DIFF_CALLBACK: DiffUtil.ItemCallback<DownloadItem> = object : DiffUtil.ItemCallback<DownloadItem>() {
|
||||||
object : DiffUtil.ItemCallback<DownloadItem>() {
|
override fun areItemsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
||||||
override fun areItemsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
return oldItem.id === newItem.id
|
||||||
return oldItem.id === newItem.id
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun areContentsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
|
||||||
return oldItem.url == newItem.url
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
||||||
|
return oldItem.url == newItem.url && oldItem.title == newItem.title && oldItem.author == newItem.author
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,14 +9,17 @@ import com.deniscerri.ytdlnis.util.FileUtil
|
||||||
@Dao
|
@Dao
|
||||||
interface DownloadDao {
|
interface DownloadDao {
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads")
|
@Query("SELECT * FROM downloads ORDER BY status")
|
||||||
fun getAllDownloads() : LiveData<List<DownloadItem>>
|
fun getAllDownloads() : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads WHERE status='Active'")
|
@Query("SELECT * FROM downloads WHERE status='Active'")
|
||||||
fun getActiveDownloads() : LiveData<List<DownloadItem>>
|
fun getActiveDownloads() : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads WHERE status='Queued'")
|
@Query("SELECT * FROM downloads WHERE status='Queued'")
|
||||||
fun getQueuedDownloads() : List<DownloadItem>
|
fun getQueuedDownloads() : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM downloads WHERE status='Processing'")
|
||||||
|
fun getProcessingDownloads() : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads WHERE workID=:workID")
|
@Query("SELECT * FROM downloads WHERE workID=:workID")
|
||||||
fun getDownloadByWorkId(workID: Int) : DownloadItem
|
fun getDownloadByWorkId(workID: Int) : DownloadItem
|
||||||
|
|
@ -33,6 +36,9 @@ interface DownloadDao {
|
||||||
@Delete
|
@Delete
|
||||||
suspend fun delete(item: DownloadItem)
|
suspend fun delete(item: DownloadItem)
|
||||||
|
|
||||||
|
@Query("DELETE FROM downloads WHERE status='Processing'")
|
||||||
|
suspend fun deleteProcessing()
|
||||||
|
|
||||||
@Update(onConflict = OnConflictStrategy.REPLACE)
|
@Update(onConflict = OnConflictStrategy.REPLACE)
|
||||||
suspend fun update(item: DownloadItem)
|
suspend fun update(item: DownloadItem)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,14 @@ import com.google.gson.annotations.SerializedName
|
||||||
@Entity(tableName = "formats")
|
@Entity(tableName = "formats")
|
||||||
data class Format(
|
data class Format(
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
var id: Long,
|
var id: Long = -1,
|
||||||
var itemId: Long,
|
var itemId: Long = 0,
|
||||||
@SerializedName(value = "format_id", alternate = ["itag"])
|
@SerializedName(value = "format_id", alternate = ["itag"])
|
||||||
val format_id: String,
|
val format_id: String = "",
|
||||||
@SerializedName(value = "ext", alternate = ["container"])
|
@SerializedName(value = "ext", alternate = ["container"])
|
||||||
val container: String,
|
val container: String = "",
|
||||||
@SerializedName(value = "filesize", alternate = ["clen", "filesize_approx"])
|
@SerializedName(value = "filesize", alternate = ["clen", "filesize_approx"])
|
||||||
val filesize: Long,
|
val filesize: Long = 0,
|
||||||
@SerializedName(value = "format_note", alternate = ["resolution", "audioQuality"])
|
@SerializedName(value = "format_note", alternate = ["resolution", "audioQuality"])
|
||||||
val format_note: String,
|
val format_note: String = ""
|
||||||
@SerializedName(value = "encoding", alternate = ["vcodec", "acodec", "video_ext"])
|
|
||||||
val encoding: String
|
|
||||||
)
|
)
|
||||||
|
|
@ -3,11 +3,16 @@ package com.deniscerri.ytdlnis.database.repository
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import com.deniscerri.ytdlnis.database.dao.DownloadDao
|
import com.deniscerri.ytdlnis.database.dao.DownloadDao
|
||||||
|
import com.deniscerri.ytdlnis.database.dao.FormatDao
|
||||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
|
import com.deniscerri.ytdlnis.database.models.Format
|
||||||
|
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||||
|
|
||||||
class DownloadRepository(private val downloadDao: DownloadDao) {
|
class DownloadRepository(private val downloadDao: DownloadDao) {
|
||||||
val allDownloads : LiveData<List<DownloadItem>> = downloadDao.getAllDownloads()
|
val allDownloads : LiveData<List<DownloadItem>> = downloadDao.getAllDownloads()
|
||||||
val activeDownloads : LiveData<List<DownloadItem>> = downloadDao.getActiveDownloads()
|
val activeDownloads : LiveData<List<DownloadItem>> = downloadDao.getActiveDownloads()
|
||||||
|
val queuedDownloads : LiveData<List<DownloadItem>> = downloadDao.getQueuedDownloads()
|
||||||
|
val processingDownloads : LiveData<List<DownloadItem>> = downloadDao.getProcessingDownloads()
|
||||||
|
|
||||||
enum class status {
|
enum class status {
|
||||||
Active, Queued, Errored, Processing
|
Active, Queued, Errored, Processing
|
||||||
|
|
@ -29,9 +34,6 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
||||||
return downloadDao.getDownloadByWorkId(workID)
|
return downloadDao.getDownloadByWorkId(workID)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getQueuedDownloads() : List<DownloadItem>{
|
|
||||||
return downloadDao.getQueuedDownloads()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setDownloadStatus(item: DownloadItem, status: status){
|
suspend fun setDownloadStatus(item: DownloadItem, status: status){
|
||||||
item.status = status.toString()
|
item.status = status.toString()
|
||||||
|
|
@ -42,4 +44,7 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
||||||
return downloadDao.getDownloadById(id)
|
return downloadDao.getDownloadById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun deleteProcessing(){
|
||||||
|
downloadDao.deleteProcessing()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,24 +1,35 @@
|
||||||
package com.deniscerri.ytdlnis.database.viewmodel
|
package com.deniscerri.ytdlnis.database.viewmodel
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.deniscerri.ytdlnis.App
|
||||||
import com.deniscerri.ytdlnis.database.DBManager
|
import com.deniscerri.ytdlnis.database.DBManager
|
||||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
|
import com.deniscerri.ytdlnis.database.models.Format
|
||||||
|
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class DownloadViewModel(application: Application) : AndroidViewModel(application) {
|
class DownloadViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
private val repository : DownloadRepository
|
private val repository : DownloadRepository
|
||||||
private val allDownloads : LiveData<List<DownloadItem>>
|
val allDownloads : LiveData<List<DownloadItem>>
|
||||||
|
val queuedDownloads : LiveData<List<DownloadItem>>
|
||||||
|
val activeDownloads : LiveData<List<DownloadItem>>
|
||||||
|
val processingDownloads : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val dao = DBManager.getInstance(application).downloadDao
|
val dao = DBManager.getInstance(application).downloadDao
|
||||||
|
val formatDao = DBManager.getInstance(application).formatDao
|
||||||
repository = DownloadRepository(dao)
|
repository = DownloadRepository(dao)
|
||||||
allDownloads = repository.allDownloads
|
allDownloads = repository.allDownloads
|
||||||
|
queuedDownloads = repository.queuedDownloads
|
||||||
|
activeDownloads = repository.activeDownloads
|
||||||
|
processingDownloads = repository.processingDownloads
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startWork(items: List<DownloadItem>){
|
fun startWork(items: List<DownloadItem>){
|
||||||
|
|
@ -48,4 +59,51 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
||||||
fun getItemByID(id: Long) : DownloadItem {
|
fun getItemByID(id: Long) : DownloadItem {
|
||||||
return repository.getItemByID(id)
|
return repository.getItemByID(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createDownloadItemFromResult(resultItem: ResultItem, type: String) : DownloadItem {
|
||||||
|
val sharedPreferences =
|
||||||
|
getApplication<App>().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||||
|
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||||
|
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
||||||
|
val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||||
|
|
||||||
|
return DownloadItem(0,
|
||||||
|
resultItem.url,
|
||||||
|
resultItem.title,
|
||||||
|
resultItem.author,
|
||||||
|
resultItem.thumb,
|
||||||
|
resultItem.duration,
|
||||||
|
type,
|
||||||
|
"", "", 0, "", false,
|
||||||
|
"", resultItem.website, "", resultItem.playlistTitle, embedSubs, addChapters, saveThumb, "",
|
||||||
|
"", DownloadRepository.status.Processing.toString(), 0
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun turnResultItemstoDownloadItems(items: List<ResultItem?>) : List<DownloadItem> {
|
||||||
|
val list : MutableList<DownloadItem> = mutableListOf()
|
||||||
|
items.forEach {
|
||||||
|
list.add(createDownloadItemFromResult(it!!, "video"))
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
fun putDownloadsForProcessing(items: List<ResultItem?>) : LiveData<List<Long>> {
|
||||||
|
val result = MutableLiveData<List<Long>>()
|
||||||
|
viewModelScope.launch(Dispatchers.IO){
|
||||||
|
val list : MutableList<Long> = mutableListOf()
|
||||||
|
items.forEachIndexed { i, it ->
|
||||||
|
val tmpDownloadItem = createDownloadItemFromResult(it!!, "video")
|
||||||
|
val id = repository.insert(tmpDownloadItem)
|
||||||
|
list.add(id)
|
||||||
|
}
|
||||||
|
result.postValue(list)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteProcessing() = viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
repository.deleteProcessing()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -10,6 +10,7 @@ import com.deniscerri.ytdlnis.database.DBManager
|
||||||
import com.deniscerri.ytdlnis.database.dao.FormatDao
|
import com.deniscerri.ytdlnis.database.dao.FormatDao
|
||||||
import com.deniscerri.ytdlnis.database.models.Format
|
import com.deniscerri.ytdlnis.database.models.Format
|
||||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||||
|
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||||
import com.deniscerri.ytdlnis.database.repository.ResultRepository
|
import com.deniscerri.ytdlnis.database.repository.ResultRepository
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -111,7 +112,7 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
||||||
"video" -> {
|
"video" -> {
|
||||||
list = list.filter { !it.format_note.contains("audio", ignoreCase = true) }
|
list = list.filter { !it.format_note.contains("audio", ignoreCase = true) }
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
videoFormats.forEach { formats.add(Format(0, item.id, it, "", 0, it, "")) }
|
videoFormats.forEach { formats.add(Format(0, item.id, it, "", 0, it)) }
|
||||||
return formats
|
return formats
|
||||||
}
|
}
|
||||||
return list
|
return list
|
||||||
|
|
@ -120,7 +121,7 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
||||||
|
|
||||||
val templates = repository.getTemplates()
|
val templates = repository.getTemplates()
|
||||||
templates.forEach {
|
templates.forEach {
|
||||||
formats.add(Format(0, item.id, it.title, "", 0, it.content, ""))
|
formats.add(Format(0, item.id, it.title, "", 0, it.content))
|
||||||
}
|
}
|
||||||
return formats
|
return formats
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ import java.util.*
|
||||||
class DownloadInfo {
|
class DownloadInfo {
|
||||||
var video: ResultItem? = null
|
var video: ResultItem? = null
|
||||||
var progress = 0
|
var progress = 0
|
||||||
var downloadQueue: LinkedList<ResultItem>? = null
|
//var downloadQueue: LinkedList<ResultItem>? = null
|
||||||
var outputLine: String? = null
|
var outputLine: String? = null
|
||||||
var downloadStatus: String? = null
|
var downloadStatus: String? = null
|
||||||
var downloadPath: String? = null
|
var downloadPath: String? = null
|
||||||
var downloadType: String? = null
|
var downloadType: String? = null
|
||||||
fun setDownloadQueue(downloadQueue: LinkedList<ResultItem>) {
|
// fun setDownloadQueue(downloadQueue: LinkedList<ResultItem>) {
|
||||||
this.downloadQueue = downloadQueue
|
// this.downloadQueue = downloadQueue
|
||||||
video = downloadQueue.peek()
|
// video = downloadQueue.peek()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
@ -23,13 +23,16 @@ import com.deniscerri.ytdlnis.MainActivity
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
import com.deniscerri.ytdlnis.adapter.HomeAdapter
|
import com.deniscerri.ytdlnis.adapter.HomeAdapter
|
||||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
|
import com.deniscerri.ytdlnis.database.models.Format
|
||||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||||
|
import com.deniscerri.ytdlnis.database.models.ResultItemWithFormats
|
||||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||||
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||||
import com.deniscerri.ytdlnis.service.DownloadInfo
|
import com.deniscerri.ytdlnis.service.DownloadInfo
|
||||||
import com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog
|
import com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog
|
||||||
|
import com.deniscerri.ytdlnis.ui.downloadcard.DownloadMultipleBottomSheetDialog
|
||||||
import com.deniscerri.ytdlnis.util.FileUtil
|
import com.deniscerri.ytdlnis.util.FileUtil
|
||||||
import com.deniscerri.ytdlnis.util.InfoUtil
|
import com.deniscerri.ytdlnis.util.InfoUtil
|
||||||
import com.facebook.shimmer.ShimmerFrameLayout
|
import com.facebook.shimmer.ShimmerFrameLayout
|
||||||
|
|
@ -42,6 +45,7 @@ import com.google.android.material.floatingactionbutton.ExtendedFloatingActionBu
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickListener {
|
class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickListener {
|
||||||
private var progressBar: LinearProgressIndicator? = null
|
private var progressBar: LinearProgressIndicator? = null
|
||||||
|
|
@ -166,12 +170,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
homeFabs = view.findViewById(R.id.home_fabs)
|
homeFabs = view.findViewById(R.id.home_fabs)
|
||||||
downloadFabs = homeFabs!!.findViewById(R.id.download_selected_coordinator)
|
downloadFabs = homeFabs!!.findViewById(R.id.download_selected_coordinator)
|
||||||
downloadAllFabCoordinator = homeFabs!!.findViewById(R.id.download_all_coordinator)
|
downloadAllFabCoordinator = homeFabs!!.findViewById(R.id.download_all_coordinator)
|
||||||
val musicFab = downloadFabs!!.findViewById<FloatingActionButton>(R.id.audio_fab)
|
val downloadSelectedFab = downloadFabs!!.findViewById<ExtendedFloatingActionButton>(R.id.download_selected_fab)
|
||||||
val videoFab = downloadFabs!!.findViewById<FloatingActionButton>(R.id.video_fab)
|
downloadSelectedFab.tag = "downloadSelected"
|
||||||
musicFab.tag = "SELECT##audio"
|
downloadSelectedFab.setOnClickListener(this)
|
||||||
videoFab.tag = "SELECT##video"
|
|
||||||
musicFab.setOnClickListener(this)
|
|
||||||
videoFab.setOnClickListener(this)
|
|
||||||
val downloadAllFab =
|
val downloadAllFab =
|
||||||
downloadAllFabCoordinator!!.findViewById<ExtendedFloatingActionButton>(R.id.download_all_fab)
|
downloadAllFabCoordinator!!.findViewById<ExtendedFloatingActionButton>(R.id.download_all_fab)
|
||||||
downloadAllFab.tag = "downloadAll"
|
downloadAllFab.tag = "downloadAll"
|
||||||
|
|
@ -359,25 +360,11 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showSingleDownloadSheet(resultItem : ResultItem, type: String){
|
private fun showSingleDownloadSheet(resultItem : ResultItem, type: String){
|
||||||
val sharedPreferences =
|
val item = ResultItemWithFormats(
|
||||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
resultItem,
|
||||||
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
resultViewModel.getFormats(resultItem, "video") as ArrayList<Format>
|
||||||
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
|
||||||
val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false)
|
|
||||||
|
|
||||||
|
|
||||||
val downloadItem = DownloadItem(0,
|
|
||||||
resultItem.url,
|
|
||||||
resultItem.title,
|
|
||||||
resultItem.author,
|
|
||||||
resultItem.thumb,
|
|
||||||
resultItem.duration,
|
|
||||||
type,
|
|
||||||
"", "", 0, "", false,
|
|
||||||
"", resultItem.website, "", resultItem.playlistTitle, embedSubs, addChapters, saveThumb, "",
|
|
||||||
"", DownloadRepository.status.Processing.toString(), 0
|
|
||||||
)
|
)
|
||||||
|
val downloadItem = downloadViewModel.createDownloadItemFromResult(resultItem, "video")
|
||||||
downloadViewModel.insertDownload(downloadItem).observe(viewLifecycleOwner) {
|
downloadViewModel.insertDownload(downloadItem).observe(viewLifecycleOwner) {
|
||||||
downloadItem.id = it
|
downloadItem.id = it
|
||||||
val bottomSheet = DownloadBottomSheetDialog(downloadItem)
|
val bottomSheet = DownloadBottomSheetDialog(downloadItem)
|
||||||
|
|
@ -428,51 +415,27 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
override fun onClick(v: View) {
|
override fun onClick(v: View) {
|
||||||
val viewIdName: String = try {
|
val viewIdName: String = try {
|
||||||
v.tag.toString()
|
v.tag.toString()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {""}
|
||||||
""
|
|
||||||
}
|
|
||||||
if (viewIdName.isNotEmpty()) {
|
if (viewIdName.isNotEmpty()) {
|
||||||
if (viewIdName.contains("audio") || viewIdName.contains("video")) {
|
if (viewIdName == "downloadSelected") {
|
||||||
val buttonData =
|
val downloadList = downloadViewModel.turnResultItemstoDownloadItems(selectedObjects!!)
|
||||||
viewIdName.split("##".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
downloadViewModel.putDownloadsForProcessing(selectedObjects!!).observe(viewLifecycleOwner) {
|
||||||
if (buttonData[0] == "SELECT") {
|
it.forEachIndexed { i, itemID ->
|
||||||
initSelectedDownload(buttonData[1])
|
downloadList[i].id = itemID
|
||||||
|
}
|
||||||
|
val bottomSheet = DownloadMultipleBottomSheetDialog(downloadList)
|
||||||
|
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (viewIdName == "downloadAll") {
|
if (viewIdName == "downloadAll") {
|
||||||
// //remove previously selected
|
val downloadList = downloadViewModel.turnResultItemstoDownloadItems(resultsList!!)
|
||||||
// for (i in selectedObjects!!.indices) {
|
downloadViewModel.putDownloadsForProcessing(resultsList!!).observe(viewLifecycleOwner) {
|
||||||
// val vid = findVideo(
|
it.forEachIndexed { i, itemID ->
|
||||||
// selectedObjects!![i].url
|
downloadList[i].id = itemID
|
||||||
// )
|
}
|
||||||
// homeAdapter!!.notifyItemChanged(resultsList!!.indexOf(vid))
|
val bottomSheet = DownloadMultipleBottomSheetDialog(downloadList)
|
||||||
// }
|
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
|
||||||
// selectedObjects = ArrayList()
|
}
|
||||||
// downloadFabs!!.visibility = GONE
|
|
||||||
// bottomSheet = BottomSheetDialog(fragmentContext!!)
|
|
||||||
// bottomSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
|
||||||
// bottomSheet!!.setContentView(R.layout.home_download_all_bottom_sheet)
|
|
||||||
// val first = bottomSheet!!.findViewById<TextInputLayout>(R.id.first_textinput)
|
|
||||||
// first!!.editText!!.setText(1.toString())
|
|
||||||
// val last = bottomSheet!!.findViewById<TextInputLayout>(R.id.last_textinput)
|
|
||||||
// last!!.editText!!.setText(resultsList!!.size.toString())
|
|
||||||
// val audio = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_audio_button)
|
|
||||||
// audio!!.setOnClickListener {
|
|
||||||
// val start = first.editText!!.text.toString().toInt()
|
|
||||||
// val end = last.editText!!.text.toString().toInt()
|
|
||||||
// initDownloadAll(bottomSheet!!, start, end, "audio")
|
|
||||||
// }
|
|
||||||
// val video = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_video_button)
|
|
||||||
// video!!.setOnClickListener {
|
|
||||||
// val start = first.editText!!.text.toString().toInt()
|
|
||||||
// val end = last.editText!!.text.toString().toInt()
|
|
||||||
// initDownloadAll(bottomSheet!!, start, end, "video")
|
|
||||||
// }
|
|
||||||
// bottomSheet!!.show()
|
|
||||||
// bottomSheet!!.window!!.setLayout(
|
|
||||||
// ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
// ViewGroup.LayoutParams.MATCH_PARENT
|
|
||||||
// )
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -518,31 +481,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initSelectedDownload(type: String) {
|
|
||||||
// val sharedPreferences =
|
|
||||||
// context!!.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
|
||||||
// val editor = sharedPreferences.edit()
|
|
||||||
// if (sharedPreferences.getBoolean("download_card", true)) {
|
|
||||||
// showConfigureDownloadCard(type)
|
|
||||||
// } else {
|
|
||||||
// for (i in selectedObjects!!.indices) {
|
|
||||||
// val vid = findVideo(
|
|
||||||
// selectedObjects!![i]!!.getURL()
|
|
||||||
// )
|
|
||||||
// vid!!.downloadedType = type
|
|
||||||
// updateDownloadingStatusOnResult(vid, type, true)
|
|
||||||
// homeAdapter!!.notifyItemChanged(resultsList!!.indexOf(vid))
|
|
||||||
// downloadQueue!!.add(vid)
|
|
||||||
// }
|
|
||||||
// selectedObjects = ArrayList()
|
|
||||||
// homeAdapter!!.clearCheckedVideos()
|
|
||||||
// downloadFabs!!.visibility = View.GONE
|
|
||||||
// if (isStoragePermissionGranted) {
|
|
||||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
|
||||||
// downloadQueue!!.clear()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "HomeFragment"
|
private const val TAG = "HomeFragment"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
package com.deniscerri.ytdlnis.ui.downloadcard
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.Button
|
||||||
|
import androidx.fragment.app.FragmentTransaction
|
||||||
|
import androidx.fragment.app.findFragment
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
|
import com.deniscerri.ytdlnis.R
|
||||||
|
import com.deniscerri.ytdlnis.adapter.ConfigureMultipleDownloadsAdapter
|
||||||
|
import com.deniscerri.ytdlnis.adapter.HomeAdapter
|
||||||
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
|
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||||
|
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
|
||||||
|
class DownloadMultipleBottomSheetDialog(private val items: List<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener {
|
||||||
|
private lateinit var downloadViewModel: DownloadViewModel
|
||||||
|
private lateinit var listAdapter : ConfigureMultipleDownloadsAdapter
|
||||||
|
private lateinit var recyclerView: RecyclerView
|
||||||
|
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
val behavior = BottomSheetBehavior.from(view.parent as View)
|
||||||
|
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
override fun setupDialog(dialog: Dialog, style: Int) {
|
||||||
|
super.setupDialog(dialog, style)
|
||||||
|
val view = LayoutInflater.from(context).inflate(R.layout.download_multiple_bottom_sheet, null)
|
||||||
|
dialog.setContentView(view)
|
||||||
|
view.minimumHeight = resources.displayMetrics.heightPixels
|
||||||
|
|
||||||
|
listAdapter =
|
||||||
|
ConfigureMultipleDownloadsAdapter(
|
||||||
|
this,
|
||||||
|
requireActivity()
|
||||||
|
)
|
||||||
|
|
||||||
|
recyclerView = view.findViewById(R.id.downloadMultipleRecyclerview)
|
||||||
|
recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
recyclerView.setHasFixedSize(true)
|
||||||
|
recyclerView.adapter = listAdapter
|
||||||
|
|
||||||
|
downloadViewModel.processingDownloads.observe(this) {
|
||||||
|
listAdapter.submitList(it)
|
||||||
|
if (it.isEmpty()){
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val cancelBtn = view.findViewById<MaterialButton>(R.id.bottomsheet_cancel_button)
|
||||||
|
cancelBtn.setOnClickListener{
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
val download = view.findViewById<Button>(R.id.bottomsheet_download_button)
|
||||||
|
download!!.setOnClickListener {
|
||||||
|
// for (i in selectedObjects!!.indices) {
|
||||||
|
// val vid = findVideo(
|
||||||
|
// selectedObjects!![i]!!.getURL()
|
||||||
|
// )
|
||||||
|
// vid!!.downloadedType = type
|
||||||
|
// updateDownloadingStatusOnResult(vid, type, true)
|
||||||
|
// homeAdapter!!.notifyItemChanged(resultsList!!.indexOf(vid))
|
||||||
|
// downloadQueue!!.add(vid)
|
||||||
|
// }
|
||||||
|
// selectedObjects = ArrayList()
|
||||||
|
// homeAdapter!!.clearCheckedVideos()
|
||||||
|
// downloadFabs!!.visibility = View.GONE
|
||||||
|
// if (isStoragePermissionGranted) {
|
||||||
|
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||||
|
// downloadQueue!!.clear()
|
||||||
|
// }
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCancel(dialog: DialogInterface) {
|
||||||
|
super.onCancel(dialog)
|
||||||
|
cleanDownloads()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
cleanDownloads()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cleanDownloads(){
|
||||||
|
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadMultipleSheet")!!).commit()
|
||||||
|
downloadViewModel.deleteProcessing()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onButtonClick(videoURL: String, type: String?) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCardClick(itemID: Long) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(p0: View?) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -177,10 +177,9 @@ class DownloadWorker(
|
||||||
YoutubeDL.getInstance().execute(request, downloadItem.id.toString()){ progress, _, line ->
|
YoutubeDL.getInstance().execute(request, downloadItem.id.toString()){ progress, _, line ->
|
||||||
setProgressAsync(workDataOf("progress" to progress.toInt()))
|
setProgressAsync(workDataOf("progress" to progress.toInt()))
|
||||||
val title: String = downloadItem.title
|
val title: String = downloadItem.title
|
||||||
val queue = dao.getQueuedDownloads()
|
|
||||||
notificationUtil.updateDownloadNotification(
|
notificationUtil.updateDownloadNotification(
|
||||||
workID,
|
workID,
|
||||||
line, progress.toInt(), queue.size, title,
|
line, progress.toInt(), 0, title,
|
||||||
NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,37 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout 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:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/downloads_card_constraintLayout"
|
android:id="@+id/downloads_card_constraintLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/materialButton"
|
android:id="@+id/materialButton"
|
||||||
style="@style/Widget.Material3.Button.IconButton"
|
style="@style/Widget.Material3.Button.IconButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="28dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:padding="0dp"
|
android:padding="0dp"
|
||||||
app:icon="@drawable/ic_handle" />
|
app:icon="@drawable/ic_handle"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/download_card_view"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/download_card_view"
|
android:id="@+id/download_card_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="95dp"
|
android:layout_height="100dp"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
android:checkable="true"
|
android:checkable="true"
|
||||||
app:cardCornerRadius="10dp"
|
app:cardCornerRadius="10dp"
|
||||||
app:cardElevation="10dp"
|
|
||||||
app:cardMaxElevation="12dp"
|
app:cardMaxElevation="12dp"
|
||||||
app:cardPreventCornerOverlap="true"
|
app:cardPreventCornerOverlap="true"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/materialButton"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:strokeWidth="0dp">
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
|
|
@ -55,60 +56,59 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/title"
|
android:id="@+id/title_author"
|
||||||
android:layout_width="296dp"
|
android:layout_width="300dp"
|
||||||
android:layout_height="41dp"
|
android:layout_height="70dp"
|
||||||
android:paddingStart="10dp"
|
android:orientation="vertical"
|
||||||
android:paddingTop="10dp"
|
|
||||||
android:paddingEnd="10dp"
|
|
||||||
android:shadowColor="@color/black"
|
|
||||||
android:shadowDx="4"
|
|
||||||
android:shadowDy="4"
|
|
||||||
android:shadowRadius="2"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="17sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/downloads_download_button_type"
|
app:layout_constraintEnd_toStartOf="@+id/downloads_download_button_type"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingEnd="10dp"
|
||||||
|
android:shadowColor="@color/black"
|
||||||
|
android:shadowDx="4"
|
||||||
|
android:shadowDy="4"
|
||||||
|
android:shadowRadius="2"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/author"
|
||||||
|
android:layout_width="296dp"
|
||||||
|
android:layout_height="23dp"
|
||||||
|
android:gravity="bottom"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:shadowColor="@color/black"
|
||||||
|
android:shadowDx="4"
|
||||||
|
android:shadowDy="4"
|
||||||
|
android:shadowRadius="1.5"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/author"
|
|
||||||
android:layout_width="296dp"
|
|
||||||
android:layout_height="23dp"
|
|
||||||
android:gravity="bottom"
|
|
||||||
android:paddingStart="10dp"
|
|
||||||
android:paddingEnd="10dp"
|
|
||||||
android:paddingBottom="5dp"
|
|
||||||
android:shadowColor="@color/black"
|
|
||||||
android:shadowDx="4"
|
|
||||||
android:shadowDy="4"
|
|
||||||
android:shadowRadius="1.5"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/downloads_download_button_type"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/title" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/container"
|
android:id="@+id/container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
|
android:text="Mp4"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintEnd_toStartOf="@+id/filesize"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/author"
|
app:layout_constraintTop_toBottomOf="@+id/downloads_download_button_type" />
|
||||||
app:layout_constraintVertical_bias="1.0" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/encoding"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/container" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/filesize"
|
android:id="@+id/filesize"
|
||||||
|
|
@ -116,7 +116,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/encoding" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/downloads_download_button_type"
|
android:id="@+id/downloads_download_button_type"
|
||||||
|
|
@ -124,15 +124,16 @@
|
||||||
android:layout_width="55dp"
|
android:layout_width="55dp"
|
||||||
android:layout_height="55dp"
|
android:layout_height="55dp"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
app:cornerRadius="10dp"
|
app:cornerRadius="10dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.155" />
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout 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"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical">
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraintLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="10dp">
|
android:padding="10dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/bottom_sheet_title"
|
android:id="@+id/bottom_sheet_title"
|
||||||
|
|
@ -48,22 +52,44 @@
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
android:id="@+id/download_multiple_recyclerview"
|
android:id="@+id/coordinatorLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/constraintLayout">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/relativeLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/downloadMultipleRecyclerview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="150dp"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
|
android:orientation="horizontal"
|
||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
android:orientation="horizontal">
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
|
||||||
android:id="@+id/bottomsheet_schedule_button"
|
android:id="@+id/bottomsheet_schedule_button"
|
||||||
|
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
|
|
@ -77,25 +103,25 @@
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
|
||||||
android:id="@+id/bottomsheet_cancel_button"
|
android:id="@+id/bottomsheet_cancel_button"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/cancel"
|
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
|
android:text="@string/cancel"
|
||||||
app:icon="@drawable/ic_cancel" />
|
app:icon="@drawable/ic_cancel" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
|
|
||||||
android:id="@+id/bottomsheet_download_button"
|
android:id="@+id/bottomsheet_download_button"
|
||||||
|
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:autoLink="all"
|
||||||
android:text="@string/download"
|
android:text="@string/download"
|
||||||
app:icon="@drawable/ic_down"
|
app:icon="@drawable/ic_down" />
|
||||||
android:autoLink="all"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -122,42 +122,16 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
|
android:id="@+id/download_selected_fab"
|
||||||
|
app:elevation="0dp"
|
||||||
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"
|
||||||
app:cardCornerRadius="20dp"
|
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
>
|
app:icon="@drawable/ic_down"
|
||||||
|
android:text="@string/download"
|
||||||
<LinearLayout
|
app:srcCompat="@drawable/ic_music"/>
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?attr/colorPrimaryContainer"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
android:id="@+id/audio_fab"
|
|
||||||
app:elevation="0dp"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom|end"
|
|
||||||
android:layout_marginRight="5dp"
|
|
||||||
app:srcCompat="@drawable/ic_music"/>
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
android:id="@+id/video_fab"
|
|
||||||
app:elevation="0dp"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom|end"
|
|
||||||
android:layout_marginLeft="5dp"
|
|
||||||
app:srcCompat="@drawable/ic_video"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue