added swipe gestures as a preference & made deleted queued items move to cancelled instead of deleting completely

This commit is contained in:
deniscerri 2023-05-25 20:35:22 +02:00
parent aadac439f3
commit e62b2e6246
No known key found for this signature in database
GPG key ID: 95C43D517D830350
49 changed files with 366 additions and 259 deletions

View file

@ -20,6 +20,13 @@
# hide the original source file name. # hide the original source file name.
#-renamesourcefileattribute SourceFile #-renamesourcefileattribute SourceFile
-if @kotlinx.serialization.Serializable class ** -if @kotlinx.serialization.Serializable class **
-keep class androidx.lifecycle.LiveData { *; }
-keep class com.google.gson.** { *; }
-keep class com.deniscerri.ytdlnis.database.models.AudioPreferences
-keep class com.deniscerri.ytdlnis.database.models.VideoPreferences
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keepclassmembers class <1> { -keepclassmembers class <1> {
static <1>$Companion Companion; static <1>$Companion Companion;
} }

View file

@ -66,7 +66,7 @@ class App : Application() {
if (sp.getInt("spl", 0) != SPL) { if (sp.getInt("spl", 0) != SPL) {
PreferenceManager.setDefaultValues(this, R.xml.root_preferences, true) PreferenceManager.setDefaultValues(this, R.xml.root_preferences, true)
PreferenceManager.setDefaultValues(this, R.xml.downloading_preferences, true) PreferenceManager.setDefaultValues(this, R.xml.downloading_preferences, true)
PreferenceManager.setDefaultValues(this, R.xml.appearance_preferences, true) PreferenceManager.setDefaultValues(this, R.xml.general_preferences, true)
PreferenceManager.setDefaultValues(this, R.xml.processing_preferences, true) PreferenceManager.setDefaultValues(this, R.xml.processing_preferences, true)
PreferenceManager.setDefaultValues(this, R.xml.folders_preference, true) PreferenceManager.setDefaultValues(this, R.xml.folders_preference, true)
PreferenceManager.setDefaultValues(this, R.xml.updating_preferences, true) PreferenceManager.setDefaultValues(this, R.xml.updating_preferences, true)

View file

@ -253,7 +253,7 @@ class MainActivity : BaseActivity() {
window.statusBarColor = getColor(android.R.color.transparent) window.statusBarColor = getColor(android.R.color.transparent)
incognitoHeader.visibility = View.GONE incognitoHeader.visibility = View.GONE
} }
//check logs option //check logs option to show in tablet navbar
if (navigationView is NavigationView){ if (navigationView is NavigationView){
(navigationView as NavigationView).menu.findItem(R.id.downloadLogListFragment).isVisible = preferences.getBoolean("log_downloads", false) (navigationView as NavigationView).menu.findItem(R.id.downloadLogListFragment).isVisible = preferences.getBoolean("log_downloads", false)
} }

View file

@ -76,7 +76,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
if (title.length > 100) { if (title.length > 100) {
title = title.substring(0, 40) + "..." title = title.substring(0, 40) + "..."
} }
itemTitle.text = title.ifEmpty { "<${activity.getString(R.string.defaultValue)}>" } itemTitle.text = title.ifEmpty { item.url }
// Author ---------------------------------- // Author ----------------------------------
val author = card.findViewById<TextView>(R.id.author) val author = card.findViewById<TextView>(R.id.author)
@ -85,7 +85,6 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
if (item.author.isNotEmpty()) info += "" if (item.author.isNotEmpty()) info += ""
info += item.duration info += item.duration
} }
author.text = info.ifEmpty { "<${activity.getString(R.string.defaultValue)}>" }
val type = card.findViewById<MaterialButton>(R.id.download_type) val type = card.findViewById<MaterialButton>(R.id.download_type)
when(item.type){ when(item.type){

View file

@ -70,7 +70,7 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
if (title.length > 100) { if (title.length > 100) {
title = title.substring(0, 40) + "..." title = title.substring(0, 40) + "..."
} }
itemTitle.text = title.ifEmpty { "<${activity.getString(R.string.defaultValue)}>" } itemTitle.text = title.ifEmpty { item.url }
val formatNote = card.findViewById<TextView>(R.id.format_note) val formatNote = card.findViewById<TextView>(R.id.format_note)
if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility = if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility =

View file

@ -5,7 +5,7 @@ import com.deniscerri.ytdlnis.database.models.SearchHistoryItem
@Dao @Dao
interface SearchHistoryDao { interface SearchHistoryDao {
@Query("SELECT * from searchHistory ORDER BY id DESC LIMIT 10") @Query("SELECT * from searchHistory ORDER BY id DESC LIMIT 25")
fun getAll() : List<SearchHistoryItem> fun getAll() : List<SearchHistoryItem>
@Query("SELECT * from searchHistory WHERE `query` COLLATE NOCASE ='%'||:keyword||'%'") @Query("SELECT * from searchHistory WHERE `query` COLLATE NOCASE ='%'||:keyword||'%'")

View file

@ -66,7 +66,7 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
if (inputQueries.size == 1){ if (inputQueries.size == 1){
parseQuery(inputQueries[0], true) parseQuery(inputQueries[0], true)
}else { }else {
repository.itemCount.postValue(2) repository.itemCount.postValue(inputQueries.size)
loadingItems.postValue(true) loadingItems.postValue(true)
inputQueries.forEach { inputQueries.forEach {
parseQuery(it, false) parseQuery(it, false)
@ -100,7 +100,7 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(tag, e.toString()) Log.e(tag, e.toString())
} }
loadingItems.postValue(false) if (resetResults) loadingItems.postValue(false)
res res
} }
} }

View file

@ -2,11 +2,19 @@ package com.deniscerri.ytdlnis.ui
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.util.ThemeUtil import com.deniscerri.ytdlnis.util.ThemeUtil
open class BaseActivity : AppCompatActivity() { open class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
ThemeUtil.updateTheme(this) ThemeUtil.updateTheme(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { v, insets ->
v.setPadding(0, 0, 0, 0)
insets
}
} }
} }

View file

