added stuff
added file picker for the sheet cancel title and author name sync between types sheet showing when there is one result trending not refreshing every time app shows
This commit is contained in:
parent
7f813ebd96
commit
92d6b2f197
27 changed files with 420 additions and 510 deletions
|
|
@ -167,7 +167,7 @@
|
|||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ dependencies {
|
|||
implementation 'androidx.navigation:navigation-fragment:2.5.3'
|
||||
implementation 'androidx.navigation:navigation-ui:2.5.3'
|
||||
implementation 'androidx.core:core-ktx:1.9.0'
|
||||
implementation 'androidx.core:core-ktx:+'
|
||||
testImplementation "junit:junit:$junitVer"
|
||||
androidTestImplementation "androidx.test.ext:junit:$androidJunitVer"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVer"
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "94d37ae85390ef5198651df2480a02bf",
|
||||
"identityHash": "2c0fdec170ca54d97ef928dfe28a6992",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "results",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL)",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `creationTime` INTEGER NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
|
|
@ -55,6 +55,12 @@
|
|||
"columnName": "playlistTitle",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "creationTime",
|
||||
"columnName": "creationTime",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
|
|
@ -386,7 +392,7 @@
|
|||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '94d37ae85390ef5198651df2480a02bf')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2c0fdec170ca54d97ef928dfe28a6992')"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,6 @@ abstract class DBManager : RoomDatabase(){
|
|||
DBManager::class.java,
|
||||
"YTDLnisDatabase"
|
||||
)
|
||||
.allowMainThreadQueries()
|
||||
.build()
|
||||
instance = dbInstance
|
||||
dbInstance
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ interface DownloadDao {
|
|||
fun getDownloadByWorkId(workID: Int) : DownloadItem
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE id=:id LIMIT 1")
|
||||
fun getDownloadById(id: Int) : DownloadItem
|
||||
fun getDownloadById(id: Long) : DownloadItem
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(item: DownloadItem) : Long
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ data class DownloadItem(
|
|||
var formatDesc: String,
|
||||
@ColumnInfo(defaultValue = "0")
|
||||
val removeAudio: Boolean,
|
||||
val downloadPath: String,
|
||||
var downloadPath: String,
|
||||
val website: String,
|
||||
val downloadSize: String,
|
||||
val playlistTitle: String,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.deniscerri.ytdlnis.database.models
|
|||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import java.util.*
|
||||
|
||||
@Entity(tableName = "results")
|
||||
data class ResultItem(
|
||||
|
|
@ -13,5 +14,6 @@ data class ResultItem(
|
|||
val duration: String,
|
||||
val thumb: String,
|
||||
val website: String,
|
||||
var playlistTitle: String
|
||||
var playlistTitle: String,
|
||||
var creationTime: Long = System.currentTimeMillis() / 1000,
|
||||
)
|
||||
|
|
@ -38,8 +38,8 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
|||
update(item);
|
||||
}
|
||||
|
||||
fun getLatest() : DownloadItem {
|
||||
return downloadDao.getLatest()
|
||||
fun getItemByID(id: Long) : DownloadItem {
|
||||
return downloadDao.getDownloadById(id)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
repository.update(item);
|
||||
}
|
||||
|
||||
fun getLatest() : DownloadItem {
|
||||
return repository.getLatest()
|
||||
fun getItemByID(id: Long) : DownloadItem {
|
||||
return repository.getItemByID(id)
|
||||
}
|
||||
}
|
||||
|
|
@ -34,15 +34,12 @@ class HistoryViewModel(application: Application) : AndroidViewModel(application)
|
|||
filter(queryFilter.value!!, formatFilter.value!!, websiteFilter.value!!, sortType.value!!)
|
||||
})
|
||||
_items.addSource(formatFilter, Observer {
|
||||
Log.e("aa", "audio");
|
||||
filter(queryFilter.value!!, formatFilter.value!!, websiteFilter.value!!, sortType.value!!)
|
||||
})
|
||||
_items.addSource(sortType, Observer {
|
||||
Log.e("aa", "asssssssssssss");
|
||||
filter(queryFilter.value!!, formatFilter.value!!, websiteFilter.value!!, sortType.value!!)
|
||||
})
|
||||
_items.addSource(websiteFilter, Observer {
|
||||
Log.e("Aa", "website")
|
||||
filter(queryFilter.value!!, formatFilter.value!!, websiteFilter.value!!, sortType.value!!)
|
||||
})
|
||||
_items.addSource(queryFilter, Observer {
|
||||
|
|
@ -56,7 +53,6 @@ class HistoryViewModel(application: Application) : AndroidViewModel(application)
|
|||
}
|
||||
|
||||
fun setSorting(sort: HistorySort){
|
||||
Log.e("aa", "asssssssssssss");
|
||||
sortType.value = sort
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +65,6 @@ class HistoryViewModel(application: Application) : AndroidViewModel(application)
|
|||
}
|
||||
|
||||
fun setFormatFilter(filter: String){
|
||||
Log.e("aa", "audio");
|
||||
formatFilter.value = filter
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,12 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
|||
fun checkTrending() = viewModelScope.launch(Dispatchers.IO){
|
||||
try {
|
||||
val item = repository.getFirstResult()
|
||||
if (item.playlistTitle == "ytdlnis-TRENDING") getTrending()
|
||||
if (
|
||||
item.playlistTitle == getApplication<App>().getString(R.string.trendingPlaylist)
|
||||
&& item.creationTime < (System.currentTimeMillis() / 1000) - 86400
|
||||
){
|
||||
getTrending()
|
||||
}
|
||||
}catch (e : Exception){
|
||||
getTrending()
|
||||
}
|
||||
|
|
@ -58,7 +63,6 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
|||
} else if (inputQuery!!.contains("http")) {
|
||||
type = "Default"
|
||||
}
|
||||
Log.e(tag, "$inputQuery $type")
|
||||
try {
|
||||
when (type) {
|
||||
"Search" -> {
|
||||
|
|
@ -102,12 +106,7 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
|||
|
||||
when(type){
|
||||
"audio" -> {
|
||||
list = list.filter { it.format_note.contains("audio", ignoreCase = true) }
|
||||
if (list.isEmpty()) {
|
||||
audioFormats.forEach { formats.add(Format(0, item.id, it, "", 0, it, "")) }
|
||||
return formats
|
||||
}
|
||||
return list
|
||||
return list.filter { it.format_note.contains("audio", ignoreCase = true) }
|
||||
}
|
||||
"video" -> {
|
||||
list = list.filter { !it.format_note.contains("audio", ignoreCase = true) }
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import com.deniscerri.ytdlnis.util.InfoUtil
|
|||
import com.facebook.shimmer.ShimmerFrameLayout
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
|
|
@ -86,6 +87,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
private var selectedObjects: ArrayList<ResultItem>? = null
|
||||
private var deleteFab: ExtendedFloatingActionButton? = null
|
||||
private var fileUtil: FileUtil? = null
|
||||
private var firstBoot = true
|
||||
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
|
||||
|
|
@ -144,10 +146,15 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
homeAdapter!!.submitList(it)
|
||||
resultsList = it
|
||||
if(it.size > 1){
|
||||
if (it[0].playlistTitle.isNotEmpty() || it[0].playlistTitle != getString(R.string.trendingPlaylist)){
|
||||
if (it[0].playlistTitle.isNotEmpty() && it[0].playlistTitle != getString(R.string.trendingPlaylist)){
|
||||
downloadAllFabCoordinator!!.visibility = VISIBLE
|
||||
}else{
|
||||
downloadAllFabCoordinator!!.visibility = GONE
|
||||
}
|
||||
}else if(it.size == 1 && !firstBoot && parentFragmentManager.findFragmentByTag("bottomSheet") == null){
|
||||
showSingleDownloadSheet(it[0], "audio")
|
||||
}
|
||||
firstBoot = false
|
||||
}
|
||||
|
||||
resultViewModel.loadingItems.observe(viewLifecycleOwner){
|
||||
|
|
@ -349,9 +356,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
// selectedObjects!!.clear()
|
||||
// selectedObjects!!.add(item!!)
|
||||
//showConfigureSingleDownloadCard(createDownloadItem(item!!, type), item)
|
||||
createDownloadItem(item!!, type){
|
||||
showSingleDownloadSheet(it)
|
||||
}
|
||||
showSingleDownloadSheet(item!!, type)
|
||||
} else {
|
||||
// downloadQueue!!.add(vid)
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
|
|
@ -362,12 +367,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
}
|
||||
}
|
||||
|
||||
private fun showSingleDownloadSheet(item : DownloadItem){
|
||||
val bottomSheet = DownloadBottomSheetDialog(item)
|
||||
bottomSheet.show(parentFragmentManager, null)
|
||||
}
|
||||
|
||||
private fun createDownloadItem(item: ResultItem, type: String, itemCreated: (DownloadItem) -> Unit) : DownloadItem {
|
||||
private fun showSingleDownloadSheet(resultItem : ResultItem, type: String){
|
||||
val sharedPreferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
|
|
@ -376,22 +376,22 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
|
||||
|
||||
val downloadItem = DownloadItem(0,
|
||||
item.url,
|
||||
item.title,
|
||||
item.author,
|
||||
item.thumb,
|
||||
item.duration,
|
||||
resultItem.url,
|
||||
resultItem.title,
|
||||
resultItem.author,
|
||||
resultItem.thumb,
|
||||
resultItem.duration,
|
||||
type,
|
||||
"", "", 0, "", false,
|
||||
"", item.website, "", item.playlistTitle, embedSubs, addChapters, saveThumb, "",
|
||||
"", resultItem.website, "", resultItem.playlistTitle, embedSubs, addChapters, saveThumb, "",
|
||||
"", DownloadRepository.status.Processing.toString(), 0
|
||||
)
|
||||
|
||||
downloadViewModel.insertDownload(downloadItem).observe(viewLifecycleOwner) {
|
||||
downloadItem.id = it
|
||||
itemCreated(downloadItem)
|
||||
val bottomSheet = DownloadBottomSheetDialog(downloadItem)
|
||||
bottomSheet.show(parentFragmentManager, "bottomSheet")
|
||||
}
|
||||
return downloadItem
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadcard
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
|
@ -8,33 +9,56 @@ import android.util.Log
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.Toast
|
||||
import android.widget.*
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
import com.deniscerri.ytdlnis.ui.HomeFragment
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class DownloadAudioFragment(item: DownloadItem) : Fragment() {
|
||||
class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment() {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
private var mainActivity: MainActivity? = null
|
||||
private lateinit var resultViewModel : ResultViewModel
|
||||
private lateinit var downloadViewModel : DownloadViewModel
|
||||
private lateinit var fileUtil : FileUtil
|
||||
private val downloadItem = item
|
||||
|
||||
private lateinit var title : TextInputLayout
|
||||
private lateinit var author : TextInputLayout
|
||||
private lateinit var saveDir : TextInputLayout
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
lifecycleScope.launch{
|
||||
val item = withContext(Dispatchers.IO){
|
||||
downloadViewModel.getItemByID(downloadItem.id)
|
||||
}
|
||||
if (::title.isInitialized){
|
||||
title.editText!!.setText(item.title)
|
||||
downloadItem.title = item.title
|
||||
}
|
||||
if(::author.isInitialized){
|
||||
author.editText!!.setText(item.author)
|
||||
downloadItem.author = item.author
|
||||
}
|
||||
}
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
|
@ -46,109 +70,176 @@ class DownloadAudioFragment(item: DownloadItem) : Fragment() {
|
|||
activity = getActivity()
|
||||
mainActivity = activity as MainActivity?
|
||||
resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java]
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
fileUtil = FileUtil()
|
||||
return fragmentView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val resultItem = resultViewModel.getItemByURL(downloadItem.url)
|
||||
val type = downloadItem.type
|
||||
lifecycleScope.launch {
|
||||
val resultItem = withContext(Dispatchers.IO){
|
||||
resultViewModel.getItemByURL(downloadItem.url)
|
||||
}
|
||||
val type = downloadItem.type
|
||||
|
||||
val sharedPreferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
val sharedPreferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
|
||||
try {
|
||||
val title = view.findViewById<TextInputLayout>(R.id.title_textinput)
|
||||
title!!.editText!!.setText(downloadItem.title)
|
||||
title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.title = p0.toString()
|
||||
resultItem.title = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
}
|
||||
})
|
||||
try {
|
||||
title = view.findViewById(R.id.title_textinput)
|
||||
title.editText!!.setText(downloadItem.title)
|
||||
title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.title = p0.toString()
|
||||
resultItem.title = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
})
|
||||
|
||||
val author = view.findViewById<TextInputLayout>(R.id.author_textinput)
|
||||
author!!.editText!!.setText(downloadItem.author)
|
||||
author.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.author = p0.toString()
|
||||
resultItem.author = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
}
|
||||
})
|
||||
|
||||
val saveDir = view.findViewById<TextInputLayout>(R.id.outputPath)
|
||||
saveDir!!.editText!!.setText(
|
||||
sharedPreferences.getString(
|
||||
author = view.findViewById(R.id.author_textinput)
|
||||
author.editText!!.setText(downloadItem.author)
|
||||
author.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.author = p0.toString()
|
||||
resultItem.author = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
})
|
||||
saveDir = view.findViewById(R.id.outputPath)
|
||||
val downloadPath = sharedPreferences.getString(
|
||||
"music_path",
|
||||
getString(R.string.music_path)
|
||||
)
|
||||
)
|
||||
saveDir.editText!!.isFocusable = false;
|
||||
saveDir.editText!!.isClickable = true;
|
||||
saveDir.editText!!.setOnClickListener {
|
||||
Toast.makeText(context, "TEST", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
val formats = resultViewModel.getFormats(resultItem, type)
|
||||
|
||||
val formatTitles = formats.map {
|
||||
if (it.format_note.contains("AUDIO_QUALITY_"))
|
||||
it.format_note.replace("AUDIO_QUALITY_", "") +
|
||||
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
else it.format_note +
|
||||
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
}
|
||||
|
||||
val format = view.findViewById<TextInputLayout>(R.id.format)
|
||||
val autoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.format_textview)
|
||||
autoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
formatTitles
|
||||
downloadItem.downloadPath = downloadPath!!
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
saveDir.editText!!.setText(
|
||||
fileUtil.formatPath(downloadPath)
|
||||
)
|
||||
)
|
||||
if (formatTitles.isNotEmpty()){
|
||||
autoCompleteTextView!!.setText(formatTitles[formats.lastIndex], false)
|
||||
}
|
||||
(format!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.formatDesc = formats[index].format_note
|
||||
downloadItem.audioFormatId = formats[index].format_id
|
||||
saveDir.editText!!.isFocusable = false;
|
||||
saveDir.editText!!.isClickable = true;
|
||||
saveDir.editText!!.setOnClickListener {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
|
||||
audioPathResultLauncher.launch(intent)
|
||||
}
|
||||
|
||||
val containers = requireContext().resources.getStringArray(R.array.audio_containers)
|
||||
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
|
||||
val containerAutoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
|
||||
val formats = withContext(Dispatchers.IO){
|
||||
resultViewModel.getFormats(resultItem, type)
|
||||
}
|
||||
val format = view.findViewById<TextInputLayout>(R.id.format)
|
||||
if (formats.isEmpty()) {
|
||||
format.visibility = View.GONE
|
||||
} else {
|
||||
val formatTitles = formats.map {
|
||||
if (it.format_note.contains("AUDIO_QUALITY_")) {
|
||||
it.format_note.replace(
|
||||
"AUDIO_QUALITY_",
|
||||
""
|
||||
) + if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
} else {
|
||||
it.format_note + if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(
|
||||
it.filesize
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
container?.isEnabled = true
|
||||
containerAutoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
containers
|
||||
)
|
||||
)
|
||||
val selectedContainer: String = formats.find { downloadItem.formatDesc == it.format_note }?.container
|
||||
?: sharedPreferences.getString("audio_format", "mp3")!!
|
||||
containerAutoCompleteTextView!!.setText(selectedContainer, false)
|
||||
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.ext = containers[index]
|
||||
val autoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.format_textview)
|
||||
autoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
formatTitles
|
||||
)
|
||||
)
|
||||
if (formatTitles.isNotEmpty()) {
|
||||
autoCompleteTextView!!.setText(formatTitles[formats.lastIndex], false)
|
||||
}
|
||||
(format!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.formatDesc = formats[index].format_note
|
||||
downloadItem.audioFormatId = formats[index].format_id
|
||||
}
|
||||
}
|
||||
|
||||
}catch (e : Exception){
|
||||
e.printStackTrace()
|
||||
val containers = requireContext().resources.getStringArray(R.array.audio_containers)
|
||||
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
|
||||
val containerAutoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
|
||||
|
||||
container?.isEnabled = true
|
||||
containerAutoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
containers
|
||||
)
|
||||
)
|
||||
val selectedContainer: String = formats.find { downloadItem.formatDesc == it.format_note }?.container
|
||||
?: sharedPreferences.getString("audio_format", "mp3")!!
|
||||
containerAutoCompleteTextView!!.setText(selectedContainer, false)
|
||||
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.ext = containers[index]
|
||||
}
|
||||
|
||||
|
||||
val cancelBtn = view.findViewById<MaterialButton>(R.id.bottomsheet_cancel_button)
|
||||
cancelBtn.setOnClickListener{
|
||||
(parentFragmentManager.findFragmentByTag("bottomSheet") as DownloadBottomSheetDialog).dismissSelf()
|
||||
}
|
||||
|
||||
val download = view.findViewById<Button>(R.id.bottomsheet_download_button)
|
||||
download!!.setOnClickListener {
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.downloadedType = type
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
// homeAdapter!!.notifyItemChanged(resultsList!!.indexOf(vid))
|
||||
// downloadQueue!!.add(vid)
|
||||
// }
|
||||
// selectedObjects = ArrayList()
|
||||
// homeAdapter!!.clearCheckedVideos()
|
||||
// downloadFabs!!.visibility = View.GONE
|
||||
// if (isStoragePermissionGranted) {
|
||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
(parentFragmentManager.findFragmentByTag("bottomSheet") as DownloadBottomSheetDialog).dismissSelf()
|
||||
}
|
||||
|
||||
}catch (e : Exception){
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var audioPathResultLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
result.data?.data?.let {
|
||||
activity?.contentResolver?.takePersistableUriPermission(
|
||||
it,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
)
|
||||
}
|
||||
downloadItem.downloadPath = result.data?.data.toString()
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
saveDir.editText?.setText(fileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,17 +4,15 @@ import android.annotation.SuppressLint
|
|||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.get
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import androidx.fragment.app.findFragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
|
||||
|
|
@ -42,6 +40,7 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
|
|||
val fragmentManager = parentFragmentManager
|
||||
fragmentAdapter = DownloadFragmentAdapter(downloadItem, fragmentManager, lifecycle)
|
||||
viewPager2.adapter = fragmentAdapter
|
||||
viewPager2.isSaveFromParentEnabled = false
|
||||
|
||||
when(downloadItem.type) {
|
||||
"audio" -> {
|
||||
|
|
@ -80,6 +79,12 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
|
|||
|
||||
override fun onCancel(dialog: DialogInterface) {
|
||||
super.onCancel(dialog)
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("bottomSheet")!!).commit()
|
||||
for (i in 0 until viewPager2.adapter?.itemCount!!){
|
||||
if (parentFragmentManager.findFragmentByTag("f${i}") != null){
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("f$i")!!).commit()
|
||||
}
|
||||
}
|
||||
downloadViewModel.deleteDownload(downloadItem)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadcard
|
||||
|
||||
import android.util.Log
|
||||
import androidx.annotation.NonNull
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.google.gson.Gson
|
||||
|
||||
class DownloadFragmentAdapter (item : DownloadItem, fragmentManager : FragmentManager, lifecycle : Lifecycle) : FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
private val downloadItem = item
|
||||
|
|
@ -18,14 +20,19 @@ class DownloadFragmentAdapter (item : DownloadItem, fragmentManager : FragmentMa
|
|||
when (position) {
|
||||
0 -> {
|
||||
downloadItem.type = "audio"
|
||||
return DownloadAudioFragment(downloadItem)
|
||||
return DownloadAudioFragment(clone(downloadItem))
|
||||
}
|
||||
1 -> {
|
||||
downloadItem.type = "video"
|
||||
return DownloadVideoFragment(downloadItem)
|
||||
return DownloadVideoFragment(clone(downloadItem))
|
||||
}
|
||||
}
|
||||
downloadItem.type = "command"
|
||||
return DownloadCommandFragment(downloadItem)
|
||||
return DownloadCommandFragment(clone(downloadItem))
|
||||
}
|
||||
|
||||
private fun clone(item: DownloadItem) : DownloadItem {
|
||||
val stringItem = Gson().toJson(item, DownloadItem::class.java)
|
||||
return Gson().fromJson(stringItem, DownloadItem::class.java)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadcard
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
|
@ -8,8 +9,10 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
|
|
@ -17,10 +20,14 @@ import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
|||
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class DownloadVideoFragment(item: DownloadItem) : Fragment() {
|
||||
class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment() {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
|
|
@ -28,8 +35,28 @@ class DownloadVideoFragment(item: DownloadItem) : Fragment() {
|
|||
private lateinit var resultViewModel : ResultViewModel
|
||||
private lateinit var downloadViewModel : DownloadViewModel
|
||||
private lateinit var fileUtil : FileUtil
|
||||
private val downloadItem = item
|
||||
|
||||
private lateinit var title : TextInputLayout
|
||||
private lateinit var author : TextInputLayout
|
||||
private lateinit var saveDir : TextInputLayout
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
lifecycleScope.launch{
|
||||
val item = withContext(Dispatchers.IO){
|
||||
downloadViewModel.getItemByID(downloadItem.id)
|
||||
}
|
||||
if (::title.isInitialized){
|
||||
title.editText!!.setText(item.title)
|
||||
downloadItem.title = item.title
|
||||
}
|
||||
if(::author.isInitialized){
|
||||
author.editText!!.setText(item.author)
|
||||
downloadItem.author = item.author
|
||||
}
|
||||
}
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
|
|
@ -45,122 +72,135 @@ class DownloadVideoFragment(item: DownloadItem) : Fragment() {
|
|||
return fragmentView
|
||||
}
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val resultItem = resultViewModel.getItemByURL(downloadItem.url)
|
||||
val type = downloadItem.type
|
||||
lifecycleScope.launch {
|
||||
val resultItem = withContext(Dispatchers.IO){
|
||||
resultViewModel.getItemByURL(downloadItem.url)
|
||||
}
|
||||
val type = downloadItem.type
|
||||
|
||||
val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
val editor = sharedPreferences.edit()
|
||||
val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
val editor = sharedPreferences.edit()
|
||||
|
||||
try {
|
||||
val title = view.findViewById<TextInputLayout>(R.id.title_textinput)
|
||||
title!!.editText!!.setText(downloadItem.title)
|
||||
title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.title = p0.toString()
|
||||
resultItem.title = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
})
|
||||
try {
|
||||
title = view.findViewById(R.id.title_textinput)
|
||||
title.editText!!.setText(downloadItem.title)
|
||||
title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.title = p0.toString()
|
||||
resultItem.title = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
})
|
||||
|
||||
val author = view.findViewById<TextInputLayout>(R.id.author_textinput)
|
||||
author!!.editText!!.setText(downloadItem.author)
|
||||
author.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.author = p0.toString()
|
||||
resultItem.author = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
})
|
||||
author = view.findViewById(R.id.author_textinput)
|
||||
author.editText!!.setText(downloadItem.author)
|
||||
author.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.author = p0.toString()
|
||||
resultItem.author = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
})
|
||||
|
||||
val saveDir = view.findViewById<TextInputLayout>(R.id.outputPath)
|
||||
saveDir!!.editText!!.setText(
|
||||
sharedPreferences.getString(
|
||||
saveDir = view.findViewById(R.id.outputPath)
|
||||
val downloadPath = sharedPreferences.getString(
|
||||
"video_path",
|
||||
getString(R.string.video_path)
|
||||
)
|
||||
)
|
||||
saveDir.editText!!.isFocusable = false;
|
||||
saveDir.editText!!.isClickable = true;
|
||||
saveDir.editText!!.setOnClickListener {
|
||||
Toast.makeText(context, "TEST", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
downloadItem.downloadPath = downloadPath!!
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
saveDir.editText!!.setText(
|
||||
fileUtil.formatPath(downloadPath)
|
||||
)
|
||||
saveDir.editText!!.isFocusable = false;
|
||||
saveDir.editText!!.isClickable = true;
|
||||
saveDir.editText!!.setOnClickListener {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
|
||||
videoPathResultLauncher.launch(intent)
|
||||
}
|
||||
|
||||
val formats = resultViewModel.getFormats(resultItem, type)
|
||||
val formats = withContext(Dispatchers.IO){
|
||||
resultViewModel.getFormats(resultItem, type)
|
||||
}
|
||||
|
||||
val formatTitles = formats.map {
|
||||
if (it.format_note.contains("AUDIO_QUALITY_"))
|
||||
it.format_note.replace("AUDIO_QUALITY_", "") +
|
||||
val formatTitles = formats.map {
|
||||
if (it.format_note.contains("AUDIO_QUALITY_"))
|
||||
it.format_note.replace("AUDIO_QUALITY_", "") +
|
||||
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
else it.format_note +
|
||||
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
else it.format_note +
|
||||
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
}
|
||||
|
||||
val format = view.findViewById<TextInputLayout>(R.id.format)
|
||||
val autoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.format_textview)
|
||||
autoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
formatTitles
|
||||
)
|
||||
)
|
||||
if (formatTitles.isNotEmpty()) {
|
||||
autoCompleteTextView!!.setText(formatTitles[formats.lastIndex], false)
|
||||
}
|
||||
(format!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.formatDesc = formats[index].format_note
|
||||
downloadItem.videoFormatId = formats[index].format_id
|
||||
}
|
||||
|
||||
val containers = requireContext().resources.getStringArray(R.array.video_containers)
|
||||
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
|
||||
val containerAutoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
|
||||
|
||||
container?.isEnabled = true
|
||||
containerAutoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
containers
|
||||
val format = view.findViewById<TextInputLayout>(R.id.format)
|
||||
val autoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.format_textview)
|
||||
autoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
formatTitles
|
||||
)
|
||||
)
|
||||
)
|
||||
val selectedContainer: String =
|
||||
formats.find { downloadItem.formatDesc == it.format_note }?.container
|
||||
?: sharedPreferences.getString("video_format", "DEFAULT")!!
|
||||
containerAutoCompleteTextView!!.setText(selectedContainer, false)
|
||||
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.ext = containers[index]
|
||||
if (formatTitles.isNotEmpty()) {
|
||||
autoCompleteTextView!!.setText(formatTitles[formats.lastIndex], false)
|
||||
}
|
||||
(format!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.formatDesc = formats[index].format_note
|
||||
downloadItem.videoFormatId = formats[index].format_id
|
||||
}
|
||||
|
||||
val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
|
||||
val containers = requireContext().resources.getStringArray(R.array.video_containers)
|
||||
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
|
||||
val containerAutoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
|
||||
|
||||
container?.isEnabled = true
|
||||
containerAutoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
containers
|
||||
)
|
||||
)
|
||||
val selectedContainer: String =
|
||||
formats.find { downloadItem.formatDesc == it.format_note }?.container
|
||||
?: sharedPreferences.getString("video_format", "DEFAULT")!!
|
||||
containerAutoCompleteTextView!!.setText(selectedContainer, false)
|
||||
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.ext = containers[index]
|
||||
}
|
||||
|
||||
val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
|
||||
embedSubs!!.isChecked = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
|
||||
val addChapters = view.findViewById<Chip>(R.id.add_chapters)
|
||||
addChapters!!.isChecked = sharedPreferences.getBoolean("add_chapters", false)
|
||||
val addChapters = view.findViewById<Chip>(R.id.add_chapters)
|
||||
addChapters!!.isChecked = sharedPreferences.getBoolean("add_chapters", false)
|
||||
|
||||
val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)
|
||||
saveThumbnail!!.isChecked = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)
|
||||
saveThumbnail!!.isChecked = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
|
||||
|
||||
val cancel = view.findViewById<Button>(R.id.bottomsheet_cancel_button)
|
||||
cancel!!.setOnClickListener {
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
val download = view.findViewById<Button>(R.id.bottomsheet_download_button)
|
||||
download!!.setOnClickListener {
|
||||
val cancel = view.findViewById<Button>(R.id.bottomsheet_cancel_button)
|
||||
cancel!!.setOnClickListener {
|
||||
(parentFragmentManager.findFragmentByTag("bottomSheet") as DownloadBottomSheetDialog).dismissSelf()
|
||||
}
|
||||
val download = view.findViewById<Button>(R.id.bottomsheet_download_button)
|
||||
download!!.setOnClickListener {
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
|
|
@ -177,11 +217,29 @@ class DownloadVideoFragment(item: DownloadItem) : Fragment() {
|
|||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
(parentFragmentManager.findFragmentByTag("bottomSheet") as DownloadBottomSheetDialog).dismissSelf()
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var videoPathResultLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
result.data?.data?.let {
|
||||
activity?.contentResolver?.takePersistableUriPermission(
|
||||
it,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
)
|
||||
}
|
||||
downloadItem.downloadPath = result.data?.data.toString()
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
saveDir.editText?.setText(fileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -313,8 +313,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
|
||||
private fun changePath(p: Preference?, data: Intent?, requestCode: Int) {
|
||||
Log.e("TEST", data!!.toUri(0))
|
||||
val path = data.data.toString()
|
||||
val path = data!!.data.toString()
|
||||
p!!.summary = fileUtil?.formatPath(data.data.toString())
|
||||
val sharedPreferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class FileUtil() {
|
|||
|
||||
fun formatPath(path: String) : String {
|
||||
var dataValue = path
|
||||
if (dataValue.startsWith("/storage/")) return dataValue
|
||||
dataValue = dataValue.replace("content://com.android.externalstorage.documents/tree/", "")
|
||||
dataValue = dataValue.replace("%3A".toRegex(), "/")
|
||||
try {
|
||||
|
|
@ -123,7 +124,7 @@ class FileUtil() {
|
|||
}
|
||||
|
||||
fun convertFileSize(s: Long): String{
|
||||
if (s <= 0) return "0"
|
||||
if (s <= 0) return "?"
|
||||
val units = arrayOf("B", "kB", "MB", "GB", "TB")
|
||||
val digitGroups = (log10(s.toDouble()) / log10(1024.0)).toInt()
|
||||
return DecimalFormat("#,##0.#").format(s / 1024.0.pow(digitGroups.toDouble())) + " " + units[digitGroups]
|
||||
|
|
|
|||
|
|
@ -474,11 +474,7 @@ class InfoUtil(context: Context) {
|
|||
} catch (e: Exception) {
|
||||
arrayOf(youtubeDLResponse.out)
|
||||
}
|
||||
var isPlaylist = 0
|
||||
val pl = JSONObject(results[0]!!)
|
||||
if (pl.has("playlist")) {
|
||||
if (pl.getString("playlist") != query) isPlaylist = 1
|
||||
}
|
||||
for (result in results) {
|
||||
val jsonObject = JSONObject(result!!)
|
||||
val title = if (jsonObject.has("title")) {
|
||||
|
|
@ -506,6 +502,7 @@ class InfoUtil(context: Context) {
|
|||
val website = if (jsonObject.has("ie_key")) jsonObject.getString("ie_key") else jsonObject.getString("extractor")
|
||||
var playlistTitle: String? = ""
|
||||
if (jsonObject.has("playlist_title")) playlistTitle = jsonObject.getString("playlist_title")
|
||||
if(playlistTitle.equals(query)) playlistTitle = ""
|
||||
val formatsInJSON = if (jsonObject.has("formats")) jsonObject.getJSONArray("formats") else null
|
||||
val formats : ArrayList<Format> = ArrayList()
|
||||
if (formatsInJSON != null) {
|
||||
|
|
|
|||
|
|
@ -8,17 +8,8 @@
|
|||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="20sp"
|
||||
android:paddingTop="10dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/download" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="15sp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textSize="25sp"
|
||||
android:padding="20dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/configure_download" />
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="10dp"
|
||||
android:hint="@string/format">
|
||||
android:hint="@string/audio_format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/format_textview"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
|
@ -78,7 +77,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="10dp"
|
||||
android:hint="@string/format">
|
||||
android:hint="@string/video_format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/format_textview"
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="10dp"
|
||||
android:hint="@string/format">
|
||||
android:hint="@string/video_format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/format_textview"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/configure_download" />
|
||||
|
||||
<include layout="@layout/home_download_settings_components" />
|
||||
|
||||
<View style="@style/Divider.Horizontal"/>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,153 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/title_textinput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="15dp"
|
||||
app:errorEnabled="true"
|
||||
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>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/author_textinput"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="40"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/author"
|
||||
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/downloadContainer"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="45"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/container">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/container_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/audio_containers"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="20dp"
|
||||
android:hint="@string/format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/format_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/video_formats"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/outputPath"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/save_dir"
|
||||
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.chip.ChipGroup
|
||||
android:id="@+id/downloadChipGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:selectionRequired="true"
|
||||
app:singleLine="true"
|
||||
app:singleSelection="true">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/audioChip"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checkable="true"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
android:text="@string/audio"
|
||||
app:chipIcon="@drawable/ic_music" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/videoChip"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/video"
|
||||
android:checkable="true"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
app:chipIcon="@drawable/ic_video" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/commandChip"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/run_command"
|
||||
android:checkable="true"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
app:chipIcon="@drawable/ic_baseline_keyboard_arrow_right_24" />
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout android:id="@+id/history_element_bottom_sheet"
|
||||
style="@style/Widget.Material3.BottomSheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="25sp"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/download" />
|
||||
|
||||
<include layout="@layout/home_download_settings_components" />
|
||||
|
||||
<View style="@style/Divider.Horizontal"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:paddingTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
|
||||
android:textSize="11sp"
|
||||
android:id="@+id/bottomsheet_schedule_button"
|
||||
android:padding="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_clock"
|
||||
android:text="@string/schedule" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="end"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
||||
android:textSize="11sp"
|
||||
android:padding="10dp"
|
||||
android:id="@+id/bottomsheet_cancel_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
|
||||
android:textSize="11sp"
|
||||
android:padding="10dp"
|
||||
android:id="@+id/bottomsheet_download_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/download"
|
||||
app:icon="@drawable/ic_down"
|
||||
android:autoLink="all"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -65,9 +65,9 @@
|
|||
<string name="choose_range_desc">Pick a range to download from the playlist (to not download everything).</string>
|
||||
<string name="last_cant_be_smaller_than_first">Last index cannot be smaller than the first.</string>
|
||||
<string name="first_cant_be_larger_than_last">First index cannot be larger than the last.</string>
|
||||
<string name="music_path" translatable="false">/storage/emulated/0/Download/YTDLnis/Audio</string>
|
||||
<string name="video_path" translatable="false">/storage/emulated/0/Download/YTDLnis/Video</string>
|
||||
<string name="command_path" translatable="false">/storage/emulated/0/Download/YTDLnis/Command</string>
|
||||
<string name="music_path" translatable="false">content://com.android.externalstorage.documents/tree/primary%3ADownload%2FYTDLnis%2FAudio</string>
|
||||
<string name="video_path" translatable="false">content://com.android.externalstorage.documents/tree/primary%3ADownload%2FYTDLnis%2FVideo</string>
|
||||
<string name="command_path" translatable="false">content://com.android.externalstorage.documents/tree/primary%3ADownload%2FYTDLnis%2FCommand</string>
|
||||
<string name="concurrent_fragments_summary">Number of fragments of a DASH/HLS native video to download concurrently</string>
|
||||
<string name="concurrent_fragments">Concurrent Fragments</string>
|
||||
<string name="downloading">Downloading</string>
|
||||
|
|
@ -163,7 +163,6 @@
|
|||
<string name="best">Best</string>
|
||||
<string name="worst">Worst</string>
|
||||
<string name="defaultValue">Default</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="container">Container</string>
|
||||
<string name="template">Template</string>
|
||||
<string name="history">History</string>
|
||||
|
|
|
|||
Loading…
Reference in a new issue