added download type toggle in download multiple card

This commit is contained in:
Denis Çerri 2023-03-11 15:07:06 +01:00
parent f26fd7498d
commit 33c081d132
No known key found for this signature in database
GPG key ID: 95C43D517D830350
24 changed files with 384 additions and 155 deletions

View file

@ -320,7 +320,7 @@
<PersistentState> <PersistentState>
<option name="values"> <option name="values">
<map> <map>
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/rule_folder/baseline_rule_folder_24.xml" /> <entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/video_file/baseline_video_file_24.xml" />
</map> </map>
</option> </option>
</PersistentState> </PersistentState>
@ -330,7 +330,7 @@
</option> </option>
<option name="values"> <option name="values">
<map> <map>
<entry key="outputName" value="ic_access_folder" /> <entry key="outputName" value="baseline_video_file_24" />
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" /> <entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
</map> </map>
</option> </option>

View file

@ -2,7 +2,7 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "6d6dea309a9207aaaedcc2a745ae2a2a", "identityHash": "f602a089dee877374642352ffd4fa6bb",
"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, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `audioPreferences` TEXT NOT NULL, `videoPreferences` TEXT NOT NULL, `customFileNameTemplate` TEXT NOT NULL, `SaveThumb` INTEGER NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `downloadStartTime` INTEGER NOT NULL DEFAULT 0)", "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, `allFormats` TEXT NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `audioPreferences` TEXT NOT NULL, `videoPreferences` TEXT NOT NULL, `customFileNameTemplate` TEXT NOT NULL, `SaveThumb` INTEGER NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `downloadStartTime` INTEGER NOT NULL DEFAULT 0)",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -210,6 +210,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": true "notNull": true
}, },
{
"fieldPath": "allFormats",
"columnName": "allFormats",
"affinity": "TEXT",
"notNull": true
},
{ {
"fieldPath": "downloadPath", "fieldPath": "downloadPath",
"columnName": "downloadPath", "columnName": "downloadPath",
@ -370,7 +376,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, '6d6dea309a9207aaaedcc2a745ae2a2a')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f602a089dee877374642352ffd4fa6bb')"
] ]
} }
} }

View file

@ -80,6 +80,7 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
val formatNote = card.findViewById<TextView>(R.id.format_note) val formatNote = card.findViewById<TextView>(R.id.format_note)
if (item.format.format_note.isNotEmpty()){ if (item.format.format_note.isNotEmpty()){
formatNote.text = item.format.format_note.uppercase(Locale.getDefault()) formatNote.text = item.format.format_note.uppercase(Locale.getDefault())
formatNote.visibility = View.VISIBLE
}else{ }else{
formatNote.visibility = View.GONE formatNote.visibility = View.GONE
} }
@ -119,7 +120,7 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video) btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video)
} }
else -> { else -> {
btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_baseline_keyboard_arrow_right_24) btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_terminal)
} }
} }

View file

@ -112,8 +112,7 @@ class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activit
datetime.text = relativeTime datetime.text = relativeTime
// BUTTON ---------------------------------- // BUTTON ----------------------------------
val buttonLayout = card.findViewById<LinearLayout>(R.id.downloads_download_button_layout) val btn = card.findViewById<MaterialButton>(R.id.downloads_download_button_type)
val btn = buttonLayout.findViewById<MaterialButton>(R.id.downloads_download_button_type)
var filePresent = true var filePresent = true
//IS IN THE FILE SYSTEM? //IS IN THE FILE SYSTEM?

View file

@ -16,6 +16,7 @@ data class DownloadItem(
val duration: String, val duration: String,
var type: DownloadViewModel.Type, var type: DownloadViewModel.Type,
var format: Format, var format: Format,
val allFormats: ArrayList<Format>,
var downloadPath: String, var downloadPath: String,
val website: String, val website: String,
val downloadSize: String, val downloadSize: String,

View file

@ -13,6 +13,10 @@ class CommandTemplateRepository(private val commandDao: CommandTemplateDao) {
return commandDao.getAllTemplates(); return commandDao.getAllTemplates();
} }
fun getTotalNumber() : Int {
return commandDao.getTotalNumber()
}
fun getItem(id: Long) : CommandTemplate { fun getItem(id: Long) : CommandTemplate {
return commandDao.getTemplate(id) return commandDao.getTemplate(id)
} }