@ -5,7 +5,6 @@ import android.app.Activity
import android.content.* import android.content.*
import android.content.Context.CLIPBOARD_SERVICE import android.content.Context.CLIPBOARD_SERVICE
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.content.res.Configuration
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -42,6 +41,7 @@ import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.InfoUtil import com.deniscerri.ytdlnis.util.InfoUtil
import com.facebook.shimmer.ShimmerFrameLayout import com.facebook.shimmer.ShimmerFrameLayout
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup import com.google.android.material.chip.ChipGroup
@ -94,6 +94,8 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
private var _binding : FragmentHomeBinding? = null private var _binding : FragmentHomeBinding? = null
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
private var appBarLayout: AppBarLayout? = null private var appBarLayout: AppBarLayout? = null
private var materialToolbar: MaterialToolbar? = null
private var loadingItems: Boolean = false
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -130,6 +132,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
searchView = view.findViewById(R.id.search_view) searchView = view.findViewById(R.id.search_view)
linkYouCopied = searchView?.findViewById(R.id.link_you_copied) linkYouCopied = searchView?.findViewById(R.id.link_you_copied)
appBarLayout = view.findViewById(R.id.home_appbarlayout) appBarLayout = view.findViewById(R.id.home_appbarlayout)
materialToolbar = view.findViewById(R.id.home_toolbar)
queriesChipGroup = view.findViewById(R.id.queries) queriesChipGroup = view.findViewById(R.id.queries)
searchSuggestions = view.findViewById(R.id.search_suggestions_scroll_view) searchSuggestions = view.findViewById(R.id.search_suggestions_scroll_view)
searchSuggestionsLinearLayout = view.findViewById(R.id.search_suggestions_linear_layout) searchSuggestionsLinearLayout = view.findViewById(R.id.search_suggestions_linear_layout)
@ -150,7 +153,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
homeAdapter!!.submitList(it) homeAdapter!!.submitList(it)
resultsList = it resultsList = it
if(resultViewModel.itemCount.value!! > 1 || resultViewModel.itemCount.value!! == -1){ if(resultViewModel.itemCount.value!! > 1 || resultViewModel.itemCount.value!! == -1){
if (it.size > 1 && it[0].playlistTitle.isNotEmpty() && it[0].playlistTitle != getString(R.string.trendingPlaylist)){ if (it.size > 1 && it[0].playlistTitle.isNotEmpty() && it[0].playlistTitle != getString(R.string.trendingPlaylist) && !loadingItems){
downloadAllFabCoordinator!!.visibility = VISIBLE downloadAllFabCoordinator!!.visibility = VISIBLE
}else{ }else{
downloadAllFabCoordinator!!.visibility = GONE downloadAllFabCoordinator!!.visibility = GONE
@ -167,7 +170,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
quickLaunchSheet = true quickLaunchSheet = true
} }
resultViewModel.loadingItems.observe(viewLifecycleOwner){ resultViewModel.loadingItems.observe(viewLifecycleOwner){
loadingItems = it
if (it){ if (it){
recyclerView?.setPadding(0,0,0,0) recyclerView?.setPadding(0,0,0,0)
shimmerCards!!.startShimmer() shimmerCards!!.startShimmer()
@ -176,6 +181,11 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
recyclerView?.setPadding(0,0,0,100) recyclerView?.setPadding(0,0,0,100)
shimmerCards!!.stopShimmer() shimmerCards!!.stopShimmer()
shimmerCards!!.visibility = GONE shimmerCards!!.visibility = GONE
if (resultsList!!.size > 1 && resultsList!![0]!!.playlistTitle.isNotEmpty() && resultsList!![0]!!.playlistTitle != getString(R.string.trendingPlaylist)){
downloadAllFabCoordinator!!.visibility = VISIBLE
}else{
downloadAllFabCoordinator!!.visibility = GONE
}
} }
} }
@ -196,7 +206,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
val url = requireArguments().getString("url") val url = requireArguments().getString("url")
if (inputQueries == null) inputQueries = mutableListOf() if (inputQueries == null) inputQueries = mutableListOf()
searchBar?.text = url searchBar?.text = url
inputQueries!!.addAll(url!!.split("\n")) val argList = url!!.split("\n").toMutableList()
argList.removeAll(listOf("", null))
inputQueries!!.addAll(argList)
} }
if (inputQueries != null) { if (inputQueries != null) {

View file

@ -19,7 +19,6 @@ import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
@ -125,9 +124,10 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr
audioPathResultLauncher.launch(intent) audioPathResultLauncher.launch(intent)
} }
freeSpace = view.findViewById(R.id.freespace) freeSpace = view.findViewById(R.id.freespace)
freeSpace.text = String.format( getString(R.string.freespace) + ": " + fileUtil.convertFileSize( val free = fileUtil.convertFileSize(
File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace)
)) freeSpace.text = String.format( getString(R.string.freespace) + ": " + free)
if (free == "?") freeSpace.visibility = View.GONE
var formats = mutableListOf<Format>() var formats = mutableListOf<Format>()
formats.addAll(resultItem.formats.filter { it.format_note.contains("audio", ignoreCase = true) }) formats.addAll(resultItem.formats.filter { it.format_note.contains("audio", ignoreCase = true) })
@ -342,9 +342,10 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr
//downloadViewModel.updateDownload(downloadItem) //downloadViewModel.updateDownload(downloadItem)
saveDir.editText?.setText(fileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE) saveDir.editText?.setText(fileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE)
freeSpace.text = String.format( getString(R.string.freespace) + ": " + fileUtil.convertFileSize( val free = fileUtil.convertFileSize(
File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace)
)) freeSpace.text = String.format( getString(R.string.freespace) + ": " + free)
if (free == "?") freeSpace.visibility = View.GONE
} }
} }

View file

@ -7,7 +7,6 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.format.DateFormat import android.text.format.DateFormat
import android.util.DisplayMetrics import android.util.DisplayMetrics
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

View file

