Merge branch 'pr/299' into dev

This commit is contained in:
rebelonion 2024-04-04 04:48:51 -05:00
commit d08e89bb63
19 changed files with 479 additions and 223 deletions

View file

@ -12,8 +12,8 @@ import ani.dantotsu.R
class Xpandable @JvmOverloads constructor( class Xpandable @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null context: Context, attrs: AttributeSet? = null
) : LinearLayout(context, attrs) { ) : LinearLayout(context, attrs) {
var expanded: Boolean = false private var expanded: Boolean = false
private var listener: OnChangeListener? = null private var listeners: ArrayList<OnChangeListener> = arrayListOf()
init { init {
context.withStyledAttributes(attrs, R.styleable.Xpandable) { context.withStyledAttributes(attrs, R.styleable.Xpandable) {
@ -50,7 +50,9 @@ class Xpandable @JvmOverloads constructor(
} }
} }
postDelayed({ postDelayed({
listener?.onRetract() listeners.forEach{
it.onRetract()
}
}, 300) }, 300)
} }
@ -64,13 +66,19 @@ class Xpandable @JvmOverloads constructor(
} }
} }
postDelayed({ postDelayed({
listener?.onExpand() listeners.forEach{
it.onExpand()
}
}, 300) }, 300)
} }
@Suppress("unused") @Suppress("unused")
fun setOnChangeListener(listener: OnChangeListener) { fun addOnChangeListener(listener: OnChangeListener) {
this.listener = listener listeners.add(listener)
}
fun removeListener(listener: OnChangeListener) {
listeners.remove(listener)
} }
interface OnChangeListener { interface OnChangeListener {

View file

@ -137,11 +137,6 @@ class PlayerSettingsActivity : AppCompatActivity() {
binding.playerSettingsAutoSkipOpEd.isEnabled = isChecked binding.playerSettingsAutoSkipOpEd.isEnabled = isChecked
} }
binding.playerSettingsTimeStampsAutoHide.isChecked = PrefManager.getVal(PrefName.AutoHideTimeStamps)
binding.playerSettingsTimeStampsAutoHide.setOnCheckedChangeListener { _, isChecked ->
PrefManager.setVal(PrefName.AutoHideTimeStamps, isChecked)
}
binding.playerSettingsTimeStampsProxy.isChecked = binding.playerSettingsTimeStampsProxy.isChecked =
PrefManager.getVal(PrefName.UseProxyForTimeStamps) PrefManager.getVal(PrefName.UseProxyForTimeStamps)
binding.playerSettingsTimeStampsProxy.setOnCheckedChangeListener { _, isChecked -> binding.playerSettingsTimeStampsProxy.setOnCheckedChangeListener { _, isChecked ->
@ -152,6 +147,13 @@ class PlayerSettingsActivity : AppCompatActivity() {
PrefManager.getVal(PrefName.ShowTimeStampButton) PrefManager.getVal(PrefName.ShowTimeStampButton)
binding.playerSettingsShowTimeStamp.setOnCheckedChangeListener { _, isChecked -> binding.playerSettingsShowTimeStamp.setOnCheckedChangeListener { _, isChecked ->
PrefManager.setVal(PrefName.ShowTimeStampButton, isChecked) PrefManager.setVal(PrefName.ShowTimeStampButton, isChecked)
binding.playerSettingsTimeStampsAutoHide.isEnabled = isChecked
}
binding.playerSettingsTimeStampsAutoHide.isChecked = PrefManager.getVal(PrefName.AutoHideTimeStamps)
binding.playerSettingsTimeStampsAutoHide.isEnabled = binding.playerSettingsShowTimeStamp.isChecked
binding.playerSettingsTimeStampsAutoHide.setOnCheckedChangeListener { _, isChecked ->
PrefManager.setVal(PrefName.AutoHideTimeStamps, isChecked)
} }
// Auto // Auto
@ -475,7 +477,7 @@ class PlayerSettingsActivity : AppCompatActivity() {
updateSubPreview() updateSubPreview()
} }
} }
binding.subtitleTest.setOnChangeListener(object: Xpandable.OnChangeListener { binding.subtitleTest.addOnChangeListener(object: Xpandable.OnChangeListener {
override fun onExpand() { override fun onExpand() {
updateSubPreview() updateSubPreview()
} }

View file

@ -14,12 +14,15 @@ import android.os.Build.VERSION.CODENAME
import android.os.Build.VERSION.RELEASE import android.os.Build.VERSION.RELEASE
import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION.SDK_INT
import android.os.Bundle import android.os.Bundle
import android.view.HapticFeedbackConstants
import android.view.KeyEvent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.animation.AnimationUtils import android.view.animation.AnimationUtils
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.RadioButton import android.widget.RadioButton
import android.widget.RadioGroup import android.widget.RadioGroup
import android.widget.TextView import android.widget.TextView
@ -30,6 +33,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import android.view.HapticFeedbackConstants import android.view.HapticFeedbackConstants
import androidx.core.view.ViewCompat.performHapticFeedback import androidx.core.view.ViewCompat.performHapticFeedback
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -52,6 +56,7 @@ import ani.dantotsu.databinding.ActivitySettingsExtensionsBinding
import ani.dantotsu.databinding.ActivitySettingsMangaBinding import ani.dantotsu.databinding.ActivitySettingsMangaBinding
import ani.dantotsu.databinding.ActivitySettingsNotificationsBinding import ani.dantotsu.databinding.ActivitySettingsNotificationsBinding
import ani.dantotsu.databinding.ActivitySettingsThemeBinding import ani.dantotsu.databinding.ActivitySettingsThemeBinding
import ani.dantotsu.databinding.ItemRepositoryBinding
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.initActivity import ani.dantotsu.initActivity
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
@ -91,15 +96,19 @@ import eltos.simpledialogfragment.SimpleDialog
import eltos.simpledialogfragment.SimpleDialog.OnDialogResultListener.BUTTON_POSITIVE import eltos.simpledialogfragment.SimpleDialog.OnDialogResultListener.BUTTON_POSITIVE
import eltos.simpledialogfragment.color.SimpleColorDialog import eltos.simpledialogfragment.color.SimpleColorDialog
import eu.kanade.domain.base.BasePreferences import eu.kanade.domain.base.BasePreferences
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
import io.noties.markwon.Markwon import io.noties.markwon.Markwon
import io.noties.markwon.SoftBreakAddsNewLinePlugin import io.noties.markwon.SoftBreakAddsNewLinePlugin
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import kotlin.random.Random import kotlin.random.Random
@ -119,7 +128,9 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
private lateinit var bindingAbout: ActivitySettingsAboutBinding private lateinit var bindingAbout: ActivitySettingsAboutBinding
private val extensionInstaller = Injekt.get<BasePreferences>().extensionInstaller() private val extensionInstaller = Injekt.get<BasePreferences>().extensionInstaller()
private var cursedCounter = 0 private var cursedCounter = 0
private val animeExtensionManager: AnimeExtensionManager by injectLazy()
private val mangaExtensionManager: MangaExtensionManager by injectLazy()
@kotlin.OptIn(DelicateCoroutinesApi::class) @kotlin.OptIn(DelicateCoroutinesApi::class)
@OptIn(UnstableApi::class) @OptIn(UnstableApi::class)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -586,6 +597,142 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
} }
bindingExtensions = ActivitySettingsExtensionsBinding.bind(binding.root).apply { bindingExtensions = ActivitySettingsExtensionsBinding.bind(binding.root).apply {
fun setExtensionOutput() {
animeRepoInventory.removeAllViews()
PrefManager.getVal<Set<String>>(PrefName.AnimeExtensionRepos).forEach { item ->
val view = ItemRepositoryBinding.inflate(
LayoutInflater.from(animeRepoInventory.context), animeRepoInventory, true
)
view.repositoryItem.text = item
view.repositoryItem.setOnClickListener {
snackString(getString(R.string.long_click_delete))
}
view.repositoryItem.setOnLongClickListener {
val anime = PrefManager.getVal<Set<String>>(PrefName.AnimeExtensionRepos)
.minus(item)
PrefManager.setVal(PrefName.AnimeExtensionRepos, anime)
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
setExtensionOutput()
CoroutineScope(Dispatchers.IO).launch {
animeExtensionManager.findAvailableExtensions()
}
true
}
}
animeRepoInventory.isVisible = animeRepoInventory.childCount > 0
mangaRepoInventory.removeAllViews()
PrefManager.getVal<Set<String>>(PrefName.MangaExtensionRepos).forEach { item ->
val view = ItemRepositoryBinding.inflate(
LayoutInflater.from(mangaRepoInventory.context), mangaRepoInventory, true
)
view.repositoryItem.text = item
view.repositoryItem.setOnClickListener {
snackString(getString(R.string.long_click_delete))
}
view.repositoryItem.setOnLongClickListener {
val anime = PrefManager.getVal<Set<String>>(PrefName.MangaExtensionRepos)
.minus(item)
PrefManager.setVal(PrefName.MangaExtensionRepos, anime)
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
setExtensionOutput()
CoroutineScope(Dispatchers.IO).launch {
mangaExtensionManager.findAvailableExtensions()
}
true
}
}
mangaRepoInventory.isVisible = mangaRepoInventory.childCount > 0
}
fun processUserInput(input: String, mediaType: MediaType) {
val entry = if (input.endsWith("/") || input.endsWith("index.min.json"))
input.substring(0, input.lastIndexOf("/")) else input
if (mediaType == MediaType.ANIME) {
val anime = PrefManager.getVal<Set<String>>(PrefName.AnimeExtensionRepos).plus(entry)
PrefManager.setVal(PrefName.AnimeExtensionRepos, anime)
CoroutineScope(Dispatchers.IO).launch {
animeExtensionManager.findAvailableExtensions()
}
}
if (mediaType == MediaType.MANGA) {
val manga = PrefManager.getVal<Set<String>>(PrefName.MangaExtensionRepos).plus(entry)
PrefManager.setVal(PrefName.MangaExtensionRepos, manga)
CoroutineScope(Dispatchers.IO).launch {
mangaExtensionManager.findAvailableExtensions()
}
}
setExtensionOutput()
}
fun processEditorAction(dialog: AlertDialog, editText: EditText, mediaType: MediaType) {
editText.setOnEditorActionListener { textView, action, keyEvent ->
if (action == EditorInfo.IME_ACTION_SEARCH || action == EditorInfo.IME_ACTION_DONE ||
(keyEvent?.action == KeyEvent.ACTION_UP
&& keyEvent.keyCode == KeyEvent.KEYCODE_ENTER)) {
processUserInput(textView.text.toString(), mediaType)
dialog.dismiss()
return@setOnEditorActionListener true
}
false
}
}
setExtensionOutput()
animeAddRepository.setOnClickListener {
val dialogView = layoutInflater.inflate(R.layout.dialog_user_agent, null)
val editText = dialogView.findViewById<TextInputEditText>(R.id.userAgentTextBox).apply {
hint = getString(R.string.anime_add_repository)
}
val alertDialog = AlertDialog.Builder(this@SettingsActivity, R.style.MyPopup)
.setTitle(R.string.anime_add_repository)
.setView(dialogView)
.setPositiveButton(getString(R.string.ok)) { dialog, _ ->
processUserInput(editText.text.toString(), MediaType.ANIME)
dialog.dismiss()
}
.setNeutralButton(getString(R.string.reset)) { dialog, _ ->
PrefManager.removeVal(PrefName.DefaultUserAgent)
editText.setText("")
dialog.dismiss()
}
.setNegativeButton(getString(R.string.cancel)) { dialog, _ ->
dialog.dismiss()
}
.create()
processEditorAction(alertDialog, editText, MediaType.ANIME)
alertDialog.show()
alertDialog.window?.setDimAmount(0.8f)
}
mangaAddRepository.setOnClickListener {
val dialogView = layoutInflater.inflate(R.layout.dialog_user_agent, null)
val editText = dialogView.findViewById<TextInputEditText>(R.id.userAgentTextBox).apply {
hint = getString(R.string.manga_add_repository)
}
val alertDialog = AlertDialog.Builder(this@SettingsActivity, R.style.MyPopup)
.setTitle(R.string.manga_add_repository)
.setView(dialogView)
.setPositiveButton(getString(R.string.ok)) { dialog, _ ->
processUserInput(editText.text.toString(), MediaType.MANGA)
dialog.dismiss()
}
.setNeutralButton(getString(R.string.reset)) { dialog, _ ->
PrefManager.removeVal(PrefName.DefaultUserAgent)
editText.setText("")
dialog.dismiss()
}
.setNegativeButton(getString(R.string.cancel)) { dialog, _ ->
dialog.dismiss()
}
.create()
processEditorAction(alertDialog, editText, MediaType.MANGA)
alertDialog.show()
alertDialog.window?.setDimAmount(0.8f)
}
settingsForceLegacyInstall.isChecked = settingsForceLegacyInstall.isChecked =
extensionInstaller.get() == BasePreferences.ExtensionInstaller.LEGACY extensionInstaller.get() == BasePreferences.ExtensionInstaller.LEGACY
settingsForceLegacyInstall.setOnCheckedChangeListener { _, isChecked -> settingsForceLegacyInstall.setOnCheckedChangeListener { _, isChecked ->
@ -1196,4 +1343,4 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
?: "Unknown Architecture" ?: "Unknown Architecture"
} }
} }
} }

View file

@ -28,6 +28,9 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
"Mozilla/5.0 (Linux; Android 13; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36" "Mozilla/5.0 (Linux; Android 13; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36"
) )
), ),
AnimeExtensionRepos(Pref(Location.General, Set::class, setOf<String>())),
MangaExtensionRepos(Pref(Location.General, Set::class, setOf<String>())),
SharedRepositories(Pref(Location.General, Boolean::class, false)),
AnimeSourcesOrder(Pref(Location.General, List::class, listOf<String>())), AnimeSourcesOrder(Pref(Location.General, List::class, listOf<String>())),
AnimeSearchHistory(Pref(Location.General, Set::class, setOf<String>())), AnimeSearchHistory(Pref(Location.General, Set::class, setOf<String>())),
MangaSourcesOrder(Pref(Location.General, List::class, listOf<String>())), MangaSourcesOrder(Pref(Location.General, List::class, listOf<String>())),

