lot of features, forgor to note

pull/933/head
deniscerri 10 months ago
parent 8c254c95d6
commit c7a0079737
No known key found for this signature in database
GPG Key ID: 95C43D517D830350

@ -37,60 +37,11 @@ jobs:
- name: Set current date as env variable
run: echo "date_today=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
# Create APK Debug
- name: Build apk debug project (APK)
run: ./gradlew assembleDebug
# Create APK Release
- name: Build apk release project (APK)
run: ./gradlew assemble
# Upload Artifact Build
# Noted For Output [main_project_module]/build/outputs/apk/debug/
- name: Find Debug arm64
run: echo "APK_PATH=$(find ${{ env.main_project_module }}/build/outputs/apk/debug/ -type f -name '*arm64*.apk')" >> $GITHUB_ENV
- name: Upload APK Debug arm64
uses: actions/upload-artifact@v4
with:
name: ytdlnis-autogenerated-arm64-v8a-debug
path: ${{ env.APK_PATH }}
- name: Find Debug armeabiv7
run: echo "APK_PATH=$(find ${{ env.main_project_module }}/build/outputs/apk/debug/ -type f -name '*armeabi*.apk')" >> $GITHUB_ENV
- name: Upload APK Debug armeabiv7
uses: actions/upload-artifact@v4
with:
name: ytdlnis-autogenerated-armeabi-v7a-debug
path: ${{ env.APK_PATH }}
- name: Find Debug universal
run: echo "APK_PATH=$(find ${{ env.main_project_module }}/build/outputs/apk/debug/ -type f -name '*universal*.apk')" >> $GITHUB_ENV
- name: Upload APK Debug universal
uses: actions/upload-artifact@v4
with:
name: ytdlnis-autogenerated-universal-debug
path: ${{ env.APK_PATH }}
- name: Find Debug x86
run: echo "APK_PATH=$(find ${{ env.main_project_module }}/build/outputs/apk/debug/ -type f -name '*x86-*.apk')" >> $GITHUB_ENV
- name: Upload APK Debug x86
uses: actions/upload-artifact@v4
with:
name: ytdlnis-autogenerated-x86-debug
path: ${{ env.APK_PATH }}
- name: Find Debug x86_64
run: echo "APK_PATH=$(find ${{ env.main_project_module }}/build/outputs/apk/debug/ -type f -name '*x86_64*.apk')" >> $GITHUB_ENV
- name: Upload APK Debug x86_64
uses: actions/upload-artifact@v4
with:
name: ytdlnis-autogenerated-x86_64-debug
path: ${{ env.APK_PATH }}
# Noted For Output [main_project_module]/build/outputs/apk/release/
- name: Find Release arm64
run: echo "APK_PATH=$(find ${{ env.main_project_module }}/build/outputs/apk/release/ -type f -name '*arm64*.apk')" >> $GITHUB_ENV
@ -137,13 +88,6 @@ jobs:
name: ytdlnis-autogenerated-x86_64-release
path: ${{ env.APK_PATH }}
# Noted For Output [main_project_module]/build/outputs/apk/debug/
- name: Upload APK Debug
uses: actions/upload-artifact@v4
with:
name: YTDLnis APK debug generated
path: ${{ env.main_project_module }}/build/outputs/apk/debug/
# Noted For Output [main_project_module]/build/outputs/apk/release/
- name: Upload APK Release
uses: actions/upload-artifact@v4
@ -220,5 +164,4 @@ jobs:
# prerelease: true
# files: |
# ${{ env.main_project_module }}/build/outputs/apk/release/*
# ${{ env.main_project_module }}/build/outputs/apk/debug/*