@ -3,7 +3,6 @@ package com.deniscerri.ytdlnis.ui.downloadcard
import android.app.Activity import android.app.Activity
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
@ -20,7 +19,6 @@ import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
@ -129,9 +127,10 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
} }
freeSpace = view.findViewById(R.id.freespace) freeSpace = view.findViewById(R.id.freespace)
freeSpace.text = String.format(getString(R.string.freespace) + ": " + fileUtil.convertFileSize( val free = fileUtil.convertFileSize(
File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace)
)) freeSpace.text = String.format( getString(R.string.freespace) + ": " + free)
if (free == "?") freeSpace.visibility = View.GONE
var formats = mutableListOf<Format>() var formats = mutableListOf<Format>()
formats.addAll(resultItem.formats) formats.addAll(resultItem.formats)
@ -358,6 +357,7 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
val saveSubtitles = view.findViewById<Chip>(R.id.save_subtitles) val saveSubtitles = view.findViewById<Chip>(R.id.save_subtitles)
val subtitleLanguages = view.findViewById<Chip>(R.id.subtitle_languages) val subtitleLanguages = view.findViewById<Chip>(R.id.subtitle_languages)
downloadItem.videoPreferences.subsLanguages = sharedPreferences.getString("subs_lang", "en.*,.*-orig")!!
if (downloadItem.videoPreferences.writeSubs) { if (downloadItem.videoPreferences.writeSubs) {
saveSubtitles.isChecked = true saveSubtitles.isChecked = true
subtitleLanguages.visibility = View.VISIBLE subtitleLanguages.visibility = View.VISIBLE
@ -370,44 +370,9 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
} }
subtitleLanguages.setOnClickListener { subtitleLanguages.setOnClickListener {
val builder = MaterialAlertDialogBuilder(requireContext()) uiUtil.showSubtitleLanguagesDialog(requireActivity(), downloadItem.videoPreferences.subsLanguages){
builder.setTitle(getString(R.string.subtitle_languages)) downloadItem.videoPreferences.subsLanguages = it
val inputLayout = layoutInflater.inflate(R.layout.textinput, null)
val editText = inputLayout.findViewById<EditText>(R.id.url_edittext)
editText.setHint(R.string.subtitle_languages)
editText.setText(downloadItem.videoPreferences.subsLanguages)
editText.setSelection(editText.text.length)
builder.setView(inputLayout)
builder.setPositiveButton(
getString(R.string.ok)
) { dialog: DialogInterface?, which: Int ->
downloadItem.videoPreferences.subsLanguages = editText.text.toString()
} }
// handle the negative button of the alert dialog
builder.setNegativeButton(
getString(R.string.cancel)
) { dialog: DialogInterface?, which: Int -> }
builder.setNeutralButton("?") { dialog: DialogInterface?, which: Int ->
val browserIntent =
Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/yt-dlp/yt-dlp#subtitle-options"))
startActivity(browserIntent)
}
val dialog = builder.create()
editText.doOnTextChanged { text, start, before, count ->
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = editText.text.isNotEmpty()
}
dialog.show()
val imm = context?.getSystemService(AppCompatActivity.INPUT_METHOD_SERVICE) as InputMethodManager
editText!!.postDelayed({
editText.requestFocus()
imm.showSoftInput(editText, 0)
}, 300)
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = editText.text.isNotEmpty()
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).gravity = Gravity.START
} }
val removeAudio = view.findViewById<Chip>(R.id.remove_audio) val removeAudio = view.findViewById<Chip>(R.id.remove_audio)
@ -436,9 +401,10 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
//downloadviewmodel.updateDownload(downloadItem) //downloadviewmodel.updateDownload(downloadItem)
saveDir.editText?.setText(fileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE) saveDir.editText?.setText(fileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE)
freeSpace.text = String.format(getString(R.string.freespace) + ": " + fileUtil.convertFileSize( val free = fileUtil.convertFileSize(
File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace)
)) freeSpace.text = String.format( getString(R.string.freespace) + ": " + free)
if (free == "?") freeSpace.visibility = View.GONE
} }
} }

View file

