From 0f6d8d6494a47704700e152e529e6ef2e406c92b Mon Sep 17 00:00:00 2001 From: deniscerri <64997243+deniscerri@users.noreply.github.com> Date: Tue, 26 Nov 2024 22:24:14 +0100 Subject: [PATCH] 1.8.1 fr this time --- CHANGELOG.md | 3 +- .../viewmodel/ObserveSourcesViewModel.kt | 14 +- .../ytdl/ui/adapter/ObserveSourcesAdapter.kt | 30 +++-- .../ObserveSourcesBottomSheetDialog.kt | 2 +- .../ytdl/ui/more/ObserveSourcesFragment.kt | 12 +- .../ui/more/settings/MainSettingsFragment.kt | 11 +- .../more/settings/UpdateSettingsFragment.kt | 2 +- .../ytdl/util/extractors/YTDLPUtil.kt | 19 ++- .../main/res/drawable/baseline_stop_24.xml | 5 + .../main/res/layout/observe_sources_item.xml | 127 ++++++++++-------- .../main/res/layout/ytdlp_sources_list.xml | 2 +- app/src/main/res/values-ar/strings.xml | 4 +- app/src/main/res/values-az/strings.xml | 4 +- app/src/main/res/values-es/strings.xml | 4 +- app/src/main/res/values-pl/strings.xml | 4 +- app/src/main/res/values-pt-rBR/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 4 +- app/src/main/res/values-sq-rAL/strings.xml | 4 +- app/src/main/res/values-sr/strings.xml | 4 +- app/src/main/res/values-ta/strings.xml | 4 +- app/src/main/res/values-uk/strings.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 4 +- app/src/main/res/values/strings.xml | 4 +- 24 files changed, 162 insertions(+), 113 deletions(-) create mode 100644 app/src/main/res/drawable/baseline_stop_24.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 3942c647..ae9f611d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,8 @@ - Made the app remember the last used scheduled time so it can suggest you that time for the next download - #618, made all preferences with a description show their values - Fixed bug that prevented app from loading all urls from text file -- Added ability to write info json when downloading so when you resume an +- Added ability to stop an observed source but not delete it +- ## Custom yt-dlp source diff --git a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/ObserveSourcesViewModel.kt b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/ObserveSourcesViewModel.kt index 681a6e77..dcca4402 100644 --- a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/ObserveSourcesViewModel.kt +++ b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/ObserveSourcesViewModel.kt @@ -12,8 +12,6 @@ import androidx.work.Data import androidx.work.ExistingWorkPolicy import androidx.work.NetworkType import androidx.work.OneTimeWorkRequestBuilder -import androidx.work.PeriodicWorkRequest -import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager import com.deniscerri.ytdl.database.DBManager import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem @@ -50,7 +48,7 @@ class ObserveSourcesViewModel(private val application: Application) : AndroidVie return repository.getByID(id) } - suspend fun insert(item: ObserveSourcesItem) : Long { + suspend fun insertUpdate(item: ObserveSourcesItem) : Long { if (item.id > 0) { repository.update(item) observeTask(item) @@ -63,6 +61,12 @@ class ObserveSourcesViewModel(private val application: Application) : AndroidVie return id } + suspend fun stopObserving(item: ObserveSourcesItem) { + item.status = ObserveSourcesRepository.SourceStatus.STOPPED + repository.update(item) + cancelObservationTaskByID(item.id) + } + fun delete(item: ObserveSourcesItem) = viewModelScope.launch(Dispatchers.IO) { runCatching { cancelObservationTaskByID(item.id) } repository.delete(item) @@ -81,7 +85,7 @@ class ObserveSourcesViewModel(private val application: Application) : AndroidVie } private fun cancelObservationTaskByID(id: Long){ - workManager.cancelAllWorkByTag(id.toString()) + workManager.cancelAllWorkByTag("observation_$id") } @@ -136,7 +140,7 @@ class ObserveSourcesViewModel(private val application: Application) : AndroidVie val workRequest = OneTimeWorkRequestBuilder() .addTag("observeSources") - .addTag(it.id.toString()) + .addTag("observation_${it.id}") .setConstraints(workConstraints.build()) .setInitialDelay(timeInMillis - System.currentTimeMillis(), TimeUnit.MILLISECONDS) .setInputData(Data.Builder().putLong("id", it.id).build()) diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/adapter/ObserveSourcesAdapter.kt b/app/src/main/java/com/deniscerri/ytdl/ui/adapter/ObserveSourcesAdapter.kt index 6331d24c..c7f57684 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/adapter/ObserveSourcesAdapter.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/adapter/ObserveSourcesAdapter.kt @@ -17,6 +17,7 @@ import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository import com.deniscerri.ytdl.util.Extensions.calculateNextTimeForObserving import com.deniscerri.ytdl.util.Extensions.popup +import com.google.android.material.button.MaterialButton import com.google.android.material.card.MaterialCardView import com.google.android.material.chip.Chip import com.google.android.material.floatingactionbutton.FloatingActionButton @@ -93,29 +94,35 @@ class ObserveSourcesAdapter(onItemClickListener: OnItemClickListener, activity: progressBar.isVisible = false // BUTTON ---------------------------------- - val btn = card.findViewById(R.id.search) - btn.isEnabled = true + val searchBtn = card.findViewById(R.id.search) + val pauseBtn = card.findViewById(R.id.pause_resume) + searchBtn.isEnabled = true + pauseBtn.isEnabled = true if (item.status == ObserveSourcesRepository.SourceStatus.STOPPED){ info.isVisible = false - checkMissing.isVisible = false + searchBtn.isVisible = false - btn.setImageResource(R.drawable.exomedia_ic_play_arrow_white) - btn.setOnClickListener { - btn.isEnabled = false - progressBar.isVisible = true - progressBar.animate() + pauseBtn.setIconResource(R.drawable.exomedia_ic_play_arrow_white) + pauseBtn.setOnClickListener { + pauseBtn.isEnabled = false onItemClickListener.onItemStart(item, position) } }else{ info.isVisible = true + searchBtn.isVisible = true - btn.setImageResource(R.drawable.ic_search) - btn.setOnClickListener { - btn.isEnabled = false + searchBtn.setOnClickListener { + searchBtn.isEnabled = false progressBar.isVisible = true progressBar.animate() onItemClickListener.onItemSearch(item) } + + pauseBtn.setIconResource(R.drawable.exomedia_ic_pause_white) + pauseBtn.setOnClickListener { + pauseBtn.isEnabled = false + onItemClickListener.onItemPaused(item, position) + } } @@ -132,6 +139,7 @@ class ObserveSourcesAdapter(onItemClickListener: OnItemClickListener, activity: fun onItemSearch(item: ObserveSourcesItem) fun onItemStart(item: ObserveSourcesItem, position: Int) + fun onItemPaused(item: ObserveSourcesItem, position: Int) fun onItemClick(item: ObserveSourcesItem) fun onDelete(item: ObserveSourcesItem) } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/ObserveSourcesBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/ObserveSourcesBottomSheetDialog.kt index 601aad90..69f19ebb 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/ObserveSourcesBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/ObserveSourcesBottomSheetDialog.kt @@ -535,7 +535,7 @@ class ObserveSourcesBottomSheetDialog : BottomSheetDialogFragment() { ) withContext(Dispatchers.IO){ - observeSourcesViewModel.insert(observeItem) + observeSourcesViewModel.insertUpdate(observeItem) } dismiss() } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/ObserveSourcesFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/ObserveSourcesFragment.kt index 92ecf20c..d1e263c5 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/ObserveSourcesFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/ObserveSourcesFragment.kt @@ -2,7 +2,6 @@ package com.deniscerri.ytdl.ui.more import android.annotation.SuppressLint import android.content.DialogInterface -import android.content.Intent import android.content.SharedPreferences import android.os.Bundle import android.view.LayoutInflater @@ -153,13 +152,22 @@ class ObserveSourcesFragment : Fragment(), ObserveSourcesAdapter.OnItemClickList withContext(Dispatchers.IO){ item.status = ObserveSourcesRepository.SourceStatus.ACTIVE item.runCount = 0 - observeSourcesViewModel.insert(item) + observeSourcesViewModel.insertUpdate(item) } listAdapter.notifyItemChanged(position) } } + override fun onItemPaused(item: ObserveSourcesItem, position: Int) { + lifecycleScope.launch { + withContext(Dispatchers.IO){ + observeSourcesViewModel.stopObserving(item) + } + listAdapter.notifyItemChanged(position) + } + } + override fun onItemClick(item: ObserveSourcesItem) { showDialog(item.url) } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/MainSettingsFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/MainSettingsFragment.kt index 447a9728..a856e711 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/MainSettingsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/MainSettingsFragment.kt @@ -5,7 +5,6 @@ import android.app.Activity import android.content.DialogInterface import android.content.Intent import android.content.SharedPreferences -import android.net.Uri import android.os.Build import android.os.Bundle import android.os.Environment @@ -13,12 +12,9 @@ import android.util.LayoutDirection import android.util.Log import android.view.Gravity import android.view.View -import android.view.inputmethod.InputMethodManager -import android.widget.EditText import android.widget.TextView import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AlertDialog -import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.core.content.edit import androidx.core.os.LocaleListCompat @@ -31,7 +27,6 @@ import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager import androidx.work.WorkInfo import androidx.work.WorkManager -import com.afollestad.materialdialogs.utils.MDUtil.getStringArray import com.deniscerri.ytdl.BuildConfig import com.deniscerri.ytdl.MainActivity import com.deniscerri.ytdl.R @@ -52,17 +47,13 @@ import com.deniscerri.ytdl.database.viewmodel.ResultViewModel import com.deniscerri.ytdl.util.FileUtil import com.deniscerri.ytdl.util.UiUtil import com.deniscerri.ytdl.util.UpdateUtil -import com.google.android.material.chip.Chip -import com.google.android.material.chip.ChipGroup import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar -import com.google.android.material.textfield.TextInputLayout import com.google.gson.Gson import com.google.gson.GsonBuilder import com.google.gson.JsonArray import com.google.gson.JsonObject import com.google.gson.JsonParser -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -754,7 +745,7 @@ class MainSettingsFragment : PreferenceFragmentCompat() { withContext(Dispatchers.IO){ if (resetData) observeSourcesViewModel.deleteAll() data.observeSources!!.forEach { - observeSourcesViewModel.insert(it) + observeSourcesViewModel.insertUpdate(it) } } } diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/UpdateSettingsFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/UpdateSettingsFragment.kt index e6b33580..0bca0902 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/UpdateSettingsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/UpdateSettingsFragment.kt @@ -134,7 +134,7 @@ class UpdateSettingsFragment : BaseSettingsFragment() { private fun setYTDLPVersion() { lifecycleScope.launch { - ytdlVersion!!.summary = "" + ytdlVersion!!.summary = getString(R.string.loading) val version = withContext(Dispatchers.IO){ ytdlpUtil.getVersion() } 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 a70cfcf5..8b51ff3b 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 @@ -165,7 +165,7 @@ class YTDLPUtil(private val context: Context) { if (url.isYoutubeURL()) { authorTags.addAll(0, listOf("artists", "artist")) } - var author = jsonObject.getStringByAny(*authorTags.map { it }.toTypedArray()) + var author = jsonObject.getStringByAny(*authorTags.map { it }.toTypedArray()).removeSuffix(" - Topic") var duration = jsonObject.getIntByAny("duration").toString() if (duration != "-1"){ duration = jsonObject.getInt("duration").toStringDuration(Locale.US) @@ -447,8 +447,9 @@ class YTDLPUtil(private val context: Context) { } val formatProper = Gson().fromJson(format.toString(), Format::class.java) - if (formatProper.format_note == null) continue + if (formatProper.format_note == null) formatProper.format_note = "" + val resolution = format.getString("resolution") if (format.has("format_note")){ if (!formatProper!!.format_note.contains("audio only", true)) { formatProper.format_note = format.getString("format_note") @@ -457,12 +458,18 @@ class YTDLPUtil(private val context: Context) { formatProper.format_note = format.getString("format_note").uppercase().removeSuffix("AUDIO") + " AUDIO" } } + + if (!resolution.isNullOrBlank() && resolution != "audio only") { + formatProper.format_note = "${formatProper.format_note} (${resolution})" + } } - if (formatProper.format_note == "storyboard") continue + + if (formatProper.format_note.contains("storyboard", ignoreCase = true)) continue + formatProper.container = format.getString("ext") if (formatProper.tbr == "None") formatProper.tbr = "" if (!formatProper.tbr.isNullOrBlank()){ - formatProper.tbr = formatProper.tbr + "k" + formatProper.tbr += "k" } if(formatProper.vcodec.isNullOrEmpty() || formatProper.vcodec == "null"){ @@ -1173,9 +1180,13 @@ class YTDLPUtil(private val context: Context) { } val lang = Locale.getDefault().language + val langTag = Locale.getDefault().toLanguageTag() if (context.getStringArray(R.array.subtitle_langs).contains(lang)) { extractorArgs.add("lang=$lang") } + if (context.getStringArray(R.array.subtitle_langs).contains(langTag)) { + extractorArgs.add("lang=$langTag") + } if (poToken.isNotBlank()) { extractorArgs.add("po_token=web+$poToken") } diff --git a/app/src/main/res/drawable/baseline_stop_24.xml b/app/src/main/res/drawable/baseline_stop_24.xml new file mode 100644 index 00000000..1dbd815e --- /dev/null +++ b/app/src/main/res/drawable/baseline_stop_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/observe_sources_item.xml b/app/src/main/res/layout/observe_sources_item.xml index 10ff39ca..88014b94 100644 --- a/app/src/main/res/layout/observe_sources_item.xml +++ b/app/src/main/res/layout/observe_sources_item.xml @@ -10,7 +10,7 @@ @@ -43,48 +43,43 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + app:layout_constraintTop_toTopOf="parent" /> - - - - - +