This commit is contained in:
Denis Çerri 2023-01-28 00:47:53 +01:00
parent 9e5f0e5fab
commit af4294e092
No known key found for this signature in database
GPG key ID: 95C43D517D830350
22 changed files with 445 additions and 303 deletions

View file

@ -2,7 +2,7 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "eddd8d0408b9e321c902948a418e6c92", "identityHash": "d658de0453c49534c5971583f41854db",
"entities": [ "entities": [
{ {
"tableName": "results", "tableName": "results",
@ -160,7 +160,7 @@
}, },
{ {
"tableName": "downloads", "tableName": "downloads",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `format` TEXT NOT NULL, `removeAudio` INTEGER NOT NULL DEFAULT 0, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `embedSubs` INTEGER NOT NULL, `addChapters` INTEGER NOT NULL, `SaveThumb` INTEGER NOT NULL, `ext` TEXT NOT NULL, `filesize` TEXT NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `workID` INTEGER NOT NULL)", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `format` TEXT NOT NULL, `removeAudio` INTEGER NOT NULL DEFAULT 0, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `embedSubs` INTEGER NOT NULL, `addChapters` INTEGER NOT NULL, `SaveThumb` INTEGER NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `workID` INTEGER NOT NULL)",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -259,18 +259,6 @@
"affinity": "INTEGER", "affinity": "INTEGER",
"notNull": true "notNull": true
}, },
{
"fieldPath": "ext",
"columnName": "ext",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "filesize",
"columnName": "filesize",
"affinity": "TEXT",
"notNull": true
},
{ {
"fieldPath": "status", "fieldPath": "status",
"columnName": "status", "columnName": "status",
@ -330,7 +318,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, 'eddd8d0408b9e321c902948a418e6c92')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd658de0453c49534c5971583f41854db')"
] ]
} }
} }

View file

@ -280,7 +280,7 @@ class MainActivity : AppCompatActivity() {
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
1 1
) )
}else{ }else if (!checkNotificationPermission()){
ActivityCompat.requestPermissions( ActivityCompat.requestPermissions(
this, this,
arrayOf(Manifest.permission.POST_NOTIFICATIONS), arrayOf(Manifest.permission.POST_NOTIFICATIONS),
@ -307,6 +307,7 @@ class MainActivity : AppCompatActivity() {
) { ) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults) super.onRequestPermissionsResult(requestCode, permissions, grantResults)
for (i in permissions.indices) { for (i in permissions.indices) {
if (permissions.contains(Manifest.permission.POST_NOTIFICATIONS)) break
if (grantResults[i] == PackageManager.PERMISSION_DENIED) { if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
createPermissionRequestDialog() createPermissionRequestDialog()
}else{ }else{
@ -325,6 +326,11 @@ class MainActivity : AppCompatActivity() {
== PackageManager.PERMISSION_GRANTED) == PackageManager.PERMISSION_GRANTED)
} }
private fun checkNotificationPermission(): Boolean {
return (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED)
}
private fun createPermissionRequestDialog() { private fun createPermissionRequestDialog() {
val dialog = MaterialAlertDialogBuilder(this) val dialog = MaterialAlertDialogBuilder(this)
dialog.setTitle(getString(R.string.warning)) dialog.setTitle(getString(R.string.warning))

View file

@ -19,18 +19,22 @@ 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.deniscerri.ytdlnis.database.models.ResultItem
import com.deniscerri.ytdlnis.util.FileUtil
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.google.android.material.progressindicator.LinearProgressIndicator
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import java.util.*
class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<DownloadItem?, ConfigureMultipleDownloadsAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) { class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : 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
private val fileUtil: FileUtil
init { init {
this.onItemClickListener = onItemClickListener this.onItemClickListener = onItemClickListener
this.activity = activity this.activity = activity
this.fileUtil = FileUtil()
} }
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) { class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
@ -77,11 +81,16 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
// Container ---------------------------------- // Container ----------------------------------
val container = card.findViewById<TextView>(R.id.container) val container = card.findViewById<TextView>(R.id.container)
container.text = item.ext container.text = item.format.container.uppercase(Locale.getDefault())
// File Size // File Size
val fileSize = card.findViewById<TextView>(R.id.filesize) val fileSize = card.findViewById<TextView>(R.id.filesize)
fileSize.text = item.filesize val formattedSize = fileUtil.convertFileSize(item.format.filesize)
fileSize.text = if (formattedSize == "?") "" else formattedSize.uppercase(Locale.getDefault())
// Quality
val quality = card.findViewById<TextView>(R.id.quality)
quality.text = item.format.format_note
// Type Icon Button // Type Icon Button
val btn = card.findViewById<MaterialButton>(R.id.downloads_download_button_type) val btn = card.findViewById<MaterialButton>(R.id.downloads_download_button_type)
@ -115,7 +124,7 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
} }
override fun areContentsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean { override fun areContentsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
return oldItem.url == newItem.url && oldItem.title == newItem.title && oldItem.author == newItem.author return oldItem.url == newItem.url && oldItem.title == newItem.title && oldItem.author == newItem.author && oldItem.type == newItem.type && oldItem.format == newItem.format
} }
} }
} }

