qol fixes

This commit is contained in:
deniscerri 2023-05-06 22:34:50 +02:00
parent fa341a53f2
commit 376ee73af2
No known key found for this signature in database
GPG key ID: 95C43D517D830350
33 changed files with 563 additions and 762 deletions

View file

@ -128,7 +128,7 @@ dependencies {
implementation "androidx.appcompat:appcompat:$appCompatVer"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation 'com.google.android.material:material:1.9.0-rc01'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.3.0'
implementation 'androidx.preference:preference:1.2.0'
@ -176,7 +176,6 @@ dependencies {
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.11'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0'
implementation "com.google.android.exoplayer:exoplayer:2.18.5"
implementation "com.google.android.exoplayer:exoplayer:2.18.6"
implementation 'it.xabaras.android:recyclerview-swipedecorator:1.4'
}

View file

@ -6,11 +6,14 @@ import android.app.UiModeManager.MODE_NIGHT_YES
import android.widget.Toast
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import androidx.work.Configuration
import androidx.work.WorkManager
import com.deniscerri.ytdlnis.util.NotificationUtil
import com.deniscerri.ytdlnis.util.UpdateUtil
import com.google.android.material.color.DynamicColors
import com.google.android.material.snackbar.Snackbar
import com.yausername.aria2c.Aria2c
import com.yausername.ffmpeg.FFmpeg
import com.yausername.youtubedl_android.YoutubeDL
@ -35,12 +38,19 @@ class App : Application() {
false
)
val sharedPreferences = getSharedPreferences("root_preferences", MODE_PRIVATE)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
applicationScope = CoroutineScope(SupervisorJob())
applicationScope.launch((Dispatchers.IO)) {
try {
initLibraries()
val appVer = sharedPreferences.getString("version", "")!!
if(appVer.isEmpty() || appVer != BuildConfig.VERSION_NAME){
UpdateUtil(this@App).updateYoutubeDL()
sharedPreferences.edit(commit = true){
putString("version", BuildConfig.VERSION_NAME)
}
}
}catch (e: Exception){
Toast.makeText(this@App, e.message, Toast.LENGTH_SHORT).show()
e.printStackTrace()

View file

@ -1,7 +1,6 @@
package com.deniscerri.ytdlnis
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
@ -18,6 +17,7 @@ import android.view.View
import android.view.WindowInsets
import android.widget.CheckBox
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.forEach
@ -26,6 +26,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.database.viewmodel.CookieViewModel
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
@ -69,7 +70,7 @@ class MainActivity : BaseActivity() {
resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java]
cookieViewModel = ViewModelProvider(this)[CookieViewModel::class.java]
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
preferences = context.getSharedPreferences("root_preferences", MODE_PRIVATE)
preferences = PreferenceManager.getDefaultSharedPreferences(context)
if (preferences.getBoolean("incognito", false)){
resultViewModel.deleteAll()
@ -98,7 +99,7 @@ class MainActivity : BaseActivity() {
}
}
val sharedPreferences = getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
val startDestination = sharedPreferences.getString("start_destination", "")
val graph = navController.navInflater.inflate(R.navigation.nav_graph)
@ -154,7 +155,7 @@ class MainActivity : BaseActivity() {
val dialogView = layoutInflater.inflate(R.layout.dialog_terminate_app, null)
val checkbox = dialogView.findViewById<CheckBox>(R.id.doNotShowAgain)
terminateDialog.setView(dialogView)
checkbox.setOnCheckedChangeListener { compoundButton, b ->
checkbox.setOnCheckedChangeListener { compoundButton, _ ->
doNotShowAgain = compoundButton.isChecked
}
@ -179,14 +180,6 @@ class MainActivity : BaseActivity() {
handleIntents(intent)
}
fun hideNav() {
navigationView.visibility = View.GONE
}
fun showNav() {
navigationView.visibility = View.VISIBLE
}
fun disableBottomNavigation(){
if (navigationView is NavigationBarView){
(navigationView as NavigationBarView).menu.forEach { it.isEnabled = false }
@ -272,8 +265,10 @@ class MainActivity : BaseActivity() {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
}
if (!checkNotificationPermission()){
permissions.add(Manifest.permission.POST_NOTIFICATIONS)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (!checkNotificationPermission()){
permissions.add(Manifest.permission.POST_NOTIFICATIONS)
}
}
if (permissions.isNotEmpty()){
@ -329,6 +324,7 @@ class MainActivity : BaseActivity() {
}
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private fun checkNotificationPermission(): Boolean {
return (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED)

View file

@ -8,7 +8,7 @@ interface SearchHistoryDao {
@Query("SELECT * from searchHistory ORDER BY id DESC LIMIT 10")
fun getAll() : List<SearchHistoryItem>
@Query("SELECT * from searchHistory WHERE query COLLATE NOCASE ='%'||:keyword||'%'")
@Query("SELECT * from searchHistory WHERE `query` COLLATE NOCASE ='%'||:keyword||'%'")
fun getAllByKeyword(keyword: String) : List<SearchHistoryItem>
@Insert(onConflict = OnConflictStrategy.IGNORE)
@ -17,6 +17,6 @@ interface SearchHistoryDao {
@Query("DELETE FROM searchHistory")
suspend fun deleteAll()
@Query("DELETE FROM searchHistory WHERE query=:query")
@Query("DELETE FROM searchHistory WHERE `query`=:query")
suspend fun delete(query: String)
}

View file

@ -9,6 +9,7 @@ import android.widget.Toast
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager
import androidx.work.*
import com.deniscerri.ytdlnis.App
import com.deniscerri.ytdlnis.R
@ -48,8 +49,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
init {
val dao = DBManager.getInstance(application).downloadDao
repository = DownloadRepository(dao)
sharedPreferences =
getApplication<App>().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(application)
commandTemplateDao = DBManager.getInstance(application).commandTemplateDao
allDownloads = repository.allDownloads

View file

@ -8,6 +8,7 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.App
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.DBManager
@ -37,7 +38,7 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
items = repository.allResults
loadingItems.postValue(false)
itemCount = repository.itemCount
sharedPreferences = application.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(application)
}
fun checkTrending() = viewModelScope.launch(Dispatchers.IO){

View file

@ -25,6 +25,7 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.MainActivity
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.DownloadItem
@ -81,7 +82,7 @@ class ShareActivity : BaseActivity() {
resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java]
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
cookieViewModel = ViewModelProvider(this)[CookieViewModel::class.java]
sharedPreferences = getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
cookieViewModel.updateCookiesFile()
val intent = intent

View file

@ -25,6 +25,7 @@ import androidx.core.widget.doAfterTextChanged
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdlnis.MainActivity
@ -48,14 +49,13 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.search.SearchBar
import com.google.android.material.search.SearchView
import com.google.android.material.search.SearchView.TransitionState
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.*
class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickListener {
class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListener {
private var inputQueries: MutableList<String>? = null
private var homeAdapter: HomeAdapter? = null
@ -120,13 +120,13 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
resultsList = mutableListOf()
selectedObjects = ArrayList()
sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
//initViews
shimmerCards = view.findViewById(R.id.shimmer_results_framelayout)
searchBar = view.findViewById(R.id.search_bar)
searchView = view.findViewById(R.id.search_view)
linkYouCopied = searchView?.findViewById<ConstraintLayout>(R.id.link_you_copied)
linkYouCopied = searchView?.findViewById(R.id.link_you_copied)
appBarLayout = view.findViewById(R.id.home_appbarlayout)
queriesChipGroup = view.findViewById(R.id.queries)
searchSuggestions = view.findViewById(R.id.search_suggestions_scroll_view)
@ -279,12 +279,10 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
updateSearchViewItems(it, linkYouCopied)
}
searchView!!.editText.setOnTouchListener(OnTouchListener { v, event ->
searchView!!.editText.setOnTouchListener(OnTouchListener { _, event ->
try{
val drawableLeft = 0
val drawableTop = 1
val drawableRight = 2
val drawableBottom = 3
if (event.action == MotionEvent.ACTION_UP) {
if (
(isRightToLeft && (event.x < (searchView!!.editText.left - searchView!!.editText.compoundDrawables[drawableLeft].bounds.width()))) ||
@ -333,7 +331,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
}
true
}
queriesChipGroup!!.addOnLayoutChangeListener { view, i, i2, i3, i4, i5, i6, i7, i8 ->
queriesChipGroup!!.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
if (queriesChipGroup!!.childCount == 0) queriesConstraint.visibility = GONE
else queriesConstraint.visibility = VISIBLE
searchView!!.editText.setText("")
@ -344,6 +342,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
}
}
@SuppressLint("InflateParams")
private fun updateSearchViewItems(it: Editable?, linkYouCopied: View?){
lifecycleScope.launch {
searchSuggestionsLinearLayout!!.removeAllViews()
@ -499,7 +498,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
Log.e(TAG, type.toString() + " " + videoURL)
val item = resultsList!!.find { it?.url == videoURL }
Log.e(TAG, resultsList!![0].toString() + " " + videoURL)
val btn = recyclerView!!.findViewWithTag<MaterialButton>("""${item?.url}##$type""")
recyclerView!!.findViewWithTag<MaterialButton>("""${item?.url}##$type""")
if (sharedPreferences!!.getBoolean("download_card", true)) {
showSingleDownloadSheet(item!!, type!!, false)
} else {
@ -524,7 +523,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
}
override fun onCardClick(videoURL: String, add: Boolean) {
val item = resultsList?.find { it -> it?.url == videoURL }
val item = resultsList?.find { it?.url == videoURL }
if (add) {
selectedObjects!!.add(item!!)
if (actionMode == null){

View file

@ -18,6 +18,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.Format
@ -81,7 +82,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr
}
}
val sharedPreferences =
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
PreferenceManager.getDefaultSharedPreferences(requireContext())
try {
title = view.findViewById(R.id.title_textinput)

View file

@ -21,6 +21,7 @@ import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.Format
@ -86,7 +87,7 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
}
}
val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
try {
title = view.findViewById(R.id.title_textinput)
title.editText!!.setText(downloadItem.title)

View file

@ -18,6 +18,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.Format
@ -56,7 +57,7 @@ class FormatSelectionBottomSheetDialog(private val items: List<DownloadItem?>, p
infoUtil = InfoUtil(requireActivity().applicationContext)
formatCollection = mutableListOf()
chosenFormats = listOf()
sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
}

View file

@ -6,6 +6,8 @@ import android.graphics.Canvas
import android.graphics.Color
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
@ -23,6 +25,7 @@ import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.chip.Chip
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import it.xabaras.android.recyclerview.swipedecorator.RecyclerViewSwipeDecorator
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -36,6 +39,7 @@ class CommandTemplatesActivity : BaseActivity(), TemplatesAdapter.OnItemClickLis
private lateinit var commandTemplateViewModel: CommandTemplateViewModel
private lateinit var uiUtil: UiUtil
private lateinit var templatesList: List<CommandTemplate>
private lateinit var noResults: RelativeLayout
var context: Context? = null
public override fun onCreate(savedInstanceState: Bundle?) {
@ -46,6 +50,7 @@ class CommandTemplatesActivity : BaseActivity(), TemplatesAdapter.OnItemClickLis
topAppBar = findViewById(R.id.logs_toolbar)
topAppBar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }
noResults = findViewById(R.id.no_results)
templatesAdapter =
TemplatesAdapter(
@ -62,6 +67,8 @@ class CommandTemplatesActivity : BaseActivity(), TemplatesAdapter.OnItemClickLis
commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java]
commandTemplateViewModel.items.observe(this) {
if (it.isEmpty()) noResults.visibility = View.VISIBLE
else noResults.visibility = View.GONE
templatesList = it
templatesAdapter.submitList(it)
}
@ -73,15 +80,18 @@ class CommandTemplatesActivity : BaseActivity(), TemplatesAdapter.OnItemClickLis
topAppBar.setOnMenuItemClickListener { m: MenuItem ->
val itemId = m.itemId
if (itemId == R.id.export_clipboard) {
lifecycleScope.launch(Dispatchers.IO){
commandTemplateViewModel.exportToClipboard()
lifecycleScope.launch{
withContext(Dispatchers.IO){
commandTemplateViewModel.exportToClipboard()
}
Snackbar.make(recyclerView, getString(R.string.copied_to_clipboard), Snackbar.LENGTH_LONG).show()
}
}else if (itemId == R.id.import_clipboard){
lifecycleScope.launch{
withContext(Dispatchers.IO){
val count = commandTemplateViewModel.importFromClipboard()
runOnUiThread{
Toast.makeText(this@CommandTemplatesActivity, "${getString(R.string.items_imported)} (${count})", Toast.LENGTH_LONG).show()
Snackbar.make(recyclerView, "${getString(R.string.items_imported)} (${count})", Snackbar.LENGTH_LONG).show()
}
}

View file

@ -7,8 +7,10 @@ import android.graphics.Canvas
import android.graphics.Color
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.RelativeLayout
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.doOnTextChanged
@ -29,6 +31,7 @@ import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.chip.Chip
import com.google.android.material.color.MaterialColors
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import it.xabaras.android.recyclerview.swipedecorator.RecyclerViewSwipeDecorator
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -42,6 +45,7 @@ class CookiesActivity : BaseActivity(), CookieAdapter.OnItemClickListener {
private lateinit var cookiesViewModel: CookieViewModel
private lateinit var uiUtil: UiUtil
private lateinit var cookiesList: List<CookieItem>
private lateinit var noResults : RelativeLayout
var context: Context? = null
public override fun onCreate(savedInstanceState: Bundle?) {
@ -52,6 +56,7 @@ class CookiesActivity : BaseActivity(), CookieAdapter.OnItemClickListener {
topAppBar = findViewById(R.id.logs_toolbar)
topAppBar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }
cookiesList = listOf()
noResults = findViewById(R.id.no_results)
listAdapter =
CookieAdapter(
@ -68,6 +73,8 @@ class CookiesActivity : BaseActivity(), CookieAdapter.OnItemClickListener {
cookiesViewModel = ViewModelProvider(this)[CookieViewModel::class.java]
cookiesViewModel.items.observe(this) {
if (it.isEmpty()) noResults.visibility = View.VISIBLE
else noResults.visibility = View.GONE
cookiesList = it
listAdapter.submitList(it)
}
@ -98,6 +105,7 @@ class CookiesActivity : BaseActivity(), CookieAdapter.OnItemClickListener {
}
R.id.export_clipboard -> {
cookiesViewModel.exportToClipboard()
Snackbar.make(recyclerView, getString(R.string.copied_to_clipboard), Snackbar.LENGTH_LONG).show()
}
}
true

View file

@ -11,6 +11,7 @@ import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.MainActivity
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.ui.downloads.DownloadQueueActivity
@ -42,7 +43,7 @@ class MoreFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainSharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
mainSharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
mainSharedPreferencesEditor = mainSharedPreferences.edit()
terminal = view.findViewById(R.id.terminal)
logs = view.findViewById(R.id.logs)

View file

@ -23,6 +23,7 @@ import androidx.core.view.forEach
import androidx.core.view.get
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.work.*
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel
@ -80,7 +81,7 @@ class TerminalActivity : BaseActivity() {
topAppBar!!.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }
commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java]
sharedPreferences = getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
bottomAppBar = findViewById(R.id.bottomAppBar)

View file

@ -1,24 +1,30 @@
package com.deniscerri.ytdlnis.ui.more.settings
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ClipboardManager
import android.content.Context.POWER_SERVICE
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.Bundle
import android.os.Environment
import android.os.Looper
import android.os.PowerManager
import android.provider.Settings
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit
import androidx.core.os.LocaleListCompat
import androidx.lifecycle.lifecycleScope
import androidx.preference.*
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import androidx.preference.SeekBarPreference
import androidx.preference.SwitchPreferenceCompat
import androidx.work.WorkInfo
import androidx.work.WorkManager
import com.deniscerri.ytdlnis.BuildConfig
@ -28,13 +34,22 @@ import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.ThemeUtil
import com.deniscerri.ytdlnis.util.UpdateUtil
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.yausername.youtubedl_android.YoutubeDL
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.put
import kotlinx.serialization.json.putJsonArray
import java.io.File
import java.util.*
import java.util.Locale
class SettingsFragment : PreferenceFragmentCompat() {
@ -48,41 +63,15 @@ class SettingsFragment : PreferenceFragmentCompat() {
private var commandPath: Preference? = null
private var accessAllFiles : Preference? = null
private var clearCache: Preference? = null
private var keepCache: SwitchPreferenceCompat? = null
private var incognito: SwitchPreferenceCompat? = null
private var preferredDownloadType : ListPreference? = null
private var searchEngine : ListPreference? = null
private var startDestination : ListPreference? = null
private var downloadCard: SwitchPreferenceCompat? = null
private var quickDownload: SwitchPreferenceCompat? = null
private var meteredNetwork: SwitchPreferenceCompat? = null
private var apiKey: EditTextPreference? = null
private var homeRecommendations: SwitchPreferenceCompat? = null
private var locale: ListPreference? = null
private var concurrentFragments: SeekBarPreference? = null
private var concurrentDownloads: SeekBarPreference? = null
private var limitRate: EditTextPreference? = null
private var aria2: SwitchPreferenceCompat? = null
private var logDownloads: SwitchPreferenceCompat? = null
private var sponsorblockFilters: MultiSelectListPreference? = null
private var filenameTemplate: EditTextPreference? = null
private var restrictFilenames: SwitchPreferenceCompat? = null
private var mtime: SwitchPreferenceCompat? = null
private var embedSubtitles: SwitchPreferenceCompat? = null
private var writeSubtitles: SwitchPreferenceCompat? = null
private var embedThumbnail: SwitchPreferenceCompat? = null
private var addChapters: SwitchPreferenceCompat? = null
private var writeThumbnail: SwitchPreferenceCompat? = null
private var audioFormat: ListPreference? = null
private var videoFormat: ListPreference? = null
private var audioQuality: SeekBarPreference? = null
private var videoQuality: ListPreference? = null
private var formatID: EditTextPreference? = null
private var updateYTDL: Preference? = null
private var updateNightlyYTDL: SwitchPreferenceCompat? = null
private var updateFormats: SwitchPreferenceCompat? = null
private var formatSource: ListPreference? = null
private var updateApp: SwitchPreferenceCompat? = null
private var exportPreferences : Preference? = null
private var importPreferences : Preference? = null
private var ytdlVersion: Preference? = null
@ -111,8 +100,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
private fun initPreferences() {
val preferences =
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val editor = preferences.edit()
language = findPreference("app_language")
theme = findPreference("ytdlnis_theme")
@ -124,41 +112,17 @@ class SettingsFragment : PreferenceFragmentCompat() {
commandPath = findPreference("command_path")
accessAllFiles = findPreference("access_all_files")
clearCache = findPreference("clear_cache")
keepCache = findPreference("keep_cache")
incognito = findPreference("incognito")
preferredDownloadType = findPreference("preferred_download_type")
searchEngine = findPreference("search_engine")
startDestination = findPreference("start_destination")
downloadCard = findPreference("download_card")
quickDownload = findPreference("quick_download")
meteredNetwork = findPreference("metered_networks")
apiKey = findPreference("api_key")
homeRecommendations = findPreference("home_recommendations")
locale = findPreference("locale")
concurrentFragments = findPreference("concurrent_fragments")
concurrentDownloads = findPreference("concurrent_downloads")
limitRate = findPreference("limit_rate")
aria2 = findPreference("aria2")
logDownloads = findPreference("log_downloads")
sponsorblockFilters = findPreference("sponsorblock_filters")
mtime = findPreference("mtime")
embedSubtitles = findPreference("embed_subtitles")
writeSubtitles = findPreference("write_subtitles")
filenameTemplate = findPreference("file_name_template")
restrictFilenames = findPreference("restrict_filenames")
embedThumbnail = findPreference("embed_thumbnail")
addChapters = findPreference("add_chapters")
writeThumbnail = findPreference("write_thumbnail")
audioFormat = findPreference("audio_format")
videoFormat = findPreference("video_format")
audioQuality = findPreference("audio_quality")
videoQuality = findPreference("video_quality")
formatID = findPreference("format_id")
updateYTDL = findPreference("update_ytdl")
updateNightlyYTDL = findPreference("nightly_ytdl")
updateFormats = findPreference("update_formats")
formatSource = findPreference("formats_source")
updateApp = findPreference("update_app")
exportPreferences = findPreference("export_preferences")
importPreferences = findPreference("import_preferences")
ytdlVersion = findPreference("ytdl-version")
@ -202,17 +166,17 @@ class SettingsFragment : PreferenceFragmentCompat() {
editor.apply()
}
@SuppressLint("BatteryLife", "InlinedApi")
private fun initListeners() {
val preferences =
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
PreferenceManager.getDefaultSharedPreferences(requireContext())
val editor = preferences.edit()
if(language!!.value == null) language!!.value = Locale.getDefault().language
language!!.summary = Locale(language!!.value).getDisplayLanguage(Locale(language!!.value))
language!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("app_language", newValue.toString())
language!!.summary = Locale(newValue.toString()).getDisplayLanguage(Locale(newValue.toString()))
editor.apply()
AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(newValue.toString()))
true
}
@ -231,10 +195,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
theme!!.summary = getString(R.string.light)
}
}
editor.putString("ytdlnis_theme", newValue.toString())
editor.commit()
ThemeUtil.updateTheme(requireActivity() as AppCompatActivity)
val intent = Intent(requireContext(), MainActivity::class.java)
this.startActivity(intent)
requireActivity().finishAffinity()
@ -242,25 +203,15 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
accent!!.summary = accent!!.entry
accent!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("theme_accent", newValue.toString())
editor.apply().apply {
accent!!.summary = accent!!.entry
}
Preference.OnPreferenceChangeListener { _: Preference?, _: Any ->
ThemeUtil.updateTheme(requireActivity() as AppCompatActivity)
val intent = Intent(requireContext(), MainActivity::class.java)
this.startActivity(intent)
requireActivity().finishAffinity()
true
}
highContrast!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("high_contrast", enable)
editor.apply()
Preference.OnPreferenceChangeListener { _: Preference?, _: Any ->
ThemeUtil.updateTheme(requireActivity() as AppCompatActivity)
val intent = Intent(requireContext(), MainActivity::class.java)
this.startActivity(intent)
@ -322,108 +273,25 @@ class SettingsFragment : PreferenceFragmentCompat() {
Preference.OnPreferenceClickListener {
if (activeDownloadCount == 0){
File(requireContext().cacheDir.absolutePath + "/downloads").deleteRecursively()
Toast.makeText(requireContext(), getString(R.string.cache_cleared), Toast.LENGTH_SHORT).show()
Snackbar.make(requireView(), getString(R.string.cache_cleared), Snackbar.LENGTH_SHORT).show()
cacheSize = File(requireContext().cacheDir.absolutePath + "/downloads").walkBottomUp().fold(0L) { acc, file -> acc + file.length() }
clearCache!!.summary = "(${fileUtil!!.convertFileSize(cacheSize)}) ${resources.getString(R.string.clear_temporary_files_summary)}"
}else{
Toast.makeText(requireContext(), getString(R.string.downloads_running_try_later), Toast.LENGTH_SHORT).show()
Snackbar.make(requireView(), getString(R.string.downloads_running_try_later), Snackbar.LENGTH_SHORT).show()
}
true
}
keepCache!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("keep_cache", enable)
editor.apply()
true
}
incognito!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("incognito", enable)
editor.apply()
true
}
preferredDownloadType!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("preferred_download_type", newValue.toString())
editor.apply()
true
}
searchEngine!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("search_engine", newValue.toString())
editor.apply()
true
}
startDestination!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("start_destination", newValue.toString())
editor.apply()
true
}
downloadCard!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("download_card", enable)
editor.apply()
true
}
quickDownload!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("quick_download", enable)
editor.apply()
true
}
meteredNetwork!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("metered_networks", enable)
editor.apply()
true
}
apiKey!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("api_key", newValue.toString())
editor.apply()
true
}
homeRecommendations!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("home_recommendations", enable)
editor.apply()
true
}
locale!!.summary = locale!!.value
locale!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("locale", newValue.toString())
locale!!.summary = newValue.toString()
editor.apply()
true
}
concurrentFragments!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val value = newValue.toString().toInt()
editor.putInt("concurrent_fragments", value)
editor.apply()
true
}
concurrentDownloads!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val value = newValue.toString().toInt()
editor.putInt("concurrent_downloads", value)
editor.apply()
locale!!.summary = locale!!.value
concurrentDownloads!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, _: Any ->
MaterialAlertDialogBuilder(requireContext())
.setTitle(resources.getString(R.string.warning))
.setMessage(resources.getString(R.string.workmanager_updated))
.setNegativeButton(resources.getString(R.string.cancel)) { dialog, which ->
.setNegativeButton(resources.getString(R.string.cancel)) { dialog, _ ->
dialog.cancel()
}
.setPositiveButton(resources.getString(R.string.restart)) { dialog, which ->
.setPositiveButton(resources.getString(R.string.restart)) { _, _ ->
val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(intent)
@ -436,257 +304,151 @@ class SettingsFragment : PreferenceFragmentCompat() {
true
}
limitRate!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("limit_rate", newValue.toString())
editor.apply()
true
}
aria2!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("aria2", enable)
editor.apply()
true
}
logDownloads!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("log_downloads", enable)
editor.apply()
true
}
sponsorblockFilters!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any? ->
sponsorblockFilters!!.values = newValue as Set<String?>?
editor.putStringSet("sponsorblock_filters", newValue)
editor.apply()
true
}
filenameTemplate!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("file_name_template", newValue.toString())
editor.apply()
true
}
restrictFilenames!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val embed = newValue as Boolean
editor.putBoolean("restrict_filenames", embed)
editor.apply()
true
}
mtime!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val embed = newValue as Boolean
editor.putBoolean("mtime", embed)
editor.apply()
true
}
embedSubtitles!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val embed = newValue as Boolean
editor.putBoolean("embed_subtitles", embed)
editor.apply()
true
}
writeSubtitles!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val embed = newValue as Boolean
editor.putBoolean("write_subtitles", embed)
editor.apply()
true
}
embedThumbnail!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val embed = newValue as Boolean
editor.putBoolean("embed_thumbnail", embed)
editor.apply()
true
}
addChapters!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val add = newValue as Boolean
editor.putBoolean("add_chapters", add)
editor.apply()
true
}
writeThumbnail!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val write = newValue as Boolean
editor.putBoolean("write_thumbnail", write)
editor.apply()
true
}
audioFormat!!.summary = preferences.getString("audio_format", "")!!.replace("Default", getString(R.string.defaultValue))
audioFormat!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("audio_format", newValue.toString())
audioFormat!!.summary = newValue.toString().replace("Default", getString(R.string.defaultValue))
editor.apply()
true
}
videoFormat!!.summary = preferences.getString("video_format", "")!!.replace("Default", getString(R.string.defaultValue))
videoFormat!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("video_format", newValue.toString())
videoFormat!!.summary = newValue.toString().replace("Default", getString(R.string.defaultValue))
editor.apply()
true
}
audioQuality!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putInt("audio_quality", newValue.toString().toInt())
editor.apply()
true
}
videoQuality!!.summary = preferences.getString("video_quality", "")
videoQuality!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("video_quality", newValue.toString())
videoQuality!!.summary = newValue.toString()
editor.apply()
true
}
formatID!!.summary = formatID!!.text
formatID!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
formatID!!.summary = newValue.toString()
editor.putString("format_id", newValue.toString())
editor.apply()
true
}
YoutubeDL.getInstance().version(context)?.let {
editor.putString("ytdl-version", it)
editor.apply()
ytdlVersion!!.summary = it
}
updateYTDL!!.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
lifecycleScope.launch {
Snackbar.make(requireView(),
requireContext().getString(R.string.ytdl_updating_started),
Snackbar.LENGTH_LONG).show()
when (updateUtil!!.updateYoutubeDL()) {
YoutubeDL.UpdateStatus.DONE -> {
Toast.makeText(
context,
Snackbar.make(requireView(),
requireContext().getString(R.string.ytld_update_success),
Toast.LENGTH_LONG
).show()
Snackbar.LENGTH_LONG).show()
YoutubeDL.getInstance().version(context)?.let {
editor.putString("ytdl-version", it)
editor.apply()
ytdlVersion!!.summary = it
}
}
YoutubeDL.UpdateStatus.ALREADY_UP_TO_DATE -> Toast.makeText(
context,
YoutubeDL.UpdateStatus.ALREADY_UP_TO_DATE -> Snackbar.make(requireView(),
requireContext().getString(R.string.you_are_in_latest_version),
Toast.LENGTH_LONG
).show()
else -> Toast.makeText(context, getString(R.string.errored), Toast.LENGTH_LONG).show()
Snackbar.LENGTH_LONG).show()
else -> {
Snackbar.make(requireView(),
requireContext().getString(R.string.errored),
Snackbar.LENGTH_LONG).show()
}
}
}
true
}
updateFormats!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("update_formats", enable)
editor.apply()
true
}
formatSource!!.summary = preferences.getString("formats_source", "")!!.replace("Default", getString(R.string.defaultValue))
formatSource!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
editor.putString("formats_source", newValue.toString())
formatSource!!.summary = newValue.toString().replace("Default", getString(R.string.defaultValue))
editor.apply()
true
}
updateNightlyYTDL!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("nightly_ytdl", enable)
editor.apply()
exportPreferences!!.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
val prefs = preferences.all
val json = buildJsonObject {
putJsonArray("YTDLnis_Preferences") {
prefs.forEach {
add(buildJsonObject {
put("key", it.key)
put("value", it.value.toString())
put("type", it.value!!::class.simpleName)
})
}
}
}
val string = jsonFormat.encodeToString(json)
val clipboard: ClipboardManager =
requireContext().getSystemService(AppCompatActivity.CLIPBOARD_SERVICE) as ClipboardManager
clipboard.setText(string)
Snackbar.make(requireView(), getString(R.string.copied_to_clipboard), Snackbar.LENGTH_LONG).show()
true
}
updateApp!!.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
val enable = newValue as Boolean
editor.putBoolean("update_app", enable)
editor.apply()
importPreferences!!.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
val clipboard = requireContext().getSystemService(AppCompatActivity.CLIPBOARD_SERVICE) as ClipboardManager
val clip = clipboard.primaryClip!!.getItemAt(0).text.toString()
try{
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit(commit = true) {
clear()
val preferencesKeys = preferences.all.map { it.key }
jsonFormat.decodeFromString<JsonObject>(clip).run {
val prefs = this.jsonObject["YTDLnis_Preferences"]!!.jsonArray
prefs.forEach {
val key : String = it.jsonObject["key"].toString().replace("\"", "")
if (preferencesKeys.contains(key)){
when(it.jsonObject["type"].toString().replace("\"", "")){
"String" -> {
val value = it.jsonObject["value"].toString().replace("\"", "")
putString(key, value)
}
"Boolean" -> {
val value = it.jsonObject["value"].toString().replace("\"", "").toBoolean()
putBoolean(key, value)
}
"Int" -> {
val value = it.jsonObject["value"].toString().replace("\"", "").toInt()
putInt(key, value)
}
"HashSet" -> {
val value = hashSetOf(it.jsonObject["value"].toString().replace("(\")|(\\[)|(])".toRegex(), ""))
putStringSet(key, value)
}
}
}
}
}
}
val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(intent)
if (context is Activity) {
(context as Activity).finish()
}
Runtime.getRuntime().exit(0)
}catch (e: Exception){
e.printStackTrace()
}
true
}
// exportPreferences!!.onPreferenceClickListener =
// Preference.OnPreferenceClickListener {
// val prefs = preferences.all
// val json = buildJsonObject {
// putJsonArray("YTDLnis_Preferences") {
// prefs.forEach {
// add(buildJsonObject {
// put("key", it.key)
// put("value", it.value.toString())
// put("type", it.value!!::class.simpleName)
// })
// }
// }
// }
// val string = jsonFormat.encodeToString(json)
// val clipboard: ClipboardManager =
// requireContext().getSystemService(AppCompatActivity.CLIPBOARD_SERVICE) as ClipboardManager
// clipboard.setText(string)
// true
// }
// importPreferences!!.onPreferenceClickListener =
// Preference.OnPreferenceClickListener {
// val clipboard = requireContext().getSystemService(AppCompatActivity.CLIPBOARD_SERVICE) as ClipboardManager
// val clip = clipboard.primaryClip!!.getItemAt(0).text.toString()
// try{
// val preferencesKeys = preferences.all.map { it.key }
// var count = 0
// jsonFormat.decodeFromString<JsonObject>(clip).run {
// val prefs = this.jsonObject["YTDLnis_Preferences"]!!.jsonArray
// prefs.forEach {
// val key : String = it.jsonObject["key"].toString().replace("\"", "")
// if (preferencesKeys.contains(key)){
// when(it.jsonObject["type"].toString().replace("\"", "")){
// "String" -> {
// val value = it.jsonObject["value"].toString().replace("\"", "")
// Log.e("aa", value.toString())
// editor.putString(key, value)
// editor.apply()
// }
// "Boolean" -> {
// val value = it.jsonObject["value"].toString().replace("\"", "").toBoolean()
// Log.e("aa", value.toString())
// editor.putBoolean(key, value)
// editor.apply()
// }
// "Int" -> {
// val value = it.jsonObject["value"].toString().replace("\"", "").toInt()
// Log.e("aa", value.toString())
// editor.putInt(key, value)
// editor.apply()
// }
// "HashSet" -> {
// val value = hashSetOf(it.jsonObject["value"].toString().replace("(\")|(\\[)|(])".toRegex(), ""))
// Log.e("aa", value.toString())
// editor.putStringSet(key, value)
// editor.apply()
// }
// }
// count++
// }
// }
// }
// Toast.makeText(requireContext(), "${getString(R.string.items_imported)} (${count})", Toast.LENGTH_LONG).show()
// }catch (e: Exception){
// e.printStackTrace()
// }
//
// true
// }
version!!.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
lifecycleScope.launch{
withContext(Dispatchers.IO){
updateUtil!!.updateApp{ msg ->
lifecycleScope.launch(Dispatchers.Main){
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
Snackbar.make(requireView(), msg, Snackbar.LENGTH_LONG).show()
}
}
}
@ -742,8 +504,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
private fun changePath(p: Preference?, data: Intent?, requestCode: Int) {
val path = data!!.data.toString()
p!!.summary = fileUtil?.formatPath(data.data.toString())
val sharedPreferences =
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val editor = sharedPreferences.edit()
when (requestCode) {
MUSIC_PATH_CODE -> editor.putString("music_path", path)
@ -757,6 +518,5 @@ class SettingsFragment : PreferenceFragmentCompat() {
const val MUSIC_PATH_CODE = 33333
const val VIDEO_PATH_CODE = 55555
const val COMMAND_PATH_CODE = 77777
private const val TAG = "SettingsFragment"
}
}

View file

@ -6,6 +6,7 @@ import android.content.SharedPreferences
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.Format
import com.deniscerri.ytdlnis.database.models.ResultItem
@ -32,8 +33,7 @@ class InfoUtil(private val context: Context) {
init {
try {
sharedPreferences =
context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
key = sharedPreferences.getString("api_key", "")
countryCODE = sharedPreferences.getString("locale", "")!!
} catch (e: Exception) {

View file

@ -4,6 +4,7 @@ import android.app.Application
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.R
import com.google.android.material.color.DynamicColors
@ -11,7 +12,7 @@ import com.google.android.material.color.DynamicColors
object ThemeUtil {
fun updateTheme(activity: AppCompatActivity) {
val sharedPreferences = activity.getSharedPreferences("root_preferences", Application.MODE_PRIVATE)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity)
//update accent
when (sharedPreferences.getString("theme_accent","blue")) {

View file

@ -11,6 +11,7 @@ import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.preference.PreferenceManager
import com.deniscerri.ytdlnis.BuildConfig
import com.deniscerri.ytdlnis.R
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@ -146,7 +147,7 @@ class UpdateUtil(var context: Context) {
suspend fun updateYoutubeDL() : UpdateStatus? =
withContext(Dispatchers.IO){
val sharedPreferences =
context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
PreferenceManager.getDefaultSharedPreferences(context)
if (updatingYTDL) {
withContext(Dispatchers.Main){
Toast.makeText(
@ -157,13 +158,6 @@ class UpdateUtil(var context: Context) {
}
UpdateStatus.ALREADY_UP_TO_DATE
}
withContext(Dispatchers.Main){
Toast.makeText(
context,
context.getString(R.string.ytdl_updating_started),
Toast.LENGTH_SHORT
).show()
}
updatingYTDL = true

View file

@ -8,6 +8,7 @@ import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.preference.PreferenceManager
import androidx.work.*
import com.deniscerri.ytdlnis.MainActivity
import com.deniscerri.ytdlnis.R
@ -103,9 +104,7 @@ class DownloadWorker(
tempFileDir.delete()
tempFileDir.mkdirs()
val sharedPreferences = context.getSharedPreferences("root_preferences",
Service.MODE_PRIVATE
)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val aria2 = sharedPreferences.getBoolean("aria2", false)
if (aria2) {
request.addOption("--downloader", "libaria2c.so")

View file

@ -8,6 +8,7 @@ import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.preference.PreferenceManager
import androidx.work.*
import com.deniscerri.ytdlnis.MainActivity
import com.deniscerri.ytdlnis.R
@ -40,9 +41,7 @@ class TerminalDownloadWorker(
setForegroundAsync(foregroundInfo)
val request = YoutubeDLRequest(emptyList())
val sharedPreferences = context.getSharedPreferences("root_preferences",
Service.MODE_PRIVATE
)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val downloadLocation = sharedPreferences.getString("command_path", context.getString(R.string.command_path))
val tempFileDir = File(context.cacheDir.absolutePath + "/downloads/" + itemId)

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:colorAccent" android:pathData="M14,2L6,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,-6zM12,18c-2.05,0 -3.81,-1.24 -4.58,-3h1.71c0.63,0.9 1.68,1.5 2.87,1.5 1.93,0 3.5,-1.57 3.5,-3.5S13.93,9.5 12,9.5c-1.35,0 -2.52,0.78 -3.1,1.9l1.6,1.6h-4L6.5,9l1.3,1.3C8.69,8.92 10.23,8 12,8c2.76,0 5,2.24 5,5s-2.24,5 -5,5z"/>
</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:colorAccent" android:pathData="M19,12v7L5,19v-7L3,12v7c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2zM13,12.67l2.59,-2.58L17,11.5l-5,5 -5,-5 1.41,-1.41L11,12.67L11,3h2z"/>
</vector>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#ffffff" />
<padding
android:left="1dp"
android:right="1dp"
android:bottom="1dp"
android:top="1dp" />
<corners android:radius="3dp" />
</shape>

View file

@ -5,7 +5,7 @@
android:orientation="vertical"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@ -13,139 +13,149 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:orientation="horizontal"
android:paddingTop="20dp">
<TextView
android:id="@+id/bottom_sheet_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/template"
android:textSize="25sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bottom_sheet_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/create_template"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bottom_sheet_title" />
<Button
android:id="@+id/template_create"
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="all"
android:text="@string/create"
app:icon="@drawable/ic_check"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:padding="15dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/title"
style="@style/Widget.Material3.TextInputLayout.FilledBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/title"
android:paddingBottom="10dp">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/content"
style="@style/Widget.Material3.TextInputLayout.FilledBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/command"
android:paddingBottom="10dp"
app:endIconDrawable="@drawable/ic_clipboard"
app:endIconMode="custom">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:maxLines="200" />
</com.google.android.material.textfield.TextInputLayout>
<View
style="@style/Divider.Horizontal"
android:layout_marginVertical="10dp" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:orientation="horizontal"
android:paddingTop="20dp">
android:layout_height="wrap_content">
<TextView
android:id="@+id/bottom_sheet_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/template"
android:textSize="25sp"
android:gravity="center"
android:paddingBottom="5dp"
android:text="@string/shortcuts"
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bottom_sheet_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/create_template"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bottom_sheet_title" />
<Button
android:id="@+id/template_create"
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
android:id="@+id/edit_shortcuts"
style="@style/Widget.Material3.Button.TextButton.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="all"
android:text="@string/create"
app:icon="@drawable/ic_check"
android:text="@string/edit"
app:icon="@drawable/ic_edit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/title"
android:layout_width="match_parent"
android:paddingBottom="10dp"
android:layout_height="wrap_content"
android:hint="@string/title"
style="@style/Widget.Material3.TextInputLayout.FilledBox">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:inputType="text"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
app:endIconMode="custom"
app:endIconDrawable="@drawable/ic_clipboard"
android:hint="@string/command"
style="@style/Widget.Material3.TextInputLayout.FilledBox">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:maxLines="200"
android:inputType="textMultiLine"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
<View
android:layout_marginVertical="10dp"
style="@style/Divider.Horizontal"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingBottom="5dp"
android:text="@string/shortcuts"
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/edit_shortcuts"
style="@style/Widget.Material3.Button.TextButton.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="all"
android:text="@string/edit"
app:icon="@drawable/ic_edit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:id="@+id/shortcutsChipGroup"
android:layout_width="wrap_content"
app:chipSpacingVertical="-10dp"
app:chipSpacing="0dp"
android:layout_height="wrap_content"
app:chipSpacing="0dp"
app:chipSpacingVertical="-10dp"
app:singleLine="false">
</com.google.android.material.chip.ChipGroup>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.core.widget.NestedScrollView>

View file

@ -1,199 +1,195 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/downloads_card_constraintLayout"
<com.google.android.material.card.MaterialCardView android:id="@+id/download_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:backgroundTint="@android:color/transparent"
android:checkable="true"
android:clickable="true"
android:focusable="true"
app:cardPreventCornerOverlap="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Avatar"
app:strokeWidth="0dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.card.MaterialCardView
android:id="@+id/download_card_view"
android:layout_width="0dp"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Avatar"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:checkable="true"
android:clickable="true"
android:focusable="true"
android:backgroundTint="@android:color/transparent"
app:cardPreventCornerOverlap="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:strokeWidth="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:paddingHorizontal="20dp"
android:paddingVertical="10dp"
android:layout_height="wrap_content">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/downloads_image_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:background="?attr/colorSurfaceVariant"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintEnd_toStartOf="@+id/download_item_data"
app:layout_constraintHorizontal_weight="0.3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Avatar" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#80000000"
android:clickable="false"
android:ellipsize="end"
android:gravity="center"
android:maxLength="17"
android:maxLines="1"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textColor="@color/white"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="@+id/downloads_image_view"
app:layout_constraintEnd_toEndOf="@+id/downloads_image_view" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/downloads_image_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHorizontal_weight="0.3"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:background="?attr/colorSurfaceVariant"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintEnd_toStartOf="@+id/download_item_data"
app:layout_constraintStart_toStartOf="parent"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Avatar"
app:layout_constraintTop_toTopOf="parent" />
android:id="@+id/download_item_data"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="0.7"
app:layout_constraintStart_toEndOf="@+id/downloads_image_view"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#80000000"
android:clickable="false"
android:layout_margin="5dp"
android:ellipsize="end"
android:gravity="center"
android:textStyle="bold"
android:maxLength="17"
android:maxLines="1"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textColor="@color/white"
android:textSize="12sp"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="@+id/downloads_image_view"
app:layout_constraintEnd_toEndOf="@+id/downloads_image_view" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/download_item_data"
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:paddingHorizontal="5dp"
android:scrollbars="none"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/action_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="title,action_button" />
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:paddingStart="5dp"
android:paddingEnd="0dp"
android:scrollbars="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="0.7"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/downloads_image_view"
app:layout_constraintTop_toTopOf="parent">
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/barrier">
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:paddingHorizontal="5dp"
android:scrollbars="none"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/action_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
app:barrierDirection="bottom"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="title,action_button"/>
android:layout_height="match_parent">
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:paddingStart="5dp"
android:paddingEnd="0dp"
android:scrollbars="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/barrier">
<LinearLayout
<TextView
android:id="@+id/format_note"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="match_parent">
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorSecondary"
android:clickable="false"
android:ellipsize="end"
android:gravity="center"
android:maxLength="17"
android:maxLines="1"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/format_note"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="?attr/colorSecondary"
android:clickable="false"
android:ellipsize="end"
android:gravity="center"
android:maxLength="17"
android:maxLines="1"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/codec"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorSecondary"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/codec"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="?attr/colorSecondary"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/file_size"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="?attr/colorSecondary"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/file_size"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorSecondary"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</LinearLayout>
</HorizontalScrollView>
<com.google.android.material.button.MaterialButton
android:id="@+id/action_button"
style="?attr/materialIconButtonStyle"
android:layout_width="0dp"
android:padding="0dp"
android:minHeight="0dp"
android:layout_height="wrap_content"
app:cornerRadius="10dp"
app:iconTint="?attr/colorAccent"
app:icon="@drawable/ic_video"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</HorizontalScrollView>
<com.google.android.material.button.MaterialButton
android:id="@+id/action_button"
style="?attr/materialIconButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:padding="0dp"
app:cornerRadius="10dp"
app:icon="@drawable/ic_video"
app:iconTint="?attr/colorAccent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -13,7 +13,8 @@
<TextView
android:id="@+id/container"
android:layout_width="60dp"
android:background="?attr/colorPrimaryInverse"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorPrimaryInverse"
android:textColor="@color/white"
android:clickable="false"
android:layout_height="55dp"
@ -62,7 +63,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="?attr/colorSecondary"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorSecondary"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
@ -79,7 +81,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="?attr/colorSecondary"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorSecondary"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"

View file

@ -44,49 +44,42 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<ScrollView
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/title"
android:padding="15dp"
android:layout_width="match_parent"
android:paddingBottom="10dp"
android:layout_height="wrap_content"
app:endIconMode="custom"
app:endIconDrawable="@drawable/ic_plus"
android:hint="@string/create_shortcut"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:maxLines="4"
android:inputType="textMultiLine"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:paddingHorizontal="15dp"
android:scrollbars="none"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
<com.google.android.material.chip.ChipGroup
android:id="@+id/shortcutsChipGroup"
android:layout_width="wrap_content"
app:chipSpacingVertical="-10dp"
app:chipSpacing="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
app:singleLine="false">
<com.google.android.material.chip.ChipGroup
android:id="@+id/shortcutsChipGroup"
android:layout_width="wrap_content"
app:chipSpacingVertical="-10dp"
app:chipSpacing="0dp"
android:layout_height="wrap_content"
app:singleLine="false">
</com.google.android.material.chip.ChipGroup>
</com.google.android.material.chip.ChipGroup>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/title"
android:layout_width="match_parent"
android:paddingBottom="10dp"
android:layout_height="wrap_content"
app:endIconMode="custom"
app:endIconDrawable="@drawable/ic_plus"
android:hint="@string/create_shortcut"
style="@style/Widget.Material3.TextInputLayout.FilledBox">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:maxLines="4"
android:inputType="textMultiLine"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View file

@ -44,29 +44,22 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<ScrollView
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:padding="15dp"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
<com.google.android.material.chip.ChipGroup
android:id="@+id/shortcutsChipGroup"
android:layout_width="wrap_content"
app:chipSpacingVertical="-10dp"
app:chipSpacing="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
app:singleLine="false">
<com.google.android.material.chip.ChipGroup
android:id="@+id/shortcutsChipGroup"
android:layout_width="wrap_content"
app:chipSpacingVertical="-10dp"
app:chipSpacing="0dp"
android:layout_height="wrap_content"
app:singleLine="false">
</com.google.android.material.chip.ChipGroup>
</com.google.android.material.chip.ChipGroup>
</LinearLayout>
</ScrollView>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View file

@ -6,6 +6,7 @@
<item name="android:color">@android:color/transparent</item>
<item name="alertDialogTheme">@style/ThemeOverlay.Material3.MaterialAlertDialog</item>
<item name="dialogCornerRadius">28dp</item>
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">false</item>
<item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat.Material3</item>
<item name="snackbarStyle">@style/snackBarStyle</item>
</style>

View file

@ -253,4 +253,6 @@
<string name="updating_download_data">Updating Download Item Data</string>
<string name="keep_cache">Keep Cache</string>
<string name="keep_cache_summary">Don\'t delete temporary files after the download is finished</string>
<string name="backup">Backup</string>
<string name="restore">Restore</string>
</resources>

View file

@ -5,6 +5,7 @@
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="alertDialogTheme">@style/ThemeOverlay.Material3.MaterialAlertDialog</item>
<item name="dialogCornerRadius">28dp</item>
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">true</item>
<item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat.Material3</item>
<item name="snackbarStyle">@style/snackBarStyle</item>
</style>

View file

@ -383,17 +383,15 @@
<PreferenceCategory android:title="@string/about">
<!-- <Preference-->
<!-- app:isPreferenceVisible="false"-->
<!-- app:icon="@drawable/ic_clipboard"-->
<!-- app:key="export_preferences"-->
<!-- app:title="@string/export_from_clipboard"/>-->
<Preference
app:icon="@drawable/baseline_save_alt_24"
app:key="export_preferences"
app:title="@string/backup"/>
<!-- <Preference-->
<!-- app:isPreferenceVisible="false"-->
<!-- app:icon="@drawable/ic_copy"-->
<!-- app:key="import_preferences"-->
<!-- app:title="@string/import_from_clipboard"/>-->
<Preference
app:icon="@drawable/baseline_restore_page_24"
app:key="import_preferences"
app:title="@string/restore"/>
<Preference
app:icon="@drawable/ic_discord"