fixed terminal mode somewhat & implemented language preference
This commit is contained in:
parent
7783b2846d
commit
5482105a18
24 changed files with 291 additions and 144 deletions
|
|
@ -320,7 +320,7 @@
|
|||
<PersistentState>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/text_format/baseline_text_format_24.xml" />
|
||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/terminal/baseline_terminal_24.xml" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
|
|
@ -330,7 +330,7 @@
|
|||
</option>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="outputName" value="ic_textformat" />
|
||||
<entry key="outputName" value="ic_terminal" />
|
||||
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
|
||||
</map>
|
||||
</option>
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="false"
|
||||
android:localeConfig="@xml/locales_config"
|
||||
android:extractNativeLibs="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:configChanges="layoutDirection|locale"
|
||||
android:label="@string/app_name"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
|
|
@ -27,6 +29,7 @@
|
|||
tools:ignore="DataExtractionRules">
|
||||
<activity android:name=".MainActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="layoutDirection|locale"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
@ -46,6 +49,7 @@
|
|||
|
||||
</activity>
|
||||
<activity android:name=".receiver.ShareActivity"
|
||||
android:configChanges="layoutDirection|locale"
|
||||
android:exported="true">
|
||||
|
||||
<!-- <intent-filter>-->
|
||||
|
|
@ -62,6 +66,7 @@
|
|||
</activity>
|
||||
<activity
|
||||
android:name=".ui.settings.SettingsActivity"
|
||||
android:configChanges="layoutDirection|locale"
|
||||
android:parentActivityName=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
|
|
@ -71,6 +76,7 @@
|
|||
</activity>
|
||||
<activity
|
||||
android:name=".ui.CustomCommandActivity"
|
||||
android:configChanges="layoutDirection|locale"
|
||||
android:theme="@style/AppDefaultTheme"
|
||||
android:parentActivityName=".MainActivity"
|
||||
android:label="@string/run_command"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package com.deniscerri.ytdlnis
|
|||
|
||||
import android.app.Application
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.work.Configuration
|
||||
import androidx.work.WorkManager
|
||||
|
|
@ -11,9 +13,11 @@ import com.yausername.aria2c.Aria2c
|
|||
import com.yausername.ffmpeg.FFmpeg
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import com.yausername.youtubedl_android.YoutubeDLException
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class App : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
DynamicColors.applyToActivitiesIfAvailable(this)
|
||||
|
|
@ -40,6 +44,9 @@ class App : Application() {
|
|||
Toast.makeText(this@App, e.message, Toast.LENGTH_SHORT).show()
|
||||
e.printStackTrace()
|
||||
}
|
||||
val locale = getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||
.getString("app_language", Locale.getDefault().language)!!
|
||||
AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(locale))
|
||||
}
|
||||
@Throws(YoutubeDLException::class)
|
||||
private fun initLibraries() {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import android.content.Context
|
|||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Build.VERSION_CODES
|
||||
|
|
@ -15,7 +16,9 @@ import android.view.MenuItem
|
|||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
|
|
@ -49,6 +52,7 @@ class MainActivity : AppCompatActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.activity_main)
|
||||
setContentView(binding.root)
|
||||
context = baseContext
|
||||
|
|
@ -253,6 +257,10 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
dialog.show()
|
||||
}
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
super.onConfigurationChanged(newConfig)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "MainActivity"
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
|
|||
DownloadViewModel.Type.video -> {
|
||||
btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video)
|
||||
}
|
||||
DownloadViewModel.Type.command -> {
|
||||
else -> {
|
||||
btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_baseline_keyboard_arrow_right_24)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ class Converters {
|
|||
return when(string){
|
||||
"audio" -> DownloadViewModel.Type.audio
|
||||
"video" -> DownloadViewModel.Type.video
|
||||
else -> DownloadViewModel.Type.command
|
||||
"command" -> DownloadViewModel.Type.command
|
||||
else -> DownloadViewModel.Type.terminal
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,4 +52,7 @@ interface DownloadDao {
|
|||
|
||||
@Query("SELECT * FROM downloads WHERE url=:url AND format=:format AND (status='Error' OR status='Cancelled') LIMIT 1")
|
||||
fun getUnfinishedByURLAndFormat(url: String, format: String) : DownloadItem
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE type='terminal' ORDER BY id DESC LIMIT 1")
|
||||
fun getTerminalDownload() : DownloadItem
|
||||
}
|
||||
|
|
@ -64,4 +64,8 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
|||
0L
|
||||
}
|
||||
}
|
||||
|
||||
fun getTerminalDownload() : Long {
|
||||
return downloadDao.getTerminalDownload().id
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
private var bestVideoFormat : Format
|
||||
private var bestAudioFormat : Format
|
||||
enum class Type {
|
||||
audio, video, command
|
||||
audio, video, command, terminal
|
||||
}
|
||||
|
||||
init {
|
||||
|
|
@ -92,7 +92,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
val downloadPath = when(type){
|
||||
Type.audio -> sharedPreferences.getString("music_path", getApplication<App>().resources.getString(R.string.music_path))
|
||||
Type.video -> sharedPreferences.getString("video_path", getApplication<App>().resources.getString(R.string.video_path))
|
||||
Type.command -> sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path))
|
||||
else -> sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path))
|
||||
}
|
||||
|
||||
val audioPreferences = AudioPreferences(embedThumb)
|
||||
|
|
@ -111,18 +111,19 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
|
||||
}
|
||||
|
||||
private fun getFormat(resultItem: ResultItem, type: Type) : Format {
|
||||
|
||||
private fun getFormat(resultItem: ResultItem?, type: Type) : Format {
|
||||
when(type) {
|
||||
Type.audio -> {
|
||||
return try {
|
||||
resultItem.formats.last { it.format_note.contains("audio", ignoreCase = true) }
|
||||
resultItem!!.formats.last { it.format_note.contains("audio", ignoreCase = true) }
|
||||
}catch (e: Exception){
|
||||
bestAudioFormat
|
||||
}
|
||||
}
|
||||
Type.video -> {
|
||||
return try {
|
||||
resultItem.formats.last { !it.format_note.contains("audio", ignoreCase = true) }
|
||||
resultItem!!.formats.last { !it.format_note.contains("audio", ignoreCase = true) }
|
||||
}catch (e: Exception){
|
||||
bestVideoFormat
|
||||
}
|
||||
|
|
@ -203,4 +204,39 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
}
|
||||
}
|
||||
|
||||
fun startTerminalDownload(command: String) = viewModelScope.launch(Dispatchers.IO) {
|
||||
val downloadPath = sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path))
|
||||
val downloadItem = DownloadItem(0,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
Type.terminal,
|
||||
Format("", "", 0, command),
|
||||
downloadPath!!, "", "", "", AudioPreferences(), VideoPreferences(), "", false, DownloadRepository.Status.Processing.toString(), 0
|
||||
)
|
||||
|
||||
downloadItem.status = DownloadRepository.Status.Queued.toString()
|
||||
Log.e("aaaaaaaa", downloadItem.toString())
|
||||
val id = repository.insert(downloadItem)
|
||||
downloadItem.id = id
|
||||
|
||||
val workRequest = OneTimeWorkRequestBuilder<DownloadWorker>()
|
||||
.setInputData(Data.Builder().putLong("id", downloadItem.id).build())
|
||||
.addTag("terminal")
|
||||
.build()
|
||||
val context = getApplication<App>().applicationContext
|
||||
WorkManager.getInstance(context).beginUniqueWork(
|
||||
downloadItem.id.toString(),
|
||||
ExistingWorkPolicy.KEEP,
|
||||
workRequest
|
||||
).enqueue()
|
||||
}
|
||||
|
||||
|
||||
fun getTerminalDownload(): Long {
|
||||
return repository.getTerminalDownload();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,19 +6,34 @@ import android.content.Intent
|
|||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.ScrollView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderService
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class CustomCommandActivity : AppCompatActivity() {
|
||||
private var topAppBar: MaterialToolbar? = null
|
||||
private lateinit var downloadViewModel: DownloadViewModel
|
||||
private lateinit var notificationUtil: NotificationUtil
|
||||
private lateinit var workManager: WorkManager
|
||||
private var isDownloadServiceRunning = false
|
||||
private var output: TextView? = null
|
||||
private var input: EditText? = null
|
||||
|
|
@ -27,80 +42,6 @@ class CustomCommandActivity : AppCompatActivity() {
|
|||
private var iDownloaderService: IDownloaderService? = null
|
||||
private var scrollView: ScrollView? = null
|
||||
var context: Context? = null
|
||||
// private val serviceConnection: ServiceConnection = object : ServiceConnection {
|
||||
// override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
// downloaderService = (service as LocalBinder).service
|
||||
// iDownloaderService = service
|
||||
// isDownloadServiceRunning = true
|
||||
// try {
|
||||
// val listeners = ArrayList<IDownloaderListener>()
|
||||
// listeners.add(listener)
|
||||
// iDownloaderService!!.addActivity(this@CustomCommandActivity, listeners)
|
||||
// listener.onDownloadStart(iDownloaderService!!.info)
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onServiceDisconnected(componentName: ComponentName) {
|
||||
// downloaderService = null
|
||||
// iDownloaderService = null
|
||||
// isDownloadServiceRunning = false
|
||||
// }
|
||||
// }
|
||||
// var listener: IDownloaderListener = object : IDownloaderListener {
|
||||
// override fun onDownloadStart(info: DownloadInfo) {
|
||||
// input!!.isEnabled = false
|
||||
// output!!.text = ""
|
||||
// swapFabs()
|
||||
// }
|
||||
//
|
||||
// override fun onDownloadProgress(info: DownloadInfo) {
|
||||
// val newInfo = info.outputLine
|
||||
// if (newInfo.contains("[download]")) {
|
||||
// val temp = output!!.text.toString()
|
||||
// output!!.text =
|
||||
// temp.substring(0, temp.lastIndexOf(System.getProperty("line.separator")!!) - 2)
|
||||
// }
|
||||
// output!!.append(
|
||||
// """${info.outputLine}
|
||||
//"""
|
||||
// )
|
||||
// output!!.scrollTo(0, output!!.height)
|
||||
// scrollView!!.fullScroll(View.FOCUS_DOWN)
|
||||
// }
|
||||
//
|
||||
// @SuppressLint("SetTextI18n")
|
||||
// override fun onDownloadError(info: DownloadInfo) {
|
||||
// output!!.append(
|
||||
// """
|
||||
//
|
||||
// ${info.outputLine}
|
||||
// """.trimIndent()
|
||||
// )
|
||||
// scrollView!!.scrollTo(0, scrollView!!.maxScrollAmount)
|
||||
// input!!.setText("yt-dlp ")
|
||||
// input!!.isEnabled = true
|
||||
// swapFabs()
|
||||
// }
|
||||
//
|
||||
// @SuppressLint("SetTextI18n")
|
||||
// override fun onDownloadEnd(info: DownloadInfo) {
|
||||
// output!!.append(info.outputLine)
|
||||
// scrollView!!.scrollTo(0, scrollView!!.maxScrollAmount)
|
||||
// // MEDIA SCAN
|
||||
// MediaScannerConnection.scanFile(context, arrayOf("/storage"), null, null)
|
||||
// input!!.setText("yt-dlp ")
|
||||
// input!!.isEnabled = true
|
||||
// swapFabs()
|
||||
// }
|
||||
//
|
||||
// override fun onDownloadCancel(downloadInfo: DownloadInfo) {}
|
||||
// override fun onDownloadCancelAll(downloadInfo: DownloadInfo) {}
|
||||
// override fun onDownloadServiceEnd() {
|
||||
// stopDownloadService()
|
||||
// }
|
||||
// }
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -115,19 +56,18 @@ class CustomCommandActivity : AppCompatActivity() {
|
|||
input!!.requestFocus()
|
||||
fab = findViewById(R.id.command_fab)
|
||||
fab!!.setOnClickListener {
|
||||
if (isStoragePermissionGranted) {
|
||||
startDownloadService(
|
||||
input!!.text.toString(),
|
||||
NotificationUtil.COMMAND_DOWNLOAD_NOTIFICATION_ID
|
||||
)
|
||||
}
|
||||
startDownload(
|
||||
input!!.text.toString()
|
||||
)
|
||||
}
|
||||
cancelFab = findViewById(R.id.cancel_command_fab)
|
||||
cancelFab!!.setOnClickListener {
|
||||
cancelDownloadService()
|
||||
swapFabs()
|
||||
cancelDownload()
|
||||
input!!.isEnabled = true
|
||||
}
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
notificationUtil = NotificationUtil(this)
|
||||
workManager = WorkManager.getInstance(this)
|
||||
handleIntent(intent)
|
||||
}
|
||||
|
||||
|
|
@ -147,53 +87,32 @@ class CustomCommandActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun swapFabs() {
|
||||
val cancel = cancelFab!!.visibility
|
||||
val start = fab!!.visibility
|
||||
cancelFab!!.visibility = start
|
||||
fab!!.visibility = cancel
|
||||
}
|
||||
|
||||
|
||||
private fun startDownloadService(command: String?, id: Int) {
|
||||
private fun startDownload(command: String?) {
|
||||
if (isDownloadServiceRunning) return
|
||||
//val serviceIntent = Intent(context, DownloaderService::class.java)
|
||||
// serviceIntent.putExtra("command", command)
|
||||
// serviceIntent.putExtra("id", id)
|
||||
//context!!.applicationContext.bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE)
|
||||
downloadViewModel.startTerminalDownload(command!!)
|
||||
output!!.text = ""
|
||||
workManager.getWorkInfosByTagLiveData("terminal")
|
||||
.observe(this){ list ->
|
||||
list.forEach {
|
||||
if(it.progress.getString("output") != null){
|
||||
output?.append("\n" + it.progress.getString("output") + "\n")
|
||||
output?.scrollTo(0, output!!.height)
|
||||
scrollView?.fullScroll(View.FOCUS_DOWN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun stopDownloadService() {
|
||||
// if (!isDownloadServiceRunning) return
|
||||
// iDownloaderService!!.removeActivity(this)
|
||||
// context!!.applicationContext.unbindService(serviceConnection)
|
||||
// downloaderService!!.stopForeground(true)
|
||||
// downloaderService!!.stopSelf()
|
||||
// isDownloadServiceRunning = false
|
||||
}
|
||||
|
||||
fun cancelDownloadService() {
|
||||
if (!isDownloadServiceRunning) return
|
||||
iDownloaderService!!.cancelDownload(false)
|
||||
stopDownloadService()
|
||||
}
|
||||
|
||||
private val isStoragePermissionGranted: Boolean
|
||||
get() = if (ActivityCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
== PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
true
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(
|
||||
this,
|
||||
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
|
||||
1
|
||||
)
|
||||
false
|
||||
private fun cancelDownload() {
|
||||
lifecycleScope.launch {
|
||||
val id = withContext(Dispatchers.IO){ downloadViewModel.getTerminalDownload(); }
|
||||
YoutubeDL.getInstance().destroyProcessById(id.toString())
|
||||
WorkManager.getInstance(this@CustomCommandActivity).cancelUniqueWork(id.toString())
|
||||
notificationUtil.cancelDownloadNotification(id.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "CustomCommandActivity"
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
|
|||
tabLayout.selectTab(tabLayout.getTabAt(1))
|
||||
viewPager2.setCurrentItem(1, false)
|
||||
}
|
||||
Type.command -> {
|
||||
else -> {
|
||||
tabLayout.selectTab(tabLayout.getTabAt(2))
|
||||
viewPager2.setCurrentItem(2, false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
|
|||
tabLayout.selectTab(tabLayout.getTabAt(1))
|
||||
viewPager2.setCurrentItem(1, false)
|
||||
}
|
||||
Type.command -> {
|
||||
else -> {
|
||||
tabLayout.selectTab(tabLayout.getTabAt(2))
|
||||
viewPager2.setCurrentItem(2, false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
package com.deniscerri.ytdlnis.ui.settings
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.os.LocaleList
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import java.util.*
|
||||
|
||||
|
||||
class SettingsActivity : AppCompatActivity() {
|
||||
private var fm: FragmentManager? = null
|
||||
|
|
@ -23,4 +27,34 @@ class SettingsActivity : AppCompatActivity() {
|
|||
.replace(R.id.settings_frame_layout, SettingsFragment())
|
||||
.commit()
|
||||
}
|
||||
|
||||
fun setLocale(l: String){
|
||||
|
||||
val locale = Locale(l)
|
||||
Locale.setDefault(locale)
|
||||
val config: Configuration = this.resources.configuration
|
||||
if (Build.VERSION.SDK_INT >= 24){
|
||||
Locale.setDefault(locale)
|
||||
config.setLocales(LocaleList(locale))
|
||||
this.resources.updateConfiguration(config, this.resources.displayMetrics)
|
||||
onConfigurationChanged(config)
|
||||
}else{
|
||||
Locale.setDefault(locale)
|
||||
config.locale = locale
|
||||
config.setLayoutDirection(locale)
|
||||
this.resources.updateConfiguration(config, this.resources.displayMetrics)
|
||||
onConfigurationChanged(config)
|
||||
}
|
||||
restartActivity()
|
||||
|
||||
}
|
||||
|
||||
private fun restartActivity() {
|
||||
// val intent = intent
|
||||
// finish()
|
||||
// startActivity(Intent(this, MainActivity::class.java))
|
||||
recreate()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,17 +2,23 @@ package com.deniscerri.ytdlnis.ui.settings
|
|||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.preference.*
|
||||
import com.deniscerri.ytdlnis.BuildConfig
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.UpdateUtil
|
||||
import java.util.*
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
private var language: ListPreference? = null
|
||||
private var musicPath: Preference? = null
|
||||
private var videoPath: Preference? = null
|
||||
private var commandPath: Preference? = null
|
||||
|
|
@ -51,6 +57,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
val preferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
val editor = preferences.edit()
|
||||
language = findPreference("app_language")
|
||||
musicPath = findPreference("music_path")
|
||||
videoPath = findPreference("video_path")
|
||||
commandPath = findPreference("command_path")
|
||||
|
|
@ -76,6 +83,20 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
updateApp = findPreference("update_app")
|
||||
version = findPreference("version")
|
||||
version!!.summary = BuildConfig.VERSION_NAME
|
||||
|
||||
val values = resources.getStringArray(R.array.language_values)
|
||||
if (Build.VERSION.SDK_INT >= 34){
|
||||
language!!.isVisible = false
|
||||
}else{
|
||||
val entries = mutableListOf<String>()
|
||||
values.forEach {
|
||||
entries.add(Locale(it).getDisplayName(Locale(it)))
|
||||
}
|
||||
language!!.entries = entries.toTypedArray()
|
||||
}
|
||||
val lang = if (values.contains(Locale.getDefault().language)) Locale.getDefault().language else "en"
|
||||
editor.putString("app_language", lang)
|
||||
|
||||
if (preferences.getString("music_path", "")!!.isEmpty()) {
|
||||
editor.putString("music_path", getString(R.string.music_path))
|
||||
}
|
||||
|
|
@ -111,6 +132,17 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
val preferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
val editor = preferences.edit()
|
||||
language!!.summary = Locale(preferences.getString("app_language", "")!!).getDisplayLanguage(Locale(preferences.getString("app_language", "")!!))
|
||||
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()))
|
||||
(requireActivity() as SettingsActivity).setLocale(newValue.toString())
|
||||
true
|
||||
}
|
||||
|
||||
musicPath!!.summary = fileUtil?.formatPath(preferences.getString("music_path", "")!!)
|
||||
musicPath!!.onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
|
|
|
|||
|
|
@ -67,13 +67,13 @@ class DownloadWorker(
|
|||
|
||||
|
||||
val url = downloadItem.url
|
||||
val request = YoutubeDLRequest(url)
|
||||
var request = YoutubeDLRequest(url)
|
||||
val type = downloadItem.type
|
||||
val downloadLocation = downloadItem.downloadPath
|
||||
|
||||
val tempFolder = StringBuilder(context.cacheDir.absolutePath + """/${downloadItem.title}##${downloadItem.type}""")
|
||||
var tempFolder = StringBuilder(context.cacheDir.absolutePath + """/${downloadItem.title}##${downloadItem.type}""")
|
||||
tempFolder.append("##${downloadItem.format.format_id}")
|
||||
val tempFileDir = File(tempFolder.toString())
|
||||
var tempFileDir = File(tempFolder.toString())
|
||||
tempFileDir.delete()
|
||||
tempFileDir.mkdir()
|
||||
|
||||
|
|
@ -190,6 +190,32 @@ class DownloadWorker(
|
|||
}
|
||||
}
|
||||
}
|
||||
DownloadViewModel.Type.terminal -> {
|
||||
if(downloadItem.format.format_note.startsWith("yt-dlp ")){
|
||||
downloadItem.format.format_note = downloadItem.format.format_note.substring(6).trim();
|
||||
}
|
||||
|
||||
val commandRegex = "\"([^\"]*)\"|(\\S+)"
|
||||
request = YoutubeDLRequest(emptyList())
|
||||
|
||||
tempFolder = StringBuilder(context.cacheDir.absolutePath + """/${downloadItem.format.format_id}##terminal""")
|
||||
tempFileDir = File(tempFolder.toString())
|
||||
tempFileDir.delete()
|
||||
tempFileDir.mkdir()
|
||||
|
||||
|
||||
val m = Pattern.compile(commandRegex).matcher(downloadItem.format.format_note)
|
||||
while (m.find()) {
|
||||
if (m.group(1) != null) {
|
||||
request.addOption(m.group(1)!!)
|
||||
} else {
|
||||
request.addOption(m.group(2)!!)
|
||||
}
|
||||
}
|
||||
|
||||
request.addOption("-o", tempFileDir.absolutePath + "/${downloadItem.customFileNameTemplate}.%(ext)s")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
runCatching {
|
||||
|
|
|
|||
5
app/src/main/res/drawable/ic_language.xml
Normal file
5
app/src/main/res/drawable/ic_language.xml
Normal 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="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2 0,0.68 0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2 0,-0.68 0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2 0,0.68 -0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2 0,-0.68 -0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z"/>
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/ic_terminal.xml
Normal file
5
app/src/main/res/drawable/ic_terminal.xml
Normal 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="M20,4H4C2.89,4 2,4.9 2,6v12c0,1.1 0.89,2 2,2h16c1.1,0 2,-0.9 2,-2V6C22,4.9 21.11,4 20,4zM20,18H4V8h16V18zM18,17h-6v-2h6V17zM7.5,17l-1.41,-1.41L8.67,13l-2.59,-2.59L7.5,9l4,4L7.5,17z"/>
|
||||
</vector>
|
||||
|
|
@ -64,8 +64,7 @@
|
|||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/custom_command_toolbar"
|
||||
android:elevation="0dp"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap"
|
||||
app:title="@string/custom_command"
|
||||
app:title="@string/terminal"
|
||||
android:layout_width="match_parent"
|
||||
app:navigationIcon="@drawable/ic_back"
|
||||
android:layout_height="match_parent"/>
|
||||
|
|
|
|||
|
|
@ -142,4 +142,22 @@
|
|||
<string name="sponsorblock_fillers">Pjesë Shtesë</string>
|
||||
<string name="sponsorblock_reminders">Përkujtuesit e Abonimit</string>
|
||||
<string name="select_sponsorblock_filtering">Zgjidh Filtrimin e SponsorBlock</string>
|
||||
<string name="save_dir">Direktoria</string>
|
||||
<string name="new_template">Shabllon i ri</string>
|
||||
<string name="adjust_templates">Cakto Shabllonët</string>
|
||||
<string name="edit_selected">Redakto të zgjedhurin</string>
|
||||
<string name="adjust_video">Modifiko Videon</string>
|
||||
<string name="schedule">Planifiko</string>
|
||||
<string name="concurrent_downloads">Shkarkimet e njëkohësishme</string>
|
||||
<string name="concurrent_downloads_summary">Numri i shkarkimeve qe do ekzekutohen në të njëjtën kohë</string>
|
||||
<string name="defaultValue">Siç është</string>
|
||||
<string name="container">Formati</string>
|
||||
<string name="template">Shablloni</string>
|
||||
<string name="logs">Shënimet</string>
|
||||
<string name="commands">Komandat</string>
|
||||
<string name="date_added">Data e shtuar</string>
|
||||
<string name="update_ytdl_nightly">Shkarko versionin beta të yt-dlp</string>
|
||||
<string name="adjust_audio">Modifiko Audion</string>
|
||||
<string name="file_name_template">Formati i Emrit të Skedarit</string>
|
||||
<string name="language">Gjuha</string>
|
||||
</resources>
|
||||
|
|
@ -58,4 +58,16 @@
|
|||
<item>0.0</item>
|
||||
<item>100.0</item>
|
||||
</array>
|
||||
|
||||
<string-array name="language_values">
|
||||
<item>en</item>
|
||||
<item>de</item>
|
||||
<item>fr</item>
|
||||
<item>ja</item>
|
||||
<item>nb</item>
|
||||
<item>pl</item>
|
||||
<item>ru</item>
|
||||
<item>sq</item>
|
||||
<item>tr</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
|
@ -155,7 +155,6 @@
|
|||
<string name="adjust_templates">Adjust templates</string>
|
||||
<string name="edit_selected">Edit selected</string>
|
||||
<string name="adjust_video">Adjust video</string>
|
||||
<string name="remove_audio">Remove Audio</string>
|
||||
<string name="schedule">Schedule</string>
|
||||
<string name="concurrent_downloads">Concurrent Downloads</string>
|
||||
<string name="concurrent_downloads_summary">Number of downloads executing at the same time</string>
|
||||
|
|
@ -168,4 +167,7 @@
|
|||
<string name="update_ytdl_nightly">Download Nightly Version of yt-dlp</string>
|
||||
<string name="adjust_audio">Adjust Audio</string>
|
||||
<string name="file_name_template">Filename Template</string>
|
||||
<string name="language">Language</string>
|
||||
<string name="command_templates">Command Templates</string>
|
||||
<string name="terminal">Terminal</string>
|
||||
</resources>
|
||||
12
app/src/main/res/xml/locales_config.xml
Normal file
12
app/src/main/res/xml/locales_config.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<locale android:name="en"/>
|
||||
<locale android:name="de"/>
|
||||
<locale android:name="fr"/>
|
||||
<locale android:name="ja"/>
|
||||
<locale android:name="nb-NO"/>
|
||||
<locale android:name="pl"/>
|
||||
<locale android:name="ru"/>
|
||||
<locale android:name="sq-AL"/>
|
||||
<locale android:name="tr-TR"/>
|
||||
</locale-config>
|
||||
|
|
@ -17,10 +17,11 @@
|
|||
android:data="https://github.com/deniscerri/ytdlnis" />
|
||||
</Preference>
|
||||
|
||||
|
||||
<Preference
|
||||
app:icon="@drawable/ic_baseline_keyboard_arrow_right_24"
|
||||
app:icon="@drawable/ic_terminal"
|
||||
app:key="run_command"
|
||||
app:title="@string/custom_command">
|
||||
app:title="@string/terminal">
|
||||
<intent android:action="ytdlnis.page.CustomCommandActivity" />
|
||||
</Preference>
|
||||
|
||||
|
|
@ -32,9 +33,18 @@
|
|||
<intent android:action="ytdlnis.page.DownloadLogsActivity" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
app:icon="@drawable/ic_baseline_keyboard_arrow_right_24"
|
||||
app:key="command_templates"
|
||||
app:allowDividerBelow="true"
|
||||
app:title="@string/command_templates">
|
||||
<intent android:action="ytdlnis.page.DownloadLogsActivity" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
app:icon="@drawable/ic_settings"
|
||||
app:key="open_settings"
|
||||
app:allowDividerAbove="true"
|
||||
app:title="@string/settings">
|
||||
<intent android:action="ytdlnis.settings.SettingsActivity" />
|
||||
</Preference>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
<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/ic_language"
|
||||
app:key="app_language"
|
||||
app:summary="en"
|
||||
app:title="@string/language" />
|
||||
|
||||
<PreferenceCategory android:title="@string/directories">
|
||||
<Preference
|
||||
app:icon="@drawable/ic_music_downloaded"
|
||||
|
|
|
|||
Loading…
Reference in a new issue