View file

@ -33,8 +33,8 @@ interface DownloadDao {
@Query("DELETE FROM downloads") @Query("DELETE FROM downloads")
suspend fun deleteAll() suspend fun deleteAll()
@Delete @Query("DELETE FROM downloads WHERE id=:id")
suspend fun delete(item: DownloadItem) suspend fun delete(id: Long)
@Query("DELETE FROM downloads WHERE status='Processing'") @Query("DELETE FROM downloads WHERE status='Processing'")
suspend fun deleteProcessing() suspend fun deleteProcessing()

View file

@ -24,8 +24,6 @@ data class DownloadItem(
val embedSubs: Boolean, val embedSubs: Boolean,
val addChapters: Boolean, val addChapters: Boolean,
val SaveThumb: Boolean, val SaveThumb: Boolean,
var ext: String,
var filesize: String,
@ColumnInfo(defaultValue = "Queued") @ColumnInfo(defaultValue = "Queued")
var status: String, var status: String,
val workID: Int val workID: Int

View file

@ -6,9 +6,9 @@ data class Format(
@SerializedName(value = "format_id", alternate = ["itag"]) @SerializedName(value = "format_id", alternate = ["itag"])
var format_id: String = "", var format_id: String = "",
@SerializedName(value = "ext", alternate = ["container"]) @SerializedName(value = "ext", alternate = ["container"])
val container: String = "", var container: String = "",
@SerializedName(value = "filesize", alternate = ["clen", "filesize_approx"]) @SerializedName(value = "filesize", alternate = ["clen", "filesize_approx"])
val filesize: Long = 0, var filesize: Long = 0,
@SerializedName(value = "format_note", alternate = ["resolution", "audioQuality"]) @SerializedName(value = "format_note", alternate = ["resolution", "audioQuality"])
var format_note: String = "" var format_note: String = ""
) )

View file

@ -19,7 +19,7 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
} }
suspend fun delete(item: DownloadItem){ suspend fun delete(item: DownloadItem){
downloadDao.delete(item) downloadDao.delete(item.id)
} }
suspend fun update(item: DownloadItem){ suspend fun update(item: DownloadItem){

View file

@ -2,11 +2,13 @@ package com.deniscerri.ytdlnis.database.viewmodel
import android.app.Activity import android.app.Activity
import android.app.Application import android.app.Application
import android.content.SharedPreferences
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.App
import com.deniscerri.ytdlnis.R
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.Format
@ -17,18 +19,33 @@ 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 sharedPreferences: SharedPreferences
val allDownloads : LiveData<List<DownloadItem>> val allDownloads : LiveData<List<DownloadItem>>
val queuedDownloads : LiveData<List<DownloadItem>> val queuedDownloads : LiveData<List<DownloadItem>>
val activeDownloads : LiveData<List<DownloadItem>> val activeDownloads : LiveData<List<DownloadItem>>
val processingDownloads : LiveData<List<DownloadItem>> val processingDownloads : LiveData<List<DownloadItem>>
private var bestVideoFormat: Format
init { init {
val dao = DBManager.getInstance(application).downloadDao val dao = DBManager.getInstance(application).downloadDao
repository = DownloadRepository(dao) repository = DownloadRepository(dao)
sharedPreferences =
getApplication<App>().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
allDownloads = repository.allDownloads allDownloads = repository.allDownloads
queuedDownloads = repository.queuedDownloads queuedDownloads = repository.queuedDownloads
activeDownloads = repository.activeDownloads activeDownloads = repository.activeDownloads
processingDownloads = repository.processingDownloads processingDownloads = repository.processingDownloads
val format = getApplication<App>().resources.getStringArray(R.array.video_formats)
val container = sharedPreferences.getString("video_format", "Default")
bestVideoFormat = Format(
format[format.lastIndex],
container!!,
0,
format[format.lastIndex]
)
} }
fun startWork(items: List<DownloadItem>){ fun startWork(items: List<DownloadItem>){
@ -60,9 +77,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
} }
fun createDownloadItemFromResult(resultItem: ResultItem, type: String) : DownloadItem { fun createDownloadItemFromResult(resultItem: ResultItem, type: String) : DownloadItem {
val sharedPreferences = val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
getApplication<App>().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
val addChapters = sharedPreferences.getBoolean("add_chapters", false) val addChapters = sharedPreferences.getBoolean("add_chapters", false)
val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false) val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false)
@ -73,13 +88,35 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
resultItem.thumb, resultItem.thumb,
resultItem.duration, resultItem.duration,
type, type,
Format(), false, getFormat(resultItem, type), false,
"", resultItem.website, "", resultItem.playlistTitle, embedSubs, addChapters, saveThumb, "", "", resultItem.website, "", resultItem.playlistTitle, embedSubs, addChapters, saveThumb, DownloadRepository.status.Processing.toString(),
"", DownloadRepository.status.Processing.toString(), 0 0
) )
} }
private fun getFormat(resultItem: ResultItem, type: String) : Format {
when(type) {
"audio" -> {
return try {
resultItem.formats.last { it.format_note.contains("audio", ignoreCase = true) }
}catch (e: Exception){
Format()
}
}
"video" -> {
return try {
resultItem.formats[resultItem.formats.lastIndex]
}catch (e: Exception){
bestVideoFormat
}
}
else -> {
return Format()
}
}
}
fun turnResultItemstoDownloadItems(items: List<ResultItem?>) : List<DownloadItem> { fun turnResultItemstoDownloadItems(items: List<ResultItem?>) : List<DownloadItem> {
val list : MutableList<DownloadItem> = mutableListOf() val list : MutableList<DownloadItem> = mutableListOf()
items.forEach { items.forEach {

View file

@ -0,0 +1,145 @@
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.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.viewpager2.widget.ViewPager2
import com.deniscerri.ytdlnis.R
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
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class ConfigureDownloadBottomSheetDialog(private val downloadItem: DownloadItem) : BottomSheetDialogFragment() {
private lateinit var tabLayout: TabLayout
private lateinit var viewPager2: ViewPager2
private lateinit var fragmentAdapter : DownloadFragmentAdapter
private val currentItem = downloadItem.copy()
private lateinit var downloadViewModel: DownloadViewModel
private lateinit var resultViewModel: ResultViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
resultViewModel = ViewModelProvider(this)[ResultViewModel::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.configure_download_bottom_sheet, null)
dialog.setContentView(view)
//view.minimumHeight = resources.displayMetrics.heightPixels
tabLayout = view.findViewById(R.id.download_tablayout)
viewPager2 = view.findViewById(R.id.download_viewpager)
val fragmentManager = parentFragmentManager
fragmentAdapter = DownloadFragmentAdapter(downloadItem, fragmentManager, lifecycle)
viewPager2.adapter = fragmentAdapter
viewPager2.isSaveFromParentEnabled = false
when(downloadItem.type) {
"audio" -> {
tabLayout.selectTab(tabLayout.getTabAt(0))
viewPager2.setCurrentItem(0, false)
}
"video" -> {
tabLayout.selectTab(tabLayout.getTabAt(1))
viewPager2.setCurrentItem(1, false)
}
"command" -> {
tabLayout.selectTab(tabLayout.getTabAt(2))
viewPager2.setCurrentItem(2, false)
}
}
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
viewPager2.currentItem = tab!!.position
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
viewPager2.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
tabLayout.selectTab(tabLayout.getTabAt(position))
}
})
val cancelBtn = view.findViewById<MaterialButton>(R.id.bottomsheet_cancel_button)
cancelBtn.setOnClickListener{
returnPreviousState();
dismiss()
}
val download = view.findViewById<Button>(R.id.bottom_sheet_ok)
download!!.setOnClickListener {
dismiss()
}
}
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
returnPreviousState();
cleanUp()
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
cleanUp()
}
private fun returnPreviousState(){
lifecycleScope.launch{
val result = withContext(Dispatchers.IO){
resultViewModel.getItemByURL(currentItem.url)
}
result.title = currentItem.title
result.author = currentItem.author
resultViewModel.update(result)
downloadViewModel.updateDownload(currentItem)
}
}
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()
}
}
}
}

