diff --git a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/FormatViewModel.kt b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/FormatViewModel.kt index 87e0bfb4..cbab3c80 100644 --- a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/FormatViewModel.kt +++ b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/FormatViewModel.kt @@ -229,7 +229,7 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a } - fun getFormatsForItemsBasedOnFormat(item: Format, audioFormats: List? = null) : MutableList { + fun getFormatsForItemsBasedOnFormat(item: Format?, audioFormats: List? = null) : MutableList { val formatsToReturn = mutableListOf() val f = if (genericAudioFormats.contains(item) || genericVideoFormats.contains(item)) item else null @@ -238,7 +238,7 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a MultipleItemFormatTuple( it.url, FormatTuple( - f ?: it.allFormats.firstOrNull { af -> af.format_id == item.format_id }, + f ?: it.allFormats.firstOrNull { af -> af.format_id == item?.format_id }, audioFormats?.map { sa -> it.allFormats.first { a -> a.format_id == sa.format_id } }?.ifEmpty { null } 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 d2513820..be87fbaf 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 @@ -411,7 +411,7 @@ class FormatSelectionBottomSheetDialog( listOf(downloadViewModel.getFormat(formats.filter { it.label == null }.map { it.format!! }, DownloadType.audio)) })) }else{ - val res = formatViewModel.getFormatsForItemsBasedOnFormat(adapter.selectedVideoFormat!!, adapter.selectedAudioFormats) + val res = formatViewModel.getFormatsForItemsBasedOnFormat(adapter.selectedVideoFormat, adapter.selectedAudioFormats) multipleFormatsListener.onFormatClick(res) } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/GenerateYoutubePoTokensFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/GenerateYoutubePoTokensFragment.kt index 3ab4c8c7..40cfa663 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/GenerateYoutubePoTokensFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/GenerateYoutubePoTokensFragment.kt @@ -216,7 +216,7 @@ class GenerateYoutubePoTokensFragment : Fragment() { regenerateBtn.isEnabled = false editText.doOnTextChanged { text, start, before, count -> - regenerateBtn.isEnabled = editText.text.toString().isYoutubeURL() + regenerateBtn.isEnabled = editText.text.toString().getIDFromYoutubeURL() != null } regenerateBtn.setOnClickListener { diff --git a/app/src/main/java/com/deniscerri/ytdl/util/FileUtil.kt b/app/src/main/java/com/deniscerri/ytdl/util/FileUtil.kt index a3067e56..c3b1ff73 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/FileUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/FileUtil.kt @@ -307,7 +307,7 @@ object FileUtil { return if (preference.isNullOrBlank() || !File(formatPath(preference)).canWrite()) { getDefaultApplicationPath() + "/Backups" }else { - formatPath(preference) + preference } } diff --git a/app/src/main/java/com/deniscerri/ytdl/work/ObserveSourceWorker.kt b/app/src/main/java/com/deniscerri/ytdl/work/ObserveSourceWorker.kt index 842d38c6..41689a7a 100644 --- a/app/src/main/java/com/deniscerri/ytdl/work/ObserveSourceWorker.kt +++ b/app/src/main/java/com/deniscerri/ytdl/work/ObserveSourceWorker.kt @@ -69,7 +69,7 @@ class ObserveSourceWorker( resultRepository.getResultsFromSource(item.url, resetResults = false, addToResults = false, singleItem = false) }.onFailure { Log.e("observe", it.toString()) - }.getOrElse { listOf() } + }.getOrElse { listOf() }.reversed() //delete downloaded items not present in source if sync is enabled if (item.syncWithSource && item.alreadyProcessedLinks.isNotEmpty()){ @@ -88,31 +88,30 @@ class ObserveSourceWorker( val toProcess = mutableListOf() //filter what results need to be downloaded, ignored for (result in list) { + val url = result.url + if (item.ignoredLinks.contains(result.url)) { continue } - // if first run and get only new items, ignore - if (item.getOnlyNewUploads && item.runCount == 0) { + val history = historyRepo.getAllByURLAndType(result.url, item.downloadItemTemplate.type) + val hasHistory = history.isNotEmpty() + val hasExistingFile = history.any { h -> h.downloadPath.any { path -> FileUtil.exists(path) }} + + // First-run "only new uploads" — ONLY if truly new (no history exists) + if (item.getOnlyNewUploads && item.runCount == 0 && !hasHistory) { item.ignoredLinks.add(result.url) continue } - val history = historyRepo.getAllByURLAndType(result.url, item.downloadItemTemplate.type) - //if history is empty or all history items are deleted, add for retry - if (item.retryMissingDownloads && (history.isEmpty() || history.none { hi -> hi.downloadPath.any { path -> FileUtil.exists(path) } })) { + + // Retry missing downloads overrides everything except ignoredLinks + if (item.retryMissingDownloads && (!hasHistory || !hasExistingFile)) { toProcess.add(result) continue } - if (item.alreadyProcessedLinks.isEmpty()) { - if (history.isEmpty()) { - toProcess.add(result) - continue - } - } - - if (item.alreadyProcessedLinks.contains(result.url)) { + if (item.alreadyProcessedLinks.contains(url)) { continue }