View file

@ -38,6 +38,10 @@ class CommandTemplateViewModel(private val application: Application) : AndroidVi
return repository.getAll() return repository.getAll()
} }
fun getTotalNumber(): Int {
return repository.getTotalNumber()
}
fun insert(item: CommandTemplate) = viewModelScope.launch(Dispatchers.IO) { fun insert(item: CommandTemplate) = viewModelScope.launch(Dispatchers.IO) {
repository.insert(item) repository.insert(item)
} }

View file

@ -21,6 +21,7 @@ import com.deniscerri.ytdlnis.work.DownloadWorker
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class DownloadViewModel(application: Application) : AndroidViewModel(application) { class DownloadViewModel(application: Application) : AndroidViewModel(application) {
@ -55,7 +56,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
erroredDownloads = repository.erroredDownloads erroredDownloads = repository.erroredDownloads
val videoFormat = getApplication<App>().resources.getStringArray(R.array.video_formats) val videoFormat = getApplication<App>().resources.getStringArray(R.array.video_formats)
val videoContainer = sharedPreferences.getString("video_format", "Default") val videoContainer = sharedPreferences.getString("video_format", getApplication<App>().resources.getString(R.string.defaultValue))
bestVideoFormat = Format( bestVideoFormat = Format(
videoFormat[videoFormat.lastIndex], videoFormat[videoFormat.lastIndex],
videoContainer!!, videoContainer!!,
@ -113,12 +114,22 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
resultItem.thumb, resultItem.thumb,
resultItem.duration, resultItem.duration,
type, type,
getFormat(resultItem, type), getFormat(resultItem.formats, type),
resultItem.formats,
downloadPath!!, resultItem.website, "", resultItem.playlistTitle, audioPreferences, videoPreferences,customFileNameTemplate!!, saveThumb, DownloadRepository.Status.Processing.toString(), 0 downloadPath!!, resultItem.website, "", resultItem.playlistTitle, audioPreferences, videoPreferences,customFileNameTemplate!!, saveThumb, DownloadRepository.Status.Processing.toString(), 0
) )
} }
fun switchDownloadType(list: List<DownloadItem>, type: Type) : List<DownloadItem>{
list.forEach {
val format = getFormat(it.allFormats, type)
it.format = format
it.type = type
}
return list
}
fun createDownloadItemFromHistory(historyItem: HistoryItem) : DownloadItem { fun createDownloadItemFromHistory(historyItem: HistoryItem) : DownloadItem {
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false) val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
val addChapters = sharedPreferences.getBoolean("add_chapters", false) val addChapters = sharedPreferences.getBoolean("add_chapters", false)
@ -143,30 +154,51 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
historyItem.duration, historyItem.duration,
historyItem.type, historyItem.type,
historyItem.format, historyItem.format,
ArrayList(),
downloadPath!!, historyItem.website, "", "", audioPreferences, videoPreferences,customFileNameTemplate!!, saveThumb, DownloadRepository.Status.Processing.toString(), 0 downloadPath!!, historyItem.website, "", "", audioPreferences, videoPreferences,customFileNameTemplate!!, saveThumb, DownloadRepository.Status.Processing.toString(), 0
) )
} }
private fun getFormat(resultItem: ResultItem?, type: Type) : Format { private fun getFormat(formats: List<Format>, type: Type) : Format {
when(type) { when(type) {
Type.audio -> { Type.audio -> {
return try { return try {
resultItem!!.formats.last { it.format_note.contains("audio", ignoreCase = true) } formats.last { it.format_note.contains("audio", ignoreCase = true) }
}catch (e: Exception){ }catch (e: Exception){
bestAudioFormat bestAudioFormat
} }
} }
Type.video -> { Type.video -> {
return try { return try {
resultItem!!.formats.last { !it.format_note.contains("audio", ignoreCase = true) } val qualityPreference = sharedPreferences.getString("video_quality", getApplication<App>().resources.getString(R.string.best_quality))
if (qualityPreference == getApplication<App>().resources.getString(R.string.worst_quality)){
formats.first { !it.format_note.contains("audio", ignoreCase = true) }
}
if (qualityPreference == getApplication<App>().resources.getString(R.string.best_quality)){
formats.last { !it.format_note.contains("audio", ignoreCase = true) }
}
try{
formats.last { format -> format.format_note.contains(qualityPreference!!.substring(0, qualityPreference.length -1)) }
}catch (e: Exception){
formats.last { !it.format_note.contains("audio", ignoreCase = true) }
}
}catch (e: Exception){ }catch (e: Exception){
bestVideoFormat bestVideoFormat
} }
} }
else -> { else -> {
return Format() val c = commandTemplateDao.getFirst()
return Format(
c.title,
"",
"",
"",
"",
0,
c.content
)
} }
} }
} }