View file

@ -17,6 +17,7 @@ import androidx.lifecycle.lifecycleScope
import com.deniscerri.ytdlnis.MainActivity import com.deniscerri.ytdlnis.MainActivity
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.Format
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
@ -136,6 +137,7 @@ class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment()
val format = view.findViewById<TextInputLayout>(R.id.format) val format = view.findViewById<TextInputLayout>(R.id.format)
if (formats.isEmpty()) { if (formats.isEmpty()) {
format.visibility = View.GONE format.visibility = View.GONE
downloadItem.format = Format()
} else { } else {
val formatTitles = formats.map { val formatTitles = formats.map {
if (it.format_note.contains("AUDIO_QUALITY_")) { if (it.format_note.contains("AUDIO_QUALITY_")) {
@ -166,6 +168,7 @@ class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment()
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long -> AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
downloadItem.format.format_note = formats[index].format_note downloadItem.format.format_note = formats[index].format_note
downloadItem.format.format_id = formats[index].format_id downloadItem.format.format_id = formats[index].format_id
downloadViewModel.updateDownload(downloadItem)
} }
} }
@ -187,36 +190,11 @@ class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment()
containerAutoCompleteTextView!!.setText(selectedContainer, false) containerAutoCompleteTextView!!.setText(selectedContainer, false)
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener = (container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long -> AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
downloadItem.ext = containers[index] downloadItem.format.container = containers[index]
downloadViewModel.updateDownload(downloadItem)
} }
downloadViewModel.updateDownload(downloadItem)
val cancelBtn = view.findViewById<MaterialButton>(R.id.bottomsheet_cancel_button)
cancelBtn.setOnClickListener{
(parentFragmentManager.findFragmentByTag("bottomSheet") as DownloadBottomSheetDialog).dismissSelf()
}
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()
// }
(parentFragmentManager.findFragmentByTag("bottomSheet") as DownloadBottomSheetDialog).dismissSelf()
}
}catch (e : Exception){ }catch (e : Exception){
e.printStackTrace() e.printStackTrace()
} }