@ -23,7 +23,6 @@ import com.facebook.shimmer.ShimmerFrameLayout
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -188,6 +187,10 @@ class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, p
okBtn.setOnClickListener { okBtn.setOnClickListener {
val selectedFormats = mutableListOf<Format>() val selectedFormats = mutableListOf<Format>()
if (!::selectedVideo.isInitialized) {
selectedVideo =
chosenFormats.filter { it.vcodec.isNotBlank() && it.vcodec != "none" }.maxByOrNull { it.filesize }!!
}
selectedFormats.add(selectedVideo) selectedFormats.add(selectedVideo)
selectedFormats.addAll(selectedAudios) selectedFormats.addAll(selectedAudios)
listener.onFormatClick(List(items.size){chosenFormats}, selectedFormats) listener.onFormatClick(List(items.size){chosenFormats}, selectedFormats)
@ -199,11 +202,11 @@ class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, p
} }
} }
private fun addFormatsToView(){ private fun addFormatsToView(){
val isSingleAndVideo = items.first()?.type == Type.video && items.count() == 1 val canMultiSelectAudio = items.first()?.type == Type.video && items.count() == 1 && chosenFormats.find { it.format_note.contains("audio", ignoreCase = true) } != null
videoFormatList.removeAllViews() videoFormatList.removeAllViews()
audioFormatList.removeAllViews() audioFormatList.removeAllViews()
if (!isSingleAndVideo) { if (!canMultiSelectAudio) {
audioFormatList.visibility = View.GONE audioFormatList.visibility = View.GONE
videoTitle.visibility = View.GONE videoTitle.visibility = View.GONE
audioTitle.visibility = View.GONE audioTitle.visibility = View.GONE
@ -229,9 +232,13 @@ class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, p
uiUtil.populateFormatCard(formatItem as MaterialCardView, format, null) uiUtil.populateFormatCard(formatItem as MaterialCardView, format, null)
formatItem.setOnClickListener{ clickedformat -> formatItem.setOnClickListener{ clickedformat ->
//if the context is behind a single download card and its a video, allow the ability to multiselect audio formats //if the context is behind a single download card and its a video, allow the ability to multiselect audio formats
if (isSingleAndVideo){ if (canMultiSelectAudio){
val clickedCard = (clickedformat as MaterialCardView) val clickedCard = (clickedformat as MaterialCardView)
if (format.vcodec.isNotBlank() && format.vcodec != "none") { if (format.vcodec.isNotBlank() && format.vcodec != "none") {
if (clickedCard.isChecked) {
listener.onFormatClick(List(items.size){chosenFormats}, listOf(format))
dismiss()
}
videoFormatList.forEach { (it as MaterialCardView).isChecked = false } videoFormatList.forEach { (it as MaterialCardView).isChecked = false }
selectedVideo = format selectedVideo = format
clickedCard.isChecked = true clickedCard.isChecked = true
@ -269,7 +276,7 @@ class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, p
true true
} }
if (isSingleAndVideo){ if (canMultiSelectAudio){
if (format.vcodec.isNotBlank() && format.vcodec != "none") videoFormatList.addView(formatItem) if (format.vcodec.isNotBlank() && format.vcodec != "none") videoFormatList.addView(formatItem)
else audioFormatList.addView(formatItem) else audioFormatList.addView(formatItem)
}else{ }else{

View file

@ -1,7 +1,6 @@
package com.deniscerri.ytdlnis.ui.downloads package com.deniscerri.ytdlnis.ui.downloads
import android.app.Activity import android.app.Activity
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -20,7 +19,6 @@ import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.repository.DownloadRepository import com.deniscerri.ytdlnis.database.repository.DownloadRepository
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
import com.deniscerri.ytdlnis.ui.more.downloadLogs.DownloadLogFragment
import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.NotificationUtil import com.deniscerri.ytdlnis.util.NotificationUtil
import com.google.android.material.progressindicator.LinearProgressIndicator import com.google.android.material.progressindicator.LinearProgressIndicator

View file

@ -2,7 +2,6 @@ package com.deniscerri.ytdlnis.ui.downloads
import android.app.Activity import android.app.Activity
import android.content.DialogInterface import android.content.DialogInterface
import android.content.res.Configuration
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
@ -21,6 +20,7 @@ import androidx.appcompat.view.ActionMode
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -82,8 +82,11 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
cancelledRecyclerView = view.findViewById(R.id.download_recyclerview) cancelledRecyclerView = view.findViewById(R.id.download_recyclerview)
cancelledRecyclerView.adapter = cancelledDownloads cancelledRecyclerView.adapter = cancelledDownloads
val itemTouchHelper = ItemTouchHelper(simpleCallback) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
itemTouchHelper.attachToRecyclerView(cancelledRecyclerView) if (preferences.getBoolean("swipe_gestures", true)){
val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(cancelledRecyclerView)
}
cancelledRecyclerView.layoutManager = GridLayoutManager(context, resources.getInteger(R.integer.grid_size)) cancelledRecyclerView.layoutManager = GridLayoutManager(context, resources.getInteger(R.integer.grid_size))

View file

@ -2,7 +2,6 @@ package com.deniscerri.ytdlnis.ui.downloads
import android.app.Activity import android.app.Activity
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
@ -23,6 +22,7 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -32,7 +32,6 @@ import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
import com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog import com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog
import com.deniscerri.ytdlnis.ui.more.downloadLogs.DownloadLogFragment
import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.UiUtil import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
@ -84,8 +83,11 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
erroredRecyclerView = view.findViewById(R.id.download_recyclerview) erroredRecyclerView = view.findViewById(R.id.download_recyclerview)
erroredRecyclerView.adapter = erroredDownloads erroredRecyclerView.adapter = erroredDownloads
val itemTouchHelper = ItemTouchHelper(simpleCallback) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
itemTouchHelper.attachToRecyclerView(erroredRecyclerView) if (preferences.getBoolean("swipe_gestures", true)){
val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(erroredRecyclerView)
}
erroredRecyclerView.layoutManager = GridLayoutManager(context, resources.getInteger(R.integer.grid_size)) erroredRecyclerView.layoutManager = GridLayoutManager(context, resources.getInteger(R.integer.grid_size))
downloadViewModel.erroredDownloads.observe(viewLifecycleOwner) { downloadViewModel.erroredDownloads.observe(viewLifecycleOwner) {

View file

@ -3,7 +3,6 @@ package com.deniscerri.ytdlnis.ui.downloads
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
@ -33,6 +32,7 @@ import androidx.core.view.forEach
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -129,8 +129,13 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
) )
recyclerView = view.findViewById(R.id.recyclerviewhistorys) recyclerView = view.findViewById(R.id.recyclerviewhistorys)
recyclerView?.adapter = historyAdapter recyclerView?.adapter = historyAdapter
val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(recyclerView) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
if (preferences.getBoolean("swipe_gestures", true)){
val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(recyclerView)
}
recyclerView?.layoutManager = GridLayoutManager(context, resources.getInteger(R.integer.grid_size)) recyclerView?.layoutManager = GridLayoutManager(context, resources.getInteger(R.integer.grid_size))
noResults?.visibility = GONE noResults?.visibility = GONE

View file

@ -2,7 +2,6 @@ package com.deniscerri.ytdlnis.ui.downloads
import android.app.Activity import android.app.Activity
import android.content.DialogInterface import android.content.DialogInterface
import android.content.res.Configuration
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
@ -23,6 +22,7 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -30,6 +30,7 @@ import androidx.work.WorkManager
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.adapter.GenericDownloadAdapter import com.deniscerri.ytdlnis.adapter.GenericDownloadAdapter
import com.deniscerri.ytdlnis.database.models.DownloadItem import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.FileUtil
@ -93,8 +94,11 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
queuedRecyclerView = view.findViewById(R.id.download_recyclerview) queuedRecyclerView = view.findViewById(R.id.download_recyclerview)
queuedRecyclerView.adapter = queuedDownloads queuedRecyclerView.adapter = queuedDownloads
val itemTouchHelper = ItemTouchHelper(simpleCallback) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
itemTouchHelper.attachToRecyclerView(queuedRecyclerView) if (preferences.getBoolean("swipe_gestures", true)){
val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(queuedRecyclerView)
}
queuedRecyclerView.layoutManager = GridLayoutManager(context, resources.getInteger(R.integer.grid_size)) queuedRecyclerView.layoutManager = GridLayoutManager(context, resources.getInteger(R.integer.grid_size))
downloadViewModel.queuedDownloads.observe(viewLifecycleOwner) { downloadViewModel.queuedDownloads.observe(viewLifecycleOwner) {
@ -262,11 +266,13 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
YoutubeDL.getInstance().destroyProcessById(id.toString()) YoutubeDL.getInstance().destroyProcessById(id.toString())
WorkManager.getInstance(requireContext()).cancelUniqueWork(id.toString()) WorkManager.getInstance(requireContext()).cancelUniqueWork(id.toString())
notificationUtil.cancelDownloadNotification(id) notificationUtil.cancelDownloadNotification(id)
downloadViewModel.deleteDownload(item!!) item!!.status = DownloadRepository.Status.Cancelled.toString()
downloadViewModel.updateDownload(item)
Snackbar.make(queuedRecyclerView, getString(R.string.cancelled) + ": " + item.title, Snackbar.LENGTH_LONG) Snackbar.make(queuedRecyclerView, getString(R.string.cancelled) + ": " + item.title, Snackbar.LENGTH_LONG)
.setAction(getString(R.string.undo)) { .setAction(getString(R.string.undo)) {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
downloadViewModel.deleteDownload(item)
downloadViewModel.queueDownloads(listOf(item)) downloadViewModel.queueDownloads(listOf(item))
} }
}.show() }.show()

View file

@ -1,6 +1,5 @@
package com.deniscerri.ytdlnis.ui.more package com.deniscerri.ytdlnis.ui.more
import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
@ -13,6 +12,7 @@ import android.widget.RelativeLayout
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -69,8 +69,11 @@ class CommandTemplatesFragment : Fragment(), TemplatesAdapter.OnItemClickListene
recyclerView = view.findViewById(R.id.template_recyclerview) recyclerView = view.findViewById(R.id.template_recyclerview)
recyclerView.layoutManager = LinearLayoutManager(context) recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = templatesAdapter recyclerView.adapter = templatesAdapter
val itemTouchHelper = ItemTouchHelper(simpleCallback) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
itemTouchHelper.attachToRecyclerView(recyclerView) if (preferences.getBoolean("swipe_gestures", true)){
val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(recyclerView)
}
uiUtil = UiUtil(FileUtil()) uiUtil = UiUtil(FileUtil())

View file

@ -1,6 +1,5 @@
package com.deniscerri.ytdlnis.ui.more package com.deniscerri.ytdlnis.ui.more
import android.content.Context
import android.content.Context.INPUT_METHOD_SERVICE import android.content.Context.INPUT_METHOD_SERVICE
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
@ -19,6 +18,7 @@ import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -74,9 +74,11 @@ class CookiesFragment : Fragment(), CookieAdapter.OnItemClickListener {
recyclerView = view.findViewById(R.id.template_recyclerview) recyclerView = view.findViewById(R.id.template_recyclerview)
recyclerView.layoutManager = LinearLayoutManager(context) recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = listAdapter recyclerView.adapter = listAdapter
val itemTouchHelper = ItemTouchHelper(simpleCallback) val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
itemTouchHelper.attachToRecyclerView(recyclerView) if (preferences.getBoolean("swipe_gestures", true)){
val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(recyclerView)
}
uiUtil = UiUtil(FileUtil()) uiUtil = UiUtil(FileUtil())
cookiesViewModel = ViewModelProvider(this)[CookieViewModel::class.java] cookiesViewModel = ViewModelProvider(this)[CookieViewModel::class.java]

View file

@ -14,7 +14,6 @@ import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.MainActivity import com.deniscerri.ytdlnis.MainActivity
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.ui.more.downloadLogs.DownloadLogListFragment
import com.deniscerri.ytdlnis.ui.more.settings.SettingsActivity import com.deniscerri.ytdlnis.ui.more.settings.SettingsActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlin.system.exitProcess import kotlin.system.exitProcess

View file

@ -1,7 +1,6 @@
package com.deniscerri.ytdlnis.ui.more.downloadLogs package com.deniscerri.ytdlnis.ui.more.downloadLogs
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context
import android.content.Context.CLIPBOARD_SERVICE import android.content.Context.CLIPBOARD_SERVICE
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@ -14,7 +13,6 @@ import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.deniscerri.ytdlnis.MainActivity import com.deniscerri.ytdlnis.MainActivity
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.ui.BaseActivity
import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import java.io.File import java.io.File

View file

@ -1,14 +1,15 @@
package com.deniscerri.ytdlnis.ui.more.settings package com.deniscerri.ytdlnis.ui.more.settings
import android.content.DialogInterface import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.EditTextPreference import androidx.preference.EditTextPreference
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.MultiSelectListPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.databinding.DialogTextPreferenceBinding import com.deniscerri.ytdlnis.databinding.TextinputBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputLayout
abstract class BaseSettingsFragment : PreferenceFragmentCompat() { abstract class BaseSettingsFragment : PreferenceFragmentCompat() {
@ -43,19 +44,26 @@ abstract class BaseSettingsFragment : PreferenceFragmentCompat() {
.show() .show()
} }
is EditTextPreference -> { is EditTextPreference -> {
val binding = DialogTextPreferenceBinding.inflate(layoutInflater) val binding = TextinputBinding.inflate(layoutInflater)
binding.input.setText(preference.text) binding.urlEdittext.setText(preference.text)
MaterialAlertDialogBuilder(requireContext()) binding.urlTextinput.findViewById<TextInputLayout>(R.id.url_textinput).hint = preference.title
val dialog = MaterialAlertDialogBuilder(requireContext())
.setTitle(preference.title) .setTitle(preference.title)
.setView(binding.root) .setView(binding.root)
.setPositiveButton(android.R.string.ok) { _, _ -> .setPositiveButton(android.R.string.ok) { _, _ ->
val newValue = binding.input.text.toString() val newValue = binding.urlEdittext.text.toString()
if (preference.callChangeListener(newValue)) { if (preference.callChangeListener(newValue)) {
preference.text = newValue preference.text = newValue
} }
} }
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.show() dialog.show()
val imm = context?.getSystemService(AppCompatActivity.INPUT_METHOD_SERVICE) as InputMethodManager
binding.urlEdittext.setSelection(binding.urlEdittext.text!!.length)
binding.urlEdittext.postDelayed({
binding.urlEdittext.requestFocus()
imm.showSoftInput(binding.urlEdittext, 0)
}, 300)
} }
/** /**
* Otherwise show the normal dialog, dialogs for other preference types are not supported yet * Otherwise show the normal dialog, dialogs for other preference types are not supported yet

View file

@ -20,8 +20,8 @@ import com.deniscerri.ytdlnis.util.UpdateUtil
import java.util.Locale import java.util.Locale
class AppearanceSettingsFragment : BaseSettingsFragment() { class GeneralSettingsFragment : BaseSettingsFragment() {
override val title: Int = R.string.appearance override val title: Int = R.string.general
private var language: ListPreference? = null private var language: ListPreference? = null
private var theme: ListPreference? = null private var theme: ListPreference? = null
@ -34,7 +34,7 @@ class AppearanceSettingsFragment : BaseSettingsFragment() {
private var activeDownloadCount = 0 private var activeDownloadCount = 0
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.appearance_preferences, rootKey) setPreferencesFromResource(R.xml.general_preferences, rootKey)
updateUtil = UpdateUtil(requireContext()) updateUtil = UpdateUtil(requireContext())
fileUtil = FileUtil() fileUtil = FileUtil()

View file

@ -4,14 +4,11 @@ import android.os.Bundle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.BuildConfig
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.util.UpdateUtil import com.deniscerri.ytdlnis.util.UpdateUtil
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.yausername.youtubedl_android.YoutubeDL import com.yausername.youtubedl_android.YoutubeDL
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class UpdateSettingsFragment : BaseSettingsFragment() { class UpdateSettingsFragment : BaseSettingsFragment() {

View file

@ -9,19 +9,14 @@ import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.Format import com.deniscerri.ytdlnis.database.models.Format
import com.deniscerri.ytdlnis.database.models.ResultItem import com.deniscerri.ytdlnis.database.models.ResultItem
import com.google.common.net.HttpHeaders.USER_AGENT
import com.google.gson.Gson import com.google.gson.Gson
import com.yausername.youtubedl_android.YoutubeDL import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLRequest import com.yausername.youtubedl_android.YoutubeDLRequest
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import java.io.BufferedReader import java.io.BufferedReader
import java.io.File import java.io.File
import java.io.IOException
import java.io.InputStreamReader import java.io.InputStreamReader
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URL import java.net.URL

View file

@ -5,23 +5,29 @@ import android.app.Activity
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.util.Log import android.util.Log
import android.view.Gravity
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.Window import android.view.Window
import android.view.inputmethod.InputMethodManager
import android.widget.Button import android.widget.Button
import android.widget.EditText
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
@ -37,6 +43,7 @@ import com.google.android.material.chip.ChipGroup
import com.google.android.material.datepicker.CalendarConstraints import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.DateValidatorPointForward import com.google.android.material.datepicker.DateValidatorPointForward
import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.google.android.material.timepicker.MaterialTimePicker import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat import com.google.android.material.timepicker.TimeFormat
@ -372,7 +379,7 @@ class UiUtil(private val fileUtil: FileUtil) {
} }
} }
if (format.fps.isNullOrBlank()) fpsParent?.visibility = View.GONE if (format.fps.isNullOrBlank() || format.fps == "0") fpsParent?.visibility = View.GONE
else { else {
fpsParent?.findViewById<TextView>(R.id.fps_value)?.text = format.fps fpsParent?.findViewById<TextView>(R.id.fps_value)?.text = format.fps
fpsParent?.setOnClickListener { fpsParent?.setOnClickListener {
@ -400,6 +407,48 @@ class UiUtil(private val fileUtil: FileUtil) {
) )
} }
fun showSubtitleLanguagesDialog(context: Activity, currentValue: String, ok: (newValue: String) -> Unit){
val builder = MaterialAlertDialogBuilder(context)
builder.setTitle(context.getString(R.string.subtitle_languages))
val inputLayout = context.layoutInflater.inflate(R.layout.textinput, null)
val editText = inputLayout.findViewById<EditText>(R.id.url_edittext)
inputLayout.findViewById<TextInputLayout>(R.id.url_textinput).hint = context.getString(R.string.subtitle_languages)
editText.setText(currentValue)
editText.setSelection(editText.text.length)
builder.setView(inputLayout)
builder.setPositiveButton(
context.getString(R.string.ok)
) { dialog: DialogInterface?, which: Int ->
ok(editText.text.toString())
}
// handle the negative button of the alert dialog
builder.setNegativeButton(
context.getString(R.string.cancel)
) { dialog: DialogInterface?, which: Int -> }
builder.setNeutralButton("?") { dialog: DialogInterface?, which: Int ->
val browserIntent =
Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/yt-dlp/yt-dlp#subtitle-options"))
context.startActivity(browserIntent)
}
val dialog = builder.create()
editText.doOnTextChanged { text, start, before, count ->
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = editText.text.isNotEmpty()
}
dialog.show()
val imm = context.getSystemService(AppCompatActivity.INPUT_METHOD_SERVICE) as InputMethodManager
editText.setSelection(editText.text!!.length)
editText!!.postDelayed({
editText.requestFocus()
imm.showSoftInput(editText, 0)
}, 300)
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = editText.text.isNotEmpty()
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).gravity = Gravity.START
}
private fun copyToClipboard(text: String, activity: Activity){ private fun copyToClipboard(text: String, activity: Activity){
val clipboard = activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clipboard = activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager

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:colorAccent" android:pathData="M14,17L4,17v2h10v-2zM20,9L4,9v2h16L20,9zM4,15h16v-2L4,13v2zM4,5v2h16L20,5L4,5z"/>
</vector>

View file

@ -0,0 +1,6 @@
<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:colorAccent" android:pathData="M18.89,14.75l-4.09,-2.04c-0.28,-0.14 -0.58,-0.21 -0.89,-0.21H13v-6C13,5.67 12.33,5 11.5,5S10,5.67 10,6.5v10.74L6.75,16.5c-0.33,-0.07 -0.68,0.03 -0.92,0.28L5,17.62l4.54,4.79C9.92,22.79 10.68,23 11.21,23h6.16c1,0 1.84,-0.73 1.98,-1.72l0.63,-4.46C20.1,15.97 19.66,15.14 18.89,14.75z"/>
<path android:fillColor="?android:colorAccent" android:pathData="M20.13,3.87C18.69,2.17 15.6,1 12,1S5.31,2.17 3.87,3.87L2,2v5h5L4.93,4.93c1,-1.29 3.7,-2.43 7.07,-2.43s6.07,1.14 7.07,2.43L17,7h5V2L20.13,3.87z"/>
</vector>

View file

@ -103,6 +103,7 @@
app:liftOnScroll="true" app:liftOnScroll="true"
android:background="@null" android:background="@null"
android:elevation="0dp" android:elevation="0dp"
android:fitsSystemWindows="true"
app:elevation="0dp" app:elevation="0dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View file

@ -103,6 +103,7 @@
app:liftOnScroll="true" app:liftOnScroll="true"
android:background="@null" android:background="@null"
android:elevation="0dp" android:elevation="0dp"
android:fitsSystemWindows="true"
app:elevation="0dp" app:elevation="0dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View file

@ -103,6 +103,7 @@
app:liftOnScroll="true" app:liftOnScroll="true"
android:background="@null" android:background="@null"
android:elevation="0dp" android:elevation="0dp"
android:fitsSystemWindows="true"
app:elevation="0dp" app:elevation="0dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View file

@ -199,7 +199,7 @@
<TextView <TextView
android:id="@+id/output" android:id="@+id/output"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="40dp" android:layout_height="45dp"
android:clickable="true" android:clickable="true"
android:ellipsize="end" android:ellipsize="end"
android:focusable="true" android:focusable="true"

View file

@ -4,6 +4,8 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.deniscerri.ytdlnis.ui.more.settings.SettingsActivity"> tools:context="com.deniscerri.ytdlnis.ui.more.settings.SettingsActivity">
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
@ -23,8 +25,7 @@
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar" android:id="@+id/collapsing_toolbar"

View file

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/inputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>

View file

@ -7,6 +7,7 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
app:checkedIcon="@null" app:checkedIcon="@null"
app:strokeColor="?attr/colorPrimary"
app:cardPreventCornerOverlap="true" app:cardPreventCornerOverlap="true"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

View file

@ -256,6 +256,21 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none">
<com.google.android.material.chip.ChipGroup
android:scrollbars="none"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/save_subtitles" android:id="@+id/save_subtitles"
style="@style/Widget.Material3.Chip.Filter.Elevated" style="@style/Widget.Material3.Chip.Filter.Elevated"

View file

@ -10,6 +10,7 @@
android:elevation="0dp" android:elevation="0dp"
app:liftOnScrollTargetViewId="@id/recyclerviewhistorys" app:liftOnScrollTargetViewId="@id/recyclerviewhistorys"
app:elevation="0dp" app:elevation="0dp"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View file

@ -104,6 +104,7 @@
android:background="@null" android:background="@null"
android:elevation="0dp" android:elevation="0dp"
app:elevation="0dp" app:elevation="0dp"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@ -124,49 +125,53 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<RelativeLayout
<androidx.recyclerview.widget.RecyclerView
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent" android:layout_width="match_parent"
android:id="@+id/recyclerViewHome" android:layout_height="wrap_content">
android:orientation="vertical"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:clipToPadding="false"
android:paddingBottom="100dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
/>
<androidx.recyclerview.widget.RecyclerView
<com.facebook.shimmer.ShimmerFrameLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/shimmer_results_framelayout"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:id="@+id/recyclerViewHome"
android:orientation="vertical"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="10dp" android:scrollbars="vertical"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:clipToPadding="false"
android:paddingBottom="100dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
/>
<com.facebook.shimmer.ShimmerFrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/recyclerViewHome"
android:id="@+id/shimmer_results_framelayout"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/result_card_shimmer" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<include layout="@layout/result_card_shimmer" /> <include layout="@layout/result_card_shimmer" />
<include layout="@layout/result_card_shimmer" /> <include layout="@layout/result_card_shimmer" />
<include layout="@layout/result_card_shimmer" /> <include layout="@layout/result_card_shimmer" />
<include layout="@layout/result_card_shimmer" /> <include layout="@layout/result_card_shimmer" />
<include layout="@layout/result_card_shimmer" />
</LinearLayout> </LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout> </com.facebook.shimmer.ShimmerFrameLayout>
</RelativeLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/home_fabs" android:id="@+id/home_fabs"

View file

@ -18,8 +18,9 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:cardCornerRadius="20dp" app:cardCornerRadius="20dp"
app:checkedIcon="@null"
app:cardElevation="5dp" app:cardElevation="5dp"
app:strokeColor="?attr/colorPrimary"
app:checkedIconTint="?attr/colorPrimary"
app:cardMaxElevation="12dp" app:cardMaxElevation="12dp"
app:cardPreventCornerOverlap="true" app:cardPreventCornerOverlap="true"
android:checkable="true" android:checkable="true"

View file

@ -11,6 +11,7 @@
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:elevation="0dp" android:elevation="0dp"
app:elevation="0dp" app:elevation="0dp"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View file

@ -4,7 +4,7 @@
app:startDestination="@id/mainSettingsFragment"> app:startDestination="@id/mainSettingsFragment">
<fragment <fragment
android:id="@+id/appearanceSettingsFragment" android:id="@+id/appearanceSettingsFragment"
android:name="com.deniscerri.ytdlnis.ui.more.settings.AppearanceSettingsFragment" android:name="com.deniscerri.ytdlnis.ui.more.settings.GeneralSettingsFragment"
android:label="AppearanceSettingsFragment" /> android:label="AppearanceSettingsFragment" />
<fragment <fragment
android:id="@+id/processingSettingsFragment" android:id="@+id/processingSettingsFragment"

View file

@ -264,5 +264,9 @@
<string name="socks5_proxy">Socks5 Proxy URL</string> <string name="socks5_proxy">Socks5 Proxy URL</string>
<string name="search_suggestions">Search Suggestions</string> <string name="search_suggestions">Search Suggestions</string>
<string name="search_suggestions_summary">Get search suggestions from google</string> <string name="search_suggestions_summary">Get search suggestions from google</string>
<string name="preferred_format_id_summary">Selec the format with this ID in the download card</string> <string name="preferred_format_id_summary">Select the format with this ID in the download card</string>
<string name="misc">Misc</string>
<string name="general">General</string>
<string name="swipe_gestures">Swipe Gestures</string>
<string name="swipe_gestures_summary">Swipe items for certain actions</string>
</resources> </resources>

View file

@ -63,5 +63,4 @@
<item name="maxLines">2</item> <item name="maxLines">2</item>
<item name="animationMode">slide</item> <item name="animationMode">slide</item>
</style> </style>
</resources> </resources>

View file

@ -6,7 +6,7 @@
<item name="alertDialogTheme">@style/ThemeOverlay.Material3.MaterialAlertDialog</item> <item name="alertDialogTheme">@style/ThemeOverlay.Material3.MaterialAlertDialog</item>
<item name="dialogCornerRadius">28dp</item> <item name="dialogCornerRadius">28dp</item>
<item name="windowActionModeOverlay">true</item> <item name="windowActionModeOverlay">true</item>
<item name="actionBarTheme">@style/ThemeOverlay.Material3.Dark.ActionBar</item> <item name="actionBarTheme">@style/ThemeOverlay.Material3.Light</item>
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">true</item> <item name="android:windowLightNavigationBar" tools:ignore="NewApi">true</item>
<item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat.Material3</item> <item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat.Material3</item>
<item name="snackbarStyle">@style/snackBarStyle</item> <item name="snackbarStyle">@style/snackBarStyle</item>

View file

@ -1,84 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ListPreference
android:entries="@array/language_values"
android:entryValues="@array/language_values"
android:icon="@drawable/baseline_translate_24"
app:key="app_language"
app:summary="en"
app:title="@string/language" />
<ListPreference
android:entries="@array/themes"
android:entryValues="@array/themes_values"
android:icon="@drawable/baseline_format_paint_24"
app:defaultValue="System"
app:key="ytdlnis_theme"
app:summary="@string/defaultValue"
app:title="@string/Theme" />
<ListPreference
android:entries="@array/accents"
android:entryValues="@array/accents_values"
android:icon="@drawable/baseline_color_lens_24"
app:defaultValue="blue"
app:key="theme_accent"
app:summary="Blue"
app:title="@string/accents" />
<SwitchPreferenceCompat
android:widgetLayout="@layout/preferece_material_switch"
app:defaultValue="false"
android:icon="@drawable/baseline_invert_colors_24"
android:key="high_contrast"
app:summary="@string/pure_theme_summary"
app:title="@string/high_contrast" />
<SwitchPreferenceCompat
android:widgetLayout="@layout/preferece_material_switch"
app:defaultValue="false"
android:icon="@drawable/baseline_recommend_24"
android:key="home_recommendations"
app:summary="@string/video_recommendations_summary"
app:title="@string/video_recommendations" />
<ListPreference
android:defaultValue="Home"
android:entries="@array/start_destination"
android:entryValues="@array/start_destination_values"
app:icon="@drawable/baseline_add_to_home_screen_24"
app:useSimpleSummaryProvider="true"
app:key="start_destination"
app:title="@string/preferred_home_screen" />
<ListPreference
android:defaultValue="ytsearch"
android:entries="@array/search_engines"
android:entryValues="@array/search_engines_values"
android:icon="@drawable/baseline_manage_search_24"
app:key="search_engine"
app:summary="@string/preferred_search_engine_summary"
app:title="@string/preferred_search_engine" />
<SwitchPreferenceCompat
android:widgetLayout="@layout/preferece_material_switch"
app:defaultValue="false"
android:icon="@drawable/ic_search_accent"
android:key="search_suggestions"
app:summary="@string/search_suggestions_summary"
app:title="@string/search_suggestions" />
<ListPreference
android:defaultValue=""
android:entries="@array/countries"
android:entryValues="@array/countries_values"
app:icon="@drawable/ic_language"
app:useSimpleSummaryProvider="true"
app:dependency="home_recommendations"
app:key="locale"
app:title="@string/preferred_locale" />
</PreferenceScreen>

View file

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory android:title="Locale">
<ListPreference
android:entries="@array/language_values"
android:entryValues="@array/language_values"
android:icon="@drawable/baseline_translate_24"
app:key="app_language"
app:summary="en"
app:title="@string/language" />
<ListPreference
android:defaultValue=""
android:entries="@array/countries"
android:entryValues="@array/countries_values"
app:icon="@drawable/ic_language"
app:useSimpleSummaryProvider="true"
app:dependency="home_recommendations"
app:key="locale"
app:title="@string/preferred_locale" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/appearance">
<ListPreference
android:entries="@array/themes"
android:entryValues="@array/themes_values"
android:icon="@drawable/baseline_format_paint_24"
app:defaultValue="System"
app:key="ytdlnis_theme"
app:summary="@string/defaultValue"
app:title="@string/Theme" />
<ListPreference
android:entries="@array/accents"
android:entryValues="@array/accents_values"
android:icon="@drawable/baseline_color_lens_24"
app:defaultValue="blue"
app:key="theme_accent"
app:summary="Blue"
app:title="@string/accents" />
<SwitchPreferenceCompat
android:widgetLayout="@layout/preferece_material_switch"
app:defaultValue="false"
android:icon="@drawable/baseline_invert_colors_24"
android:key="high_contrast"
app:summary="@string/pure_theme_summary"
app:title="@string/high_contrast" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/misc">
<SwitchPreferenceCompat
android:widgetLayout="@layout/preferece_material_switch"
app:defaultValue="false"
android:icon="@drawable/baseline_recommend_24"
android:key="home_recommendations"
app:summary="@string/video_recommendations_summary"
app:title="@string/video_recommendations" />
<ListPreference
android:defaultValue="Home"
android:entries="@array/start_destination"
android:entryValues="@array/start_destination_values"
app:icon="@drawable/baseline_add_to_home_screen_24"
app:useSimpleSummaryProvider="true"
app:key="start_destination"
app:title="@string/preferred_home_screen" />
<ListPreference
android:defaultValue="ytsearch"
android:entries="@array/search_engines"
android:entryValues="@array/search_engines_values"
android:icon="@drawable/baseline_manage_search_24"
app:key="search_engine"
app:summary="@string/preferred_search_engine_summary"
app:title="@string/preferred_search_engine" />
<SwitchPreferenceCompat
android:widgetLayout="@layout/preferece_material_switch"
app:defaultValue="false"
android:icon="@drawable/ic_search_accent"
android:key="search_suggestions"
app:summary="@string/search_suggestions_summary"
app:title="@string/search_suggestions" />
<SwitchPreferenceCompat
android:widgetLayout="@layout/preferece_material_switch"
app:defaultValue="true"
android:icon="@drawable/baseline_swipe_24"
android:key="swipe_gestures"
app:summary="@string/swipe_gestures_summary"
app:title="@string/swipe_gestures" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -57,6 +57,15 @@
app:summary="@string/save_subs_desc" app:summary="@string/save_subs_desc"
app:title="@string/save_subs" /> app:title="@string/save_subs" />
<EditTextPreference
android:icon="@drawable/baseline_subject_24"
app:key="subs_lang"
android:dependency="write_subtitles"
app:useSimpleSummaryProvider="true"
app:defaultValue="en.*,.*-orig"
app:title="@string/subtitle_languages" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:widgetLayout="@layout/preferece_material_switch" android:widgetLayout="@layout/preferece_material_switch"
app:defaultValue="true" app:defaultValue="true"

View file

@ -3,8 +3,8 @@
<Preference <Preference
android:key="appearance" android:key="appearance"
app:icon="@drawable/baseline_format_paint_24" app:icon="@drawable/ic_settings"
android:title="@string/appearance"/> android:title="@string/general"/>
<Preference <Preference
android:key="folders" android:key="folders"