From 10b17337b38de18ec07d3ed3ecd6c77d9c4d765a Mon Sep 17 00:00:00 2001 From: deniscerri <64997243+deniscerri@users.noreply.github.com> Date: Sat, 4 Oct 2025 14:48:00 +0200 Subject: [PATCH] add video embed thumbnail toggle in adjust video --- .../ytdl/database/models/VideoPreferences.kt | 3 +- .../database/viewmodel/DownloadViewModel.kt | 4 +- .../DownloadMultipleBottomSheetDialog.kt | 4 + .../ui/downloadcard/DownloadVideoFragment.kt | 3 + .../com/deniscerri/ytdl/util/Extensions.kt | 4 +- .../java/com/deniscerri/ytdl/util/UiUtil.kt | 160 +++++++++++++----- .../ytdl/util/extractors/ytdlp/YTDLPUtil.kt | 3 +- app/src/main/res/layout/adjust_video.xml | 44 +++-- ...eo_chapter_download_preferences_dialog.xml | 23 +++ ..._thumbnail_download_preferences_dialog.xml | 23 +++ app/src/main/res/values/strings.xml | 1 + .../main/res/xml/processing_preferences.xml | 8 + 12 files changed, 204 insertions(+), 76 deletions(-) create mode 100644 app/src/main/res/layout/video_chapter_download_preferences_dialog.xml create mode 100644 app/src/main/res/layout/video_thumbnail_download_preferences_dialog.xml diff --git a/app/src/main/java/com/deniscerri/ytdl/database/models/VideoPreferences.kt b/app/src/main/java/com/deniscerri/ytdl/database/models/VideoPreferences.kt index 655c7016..5c283e51 100644 --- a/app/src/main/java/com/deniscerri/ytdl/database/models/VideoPreferences.kt +++ b/app/src/main/java/com/deniscerri/ytdl/database/models/VideoPreferences.kt @@ -18,5 +18,6 @@ data class VideoPreferences ( var recodeVideo: Boolean = false, var liveFromStart: Boolean = false, var waitForVideoMinutes: Int = 0, - var compatibilityMode: Boolean = false + var compatibilityMode: Boolean = false, + var embedThumbnail: Boolean = false, ) : Parcelable diff --git a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/DownloadViewModel.kt b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/DownloadViewModel.kt index 28e10e4c..60d3c845 100644 --- a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/DownloadViewModel.kt +++ b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/DownloadViewModel.kt @@ -270,6 +270,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel val addChapters = sharedPreferences.getBoolean("add_chapters", false) val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false) val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false) + val videoEmbedThumb = sharedPreferences.getBoolean("video_embed_thumbnail", false) val cropThumb = sharedPreferences.getBoolean("crop_thumbnail", false) var type = getDownloadType(givenType, resultItem.url) @@ -310,7 +311,8 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel saveAutoSubs, subsLanguages, audioFormatIDs = preferredAudioFormats, - recodeVideo = recodeVideo + recodeVideo = recodeVideo, + embedThumbnail = videoEmbedThumb ) val extraCommands = when(type){ 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 fc310aec..b04562ca 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 @@ -644,6 +644,10 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure items.forEach { it.videoPreferences.splitByChapters = checked } CoroutineScope(Dispatchers.IO).launch { items.forEach { downloadViewModel.updateDownload(it) } } }, + embedThumbnailClicked = {checked -> + items.forEach { it.videoPreferences.embedThumbnail = checked } + CoroutineScope(Dispatchers.IO).launch { items.forEach { downloadViewModel.updateDownload(it) } } + }, saveThumbnailClicked = {checked -> items.forEach { it.SaveThumb = checked } CoroutineScope(Dispatchers.IO).launch { items.forEach { downloadViewModel.updateDownload(it) } } 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 ef7b5ead..6547b130 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 @@ -363,6 +363,9 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private splitByChaptersClicked = { downloadItem.videoPreferences.splitByChapters = it }, + embedThumbnailClicked = { + downloadItem.videoPreferences.embedThumbnail = it + }, saveThumbnailClicked = { downloadItem.SaveThumb = it }, 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 1f4deed5..b4919db1 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/Extensions.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/Extensions.kt @@ -297,9 +297,9 @@ object Extensions { val badge = BadgeDrawable.create(context).apply { number = nr backgroundColor = context.getColor(R.color.white) - verticalOffset = 25 + verticalOffset = 30 horizontalOffset = - if (nr < 10) dp(App.instance.resources, 17f) + if (nr < 10) dp(App.instance.resources, 16f) else if (nr < 100) dp(App.instance.resources, 19f) else dp(App.instance.resources, 22f) } 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 9575e5b2..8f541efa 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/UiUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/UiUtil.kt @@ -1306,6 +1306,7 @@ object UiUtil { embedSubsClicked : (Boolean) -> Unit, addChaptersClicked: (Boolean) -> Unit, splitByChaptersClicked: (Boolean) -> Unit, + embedThumbnailClicked: (Boolean) -> Unit, saveThumbnailClicked: (Boolean) -> Unit, sponsorBlockItemsSet: (values: Array, checkedItems: List) -> Unit, cutClicked: (VideoCutListener) -> Unit, @@ -1325,42 +1326,109 @@ object UiUtil { ){ val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) - val addChapters = view.findViewById(R.id.add_chapters) - addChapters!!.isChecked = items.all { it.videoPreferences.addChapters } - addChapters.setOnClickListener{ - addChaptersClicked(addChapters.isChecked) + val adjustThumbnail = view.findViewById(R.id.thumbnail) + fun calculateAdjustThumbnailChangeCount() { + if (items.size == 1) { + val firstItem = items.first() + val count = listOf( + firstItem.SaveThumb, + firstItem.videoPreferences.embedThumbnail + ) + adjustThumbnail.createBadge(context, count.filter { it }.size) + } } + calculateAdjustThumbnailChangeCount() + adjustThumbnail.setOnClickListener { + val adjustThumbnailView = context.layoutInflater.inflate(R.layout.video_thumbnail_download_preferences_dialog, null) + val embedThumb = adjustThumbnailView.findViewById(R.id.embed_thumbnail) + val saveThumb = adjustThumbnailView.findViewById(R.id.save_thumbnail) - val splitByChapters = view.findViewById(R.id.split_by_chapters) - if(items.size == 1 && items[0].downloadSections.isNotBlank()){ - splitByChapters.isEnabled = false - splitByChapters.isChecked = false - }else{ - splitByChapters!!.isChecked = items.all { it.videoPreferences.splitByChapters } + embedThumb!!.isChecked = items.all { it.videoPreferences.embedThumbnail } + embedThumb.setOnClickListener { + embedThumbnailClicked(embedThumb.isChecked) + items.forEach { it.videoPreferences.embedThumbnail = embedThumb.isChecked } + calculateAdjustThumbnailChangeCount() + } + + saveThumb!!.isChecked = items.all { it.SaveThumb } + saveThumb.setOnClickListener { + saveThumbnailClicked(saveThumb.isChecked) + items.forEach { it.SaveThumb = saveThumb.isChecked } + calculateAdjustThumbnailChangeCount() + } + + val adjustThumbnailDialog = MaterialAlertDialogBuilder(context) + .setTitle(context.getString(R.string.thumbnail)) + .setView(adjustThumbnailView) + .setIcon(R.drawable.ic_image) + .setNegativeButton(context.resources.getString(R.string.dismiss)) { _: DialogInterface?, _: Int -> } + + adjustThumbnailDialog.show() + } + + + val adjustChapters = view.findViewById(R.id.chapters) + fun calculateAdjustChaptersChangeCount() { + if (items.size == 1) { + val firstItem = items.first() + val count = listOf( + firstItem.videoPreferences.addChapters, + firstItem.videoPreferences.splitByChapters + ) + adjustChapters.createBadge(context, count.filter { it }.size) + } } - if (splitByChapters.isChecked){ - items.forEach { it.videoPreferences.addChapters = false } - addChapters.isChecked = false - addChapters.isEnabled = false - addChaptersClicked(false) + + if(items.size == 1 && items[0].downloadSections.isNotBlank()){ + items.forEach { it.videoPreferences.splitByChapters = false } } - splitByChapters.setOnClickListener { + + calculateAdjustChaptersChangeCount() + adjustChapters.setOnClickListener { + val adjustChapterView = context.layoutInflater.inflate(R.layout.video_chapter_download_preferences_dialog, null) + val addChapters = adjustChapterView.findViewById(R.id.add_chapters) + addChapters!!.isChecked = items.all { it.videoPreferences.addChapters } + addChapters.setOnClickListener{ + addChaptersClicked(addChapters.isChecked) + items.forEach { it.videoPreferences.addChapters = addChapters.isChecked } + calculateAdjustChaptersChangeCount() + } + + val splitByChapters = adjustChapterView.findViewById(R.id.split_by_chapters) + if(items.size == 1 && items[0].downloadSections.isNotBlank()){ + splitByChapters.isEnabled = false + splitByChapters.isChecked = false + }else{ + splitByChapters!!.isChecked = items.all { it.videoPreferences.splitByChapters } + } if (splitByChapters.isChecked){ - addChapters.isEnabled = false - addChapters.isChecked = false + items.forEach { it.videoPreferences.addChapters = false } addChaptersClicked(false) - }else{ - addChapters.isEnabled = true + + addChapters.isChecked = false + addChapters.isEnabled = false + } + splitByChapters.setOnClickListener { + if (splitByChapters.isChecked){ + addChapters.isEnabled = false + addChapters.isChecked = false + items.forEach { it.videoPreferences.addChapters = false } + addChaptersClicked(false) + }else{ + addChapters.isEnabled = true + } + splitByChaptersClicked(splitByChapters.isChecked) + calculateAdjustChaptersChangeCount() } - splitByChaptersClicked(splitByChapters.isChecked) - } - val saveThumbnail = view.findViewById(R.id.save_thumbnail) - saveThumbnail!!.isChecked = items.all { it.SaveThumb } - saveThumbnail.setOnClickListener { - saveThumbnailClicked(saveThumbnail.isChecked) - } + val adjustChapterDialog = MaterialAlertDialogBuilder(context) + .setTitle(context.getString(R.string.thumbnail)) + .setView(adjustChapterView) + .setIcon(R.drawable.ic_chapters) + .setNegativeButton(context.resources.getString(R.string.dismiss)) { _: DialogInterface?, _: Int -> } + adjustChapterDialog.show() + } val adjustSubtitles = view.findViewById(R.id.adjust_subtitles) fun calculateAdjustSubtitlesChangeCount() { @@ -1538,6 +1606,13 @@ object UiUtil { val adjustLiveStream = view.findViewById(R.id.adjust_live_stream) + fun calculateLiveStreamChanges() { + if (items.size == 1) { + val count = listOf(items.first().videoPreferences.waitForVideoMinutes > 0, items.first().videoPreferences.liveFromStart) + adjustLiveStream.createBadge(context, count.filter { it }.size) + } + } + calculateLiveStreamChanges() if (items.size == 1) { adjustLiveStream.setOnClickListener { val adjustLiveStreamView = context.layoutInflater.inflate(R.layout.livestream_download_preferences_dialog, null) @@ -1566,6 +1641,8 @@ object UiUtil { liveFromStartSwitch.setOnCheckedChangeListener { compoundButton, b -> liveFromStart(b) + items.forEach { it.videoPreferences.liveFromStart = b } + calculateLiveStreamChanges() } waitForVideoSwitch.setOnCheckedChangeListener { compoundButton, b -> @@ -1577,6 +1654,8 @@ object UiUtil { } waitForVideo(b, number) + items.forEach { it.videoPreferences.waitForVideoMinutes = if (b) number else 0 } + calculateLiveStreamChanges() } liveFromStartSwitch.isChecked = item.videoPreferences.liveFromStart @@ -1647,33 +1726,22 @@ object UiUtil { if(duration.isNotEmpty() && duration != "-1" && duration != "0:00"){ val downloadItem = items[0] cut.alpha = 1f - if (downloadItem.downloadSections.isNotBlank()) cut.text = downloadItem.downloadSections + if (downloadItem.downloadSections.isNotBlank()) cut.createBadge(context, downloadItem.downloadSections.count()) val cutVideoListener = object : VideoCutListener { override fun onChangeCut(list: List) { + cut.createBadge(context, list.size) if (list.isEmpty()){ cutValueChanged("") - cut.text = context.getString(R.string.cut) - - splitByChapters.isEnabled = true - splitByChapters.isChecked = downloadItem.videoPreferences.splitByChapters - if (splitByChapters.isChecked){ - addChapters.isEnabled = false - addChapters.isChecked = false - }else{ - addChapters.isEnabled = true - } }else{ var value = "" list.forEach { value += "$it;" } cutValueChanged(value) - cut.text = value.dropLast(1) - splitByChapters.isEnabled = false - splitByChapters.isChecked = false - addChapters.isEnabled = true + items.forEach { it.videoPreferences.splitByChapters = false } + calculateAdjustChaptersChangeCount() } } @@ -1856,12 +1924,15 @@ object UiUtil { val duration = downloadItem.duration if (duration.isNotEmpty() && duration != "-1" && duration != "0:00"){ cut.alpha = 1f - if (downloadItem.downloadSections.isNotBlank()) cut.text = downloadItem.downloadSections + if (downloadItem.downloadSections.isNotBlank()) { + cut.createBadge(context, downloadItem.downloadSections.count()) + } val cutVideoListener = object : VideoCutListener { override fun onChangeCut(list: List) { + cut.createBadge(context, list.size) if (list.isEmpty()){ cutValueChanged("") - cut.text = context.getString(R.string.cut) + splitByChapters.isEnabled = true splitByChapters.isChecked = downloadItem.audioPreferences.splitByChapters @@ -1871,7 +1942,6 @@ object UiUtil { value += "$it;" } cutValueChanged(value) - cut.text = value.dropLast(1) splitByChapters.isEnabled = false splitByChapters.isChecked = false diff --git a/app/src/main/java/com/deniscerri/ytdl/util/extractors/ytdlp/YTDLPUtil.kt b/app/src/main/java/com/deniscerri/ytdl/util/extractors/ytdlp/YTDLPUtil.kt index f542957f..32c11a9a 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/extractors/ytdlp/YTDLPUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/extractors/ytdlp/YTDLPUtil.kt @@ -1155,8 +1155,7 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co } if (!listOf("webm", "avi", "flv", "gif").contains(outputContainer.lowercase())) { - val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false) - if (embedThumb) { + if (downloadItem.videoPreferences.embedThumbnail) { metadataCommands.addOption("--embed-thumbnail") if (!request.toString().contains("--convert-thumbnails")) request.addOption("--convert-thumbnails", thumbnailFormat!!) } diff --git a/app/src/main/res/layout/adjust_video.xml b/app/src/main/res/layout/adjust_video.xml index 713e253b..16c3a448 100644 --- a/app/src/main/res/layout/adjust_video.xml +++ b/app/src/main/res/layout/adjust_video.xml @@ -26,31 +26,40 @@ app:singleLine="true"> + android:text="@string/thumbnail" /> + android:text="@string/chapters" /> + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> @@ -68,21 +77,6 @@ android:layout_height="wrap_content" app:singleLine="true"> - + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/video_thumbnail_download_preferences_dialog.xml b/app/src/main/res/layout/video_thumbnail_download_preferences_dialog.xml new file mode 100644 index 00000000..566a5cff --- /dev/null +++ b/app/src/main/res/layout/video_thumbnail_download_preferences_dialog.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a56bded0..8e24e1eb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -499,4 +499,5 @@ URL Regex Disable flat playlist Don\'t use --flat-playlist. Slower data fetching, but more data rich + Chapters diff --git a/app/src/main/res/xml/processing_preferences.xml b/app/src/main/res/xml/processing_preferences.xml index f89bc3e0..aaaef756 100644 --- a/app/src/main/res/xml/processing_preferences.xml +++ b/app/src/main/res/xml/processing_preferences.xml @@ -214,6 +214,14 @@ app:summary="@string/save_thumb_summary" app:title="@string/save_thumb" /> + +