View file

@ -7,6 +7,10 @@ import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.Adapter
import android.widget.Button
import android.widget.LinearLayout
import androidx.core.view.get
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.findFragment import androidx.fragment.app.findFragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
@ -17,6 +21,7 @@ import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment 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
class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment() { class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment() {
@ -42,7 +47,6 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
super.setupDialog(dialog, style) super.setupDialog(dialog, style)
val view = LayoutInflater.from(context).inflate(R.layout.download_bottom_sheet, null) val view = LayoutInflater.from(context).inflate(R.layout.download_bottom_sheet, null)
dialog.setContentView(view) dialog.setContentView(view)
//view.minimumHeight = resources.displayMetrics.heightPixels
tabLayout = view.findViewById(R.id.download_tablayout) tabLayout = view.findViewById(R.id.download_tablayout)
viewPager2 = view.findViewById(R.id.download_viewpager) viewPager2 = view.findViewById(R.id.download_viewpager)
@ -85,10 +89,46 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
tabLayout.selectTab(tabLayout.getTabAt(position)) tabLayout.selectTab(tabLayout.getTabAt(position))
} }
}) })
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) { override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog) super.onCancel(dialog)
cleanUp()
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
cleanUp()
}
private fun cleanUp(){
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadSingleSheet")!!).commit() parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("downloadSingleSheet")!!).commit()
for (i in 0 until viewPager2.adapter?.itemCount!!){ for (i in 0 until viewPager2.adapter?.itemCount!!){
if (parentFragmentManager.findFragmentByTag("f${i}") != null){ if (parentFragmentManager.findFragmentByTag("f${i}") != null){
@ -98,9 +138,5 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
downloadViewModel.deleteDownload(downloadItem) downloadViewModel.deleteDownload(downloadItem)
} }
fun dismissSelf(){
this.dismiss()
}
} }

View file

@ -31,6 +31,7 @@ class DownloadFragmentAdapter (item : DownloadItem, fragmentManager : FragmentMa
return DownloadCommandFragment(clone(downloadItem)) return DownloadCommandFragment(clone(downloadItem))
} }
private fun clone(item: DownloadItem) : DownloadItem { private fun clone(item: DownloadItem) : DownloadItem {
val stringItem = Gson().toJson(item, DownloadItem::class.java) val stringItem = Gson().toJson(item, DownloadItem::class.java)
return Gson().fromJson(stringItem, DownloadItem::class.java) return Gson().fromJson(stringItem, DownloadItem::class.java)

View file

@ -12,6 +12,7 @@ import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.findFragment import androidx.fragment.app.findFragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
@ -26,6 +27,9 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class DownloadMultipleBottomSheetDialog(private val items: List<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener { class DownloadMultipleBottomSheetDialog(private val items: List<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener {
private lateinit var downloadViewModel: DownloadViewModel private lateinit var downloadViewModel: DownloadViewModel
@ -116,7 +120,13 @@ class DownloadMultipleBottomSheetDialog(private val items: List<DownloadItem>) :
} }
override fun onCardClick(itemID: Long) { override fun onCardClick(itemID: Long) {
TODO("Not yet implemented") lifecycleScope.launch{
val downloadItem = withContext(Dispatchers.IO){
downloadViewModel.getItemByID(itemID)
}
val bottomSheet = ConfigureDownloadBottomSheetDialog(downloadItem)
bottomSheet.show(parentFragmentManager, "configureDownloadSingleSheet")
}
} }
override fun onClick(p0: View?) { override fun onClick(p0: View?) {

View file

@ -5,6 +5,7 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
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
@ -142,11 +143,7 @@ class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment()
} }
val formatTitles = formats.map { val formatTitles = formats.map {
if (it.format_note.contains("AUDIO_QUALITY_")) it.format_note + if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
it.format_note.replace("AUDIO_QUALITY_", "") +
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
else it.format_note +
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
} }
val format = view.findViewById<TextInputLayout>(R.id.format) val format = view.findViewById<TextInputLayout>(R.id.format)
@ -166,6 +163,8 @@ class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment()
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long -> AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
downloadItem.format.format_note = formats[index].format_note downloadItem.format.format_note = formats[index].format_note
downloadItem.format.format_id = formats[index].format_id downloadItem.format.format_id = formats[index].format_id
downloadItem.format.filesize = formats[index].filesize
downloadViewModel.updateDownload(downloadItem)
} }
val containers = requireContext().resources.getStringArray(R.array.video_containers) val containers = requireContext().resources.getStringArray(R.array.video_containers)
@ -181,13 +180,15 @@ class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment()
containers containers
) )
) )
val selectedContainer: String = var selectedContainer: String = downloadItem.format.container
formats.find { downloadItem.format.format_note == it.format_note }?.container if (selectedContainer.isEmpty()){
?: sharedPreferences.getString("video_format", "DEFAULT")!! selectedContainer = sharedPreferences.getString("video_format", "Default")!!
}
containerAutoCompleteTextView!!.setText(selectedContainer, false) containerAutoCompleteTextView!!.setText(selectedContainer, false)
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener = (container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long -> AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
downloadItem.ext = containers[index] downloadItem.format.container = containers[index]
downloadViewModel.updateDownload(downloadItem)
} }
val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles) val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
@ -199,32 +200,6 @@ class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment()
val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail) val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)
saveThumbnail!!.isChecked = sharedPreferences.getBoolean("write_thumbnail", false) saveThumbnail!!.isChecked = sharedPreferences.getBoolean("write_thumbnail", false)
val cancel = view.findViewById<Button>(R.id.bottomsheet_cancel_button)
cancel!!.setOnClickListener {
(parentFragmentManager.findFragmentByTag("bottomSheet") as DownloadBottomSheetDialog).dismissSelf()
}
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()
// }
(parentFragmentManager.findFragmentByTag("bottomSheet") as DownloadBottomSheetDialog).dismissSelf()
}
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }

