subdub toggle | regex fix (yomiroll) | idk I forgot
This commit is contained in:
parent
4a5eab13c9
commit
49b3c33fbc
8 changed files with 134 additions and 17 deletions
|
@ -10,8 +10,8 @@ class AnimeNameAdapter {
|
||||||
"(episode|ep|e)[\\s:.\\-]*([\\d]+\\.?[\\d]*)[\\s:.\\-]*\\(?\\s*(sub|subbed|dub|dubbed)*\\s*\\)?\\s*"
|
"(episode|ep|e)[\\s:.\\-]*([\\d]+\\.?[\\d]*)[\\s:.\\-]*\\(?\\s*(sub|subbed|dub|dubbed)*\\s*\\)?\\s*"
|
||||||
const val failedEpisodeNumberRegex =
|
const val failedEpisodeNumberRegex =
|
||||||
"(?<!part\\s)\\b(\\d+)\\b"
|
"(?<!part\\s)\\b(\\d+)\\b"
|
||||||
const val seasonRegex = "\\s+(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
|
const val seasonRegex = "(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
|
||||||
const val subdubRegex = "^(soft)?[\\s-]*(sub|dub|mixed)(bed)?\\s*$"
|
const val subdubRegex = "^(soft)?[\\s-]*(sub|dub|mixed)(bed|s)?\\s*$"
|
||||||
|
|
||||||
fun setSubDub(text: String, typeToSetTo: SubDubType): String? {
|
fun setSubDub(text: String, typeToSetTo: SubDubType): String? {
|
||||||
val subdubPattern: Pattern = Pattern.compile(subdubRegex, Pattern.CASE_INSENSITIVE)
|
val subdubPattern: Pattern = Pattern.compile(subdubRegex, Pattern.CASE_INSENSITIVE)
|
||||||
|
@ -25,6 +25,7 @@ class AnimeNameAdapter {
|
||||||
val toggled = when (typeToSetTo) {
|
val toggled = when (typeToSetTo) {
|
||||||
SubDubType.SUB -> "sub"
|
SubDubType.SUB -> "sub"
|
||||||
SubDubType.DUB -> "dub"
|
SubDubType.DUB -> "dub"
|
||||||
|
SubDubType.NULL -> ""
|
||||||
}
|
}
|
||||||
val toggledCasePreserved =
|
val toggledCasePreserved =
|
||||||
if (subdub?.get(0)?.isUpperCase() == true || soft?.get(0)
|
if (subdub?.get(0)?.isUpperCase() == true || soft?.get(0)
|
||||||
|
@ -41,8 +42,24 @@ class AnimeNameAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getSubDub(text: String): SubDubType {
|
||||||
|
val subdubPattern: Pattern = Pattern.compile(subdubRegex, Pattern.CASE_INSENSITIVE)
|
||||||
|
val subdubMatcher: Matcher = subdubPattern.matcher(text)
|
||||||
|
|
||||||
|
return if (subdubMatcher.find()) {
|
||||||
|
val subdub = subdubMatcher.group(2)?.lowercase(Locale.ROOT)
|
||||||
|
when (subdub) {
|
||||||
|
"sub" -> SubDubType.SUB
|
||||||
|
"dub" -> SubDubType.DUB
|
||||||
|
else -> SubDubType.NULL
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SubDubType.NULL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum class SubDubType {
|
enum class SubDubType {
|
||||||
SUB, DUB
|
SUB, DUB, NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findSeasonNumber(text: String): Int? {
|
fun findSeasonNumber(text: String): Int? {
|
||||||
|
|
|
@ -113,7 +113,7 @@ class AnimeWatchAdapter(
|
||||||
binding.animeSourceTitle.text = showUserText
|
binding.animeSourceTitle.text = showUserText
|
||||||
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
|
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
|
||||||
binding.animeSourceDubbedCont.visibility =
|
binding.animeSourceDubbedCont.visibility =
|
||||||
if (isDubAvailableSeparately) View.VISIBLE else View.GONE
|
if (isDubAvailableSeparately()) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ class AnimeWatchAdapter(
|
||||||
binding.animeSourceDubbed.isChecked = selectDub
|
binding.animeSourceDubbed.isChecked = selectDub
|
||||||
changing = false
|
changing = false
|
||||||
binding.animeSourceDubbedCont.visibility =
|
binding.animeSourceDubbedCont.visibility =
|
||||||
if (isDubAvailableSeparately) View.VISIBLE else View.GONE
|
if (isDubAvailableSeparately()) View.VISIBLE else View.GONE
|
||||||
source = i
|
source = i
|
||||||
setLanguageList(0, i)
|
setLanguageList(0, i)
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ class AnimeWatchAdapter(
|
||||||
binding.animeSourceDubbed.isChecked = selectDub
|
binding.animeSourceDubbed.isChecked = selectDub
|
||||||
changing = false
|
changing = false
|
||||||
binding.animeSourceDubbedCont.visibility =
|
binding.animeSourceDubbedCont.visibility =
|
||||||
if (isDubAvailableSeparately) View.VISIBLE else View.GONE
|
if (isDubAvailableSeparately()) View.VISIBLE else View.GONE
|
||||||
setLanguageList(i, source)
|
setLanguageList(i, source)
|
||||||
}
|
}
|
||||||
subscribeButton(false)
|
subscribeButton(false)
|
||||||
|
|
|
@ -840,7 +840,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
||||||
isFastForwarding = true
|
isFastForwarding = true
|
||||||
exoPlayer.setPlaybackSpeed(exoPlayer.playbackParameters.speed * 2)
|
exoPlayer.setPlaybackSpeed(exoPlayer.playbackParameters.speed * 2)
|
||||||
fastForward.visibility = View.VISIBLE
|
fastForward.visibility = View.VISIBLE
|
||||||
fastForward.text = ("${exoPlayer.playbackParameters.speed}x")
|
fastForward.text = "${exoPlayer.playbackParameters.speed}x"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopFastForward() {
|
fun stopFastForward() {
|
||||||
|
@ -1286,7 +1286,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
||||||
}
|
}
|
||||||
println("sub: $sub")
|
println("sub: $sub")
|
||||||
} else {
|
} else {
|
||||||
val subUri = Uri.parse((subtitle!!.file.url))
|
val subUri = Uri.parse(subtitle!!.file.url)
|
||||||
sub = MediaItem.SubtitleConfiguration
|
sub = MediaItem.SubtitleConfiguration
|
||||||
.Builder(subUri)
|
.Builder(subUri)
|
||||||
.setSelectionFlags(C.SELECTION_FLAG_FORCED)
|
.setSelectionFlags(C.SELECTION_FLAG_FORCED)
|
||||||
|
|
|
@ -716,7 +716,7 @@ class MangaReaderActivity : AppCompatActivity() {
|
||||||
val y = event.rawY.toInt()
|
val y = event.rawY.toInt()
|
||||||
val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
||||||
//if in the 1st 1/5th of the screen width, left and lower than 1/5th of the screen height, left
|
//if in the 1st 1/5th of the screen width, left and lower than 1/5th of the screen height, left
|
||||||
if (screenWidth / 5 in (x + 1)..<y) {
|
if (screenWidth / 5 in x + 1..<y) {
|
||||||
pressLocation = if (settings.default.direction == RIGHT_TO_LEFT) {
|
pressLocation = if (settings.default.direction == RIGHT_TO_LEFT) {
|
||||||
pressPos.RIGHT
|
pressPos.RIGHT
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -163,7 +163,7 @@ abstract class AnimeParser : BaseParser() {
|
||||||
*
|
*
|
||||||
* **NOTE : do not forget to override `search` if the site does not support only dub search**
|
* **NOTE : do not forget to override `search` if the site does not support only dub search**
|
||||||
* **/
|
* **/
|
||||||
open val isDubAvailableSeparately by Delegates.notNull<Boolean>()
|
open fun isDubAvailableSeparately(sourceLang: Int? = null): Boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The app changes this, depending on user's choice.
|
* The app changes this, depending on user's choice.
|
||||||
|
@ -182,7 +182,7 @@ abstract class AnimeParser : BaseParser() {
|
||||||
* **/
|
* **/
|
||||||
override suspend fun loadSavedShowResponse(mediaId: Int): ShowResponse? {
|
override suspend fun loadSavedShowResponse(mediaId: Int): ShowResponse? {
|
||||||
checkIfVariablesAreEmpty()
|
checkIfVariablesAreEmpty()
|
||||||
val dub = if (isDubAvailableSeparately) "_${if (selectDub) "dub" else "sub"}" else ""
|
val dub = if (isDubAvailableSeparately()) "_${if (selectDub) "dub" else "sub"}" else ""
|
||||||
var loaded = loadData<ShowResponse>("${saveName}${dub}_$mediaId")
|
var loaded = loadData<ShowResponse>("${saveName}${dub}_$mediaId")
|
||||||
if (loaded == null && malSyncBackupName.isNotEmpty())
|
if (loaded == null && malSyncBackupName.isNotEmpty())
|
||||||
loaded = MalSyncBackup.get(mediaId, malSyncBackupName, selectDub)
|
loaded = MalSyncBackup.get(mediaId, malSyncBackupName, selectDub)
|
||||||
|
@ -200,7 +200,7 @@ abstract class AnimeParser : BaseParser() {
|
||||||
)
|
)
|
||||||
} : ${response.name}"
|
} : ${response.name}"
|
||||||
)
|
)
|
||||||
val dub = if (isDubAvailableSeparately) "_${if (selectDub) "dub" else "sub"}" else ""
|
val dub = if (isDubAvailableSeparately()) "_${if (selectDub) "dub" else "sub"}" else ""
|
||||||
saveData("${saveName}${dub}_$mediaId", response)
|
saveData("${saveName}${dub}_$mediaId", response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,8 +209,6 @@ abstract class AnimeParser : BaseParser() {
|
||||||
class EmptyAnimeParser : AnimeParser() {
|
class EmptyAnimeParser : AnimeParser() {
|
||||||
override val name: String = "None"
|
override val name: String = "None"
|
||||||
override val saveName: String = "None"
|
override val saveName: String = "None"
|
||||||
|
|
||||||
override val isDubAvailableSeparately: Boolean = false
|
|
||||||
override suspend fun loadEpisodes(
|
override suspend fun loadEpisodes(
|
||||||
animeLink: String,
|
animeLink: String,
|
||||||
extra: Map<String, String>?,
|
extra: Map<String, String>?,
|
||||||
|
|
|
@ -10,12 +10,14 @@ import android.os.Build
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import ani.dantotsu.FileUrl
|
import ani.dantotsu.FileUrl
|
||||||
|
import ani.dantotsu.currContext
|
||||||
import ani.dantotsu.logger
|
import ani.dantotsu.logger
|
||||||
import ani.dantotsu.media.anime.AnimeNameAdapter
|
import ani.dantotsu.media.anime.AnimeNameAdapter
|
||||||
import ani.dantotsu.media.manga.ImageData
|
import ani.dantotsu.media.manga.ImageData
|
||||||
import ani.dantotsu.media.manga.MangaCache
|
import ani.dantotsu.media.manga.MangaCache
|
||||||
import ani.dantotsu.snackString
|
import ani.dantotsu.snackString
|
||||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||||
|
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||||
|
@ -26,6 +28,7 @@ import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.network.interceptor.CloudflareBypassException
|
import eu.kanade.tachiyomi.network.interceptor.CloudflareBypassException
|
||||||
|
import eu.kanade.tachiyomi.source.anime.getPreferenceKey
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
@ -71,8 +74,63 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
||||||
override val name = extension.name
|
override val name = extension.name
|
||||||
override val saveName = extension.name
|
override val saveName = extension.name
|
||||||
override val hostUrl = extension.sources.first().name
|
override val hostUrl = extension.sources.first().name
|
||||||
override val isDubAvailableSeparately = false
|
|
||||||
override val isNSFW = extension.isNsfw
|
override val isNSFW = extension.isNsfw
|
||||||
|
override var selectDub: Boolean
|
||||||
|
get() = getDub()
|
||||||
|
set(value) {
|
||||||
|
setDub(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDub(): Boolean {
|
||||||
|
val configurableSource = extension.sources[sourceLanguage] as? ConfigurableAnimeSource
|
||||||
|
?: return false
|
||||||
|
currContext()?.let { context ->
|
||||||
|
val sharedPreferences =
|
||||||
|
context.getSharedPreferences(configurableSource.getPreferenceKey(), Context.MODE_PRIVATE)
|
||||||
|
sharedPreferences.all.filterValues { AnimeNameAdapter.getSubDub(it.toString()) != AnimeNameAdapter.Companion.SubDubType.NULL }
|
||||||
|
.forEach { value ->
|
||||||
|
return when (AnimeNameAdapter.getSubDub(value.value.toString())) {
|
||||||
|
AnimeNameAdapter.Companion.SubDubType.SUB -> false
|
||||||
|
AnimeNameAdapter.Companion.SubDubType.DUB -> true
|
||||||
|
AnimeNameAdapter.Companion.SubDubType.NULL -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setDub(setDub: Boolean) {
|
||||||
|
val configurableSource = extension.sources[sourceLanguage] as? ConfigurableAnimeSource
|
||||||
|
?: return
|
||||||
|
val type = when (setDub) {
|
||||||
|
true -> AnimeNameAdapter.Companion.SubDubType.DUB
|
||||||
|
false -> AnimeNameAdapter.Companion.SubDubType.SUB
|
||||||
|
}
|
||||||
|
currContext()?.let { context ->
|
||||||
|
val sharedPreferences =
|
||||||
|
context.getSharedPreferences(configurableSource.getPreferenceKey(), Context.MODE_PRIVATE)
|
||||||
|
sharedPreferences.all.filterValues { AnimeNameAdapter.getSubDub(it.toString()) != AnimeNameAdapter.Companion.SubDubType.NULL }
|
||||||
|
.forEach { value ->
|
||||||
|
val setValue = AnimeNameAdapter.setSubDub(value.value.toString(), type)
|
||||||
|
if (setValue != null) {
|
||||||
|
sharedPreferences.edit().putString(value.key, setValue).apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun isDubAvailableSeparately(sourceLang: Int?): Boolean {
|
||||||
|
val configurableSource = extension.sources[sourceLanguage] as? ConfigurableAnimeSource
|
||||||
|
?: return false
|
||||||
|
currContext()?.let { context ->
|
||||||
|
logger("isDubAvailableSeparately: ${configurableSource.getPreferenceKey()}")
|
||||||
|
val sharedPreferences =
|
||||||
|
context.getSharedPreferences(configurableSource.getPreferenceKey(), Context.MODE_PRIVATE)
|
||||||
|
sharedPreferences.all.filterValues { AnimeNameAdapter.setSubDub(it.toString(), AnimeNameAdapter.Companion.SubDubType.NULL) != null }
|
||||||
|
.forEach { _ -> return true }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun loadEpisodes(
|
override suspend fun loadEpisodes(
|
||||||
animeLink: String,
|
animeLink: String,
|
||||||
extra: Map<String, String>?,
|
extra: Map<String, String>?,
|
||||||
|
@ -106,6 +164,8 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
||||||
}
|
}
|
||||||
it
|
it
|
||||||
}
|
}
|
||||||
|
} else if (episodesAreIncrementing(res)) {
|
||||||
|
res.sortedBy { it.episode_number }
|
||||||
} else {
|
} else {
|
||||||
var episodeCounter = 1f
|
var episodeCounter = 1f
|
||||||
// Group by season, sort within each season, and then renumber while keeping episode number 0 as is
|
// Group by season, sort within each season, and then renumber while keeping episode number 0 as is
|
||||||
|
@ -135,6 +195,19 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun episodesAreIncrementing(episodes: List<SEpisode>): Boolean {
|
||||||
|
val sortedEpisodes = episodes.sortedBy { it.episode_number }
|
||||||
|
val takenNumbers = mutableListOf<Float>()
|
||||||
|
sortedEpisodes.forEach {
|
||||||
|
if (it.episode_number !in takenNumbers) {
|
||||||
|
takenNumbers.add(it.episode_number)
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun loadVideoServers(
|
override suspend fun loadVideoServers(
|
||||||
episodeLink: String,
|
episodeLink: String,
|
||||||
extra: Map<String, String>?,
|
extra: Map<String, String>?,
|
||||||
|
|
|
@ -21,7 +21,6 @@ class OfflineAnimeParser : AnimeParser() {
|
||||||
override val name = "Offline"
|
override val name = "Offline"
|
||||||
override val saveName = "Offline"
|
override val saveName = "Offline"
|
||||||
override val hostUrl = "Offline"
|
override val hostUrl = "Offline"
|
||||||
override val isDubAvailableSeparately = false
|
|
||||||
override val isNSFW = false
|
override val isNSFW = false
|
||||||
|
|
||||||
override suspend fun loadEpisodes(
|
override suspend fun loadEpisodes(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ani.dantotsu.settings.extensionprefs
|
package ani.dantotsu.settings.extensionprefs
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
|
@ -8,6 +9,7 @@ import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.DialogPreference
|
import androidx.preference.DialogPreference
|
||||||
import androidx.preference.EditTextPreference
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.preference.forEach
|
import androidx.preference.forEach
|
||||||
import androidx.preference.getOnBindEditTextListener
|
import androidx.preference.getOnBindEditTextListener
|
||||||
import ani.dantotsu.snackString
|
import ani.dantotsu.snackString
|
||||||
|
@ -46,7 +48,7 @@ class AnimeSourcePreferencesFragment : PreferenceFragmentCompat() {
|
||||||
onCloseAction?.invoke()
|
onCloseAction?.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun populateAnimePreferenceScreen(): PreferenceScreen {
|
fun populateAnimePreferenceScreen(): PreferenceScreen {
|
||||||
val sourceId = requireArguments().getLong(SOURCE_ID)
|
val sourceId = requireArguments().getLong(SOURCE_ID)
|
||||||
val source = Injekt.get<AnimeSourceManager>().get(sourceId) as? ConfigurableAnimeSource
|
val source = Injekt.get<AnimeSourceManager>().get(sourceId) as? ConfigurableAnimeSource
|
||||||
?: error("Source with id: $sourceId not found!")
|
?: error("Source with id: $sourceId not found!")
|
||||||
|
@ -93,3 +95,31 @@ class AnimeSourcePreferencesFragment : PreferenceFragmentCompat() {
|
||||||
private const val SOURCE_ID = "source_id"
|
private const val SOURCE_ID = "source_id"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InitialAnimeSourcePreferencesFragment(val sharedPreferences: SharedPreferences, val source: ConfigurableAnimeSource, val currContext: Context) : PreferenceFragmentCompat() {
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
preferenceScreen = try {
|
||||||
|
populateAnimePreferenceScreen()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
snackString(e.message ?: "Unknown error")
|
||||||
|
preferenceManager.createPreferenceScreen(requireContext())
|
||||||
|
}
|
||||||
|
//set background color
|
||||||
|
val color = TypedValue()
|
||||||
|
requireContext().theme.resolveAttribute(
|
||||||
|
com.google.android.material.R.attr.backgroundColor,
|
||||||
|
color,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
view?.setBackgroundColor(color.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun populateAnimePreferenceScreen(): PreferenceScreen {
|
||||||
|
val dataStore = SharedPreferencesDataStore(sharedPreferences)
|
||||||
|
preferenceManager.preferenceDataStore = dataStore
|
||||||
|
val sourceScreen = preferenceManager.createPreferenceScreen(requireContext())
|
||||||
|
source.setupPreferenceScreen(sourceScreen)
|
||||||
|
return sourceScreen
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue