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*"
|
||||
const val failedEpisodeNumberRegex =
|
||||
"(?<!part\\s)\\b(\\d+)\\b"
|
||||
const val seasonRegex = "\\s+(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
|
||||
const val subdubRegex = "^(soft)?[\\s-]*(sub|dub|mixed)(bed)?\\s*$"
|
||||
const val seasonRegex = "(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
|
||||
const val subdubRegex = "^(soft)?[\\s-]*(sub|dub|mixed)(bed|s)?\\s*$"
|
||||
|
||||
fun setSubDub(text: String, typeToSetTo: SubDubType): String? {
|
||||
val subdubPattern: Pattern = Pattern.compile(subdubRegex, Pattern.CASE_INSENSITIVE)
|
||||
|
@ -25,6 +25,7 @@ class AnimeNameAdapter {
|
|||
val toggled = when (typeToSetTo) {
|
||||
SubDubType.SUB -> "sub"
|
||||
SubDubType.DUB -> "dub"
|
||||
SubDubType.NULL -> ""
|
||||
}
|
||||
val toggledCasePreserved =
|
||||
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 {
|
||||
SUB, DUB
|
||||
SUB, DUB, NULL
|
||||
}
|
||||
|
||||
fun findSeasonNumber(text: String): Int? {
|
||||
|
|
|
@ -113,7 +113,7 @@ class AnimeWatchAdapter(
|
|||
binding.animeSourceTitle.text = showUserText
|
||||
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
|
||||
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
|
||||
changing = false
|
||||
binding.animeSourceDubbedCont.visibility =
|
||||
if (isDubAvailableSeparately) View.VISIBLE else View.GONE
|
||||
if (isDubAvailableSeparately()) View.VISIBLE else View.GONE
|
||||
source = i
|
||||
setLanguageList(0, i)
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ class AnimeWatchAdapter(
|
|||
binding.animeSourceDubbed.isChecked = selectDub
|
||||
changing = false
|
||||
binding.animeSourceDubbedCont.visibility =
|
||||
if (isDubAvailableSeparately) View.VISIBLE else View.GONE
|
||||
if (isDubAvailableSeparately()) View.VISIBLE else View.GONE
|
||||
setLanguageList(i, source)
|
||||
}
|
||||
subscribeButton(false)
|
||||
|
|
|
@ -840,7 +840,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
|||
isFastForwarding = true
|
||||
exoPlayer.setPlaybackSpeed(exoPlayer.playbackParameters.speed * 2)
|
||||
fastForward.visibility = View.VISIBLE
|
||||
fastForward.text = ("${exoPlayer.playbackParameters.speed}x")
|
||||
fastForward.text = "${exoPlayer.playbackParameters.speed}x"
|
||||
}
|
||||
|
||||
fun stopFastForward() {
|
||||
|
@ -1286,7 +1286,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
|||
}
|
||||
println("sub: $sub")
|
||||
} else {
|
||||
val subUri = Uri.parse((subtitle!!.file.url))
|
||||
val subUri = Uri.parse(subtitle!!.file.url)
|
||||
sub = MediaItem.SubtitleConfiguration
|
||||
.Builder(subUri)
|
||||
.setSelectionFlags(C.SELECTION_FLAG_FORCED)
|
||||
|
|
|
@ -716,7 +716,7 @@ class MangaReaderActivity : AppCompatActivity() {
|
|||
val y = event.rawY.toInt()
|
||||
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 (screenWidth / 5 in (x + 1)..<y) {
|
||||
if (screenWidth / 5 in x + 1..<y) {
|
||||
pressLocation = if (settings.default.direction == RIGHT_TO_LEFT) {
|
||||
pressPos.RIGHT
|
||||
} 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**
|
||||
* **/
|
||||
open val isDubAvailableSeparately by Delegates.notNull<Boolean>()
|
||||
open fun isDubAvailableSeparately(sourceLang: Int? = null): Boolean = false
|
||||
|
||||
/**
|
||||
* The app changes this, depending on user's choice.
|
||||
|
@ -182,7 +182,7 @@ abstract class AnimeParser : BaseParser() {
|
|||
* **/
|
||||
override suspend fun loadSavedShowResponse(mediaId: Int): ShowResponse? {
|
||||
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")
|
||||
if (loaded == null && malSyncBackupName.isNotEmpty())
|
||||
loaded = MalSyncBackup.get(mediaId, malSyncBackupName, selectDub)
|
||||
|
@ -200,7 +200,7 @@ abstract class AnimeParser : BaseParser() {
|
|||
)
|
||||
} : ${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)
|
||||
}
|
||||
}
|
||||
|
@ -209,8 +209,6 @@ abstract class AnimeParser : BaseParser() {
|
|||
class EmptyAnimeParser : AnimeParser() {
|
||||
override val name: String = "None"
|
||||
override val saveName: String = "None"
|
||||
|
||||
override val isDubAvailableSeparately: Boolean = false
|
||||
override suspend fun loadEpisodes(
|
||||
animeLink: String,
|
||||
extra: Map<String, String>?,
|
||||
|
|
|
@ -10,12 +10,14 @@ import android.os.Build
|
|||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import ani.dantotsu.FileUrl
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.media.anime.AnimeNameAdapter
|
||||
import ani.dantotsu.media.manga.ImageData
|
||||
import ani.dantotsu.media.manga.MangaCache
|
||||
import ani.dantotsu.snackString
|
||||
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.SAnime
|
||||
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.network.NetworkHelper
|
||||
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.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
|
@ -71,8 +74,63 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
|||
override val name = extension.name
|
||||
override val saveName = extension.name
|
||||
override val hostUrl = extension.sources.first().name
|
||||
override val isDubAvailableSeparately = false
|
||||
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(
|
||||
animeLink: String,
|
||||
extra: Map<String, String>?,
|
||||
|
@ -106,6 +164,8 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
|||
}
|
||||
it
|
||||
}
|
||||
} else if (episodesAreIncrementing(res)) {
|
||||
res.sortedBy { it.episode_number }
|
||||
} else {
|
||||
var episodeCounter = 1f
|
||||
// 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()
|
||||
}
|
||||
|
||||
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(
|
||||
episodeLink: String,
|
||||
extra: Map<String, String>?,
|
||||
|
|
|
@ -21,7 +21,6 @@ class OfflineAnimeParser : AnimeParser() {
|
|||
override val name = "Offline"
|
||||
override val saveName = "Offline"
|
||||
override val hostUrl = "Offline"
|
||||
override val isDubAvailableSeparately = false
|
||||
override val isNSFW = false
|
||||
|
||||
override suspend fun loadEpisodes(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ani.dantotsu.settings.extensionprefs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import androidx.core.os.bundleOf
|
||||
|
@ -8,6 +9,7 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.preference.DialogPreference
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.preference.forEach
|
||||
import androidx.preference.getOnBindEditTextListener
|
||||
import ani.dantotsu.snackString
|
||||
|
@ -46,7 +48,7 @@ class AnimeSourcePreferencesFragment : PreferenceFragmentCompat() {
|
|||
onCloseAction?.invoke()
|
||||
}
|
||||
|
||||
private fun populateAnimePreferenceScreen(): PreferenceScreen {
|
||||
fun populateAnimePreferenceScreen(): PreferenceScreen {
|
||||
val sourceId = requireArguments().getLong(SOURCE_ID)
|
||||
val source = Injekt.get<AnimeSourceManager>().get(sourceId) as? ConfigurableAnimeSource
|
||||
?: error("Source with id: $sourceId not found!")
|
||||
|
@ -93,3 +95,31 @@ class AnimeSourcePreferencesFragment : PreferenceFragmentCompat() {
|
|||
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