View file

@ -132,8 +132,10 @@ class ShareActivity : AppCompatActivity() {
val bottomSheet = DownloadBottomSheetDialog(it, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!)) val bottomSheet = DownloadBottomSheetDialog(it, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
bottomSheet.show(supportFragmentManager, "downloadSingleSheet") bottomSheet.show(supportFragmentManager, "downloadSingleSheet")
}else{ }else{
val downloadItem = downloadViewModel.createDownloadItemFromResult(it, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!)) lifecycleScope.launch(Dispatchers.IO){
downloadViewModel.queueDownloads(listOf(downloadItem)) val downloadItem = downloadViewModel.createDownloadItemFromResult(it, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
downloadViewModel.queueDownloads(listOf(downloadItem))
}
this.finish() this.finish()
} }
} }
@ -145,12 +147,14 @@ class ShareActivity : AppCompatActivity() {
}else{ }else{
lifecycleScope.launch(Dispatchers.IO){ lifecycleScope.launch(Dispatchers.IO){
val downloadItems = mutableListOf<DownloadItem>() val downloadItems = mutableListOf<DownloadItem>()
it.forEach { res -> lifecycleScope.launch(Dispatchers.IO){
val i = downloadViewModel.createDownloadItemFromResult(res!!, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!)) it.forEach { res ->
i.format = downloadViewModel.getLatestCommandTemplateAsFormat() val i = downloadViewModel.createDownloadItemFromResult(res!!, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
downloadItems.add(i) i.format = downloadViewModel.getLatestCommandTemplateAsFormat()
downloadItems.add(i)
}
downloadViewModel.queueDownloads(downloadItems)
} }
downloadViewModel.queueDownloads(downloadItems)
} }
this.finish() this.finish()
} }

View file

@ -328,8 +328,10 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
if (sharedPreferences!!.getBoolean("download_card", true)) { if (sharedPreferences!!.getBoolean("download_card", true)) {
showSingleDownloadSheet(item!!, type!!) showSingleDownloadSheet(item!!, type!!)
} else { } else {
val downloadItem = downloadViewModel.createDownloadItemFromResult(item!!, type!!) lifecycleScope.launch(Dispatchers.IO){
downloadViewModel.queueDownloads(listOf(downloadItem)) val downloadItem = downloadViewModel.createDownloadItemFromResult(item!!, type!!)
downloadViewModel.queueDownloads(listOf(downloadItem))
}
} }
} }

View file

@ -32,7 +32,9 @@ import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class DownloadAudioFragment(private var resultItem: ResultItem, private var currentDownloadItem: DownloadItem?) : Fragment() { class DownloadAudioFragment(private var resultItem: ResultItem, private var currentDownloadItem: DownloadItem?) : Fragment() {
@ -57,14 +59,6 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr
fragmentView = inflater.inflate(R.layout.fragment_download_audio, container, false) fragmentView = inflater.inflate(R.layout.fragment_download_audio, container, false)
activity = getActivity() activity = getActivity()
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
downloadItem = if (currentDownloadItem != null && currentDownloadItem!!.type == Type.audio){
val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java)
Gson().fromJson(string, DownloadItem::class.java)
}else{
downloadViewModel.createDownloadItemFromResult(resultItem, Type.audio)
}
fileUtil = FileUtil() fileUtil = FileUtil()
uiUtil = UiUtil(fileUtil) uiUtil = UiUtil(fileUtil)
return fragmentView return fragmentView
@ -73,6 +67,14 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
lifecycleScope.launch { lifecycleScope.launch {
downloadItem = withContext(Dispatchers.IO) {
if (currentDownloadItem != null && currentDownloadItem!!.type == Type.audio){
val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java)
Gson().fromJson(string, DownloadItem::class.java)
}else{
downloadViewModel.createDownloadItemFromResult(resultItem, Type.audio)
}
}
val sharedPreferences = val sharedPreferences =
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE) requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)