View file

@ -93,7 +93,7 @@ class DownloadWorker(
request.addOption("-x") request.addOption("-x")
var audioQualityId : String = downloadItem.format.format_id var audioQualityId : String = downloadItem.format.format_id
if (audioQualityId == "0") audioQualityId = "ba" if (audioQualityId == "0") audioQualityId = "ba"
var ext = downloadItem.ext var ext = downloadItem.format.container
request.addOption("-f", audioQualityId) request.addOption("-f", audioQualityId)
request.addOption("--audio-format", ext) request.addOption("--audio-format", ext)
request.addOption("--embed-metadata") request.addOption("--embed-metadata")
@ -140,7 +140,7 @@ class DownloadWorker(
val formatArgument = StringBuilder(videoFormatID) val formatArgument = StringBuilder(videoFormatID)
formatArgument.append("+bestaudio/best") formatArgument.append("+bestaudio/best")
request.addOption("-f", formatArgument.toString()) request.addOption("-f", formatArgument.toString())
var format = downloadItem.ext var format = downloadItem.format.container
if (format.isNotEmpty()) { if (format.isNotEmpty()) {
format = sharedPreferences.getString("video_format", "")!! format = sharedPreferences.getString("video_format", "")!!
if (format != "DEFAULT") request.addOption("--merge-output-format", format) if (format != "DEFAULT") request.addOption("--merge-output-format", format)

View file

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_height="match_parent">
<TextView
android:id="@+id/bottom_sheet_title"
android:layout_width="wrap_content"
android:textSize="25sp"
android:padding="20dp"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:text="@string/configure_download" />
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="@android:color/transparent"
app:tabMode="scrollable"
app:tabGravity="center"
android:id="@+id/download_tablayout" >
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/audio" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/video" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/run_command" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/download_viewpager" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="10dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:gravity="end"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:id="@+id/bottomsheet_cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cancel"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_cancel" />
<Button
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:id="@+id/bottom_sheet_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ok"
app:icon="@drawable/ic_check"
android:autoLink="all"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -43,7 +43,52 @@
<androidx.viewpager2.widget.ViewPager2 <androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:id="@+id/download_viewpager" /> android:id="@+id/download_viewpager" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="10dp"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
android:id="@+id/bottomsheet_schedule_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_clock" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:gravity="end"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:id="@+id/bottomsheet_cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cancel"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_cancel" />
<Button
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:id="@+id/bottomsheet_download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/download"
app:icon="@drawable/ic_down"
android:autoLink="all"/>
</LinearLayout>
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -105,7 +105,11 @@
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" android:textStyle="bold"
android:shadowColor="@color/black"
android:shadowDx="4"
android:shadowDy="4"
android:shadowRadius="1.5"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/filesize" app:layout_constraintEnd_toStartOf="@+id/filesize"
app:layout_constraintTop_toBottomOf="@+id/downloads_download_button_type" /> app:layout_constraintTop_toBottomOf="@+id/downloads_download_button_type" />
@ -115,6 +119,24 @@
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:textStyle="bold"
android:shadowColor="@color/black"
android:shadowDx="4"
android:shadowDy="4"
android:shadowRadius="1.5"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/quality" />
<TextView
android:id="@+id/quality"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textStyle="bold"
android:shadowColor="@color/black"
android:shadowDx="4"
android:shadowDy="4"
android:shadowRadius="1.5"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />

View file

@ -93,65 +93,22 @@
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/outputPath" android:id="@+id/outputPath"
style="@style/Widget.Material3.TextInputLayout.FilledBox"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:errorEnabled="true"
android:hint="@string/save_dir" android:hint="@string/save_dir"
style="@style/Widget.Material3.TextInputLayout.FilledBox"> app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent" android:layout_width="match_parent"
android:inputType="text" android:layout_height="wrap_content"
android:layout_height="wrap_content"/> android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingTop="10dp"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
android:id="@+id/bottomsheet_schedule_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_clock" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:gravity="end"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:id="@+id/bottomsheet_cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cancel"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_cancel" />
<Button
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:id="@+id/bottomsheet_download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/download"
app:icon="@drawable/ic_down"
android:autoLink="all"/>
</LinearLayout>
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -147,52 +147,6 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingTop="10dp"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
android:id="@+id/bottomsheet_schedule_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_clock" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:gravity="end"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:id="@+id/bottomsheet_cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cancel"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_cancel" />
<Button
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:id="@+id/bottomsheet_download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/download"
app:icon="@drawable/ic_down"
android:autoLink="all"/>
</LinearLayout>
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -164,52 +164,6 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingTop="10dp"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
android:id="@+id/bottomsheet_schedule_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_clock" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:gravity="end"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:id="@+id/bottomsheet_cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cancel"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_cancel" />
<Button
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:id="@+id/bottomsheet_download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/download"
app:icon="@drawable/ic_down"
android:autoLink="all"/>
</LinearLayout>
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/history_element_bottom_sheet"
style="@style/Widget.Material3.BottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:orientation="vertical"
>
<TextView
android:id="@+id/bottom_sheet_title"
android:layout_width="wrap_content"
android:textSize="25sp"
android:textColor="?attr/colorOnSurface"
android:layout_height="wrap_content"
android:text="@string/configure_download" />
<View style="@style/Divider.Horizontal"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="end"
android:orientation="horizontal">
<Button
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:id="@+id/bottomsheet_schedule_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
app:icon="@drawable/ic_cancel"
android:text="@string/cancel" />
<Button
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:id="@+id/bottomsheet_download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ok"
app:icon="@drawable/ic_check"
android:autoLink="all"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>