added ability to edit command template & delete. Fixed logs not scrolling. Implemented import/export templates from clipboard. Implemented Error Items Log Button
This commit is contained in:
parent
5fed145313
commit
7d5f32b4bf
30 changed files with 331 additions and 110 deletions
|
|
@ -6,6 +6,7 @@ plugins {
|
||||||
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1'
|
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1'
|
||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
id 'kotlin-kapt'
|
id 'kotlin-kapt'
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization" version "1.7.21"
|
||||||
}
|
}
|
||||||
|
|
||||||
def properties = new Properties()
|
def properties = new Properties()
|
||||||
|
|
@ -175,5 +176,4 @@ dependencies {
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -23,6 +23,7 @@ import com.deniscerri.ytdlnis.util.FileUtil
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.card.MaterialCardView
|
import com.google.android.material.card.MaterialCardView
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
import java.io.File
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
@ -106,7 +107,13 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
|
||||||
when(item.status){
|
when(item.status){
|
||||||
DownloadRepository.Status.Cancelled.toString() -> actionButton.setIconResource(R.drawable.ic_refresh)
|
DownloadRepository.Status.Cancelled.toString() -> actionButton.setIconResource(R.drawable.ic_refresh)
|
||||||
DownloadRepository.Status.Queued.toString() -> actionButton.setIconResource(R.drawable.ic_baseline_delete_outline_24)
|
DownloadRepository.Status.Queued.toString() -> actionButton.setIconResource(R.drawable.ic_baseline_delete_outline_24)
|
||||||
else -> actionButton.setIconResource(R.drawable.ic_baseline_file_open_24)
|
else -> {
|
||||||
|
actionButton.setIconResource(R.drawable.ic_baseline_file_open_24)
|
||||||
|
val logFile = File(activity.filesDir.absolutePath + """/logs/${item.id} - ${item.title}##${item.type}##${item.format.format_id}.log""")
|
||||||
|
if (!logFile.exists()){
|
||||||
|
actionButton.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,14 +53,19 @@ class TemplatesAdapter(onItemClickListener: OnItemClickListener, activity: Activ
|
||||||
// onItemClickListener.onSelected(item!!)
|
// onItemClickListener.onSelected(item!!)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
title.setOnClickListener {
|
card.setOnClickListener {
|
||||||
onItemClickListener.onItemClick(item!!)
|
onItemClickListener.onItemClick(item!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
card.setOnLongClickListener {
|
||||||
|
onItemClickListener.onDelete(item!!); true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnItemClickListener {
|
interface OnItemClickListener {
|
||||||
fun onItemClick(commandTemplate: CommandTemplate)
|
fun onItemClick(commandTemplate: CommandTemplate)
|
||||||
fun onSelected(commandTemplate: CommandTemplate)
|
fun onSelected(commandTemplate: CommandTemplate)
|
||||||
|
fun onDelete(commandTemplate: CommandTemplate)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,10 @@ interface CommandTemplateDao {
|
||||||
fun getAllTemplatesLiveData() : LiveData<List<CommandTemplate>>
|
fun getAllTemplatesLiveData() : LiveData<List<CommandTemplate>>
|
||||||
|
|
||||||
@Query("SELECT * FROM templateShortcuts ORDER BY id DESC")
|
@Query("SELECT * FROM templateShortcuts ORDER BY id DESC")
|
||||||
fun getAllShortcuts() : LiveData<List<TemplateShortcut>>
|
fun getAllShortcutsLiveData() : LiveData<List<TemplateShortcut>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM templateShortcuts ORDER BY id DESC")
|
||||||
|
fun getAllShortcuts() : List<TemplateShortcut>
|
||||||
|
|
||||||
@Query("SELECT COUNT(id) FROM commandTemplates")
|
@Query("SELECT COUNT(id) FROM commandTemplates")
|
||||||
fun getTotalNumber() : Int
|
fun getTotalNumber() : Int
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ interface DownloadDao {
|
||||||
@Query("SELECT * FROM downloads WHERE status='Queued'")
|
@Query("SELECT * FROM downloads WHERE status='Queued'")
|
||||||
fun getQueuedDownloads() : LiveData<List<DownloadItem>>
|
fun getQueuedDownloads() : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads WHERE status='Cancelled'")
|
@Query("SELECT * FROM downloads WHERE status='Cancelled' ORDER BY id DESC")
|
||||||
fun getCancelledDownloads() : LiveData<List<DownloadItem>>
|
fun getCancelledDownloads() : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads WHERE status='Error'")
|
@Query("SELECT * FROM downloads WHERE status='Error' ORDER BY id DESC")
|
||||||
fun getErroredDownloads() : LiveData<List<DownloadItem>>
|
fun getErroredDownloads() : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads WHERE status='Processing'")
|
@Query("SELECT * FROM downloads WHERE status='Processing' ORDER BY id DESC")
|
||||||
fun getProcessingDownloads() : LiveData<List<DownloadItem>>
|
fun getProcessingDownloads() : LiveData<List<DownloadItem>>
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads WHERE id=:id LIMIT 1")
|
@Query("SELECT * FROM downloads WHERE id=:id LIMIT 1")
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
package com.deniscerri.ytdlnis.database.models
|
package com.deniscerri.ytdlnis.database.models
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
@Entity(tableName = "commandTemplates")
|
@Entity(tableName = "commandTemplates")
|
||||||
data class CommandTemplate(
|
data class CommandTemplate(
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
var id: Long,
|
var id: Long,
|
||||||
val title: String,
|
var title: String,
|
||||||
val content: String
|
var content: String
|
||||||
)
|
)
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.deniscerri.ytdlnis.database.models
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CommandTemplateExport(
|
||||||
|
val templates: List<CommandTemplate>,
|
||||||
|
val shortcuts: List<TemplateShortcut>
|
||||||
|
)
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
package com.deniscerri.ytdlnis.database.models
|
package com.deniscerri.ytdlnis.database.models
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
@Entity(tableName = "templateShortcuts")
|
@Entity(tableName = "templateShortcuts")
|
||||||
data class TemplateShortcut(
|
data class TemplateShortcut(
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import com.deniscerri.ytdlnis.database.models.TemplateShortcut
|
||||||
|
|
||||||
class CommandTemplateRepository(private val commandDao: CommandTemplateDao) {
|
class CommandTemplateRepository(private val commandDao: CommandTemplateDao) {
|
||||||
val items : LiveData<List<CommandTemplate>> = commandDao.getAllTemplatesLiveData()
|
val items : LiveData<List<CommandTemplate>> = commandDao.getAllTemplatesLiveData()
|
||||||
val shortcuts : LiveData<List<TemplateShortcut>> = commandDao.getAllShortcuts()
|
val shortcuts : LiveData<List<TemplateShortcut>> = commandDao.getAllShortcutsLiveData()
|
||||||
|
|
||||||
fun getAll() : List<CommandTemplate> {
|
fun getAll() : List<CommandTemplate> {
|
||||||
return commandDao.getAllTemplates();
|
return commandDao.getAllTemplates();
|
||||||
|
|
@ -25,6 +25,10 @@ class CommandTemplateRepository(private val commandDao: CommandTemplateDao) {
|
||||||
commandDao.delete(item.id)
|
commandDao.delete(item.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getAllShortCuts() : List<TemplateShortcut> {
|
||||||
|
return commandDao.getAllShortcuts();
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun insertShortcut(item: TemplateShortcut){
|
suspend fun insertShortcut(item: TemplateShortcut){
|
||||||
commandDao.insertShortcut(item.content)
|
commandDao.insertShortcut(item.content)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
package com.deniscerri.ytdlnis.database.viewmodel
|
package com.deniscerri.ytdlnis.database.viewmodel
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
|
import android.content.Context.CLIPBOARD_SERVICE
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.ContextCompat.getSystemService
|
||||||
import androidx.lifecycle.*
|
import androidx.lifecycle.*
|
||||||
import com.deniscerri.ytdlnis.database.DBManager
|
import com.deniscerri.ytdlnis.database.DBManager
|
||||||
import com.deniscerri.ytdlnis.database.models.CommandTemplate
|
import com.deniscerri.ytdlnis.database.models.CommandTemplate
|
||||||
|
import com.deniscerri.ytdlnis.database.models.CommandTemplateExport
|
||||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||||
import com.deniscerri.ytdlnis.database.models.TemplateShortcut
|
import com.deniscerri.ytdlnis.database.models.TemplateShortcut
|
||||||
import com.deniscerri.ytdlnis.database.repository.CommandTemplateRepository
|
import com.deniscerri.ytdlnis.database.repository.CommandTemplateRepository
|
||||||
|
|
@ -11,13 +17,20 @@ import com.deniscerri.ytdlnis.database.repository.HistoryRepository
|
||||||
import com.deniscerri.ytdlnis.database.repository.HistoryRepository.HistorySort
|
import com.deniscerri.ytdlnis.database.repository.HistoryRepository.HistorySort
|
||||||
import com.deniscerri.ytdlnis.database.repository.HistoryRepository.HistorySortType
|
import com.deniscerri.ytdlnis.database.repository.HistoryRepository.HistorySortType
|
||||||
import com.deniscerri.ytdlnis.util.FileUtil
|
import com.deniscerri.ytdlnis.util.FileUtil
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.JsonObject
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
class CommandTemplateViewModel(application: Application) : AndroidViewModel(application) {
|
class CommandTemplateViewModel(private val application: Application) : AndroidViewModel(application) {
|
||||||
private val repository: CommandTemplateRepository
|
private val repository: CommandTemplateRepository
|
||||||
val items: LiveData<List<CommandTemplate>>
|
val items: LiveData<List<CommandTemplate>>
|
||||||
val shortcuts : LiveData<List<TemplateShortcut>>
|
val shortcuts : LiveData<List<TemplateShortcut>>
|
||||||
|
private val jsonFormat = Json { prettyPrint = true }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val dao = DBManager.getInstance(application).commandTemplateDao
|
val dao = DBManager.getInstance(application).commandTemplateDao
|
||||||
|
|
@ -58,12 +71,53 @@ class CommandTemplateViewModel(application: Application) : AndroidViewModel(appl
|
||||||
repository.update(item)
|
repository.update(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun importFromClipboard() = viewModelScope.launch(Dispatchers.IO) {
|
suspend fun importFromClipboard() : Int {
|
||||||
|
val allTemplates = repository.getAll()
|
||||||
|
val allShortcuts = repository.getAllShortCuts()
|
||||||
|
var count = 0
|
||||||
|
val clipboard = application.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
val clip = clipboard.primaryClip!!.getItemAt(0).text.toString()
|
||||||
|
try{
|
||||||
|
jsonFormat.decodeFromString<CommandTemplateExport>(clip).run {
|
||||||
|
templates.filterNot {
|
||||||
|
allTemplates.contains(it)
|
||||||
|
}.run {
|
||||||
|
this.forEach {
|
||||||
|
repository.insert(it.copy(id=0))
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shortcuts.filterNot {
|
||||||
|
allShortcuts.contains(it)
|
||||||
|
}.run{
|
||||||
|
this.forEach {
|
||||||
|
repository.insertShortcut(it.copy(id=0))
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch (e: Exception){
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exportToClipboard() {
|
|
||||||
|
|
||||||
|
fun exportToClipboard() = viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
val allTemplates = repository.getAll()
|
||||||
|
val allShortcuts = repository.getAllShortCuts()
|
||||||
|
val output = jsonFormat.encodeToString(
|
||||||
|
CommandTemplateExport(
|
||||||
|
templates = allTemplates,
|
||||||
|
shortcuts = allShortcuts
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val clipboard: ClipboardManager =
|
||||||
|
application.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
clipboard.setText(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +105,14 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addSearchQueryToHistory(query: String) = viewModelScope.launch(Dispatchers.IO) {
|
fun addSearchQueryToHistory(query: String) = viewModelScope.launch(Dispatchers.IO) {
|
||||||
searchHistoryRepository.insert(query)
|
val allQueries = searchHistoryRepository.getAll()
|
||||||
|
allQueries.filterNot {
|
||||||
|
it.query == query
|
||||||
|
}.run {
|
||||||
|
this.forEach {
|
||||||
|
searchHistoryRepository.insert(it.query)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteAllSearchQueryHistory() = viewModelScope.launch(Dispatchers.IO){
|
fun deleteAllSearchQueryHistory() = viewModelScope.launch(Dispatchers.IO){
|
||||||
|
|
|
||||||
|
|
@ -121,10 +121,10 @@ class ShareActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private fun showDownloadSheet(it: ResultItem){
|
private fun showDownloadSheet(it: ResultItem){
|
||||||
if (sharedPreferences.getBoolean("download_card", true)){
|
if (sharedPreferences.getBoolean("download_card", true)){
|
||||||
val bottomSheet = DownloadBottomSheetDialog(it, DownloadViewModel.Type.video)
|
val bottomSheet = DownloadBottomSheetDialog(it, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
|
||||||
bottomSheet.show(supportFragmentManager, "downloadSingleSheet")
|
bottomSheet.show(supportFragmentManager, "downloadSingleSheet")
|
||||||
}else{
|
}else{
|
||||||
val downloadItem = downloadViewModel.createDownloadItemFromResult(it, DownloadViewModel.Type.video)
|
val downloadItem = downloadViewModel.createDownloadItemFromResult(it, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
|
||||||
downloadViewModel.queueDownloads(listOf(downloadItem))
|
downloadViewModel.queueDownloads(listOf(downloadItem))
|
||||||
this.finish()
|
this.finish()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
}else if (resultViewModel.itemCount.value!! == 1){
|
}else if (resultViewModel.itemCount.value!! == 1){
|
||||||
if (sharedPreferences!!.getBoolean("download_card", true)){
|
if (sharedPreferences!!.getBoolean("download_card", true)){
|
||||||
if(it.size == 1 && !firstBoot && parentFragmentManager.findFragmentByTag("downloadSingleSheet") == null){
|
if(it.size == 1 && !firstBoot && parentFragmentManager.findFragmentByTag("downloadSingleSheet") == null){
|
||||||
showSingleDownloadSheet(it[0], DownloadViewModel.Type.video)
|
showSingleDownloadSheet(it[0], DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
|
|
||||||
|
|
@ -109,16 +109,18 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
|
||||||
|
|
||||||
when(type) {
|
when(type) {
|
||||||
Type.audio -> {
|
Type.audio -> {
|
||||||
tabLayout.selectTab(tabLayout.getTabAt(0))
|
tabLayout.getTabAt(0)!!.select()
|
||||||
viewPager2.setCurrentItem(0, false)
|
viewPager2.setCurrentItem(0, false)
|
||||||
}
|
}
|
||||||
Type.video -> {
|
Type.video -> {
|
||||||
tabLayout.selectTab(tabLayout.getTabAt(1))
|
tabLayout.getTabAt(1)!!.select()
|
||||||
viewPager2.setCurrentItem(1, false)
|
viewPager2.setCurrentItem(1, false)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
tabLayout.selectTab(tabLayout.getTabAt(2))
|
tabLayout.getTabAt(2)!!.select()
|
||||||
viewPager2.setCurrentItem(2, false)
|
viewPager2.postDelayed( {
|
||||||
|
viewPager2.setCurrentItem(2, false)
|
||||||
|
}, 200)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
|
import com.deniscerri.ytdlnis.database.models.CommandTemplate
|
||||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
import com.deniscerri.ytdlnis.database.models.Format
|
import com.deniscerri.ytdlnis.database.models.Format
|
||||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||||
|
|
@ -68,8 +69,8 @@ class DownloadCommandFragment(private val resultItem: ResultItem) : Fragment() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||||
try {
|
try {
|
||||||
val templates = withContext(Dispatchers.IO){
|
val templates : MutableList<CommandTemplate> = withContext(Dispatchers.IO){
|
||||||
commandTemplateViewModel.getAll()
|
commandTemplateViewModel.getAll().toMutableList()
|
||||||
}
|
}
|
||||||
val id = sharedPreferences.getLong("commandTemplate", templates[0].id)
|
val id = sharedPreferences.getLong("commandTemplate", templates[0].id)
|
||||||
val chosenCommand = templates.find { it.id == id }
|
val chosenCommand = templates.find { it.id == id }
|
||||||
|
|
@ -117,21 +118,10 @@ class DownloadCommandFragment(private val resultItem: ResultItem) : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val templateTitles = templates.map {it.title}
|
|
||||||
|
|
||||||
val commandTemplates = view.findViewById<TextInputLayout>(R.id.template)
|
val commandTemplates = view.findViewById<TextInputLayout>(R.id.template)
|
||||||
val autoCompleteTextView =
|
val autoCompleteTextView =
|
||||||
view.findViewById<AutoCompleteTextView>(R.id.template_textview)
|
requireView().findViewById<AutoCompleteTextView>(R.id.template_textview)
|
||||||
autoCompleteTextView?.setAdapter(
|
populateCommandTemplates(templates, autoCompleteTextView)
|
||||||
ArrayAdapter(
|
|
||||||
requireContext(),
|
|
||||||
android.R.layout.simple_dropdown_item_1line,
|
|
||||||
templateTitles
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if (templateTitles.isNotEmpty()) {
|
|
||||||
autoCompleteTextView!!.setText(downloadItem.format.format_id, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
(commandTemplates!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
(commandTemplates!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||||
|
|
@ -168,29 +158,40 @@ class DownloadCommandFragment(private val resultItem: ResultItem) : Fragment() {
|
||||||
|
|
||||||
val newTemplate : Chip = view.findViewById(R.id.newTemplate)
|
val newTemplate : Chip = view.findViewById(R.id.newTemplate)
|
||||||
newTemplate.setOnClickListener {
|
newTemplate.setOnClickListener {
|
||||||
uiUtil.showCreationSheet(requireActivity(), viewLifecycleOwner, commandTemplateViewModel) {
|
uiUtil.showCommandTemplateCreationOrUpdatingSheet(null, requireActivity(), viewLifecycleOwner, commandTemplateViewModel) {
|
||||||
|
templates.add(it)
|
||||||
|
chosenCommandView.editText!!.setText(it.content)
|
||||||
|
downloadItem.format = Format(
|
||||||
|
it.title,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
0,
|
||||||
|
it.content
|
||||||
|
)
|
||||||
|
populateCommandTemplates(templates, autoCompleteTextView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
val editSelected : Chip = view.findViewById(R.id.editSelected)
|
||||||
// val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
|
editSelected.setOnClickListener {
|
||||||
// embedSubs!!.isChecked = embedSubs.isChecked
|
var current = templates.find { it.title == autoCompleteTextView.text.toString() }
|
||||||
// embedSubs.setOnClickListener {
|
if (current == null) current = CommandTemplate(0, "", chosenCommandView.editText!!.text.toString())
|
||||||
// downloadItem.embedSubs = embedSubs.isChecked
|
uiUtil.showCommandTemplateCreationOrUpdatingSheet(current, requireActivity(), viewLifecycleOwner, commandTemplateViewModel) {
|
||||||
// }
|
templates.add(it)
|
||||||
//
|
chosenCommandView.editText!!.setText(it.content)
|
||||||
// val addChapters = view.findViewById<Chip>(R.id.add_chapters)
|
downloadItem.format = Format(
|
||||||
// addChapters!!.isChecked = addChapters.isChecked
|
it.title,
|
||||||
// addChapters.setOnClickListener{
|
"",
|
||||||
// downloadItem.addChapters = addChapters.isChecked
|
"",
|
||||||
// }
|
"",
|
||||||
//
|
"",
|
||||||
// val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)
|
0,
|
||||||
// saveThumbnail!!.isChecked = saveThumbnail.isChecked
|
it.content
|
||||||
// saveThumbnail.setOnClickListener {
|
)
|
||||||
// downloadItem.SaveThumb = saveThumbnail.isChecked
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
@ -198,6 +199,22 @@ class DownloadCommandFragment(private val resultItem: ResultItem) : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun populateCommandTemplates(templates: List<CommandTemplate>, autoCompleteTextView: AutoCompleteTextView?){
|
||||||
|
val templateTitles = templates.map {it.title}
|
||||||
|
|
||||||
|
|
||||||
|
autoCompleteTextView?.setAdapter(
|
||||||
|
ArrayAdapter(
|
||||||
|
requireContext(),
|
||||||
|
android.R.layout.simple_dropdown_item_1line,
|
||||||
|
templateTitles
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (templateTitles.isNotEmpty()) {
|
||||||
|
autoCompleteTextView!!.setText(downloadItem.format.format_id, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var commandPathResultLauncher = registerForActivityResult(
|
private var commandPathResultLauncher = registerForActivityResult(
|
||||||
ActivityResultContracts.StartActivityForResult()
|
ActivityResultContracts.StartActivityForResult()
|
||||||
) { result ->
|
) { result ->
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.deniscerri.ytdlnis.ui.downloadqueue
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
|
import android.content.Intent
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
|
@ -23,6 +24,7 @@ import com.deniscerri.ytdlnis.adapter.GenericDownloadAdapter
|
||||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||||
|
import com.deniscerri.ytdlnis.ui.more.downloadLogs.DownloadLogActivity
|
||||||
import com.deniscerri.ytdlnis.util.FileUtil
|
import com.deniscerri.ytdlnis.util.FileUtil
|
||||||
import com.deniscerri.ytdlnis.util.UiUtil
|
import com.deniscerri.ytdlnis.util.UiUtil
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
|
@ -85,7 +87,11 @@ class ErroredDownloadsFragment() : Fragment(), GenericDownloadAdapter.OnItemClic
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActionButtonClick(itemID: Long) {
|
override fun onActionButtonClick(itemID: Long) {
|
||||||
TODO("Not yet implemented")
|
val item = items.find { it.id == itemID } ?: return
|
||||||
|
val file = File(requireContext().filesDir.absolutePath + """/logs/${item.id} - ${item.title}##${item.type}##${item.format.format_id}.log""")
|
||||||
|
val intent = Intent(requireContext(), DownloadLogActivity::class.java)
|
||||||
|
intent.putExtra("path", file.absolutePath)
|
||||||
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCardClick(itemID: Long) {
|
override fun onCardClick(itemID: Long) {
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,27 @@
|
||||||
package com.deniscerri.ytdlnis.ui.more
|
package com.deniscerri.ytdlnis.ui.more
|
||||||
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.os.*
|
import android.os.*
|
||||||
import android.text.Editable
|
|
||||||
import android.text.TextWatcher
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.view.Window
|
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
import com.deniscerri.ytdlnis.adapter.TemplatesAdapter
|
import com.deniscerri.ytdlnis.adapter.TemplatesAdapter
|
||||||
import com.deniscerri.ytdlnis.database.models.CommandTemplate
|
import com.deniscerri.ytdlnis.database.models.CommandTemplate
|
||||||
import com.deniscerri.ytdlnis.database.models.TemplateShortcut
|
|
||||||
import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel
|
import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel
|
||||||
import com.deniscerri.ytdlnis.util.FileUtil
|
import com.deniscerri.ytdlnis.util.FileUtil
|
||||||
import com.deniscerri.ytdlnis.util.UiUtil
|
import com.deniscerri.ytdlnis.util.UiUtil
|
||||||
import com.google.android.material.appbar.MaterialToolbar
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
|
||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
import com.google.android.material.chip.ChipGroup
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
|
||||||
class CommandTemplatesActivity : AppCompatActivity(), TemplatesAdapter.OnItemClickListener {
|
class CommandTemplatesActivity : AppCompatActivity(), TemplatesAdapter.OnItemClickListener {
|
||||||
|
|
@ -68,9 +63,19 @@ class CommandTemplatesActivity : AppCompatActivity(), TemplatesAdapter.OnItemCli
|
||||||
topAppBar.setOnMenuItemClickListener { m: MenuItem ->
|
topAppBar.setOnMenuItemClickListener { m: MenuItem ->
|
||||||
val itemId = m.itemId
|
val itemId = m.itemId
|
||||||
if (itemId == R.id.export_clipboard) {
|
if (itemId == R.id.export_clipboard) {
|
||||||
commandTemplateViewModel.exportToClipboard()
|
lifecycleScope.launch(Dispatchers.IO){
|
||||||
|
commandTemplateViewModel.exportToClipboard()
|
||||||
|
}
|
||||||
}else if (itemId == R.id.import_clipboard){
|
}else if (itemId == R.id.import_clipboard){
|
||||||
commandTemplateViewModel.importFromClipboard()
|
lifecycleScope.launch{
|
||||||
|
withContext(Dispatchers.IO){
|
||||||
|
val count = commandTemplateViewModel.importFromClipboard()
|
||||||
|
runOnUiThread{
|
||||||
|
Toast.makeText(this@CommandTemplatesActivity, "$count items imported!", Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +84,7 @@ class CommandTemplatesActivity : AppCompatActivity(), TemplatesAdapter.OnItemCli
|
||||||
private fun initChips() {
|
private fun initChips() {
|
||||||
val new = findViewById<Chip>(R.id.newTemplate)
|
val new = findViewById<Chip>(R.id.newTemplate)
|
||||||
new.setOnClickListener {
|
new.setOnClickListener {
|
||||||
uiUtil.showCreationSheet(this@CommandTemplatesActivity, this, commandTemplateViewModel) {}
|
uiUtil.showCommandTemplateCreationOrUpdatingSheet(null,this@CommandTemplatesActivity, this, commandTemplateViewModel) {}
|
||||||
}
|
}
|
||||||
val shortcuts = findViewById<Chip>(R.id.shortcuts)
|
val shortcuts = findViewById<Chip>(R.id.shortcuts)
|
||||||
shortcuts.setOnClickListener {
|
shortcuts.setOnClickListener {
|
||||||
|
|
@ -92,10 +97,21 @@ class CommandTemplatesActivity : AppCompatActivity(), TemplatesAdapter.OnItemCli
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClick(commandTemplate: CommandTemplate) {
|
override fun onItemClick(commandTemplate: CommandTemplate) {
|
||||||
TODO("Not yet implemented")
|
uiUtil.showCommandTemplateCreationOrUpdatingSheet(commandTemplate,this@CommandTemplatesActivity, this, commandTemplateViewModel) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSelected(commandTemplate: CommandTemplate) {
|
override fun onSelected(commandTemplate: CommandTemplate) {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDelete(commandTemplate: CommandTemplate) {
|
||||||
|
val deleteDialog = MaterialAlertDialogBuilder(this)
|
||||||
|
deleteDialog.setTitle(getString(R.string.you_are_going_to_delete) + " \"" + commandTemplate.title + "\"!")
|
||||||
|
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||||
|
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||||
|
commandTemplateViewModel.delete(commandTemplate)
|
||||||
|
}
|
||||||
|
deleteDialog.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,15 +36,13 @@ class DownloadLogActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
content = findViewById(R.id.content)
|
content = findViewById(R.id.content)
|
||||||
content.movementMethod = ScrollingMovementMethod()
|
|
||||||
contentScrollView = findViewById(R.id.content_scrollview)
|
contentScrollView = findViewById(R.id.content_scrollview)
|
||||||
|
|
||||||
copyLog = findViewById(R.id.copy_log)
|
copyLog = findViewById(R.id.copy_log)
|
||||||
copyLog.setOnClickListener {
|
copyLog.setOnClickListener {
|
||||||
val clipboard: ClipboardManager =
|
val clipboard: ClipboardManager =
|
||||||
getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
val clip: ClipData = ClipData.newPlainText("Download Log", content.text)
|
clipboard.setText(content.text)
|
||||||
clipboard.setPrimaryClip(clip)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val path = intent.getStringExtra("path")
|
val path = intent.getStringExtra("path")
|
||||||
|
|
@ -60,8 +58,10 @@ class DownloadLogActivity : AppCompatActivity() {
|
||||||
observer = object : FileObserver(file.absolutePath, MODIFY) {
|
observer = object : FileObserver(file.absolutePath, MODIFY) {
|
||||||
override fun onEvent(event: Int, p: String?) {
|
override fun onEvent(event: Int, p: String?) {
|
||||||
runOnUiThread{
|
runOnUiThread{
|
||||||
content.text = File(path).readText()
|
val newText = File(path).readText()
|
||||||
|
content.text = newText
|
||||||
content.scrollTo(0, content.height)
|
content.scrollTo(0, content.height)
|
||||||
|
contentScrollView.fullScroll(View.FOCUS_DOWN)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,8 @@ class DownloadLogActivity : AppCompatActivity() {
|
||||||
observer = object : FileObserver(file, MODIFY) {
|
observer = object : FileObserver(file, MODIFY) {
|
||||||
override fun onEvent(event: Int, p: String?) {
|
override fun onEvent(event: Int, p: String?) {
|
||||||
runOnUiThread{
|
runOnUiThread{
|
||||||
content.text = File(path).readText()
|
val newText = File(path).readText()
|
||||||
|
content.text = newText
|
||||||
content.scrollTo(0, content.height)
|
content.scrollTo(0, content.height)
|
||||||
contentScrollView.fullScroll(View.FOCUS_DOWN)
|
contentScrollView.fullScroll(View.FOCUS_DOWN)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.deniscerri.ytdlnis.ui.more.downloadLogs
|
package com.deniscerri.ytdlnis.ui.more.downloadLogs
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.*
|
import android.os.*
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
|
@ -13,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
import com.deniscerri.ytdlnis.adapter.DownloadLogsAdapter
|
import com.deniscerri.ytdlnis.adapter.DownloadLogsAdapter
|
||||||
import com.google.android.material.appbar.MaterialToolbar
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -22,6 +24,7 @@ class DownloadLogListActivity : AppCompatActivity(), DownloadLogsAdapter.OnItemC
|
||||||
private lateinit var noResults: RelativeLayout
|
private lateinit var noResults: RelativeLayout
|
||||||
private lateinit var fileList: MutableList<File>
|
private lateinit var fileList: MutableList<File>
|
||||||
private lateinit var topAppBar: MaterialToolbar
|
private lateinit var topAppBar: MaterialToolbar
|
||||||
|
private lateinit var logFolder : File
|
||||||
var context: Context? = null
|
var context: Context? = null
|
||||||
|
|
||||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
|
@ -43,7 +46,7 @@ class DownloadLogListActivity : AppCompatActivity(), DownloadLogsAdapter.OnItemC
|
||||||
noResults = findViewById(R.id.no_results)
|
noResults = findViewById(R.id.no_results)
|
||||||
noResults.visibility = View.GONE
|
noResults.visibility = View.GONE
|
||||||
|
|
||||||
val logFolder = File(filesDir.absolutePath + "/logs")
|
logFolder = File(filesDir.absolutePath + "/logs")
|
||||||
updateList(logFolder)
|
updateList(logFolder)
|
||||||
|
|
||||||
if(Build.VERSION.SDK_INT < 29){
|
if(Build.VERSION.SDK_INT < 29){
|
||||||
|
|
@ -73,9 +76,18 @@ class DownloadLogListActivity : AppCompatActivity(), DownloadLogsAdapter.OnItemC
|
||||||
val itemId = m.itemId
|
val itemId = m.itemId
|
||||||
if (itemId == R.id.remove_logs) {
|
if (itemId == R.id.remove_logs) {
|
||||||
try{
|
try{
|
||||||
logFolder.listFiles()!!.forEach {
|
val deleteDialog = MaterialAlertDialogBuilder(this)
|
||||||
it.delete()
|
deleteDialog.setTitle(getString(R.string.confirm_delete_history))
|
||||||
|
deleteDialog.setMessage(getString(R.string.confirm_delete_logs_desc))
|
||||||
|
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||||
|
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||||
|
logFolder.listFiles()!!.forEach {
|
||||||
|
it.delete()
|
||||||
|
}.run {
|
||||||
|
updateList(logFolder)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
deleteDialog.show()
|
||||||
}catch (e: Exception){
|
}catch (e: Exception){
|
||||||
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
|
@ -113,6 +125,14 @@ class DownloadLogListActivity : AppCompatActivity(), DownloadLogsAdapter.OnItemC
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDeleteClick(file: File) {
|
override fun onDeleteClick(file: File) {
|
||||||
file.delete()
|
val deleteDialog = MaterialAlertDialogBuilder(this)
|
||||||
|
deleteDialog.setTitle(getString(R.string.you_are_going_to_delete) + " \"" + file.name + "\"!")
|
||||||
|
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||||
|
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||||
|
file.delete().run {
|
||||||
|
updateList(logFolder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deleteDialog.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -23,6 +23,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
private var videoPath: Preference? = null
|
private var videoPath: Preference? = null
|
||||||
private var commandPath: Preference? = null
|
private var commandPath: Preference? = null
|
||||||
private var incognito: SwitchPreferenceCompat? = null
|
private var incognito: SwitchPreferenceCompat? = null
|
||||||
|
private var preferredDownloadType : ListPreference? = null
|
||||||
private var downloadCard: SwitchPreferenceCompat? = null
|
private var downloadCard: SwitchPreferenceCompat? = null
|
||||||
private var apiKey: EditTextPreference? = null
|
private var apiKey: EditTextPreference? = null
|
||||||
private var concurrentFragments: SeekBarPreference? = null
|
private var concurrentFragments: SeekBarPreference? = null
|
||||||
|
|
@ -64,6 +65,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
videoPath = findPreference("video_path")
|
videoPath = findPreference("video_path")
|
||||||
commandPath = findPreference("command_path")
|
commandPath = findPreference("command_path")
|
||||||
incognito = findPreference("incognito")
|
incognito = findPreference("incognito")
|
||||||
|
preferredDownloadType = findPreference("preferred_download_type")
|
||||||
downloadCard = findPreference("download_card")
|
downloadCard = findPreference("download_card")
|
||||||
apiKey = findPreference("api_key")
|
apiKey = findPreference("api_key")
|
||||||
concurrentFragments = findPreference("concurrent_fragments")
|
concurrentFragments = findPreference("concurrent_fragments")
|
||||||
|
|
@ -111,6 +113,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
editor.putString("command_path", getString(R.string.command_path))
|
editor.putString("command_path", getString(R.string.command_path))
|
||||||
}
|
}
|
||||||
editor.putBoolean("incognito", incognito!!.isChecked)
|
editor.putBoolean("incognito", incognito!!.isChecked)
|
||||||
|
editor.putString("preferred_download_type", preferredDownloadType!!.value)
|
||||||
editor.putBoolean("download_card", downloadCard!!.isChecked)
|
editor.putBoolean("download_card", downloadCard!!.isChecked)
|
||||||
editor.putString("api_key", apiKey!!.text)
|
editor.putString("api_key", apiKey!!.text)
|
||||||
editor.putInt("concurrent_fragments", concurrentFragments!!.value)
|
editor.putInt("concurrent_fragments", concurrentFragments!!.value)
|
||||||
|
|
@ -186,6 +189,13 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
editor.apply()
|
editor.apply()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
preferredDownloadType!!.onPreferenceChangeListener =
|
||||||
|
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
|
||||||
|
editor.putString("preferred_download_type", newValue.toString())
|
||||||
|
editor.apply()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
downloadCard!!.onPreferenceChangeListener =
|
downloadCard!!.onPreferenceChangeListener =
|
||||||
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
|
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
|
||||||
val enable = newValue as Boolean
|
val enable = newValue as Boolean
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
|
|
@ -18,7 +17,6 @@ import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.ContextCompat.getSystemService
|
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
|
|
@ -55,7 +53,7 @@ class UiUtil(private val fileUtil: FileUtil) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showCreationSheet(context: Activity, lifeCycle: LifecycleOwner, commandTemplateViewModel: CommandTemplateViewModel, newTemplate: (newTemplate: CommandTemplate) -> Unit){
|
fun showCommandTemplateCreationOrUpdatingSheet(item: CommandTemplate?, context: Activity, lifeCycle: LifecycleOwner, commandTemplateViewModel: CommandTemplateViewModel, newTemplate: (newTemplate: CommandTemplate) -> Unit){
|
||||||
val bottomSheet = BottomSheetDialog(context)
|
val bottomSheet = BottomSheetDialog(context)
|
||||||
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||||
bottomSheet.setContentView(R.layout.create_command_template)
|
bottomSheet.setContentView(R.layout.create_command_template)
|
||||||
|
|
@ -66,7 +64,15 @@ class UiUtil(private val fileUtil: FileUtil) {
|
||||||
val shortcutsChipGroup : ChipGroup = bottomSheet.findViewById(R.id.shortcutsChipGroup)!!
|
val shortcutsChipGroup : ChipGroup = bottomSheet.findViewById(R.id.shortcutsChipGroup)!!
|
||||||
val editShortcuts : Button = bottomSheet.findViewById(R.id.edit_shortcuts)!!
|
val editShortcuts : Button = bottomSheet.findViewById(R.id.edit_shortcuts)!!
|
||||||
|
|
||||||
ok.isEnabled = false
|
if (item != null){
|
||||||
|
title.editText!!.setText(item.title)
|
||||||
|
content.editText!!.setText(item.content)
|
||||||
|
bottomSheet.findViewById<TextView>(R.id.bottom_sheet_subtitle)!!.text = content.resources.getString(R.string.update_template)
|
||||||
|
ok.text = content.resources.getString(R.string.update)
|
||||||
|
ok.isEnabled = true
|
||||||
|
}else{
|
||||||
|
ok.isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
title.editText!!.addTextChangedListener(object : TextWatcher {
|
title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||||
|
|
@ -91,6 +97,10 @@ class UiUtil(private val fileUtil: FileUtil) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (content.editText!!.text.isEmpty()){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
content.setEndIconOnClickListener {
|
content.setEndIconOnClickListener {
|
||||||
if(content.editText!!.text.isEmpty()){
|
if(content.editText!!.text.isEmpty()){
|
||||||
val clipboard: ClipboardManager =
|
val clipboard: ClipboardManager =
|
||||||
|
|
@ -118,9 +128,16 @@ class UiUtil(private val fileUtil: FileUtil) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ok.setOnClickListener {
|
ok.setOnClickListener {
|
||||||
val t = CommandTemplate(0, title.editText!!.text.toString(), content.editText!!.text.toString())
|
if (item == null){
|
||||||
commandTemplateViewModel.insert(t)
|
val t = CommandTemplate(0, title.editText!!.text.toString(), content.editText!!.text.toString())
|
||||||
newTemplate(t)
|
commandTemplateViewModel.insert(t)
|
||||||
|
newTemplate(t)
|
||||||
|
}else{
|
||||||
|
item.title = title.editText!!.text.toString()
|
||||||
|
item.content = content.editText!!.text.toString()
|
||||||
|
commandTemplateViewModel.update(item)
|
||||||
|
newTemplate(item)
|
||||||
|
}
|
||||||
bottomSheet.cancel()
|
bottomSheet.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<vector android:height="24dp"
|
<vector android:height="24dp"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="?android:textColorPrimary" android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19L3,19L3,5h18v14zM8,15c0,-1.66 1.34,-3 3,-3 0.35,0 0.69,0.07 1,0.18L12,6h5v2h-3v7.03c-0.02,1.64 -1.35,2.97 -3,2.97 -1.66,0 -3,-1.34 -3,-3z"/>
|
<path android:fillColor="?attr/colorAccent" android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19L3,19L3,5h18v14zM8,15c0,-1.66 1.34,-3 3,-3 0.35,0 0.69,0.07 1,0.18L12,6h5v2h-3v7.03c-0.02,1.64 -1.35,2.97 -3,2.97 -1.66,0 -3,-1.34 -3,-3z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
||||||
|
|
@ -23,27 +23,34 @@
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<ScrollView
|
<LinearLayout
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
android:id="@+id/content_scrollview"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:clipToPadding="false"
|
android:descendantFocusability="blocksDescendants"
|
||||||
android:fillViewport="true"
|
android:orientation="vertical">
|
||||||
android:paddingBottom="150dp"
|
|
||||||
>
|
|
||||||
|
|
||||||
<TextView
|
<ScrollView
|
||||||
android:id="@+id/content"
|
android:id="@+id/content_scrollview"
|
||||||
android:padding="10dp"
|
android:layout_width="match_parent"
|
||||||
android:scrollHorizontally="true"
|
android:layout_height="match_parent"
|
||||||
android:fontFamily="monospace"
|
android:clipToPadding="false"
|
||||||
android:textSize="15sp"
|
android:paddingBottom="150dp"
|
||||||
android:layout_width="wrap_content"
|
>
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
</ScrollView>
|
<TextView
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:gravity="bottom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:textIsSelectable="true"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
android:id="@+id/copy_log"
|
android:id="@+id/copy_log"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:padding="15dp">
|
android:padding="15dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:autoLink="all"
|
android:autoLink="all"
|
||||||
android:text="@string/ok"
|
android:text="@string/create"
|
||||||
app:icon="@drawable/ic_check"
|
app:icon="@drawable/ic_check"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
|
android:clickable="true"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
|
|
@ -17,7 +19,8 @@
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/delete"
|
app:layout_constraintEnd_toStartOf="@+id/delete"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:focusable="true" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/delete"
|
android:id="@+id/delete"
|
||||||
|
|
|
||||||
|
|
@ -75,4 +75,17 @@
|
||||||
<item>tr</item>
|
<item>tr</item>
|
||||||
<item>vi</item>
|
<item>vi</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
|
||||||
|
<string-array name="download_types">
|
||||||
|
<item>@string/audio</item>
|
||||||
|
<item>@string/video</item>
|
||||||
|
<item>@string/command</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="download_types_values">
|
||||||
|
<item>audio</item>
|
||||||
|
<item>video</item>
|
||||||
|
<item>command</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -197,4 +197,10 @@
|
||||||
<string name="create_shortcut">Create Shortcut</string>
|
<string name="create_shortcut">Create Shortcut</string>
|
||||||
<string name="error_restarting_download">Error trying to restart the download</string>
|
<string name="error_restarting_download">Error trying to restart the download</string>
|
||||||
<string name="delete_temp_file_too">Delete temporary files from the device</string>
|
<string name="delete_temp_file_too">Delete temporary files from the device</string>
|
||||||
|
<string name="update_template">Update Template</string>
|
||||||
|
<string name="create">Create</string>
|
||||||
|
<string name="update">Update</string>
|
||||||
|
<string name="preferred_download_type">Preferred Download Type</string>
|
||||||
|
<string name="preferred_download_type_summary">Default tab the download card will open to</string>
|
||||||
|
<string name="confirm_delete_logs_desc">Delete the entire log list, permanently.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -45,6 +45,16 @@
|
||||||
app:summary="@string/download_card_summary"
|
app:summary="@string/download_card_summary"
|
||||||
app:title="@string/show_download_card" />
|
app:title="@string/show_download_card" />
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:dependency="download_card"
|
||||||
|
android:defaultValue="video"
|
||||||
|
android:entries="@array/download_types"
|
||||||
|
android:entryValues="@array/download_types_values"
|
||||||
|
android:icon="@drawable/ic_download_type"
|
||||||
|
app:key="preferred_download_type"
|
||||||
|
app:summary="@string/preferred_download_type_summary"
|
||||||
|
app:title="@string/preferred_download_type" />
|
||||||
|
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:icon="@drawable/ic_key"
|
android:icon="@drawable/ic_key"
|
||||||
app:key="api_key"
|
app:key="api_key"
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ plugins {
|
||||||
id 'com.android.application' version '7.4.1' apply false
|
id 'com.android.application' version '7.4.1' apply false
|
||||||
id 'com.android.library' version '7.4.1' apply false
|
id 'com.android.library' version '7.4.1' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.7.21' apply false
|
id 'org.jetbrains.kotlin.android' version '1.7.21' apply false
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization" version "1.7.21" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue