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