From 70ed5008ac8fd50d54ce03d113b82d49c4e74005 Mon Sep 17 00:00:00 2001 From: zaednasr <75589932+zaednasr@users.noreply.github.com> Date: Sat, 31 Aug 2024 21:39:04 +0200 Subject: [PATCH] fixes newpipe extractor fix add approx filesize remember text wrap state in logs/terminal if quick download enabled, added ability to show the download card while sharing the txt file on any download type hide download size when enabling cutting because the size is unknown --- app/build.gradle | 4 +- .../java/com/deniscerri/ytdl/MainActivity.kt | 62 +++++++++++-------- .../ui/downloadcard/DownloadAudioFragment.kt | 16 +++-- .../downloadcard/DownloadBottomSheetDialog.kt | 2 +- .../DownloadMultipleBottomSheetDialog.kt | 8 ++- .../ui/downloadcard/DownloadVideoFragment.kt | 42 ++++++++++--- .../FormatSelectionBottomSheetDialog.kt | 3 +- .../more/downloadLogs/DownloadLogFragment.kt | 7 +++ .../ytdl/ui/more/terminal/TerminalFragment.kt | 8 +++ .../com/deniscerri/ytdl/util/Extensions.kt | 19 +++--- .../deniscerri/ytdl/util/NotificationUtil.kt | 8 +++ .../java/com/deniscerri/ytdl/util/UiUtil.kt | 30 +++++---- .../ytdl/util/extractors/YTDLPUtil.kt | 12 ++-- .../ytdl/work/TerminalDownloadWorker.kt | 2 +- app/src/main/res/layout/cut_video_sheet.xml | 1 - .../main/res/layout/result_card_details.xml | 1 - app/src/main/res/values/styles.xml | 3 +- 17 files changed, 150 insertions(+), 78 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index bda48583..900a58e2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -134,7 +134,7 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4" + coreLibraryDesugaring "com.android.tools:desugar_jdk_libs_nio:2.1.0" implementation "com.github.yausername.youtubedl-android:library:$youtubedlAndroidVer" implementation "com.github.yausername.youtubedl-android:ffmpeg:$youtubedlAndroidVer" implementation "com.github.yausername.youtubedl-android:aria2c:$youtubedlAndroidVer" @@ -161,7 +161,7 @@ dependencies { androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVer" implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' - implementation "com.devbrackets.android:exomedia:4.3.0" + implementation 'com.devbrackets.android:exomedia:5.1.0' implementation("androidx.cardview:cardview:1.0.0") implementation("com.squareup.picasso:picasso:2.71828") diff --git a/app/src/main/java/com/deniscerri/ytdl/MainActivity.kt b/app/src/main/java/com/deniscerri/ytdl/MainActivity.kt index fe99d3a7..99a24f99 100644 --- a/app/src/main/java/com/deniscerri/ytdl/MainActivity.kt +++ b/app/src/main/java/com/deniscerri/ytdl/MainActivity.kt @@ -29,6 +29,7 @@ import androidx.core.view.WindowInsetsCompat import androidx.core.view.forEach import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams +import androidx.documentfile.provider.DocumentFile import androidx.fragment.app.FragmentContainerView import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope @@ -38,6 +39,7 @@ import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.findNavController import androidx.navigation.ui.setupWithNavController import androidx.preference.PreferenceManager +import com.anggrayudi.storage.file.getAbsolutePath import com.deniscerri.ytdl.database.DBManager import com.deniscerri.ytdl.database.repository.DownloadRepository import com.deniscerri.ytdl.database.viewmodel.CookieViewModel @@ -405,39 +407,45 @@ class MainActivity : BaseActivity() { intent.getParcelableExtra(Intent.EXTRA_STREAM) } - if (preferences.getString("preferred_download_type", "video") == "command"){ - val f = File(FileUtil.formatPath(uri?.path ?: "")) - if (!f.exists()){ - Toast.makeText(context, "Couldn't read file", Toast.LENGTH_LONG).show() + var downloadType = DownloadViewModel.Type.valueOf(preferences.getString("preferred_download_type", "video")!!) + if (preferences.getBoolean("quick_download", false) || downloadType == DownloadViewModel.Type.command) { + val docFile = DocumentFile.fromSingleUri(this, uri!!) + if (docFile?.exists() == true){ + val bundle = Bundle() + val path = docFile.getAbsolutePath(this) + if (downloadType == DownloadViewModel.Type.auto) { + downloadType = downloadViewModel.getDownloadType(null, path) + } + + bundle.putParcelable("result", downloadViewModel.createEmptyResultItem(path)) + bundle.putSerializable("type", downloadType) + navController.navigate(R.id.downloadBottomSheetDialog, bundle) return } - val bundle = Bundle() - bundle.putParcelable("result", downloadViewModel.createEmptyResultItem(f.absolutePath)) - bundle.putSerializable("type", DownloadViewModel.Type.command) - navController.navigate(R.id.downloadBottomSheetDialog, bundle) - }else{ - val `is` = contentResolver.openInputStream(uri!!) - val textBuilder = StringBuilder() - val reader: Reader = BufferedReader( - InputStreamReader( - `is`, Charset.forName( - StandardCharsets.UTF_8.name() - ) + } + + val `is` = contentResolver.openInputStream(uri!!) + val textBuilder = StringBuilder() + val reader: Reader = BufferedReader( + InputStreamReader( + `is`, Charset.forName( + StandardCharsets.UTF_8.name() ) ) - var c: Int - while (reader.read().also { c = it } != -1) { - textBuilder.append(c.toChar()) - } - val bundle = Bundle() - bundle.putString("url", textBuilder.toString()) - navController.popBackStack(R.id.homeFragment, true) - navController.navigate( - R.id.homeFragment, - bundle - ) + ) + var c: Int + while (reader.read().also { c = it } != -1) { + textBuilder.append(c.toChar()) } + val bundle = Bundle() + bundle.putString("url", textBuilder.toString()) + navController.popBackStack(R.id.homeFragment, true) + navController.navigate( + R.id.homeFragment, + bundle + ) } catch (e: Exception) { + Toast.makeText(context, "Couldn't read file", Toast.LENGTH_LONG).show() e.printStackTrace() } }else if (action == Intent.ACTION_VIEW){ diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadAudioFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadAudioFragment.kt index 151803e2..7823528f 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadAudioFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadAudioFragment.kt @@ -219,12 +219,12 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private val formatCard = view.findViewById(R.id.format_card_constraintLayout) val chosenFormat = downloadItem.format - UiUtil.populateFormatCard(requireContext(), formatCard, chosenFormat, null) + UiUtil.populateFormatCard(requireContext(), formatCard, chosenFormat, null, showSize = downloadItem.downloadSections.isEmpty()) val listener = object : OnFormatClickListener { override fun onFormatClick(formatTuple: FormatTuple) { formatTuple.format?.apply { downloadItem.format = this - UiUtil.populateFormatCard(requireContext(), formatCard, this, null) + UiUtil.populateFormatCard(requireContext(), formatCard, this, null, showSize = downloadItem.downloadSections.isEmpty()) } } @@ -245,12 +245,12 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private val preferredFormat = downloadViewModel.getFormat(formats, Type.audio) downloadItem.format = preferredFormat downloadItem.allFormats = formats - UiUtil.populateFormatCard(requireContext(), formatCard, preferredFormat, null) + UiUtil.populateFormatCard(requireContext(), formatCard, preferredFormat, null, showSize = downloadItem.downloadSections.isEmpty()) } } formatCard.setOnClickListener{ if (parentFragmentManager.findFragmentByTag("formatSheet") == null){ - val bottomSheet = FormatSelectionBottomSheetDialog(listOf(downloadItem), listener) + val bottomSheet = FormatSelectionBottomSheetDialog(listOf(downloadItem), listener, canUpdate = !nonSpecific) bottomSheet.show(parentFragmentManager, "formatSheet") } } @@ -319,7 +319,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private if(isUpdatingData){ val snack = Snackbar.make(view, context.getString(R.string.please_wait), Snackbar.LENGTH_SHORT) snack.show() - }else{ + }else if (!nonSpecific){ val snack = Snackbar.make(view, context.getString(R.string.cut_unavailable), Snackbar.LENGTH_SHORT) snack.setAction(R.string.update){ CoroutineScope(SupervisorJob()).launch(Dispatchers.IO) { @@ -332,6 +332,10 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private snack.show() } }, + cutValueChanged = { + downloadItem.downloadSections = it + UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, showSize = downloadItem.downloadSections.isEmpty()) + }, extraCommandsClicked = { val callback = object : ExtraCommandsListener { override fun onChangeExtraCommand(c: String) { @@ -358,7 +362,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private formats.find { it.format_id == formatID }?.apply { downloadItem.format = this val formatCard = requireView().findViewById(R.id.format_card_constraintLayout) - UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, listOf()) + UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, listOf(), showSize = downloadItem.downloadSections.isEmpty()) } } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadBottomSheetDialog.kt index ec38bb37..17044d3c 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadBottomSheetDialog.kt @@ -187,13 +187,13 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() { //remove outdated player url of 1hr so it can refetch it in the cut player if (result.creationTime > System.currentTimeMillis() - 3600000) result.urls = "" - val fragmentManager = parentFragmentManager fragmentAdapter = DownloadFragmentAdapter( fragmentManager, lifecycle, result, currentDownloadItem, + nonSpecific = result.url.endsWith(".txt"), isIncognito = incognito ) diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadMultipleBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadMultipleBottomSheetDialog.kt index f96ce041..32ff2a77 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadMultipleBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadMultipleBottomSheetDialog.kt @@ -579,6 +579,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure }, cutClicked = {}, cutDisabledClicked = {}, + cutValueChanged = {}, extraCommandsClicked = { val callback = object : ExtraCommandsListener { override fun onChangeExtraCommand(c: String) { @@ -649,6 +650,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure }, cutClicked = {}, cutDisabledClicked = {}, + cutValueChanged = {}, filenameTemplateSet = { checked -> items.forEach { it.customFileNameTemplate = checked } CoroutineScope(Dispatchers.IO).launch { items.forEach { downloadViewModel.updateDownload(it) } } @@ -846,8 +848,8 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure audio!!.setOnClickListener { lifecycleScope.launch { - item = downloadViewModel.switchDownloadType(listOf(item), DownloadViewModel.Type.audio).first() withContext(Dispatchers.IO){ + item = downloadViewModel.switchDownloadType(listOf(item), DownloadViewModel.Type.audio).first() downloadViewModel.updateDownload(item) } bottomSheet.cancel() @@ -856,8 +858,8 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure video!!.setOnClickListener { lifecycleScope.launch { - item = downloadViewModel.switchDownloadType(listOf(item), DownloadViewModel.Type.video).first() withContext(Dispatchers.IO){ + item = downloadViewModel.switchDownloadType(listOf(item), DownloadViewModel.Type.video).first() downloadViewModel.updateDownload(item) } bottomSheet.cancel() @@ -866,8 +868,8 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure command!!.setOnClickListener { lifecycleScope.launch { - item = downloadViewModel.switchDownloadType(listOf(item), DownloadViewModel.Type.command).first() withContext(Dispatchers.IO){ + item = downloadViewModel.switchDownloadType(listOf(item), DownloadViewModel.Type.command).first() downloadViewModel.updateDownload(item) } bottomSheet.cancel() diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadVideoFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadVideoFragment.kt index 6bfe829d..9f75dbb0 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadVideoFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadVideoFragment.kt @@ -237,7 +237,15 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private val formatCard = view.findViewById(R.id.format_card_constraintLayout) val chosenFormat = downloadItem.format - UiUtil.populateFormatCard(requireContext(), formatCard, chosenFormat, downloadItem.allFormats.filter { downloadItem.videoPreferences.audioFormatIDs.contains(it.format_id) }) + + UiUtil.populateFormatCard( + requireContext(), + formatCard, + chosenFormat, + downloadItem.allFormats.filter { downloadItem.videoPreferences.audioFormatIDs.contains(it.format_id) }, + showSize = downloadItem.downloadSections.isEmpty() + ) + val listener = object : OnFormatClickListener { override fun onFormatClick(formatTuple: FormatTuple) { formatTuple.format?.apply { @@ -248,7 +256,8 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private downloadItem.videoPreferences.audioFormatIDs.addAll(it) } UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, - if(downloadItem.videoPreferences.removeAudio) listOf() else formatTuple.audioFormats + if(downloadItem.videoPreferences.removeAudio) listOf() else formatTuple.audioFormats, + showSize = downloadItem.downloadSections.isEmpty() ) } @@ -272,14 +281,15 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private downloadItem.format = preferredFormat downloadItem.allFormats = formats UiUtil.populateFormatCard(requireContext(), formatCard, preferredFormat, - if(downloadItem.videoPreferences.removeAudio) listOf() else formats.filter { preferredAudioFormats.contains(it.format_id) } + if(downloadItem.videoPreferences.removeAudio) listOf() else formats.filter { preferredAudioFormats.contains(it.format_id) }, + showSize = downloadItem.downloadSections.isEmpty() ) } } formatCard.setOnClickListener{ if (parentFragmentManager.findFragmentByTag("formatSheet") == null){ - val bottomSheet = FormatSelectionBottomSheetDialog(listOf(downloadItem), listener) + val bottomSheet = FormatSelectionBottomSheetDialog(listOf(downloadItem), listener, canUpdate = !nonSpecific) bottomSheet.show(parentFragmentManager, "formatSheet") } } @@ -349,7 +359,7 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private if(isUpdatingData){ val snack = Snackbar.make(view, context.getString(R.string.please_wait), Snackbar.LENGTH_SHORT) snack.show() - }else{ + }else if (!nonSpecific){ val snack = Snackbar.make(view, context.getString(R.string.cut_unavailable), Snackbar.LENGTH_SHORT) snack.setAction(R.string.update){ CoroutineScope(SupervisorJob()).launch(Dispatchers.IO) { @@ -362,6 +372,17 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private snack.show() } }, + cutValueChanged = { + downloadItem.downloadSections = it + UiUtil.populateFormatCard( + requireContext(), + formatCard, + downloadItem.format, + if(downloadItem.videoPreferences.removeAudio) listOf() + else downloadItem.allFormats.filter { f -> downloadItem.videoPreferences.audioFormatIDs.contains(f.format_id) }, + showSize = downloadItem.downloadSections.isEmpty() + ) + }, filenameTemplateSet = { downloadItem.customFileNameTemplate = it }, @@ -376,7 +397,13 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private }, removeAudioClicked = { downloadItem.videoPreferences.removeAudio = it - UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, if (it) listOf() else downloadItem.allFormats.filter { downloadItem.videoPreferences.audioFormatIDs.contains(it.format_id) }) + UiUtil.populateFormatCard( + requireContext(), + formatCard, + downloadItem.format, + if (it) listOf() else downloadItem.allFormats.filter { downloadItem.videoPreferences.audioFormatIDs.contains(it.format_id) }, + showSize = downloadItem.downloadSections.isEmpty() + ) }, recodeVideoClicked = { downloadItem.videoPreferences.recodeVideo = it @@ -429,7 +456,8 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private downloadItem.videoPreferences.audioFormatIDs.addAll(arrayListOf(format.format_id)) val formatCard = requireView().findViewById(R.id.format_card_constraintLayout) UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, - if(downloadItem.videoPreferences.removeAudio) listOf() else listOf(format) + if(downloadItem.videoPreferences.removeAudio) listOf() else listOf(format), + showSize = downloadItem.downloadSections.isEmpty() ) } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/FormatSelectionBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/FormatSelectionBottomSheetDialog.kt index e72361ef..d0d21f8e 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/FormatSelectionBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/FormatSelectionBottomSheetDialog.kt @@ -41,6 +41,7 @@ import kotlinx.coroutines.withContext class FormatSelectionBottomSheetDialog( private val _items: List? = null, private val _listener: OnFormatClickListener? = null, + private val canUpdate: Boolean = true, private val _multipleFormatsListener: OnMultipleFormatClickListener? = null ) : BottomSheetDialogFragment() { @@ -180,7 +181,7 @@ class FormatSelectionBottomSheetDialog( refreshBtn = view.findViewById(R.id.format_refresh) filterBtn.isVisible = chosenFormats.isNotEmpty() || items.all { it!!.url.isYoutubeURL() } - if (!isMissingFormats || items.isEmpty() || items.first()?.url?.isEmpty() == true) { + if (!isMissingFormats || items.isEmpty() || items.first()?.url?.isEmpty() == true || !canUpdate) { refreshBtn.visibility = View.GONE } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/downloadLogs/DownloadLogFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/downloadLogs/DownloadLogFragment.kt index daa0cd48..764dec6a 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/downloadLogs/DownloadLogFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/downloadLogs/DownloadLogFragment.kt @@ -131,6 +131,7 @@ class DownloadLogFragment : Fragment() { // contentScrollView.setPadding(0,0,0, // (requireContext().resources.displayMetrics.density * 150).toInt() // ) + sharedPreferences.edit().putBoolean("wrap_text_log", true).apply() updateAutoScrollState() }else{ val parent = content.parent as ViewGroup @@ -148,6 +149,7 @@ class DownloadLogFragment : Fragment() { scrollView.id = R.id.horizontalscroll_output parent.addView(scrollView, 0) updateAutoScrollState() + sharedPreferences.edit().putBoolean("wrap_text_log", false).apply() } } @@ -186,6 +188,11 @@ class DownloadLogFragment : Fragment() { false } + sharedPreferences.getBoolean("wrap_text_log", false).apply { + if (this){ + bottomAppBar.menu.performIdentifierAction(R.id.wrap, 0) + } + } logViewModel.getLogFlowByID(id!!).observe(viewLifecycleOwner){logItem -> kotlin.runCatching { diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalFragment.kt index 31a6f838..da74a7a0 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/terminal/TerminalFragment.kt @@ -256,6 +256,7 @@ class TerminalFragment : Fragment() { scrollView.removeAllViews() parent.removeView(scrollView) parent.addView(output, 0) + sharedPreferences.edit().putBoolean("wrap_text_terminal", true).apply() }else{ val parent = output?.parent as ViewGroup parent.removeView(output) @@ -267,6 +268,7 @@ class TerminalFragment : Fragment() { scrollView.addView(output) scrollView.id = R.id.horizontalscroll_output parent.addView(scrollView, 0) + sharedPreferences.edit().putBoolean("wrap_text_terminal", false).apply() } } R.id.export_clipboard -> { @@ -297,6 +299,12 @@ class TerminalFragment : Fragment() { } } } + + sharedPreferences.getBoolean("wrap_text_terminal", false).apply { + if (this){ + bottomAppBar.menu.performIdentifierAction(R.id.wrap, 0) + } + } } private fun hideCancelFab() { kotlin.runCatching { diff --git a/app/src/main/java/com/deniscerri/ytdl/util/Extensions.kt b/app/src/main/java/com/deniscerri/ytdl/util/Extensions.kt index 703999eb..9c8a349d 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/Extensions.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/Extensions.kt @@ -267,16 +267,21 @@ object Extensions { val finishingProgressLinesRegex = Pattern.compile("\\[download]\\h+(100%|[a-zA-Z])") if (line.isNotBlank()) { - var newLine = "" - val newLines = line.lines() - if (!lines.takeLast(3).any { newLines.contains(it) }) { - lines.addAll(newLines.dropLast(1)) - newLine = "\n${newLines.last()}" + var newline = "" + val newLines = line.lines().filter { !lines.contains(it) } + lines.addAll(newLines) + if (newLines.isNotEmpty()) { + newLines.last().apply { + if (this.contains("[download")) { + newline = "\n${this}" + } + } } - return lines.dropLastWhile { + + return lines.distinct().filterNot { it.contains("[download") && !finishingProgressLinesRegex.matcher(it).find() - }.joinToString("\n") + newLine + }.joinToString("\n") + newline } return lines.filterNot { diff --git a/app/src/main/java/com/deniscerri/ytdl/util/NotificationUtil.kt b/app/src/main/java/com/deniscerri/ytdl/util/NotificationUtil.kt index 43d74b45..62a37209 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/NotificationUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/NotificationUtil.kt @@ -119,6 +119,7 @@ class NotificationUtil(var context: Context) { ) .setPriority(NotificationCompat.PRIORITY_LOW) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setGroup(DOWNLOAD_RUNNING_NOTIFICATION_ID.toString()) .setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE) .clearActions() .build() @@ -148,6 +149,7 @@ class NotificationUtil(var context: Context) { fun createDownloadServiceNotification( pendingIntent: PendingIntent?, title: String?, + group : Int = DOWNLOAD_RUNNING_NOTIFICATION_ID ): Notification { val notificationBuilder = getBuilder(DOWNLOAD_SERVICE_CHANNEL_ID) @@ -167,6 +169,7 @@ class NotificationUtil(var context: Context) { .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setProgress(PROGRESS_MAX, PROGRESS_CURR, true) .setContentIntent(pendingIntent) + .setGroup(group.toString()) .setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE) .clearActions() .build() @@ -371,6 +374,7 @@ class NotificationUtil(var context: Context) { R.drawable.ic_launcher_foreground_large ) ) + .setGroup(DOWNLOAD_ERRORED_NOTIFICATION_ID.toString()) .setContentIntent(errorTabPendingIntent) .setPriority(NotificationCompat.PRIORITY_MAX) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) @@ -427,6 +431,7 @@ class NotificationUtil(var context: Context) { notificationBuilder.setProgress(100, progress, (progress == 0 || progress == 100)) .setContentTitle(title) .setStyle(NotificationCompat.BigTextStyle().bigText(contentText)) + .setGroup(DOWNLOAD_RUNNING_NOTIFICATION_ID.toString()) .clearActions() //.addAction(0, resources.getString(R.string.pause), pauseNotificationPendingIntent) .addAction(0, resources.getString(R.string.cancel), cancelNotificationPendingIntent) @@ -462,6 +467,7 @@ class NotificationUtil(var context: Context) { notificationBuilder.setProgress(100, progress, progress == 0) .setContentTitle(title) .setStyle(NotificationCompat.BigTextStyle().bigText(contentText)) + .setGroup(DOWNLOAD_TERMINAL_RUNNING_NOTIFICATION_ID.toString()) .clearActions() .addAction(0, resources.getString(R.string.cancel), cancelNotificationPendingIntent) notificationManager.notify(id, notificationBuilder.build()) @@ -686,6 +692,8 @@ class NotificationUtil(var context: Context) { const val DOWNLOAD_ERRORED_NOTIFICATION_ID = 60000 const val FORMAT_UPDATING_FINISHED_NOTIFICATION_ID = 70000 const val QUERY_PROCESS_FINISHED_NOTIFICATION_ID = 80000 + const val DOWNLOAD_RUNNING_NOTIFICATION_ID = 90000 + const val DOWNLOAD_TERMINAL_RUNNING_NOTIFICATION_ID = 99000 private const val PROGRESS_MAX = 100 private const val PROGRESS_CURR = 0 diff --git a/app/src/main/java/com/deniscerri/ytdl/util/UiUtil.kt b/app/src/main/java/com/deniscerri/ytdl/util/UiUtil.kt index 05f2b5c9..bcefc6d5 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/UiUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/UiUtil.kt @@ -110,7 +110,7 @@ import java.util.function.Predicate object UiUtil { @SuppressLint("SetTextI18n") - fun populateFormatCard(context: Context, formatCard : MaterialCardView, chosenFormat: Format, audioFormats: List?){ + fun populateFormatCard(context: Context, formatCard : MaterialCardView, chosenFormat: Format, audioFormats: List? = null, showSize: Boolean = true){ var formatNote = chosenFormat.format_note if (formatNote.isEmpty()) formatNote = context.getString(R.string.defaultValue) else if (formatNote == "best") formatNote = context.getString(R.string.best_quality) @@ -168,7 +168,11 @@ object UiUtil { var filesize = chosenFormat.filesize if (!audioFormats.isNullOrEmpty() && filesize > 10L) filesize += audioFormats.sumOf { it.filesize } formatCard.findViewById(R.id.file_size).apply { - text = FileUtil.convertFileSize(filesize) + if (showSize) { + text = FileUtil.convertFileSize(filesize) + }else{ + text = "?" + } setOnClickListener { formatCard.callOnClick() } @@ -1015,16 +1019,14 @@ object UiUtil { tmp.setOnClickListener { val c = it as Chip + val currentLanguages = editText.text.toString().split(",").filter { f -> f.isNotBlank() }.toMutableList() if(!c.isChecked){ - editText.setText(editText.text.toString().replace(c.tag.toString(), "").removeSuffix(",")) + editText.setText(currentLanguages.filter { l -> l != c.tag }.joinToString(",")) editText.setSelection(editText.text.length) }else{ - if (editText.text.isBlank()){ - editText.setText(c.tag.toString()) - editText.setSelection(editText.text.length) - }else{ - editText.append(",${c.tag}") - } + currentLanguages.add(c.tag.toString()) + editText.setText(currentLanguages.joinToString(",")) + editText.setSelection(editText.text.length) } } @@ -1143,6 +1145,7 @@ object UiUtil { saveThumbnailClicked: (Boolean) -> Unit, sponsorBlockItemsSet: (values: Array, checkedItems: List) -> Unit, cutClicked: (VideoCutListener) -> Unit, + cutValueChanged: (String) -> Unit, cutDisabledClicked: () -> Unit, filenameTemplateSet: (String) -> Unit, saveSubtitlesClicked: (Boolean) -> Unit, @@ -1346,7 +1349,7 @@ object UiUtil { override fun onChangeCut(list: List) { if (list.isEmpty()){ - downloadItem.downloadSections = "" + cutValueChanged("") cut.text = context.getString(R.string.cut) splitByChapters.isEnabled = true @@ -1362,7 +1365,7 @@ object UiUtil { list.forEach { value += "$it;" } - downloadItem.downloadSections = value + cutValueChanged(value) cut.text = value.dropLast(1) splitByChapters.isEnabled = false @@ -1419,6 +1422,7 @@ object UiUtil { sponsorBlockItemsSet: (Array, List) -> Unit, cutClicked: (VideoCutListener) -> Unit, cutDisabledClicked: () -> Unit, + cutValueChanged: (String) -> Unit, extraCommandsClicked: () -> Unit ){ val embedThumb = view.findViewById(R.id.embed_thumb) @@ -1508,7 +1512,7 @@ object UiUtil { val cutVideoListener = object : VideoCutListener { override fun onChangeCut(list: List) { if (list.isEmpty()){ - downloadItem.downloadSections = "" + cutValueChanged("") cut.text = context.getString(R.string.cut) splitByChapters.isEnabled = true @@ -1518,7 +1522,7 @@ object UiUtil { list.forEach { value += "$it;" } - downloadItem.downloadSections = value + cutValueChanged(value) cut.text = value.dropLast(1) splitByChapters.isEnabled = false diff --git a/app/src/main/java/com/deniscerri/ytdl/util/extractors/YTDLPUtil.kt b/app/src/main/java/com/deniscerri/ytdl/util/extractors/YTDLPUtil.kt index 605c1a1c..f1a5f627 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/extractors/YTDLPUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/extractors/YTDLPUtil.kt @@ -387,12 +387,6 @@ class YTDLPUtil(private val context: Context) { } } - kotlin.runCatching { - if (!format.has("filesize")) { - format.put("filesize", 0) - } - } - kotlin.runCatching { if(format.get("format_note").toString() == "null"){ format.remove("format_note") @@ -528,7 +522,11 @@ class YTDLPUtil(private val context: Context) { fun buildYoutubeDLRequest(downloadItem: DownloadItem) : YoutubeDLRequest { val useItemURL = sharedPreferences.getBoolean("use_itemurl_instead_playlisturl", false) - val request = if (downloadItem.playlistURL.isNullOrBlank() || downloadItem.playlistTitle.isBlank() || useItemURL){ + val request = if (downloadItem.url.endsWith(".txt")) { + YoutubeDLRequest(listOf()).apply { + addOption("-a", downloadItem.url) + } + }else if (downloadItem.playlistURL.isNullOrBlank() || downloadItem.playlistTitle.isBlank() || useItemURL){ YoutubeDLRequest(downloadItem.url) }else{ YoutubeDLRequest(downloadItem.playlistURL!!).apply { diff --git a/app/src/main/java/com/deniscerri/ytdl/work/TerminalDownloadWorker.kt b/app/src/main/java/com/deniscerri/ytdl/work/TerminalDownloadWorker.kt index 31d9ed83..615b88a9 100644 --- a/app/src/main/java/com/deniscerri/ytdl/work/TerminalDownloadWorker.kt +++ b/app/src/main/java/com/deniscerri/ytdl/work/TerminalDownloadWorker.kt @@ -49,7 +49,7 @@ class TerminalDownloadWorker( val intent = Intent(context, TerminalActivity::class.java) val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) - val notification = notificationUtil.createDownloadServiceNotification(pendingIntent, command.take(65)) + val notification = notificationUtil.createDownloadServiceNotification(pendingIntent, command.take(65), NotificationUtil.DOWNLOAD_TERMINAL_RUNNING_NOTIFICATION_ID) val foregroundInfo = ForegroundInfo(itemId, notification) setForegroundAsync(foregroundInfo) diff --git a/app/src/main/res/layout/cut_video_sheet.xml b/app/src/main/res/layout/cut_video_sheet.xml index b7b25218..de0a2914 100644 --- a/app/src/main/res/layout/cut_video_sheet.xml +++ b/app/src/main/res/layout/cut_video_sheet.xml @@ -34,7 +34,6 @@ android:layout_height="match_parent" app:layout_constraintTop_toTopOf="parent" app:resize_mode="fixed_height" - app:useDefaultControls="true" app:use_controller="false" /> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index b26dcd49..5d05322d 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -4,7 +4,8 @@ @android:color/transparent true @null - @null + @null + @android:color/transparent @style/PreferenceTheme