View file

@ -58,14 +58,6 @@ class DownloadCommandFragment(private val resultItem: ResultItem, private var cu
activity = getActivity() activity = getActivity()
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java] commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java]
downloadItem = if (currentDownloadItem != null && currentDownloadItem!!.type == DownloadViewModel.Type.command){
val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java)
Gson().fromJson(string, DownloadItem::class.java)
}else{
downloadViewModel.createDownloadItemFromResult(resultItem, DownloadViewModel.Type.command)
}
fileUtil = FileUtil() fileUtil = FileUtil()
uiUtil = UiUtil(fileUtil) uiUtil = UiUtil(fileUtil)
return fragmentView return fragmentView
@ -75,25 +67,34 @@ class DownloadCommandFragment(private val resultItem: ResultItem, private var cu
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
lifecycleScope.launch { lifecycleScope.launch {
downloadItem = withContext(Dispatchers.IO){
if (currentDownloadItem != null && currentDownloadItem!!.type == DownloadViewModel.Type.command){
val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java)
Gson().fromJson(string, DownloadItem::class.java)
}else{
downloadViewModel.createDownloadItemFromResult(resultItem, DownloadViewModel.Type.command)
}
}
val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE) val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
try { try {
val templates : MutableList<CommandTemplate> = withContext(Dispatchers.IO){ val templates : MutableList<CommandTemplate> = withContext(Dispatchers.IO){
commandTemplateViewModel.getAll().toMutableList() commandTemplateViewModel.getAll().toMutableList()
} }
val id = sharedPreferences.getLong("commandTemplate", templates[0].id) // val id = sharedPreferences.getLong("commandTemplate", templates[0].id)
val chosenCommand = templates.find { it.id == id } // val chosenCommand = templates.find { it.id == id }
downloadItem.format = Format( // downloadItem.format = Format(
chosenCommand!!.title, // chosenCommand!!.title,
"", // "",
"", // "",
"", // "",
"", // "",
0, // 0,
chosenCommand.content // chosenCommand.content
) // )
val chosenCommandView = view.findViewById<TextInputLayout>(R.id.content) val chosenCommandView = view.findViewById<TextInputLayout>(R.id.content)
chosenCommandView.editText!!.setText(chosenCommand.content) chosenCommandView.editText!!.setText(downloadItem.format.format_note)
chosenCommandView.endIconDrawable = AppCompatResources.getDrawable(requireContext(), R.drawable.ic_delete_all) chosenCommandView.endIconDrawable = AppCompatResources.getDrawable(requireContext(), R.drawable.ic_delete_all)
chosenCommandView.editText!!.addTextChangedListener(object : TextWatcher { chosenCommandView.editText!!.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}

View file

@ -8,25 +8,29 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.*
import android.view.MenuItem
import android.view.View
import android.widget.Button import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope 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 com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.adapter.ConfigureMultipleDownloadsAdapter import com.deniscerri.ytdlnis.adapter.ConfigureMultipleDownloadsAdapter
import com.deniscerri.ytdlnis.database.models.CommandTemplate
import com.deniscerri.ytdlnis.database.models.DownloadItem import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel
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.receiver.ShareActivity import com.deniscerri.ytdlnis.receiver.ShareActivity
import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.FileUtil
import com.google.android.material.bottomappbar.BottomAppBar import com.google.android.material.bottomappbar.BottomAppBar
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.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.datepicker.CalendarConstraints import com.google.android.material.datepicker.CalendarConstraints
@ -39,9 +43,10 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.util.* import java.util.*
class DownloadMultipleBottomSheetDialog(private val items: MutableList<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener, class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener,
ConfigureDownloadBottomSheetDialog.OnDownloadItemUpdateListener { ConfigureDownloadBottomSheetDialog.OnDownloadItemUpdateListener {
private lateinit var downloadViewModel: DownloadViewModel private lateinit var downloadViewModel: DownloadViewModel
private lateinit var commandTemplateViewModel: CommandTemplateViewModel
private lateinit var resultViewModel: ResultViewModel private lateinit var resultViewModel: ResultViewModel
private lateinit var listAdapter : ConfigureMultipleDownloadsAdapter private lateinit var listAdapter : ConfigureMultipleDownloadsAdapter
private lateinit var recyclerView: RecyclerView private lateinit var recyclerView: RecyclerView
@ -53,6 +58,7 @@ class DownloadMultipleBottomSheetDialog(private val items: MutableList<DownloadI
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java] resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java]
commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java]
fileUtil = FileUtil() fileUtil = FileUtil()
} }
@ -136,6 +142,20 @@ class DownloadMultipleBottomSheetDialog(private val items: MutableList<DownloadI
} }
val bottomAppBar = view.findViewById<BottomAppBar>(R.id.bottomAppBar) val bottomAppBar = view.findViewById<BottomAppBar>(R.id.bottomAppBar)
val preferredDownloadType = bottomAppBar.menu.findItem(R.id.preferred_download_type)
when(items.first().type){
DownloadViewModel.Type.audio -> {
preferredDownloadType.setIcon(R.drawable.baseline_audio_file_24)
}
DownloadViewModel.Type.video -> {
preferredDownloadType.setIcon(R.drawable.baseline_video_file_24)
}
DownloadViewModel.Type.command -> {
preferredDownloadType.setIcon(R.drawable.baseline_insert_drive_file_24)
}
}
bottomAppBar!!.setOnMenuItemClickListener { m: MenuItem -> bottomAppBar!!.setOnMenuItemClickListener { m: MenuItem ->
val itemId = m.itemId val itemId = m.itemId
if (itemId == R.id.folder) { if (itemId == R.id.folder) {
@ -144,7 +164,61 @@ class DownloadMultipleBottomSheetDialog(private val items: MutableList<DownloadI
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
pathResultLauncher.launch(intent) pathResultLauncher.launch(intent)
} else if (itemId == R.id.edit){ } else if (itemId == R.id.preferred_download_type){
lifecycleScope.launch{
val bottomSheet = BottomSheetDialog(requireContext())
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
bottomSheet.setContentView(R.layout.download_type_sheet)
// BUTTON ----------------------------------
val audio = bottomSheet.findViewById<LinearLayout>(R.id.audio)
val video = bottomSheet.findViewById<LinearLayout>(R.id.video)
val command = bottomSheet.findViewById<LinearLayout>(R.id.command)
withContext(Dispatchers.IO){
val nr = commandTemplateViewModel.getTotalNumber()
if(nr == 0){
command!!.visibility = View.GONE
}else{
command!!.visibility = View.VISIBLE
}
}
audio!!.setOnClickListener {
items = downloadViewModel.switchDownloadType(items, DownloadViewModel.Type.audio).toMutableList()
listAdapter.submitList(items.toList())
listAdapter.notifyDataSetChanged()
preferredDownloadType.setIcon(R.drawable.baseline_audio_file_24)
bottomSheet.cancel()
}
video!!.setOnClickListener {
items = downloadViewModel.switchDownloadType(items, DownloadViewModel.Type.video).toMutableList()
listAdapter.submitList(items.toList())
listAdapter.notifyDataSetChanged()
preferredDownloadType.setIcon(R.drawable.baseline_video_file_24)
bottomSheet.cancel()
}
command!!.setOnClickListener {
lifecycleScope.launch {
items = withContext(Dispatchers.IO){
downloadViewModel.switchDownloadType(items, DownloadViewModel.Type.command).toMutableList()
}
listAdapter.submitList(items.toList())
listAdapter.notifyDataSetChanged()
preferredDownloadType.setIcon(R.drawable.baseline_insert_drive_file_24)
bottomSheet.cancel()
}
}
bottomSheet.show()
bottomSheet.window!!.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
} }
true true
@ -197,7 +271,6 @@ class DownloadMultipleBottomSheetDialog(private val items: MutableList<DownloadI
val resultItem = withContext(Dispatchers.IO){ val resultItem = withContext(Dispatchers.IO){
resultViewModel.getItemByURL(downloadItem!!.url) resultViewModel.getItemByURL(downloadItem!!.url)
} }
Log.e("aa", resultItem.toString())
val bottomSheet = ConfigureDownloadBottomSheetDialog(resultItem, downloadItem!!, this@DownloadMultipleBottomSheetDialog) val bottomSheet = ConfigureDownloadBottomSheetDialog(resultItem, downloadItem!!, this@DownloadMultipleBottomSheetDialog)
bottomSheet.show(parentFragmentManager, "configureDownloadSingleSheet") bottomSheet.show(parentFragmentManager, "configureDownloadSingleSheet")
} }

View file

@ -63,13 +63,6 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
resultViewModel = ViewModelProvider(this@DownloadVideoFragment)[ResultViewModel::class.java] resultViewModel = ViewModelProvider(this@DownloadVideoFragment)[ResultViewModel::class.java]
downloadItem = if (currentDownloadItem != null && currentDownloadItem!!.type == Type.video){
val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java)
Gson().fromJson(string, DownloadItem::class.java)
}else{
downloadViewModel.createDownloadItemFromResult(resultItem, Type.video)
}
fileUtil = FileUtil() fileUtil = FileUtil()
uiUtil = UiUtil(fileUtil) uiUtil = UiUtil(fileUtil)
return fragmentView return fragmentView
@ -79,6 +72,14 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
lifecycleScope.launch { lifecycleScope.launch {
downloadItem = withContext(Dispatchers.IO){
if (currentDownloadItem != null && currentDownloadItem!!.type == Type.video){
val string = Gson().toJson(currentDownloadItem, DownloadItem::class.java)
Gson().fromJson(string, DownloadItem::class.java)
}else{
downloadViewModel.createDownloadItemFromResult(resultItem, Type.video)
}
}
val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE) val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
try { try {

View file

@ -168,8 +168,8 @@ class DownloadWorker(
Log.e(TAG, videoFormatID) Log.e(TAG, videoFormatID)
var formatArgument = "bestvideo+bestaudio/best" var formatArgument = "bestvideo+bestaudio/best"
if (videoFormatID.isNotEmpty()) { if (videoFormatID.isNotEmpty()) {
if (videoFormatID == "Best Quality") videoFormatID = "bestvideo" if (videoFormatID == context.resources.getString(R.string.best_quality)) videoFormatID = "bestvideo"
else if (videoFormatID == "Worst Quality") videoFormatID = "worst" else if (videoFormatID == context.resources.getString(R.string.worst_quality)) videoFormatID = "worst"
else if (defaultFormats.contains(videoFormatID)) videoFormatID = "bestvideo[height<="+videoFormatID.substring(0, videoFormatID.length -1)+"]" else if (defaultFormats.contains(videoFormatID)) videoFormatID = "bestvideo[height<="+videoFormatID.substring(0, videoFormatID.length -1)+"]"
formatArgument = "$videoFormatID+bestaudio/best/$videoFormatID" formatArgument = "$videoFormatID+bestaudio/best/$videoFormatID"
} }

View file

@ -0,0 +1,5 @@
<vector android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?android:textColorPrimary" android:pathData="M14,2H6C4.9,2 4.01,2.9 4.01,4L4,20c0,1.1 0.89,2 1.99,2H18c1.1,0 2,-0.9 2,-2V8L14,2zM16,13h-3v3.75c0,1.24 -1.01,2.25 -2.25,2.25S8.5,17.99 8.5,16.75c0,-1.24 1.01,-2.25 2.25,-2.25c0.46,0 0.89,0.14 1.25,0.38V11h4V13zM13,9V3.5L18.5,9H13z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?android:textColorPrimary" android:pathData="M6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6L6,2zM13,9L13,3.5L18.5,9L13,9z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?android:textColorPrimary" android:pathData="M14,2H6.01c-1.1,0 -2,0.89 -2,2L4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V8L14,2zM13,9V3.5L18.5,9H13zM14,14l2,-1.06v4.12L14,16v1c0,0.55 -0.45,1 -1,1H9c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h4c0.55,0 1,0.45 1,1V14z"/>
</vector>

View file

@ -48,6 +48,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="2" android:maxLines="2"
android:scrollbars="none"
android:paddingTop="10dp" android:paddingTop="10dp"
android:paddingEnd="10dp" android:paddingEnd="10dp"
android:shadowColor="@color/black" android:shadowColor="@color/black"
@ -65,6 +66,7 @@
android:ellipsize="end" android:ellipsize="end"
android:gravity="bottom" android:gravity="bottom"
android:maxLines="1" android:maxLines="1"
android:scrollbars="none"
android:paddingEnd="10dp" android:paddingEnd="10dp"
android:paddingBottom="5dp" android:paddingBottom="5dp"
android:shadowColor="@color/black" android:shadowColor="@color/black"

View file

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/downloads_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="10dp"
android:padding="10dp"
android:layout_marginVertical="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:text="@string/preferred_download_type"
android:paddingBottom="20dp"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/audio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:paddingEnd="20dp"
android:src="@drawable/ic_music"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="@string/audio" />
</LinearLayout>
<LinearLayout
android:id="@+id/video"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:paddingEnd="20dp"
android:src="@drawable/ic_video"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="@string/video" />
</LinearLayout>
<LinearLayout
android:id="@+id/command"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:paddingEnd="20dp"
android:src="@drawable/ic_terminal"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="@string/command" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
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"
@ -12,8 +12,7 @@
app:layout_constraintDimensionRatio="H,2.66:1" app:layout_constraintDimensionRatio="H,2.66:1"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent">
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/downloads_card_view" android:id="@+id/downloads_card_view"
@ -22,7 +21,6 @@
app:cardCornerRadius="10dp" app:cardCornerRadius="10dp"
app:cardElevation="10dp" app:cardElevation="10dp"
app:cardMaxElevation="12dp" app:cardMaxElevation="12dp"
app:cardBackgroundColor="@color/black"
android:checkable="true" android:checkable="true"
app:strokeWidth="0dp" app:strokeWidth="0dp"
app:cardPreventCornerOverlap="true" app:cardPreventCornerOverlap="true"
@ -35,87 +33,86 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<com.google.android.material.progressindicator.LinearProgressIndicator <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/download_progress"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:layout_gravity="bottom"
android:indeterminate="true"
android:visibility="gone"
android:alpha="0.7"
android:scaleY="100" />
<TextView <TextView
android:id="@+id/downloads_title" android:id="@+id/downloads_title"
android:layout_width="300dp" android:layout_width="0dp"
android:layout_height="100dp" android:layout_height="wrap_content"
android:paddingTop="10dp" android:ellipsize="end"
android:paddingEnd="10dp" android:maxLines="2"
android:paddingBottom="10dp" android:paddingTop="10dp"
android:paddingStart="10dp" android:paddingHorizontal="10dp"
android:textSize="15sp" android:scrollbars="none"
android:textColor="@color/white" android:shadowColor="@color/black"
android:textStyle="bold" android:shadowDx="4"
android:shadowRadius="2" android:shadowDy="4"
android:shadowDx="4" android:shadowRadius="10"
android:shadowDy="4" android:textColor="@color/white"
android:shadowColor="@color/black" /> android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/downloads_download_button_type"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/downloads_info_bottom"
android:layout_width="250dp"
android:layout_height="match_parent"
android:gravity="bottom"
android:paddingTop="10dp"
android:paddingRight="10dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:textSize="12sp"
android:textColor="@color/white"
android:textStyle="bold"
android:shadowRadius="1.5"
android:shadowDx="4"
android:shadowDy="4"
android:shadowColor="@color/black" />
<TextView <TextView
android:id="@+id/downloads_info_time" android:id="@+id/downloads_info_bottom"
android:layout_width="match_parent" android:layout_width="296dp"
android:layout_height="match_parent" android:layout_height="20dp"
android:gravity="bottom|end" android:ellipsize="end"
android:paddingTop="10dp" android:gravity="bottom"
android:paddingRight="10dp" android:maxLines="1"
android:paddingBottom="10dp" android:layout_margin="10dp"
android:paddingLeft="10dp" android:scrollbars="none"
android:textSize="12sp" android:shadowColor="@color/black"
android:textColor="@color/white" android:shadowDx="4"
android:textStyle="bold" android:shadowDy="4"
android:shadowRadius="1.5" android:shadowRadius="10"
android:shadowDx="4" android:textColor="@color/white"
android:shadowDy="4" android:textSize="11sp"
android:shadowColor="@color/black" /> android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/downloads_title"
app:layout_constraintVertical_bias="1.0" />
<LinearLayout <TextView
android:id="@+id/downloads_download_button_layout" android:id="@+id/downloads_info_time"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:gravity="center|right" android:gravity="bottom|end"
android:orientation="horizontal" android:layout_margin="10dp"
android:paddingBottom="10dp" android:shadowColor="@color/black"
android:paddingLeft="20dp" android:shadowDx="4"
android:paddingRight="20dp"> android:shadowDy="4"
android:shadowRadius="10"
android:textColor="@color/white"
android:textSize="11sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/downloads_download_button_type"
app:layout_constraintVertical_bias="1.0" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
style="@style/Widget.Material3.ExtendedFloatingActionButton.Icon.Secondary"
android:id="@+id/downloads_download_button_type" android:id="@+id/downloads_download_button_type"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Icon.Secondary"
android:layout_width="55dp" android:layout_width="55dp"
android:layout_height="55dp" android:layout_height="55dp"
app:cornerRadius="10dp" android:layout_marginHorizontal="20dp"
android:layout_marginEnd="16dp"
android:clickable="false" android:clickable="false"
android:layout_marginStart="10dp" app:cornerRadius="10dp"
/> app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.2" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
</RelativeLayout> </RelativeLayout>

View file

@ -75,7 +75,7 @@
android:layout_marginStart="20dp" android:layout_marginStart="20dp"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<LinearLayout <com.google.android.material.chip.ChipGroup
android:id="@+id/linearLayout3" android:id="@+id/linearLayout3"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -89,11 +89,8 @@
style="@style/Widget.Material3.FloatingActionButton.Large.Primary" style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:clickable="false" android:clickable="false"
android:gravity="center"
android:minWidth="30dp" android:minWidth="30dp"
android:paddingHorizontal="10dp"
app:cornerRadius="10dp" app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -104,11 +101,8 @@
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary" style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:clickable="false" android:clickable="false"
android:gravity="center"
android:minWidth="30dp" android:minWidth="30dp"
android:paddingHorizontal="10dp"
app:cornerRadius="10dp" app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -119,17 +113,14 @@
style="@style/Widget.Material3.FloatingActionButton.Large.Tertiary" style="@style/Widget.Material3.FloatingActionButton.Large.Tertiary"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:clickable="false" android:clickable="false"
android:gravity="center"
android:minWidth="30dp" android:minWidth="30dp"
android:paddingHorizontal="10dp"
app:cornerRadius="10dp" app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</LinearLayout> </com.google.android.material.chip.ChipGroup>
</HorizontalScrollView> </HorizontalScrollView>

View file

@ -10,9 +10,9 @@
app:showAsAction="collapseActionView|ifRoom"/> app:showAsAction="collapseActionView|ifRoom"/>
<item <item
android:id="@+id/edit" android:id="@+id/preferred_download_type"
android:title="@string/directories" android:title="@string/preferred_download_type"
android:icon="@drawable/ic_edit_multiple" android:icon="@drawable/baseline_insert_drive_file_24"
app:showAsAction="collapseActionView|ifRoom"/> app:showAsAction="collapseActionView|ifRoom"/>
</menu> </menu>

View file

@ -18,14 +18,14 @@
</string-array> </string-array>
<string-array name="video_formats"> <string-array name="video_formats">
<item>Worst Quality</item> <item>@string/worst_quality</item>
<item>360p</item> <item>360p</item>
<item>480p</item> <item>480p</item>
<item>720p</item> <item>720p</item>
<item>1080p</item> <item>1080p</item>
<item>1440p</item> <item>1440p</item>
<item>2160p</item> <item>2160p</item>
<item>Best Quality</item> <item>@string/best_quality</item>
</string-array> </string-array>
<string-array name="sponsorblock_settings_entries"> <string-array name="sponsorblock_settings_entries">
@ -88,4 +88,6 @@
<item>video</item> <item>video</item>
<item>command</item> <item>command</item>
</string-array> </string-array>
<string name="worst_quality">Worst Quality</string>
<string name="best_quality">Best Quality</string>
</resources> </resources>