extension settings

This commit is contained in:
Finnley Somdahl 2023-10-29 19:45:11 -05:00
parent 9c0ef7a788
commit 3368a1bc8d
76 changed files with 2320 additions and 131 deletions

View file

@ -120,8 +120,8 @@ class MediaDetailsViewModel : ViewModel() {
private val episodes = MutableLiveData<MutableMap<Int, MutableMap<String, Episode>>>(null)
private val epsLoaded = mutableMapOf<Int, MutableMap<String, Episode>>()
fun getEpisodes(): LiveData<MutableMap<Int, MutableMap<String, Episode>>> = episodes
suspend fun loadEpisodes(media: Media, i: Int) {
if (!epsLoaded.containsKey(i)) {
suspend fun loadEpisodes(media: Media, i: Int, invalidate: Boolean = false) {
if (!epsLoaded.containsKey(i) || invalidate) {
epsLoaded[i] = watchSources?.loadEpisodesFromMedia(i, media) ?: return
}
episodes.postValue(epsLoaded)
@ -240,9 +240,9 @@ class MediaDetailsViewModel : ViewModel() {
private val mangaChapters = MutableLiveData<MutableMap<Int, MutableMap<String, MangaChapter>>>(null)
private val mangaLoaded = mutableMapOf<Int, MutableMap<String, MangaChapter>>()
fun getMangaChapters(): LiveData<MutableMap<Int, MutableMap<String, MangaChapter>>> = mangaChapters
suspend fun loadMangaChapters(media: Media, i: Int) {
suspend fun loadMangaChapters(media: Media, i: Int, invalidate: Boolean = false) {
logger("Loading Manga Chapters : $mangaLoaded")
if (!mangaLoaded.containsKey(i)) tryWithSuspend {
if (!mangaLoaded.containsKey(i) || invalidate) tryWithSuspend {
mangaLoaded[i] = mangaReadSources?.loadChaptersFromMedia(i, media) ?: return@tryWithSuspend
}
mangaChapters.postValue(mangaLoaded)

View file

@ -9,6 +9,7 @@ data class Selected(
var chip: Int = 0,
//var source: String = "",
var sourceIndex: Int = 0,
var langIndex: Int = 0,
var preferDub: Boolean = false,
var server: String? = null,
var video: Int = 0,

View file

@ -1,6 +1,8 @@
package ani.dantotsu.media.anime
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.util.TypedValue
@ -8,23 +10,38 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import ani.dantotsu.*
import ani.dantotsu.databinding.ItemAnimeWatchBinding
import ani.dantotsu.databinding.ItemChipBinding
import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.SourceSearchDialogFragment
import ani.dantotsu.parsers.AnimeSources
import ani.dantotsu.parsers.DynamicAnimeParser
import ani.dantotsu.parsers.WatchSources
import ani.dantotsu.settings.ExtensionsActivity
import ani.dantotsu.settings.extensionprefs.AnimeSourcePreferencesFragment
import ani.dantotsu.subcriptions.Notifications.Companion.openSettings
import ani.dantotsu.subcriptions.Subscription.Companion.getChannelId
import com.google.android.material.chip.Chip
import com.google.android.material.tabs.TabLayout
import com.google.android.material.textfield.TextInputLayout
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.lang.IndexOutOfBoundsException
class AnimeWatchAdapter(
private val media: Media,
@ -70,7 +87,8 @@ class AnimeWatchAdapter(
}
//Source Selection
val source = media.selected!!.sourceIndex.let { if (it >= watchSources.names.size) 0 else it }
var source = media.selected!!.sourceIndex.let { if (it >= watchSources.names.size) 0 else it }
setLanguageList(media.selected!!.langIndex,source)
if (watchSources.names.isNotEmpty() && source in 0 until watchSources.names.size) {
binding.animeSource.setText(watchSources.names[source])
watchSources[source].apply {
@ -92,11 +110,41 @@ class AnimeWatchAdapter(
binding.animeSourceDubbed.isChecked = selectDub
changing = false
binding.animeSourceDubbedCont.visibility = if (isDubAvailableSeparately) View.VISIBLE else View.GONE
source = i
setLanguageList(0,i)
}
subscribeButton(false)
fragment.loadEpisodes(i)
fragment.loadEpisodes(i, false)
}
binding.animeSourceLanguage.setOnItemClickListener { _, _, i, _ ->
// Check if 'extension' and 'selected' properties exist and are accessible
(watchSources[source] as? DynamicAnimeParser)?.let { ext ->
ext.sourceLanguage = i
fragment.onLangChange(i)
fragment.onSourceChange(media.selected!!.sourceIndex).apply {
binding.animeSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
changing = true
binding.animeSourceDubbed.isChecked = selectDub
changing = false
binding.animeSourceDubbedCont.visibility = if (isDubAvailableSeparately) View.VISIBLE else View.GONE
setLanguageList(i, source)
}
subscribeButton(false)
fragment.loadEpisodes(media.selected!!.sourceIndex, true)
} ?: run {
}
}
//settings
binding.animeSourceSettings.setOnClickListener {
(watchSources[source] as? DynamicAnimeParser)?.let { ext ->
fragment.openSettings(ext.extension)
}
}
//Subscription
subscribe = MediaDetailsActivity.PopImageButton(
fragment.lifecycleScope,
@ -263,6 +311,25 @@ class AnimeWatchAdapter(
}
}
fun setLanguageList(lang: Int, source: Int) {
val binding = _binding
if (watchSources is AnimeSources) {
val parser = watchSources[source] as? DynamicAnimeParser
if (parser != null) {
(watchSources[source] as? DynamicAnimeParser)?.let { ext ->
ext.sourceLanguage = lang
}
try {
binding?.animeSourceLanguage?.setText(parser.extension.sources[lang].lang)
}catch (e: IndexOutOfBoundsException) {
binding?.animeSourceLanguage?.setText(parser.extension.sources.firstOrNull()?.lang ?: "Unknown")
}
binding?.animeSourceLanguage?.setAdapter(ArrayAdapter(fragment.requireContext(), R.layout.item_dropdown, parser.extension.sources.map { it.lang }))
}
}
}
override fun getItemCount(): Int = 1
inner class ViewHolder(val binding: ItemAnimeWatchBinding) : RecyclerView.ViewHolder(binding.root) {

View file

@ -1,11 +1,17 @@
package ani.dantotsu.media.anime
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Toast
import androidx.cardview.widget.CardView
import androidx.core.math.MathUtils
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
@ -13,24 +19,38 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.GridLayoutManager
import androidx.viewpager2.widget.ViewPager2
import ani.dantotsu.*
import ani.dantotsu.databinding.FragmentAnimeWatchBinding
import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.MediaDetailsViewModel
import ani.dantotsu.parsers.AnimeParser
import ani.dantotsu.parsers.AnimeSources
import ani.dantotsu.parsers.HAnimeSources
import ani.dantotsu.settings.ExtensionsActivity
import ani.dantotsu.settings.InstalledAnimeExtensionsFragment
import ani.dantotsu.settings.PlayerSettings
import ani.dantotsu.settings.UserInterfaceSettings
import ani.dantotsu.settings.extensionprefs.AnimeSourcePreferencesFragment
import ani.dantotsu.subcriptions.Notifications
import ani.dantotsu.subcriptions.Notifications.Group.ANIME_GROUP
import ani.dantotsu.subcriptions.Subscription.Companion.getChannelId
import ani.dantotsu.subcriptions.SubscriptionHelper
import ani.dantotsu.subcriptions.SubscriptionHelper.Companion.saveSubscription
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.navigationrail.NavigationRailView
import com.google.android.material.tabs.TabLayout
import com.google.android.material.textfield.TextInputLayout
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.launch
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.math.ceil
import kotlin.math.max
import kotlin.math.roundToInt
@ -214,6 +234,13 @@ class AnimeWatchFragment : Fragment() {
return model.watchSources?.get(i)!!
}
fun onLangChange(i: Int) {
val selected = model.loadSelected(media)
selected.langIndex = i
model.saveSelected(media.id, selected, requireActivity())
media.selected = selected
}
fun onDubClicked(checked: Boolean) {
val selected = model.loadSelected(media)
model.watchSources?.get(selected.sourceIndex)?.selectDub = checked
@ -223,8 +250,8 @@ class AnimeWatchFragment : Fragment() {
lifecycleScope.launch(Dispatchers.IO) { model.forceLoadEpisode(media, selected.sourceIndex) }
}
fun loadEpisodes(i: Int) {
lifecycleScope.launch(Dispatchers.IO) { model.loadEpisodes(media, i) }
fun loadEpisodes(i: Int, invalidate: Boolean) {
lifecycleScope.launch(Dispatchers.IO) { model.loadEpisodes(media, i, invalidate) }
}
fun onIconPressed(viewType: Int, rev: Boolean) {
@ -262,45 +289,115 @@ class AnimeWatchFragment : Fragment() {
else getString(R.string.unsubscribed_notification)
)
}
fun onEpisodeClick(i: String) {
model.continueMedia = false
model.saveSelected(media.id, media.selected!!, requireActivity())
model.onEpisodeClick(media, i, requireActivity().supportFragmentManager)
}
@SuppressLint("NotifyDataSetChanged")
private fun reload() {
val selected = model.loadSelected(media)
//Find latest episode for subscription
selected.latest = media.anime?.episodes?.values?.maxOfOrNull { it.number.toFloatOrNull() ?: 0f } ?: 0f
selected.latest = media.userProgress?.toFloat()?.takeIf { selected.latest < it } ?: selected.latest
model.saveSelected(media.id, selected, requireActivity())
headerAdapter.handleEpisodes()
episodeAdapter.notifyItemRangeRemoved(0, episodeAdapter.arr.size)
var arr: ArrayList<Episode> = arrayListOf()
if (media.anime!!.episodes != null) {
val end = if (end != null && end!! < media.anime!!.episodes!!.size) end else null
arr.addAll(
media.anime!!.episodes!!.values.toList()
.slice(start..(end ?: (media.anime!!.episodes!!.size - 1)))
)
if (reverse)
arr = (arr.reversed() as? ArrayList<Episode>) ?: arr
fun openSettings(pkg: AnimeExtension.Installed){
val changeUIVisibility: (Boolean) -> Unit = { show ->
val activity = requireActivity() as MediaDetailsActivity
val visibility = if (show) View.VISIBLE else View.GONE
activity.findViewById<AppBarLayout>(R.id.mediaAppBar).visibility = visibility
activity.findViewById<ViewPager2>(R.id.mediaViewPager).visibility = visibility
activity.findViewById<CardView>(R.id.mediaCover).visibility = visibility
activity.findViewById<CardView>(R.id.mediaClose).visibility = visibility
try{
activity.findViewById<CustomBottomNavBar>(R.id.mediaTab).visibility = visibility
}catch (e: ClassCastException){
activity.findViewById<NavigationRailView>(R.id.mediaTab).visibility = visibility
}
activity.findViewById<FrameLayout>(R.id.fragmentExtensionsContainer).visibility =
if (show) View.GONE else View.VISIBLE
}
val allSettings = pkg.sources.filterIsInstance<ConfigurableAnimeSource>()
if (allSettings.isNotEmpty()) {
var selectedSetting = allSettings[0]
if (allSettings.size > 1) {
val names = allSettings.map { it.lang }.toTypedArray()
var selectedIndex = 0
AlertDialog.Builder(requireContext())
.setTitle("Select a Source")
.setSingleChoiceItems(names, selectedIndex) { _, which ->
selectedIndex = which
}
.setPositiveButton("OK") { dialog, _ ->
selectedSetting = allSettings[selectedIndex]
dialog.dismiss()
// Move the fragment transaction here
val fragment =
AnimeSourcePreferencesFragment().getInstance(selectedSetting.id){
changeUIVisibility(true)
loadEpisodes(media.selected!!.sourceIndex, true)
}
parentFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.slide_up, R.anim.slide_down)
.replace(R.id.fragmentExtensionsContainer, fragment)
.addToBackStack(null)
.commit()
}
.setNegativeButton("Cancel") { dialog, _ ->
dialog.cancel()
changeUIVisibility(true)
return@setNegativeButton
}
.show()
} else {
// If there's only one setting, proceed with the fragment transaction
val fragment = AnimeSourcePreferencesFragment().getInstance(selectedSetting.id){
changeUIVisibility(true)
loadEpisodes(media.selected!!.sourceIndex, true)
}
parentFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.slide_up, R.anim.slide_down)
.replace(R.id.fragmentExtensionsContainer, fragment)
.addToBackStack(null)
.commit()
}
changeUIVisibility(false)
} else {
Toast.makeText(requireContext(), "Source is not configurable", Toast.LENGTH_SHORT)
.show()
}
episodeAdapter.arr = arr
episodeAdapter.updateType(style ?: uiSettings.animeDefaultView)
episodeAdapter.notifyItemRangeInserted(0, arr.size)
}
override fun onDestroy() {
model.watchSources?.flushText()
super.onDestroy()
}
fun onEpisodeClick(i: String) {
model.continueMedia = false
model.saveSelected(media.id, media.selected!!, requireActivity())
model.onEpisodeClick(media, i, requireActivity().supportFragmentManager)
}
var state: Parcelable? = null
@SuppressLint("NotifyDataSetChanged")
private fun reload() {
val selected = model.loadSelected(media)
//Find latest episode for subscription
selected.latest =
media.anime?.episodes?.values?.maxOfOrNull { it.number.toFloatOrNull() ?: 0f } ?: 0f
selected.latest =
media.userProgress?.toFloat()?.takeIf { selected.latest < it } ?: selected.latest
model.saveSelected(media.id, selected, requireActivity())
headerAdapter.handleEpisodes()
episodeAdapter.notifyItemRangeRemoved(0, episodeAdapter.arr.size)
var arr: ArrayList<Episode> = arrayListOf()
if (media.anime!!.episodes != null) {
val end = if (end != null && end!! < media.anime!!.episodes!!.size) end else null
arr.addAll(
media.anime!!.episodes!!.values.toList()
.slice(start..(end ?: (media.anime!!.episodes!!.size - 1)))
)
if (reverse)
arr = (arr.reversed() as? ArrayList<Episode>) ?: arr
}
episodeAdapter.arr = arr
episodeAdapter.updateType(style ?: uiSettings.animeDefaultView)
episodeAdapter.notifyItemRangeInserted(0, arr.size)
}
override fun onDestroy() {
model.watchSources?.flushText()
super.onDestroy()
}
var state: Parcelable? = null
override fun onResume() {
super.onResume()
binding.mediaInfoProgressBar.visibility = progress

View file

@ -17,12 +17,17 @@ import ani.dantotsu.databinding.ItemChipBinding
import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.SourceSearchDialogFragment
import ani.dantotsu.parsers.AnimeSources
import ani.dantotsu.parsers.DynamicAnimeParser
import ani.dantotsu.parsers.DynamicMangaParser
import ani.dantotsu.parsers.MangaReadSources
import ani.dantotsu.parsers.MangaSources
import ani.dantotsu.subcriptions.Notifications.Companion.openSettings
import ani.dantotsu.subcriptions.Subscription.Companion.getChannelId
import com.google.android.material.chip.Chip
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import java.lang.IndexOutOfBoundsException
class MangaReadAdapter(
private val media: Media,
@ -50,10 +55,10 @@ class MangaReadAdapter(
}
//Source Selection
val source = media.selected!!.sourceIndex.let { if (it >= mangaReadSources.names.size) 0 else it }
var source = media.selected!!.sourceIndex.let { if (it >= mangaReadSources.names.size) 0 else it }
setLanguageList(media.selected!!.langIndex,source)
if (mangaReadSources.names.isNotEmpty() && source in 0 until mangaReadSources.names.size) {
binding.animeSource.setText(mangaReadSources.names[source])
mangaReadSources[source].apply {
binding.animeSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
@ -65,9 +70,34 @@ class MangaReadAdapter(
fragment.onSourceChange(i).apply {
binding.animeSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
source = i
setLanguageList(0,i)
}
subscribeButton(false)
fragment.loadChapters(i)
fragment.loadChapters(i, false)
}
binding.animeSourceLanguage.setOnItemClickListener { _, _, i, _ ->
// Check if 'extension' and 'selected' properties exist and are accessible
(mangaReadSources[source] as? DynamicMangaParser)?.let { ext ->
ext.sourceLanguage = i
fragment.onLangChange(i)
fragment.onSourceChange(media.selected!!.sourceIndex).apply {
binding.animeSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
setLanguageList(i, source)
}
subscribeButton(false)
fragment.loadChapters(media.selected!!.sourceIndex, true)
} ?: run {
}
}
//settings
binding.animeSourceSettings.setOnClickListener {
(mangaReadSources[source] as? DynamicMangaParser)?.let { ext ->
fragment.openSettings(ext.extension)
}
}
//Subscription
@ -224,6 +254,25 @@ class MangaReadAdapter(
}
}
fun setLanguageList(lang: Int, source: Int) {
val binding = _binding
if (mangaReadSources is MangaSources) {
val parser = mangaReadSources[source] as? DynamicMangaParser
if (parser != null) {
(mangaReadSources[source] as? DynamicMangaParser)?.let { ext ->
ext.sourceLanguage = lang
}
try {
binding?.animeSourceLanguage?.setText(parser.extension.sources[lang].lang)
}catch (e: IndexOutOfBoundsException) {
binding?.animeSourceLanguage?.setText(parser.extension.sources.firstOrNull()?.lang ?: "Unknown")
}
binding?.animeSourceLanguage?.setAdapter(ArrayAdapter(fragment.requireContext(), R.layout.item_dropdown, parser.extension.sources.map { it.lang }))
}
}
}
override fun getItemCount(): Int = 1
inner class ViewHolder(val binding: ItemAnimeWatchBinding) : RecyclerView.ViewHolder(binding.root)

View file

@ -1,11 +1,15 @@
package ani.dantotsu.media.manga
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.Toast
import androidx.cardview.widget.CardView
import androidx.core.math.MathUtils.clamp
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
@ -13,20 +17,30 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.GridLayoutManager
import androidx.viewpager2.widget.ViewPager2
import ani.dantotsu.*
import ani.dantotsu.databinding.FragmentAnimeWatchBinding
import ani.dantotsu.media.manga.mangareader.ChapterLoaderDialog
import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.MediaDetailsViewModel
import ani.dantotsu.parsers.HMangaSources
import ani.dantotsu.parsers.MangaParser
import ani.dantotsu.parsers.MangaSources
import ani.dantotsu.settings.UserInterfaceSettings
import ani.dantotsu.settings.extensionprefs.AnimeSourcePreferencesFragment
import ani.dantotsu.settings.extensionprefs.MangaSourcePreferencesFragment
import ani.dantotsu.subcriptions.Notifications
import ani.dantotsu.subcriptions.Notifications.Group.MANGA_GROUP
import ani.dantotsu.subcriptions.Subscription.Companion.getChannelId
import ani.dantotsu.subcriptions.SubscriptionHelper
import ani.dantotsu.subcriptions.SubscriptionHelper.Companion.saveSubscription
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.navigationrail.NavigationRailView
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
import eu.kanade.tachiyomi.source.ConfigurableSource
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.math.ceil
@ -185,8 +199,16 @@ open class MangaReadFragment : Fragment() {
return model.mangaReadSources?.get(i)!!
}
fun loadChapters(i: Int) {
lifecycleScope.launch(Dispatchers.IO) { model.loadMangaChapters(media, i) }
fun onLangChange(i: Int) {
val selected = model.loadSelected(media)
selected.langIndex = i
model.saveSelected(media.id, selected, requireActivity())
media.selected = selected
}
fun loadChapters(i: Int, invalidate: Boolean) {
lifecycleScope.launch(Dispatchers.IO) { model.loadMangaChapters(media, i, invalidate) }
}
fun onIconPressed(viewType: Int, rev: Boolean) {
@ -225,6 +247,75 @@ open class MangaReadFragment : Fragment() {
)
}
fun openSettings(pkg: MangaExtension.Installed){
val changeUIVisibility: (Boolean) -> Unit = { show ->
val activity = requireActivity() as MediaDetailsActivity
val visibility = if (show) View.VISIBLE else View.GONE
activity.findViewById<AppBarLayout>(R.id.mediaAppBar).visibility = visibility
activity.findViewById<ViewPager2>(R.id.mediaViewPager).visibility = visibility
activity.findViewById<CardView>(R.id.mediaCover).visibility = visibility
activity.findViewById<CardView>(R.id.mediaClose).visibility = visibility
try{
activity.findViewById<CustomBottomNavBar>(R.id.mediaTab).visibility = visibility
}catch (e: ClassCastException){
activity.findViewById<NavigationRailView>(R.id.mediaTab).visibility = visibility
}
activity.findViewById<FrameLayout>(R.id.fragmentExtensionsContainer).visibility =
if (show) View.GONE else View.VISIBLE
}
val allSettings = pkg.sources.filterIsInstance<ConfigurableSource>()
if (allSettings.isNotEmpty()) {
var selectedSetting = allSettings[0]
if (allSettings.size > 1) {
val names = allSettings.map { it.lang }.toTypedArray()
var selectedIndex = 0
AlertDialog.Builder(requireContext())
.setTitle("Select a Source")
.setSingleChoiceItems(names, selectedIndex) { _, which ->
selectedIndex = which
}
.setPositiveButton("OK") { dialog, _ ->
selectedSetting = allSettings[selectedIndex]
dialog.dismiss()
// Move the fragment transaction here
val fragment =
MangaSourcePreferencesFragment().getInstance(selectedSetting.id){
changeUIVisibility(true)
loadChapters(media.selected!!.sourceIndex, true)
}
parentFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.slide_up, R.anim.slide_down)
.replace(R.id.fragmentExtensionsContainer, fragment)
.addToBackStack(null)
.commit()
}
.setNegativeButton("Cancel") { dialog, _ ->
dialog.cancel()
changeUIVisibility(true)
return@setNegativeButton
}
.show()
} else {
// If there's only one setting, proceed with the fragment transaction
val fragment = MangaSourcePreferencesFragment().getInstance(selectedSetting.id){
changeUIVisibility(true)
loadChapters(media.selected!!.sourceIndex, true)
}
parentFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.slide_up, R.anim.slide_down)
.replace(R.id.fragmentExtensionsContainer, fragment)
.addToBackStack(null)
.commit()
}
changeUIVisibility(false)
} else {
Toast.makeText(requireContext(), "Source is not configurable", Toast.LENGTH_SHORT)
.show()
}
}
fun onMangaChapterClick(i: String) {
model.continueMedia = false
media.manga?.chapters?.get(i)?.let {