@ -374,10 +374,11 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
}
},
extraCommandsClicked = {
extraCommandsClicked = { returnValue ->
val callback = object : ExtraCommandsListener {
override fun onChangeExtraCommand(c: String) {
downloadItem.extraCommands = c
returnValue(c)
}
}

@ -591,13 +591,14 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
cutClicked = {},
cutDisabledClicked = {},
cutValueChanged = {},
extraCommandsClicked = {
extraCommandsClicked = { returnValue ->
val callback = object : ExtraCommandsListener {
override fun onChangeExtraCommand(c: String) {
items.forEach { it.extraCommands = c }
requireActivity().lifecycleScope.launch {
items.forEach { downloadViewModel.updateDownload(it) }
}
returnValue(c)
bottomSheet.dismiss()
}
}
@ -696,11 +697,12 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
CoroutineScope(Dispatchers.IO).launch { items.forEach { downloadViewModel.updateDownload(it) } }
},
alsoDownloadAsAudioClicked = {},
extraCommandsClicked = {
extraCommandsClicked = { returnValue ->
val callback = object : ExtraCommandsListener {
override fun onChangeExtraCommand(c: String) {
items.forEach { it.extraCommands = c }
CoroutineScope(Dispatchers.IO).launch { items.forEach { downloadViewModel.updateDownload(it) } }
returnValue(c)
bottomSheet.dismiss()
}
}

@ -457,10 +457,11 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
alsoDownloadAsAudioClicked = {
downloadItem.videoPreferences.alsoDownloadAsAudio = it
},
extraCommandsClicked = {
extraCommandsClicked = { returnValue ->
val callback = object : ExtraCommandsListener {
override fun onChangeExtraCommand(c: String) {
downloadItem.extraCommands = c
returnValue(c)
}
}

@ -75,14 +75,10 @@ class WebViewActivity : BaseActivity() {
}
toolbar.menu.children.firstOrNull { it.itemId == R.id.incognito }?.isChecked = incognito
toolbar.menu.children.firstOrNull { it.itemId == R.id.get_data_sync_id }?.isVisible = false
toolbar.setOnMenuItemClickListener { m : MenuItem ->
when(m.itemId) {
R.id.get_data_sync_id -> {
webView?.evaluateJavascript("ytcfg.get('DATASYNC_ID')") { id ->
UiUtil.copyToClipboard(id.replace("\"", ""), this@WebViewActivity)
}
}
R.id.incognito -> {
intent.putExtra("incognito", !incognito)
recreate()

@ -492,7 +492,7 @@ class MainSettingsFragment : PreferenceFragmentCompat() {
val builder = MaterialAlertDialogBuilder(requireContext())
builder.setTitle(getString(R.string.restore))
builder.setMessage("${getString(R.string.restore_complete)}\n $restoreDataMessage")
builder.setMessage("${getString(R.string.restore_complete)}\n$restoreDataMessage")
builder.setCancelable(false)
builder.setPositiveButton(
getString(R.string.ok)

@ -173,16 +173,24 @@ class TerminalFragment : Fragment() {
if (shortcutCount > 0){
UiUtil.showShortcuts(requireActivity(), commandTemplateViewModel,
itemSelected = {sh ->
val txt = "${input.text} $sh"
val txt = "${input.text.trim()} $sh"
input.setText(txt)
input.setSelection(input.text.length)
},
itemRemoved = {removed ->
input.setText(input.text.replace("(${Regex.escape(removed)})(?!.*\\1)".toRegex(), "").trimEnd())
input.setText(input.text.replace("(${Regex.escape(removed)})(?!.*\\1)".toRegex(), "").trim())
input.setSelection(input.text.length)
})
}
}
}
R.id.filename_template -> {
UiUtil.showFilenameTemplateDialog(requireActivity(), "") { filenameSelected ->
val txt = "${input.text.replace("-o\\s+(?:\"([^\"]+)\"|(\\S+))".toRegex(), "").trim()} -o \"$filenameSelected\""
input.setText(txt)
input.setSelection(input.text.length)
}
}
R.id.folder -> {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

@ -24,12 +24,14 @@ import android.util.TypedValue
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroupOverlay
import android.view.ViewOutlineProvider
import android.view.animation.Interpolator
import android.widget.EditText
import android.widget.ImageView
import android.widget.ScrollView
import android.widget.TextView
import androidx.annotation.OptIn
import androidx.annotation.Px
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
@ -44,8 +46,12 @@ import com.deniscerri.ytdl.database.models.DownloadItem
import com.deniscerri.ytdl.database.models.observeSources.ObserveSourcesItem
import com.deniscerri.ytdl.database.repository.DownloadRepository
import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository.EveryCategory
import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.badge.BadgeUtils
import com.google.android.material.badge.ExperimentalBadgeUtils
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.chip.Chip
import com.google.android.material.tabs.TabLayout
import com.neoutils.highlight.core.Highlight
import com.neoutils.highlight.core.scheme.TextColorScheme
@ -284,6 +290,23 @@ object Extensions {
animator.start()
}
@OptIn(ExperimentalBadgeUtils::class)
fun Chip.createBadge(context: Context, nr: Int) {
this.overlay.clear()
if (nr > 0) {
val badge = BadgeDrawable.create(context).apply {
number = nr
backgroundColor = context.getColor(R.color.white)
verticalOffset = 25
horizontalOffset =
if (nr < 10) dp(App.instance.resources, 17f)
else if (nr < 100) dp(App.instance.resources, 19f)
else dp(App.instance.resources, 22f)
}
BadgeUtils.attachBadgeDrawable(badge, this)
}
}
fun TabLayout.Tab.createBadge(nr: Int){
removeBadge()
if (nr > 0) {

@ -67,6 +67,7 @@ import com.deniscerri.ytdl.database.viewmodel.CommandTemplateViewModel
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdl.database.viewmodel.YTDLPViewModel
import com.deniscerri.ytdl.ui.downloadcard.VideoCutListener
import com.deniscerri.ytdl.util.Extensions.createBadge
import com.deniscerri.ytdl.util.Extensions.enableTextHighlight
import com.deniscerri.ytdl.util.Extensions.getMediaDuration
import com.deniscerri.ytdl.util.Extensions.toStringDuration
@ -1318,7 +1319,7 @@ object UiUtil {
recodeVideoClicked: (Boolean) -> Unit,
compatibilityModeClicked: (Boolean) -> Unit,
alsoDownloadAsAudioClicked: (Boolean) -> Unit,
extraCommandsClicked: () -> Unit,
extraCommandsClicked: (changed: (newExtraCommandString: String) -> Unit) -> Unit,
liveFromStart: (Boolean) -> Unit,
waitForVideo: (Boolean, Int) -> Unit,
){
@ -1362,6 +1363,18 @@ object UiUtil {
val adjustSubtitles = view.findViewById<Chip>(R.id.adjust_subtitles)
fun calculateAdjustSubtitlesChangeCount() {
if (items.size == 1) {
val firstItem = items.first()
val count = listOf(
firstItem.videoPreferences.embedSubs,
firstItem.videoPreferences.writeSubs,
firstItem.videoPreferences.writeAutoSubs,
)
adjustSubtitles.createBadge(context, count.filter { it }.size)
}
}
calculateAdjustSubtitlesChangeCount()
adjustSubtitles.setOnClickListener {
val adjustSubtitleView = context.layoutInflater.inflate(R.layout.subtitle_download_preferences_dialog, null)
val embedSubs = adjustSubtitleView.findViewById<MaterialSwitch>(R.id.embed_subtitles)
@ -1376,6 +1389,9 @@ object UiUtil {
embedSubs.setOnClickListener {
subtitleLanguages.isClickable = embedSubs.isChecked || saveSubtitles.isChecked
embedSubsClicked(embedSubs.isChecked)
items.forEach { it.videoPreferences.embedSubs = embedSubs.isChecked }
calculateAdjustSubtitlesChangeCount()
}
if (items.all { it.videoPreferences.writeSubs}) {
@ -1391,11 +1407,15 @@ object UiUtil {
saveSubtitles.setOnCheckedChangeListener { _, _ ->
subtitleLanguages.isClickable = embedSubs.isChecked || saveSubtitles.isChecked || saveAutoSubtitles.isChecked
saveSubtitlesClicked(saveSubtitles.isChecked)
items.forEach { it.videoPreferences.writeSubs = saveSubtitles.isChecked }
calculateAdjustSubtitlesChangeCount()
}
saveAutoSubtitles.setOnCheckedChangeListener { _, _ ->
subtitleLanguages.isClickable = embedSubs.isChecked || saveSubtitles.isChecked || saveAutoSubtitles.isChecked
saveAutoSubtitlesClicked(saveAutoSubtitles.isChecked)
items.forEach { it.videoPreferences.writeAutoSubs = saveAutoSubtitles.isChecked }
calculateAdjustSubtitlesChangeCount()
}
subtitleLanguages.isClickable = embedSubs.isChecked || saveSubtitles.isChecked
@ -1424,12 +1444,19 @@ object UiUtil {
if (items.size == 1){
val adjustAudio = view.findViewById<Chip>(R.id.adjust_audio)
fun calculateAdjustAudioChanges() {
val count = listOf(items.first().videoPreferences.removeAudio, items.first().videoPreferences.alsoDownloadAsAudio)
adjustAudio.createBadge(context, count.filter { it }.size)
}
calculateAdjustAudioChanges()
adjustAudio.setOnClickListener {
val adjustAudioView = context.layoutInflater.inflate(R.layout.audio_download_preferences_dialog, null)
adjustAudioView.findViewById<MaterialSwitch>(R.id.remove_audio).apply {
isChecked = items.first().videoPreferences.removeAudio
setOnCheckedChangeListener { _, b ->
removeAudioClicked(b)
items.first().videoPreferences.removeAudio = b
calculateAdjustAudioChanges()
}
}
@ -1437,6 +1464,8 @@ object UiUtil {
isChecked = items.first().videoPreferences.alsoDownloadAsAudio
setOnCheckedChangeListener { _, b ->
alsoDownloadAsAudioClicked(b)
items.first().videoPreferences.alsoDownloadAsAudio = b
calculateAdjustAudioChanges()
}
}
@ -1462,6 +1491,13 @@ object UiUtil {
}
val recodeVideo = view.findViewById<Chip>(R.id.recode_video)
fun calculateRecodeVideoChanges() {
if (items.size == 1) {
val count = listOf(items.first().videoPreferences.recodeVideo, items.first().videoPreferences.compatibilityMode)
recodeVideo.createBadge(context, count.filter { it }.size)
}
}
calculateRecodeVideoChanges()
recodeVideo.setOnClickListener {
val adjustVideoView = context.layoutInflater.inflate(R.layout.video_download_preferences_dialog, null)
@ -1475,6 +1511,7 @@ object UiUtil {
compatibilityModeSwitch.isChecked = false
compatibilityModeClicked(false)
recodeVideo.createBadge(context, if (isChecked) 1 else 0)
}
}
@ -1485,6 +1522,7 @@ object UiUtil {
recodeVideoSwitch.isChecked = false
recodeVideoClicked(false)
recodeVideo.createBadge(context, if (isChecked) 1 else 0)
}
}
@ -1559,6 +1597,9 @@ object UiUtil {
val sponsorBlock = view.findViewById<Chip>(R.id.sponsorblock_filters)
sponsorBlock.isEnabled = sharedPreferences.getBoolean("use_sponsorblock", true)
if (items.size == 1 && sponsorBlock.isEnabled) {
sponsorBlock.createBadge(context, items.first().videoPreferences.sponsorBlockFilters.size)
}
sponsorBlock!!.setOnClickListener {
val builder = MaterialAlertDialogBuilder(context)
builder.setTitle(context.getString(R.string.select_sponsorblock_filtering))
@ -1583,6 +1624,9 @@ object UiUtil {
builder.setPositiveButton(
context.getString(R.string.ok)
) { _: DialogInterface?, _: Int ->
if (items.size == 1) {
sponsorBlock.createBadge(context, checkedItems.filter { it }.size)
}
sponsorBlockItemsSet(values, checkedItems)
}
@ -1658,10 +1702,18 @@ object UiUtil {
}
val extraCommands = view.findViewById<Chip>(R.id.extra_commands)
if (items.size == 1) {
extraCommands.createBadge(context, if (items.first().extraCommands.isNotBlank()) 1 else 0)
}
if (sharedPreferences.getBoolean("use_extra_commands", false)){
extraCommands.visibility = View.VISIBLE
extraCommands.setOnClickListener {
extraCommandsClicked()
extraCommandsClicked { newExtraCommandString ->
items.forEach { it.extraCommands = newExtraCommandString }
if (items.size == 1) {
extraCommands.createBadge(context, if (newExtraCommandString.isNotBlank()) 1 else 0)
}
}
}
}else{
extraCommands.visibility = View.GONE
@ -1681,8 +1733,10 @@ object UiUtil {
cutClicked: (VideoCutListener) -> Unit,
cutDisabledClicked: () -> Unit,
cutValueChanged: (String) -> Unit,
extraCommandsClicked: () -> Unit
extraCommandsClicked: (changed: (newExtraCommandString: String) -> Unit) -> Unit
){
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val embedThumb = view.findViewById<Chip>(R.id.embed_thumb)
val cropThumb = view.findViewById<Chip>(R.id.crop_thumb)
@ -1751,6 +1805,10 @@ object UiUtil {
}
val sponsorBlock = view.findViewById<Chip>(R.id.sponsorblock_filters)
sponsorBlock.isEnabled = sharedPreferences.getBoolean("use_sponsorblock", true)
if (items.size == 1 && sponsorBlock.isEnabled) {
sponsorBlock.createBadge(context, items.first().videoPreferences.sponsorBlockFilters.size)
}
sponsorBlock!!.setOnClickListener {
val builder = MaterialAlertDialogBuilder(context)
builder.setTitle(context.getString(R.string.select_sponsorblock_filtering))
@ -1775,6 +1833,9 @@ object UiUtil {
builder.setPositiveButton(
context.getString(R.string.ok)
) { _: DialogInterface?, _: Int ->
if (items.size == 1) {
sponsorBlock.createBadge(context, checkedItems.filter { it }.size)
}
sponsorBlockItemsSet(values, checkedItems)
}
@ -1829,14 +1890,19 @@ object UiUtil {
}
}
val extraCommands = view.findViewById<Chip>(R.id.extra_commands)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
if (items.size == 1) {
extraCommands.createBadge(context, if (items.first().extraCommands.isNotBlank()) 1 else 0)
}
if (sharedPreferences.getBoolean("use_extra_commands", false)){
extraCommands.visibility = View.VISIBLE
extraCommands.setOnClickListener {
extraCommandsClicked()
extraCommandsClicked { newExtraCommandString ->
items.forEach { it.extraCommands = newExtraCommandString }
if (items.size == 1) {
extraCommands.createBadge(context, if (newExtraCommandString.isNotBlank()) 1 else 0)
}
}
}
}else{
extraCommands.visibility = View.GONE

@ -133,7 +133,10 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
request.setYoutubeExtractorArgs(query)
}
request.addOption("--flat-playlist")
if (!sharedPreferences.getBoolean("no_flat_playlist", false)) {
request.addOption("--flat-playlist")
}
request.addOption("--lazy-playlist")
request.addOption(if (singleItem) "-J" else "-j")
request.applyDefaultOptionsForFetchingData(if (query.isURL()) query else null)
@ -508,6 +511,7 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
if (formatProper.format_note.contains("storyboard", ignoreCase = true)) continue
formatProper.format_note = formatProper.format_note.trim()
formatProper.container = format.getString("ext")
if (formatProper.tbr == "None") formatProper.tbr = ""
if (!formatProper.tbr.isNullOrBlank()){
@ -817,9 +821,6 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
request.addOption("--socket-timeout", socketTimeout)
}
val sponsorblockURL = sharedPreferences.getString("sponsorblock_url", "")!!
if (sponsorblockURL.isNotBlank()) request.addOption("--sponsorblock-api", sponsorblockURL)
if (sharedPreferences.getBoolean("restrict_filenames", true)) request.addOption("--restrict-filenames")
if (sharedPreferences.getBoolean("force_ipv4", false)){
request.addOption("-4")
@ -1426,6 +1427,11 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
request.addOption(downloadItem.extraCommands)
}
if (request.toString().contains("sponsorblock")) {
val sponsorBlockURL = sharedPreferences.getString("sponsorblock_url", "")!!
if (sponsorBlockURL.isNotBlank()) request.addOption("--sponsorblock-api", sponsorBlockURL)
}
val cache = File(FileUtil.getCachePath(context))
cache.mkdirs()
val conf = File(cache.absolutePath + "/${System.currentTimeMillis()}${UUID.randomUUID()}.txt")

@ -118,7 +118,7 @@
android:layout_width="wrap_content"
android:visibility="gone"
android:layout_height="wrap_content"
android:text="URL Regex"
android:text="@string/url_regex"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorTertiaryContainer"
android:clickable="false"
@ -130,8 +130,7 @@
app:cornerRadius="10dp"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="HardcodedText" />
app:layout_constraintEnd_toEndOf="parent"/>
</com.google.android.material.chip.ChipGroup>

@ -51,11 +51,10 @@
android:layout_marginEnd="10dp"
android:textSize="15sp"
android:textStyle="bold"
android:text="PO Token (GVS)"
android:text="@string/potoken_gvs"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/content_gvs"
@ -97,11 +96,10 @@
android:layout_marginEnd="10dp"
android:textSize="15sp"
android:textStyle="bold"
android:text="PO Token (Player)"
android:text="@string/potoken_player"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/content_player"
@ -143,11 +141,10 @@
android:layout_marginEnd="10dp"
android:textSize="15sp"
android:textStyle="bold"
android:text="PO Token (Subs)"
android:text="@string/potoken_subs"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/content_subs"
@ -189,11 +186,10 @@
android:layout_marginEnd="10dp"
android:textSize="15sp"
android:textStyle="bold"
android:text="Visitor Data"
android:text="@string/visitor_data"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/content_visitordata"

@ -131,8 +131,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/potoken"
tools:ignore="HardcodedText" />
android:text="@string/potoken"/>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/po_token_gvs"

@ -11,6 +11,10 @@
android:icon="@drawable/ic_shortcut"
app:showAsAction="ifRoom"
android:id="@+id/shortcuts"/>
<item android:title="@string/file_name_template"
android:icon="@drawable/ic_edit"
app:showAsAction="ifRoom"
android:id="@+id/filename_template"/>
<item
android:id="@+id/folder"
android:title="@string/command_directory"

@ -5,8 +5,7 @@
<item
android:id="@+id/get_data_sync_id"
android:title="Get Data Sync ID"
tools:ignore="HardcodedText" />
android:title="@string/get_data_sync_id" />
<item
android:id="@+id/incognito"
@ -17,7 +16,7 @@
<item
android:id="@+id/desktop"
android:title="Desktop"
android:title="@string/desktop"
android:checkable="true"
app:showAsAction="never" />

@ -490,4 +490,13 @@
<string name="smallest">Smallest</string>
<string name="largest">Largest</string>
<string name="no_prefer_drc_audio">Don\'t prefer DRC Audio</string>
<string name="potoken_gvs">PO Token (GVS)</string>
<string name="potoken_player">PO Token (Player)</string>
<string name="potoken_subs">PO Token (Subs)</string>
<string name="visitor_data">Visitor Data</string>
<string name="get_data_sync_id">Visitor Data</string>
<string name="desktop">Desktop</string>
<string name="url_regex">URL Regex</string>
<string name="disable_flat_playlist">Disable flat playlist</string>
<string name="disable_flat_playlist_summary">Don\'t use --flat-playlist. Slower data fetching, but more data rich</string>
</resources>

@ -79,6 +79,15 @@
android:title="@string/disable_write_info_json" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/misc">
<SwitchPreferenceCompat
android:widgetLayout="@layout/preferece_material_switch"
android:icon="@drawable/ic_search"
android:key="no_flat_playlist"
android:summary="@string/disable_flat_playlist_summary"
android:title="@string/disable_flat_playlist" />
</PreferenceCategory>
<Preference
app:allowDividerAbove="true"
app:icon="@drawable/baseline_reset_tv_24"

Loading…
Cancel
Save