fixed file scanning and tabs not storing correct types
This commit is contained in:
parent
144e8e9bc5
commit
2b0f1322d3
15 changed files with 185 additions and 206 deletions
|
|
@ -165,7 +165,6 @@ class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activit
|
|||
interface OnItemClickListener {
|
||||
fun onCardClick(itemID: Long, isPresent: Boolean)
|
||||
fun onCardSelect(itemID: Long, isChecked: Boolean)
|
||||
fun onButtonClick(position: Int)
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ data class DownloadItem(
|
|||
val website: String,
|
||||
val downloadSize: String,
|
||||
val playlistTitle: String,
|
||||
val embedSubs: Boolean,
|
||||
val addChapters: Boolean,
|
||||
val SaveThumb: Boolean,
|
||||
var embedSubs: Boolean,
|
||||
var addChapters: Boolean,
|
||||
var SaveThumb: Boolean,
|
||||
@ColumnInfo(defaultValue = "Queued")
|
||||
var status: String
|
||||
)
|
||||
|
|
@ -29,12 +29,8 @@ class HistoryRepository(private val historyDao: HistoryDao) {
|
|||
historyDao.insert(item)
|
||||
}
|
||||
|
||||
suspend fun delete(item: HistoryItem, deleteFile: Boolean){
|
||||
historyDao.delete(item.id!!)
|
||||
if (deleteFile){
|
||||
val fileUtil = FileUtil()
|
||||
fileUtil.deleteFile(item.downloadPath)
|
||||
}
|
||||
suspend fun delete(item: HistoryItem){
|
||||
historyDao.delete(item.id)
|
||||
}
|
||||
|
||||
suspend fun deleteAll(){
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
val processingDownloads : LiveData<List<DownloadItem>>
|
||||
|
||||
private var bestVideoFormat: Format
|
||||
private var bestAudioFormat: Format
|
||||
enum class Type {
|
||||
AUDIO, VIDEO, COMMAND
|
||||
}
|
||||
|
||||
init {
|
||||
val dao = DBManager.getInstance(application).downloadDao
|
||||
|
|
@ -45,30 +49,22 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
activeDownloads = repository.activeDownloads
|
||||
processingDownloads = repository.processingDownloads
|
||||
|
||||
val format = getApplication<App>().resources.getStringArray(R.array.video_formats)
|
||||
val container = sharedPreferences.getString("video_format", "Default")
|
||||
val videoFormat = getApplication<App>().resources.getStringArray(R.array.video_formats)
|
||||
val videoContainer = sharedPreferences.getString("video_format", "Default")
|
||||
bestVideoFormat = Format(
|
||||
format[format.lastIndex],
|
||||
container!!,
|
||||
videoFormat[videoFormat.lastIndex],
|
||||
videoContainer!!,
|
||||
0,
|
||||
format[format.lastIndex]
|
||||
videoFormat[videoFormat.lastIndex]
|
||||
)
|
||||
}
|
||||
|
||||
fun startWork(items: List<DownloadItem>){
|
||||
items.forEach {
|
||||
insertDownload(it)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun insertDownload(item: DownloadItem) : LiveData<Long> {
|
||||
val result = MutableLiveData<Long>()
|
||||
viewModelScope.launch(Dispatchers.IO){
|
||||
val id = repository.insert(item)
|
||||
result.postValue(id)
|
||||
}
|
||||
return result
|
||||
val audioContainer = sharedPreferences.getString("audio_format", "mp3")
|
||||
bestAudioFormat = Format(
|
||||
"",
|
||||
audioContainer!!,
|
||||
0,
|
||||
""
|
||||
)
|
||||
}
|
||||
|
||||
fun deleteDownload(item: DownloadItem) = viewModelScope.launch(Dispatchers.IO) {
|
||||
|
|
@ -107,12 +103,12 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
return try {
|
||||
resultItem.formats.last { it.format_note.contains("audio", ignoreCase = true) }
|
||||
}catch (e: Exception){
|
||||
Format()
|
||||
bestAudioFormat
|
||||
}
|
||||
}
|
||||
"video" -> {
|
||||
return try {
|
||||
resultItem.formats[resultItem.formats.lastIndex]
|
||||
resultItem.formats.last { !it.format_note.contains("audio", ignoreCase = true) }
|
||||
}catch (e: Exception){
|
||||
bestVideoFormat
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.deniscerri.ytdlnis.database.DBManager
|
|||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.repository.HistoryRepository
|
||||
import com.deniscerri.ytdlnis.database.repository.HistoryRepository.HistorySort
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
|
@ -77,7 +78,11 @@ class HistoryViewModel(application: Application) : AndroidViewModel(application)
|
|||
}
|
||||
|
||||
fun delete(item: HistoryItem, deleteFile: Boolean) = viewModelScope.launch(Dispatchers.IO){
|
||||
repository.delete(item, deleteFile)
|
||||
repository.delete(item)
|
||||
if (deleteFile){
|
||||
val fileUtil = FileUtil()
|
||||
fileUtil.deleteFile(item.downloadPath)
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteAll() = viewModelScope.launch(Dispatchers.IO) {
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ import java.io.File
|
|||
/**
|
||||
* A fragment representing a list of Items.
|
||||
*/
|
||||
class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
||||
OnClickListener, OnLongClickListener {
|
||||
class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
||||
private lateinit var historyViewModel : HistoryViewModel
|
||||
|
||||
private var fragmentView: View? = null
|
||||
|
|
@ -90,7 +89,9 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
deleteFab = view.findViewById(R.id.delete_selected_fab)
|
||||
fileUtil = FileUtil()
|
||||
deleteFab?.tag = "deleteSelected"
|
||||
deleteFab?.setOnClickListener(this)
|
||||
deleteFab?.setOnClickListener{
|
||||
removeSelectedItems()
|
||||
}
|
||||
uiHandler = Handler(Looper.getMainLooper())
|
||||
selectedObjects = ArrayList()
|
||||
|
||||
|
|
@ -129,6 +130,7 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
historyViewModel.getFilteredList().observe(viewLifecycleOwner) {
|
||||
historyAdapter!!.submitList(it)
|
||||
historyList = it
|
||||
scrollToTop()
|
||||
}
|
||||
|
||||
initMenu()
|
||||
|
|
@ -301,31 +303,6 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
}
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.bottomsheet_remove_button -> {
|
||||
removeItem(v.tag as Long)
|
||||
}
|
||||
R.id.bottom_sheet_link -> {
|
||||
openLinkIntent(v.tag as Long)
|
||||
}
|
||||
R.id.bottomsheet_open_file_button -> {
|
||||
openFileIntent(v.tag as Long)
|
||||
}
|
||||
R.id.delete_selected_fab -> {
|
||||
removeSelectedItems()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLongClick(v: View): Boolean {
|
||||
val id = v.id
|
||||
if (id == R.id.bottom_sheet_link) {
|
||||
copyLinkToClipBoard(v.tag as Long)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun removeSelectedItems() {
|
||||
if (bottomSheet != null) bottomSheet!!.hide()
|
||||
|
|
@ -348,25 +325,23 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
deleteDialog.show()
|
||||
}
|
||||
|
||||
private fun removeItem(id: Long) {
|
||||
private fun removeItem(item: HistoryItem) {
|
||||
if (bottomSheet != null) bottomSheet!!.hide()
|
||||
val deleteFile = booleanArrayOf(false)
|
||||
val v = findItem(id)
|
||||
val deleteDialog = MaterialAlertDialogBuilder(fragmentContext!!)
|
||||
deleteDialog.setTitle(getString(R.string.you_are_going_to_delete) + " \"" + v!!.title + "\"!")
|
||||
deleteDialog.setTitle(getString(R.string.you_are_going_to_delete) + " \"" + item.title + "\"!")
|
||||
deleteDialog.setMultiChoiceItems(
|
||||
arrayOf(getString(R.string.delete_file_too)),
|
||||
booleanArrayOf(false)
|
||||
) { _: DialogInterface?, _: Int, b: Boolean -> deleteFile[0] = b }
|
||||
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||
historyViewModel.delete(v, deleteFile[0])
|
||||
historyViewModel.delete(item, deleteFile[0])
|
||||
}
|
||||
deleteDialog.show()
|
||||
}
|
||||
|
||||
private fun copyLinkToClipBoard(id: Long) {
|
||||
val url = findItem(id)?.url
|
||||
private fun copyLinkToClipBoard(url: String) {
|
||||
val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText(getString(R.string.url), url)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
|
|
@ -375,16 +350,14 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
.show()
|
||||
}
|
||||
|
||||
private fun openLinkIntent(id: Long) {
|
||||
val url = findItem(id)?.url
|
||||
private fun openLinkIntent(url: String) {
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.data = Uri.parse(url)
|
||||
if (bottomSheet != null) bottomSheet!!.hide()
|
||||
startActivity(i)
|
||||
}
|
||||
|
||||
private fun openFileIntent(id: Long) {
|
||||
val downloadPath = findItem(id)!!.downloadPath
|
||||
private fun openFileIntent(downloadPath: String) {
|
||||
val file = File(downloadPath)
|
||||
val uri = FileProvider.getUriForFile(
|
||||
fragmentContext!!,
|
||||
|
|
@ -411,14 +384,23 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
val url = video.url
|
||||
link!!.text = url
|
||||
link.tag = videoID
|
||||
link.setOnClickListener(this)
|
||||
link.setOnLongClickListener(this)
|
||||
link.setOnClickListener{
|
||||
openLinkIntent(video.url)
|
||||
}
|
||||
link.setOnLongClickListener{
|
||||
copyLinkToClipBoard(video.url)
|
||||
true
|
||||
}
|
||||
val remove = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_remove_button)
|
||||
remove!!.tag = videoID
|
||||
remove.setOnClickListener(this)
|
||||
remove.setOnClickListener{
|
||||
removeItem(video)
|
||||
}
|
||||
val openFile = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_open_file_button)
|
||||
openFile!!.tag = videoID
|
||||
openFile.setOnClickListener(this)
|
||||
openFile.setOnClickListener{
|
||||
openFileIntent(video.downloadPath)
|
||||
}
|
||||
if (!isPresent) openFile.visibility = GONE
|
||||
bottomSheet!!.show()
|
||||
bottomSheet!!.window!!.setLayout(
|
||||
|
|
@ -438,17 +420,6 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
}
|
||||
}
|
||||
|
||||
override fun onButtonClick(position: Int) {
|
||||
// val vid = historyObjects!![position]
|
||||
// try {
|
||||
// //mainActivity!!.removeItemFromDownloadQueue(vid, vid!!.downloadedType)
|
||||
// } catch (e: Exception) {
|
||||
// val info = DownloadInfo()
|
||||
// info.video = vid
|
||||
// info.downloadType = vid!!.downloadedType
|
||||
// }
|
||||
}
|
||||
|
||||
private fun findItem(id : Long): HistoryItem? {
|
||||
return historyList?.find { it?.id == id }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,25 +8,21 @@ import android.util.Log
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import androidx.fragment.app.findFragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
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.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
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.tabs.TabLayout
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel.Type
|
||||
|
||||
class ConfigureDownloadBottomSheetDialog(private val downloadItem: DownloadItem) : BottomSheetDialogFragment() {
|
||||
private lateinit var tabLayout: TabLayout
|
||||
|
|
@ -36,6 +32,10 @@ class ConfigureDownloadBottomSheetDialog(private val downloadItem: DownloadItem)
|
|||
private lateinit var downloadViewModel: DownloadViewModel
|
||||
private lateinit var resultViewModel: ResultViewModel
|
||||
|
||||
private val audioDownloadItem =clone(downloadItem)
|
||||
private val videoDownloadItem = clone(downloadItem)
|
||||
private val commandDownloadItem = clone(downloadItem)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
|
|
@ -60,7 +60,11 @@ class ConfigureDownloadBottomSheetDialog(private val downloadItem: DownloadItem)
|
|||
viewPager2 = view.findViewById(R.id.download_viewpager)
|
||||
|
||||
val fragmentManager = parentFragmentManager
|
||||
fragmentAdapter = DownloadFragmentAdapter(downloadItem, fragmentManager, lifecycle)
|
||||
fragmentAdapter = DownloadFragmentAdapter(
|
||||
audioDownloadItem,videoDownloadItem,commandDownloadItem,
|
||||
fragmentManager,
|
||||
lifecycle
|
||||
)
|
||||
viewPager2.adapter = fragmentAdapter
|
||||
viewPager2.isSaveFromParentEnabled = false
|
||||
|
||||
|
|
@ -104,9 +108,13 @@ class ConfigureDownloadBottomSheetDialog(private val downloadItem: DownloadItem)
|
|||
dismiss()
|
||||
}
|
||||
|
||||
val download = view.findViewById<Button>(R.id.bottom_sheet_ok)
|
||||
download!!.setOnClickListener {
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
val ok = view.findViewById<Button>(R.id.bottom_sheet_ok)
|
||||
ok!!.setOnClickListener {
|
||||
when(tabLayout.selectedTabPosition){
|
||||
0 -> downloadViewModel.updateDownload(audioDownloadItem)
|
||||
1 -> downloadViewModel.updateDownload(videoDownloadItem)
|
||||
else -> downloadViewModel.updateDownload(commandDownloadItem)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
|
@ -142,5 +150,10 @@ class ConfigureDownloadBottomSheetDialog(private val downloadItem: DownloadItem)
|
|||
}
|
||||
}
|
||||
|
||||
private fun clone(item: DownloadItem) : DownloadItem {
|
||||
val stringItem = Gson().toJson(item, DownloadItem::class.java)
|
||||
return Gson().fromJson(stringItem, DownloadItem::class.java)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,20 +17,18 @@ 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.Format
|
||||
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.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
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel.Type
|
||||
|
||||
class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment() {
|
||||
|
||||
class DownloadAudioFragment(private var downloadItem: DownloadItem) : Fragment() {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
|
|
@ -43,24 +41,7 @@ class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
private lateinit var author : TextInputLayout
|
||||
private lateinit var saveDir : TextInputLayout
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
downloadItem.type = "audio"
|
||||
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,
|
||||
|
|
@ -79,11 +60,11 @@ class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
downloadItem.type = "audio"
|
||||
lifecycleScope.launch {
|
||||
val resultItem = withContext(Dispatchers.IO){
|
||||
resultViewModel.getItemByURL(downloadItem.url)
|
||||
}
|
||||
val type = downloadItem.type
|
||||
|
||||
val sharedPreferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
|
|
@ -128,13 +109,11 @@ class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
audioPathResultLauncher.launch(intent)
|
||||
}
|
||||
|
||||
val formats = resultItem.formats.filter { it.format_note.contains("audio", ignoreCase = true) }
|
||||
val format = view.findViewById<TextInputLayout>(R.id.format)
|
||||
if (formats.isEmpty()) {
|
||||
if (resultItem.formats.isEmpty()) {
|
||||
format.visibility = View.GONE
|
||||
downloadItem.format = Format()
|
||||
} else {
|
||||
val formatTitles = formats.map {
|
||||
val formatTitles = resultItem.formats.map {
|
||||
if (it.format_note.contains("AUDIO_QUALITY_")) {
|
||||
it.format_note.replace(
|
||||
"AUDIO_QUALITY_",
|
||||
|
|
@ -157,12 +136,12 @@ class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
)
|
||||
)
|
||||
if (formatTitles.isNotEmpty()) {
|
||||
autoCompleteTextView!!.setText(formatTitles[formats.lastIndex], false)
|
||||
autoCompleteTextView!!.setText(formatTitles[resultItem.formats.lastIndex], false)
|
||||
}
|
||||
(format!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.format.format_note = formats[index].format_note
|
||||
downloadItem.format.format_id = formats[index].format_id
|
||||
downloadItem.format.format_note = resultItem.formats[index].format_note
|
||||
downloadItem.format.format_id = resultItem.formats[index].format_id
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -179,8 +158,12 @@ class DownloadAudioFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
containers
|
||||
)
|
||||
)
|
||||
val selectedContainer: String = formats.find { downloadItem.format.format_note == it.format_note }?.container
|
||||
?: sharedPreferences.getString("audio_format", "mp3")!!
|
||||
Log.e("aa", downloadItem.format.container)
|
||||
val selectedContainer: String = if (containers.contains(downloadItem.format.container)){
|
||||
downloadItem.format.container
|
||||
}else{
|
||||
containers[0]
|
||||
}
|
||||
downloadItem.format.container = selectedContainer
|
||||
containerAutoCompleteTextView!!.setText(selectedContainer, false)
|
||||
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
|
|
|
|||
|
|
@ -4,40 +4,33 @@ import android.annotation.SuppressLint
|
|||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.Adapter
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.view.get
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import androidx.fragment.app.findFragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import androidx.work.Data
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.work.DownloadWorker
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
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.tabs.TabLayout
|
||||
import com.google.gson.Gson
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel.Type
|
||||
|
||||
class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment() {
|
||||
class DownloadBottomSheetDialog(private val downloadItem: DownloadItem) : BottomSheetDialogFragment() {
|
||||
private lateinit var tabLayout: TabLayout
|
||||
private lateinit var viewPager2: ViewPager2
|
||||
private lateinit var fragmentAdapter : DownloadFragmentAdapter
|
||||
private val downloadItem = item
|
||||
private lateinit var downloadViewModel: DownloadViewModel
|
||||
|
||||
private var downloadType = Type.VIDEO
|
||||
private val audioDownloadItem = clone(downloadItem)
|
||||
private val videoDownloadItem = clone(downloadItem)
|
||||
private val commandDownloadItem = clone(downloadItem)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
|
|
@ -55,11 +48,17 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
|
|||
val view = LayoutInflater.from(context).inflate(R.layout.download_bottom_sheet, null)
|
||||
dialog.setContentView(view)
|
||||
|
||||
Log.e("aaa", downloadItem.toString())
|
||||
|
||||
tabLayout = view.findViewById(R.id.download_tablayout)
|
||||
viewPager2 = view.findViewById(R.id.download_viewpager)
|
||||
|
||||
val fragmentManager = parentFragmentManager
|
||||
fragmentAdapter = DownloadFragmentAdapter(downloadItem, fragmentManager, lifecycle)
|
||||
fragmentAdapter = DownloadFragmentAdapter(
|
||||
audioDownloadItem, videoDownloadItem, commandDownloadItem,
|
||||
fragmentManager,
|
||||
lifecycle
|
||||
)
|
||||
viewPager2.adapter = fragmentAdapter
|
||||
viewPager2.isSaveFromParentEnabled = false
|
||||
|
||||
|
|
@ -104,7 +103,13 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
|
|||
|
||||
val download = view.findViewById<Button>(R.id.bottomsheet_download_button)
|
||||
download!!.setOnClickListener {
|
||||
downloadViewModel.queueDownloads(listOf(downloadItem))
|
||||
Log.e("aa", tabLayout.selectedTabPosition.toString())
|
||||
val item: List<DownloadItem> = when(tabLayout.selectedTabPosition){
|
||||
0 -> listOf(audioDownloadItem)
|
||||
1 -> listOf(videoDownloadItem)
|
||||
else -> listOf(commandDownloadItem)
|
||||
}
|
||||
downloadViewModel.queueDownloads(item)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
|
@ -130,5 +135,14 @@ class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment(
|
|||
downloadViewModel.deleteSingleProcessing(downloadItem)
|
||||
}
|
||||
|
||||
fun updateType(type: Type){
|
||||
downloadType = type
|
||||
}
|
||||
|
||||
private fun clone(item: DownloadItem) : DownloadItem {
|
||||
val stringItem = Gson().toJson(item, DownloadItem::class.java)
|
||||
return Gson().fromJson(stringItem, DownloadItem::class.java)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,13 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
|
|||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.google.gson.Gson
|
||||
|
||||
class DownloadFragmentAdapter (private val downloadItem : DownloadItem, fragmentManager : FragmentManager, lifecycle : Lifecycle) : FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
class DownloadFragmentAdapter (
|
||||
private val audioDownloadItem : DownloadItem,
|
||||
private val videoDownloadItem : DownloadItem,
|
||||
private val commandDownloadItem : DownloadItem,
|
||||
fragmentManager : FragmentManager,
|
||||
lifecycle : Lifecycle
|
||||
) : FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return 3
|
||||
|
|
@ -18,18 +24,13 @@ class DownloadFragmentAdapter (private val downloadItem : DownloadItem, fragment
|
|||
override fun createFragment(position: Int): Fragment {
|
||||
when (position) {
|
||||
0 -> {
|
||||
return DownloadAudioFragment(downloadItem)
|
||||
return DownloadAudioFragment(audioDownloadItem)
|
||||
}
|
||||
1 -> {
|
||||
return DownloadVideoFragment(downloadItem)
|
||||
return DownloadVideoFragment(videoDownloadItem)
|
||||
}
|
||||
}
|
||||
return DownloadCommandFragment(downloadItem)
|
||||
return DownloadCommandFragment(commandDownloadItem)
|
||||
}
|
||||
|
||||
|
||||
private fun clone(item: DownloadItem) : DownloadItem {
|
||||
val stringItem = Gson().toJson(item, DownloadItem::class.java)
|
||||
return Gson().fromJson(stringItem, DownloadItem::class.java)
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,6 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
|
@ -14,7 +13,6 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.deniscerri.ytdlnis.App
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
|
|
@ -23,12 +21,13 @@ 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
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel.Type
|
||||
|
||||
|
||||
class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment() {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
|
|
@ -43,24 +42,8 @@ class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
private lateinit var author : TextInputLayout
|
||||
private lateinit var saveDir : TextInputLayout
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
downloadItem.type = "video"
|
||||
// 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?,
|
||||
|
|
@ -79,7 +62,7 @@ class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
downloadItem.type = "video"
|
||||
lifecycleScope.launch {
|
||||
val resultItem = withContext(Dispatchers.IO){
|
||||
resultViewModel.getItemByURL(downloadItem.url)
|
||||
|
|
@ -140,13 +123,17 @@ class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
formats.addAll(resultItem.formats.filter { !it.format_note.contains("audio", ignoreCase = true) })
|
||||
if (formats.isEmpty()) {
|
||||
val videoFormats = resources.getStringArray(R.array.video_formats)
|
||||
videoFormats.forEach { formats.add(Format(it, "", 0, it)) }
|
||||
val container = sharedPreferences.getString("video_format", "Default")
|
||||
videoFormats.forEach { formats.add(Format(it, container!!, 0, it)) }
|
||||
}
|
||||
|
||||
val formatTitles = formats.map {
|
||||
it.format_note + if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
}
|
||||
|
||||
|
||||
downloadItem.format = formats[formats.lastIndex]
|
||||
|
||||
val format = view.findViewById<TextInputLayout>(R.id.format)
|
||||
val autoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.format_textview)
|
||||
|
|
@ -181,10 +168,7 @@ class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
containers
|
||||
)
|
||||
)
|
||||
var selectedContainer: String = downloadItem.format.container
|
||||
if (selectedContainer.isEmpty()){
|
||||
selectedContainer = sharedPreferences.getString("video_format", "Default")!!
|
||||
}
|
||||
val selectedContainer: String = downloadItem.format.container
|
||||
containerAutoCompleteTextView!!.setText(selectedContainer, false)
|
||||
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
|
|
@ -193,13 +177,22 @@ class DownloadVideoFragment(private val downloadItem: DownloadItem) : Fragment()
|
|||
}
|
||||
|
||||
val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
|
||||
embedSubs!!.isChecked = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
embedSubs!!.isChecked = embedSubs.isChecked
|
||||
embedSubs.setOnClickListener {
|
||||
downloadItem.embedSubs = embedSubs.isChecked
|
||||
}
|
||||
|
||||
val addChapters = view.findViewById<Chip>(R.id.add_chapters)
|
||||
addChapters!!.isChecked = sharedPreferences.getBoolean("add_chapters", false)
|
||||
addChapters!!.isChecked = addChapters.isChecked
|
||||
addChapters.setOnClickListener{
|
||||
downloadItem.addChapters = addChapters.isChecked
|
||||
}
|
||||
|
||||
val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)
|
||||
saveThumbnail!!.isChecked = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
saveThumbnail!!.isChecked = saveThumbnail.isChecked
|
||||
saveThumbnail.setOnClickListener {
|
||||
downloadItem.SaveThumb = saveThumbnail.isChecked
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import java.nio.file.Files
|
|||
import java.nio.file.StandardCopyOption
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.log10
|
||||
import kotlin.math.max
|
||||
import kotlin.math.pow
|
||||
|
||||
class FileUtil() {
|
||||
|
|
@ -58,21 +59,18 @@ class FileUtil() {
|
|||
return formattedPath.toString()
|
||||
}
|
||||
|
||||
private fun scanMedia(destDir: String, context: Context) : String {
|
||||
val files = ArrayList<File>()
|
||||
private fun scanMedia(destDir: String, fileName: String, context: Context) : String {
|
||||
val file : File
|
||||
val path = File(formatPath(destDir))
|
||||
|
||||
try {
|
||||
for (file in path.listFiles()!!) {
|
||||
if (file.isFile) {
|
||||
files.add(file)
|
||||
}
|
||||
}
|
||||
file = path.listFiles()?.find {
|
||||
it!!.name == fileName
|
||||
}!!
|
||||
|
||||
val paths = arrayOfNulls<String>(files.size)
|
||||
for (i in files.indices) paths[i] = files[i].absolutePath
|
||||
val paths = arrayOf(file.absolutePath)
|
||||
MediaScannerConnection.scanFile(context, paths, null, null)
|
||||
return paths[0]!!
|
||||
return paths[0]
|
||||
}catch (e: Exception){
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
|
@ -81,12 +79,19 @@ class FileUtil() {
|
|||
}
|
||||
@Throws(Exception::class)
|
||||
fun moveFile(originDir: File, context: Context, destDir: String, progress: (p: Int) -> Unit) : String {
|
||||
var fileName = ""
|
||||
var maxSize = 0L
|
||||
originDir.listFiles()?.forEach {
|
||||
if (it.name.equals("rList")){
|
||||
it.delete()
|
||||
return@forEach
|
||||
}
|
||||
|
||||
if (it.length() > maxSize){
|
||||
maxSize = it.length()
|
||||
fileName = it.name
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
|
||||
val f = File(formatPath(destDir)+"/"+it.name)
|
||||
f.mkdirs()
|
||||
|
|
@ -131,8 +136,12 @@ class FileUtil() {
|
|||
it.delete()
|
||||
}
|
||||
}
|
||||
originDir.delete()
|
||||
return scanMedia(destDir, context)
|
||||
originDir.delete()
|
||||
return if (maxSize > 0L){
|
||||
scanMedia(destDir, fileName, context)
|
||||
}else{
|
||||
context.getString(R.string.unfound_file)
|
||||
}
|
||||
}
|
||||
|
||||
fun convertFileSize(s: Long): String{
|
||||
|
|
|
|||
|
|
@ -108,9 +108,14 @@ class DownloadWorker(
|
|||
request.addOption("-x")
|
||||
var audioQualityId : String = downloadItem.format.format_id
|
||||
if (audioQualityId == "0" || audioQualityId.isEmpty()) audioQualityId = "ba"
|
||||
val ext = downloadItem.format.container
|
||||
request.addOption("-f", audioQualityId)
|
||||
request.addOption("--audio-format", ext)
|
||||
|
||||
val ext = downloadItem.format.container
|
||||
if(ext != context.getString(R.string.defaultValue)){
|
||||
request.addOption("--audio-format", ext)
|
||||
}else{
|
||||
request.addOption("--audio-format", sharedPreferences.getString("audio_format", "mp3")!!)
|
||||
}
|
||||
request.addOption("--embed-metadata")
|
||||
|
||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<resources>
|
||||
<string-array name="audio_containers">
|
||||
<item>@string/defaultValue</item>
|
||||
<item>mp3</item>
|
||||
<item>m4a</item>
|
||||
<item>aac</item>
|
||||
|
|
@ -9,11 +10,6 @@
|
|||
<item>wav</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="audio_formats">
|
||||
<item>@string/worst</item>
|
||||
<item>@string/best</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="video_containers">
|
||||
<item>@string/defaultValue</item>
|
||||
<item>mp4</item>
|
||||
|
|
|
|||
|
|
@ -160,8 +160,6 @@
|
|||
<string name="schedule">Schedule</string>
|
||||
<string name="concurrent_downloads">Concurrent Downloads</string>
|
||||
<string name="concurrent_downloads_summary">Number of downloads executing at the same time</string>
|
||||
<string name="best">Best</string>
|
||||
<string name="worst">Worst</string>
|
||||
<string name="defaultValue">Default</string>
|
||||
<string name="container">Container</string>
|
||||
<string name="template">Template</string>
|
||||
|
|
|
|||
Loading…
Reference in a new issue