implemented fetching common formats for a playlist (WIP)
This commit is contained in:
parent
a91110d23e
commit
81a47c3407
18 changed files with 320 additions and 175 deletions
|
|
@ -4,6 +4,7 @@ import android.app.Activity
|
|||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Resources
|
||||
import android.net.ConnectivityManager
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
|
|
@ -24,7 +25,7 @@ import kotlinx.coroutines.launch
|
|||
import kotlinx.coroutines.withContext
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class DownloadViewModel(application: Application) : AndroidViewModel(application) {
|
||||
class DownloadViewModel(private val application: Application) : AndroidViewModel(application) {
|
||||
private val repository : DownloadRepository
|
||||
private val sharedPreferences: SharedPreferences
|
||||
private val commandTemplateDao: CommandTemplateDao
|
||||
|
|
@ -213,19 +214,39 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
}
|
||||
else -> {
|
||||
val c = commandTemplateDao.getFirst()
|
||||
return Format(
|
||||
c.title,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
c.content.replace("\n", " ")
|
||||
)
|
||||
return generateCommandFormat(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun generateCommandFormat(c: CommandTemplate) : Format {
|
||||
return Format(
|
||||
c.title,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
c.content.replace("\n", " ")
|
||||
)
|
||||
}
|
||||
|
||||
fun getGenericAudioFormats() : MutableList<Format>{
|
||||
val audioFormats = application.resources.getStringArray(R.array.audio_formats)
|
||||
val formats = mutableListOf<Format>()
|
||||
val containerPreference = sharedPreferences.getString("audio_format", "Default")
|
||||
audioFormats.forEach { formats.add(Format(it, containerPreference!!,"","", "",0, it)) }
|
||||
return formats
|
||||
}
|
||||
|
||||
fun getGenericVideoFormats() : MutableList<Format>{
|
||||
val videoFormats = application.resources.getStringArray(R.array.video_formats)
|
||||
val formats = mutableListOf<Format>()
|
||||
val containerPreference = sharedPreferences.getString("video_format", "Default")
|
||||
videoFormats.forEach { formats.add(Format(it, containerPreference!!,"","", "",0, it)) }
|
||||
return formats
|
||||
}
|
||||
|
||||
fun getLatestCommandTemplateAsFormat() : Format {
|
||||
val t = commandTemplateDao.getFirst()
|
||||
return Format(t.title, "", "", "", "", 0, t.content)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
|
|||
private lateinit var onDownloadItemUpdateListener: OnDownloadItemUpdateListener
|
||||
private lateinit var uiUtil: UiUtil
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
|
|
@ -71,7 +70,7 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
|
|||
behavior = BottomSheetBehavior.from(view.parent as View)
|
||||
val displayMetrics = DisplayMetrics()
|
||||
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||
behavior.peekHeight = displayMetrics.heightPixels - 700
|
||||
behavior.peekHeight = displayMetrics.heightPixels - 400
|
||||
}
|
||||
|
||||
tabLayout = view.findViewById(R.id.download_tablayout)
|
||||
|
|
@ -82,7 +81,7 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
|
|||
overScrollMode = View.OVER_SCROLL_NEVER
|
||||
}
|
||||
|
||||
val fragments = mutableListOf<Fragment>(DownloadAudioFragment(resultItem, downloadItem), DownloadVideoFragment(resultItem, downloadItem))
|
||||
val fragments = mutableListOf(DownloadAudioFragment(resultItem, downloadItem), DownloadVideoFragment(resultItem, downloadItem))
|
||||
var commandTemplateNr = 0
|
||||
lifecycleScope.launch{
|
||||
withContext(Dispatchers.IO){
|
||||
|
|
@ -211,10 +210,12 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
|
|||
// }
|
||||
|
||||
private fun cleanUp(){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("configureDownloadSingleSheet")!!).commit()
|
||||
for (i in 0 until viewPager2.adapter?.itemCount!!){
|
||||
if (parentFragmentManager.findFragmentByTag("f${i}") != null){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("f$i")!!).commit()
|
||||
kotlin.runCatching {
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("configureDownloadSingleSheet")!!).commit()
|
||||
for (i in 0 until viewPager2.adapter?.itemCount!!){
|
||||
if (parentFragmentManager.findFragmentByTag("f${i}") != null){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("f$i")!!).commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -570,9 +570,11 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list
|
|||
|
||||
|
||||
private fun cleanUp(){
|
||||
player.stop()
|
||||
cache.release()
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("cutVideoSheet")!!).commit()
|
||||
kotlin.runCatching {
|
||||
player.stop()
|
||||
cache.release()
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("cutVideoSheet")!!).commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,42 +123,40 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr
|
|||
|
||||
var formats = mutableListOf<Format>()
|
||||
formats.addAll(resultItem.formats.filter { it.format_note.contains("audio", ignoreCase = true) })
|
||||
val audioFormats = resources.getStringArray(R.array.audio_formats)
|
||||
if (formats.isEmpty()) formats.addAll(downloadItem.allFormats.filter { it.format_note.contains("audio", ignoreCase = true) })
|
||||
|
||||
val containers = requireContext().resources.getStringArray(R.array.audio_containers)
|
||||
val containerPreference = sharedPreferences.getString("audio_format", getString(R.string.defaultValue))
|
||||
val containerPreference = sharedPreferences.getString("audio_format", "Default")
|
||||
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
|
||||
val containerAutoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
|
||||
|
||||
if (formats.isEmpty()) {
|
||||
audioFormats.forEach { formats.add(Format(it, containerPreference!!,"","", "",0, it)) }
|
||||
}
|
||||
if (formats.isEmpty()) formats = downloadViewModel.getGenericAudioFormats()
|
||||
|
||||
val formatCard = view.findViewById<ConstraintLayout>(R.id.format_card_constraintLayout)
|
||||
val chosenFormat = downloadItem.format
|
||||
uiUtil.populateFormatCard(formatCard, chosenFormat)
|
||||
val listener = object : OnFormatClickListener {
|
||||
override fun onFormatClick(allFormats: List<Format>, item: Format) {
|
||||
downloadItem.format = item
|
||||
uiUtil.populateFormatCard(formatCard, item)
|
||||
if (containers.contains(item.container)){
|
||||
downloadItem.format.container = item.container
|
||||
containerAutoCompleteTextView.setText(item.container, false)
|
||||
override fun onFormatClick(allFormats: List<List<Format>>, item: List<Format>) {
|
||||
downloadItem.format = item.first()
|
||||
uiUtil.populateFormatCard(formatCard, item.first())
|
||||
if (containers.contains(item.first().container)){
|
||||
downloadItem.format.container = item.first().container
|
||||
containerAutoCompleteTextView.setText(item.first().container, false)
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO){
|
||||
resultItem.formats.removeAll(formats.toSet())
|
||||
resultItem.formats.addAll(allFormats)
|
||||
resultItem.formats.addAll(allFormats.first())
|
||||
resultViewModel.update(resultItem)
|
||||
}
|
||||
}
|
||||
formats = allFormats.toMutableList()
|
||||
formats = allFormats.first().toMutableList()
|
||||
}
|
||||
}
|
||||
formatCard.setOnClickListener{_ ->
|
||||
if (parentFragmentManager.findFragmentByTag("formatSheet") == null){
|
||||
val bottomSheet = FormatSelectionBottomSheetDialog(downloadItem, formats, listener)
|
||||
val bottomSheet = FormatSelectionBottomSheetDialog(listOf(downloadItem), listOf(formats), listener)
|
||||
bottomSheet.show(parentFragmentManager, "formatSheet")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.DBManager
|
||||
|
|
@ -30,6 +31,8 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayout.TabLayoutOnPageChangeListener
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
|
@ -64,7 +67,7 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
|
|||
behavior = BottomSheetBehavior.from(view.parent as View)
|
||||
val displayMetrics = DisplayMetrics()
|
||||
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||
behavior.peekHeight = displayMetrics.heightPixels - 700
|
||||
behavior.peekHeight = displayMetrics.heightPixels - 400
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -158,7 +161,6 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
|
|||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
val download = view.findViewById<Button>(R.id.bottomsheet_download_button)
|
||||
download!!.setOnClickListener {
|
||||
val item: DownloadItem = getDownloadItem();
|
||||
|
|
@ -208,14 +210,16 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
|
|||
|
||||
|
||||
private fun cleanUp(){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadSingleSheet")!!).commit()
|
||||
for (i in 0 until viewPager2.adapter?.itemCount!!){
|
||||
if (parentFragmentManager.findFragmentByTag("f${i}") != null){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("f$i")!!).commit()
|
||||
kotlin.runCatching {
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadSingleSheet")!!).commit()
|
||||
for (i in 0 until viewPager2.adapter?.itemCount!!){
|
||||
if (parentFragmentManager.findFragmentByTag("f${i}") != null){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("f$i")!!).commit()
|
||||
}
|
||||
}
|
||||
if (activity is ShareActivity){
|
||||
(activity as ShareActivity).finish()
|
||||
}
|
||||
}
|
||||
if (activity is ShareActivity){
|
||||
(activity as ShareActivity).finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import android.text.format.DateFormat
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.widget.Button
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.get
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
|
|
@ -21,6 +21,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.ConfigureMultipleDownloadsAdapter
|
||||
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.viewmodel.CommandTemplateViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
|
|
@ -34,7 +35,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
|||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -51,6 +51,7 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
private lateinit var behavior: BottomSheetBehavior<View>
|
||||
private lateinit var fileUtil: FileUtil
|
||||
private lateinit var uiUtil: UiUtil
|
||||
private lateinit var bottomAppBar: BottomAppBar
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
@ -68,7 +69,7 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@SuppressLint("RestrictedApi", "NotifyDataSetChanged")
|
||||
override fun setupDialog(dialog: Dialog, style: Int) {
|
||||
super.setupDialog(dialog, style)
|
||||
val view = LayoutInflater.from(context).inflate(R.layout.download_multiple_bottom_sheet, null)
|
||||
|
|
@ -116,7 +117,7 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
dismiss()
|
||||
}
|
||||
|
||||
val bottomAppBar = view.findViewById<BottomAppBar>(R.id.bottomAppBar)
|
||||
bottomAppBar = view.findViewById(R.id.bottomAppBar)
|
||||
val preferredDownloadType = bottomAppBar.menu.findItem(R.id.preferred_download_type)
|
||||
when(items.first().type){
|
||||
DownloadViewModel.Type.audio -> {
|
||||
|
|
@ -131,7 +132,19 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
}
|
||||
}
|
||||
|
||||
bottomAppBar!!.setOnMenuItemClickListener { m: MenuItem ->
|
||||
val formatListener = object : OnFormatClickListener {
|
||||
override fun onFormatClick(allFormats: List<List<Format>>, selectedFormats: List<Format>) {
|
||||
items.forEachIndexed { index, it ->
|
||||
it.allFormats.clear()
|
||||
it.allFormats.addAll(allFormats[index])
|
||||
it.format = selectedFormats[index]
|
||||
}
|
||||
listAdapter.submitList(items.toList())
|
||||
listAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
bottomAppBar.setOnMenuItemClickListener { m: MenuItem ->
|
||||
when (m.itemId) {
|
||||
R.id.folder -> {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||
|
|
@ -166,6 +179,7 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
listAdapter.submitList(items.toList())
|
||||
listAdapter.notifyDataSetChanged()
|
||||
preferredDownloadType.setIcon(R.drawable.baseline_audio_file_24)
|
||||
bottomAppBar.menu[2].icon?.alpha = 255
|
||||
bottomSheet.cancel()
|
||||
}
|
||||
|
||||
|
|
@ -174,6 +188,7 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
listAdapter.submitList(items.toList())
|
||||
listAdapter.notifyDataSetChanged()
|
||||
preferredDownloadType.setIcon(R.drawable.baseline_video_file_24)
|
||||
bottomAppBar.menu[2].icon?.alpha = 255
|
||||
bottomSheet.cancel()
|
||||
}
|
||||
|
||||
|
|
@ -185,11 +200,15 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
listAdapter.submitList(items.toList())
|
||||
listAdapter.notifyDataSetChanged()
|
||||
preferredDownloadType.setIcon(R.drawable.baseline_insert_drive_file_24)
|
||||
bottomAppBar.menu[2].icon?.alpha = 255
|
||||
bottomSheet.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
bottomSheet.show()
|
||||
val displayMetrics = DisplayMetrics()
|
||||
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||
bottomSheet.behavior.peekHeight = displayMetrics.heightPixels
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
|
|
@ -198,47 +217,48 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
|
||||
}
|
||||
R.id.format -> {
|
||||
if (results.first()!!.formats.isEmpty()){
|
||||
if (! items.all { it.type == items[0].type }){
|
||||
Toast.makeText(requireContext(), getString(R.string.format_filtering_hint), Toast.LENGTH_SHORT).show()
|
||||
}else{
|
||||
if (items.first().type == DownloadViewModel.Type.command){
|
||||
lifecycleScope.launch {
|
||||
uiUtil.showCommandTemplates(requireActivity(), commandTemplateViewModel) {
|
||||
val format = downloadViewModel.generateCommandFormat(it)
|
||||
items.forEach { f ->
|
||||
f.format = format
|
||||
}
|
||||
listAdapter.submitList(items.toList())
|
||||
listAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}else{
|
||||
lifecycleScope.launch {
|
||||
val flatFormatCollection = items.map { it.allFormats }.flatten()
|
||||
val commonFormats = withContext(Dispatchers.IO){
|
||||
flatFormatCollection.groupingBy { it.format_id }.eachCount().filter { it.value == items.size }.mapValues { flatFormatCollection.first { f -> f.format_id == it.key } }.map { it.value }
|
||||
}
|
||||
|
||||
val formats = if (commonFormats.isNotEmpty() && items.none{it.allFormats.isEmpty()}) {
|
||||
items.map { it.allFormats }
|
||||
}else{
|
||||
when(items.first().type){
|
||||
DownloadViewModel.Type.audio -> listOf<List<Format>>(downloadViewModel.getGenericAudioFormats())
|
||||
else -> listOf<List<Format>>(downloadViewModel.getGenericVideoFormats())
|
||||
}
|
||||
}
|
||||
val bottomSheet = FormatSelectionBottomSheetDialog(items, formats, formatListener)
|
||||
bottomSheet.show(parentFragmentManager, "formatSheet")
|
||||
}
|
||||
}
|
||||
}
|
||||
// val formatListCollection = items.map { it.format }
|
||||
// val commonFormats = getCommonFormats(formatListCollection)
|
||||
//
|
||||
// val listener = object : OnFormatClickListener {
|
||||
// override fun onFormatClick(allFormats: List<Format>, item: Format) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// if (parentFragmentManager.findFragmentByTag("formatSheet") == null){
|
||||
// val bottomSheet = FormatSelectionBottomSheetDialog(null, commonFormats.toList(), listener)
|
||||
// bottomSheet.show(parentFragmentManager, "formatSheet")
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
val itemsLiveData = items.asFlow()
|
||||
}
|
||||
|
||||
// private fun getCommonFormats(vararg lists: MutableList<List<Format>>): Set<Format> {
|
||||
// val commons: MutableList<Format> = mutableListOf()
|
||||
// commons.addAll(lists[1])
|
||||
// {
|
||||
// lists[1].forEach {
|
||||
// commons.retainAll(it)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (numbers in list) {
|
||||
// result = Sets.intersection(result, Sets.newHashSet(numbers))
|
||||
// }
|
||||
// return result
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
private var pathResultLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) { result ->
|
||||
|
|
@ -268,9 +288,11 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
}
|
||||
|
||||
private fun cleanup(){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadMultipleSheet")!!).commit()
|
||||
if (parentFragmentManager.fragments.size == 1){
|
||||
(activity as ShareActivity).finish()
|
||||
kotlin.runCatching {
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadMultipleSheet")!!).commit()
|
||||
if (parentFragmentManager.fragments.size == 1){
|
||||
(activity as ShareActivity).finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +320,11 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
override fun onDownloadItemUpdate(resultItemID: Long, item: DownloadItem) {
|
||||
val i = items.indexOf(items.find { it.url == item.url })
|
||||
items[i] = item
|
||||
Log.e("aa", items.toList().toString())
|
||||
if (! items.all { it.type == items[0].type }){
|
||||
bottomAppBar.menu[2].icon?.alpha = 30
|
||||
}else{
|
||||
bottomAppBar.menu[2].icon?.alpha = 255
|
||||
}
|
||||
listAdapter.submitList(items.toList())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,44 +129,42 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
|
|||
|
||||
var formats = mutableListOf<Format>()
|
||||
formats.addAll(resultItem.formats.filter { !it.format_note.contains("audio", ignoreCase = true) })
|
||||
val videoFormats = resources.getStringArray(R.array.video_formats)
|
||||
if (formats.isEmpty()) formats.addAll(downloadItem.allFormats.filter { !it.format_note.contains("audio", ignoreCase = true) })
|
||||
|
||||
val containers = requireContext().resources.getStringArray(R.array.video_containers)
|
||||
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
|
||||
val containerAutoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
|
||||
val containerPreference = sharedPreferences.getString("video_format", getString(R.string.defaultValue))
|
||||
val containerPreference = sharedPreferences.getString("video_format", "Default")
|
||||
|
||||
if (formats.isEmpty()) {
|
||||
videoFormats.forEach { formats.add(Format(it, containerPreference!!,"","", "",0, it)) }
|
||||
}
|
||||
if (formats.isEmpty()) formats = downloadViewModel.getGenericVideoFormats()
|
||||
|
||||
val formatCard = view.findViewById<ConstraintLayout>(R.id.format_card_constraintLayout)
|
||||
|
||||
val chosenFormat = downloadItem.format
|
||||
uiUtil.populateFormatCard(formatCard, chosenFormat)
|
||||
val listener = object : OnFormatClickListener {
|
||||
override fun onFormatClick(allFormats: List<Format>, item: Format) {
|
||||
downloadItem.format = item
|
||||
override fun onFormatClick(allFormats: List<List<Format>>, item: List<Format>) {
|
||||
downloadItem.format = item.first()
|
||||
|
||||
if (containers.contains(item.container)){
|
||||
downloadItem.format.container = item.container
|
||||
containerAutoCompleteTextView.setText(item.container, false)
|
||||
if (containers.contains(item.first().container)){
|
||||
downloadItem.format.container = item.first().container
|
||||
containerAutoCompleteTextView.setText(item.first().container, false)
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO){
|
||||
resultItem.formats.removeAll(formats.toSet())
|
||||
resultItem.formats.addAll(allFormats)
|
||||
resultItem.formats.addAll(allFormats.first())
|
||||
resultViewModel.update(resultItem)
|
||||
}
|
||||
}
|
||||
formats = allFormats.toMutableList()
|
||||
uiUtil.populateFormatCard(formatCard, item)
|
||||
formats = allFormats.first().toMutableList()
|
||||
uiUtil.populateFormatCard(formatCard, item.first())
|
||||
}
|
||||
}
|
||||
formatCard.setOnClickListener{
|
||||
if (parentFragmentManager.findFragmentByTag("formatSheet") == null){
|
||||
val bottomSheet = FormatSelectionBottomSheetDialog(downloadItem, formats, listener)
|
||||
val bottomSheet = FormatSelectionBottomSheetDialog(listOf(downloadItem), listOf(formats), listener)
|
||||
bottomSheet.show(parentFragmentManager, "formatSheet")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import android.app.Activity
|
|||
import android.app.Dialog
|
||||
import android.content.*
|
||||
import android.os.Bundle
|
||||
import android.os.Looper
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
|
|
@ -27,20 +28,25 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
class FormatSelectionBottomSheetDialog(private val item: DownloadItem?, private var formats: List<Format>, private val listener: OnFormatClickListener) : BottomSheetDialogFragment() {
|
||||
class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, private var formats: List<List<Format>>, private val listener: OnFormatClickListener) : BottomSheetDialogFragment() {
|
||||
private lateinit var behavior: BottomSheetBehavior<View>
|
||||
private lateinit var fileUtil: FileUtil
|
||||
private lateinit var infoUtil: InfoUtil
|
||||
private lateinit var uiUtil: UiUtil
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
private lateinit var formatCollection: MutableList<List<Format>>
|
||||
private lateinit var chosenFormats: List<Format>
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
fileUtil = FileUtil()
|
||||
uiUtil = UiUtil(fileUtil)
|
||||
infoUtil = InfoUtil(requireActivity().applicationContext)
|
||||
formatCollection = mutableListOf()
|
||||
chosenFormats = listOf()
|
||||
sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
}
|
||||
|
||||
|
|
@ -61,10 +67,35 @@ class FormatSelectionBottomSheetDialog(private val item: DownloadItem?, private
|
|||
val linearLayout = view.findViewById<LinearLayout>(R.id.format_list_linear_layout)
|
||||
val shimmers = view.findViewById<ShimmerFrameLayout>(R.id.format_list_shimmer)
|
||||
shimmers.visibility = View.GONE
|
||||
addFormatsToView(linearLayout)
|
||||
|
||||
if (items.size > 1){
|
||||
val hasGenericFormats = when(items.first()!!.type){
|
||||
Type.audio -> formats.flatten().size == resources.getStringArray(R.array.audio_formats).size
|
||||
else -> formats.flatten().size == resources.getStringArray(R.array.video_formats).size
|
||||
}
|
||||
if (!hasGenericFormats){
|
||||
formatCollection.addAll(formats)
|
||||
val flattenFormats = formats.flatten()
|
||||
val commonFormats = flattenFormats.groupingBy { it.format_id }.eachCount().filter { it.value == items.size }.mapValues { flattenFormats.first { f -> f.format_id == it.key } }.map { it.value }
|
||||
commonFormats.forEach {
|
||||
it.filesize =
|
||||
flattenFormats.filter { f -> f.format_id == it.format_id }
|
||||
.sumOf { itt -> itt.filesize }
|
||||
}
|
||||
chosenFormats = commonFormats
|
||||
}else{
|
||||
chosenFormats = formats.flatten()
|
||||
}
|
||||
addFormatsToView(linearLayout)
|
||||
}else{
|
||||
chosenFormats = formats.flatten()
|
||||
addFormatsToView(linearLayout)
|
||||
}
|
||||
|
||||
val refreshBtn = view.findViewById<Button>(R.id.format_refresh)
|
||||
if (formats.none { it.filesize == 0L } || item == null) refreshBtn.visibility = View.GONE
|
||||
if (formats.flatten().none { it.filesize == 0L } || items.isEmpty()) refreshBtn.visibility = View.GONE
|
||||
|
||||
|
||||
refreshBtn.setOnClickListener {
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
|
|
@ -73,15 +104,45 @@ class FormatSelectionBottomSheetDialog(private val item: DownloadItem?, private
|
|||
shimmers.visibility = View.VISIBLE
|
||||
shimmers.startShimmer()
|
||||
|
||||
val res = withContext(Dispatchers.IO){
|
||||
infoUtil.getFormats(item!!.url)
|
||||
//simple download
|
||||
if (items.size == 1){
|
||||
val res = withContext(Dispatchers.IO){
|
||||
infoUtil.getFormats(items.first()!!.url)
|
||||
}
|
||||
chosenFormats = res.formats.filter { it.filesize != 0L }
|
||||
chosenFormats = when(items.first()?.type){
|
||||
Type.audio -> chosenFormats.filter { it.format_note.contains("audio", ignoreCase = true) }
|
||||
else -> chosenFormats.filter { !it.format_note.contains("audio", ignoreCase = true) }
|
||||
}
|
||||
if (chosenFormats.isEmpty()) throw Exception()
|
||||
//playlist format filtering
|
||||
}else{
|
||||
var progress = "0/${items.size}"
|
||||
refreshBtn.text = progress
|
||||
withContext(Dispatchers.IO){
|
||||
infoUtil.getFormatsMultiple(items.map { it!!.url }) {
|
||||
lifecycleScope.launch(Dispatchers.Main){
|
||||
progress = "${formatCollection.size}/${items.size}"
|
||||
refreshBtn.text = progress
|
||||
}
|
||||
formatCollection.add(it)
|
||||
}
|
||||
}
|
||||
val flatFormatCollection = formatCollection.flatten()
|
||||
val commonFormats = flatFormatCollection.groupingBy { it.format_id }.eachCount().filter { it.value == items.size }.mapValues { flatFormatCollection.first { f -> f.format_id == it.key } }.map { it.value }
|
||||
chosenFormats = commonFormats.filter { it.filesize != 0L }.mapTo(mutableListOf()) {it.copy()}
|
||||
chosenFormats = when(items.first()?.type){
|
||||
Type.audio -> chosenFormats.filter { it.format_note.contains("audio", ignoreCase = true) }
|
||||
else -> chosenFormats.filter { !it.format_note.contains("audio", ignoreCase = true) }
|
||||
}
|
||||
if (chosenFormats.isEmpty()) throw Exception()
|
||||
chosenFormats.forEach {
|
||||
it.filesize =
|
||||
flatFormatCollection.filter { f -> f.format_id == it.format_id }
|
||||
.sumOf { itt -> itt.filesize }
|
||||
}
|
||||
}
|
||||
formats = res.formats.filter { it.filesize != 0L }
|
||||
formats = when(item?.type){
|
||||
Type.audio -> formats.filter { it.format_note.contains("audio", ignoreCase = true) }
|
||||
else -> formats.filter { !it.format_note.contains("audio", ignoreCase = true) }
|
||||
}
|
||||
if (formats.isEmpty()) throw Exception()
|
||||
|
||||
addFormatsToView(linearLayout)
|
||||
refreshBtn.visibility = View.GONE
|
||||
|
||||
|
|
@ -90,6 +151,7 @@ class FormatSelectionBottomSheetDialog(private val item: DownloadItem?, private
|
|||
shimmers.stopShimmer()
|
||||
}catch (e: Exception){
|
||||
refreshBtn.isEnabled = true
|
||||
refreshBtn.text = getString(R.string.update_formats)
|
||||
linearLayout.visibility = View.VISIBLE
|
||||
shimmers.visibility = View.GONE
|
||||
shimmers.stopShimmer()
|
||||
|
|
@ -99,20 +161,27 @@ class FormatSelectionBottomSheetDialog(private val item: DownloadItem?, private
|
|||
}
|
||||
}
|
||||
}
|
||||
if (sharedPreferences.getBoolean("update_formats", false) && refreshBtn.isVisible){
|
||||
if (sharedPreferences.getBoolean("update_formats", false) && refreshBtn.isVisible && items.size == 1){
|
||||
refreshBtn.performClick()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addFormatsToView(linearLayout: LinearLayout){
|
||||
linearLayout.removeAllViews()
|
||||
Log.e("aa", formats.toString())
|
||||
for (i in formats.lastIndex downTo 0){
|
||||
val format = formats[i]
|
||||
Log.e("aa", chosenFormats.toString())
|
||||
for (i in chosenFormats.lastIndex downTo 0){
|
||||
val format = chosenFormats[i]
|
||||
val formatItem = LayoutInflater.from(context).inflate(R.layout.format_item, null)
|
||||
uiUtil.populateFormatCard(formatItem as ConstraintLayout, format)
|
||||
formatItem.setOnClickListener{_ ->
|
||||
listener.onFormatClick(formats, format)
|
||||
if (items.size == 1){
|
||||
listener.onFormatClick(List(items.size){chosenFormats}, listOf(format))
|
||||
}else{
|
||||
val selectedFormats = mutableListOf<Format>()
|
||||
formatCollection.forEach {
|
||||
selectedFormats.add(it.first{ f -> f.format_id == format.format_id})
|
||||
}
|
||||
listener.onFormatClick(formatCollection, selectedFormats)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
formatItem.setOnLongClickListener {
|
||||
|
|
@ -141,10 +210,12 @@ class FormatSelectionBottomSheetDialog(private val item: DownloadItem?, private
|
|||
|
||||
|
||||
private fun cleanUp(){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("formatSheet")!!).commit()
|
||||
kotlin.runCatching {
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("formatSheet")!!).commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface OnFormatClickListener{
|
||||
fun onFormatClick(allFormats: List<Format>, item: Format)
|
||||
fun onFormatClick(allFormats: List<List<Format>>, item: List<Format>)
|
||||
}
|
||||
|
|
@ -179,9 +179,11 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem?>,
|
|||
}
|
||||
|
||||
private fun cleanup(){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadPlaylistSheet")!!).commit()
|
||||
if (parentFragmentManager.fragments.size == 1){
|
||||
(activity as ShareActivity).finish()
|
||||
kotlin.runCatching {
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadPlaylistSheet")!!).commit()
|
||||
if (parentFragmentManager.fragments.size == 1){
|
||||
(activity as ShareActivity).finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
|
|||
openFile.visibility = View.GONE
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.behavior.peekHeight = 512
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
|
|||
openFile.visibility = View.GONE
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.behavior.peekHeight = 512
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
|
|
|
|||
|
|
@ -483,6 +483,7 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
else redownload.visibility = GONE
|
||||
|
||||
bottomSheet!!.show()
|
||||
bottomSheet!!.behavior.peekHeight = 512
|
||||
bottomSheet!!.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
|
|
|
|||
|
|
@ -202,6 +202,7 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
|
|||
redownload!!.visibility = View.GONE
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.behavior.peekHeight = 512
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.work.*
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import com.deniscerri.ytdlnis.util.UiUtil
|
||||
import com.deniscerri.ytdlnis.work.TerminalDownloadWorker
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.bottomappbar.BottomAppBar
|
||||
|
|
@ -55,6 +57,7 @@ class TerminalActivity : AppCompatActivity() {
|
|||
private lateinit var downloadFile : File
|
||||
private lateinit var observer: FileObserver
|
||||
private lateinit var imm : InputMethodManager
|
||||
private lateinit var uiUtil: UiUtil
|
||||
var context: Context? = null
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
@ -65,6 +68,7 @@ class TerminalActivity : AppCompatActivity() {
|
|||
downloadFile = File(cacheDir.absolutePath + "/$downloadID.txt")
|
||||
if (! downloadFile.exists()) downloadFile.createNewFile()
|
||||
imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
uiUtil = UiUtil(FileUtil())
|
||||
|
||||
context = baseContext
|
||||
scrollView = findViewById(R.id.custom_command_scrollview)
|
||||
|
|
@ -89,7 +93,17 @@ class TerminalActivity : AppCompatActivity() {
|
|||
}
|
||||
bottomAppBar.setOnMenuItemClickListener {
|
||||
when(it.itemId){
|
||||
R.id.command_templates -> showCommandTemplates()
|
||||
R.id.command_templates -> {
|
||||
lifecycleScope.launch {
|
||||
uiUtil.showCommandTemplates(this@TerminalActivity, commandTemplateViewModel){ template ->
|
||||
input!!.text.insert(input!!.selectionStart, template.content + " ")
|
||||
input!!.postDelayed({
|
||||
input!!.requestFocus()
|
||||
imm.showSoftInput(input!!, 0)
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
}
|
||||
R.id.shortcuts -> showShortcuts()
|
||||
else -> {}
|
||||
}
|
||||
|
|
@ -210,41 +224,6 @@ class TerminalActivity : AppCompatActivity() {
|
|||
fab!!.setIconResource(R.drawable.ic_cancel)
|
||||
}
|
||||
|
||||
private fun showCommandTemplates(){
|
||||
lifecycleScope.launch {
|
||||
val bottomSheet = BottomSheetDialog(this@TerminalActivity)
|
||||
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet.setContentView(R.layout.command_template_list)
|
||||
|
||||
val linearLayout = bottomSheet.findViewById<LinearLayout>(R.id.command_list_linear_layout)
|
||||
val list = withContext(Dispatchers.IO){
|
||||
commandTemplateViewModel.getAll()
|
||||
}
|
||||
|
||||
linearLayout!!.removeAllViews()
|
||||
list.forEach {template ->
|
||||
val item = layoutInflater.inflate(R.layout.command_template_item, linearLayout, false) as ConstraintLayout
|
||||
item.findViewById<TextView>(R.id.title).text = template.title
|
||||
item.findViewById<TextView>(R.id.content).text = template.content
|
||||
item.setOnClickListener {
|
||||
input!!.text.insert(input!!.selectionStart, template.content + " ")
|
||||
bottomSheet.cancel()
|
||||
input!!.postDelayed({
|
||||
input!!.requestFocus()
|
||||
imm.showSoftInput(input!!, 0)
|
||||
}, 200)
|
||||
}
|
||||
linearLayout.addView(item)
|
||||
}
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showShortcuts() {
|
||||
lifecycleScope.launch {
|
||||
val bottomSheet = BottomSheetDialog(this@TerminalActivity)
|
||||
|
|
|
|||
|
|
@ -504,7 +504,7 @@ class InfoUtil(private val context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getFormatsTest(urls: List<String>, progress: (progress: List<Format>) -> Unit){
|
||||
fun getFormatsMultiple(urls: List<String>, progress: (progress: List<Format>) -> Unit){
|
||||
init()
|
||||
val urlsFile = File(context.cacheDir, "urls.txt")
|
||||
urlsFile.delete()
|
||||
|
|
@ -524,26 +524,30 @@ class InfoUtil(private val context: Context) {
|
|||
request.addOption("--cookies", cookiesFile.absolutePath)
|
||||
}
|
||||
|
||||
val youtubeDLResponse = YoutubeDL.getInstance().execute(request){ progress, _, line ->
|
||||
val formats = mutableListOf<Format>()
|
||||
val listOfStrings = JSONArray(line)
|
||||
for (f in 0 until listOfStrings.length()){
|
||||
val format = listOfStrings.get(f) as JSONObject
|
||||
try{
|
||||
if (format.getString("filesize") == "None") continue
|
||||
}catch (e: Exception) { continue }
|
||||
val formatProper = Gson().fromJson(format.toString(), Format::class.java)
|
||||
if (formatProper.filesize > 0){
|
||||
if ( !formatProper.format_note.contains("audio only", true)) {
|
||||
formatProper.format_note = format.getString("format_note")
|
||||
}else{
|
||||
formatProper.format_note = "${format.getString("format_note")} audio"
|
||||
YoutubeDL.getInstance().execute(request){ progress, _, line ->
|
||||
try{
|
||||
val formats = mutableListOf<Format>()
|
||||
val listOfStrings = JSONArray(line)
|
||||
for (f in 0 until listOfStrings.length()){
|
||||
val format = listOfStrings.get(f) as JSONObject
|
||||
try{
|
||||
if (format.getString("filesize") == "None") continue
|
||||
}catch (e: Exception) { continue }
|
||||
val formatProper = Gson().fromJson(format.toString(), Format::class.java)
|
||||
if (formatProper.filesize > 0){
|
||||
if ( !formatProper.format_note.contains("audio only", true)) {
|
||||
formatProper.format_note = format.getString("format_note")
|
||||
}else{
|
||||
formatProper.format_note = "${format.getString("format_note")} audio"
|
||||
}
|
||||
formatProper.container = format.getString("ext")
|
||||
formats.add(formatProper)
|
||||
}
|
||||
formatProper.container = format.getString("ext")
|
||||
formats.add(formatProper)
|
||||
}
|
||||
progress(formats)
|
||||
}catch (e: Exception){
|
||||
progress(emptyList())
|
||||
}
|
||||
progress(formats)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Looper.prepare().run {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
|
@ -21,6 +22,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
|||
import androidx.core.content.FileProvider
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.CommandTemplate
|
||||
import com.deniscerri.ytdlnis.database.models.Format
|
||||
|
|
@ -35,6 +37,9 @@ import com.google.android.material.datepicker.MaterialDatePicker
|
|||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.google.android.material.timepicker.MaterialTimePicker
|
||||
import com.google.android.material.timepicker.TimeFormat
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
|
|
@ -282,4 +287,33 @@ class UiUtil(private val fileUtil: FileUtil) {
|
|||
}
|
||||
datePicker.show(fragmentManager, "datepicker")
|
||||
}
|
||||
|
||||
suspend fun showCommandTemplates(activity: Activity, commandTemplateViewModel: CommandTemplateViewModel, itemSelected: (itemSelected: CommandTemplate) -> Unit) {
|
||||
val bottomSheet = BottomSheetDialog(activity)
|
||||
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet.setContentView(R.layout.command_template_list)
|
||||
|
||||
val linearLayout = bottomSheet.findViewById<LinearLayout>(R.id.command_list_linear_layout)
|
||||
val list = withContext(Dispatchers.IO){
|
||||
commandTemplateViewModel.getAll()
|
||||
}
|
||||
|
||||
linearLayout!!.removeAllViews()
|
||||
list.forEach {template ->
|
||||
val item = activity.layoutInflater.inflate(R.layout.command_template_item, linearLayout, false) as ConstraintLayout
|
||||
item.findViewById<TextView>(R.id.title).text = template.title
|
||||
item.findViewById<TextView>(R.id.content).text = template.content
|
||||
item.setOnClickListener {
|
||||
itemSelected(template)
|
||||
bottomSheet.cancel()
|
||||
}
|
||||
linearLayout.addView(item)
|
||||
}
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -145,7 +145,7 @@ class DownloadWorker(
|
|||
|
||||
val ext = downloadItem.format.container
|
||||
if (audioQualityId.isBlank() || ext == "Default") request.addOption("-x")
|
||||
request.addOption("-f", audioQualityId)
|
||||
else request.addOption("-f", audioQualityId)
|
||||
|
||||
if(ext != "webm"){
|
||||
val codec = when(downloadItem.format.container){
|
||||
|
|
|
|||
|
|
@ -216,4 +216,5 @@
|
|||
<string name="video_recommendations_summary">Get Recommended Youtube Videos on the Home Screen from Invidious</string>
|
||||
<string name="preferred_search_engine">Preferred Search Engine</string>
|
||||
<string name="preferred_search_engine_summary">The search engine to use for in-app searches</string>
|
||||
<string name="format_filtering_hint">All items must be of the same type to use this option</string>
|
||||
</resources>
|
||||
Loading…
Reference in a new issue