View file

@ -1,6 +1,8 @@
package eu.kanade.tachiyomi.extension.anime.api package eu.kanade.tachiyomi.extension.anime.api
import android.content.Context import android.content.Context
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import eu.kanade.tachiyomi.extension.ExtensionUpdateNotifier import eu.kanade.tachiyomi.extension.ExtensionUpdateNotifier
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
@ -32,42 +34,36 @@ internal class AnimeExtensionGithubApi {
preferenceStore.getLong("last_ext_check", 0) preferenceStore.getLong("last_ext_check", 0)
} }
private var requiresFallbackSource = false
suspend fun findExtensions(): List<AnimeExtension.Available> { suspend fun findExtensions(): List<AnimeExtension.Available> {
return withIOContext { return withIOContext {
val githubResponse = if (requiresFallbackSource) {
null val extensions: ArrayList<AnimeExtension.Available> = arrayListOf()
} else {
PrefManager.getVal<Set<String>>(PrefName.AnimeExtensionRepos).forEach {
try { try {
networkService.client val githubResponse =
.newCall(GET("${REPO_URL_PREFIX}index.min.json")) networkService.client
.awaitSuccess() .newCall(GET("${it}/index.min.json"))
.awaitSuccess()
val repoExtensions = with(json) {
githubResponse
.parseAs<List<AnimeExtensionJsonObject>>()
.toExtensions(it)
}
// Sanity check - a small number of extensions probably means something broke
// with the repo generator
if (repoExtensions.size < 10) {
throw Exception()
}
extensions.addAll(repoExtensions)
} catch (e: Throwable) { } catch (e: Throwable) {
Logger.log("Failed to get extensions from GitHub") Logger.log("Failed to get extensions from GitHub")
requiresFallbackSource = true
null
} }
} }
val response = githubResponse ?: run {
networkService.client
.newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json"))
.awaitSuccess()
}
val extensions = with(json) {
response
.parseAs<List<AnimeExtensionJsonObject>>()
.toExtensions()
}
// Sanity check - a small number of extensions probably means something broke
// with the repo generator
if (extensions.size < 10) {
throw Exception()
}
extensions extensions
} }
} }
@ -111,7 +107,7 @@ internal class AnimeExtensionGithubApi {
return extensionsWithUpdate return extensionsWithUpdate
} }
private fun List<AnimeExtensionJsonObject>.toExtensions(): List<AnimeExtension.Available> { private fun List<AnimeExtensionJsonObject>.toExtensions(repository: String): List<AnimeExtension.Available> {
return this return this
.filter { .filter {
val libVersion = it.extractLibVersion() val libVersion = it.extractLibVersion()
@ -130,7 +126,8 @@ internal class AnimeExtensionGithubApi {
hasChangelog = it.hasChangelog == 1, hasChangelog = it.hasChangelog == 1,
sources = it.sources?.toAnimeExtensionSources().orEmpty(), sources = it.sources?.toAnimeExtensionSources().orEmpty(),
apkName = it.apk, apkName = it.apk,
iconUrl = "${getUrlPrefix()}icon/${it.pkg}.png", repository = repository,
iconUrl = "${repository}/icon/${it.pkg}.png",
) )
} }
} }
@ -147,15 +144,7 @@ internal class AnimeExtensionGithubApi {
} }
fun getApkUrl(extension: AnimeExtension.Available): String { fun getApkUrl(extension: AnimeExtension.Available): String {
return "${getUrlPrefix()}apk/${extension.apkName}" return "${extension.repository}/apk/${extension.apkName}"
}
private fun getUrlPrefix(): String {
return if (requiresFallbackSource) {
FALLBACK_REPO_URL_PREFIX
} else {
REPO_URL_PREFIX
}
} }
} }
@ -163,11 +152,6 @@ private fun AnimeExtensionJsonObject.extractLibVersion(): Double {
return version.substringBeforeLast('.').toDouble() return version.substringBeforeLast('.').toDouble()
} }
private const val REPO_URL_PREFIX =
"https://raw.githubusercontent.com/aniyomiorg/aniyomi-extensions/repo/"
private const val FALLBACK_REPO_URL_PREFIX =
"https://gcore.jsdelivr.net/gh/aniyomiorg/aniyomi-extensions@repo/"
@Serializable @Serializable
private data class AnimeExtensionJsonObject( private data class AnimeExtensionJsonObject(
val name: String, val name: String,

View file

@ -47,6 +47,7 @@ sealed class AnimeExtension {
val sources: List<AvailableAnimeSources>, val sources: List<AvailableAnimeSources>,
val apkName: String, val apkName: String,
val iconUrl: String, val iconUrl: String,
val repository: String
) : AnimeExtension() ) : AnimeExtension()
data class Untrusted( data class Untrusted(

View file

@ -1,6 +1,8 @@
package eu.kanade.tachiyomi.extension.manga.api package eu.kanade.tachiyomi.extension.manga.api
import android.content.Context import android.content.Context
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import eu.kanade.tachiyomi.extension.ExtensionUpdateNotifier import eu.kanade.tachiyomi.extension.ExtensionUpdateNotifier
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
@ -32,42 +34,37 @@ internal class MangaExtensionGithubApi {
preferenceStore.getLong("last_ext_check", 0) preferenceStore.getLong("last_ext_check", 0)
} }
private var requiresFallbackSource = false
suspend fun findExtensions(): List<MangaExtension.Available> { suspend fun findExtensions(): List<MangaExtension.Available> {
return withIOContext { return withIOContext {
val githubResponse = if (requiresFallbackSource) {
null val extensions: ArrayList<MangaExtension.Available> = arrayListOf()
} else {
PrefManager.getVal<Set<String>>(PrefName.MangaExtensionRepos).forEach {
try { try {
networkService.client val githubResponse =
.newCall(GET("${REPO_URL_PREFIX}index.min.json")) networkService.client
.awaitSuccess() .newCall(GET("${it}/index.min.json"))
.awaitSuccess()
val repoExtensions = with(json) {
githubResponse
.parseAs<List<ExtensionJsonObject>>()
.toExtensions(it)
}
// Sanity check - a small number of extensions probably means something broke
// with the repo generator
if (repoExtensions.size < 10) {
throw Exception()
}
extensions.addAll(repoExtensions)
} catch (e: Throwable) { } catch (e: Throwable) {
Logger.log("Failed to get extensions from GitHub") Logger.log("Failed to get extensions from GitHub")
requiresFallbackSource = true
null
} }
} }
val response = githubResponse ?: run {
networkService.client
.newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json"))
.awaitSuccess()
}
val extensions = with(json) {
response
.parseAs<List<ExtensionJsonObject>>()
.toExtensions()
}
// Sanity check - a small number of extensions probably means something broke
// with the repo generator
if (extensions.size < 100) {
throw Exception()
}
extensions extensions
} }
} }
@ -110,7 +107,7 @@ internal class MangaExtensionGithubApi {
return extensionsWithUpdate return extensionsWithUpdate
} }
private fun List<ExtensionJsonObject>.toExtensions(): List<MangaExtension.Available> { private fun List<ExtensionJsonObject>.toExtensions(repository: String): List<MangaExtension.Available> {
return this return this
.filter { .filter {
val libVersion = it.extractLibVersion() val libVersion = it.extractLibVersion()
@ -129,7 +126,8 @@ internal class MangaExtensionGithubApi {
hasChangelog = it.hasChangelog == 1, hasChangelog = it.hasChangelog == 1,
sources = it.sources?.toExtensionSources().orEmpty(), sources = it.sources?.toExtensionSources().orEmpty(),
apkName = it.apk, apkName = it.apk,
iconUrl = "${getUrlPrefix()}icon/${it.pkg}.png", repository = repository,
iconUrl = "${repository}/icon/${it.pkg}.png",
) )
} }
} }
@ -146,15 +144,7 @@ internal class MangaExtensionGithubApi {
} }
fun getApkUrl(extension: MangaExtension.Available): String { fun getApkUrl(extension: MangaExtension.Available): String {
return "${getUrlPrefix()}apk/${extension.apkName}" return "${extension.repository}/apk/${extension.apkName}"
}
private fun getUrlPrefix(): String {
return if (requiresFallbackSource) {
FALLBACK_REPO_URL_PREFIX
} else {
REPO_URL_PREFIX
}
} }
private fun ExtensionJsonObject.extractLibVersion(): Double { private fun ExtensionJsonObject.extractLibVersion(): Double {
@ -162,10 +152,6 @@ internal class MangaExtensionGithubApi {
} }
} }
private const val REPO_URL_PREFIX = "https://raw.githubusercontent.com/keiyoushi/extensions/main/"
private const val FALLBACK_REPO_URL_PREFIX =
"https://gcore.jsdelivr.net/gh/keiyoushi/extensions@main/"
@Serializable @Serializable
private data class ExtensionJsonObject( private data class ExtensionJsonObject(
val name: String, val name: String,

View file

@ -47,6 +47,7 @@ sealed class MangaExtension {
val sources: List<AvailableMangaSources>, val sources: List<AvailableMangaSources>,
val apkName: String, val apkName: String,
val iconUrl: String, val iconUrl: String,
val repository: String
) : MangaExtension() ) : MangaExtension()
data class Untrusted( data class Untrusted(

View file

@ -177,8 +177,7 @@
android:layout_height="64dp" android:layout_height="64dp"
android:fontFamily="@font/poppins_bold" android:fontFamily="@font/poppins_bold"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingStart="48dp" android:paddingHorizontal="32dp"
android:paddingEnd="32dp"
android:text="@string/sub_text_example" android:text="@string/sub_text_example"
android:textColor="?attr/colorSecondary" android:textColor="?attr/colorSecondary"
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24" app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"
@ -492,37 +491,6 @@
app:showText="false" app:showText="false"
app:thumbTint="@color/button_switch_track" /> app:thumbTint="@color/button_switch_track" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/playerSettingsTimeStampsAutoHide"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:checked="true"
android:drawableStart="@drawable/ic_round_art_track_24"
android:drawablePadding="16dp"
android:elegantTextHeight="true"
android:fontFamily="@font/poppins_bold"
android:minHeight="64dp"
android:paddingHorizontal="32dp"
android:text="@string/auto_hide_time_stamps"
android:textAlignment="viewStart"
android:textColor="@color/bg_opp"
app:cornerRadius="0dp"
app:drawableTint="?attr/colorPrimary"
app:showText="false"
app:thumbTint="@color/button_switch_track" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-8dp"
android:layout_marginBottom="8dp"
android:alpha="0.58"
android:fontFamily="@font/poppins_family"
android:paddingHorizontal="32dp"
android:text="@string/hide_skip_button"
android:textSize="14sp" />
<com.google.android.material.materialswitch.MaterialSwitch <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/playerSettingsTimeStampsProxy" android:id="@+id/playerSettingsTimeStampsProxy"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -577,23 +545,36 @@
</com.google.android.material.materialswitch.MaterialSwitch> </com.google.android.material.materialswitch.MaterialSwitch>
</ani.dantotsu.others.Xpandable> <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/playerSettingsTimeStampsAutoHide"
<ani.dantotsu.others.Xpandable android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_marginBottom="8dp"
android:orientation="vertical"> android:checked="true"
android:drawableStart="@drawable/ic_round_art_track_24"
android:drawablePadding="16dp"
android:elegantTextHeight="true"
android:fontFamily="@font/poppins_bold"
android:minHeight="64dp"
android:paddingHorizontal="32dp"
android:text="@string/auto_hide_time_stamps"
android:textAlignment="viewStart"
android:textColor="@color/bg_opp"
app:cornerRadius="0dp"
app:drawableTint="?attr/colorPrimary"
app:showText="false"
app:thumbTint="@color/button_switch_track" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="64dp" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_bold" android:layout_marginTop="-8dp"
android:gravity="center_vertical" android:layout_marginBottom="8dp"
android:alpha="0.58"
android:fontFamily="@font/poppins_family"
android:paddingHorizontal="32dp" android:paddingHorizontal="32dp"
android:text="@string/auto" android:text="@string/hide_skip_button"
android:textColor="?attr/colorSecondary" android:textSize="14sp" />
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"
tools:ignore="TextContrastCheck" />
<com.google.android.material.materialswitch.MaterialSwitch <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/playerSettingsAutoSkipOpEd" android:id="@+id/playerSettingsAutoSkipOpEd"

View file

@ -19,6 +19,13 @@
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24" app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"
tools:ignore="TextContrastCheck" /> tools:ignore="TextContrastCheck" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/settingsFAQ" android:id="@+id/settingsFAQ"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -18,10 +18,18 @@
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24" app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"
tools:ignore="TextContrastCheck" /> tools:ignore="TextContrastCheck" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<LinearLayout <LinearLayout
android:id="@+id/settingsAnilistLoginContainer" android:id="@+id/settingsAnilistLoginContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <ImageView
@ -260,5 +268,12 @@
app:drawableStartCompat="@drawable/ic_round_help_24" app:drawableStartCompat="@drawable/ic_round_help_24"
app:drawableTint="?attr/colorPrimary" /> app:drawableTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/listDivider" />
</ani.dantotsu.others.Xpandable> </ani.dantotsu.others.Xpandable>
</merge> </merge>

View file

@ -18,6 +18,13 @@
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24" app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"
tools:ignore="TextContrastCheck" /> tools:ignore="TextContrastCheck" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -90,14 +97,6 @@
</LinearLayout> </LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/settingsPlayer" android:id="@+id/settingsPlayer"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -122,13 +121,6 @@
app:iconSize="24dp" app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" /> app:iconTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/purgeAnimeDownloads" android:id="@+id/purgeAnimeDownloads"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -151,14 +143,6 @@
app:iconSize="24dp" app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" /> app:iconTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/listDivider" />
<com.google.android.material.materialswitch.MaterialSwitch <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/settingsPreferDub" android:id="@+id/settingsPreferDub"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -194,6 +178,7 @@
app:drawableTint="?attr/colorPrimary" app:drawableTint="?attr/colorPrimary"
app:showText="false" app:showText="false"
app:thumbTint="@color/button_switch_track" /> app:thumbTint="@color/button_switch_track" />
<com.google.android.material.materialswitch.MaterialSwitch <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/settingsIncludeAnimeList" android:id="@+id/settingsIncludeAnimeList"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -212,6 +197,13 @@
app:showText="false" app:showText="false"
app:thumbTint="@color/button_switch_track" /> app:thumbTint="@color/button_switch_track" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/listDivider" />
</ani.dantotsu.others.Xpandable> </ani.dantotsu.others.Xpandable>
</merge> </merge>

View file

@ -19,6 +19,12 @@
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24" app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"
tools:ignore="TextContrastCheck" /> tools:ignore="TextContrastCheck" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -91,14 +97,6 @@
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
</LinearLayout> </LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/settingsUi" android:id="@+id/settingsUi"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -121,13 +119,6 @@
app:iconSize="24dp" app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" /> app:iconTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/settingsDownloadManager" android:id="@+id/settingsDownloadManager"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -152,13 +143,6 @@
app:iconSize="24dp" app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" /> app:iconTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/importExportSettings" android:id="@+id/importExportSettings"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -202,6 +186,7 @@
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="8dp"
app:boxCornerRadiusBottomEnd="8dp" app:boxCornerRadiusBottomEnd="8dp"
app:boxCornerRadiusBottomStart="8dp" app:boxCornerRadiusBottomStart="8dp"
app:boxCornerRadiusTopEnd="8dp" app:boxCornerRadiusTopEnd="8dp"
@ -320,5 +305,14 @@
app:iconPadding="16dp" app:iconPadding="16dp"
app:iconSize="24dp" app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" /> app:iconTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/listDivider" />
</ani.dantotsu.others.Xpandable> </ani.dantotsu.others.Xpandable>
</merge> </merge>

View file

@ -2,7 +2,9 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android" <merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<ani.dantotsu.others.Xpandable <ani.dantotsu.others.Xpandable
android:id="@+id/extensionSettings"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
@ -22,7 +24,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_marginStart="-16dp" android:layout_marginStart="-16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="-16dp" android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" /> android:background="?android:attr/listDivider" />
@ -38,8 +39,7 @@
android:fontFamily="@font/poppins_bold" android:fontFamily="@font/poppins_bold"
android:insetTop="0dp" android:insetTop="0dp"
android:insetBottom="0dp" android:insetBottom="0dp"
android:paddingStart="31dp" android:paddingHorizontal="31dp"
android:paddingEnd="31dp"
android:text="@string/user_agent" android:text="@string/user_agent"
android:textAlignment="viewStart" android:textAlignment="viewStart"
android:textAllCaps="false" android:textAllCaps="false"
@ -50,14 +50,107 @@
app:iconSize="24dp" app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" /> app:iconTint="?attr/colorPrimary" />
<TextView
android:id="@+id/animeRepoHeading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:fontFamily="@font/poppins_bold"
android:text="@string/anime_repo_listing"
android:textSize="14sp"
tools:ignore="RtlSymmetry" />
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_marginStart="-16dp" android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp" android:layout_marginEnd="-16dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider" /> android:background="?android:attr/listDivider" />
<LinearLayout
android:id="@+id/animeRepoInventory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:paddingStart="36dp"
android:visibility="gone"
tools:ignore="RtlSymmetry"
android:orientation="vertical" />
<Button
android:id="@+id/animeAddRepository"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingHorizontal="31dp"
android:text="@string/anime_add_repository"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_github"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<TextView
android:id="@+id/mangaRepoHeading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:fontFamily="@font/poppins_bold"
android:text="@string/manga_repo_listing"
android:textSize="14sp"
tools:ignore="RtlSymmetry" />
<View
android:id="@+id/mangaRepoDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<LinearLayout
android:id="@+id/mangaRepoInventory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:paddingStart="36dp"
android:visibility="gone"
tools:ignore="RtlSymmetry"
android:orientation="vertical" />
<Button
android:id="@+id/mangaAddRepository"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingHorizontal="31dp"
android:text="@string/manga_add_repository"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_github"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<com.google.android.material.materialswitch.MaterialSwitch <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/settingsForceLegacyInstall" android:id="@+id/settingsForceLegacyInstall"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -112,5 +205,13 @@
app:showText="false" app:showText="false"
app:thumbTint="@color/button_switch_track" /> app:thumbTint="@color/button_switch_track" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/listDivider" />
</ani.dantotsu.others.Xpandable> </ani.dantotsu.others.Xpandable>
</merge> </merge>

View file

@ -18,10 +18,17 @@
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24" app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"
tools:ignore="TextContrastCheck" /> tools:ignore="TextContrastCheck" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="24dp" android:layout_marginTop="16dp"
android:gravity="center" android:gravity="center"
android:orientation="horizontal"> android:orientation="horizontal">
@ -71,14 +78,6 @@
</LinearLayout> </LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/settingsReader" android:id="@+id/settingsReader"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -101,13 +100,6 @@
app:iconSize="24dp" app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" /> app:iconTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/purgeMangaDownloads" android:id="@+id/purgeMangaDownloads"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -130,13 +122,6 @@
app:iconSize="24dp" app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" /> app:iconTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/purgeNovelDownloads" android:id="@+id/purgeNovelDownloads"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -18,6 +18,13 @@
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24" app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"
tools:ignore="TextContrastCheck" /> tools:ignore="TextContrastCheck" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button <Button
android:id="@+id/settingsSubscriptionsTime" android:id="@+id/settingsSubscriptionsTime"
style="@style/Widget.Material3.Button.TextButton" style="@style/Widget.Material3.Button.TextButton"
@ -157,5 +164,13 @@
app:showText="false" app:showText="false"
app:thumbTint="@color/button_switch_track" /> app:thumbTint="@color/button_switch_track" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/listDivider" />
</ani.dantotsu.others.Xpandable> </ani.dantotsu.others.Xpandable>
</merge> </merge>

View file

@ -18,6 +18,13 @@
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24" app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"
tools:ignore="TextContrastCheck" /> tools:ignore="TextContrastCheck" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -94,6 +101,7 @@
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="8dp"
app:boxCornerRadiusBottomEnd="8dp" app:boxCornerRadiusBottomEnd="8dp"
app:boxCornerRadiusBottomStart="8dp" app:boxCornerRadiusBottomStart="8dp"
app:boxCornerRadiusTopEnd="8dp" app:boxCornerRadiusTopEnd="8dp"

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/repositoryItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/poppins_semi_bold"
android:textSize="12sp"
android:textAlignment="viewStart"
android:textColor="?attr/colorOnBackground" />
</LinearLayout>

View file

@ -252,7 +252,7 @@
<string name="sub_window_color_info">"The subtitle window is the part left and right from them. (where the background isn\'t)"</string> <string name="sub_window_color_info">"The subtitle window is the part left and right from them. (where the background isn\'t)"</string>
<string name="sub_color_info"><b>Note:</b> Changing above settings only affects Soft-Subtitles!</string> <string name="sub_color_info"><b>Note:</b> Changing above settings only affects Soft-Subtitles!</string>
<string name="sub_alpha">Subtitle Transparency</string> <string name="sub_alpha">Subtitle Transparency</string>
<string name="sub_text_example">Example Subtitle</string> <string name="sub_text_example">Example Sub</string>
<string name="sub_font_select">Subtitle Font</string> <string name="sub_font_select">Subtitle Font</string>
<string name="subtitle_font_size">Subtitle Size</string> <string name="subtitle_font_size">Subtitle Size</string>
@ -417,6 +417,7 @@
<string name="crop_borders">Crop Borders</string> <string name="crop_borders">Crop Borders</string>
<string name="note">NOTE</string> <string name="note">NOTE</string>
<string name="manage_extension_repos">Manage Extension Repos</string>
<string name="installing_extension">Installing extension</string> <string name="installing_extension">Installing extension</string>
<string name="installation_failed">Installation failed: %1$s</string> <string name="installation_failed">Installation failed: %1$s</string>
<string name="installation_complete">Installation complete</string> <string name="installation_complete">Installation complete</string>
@ -451,7 +452,7 @@
<string name="show_skip_time_stamp_button">Show Skip Time Stamp Button</string> <string name="show_skip_time_stamp_button">Show Skip Time Stamp Button</string>
<string name="always_load_time_stamps">Always Load Time Stamps</string> <string name="always_load_time_stamps">Always Load Time Stamps</string>
<string name="auto_hide_time_stamps">Auto Hide Time Stamps</string>string <string name="auto_hide_time_stamps">Auto Hide Time Stamps</string>string
<string name="timestamps">Time Stamps</string> <string name="timestamps">Segments</string>
<string name="auto_skip_op_ed">Auto Skip OP / ED</string> <string name="auto_skip_op_ed">Auto Skip OP / ED</string>
<string name="requires_time_stamps_to_be_enabled">Requires Time Stamps to be Enabled</string> <string name="requires_time_stamps_to_be_enabled">Requires Time Stamps to be Enabled</string>
<string name="hide_skip_button">Make the skip time stamp button disappear after 5 seconds</string> <string name="hide_skip_button">Make the skip time stamp button disappear after 5 seconds</string>
@ -861,6 +862,13 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
<string name="title_color">Title Color</string> <string name="title_color">Title Color</string>
<string name="stat_text_color">Stats Text Color</string> <string name="stat_text_color">Stats Text Color</string>
<string name="placeholder">Placeholder</string> <string name="placeholder">Placeholder</string>
<string name="anime_repo_listing">Anime Extension Repos</string>
<string name="anime_add_repository">Add Anime Repo</string>
<string name="manga_repo_listing">Manga Extension Repos</string>
<string name="manga_add_repository">Add Manga Repo</string>
<string name="long_click_delete">Long click to delete</string>
<string name="trending_movies">Trending Movies</string> <string name="trending_movies">Trending Movies</string>
<string name="include_list">Include list</string> <string name="include_list">Include list</string>
<string name="top_rated">Top rated</string> <string name="top_rated">Top rated</string>