Dantotsu/app/src/main/java/ani/dantotsu/media/anime/AnimeWatchAdapter.kt
aayush262 75895d851f
Language add to extensions (#52)
* got rid of both companion object

* minor changes

* It Now show lang on extensions

* fixed

* quickfix

* android locale tuning

* toggle option to setting

* some fixes
added 2 fonts
removed Scanlators for anime

---------

Co-authored-by: rebelonion <87634197+rebelonion@users.noreply.github.com>
2023-11-21 20:33:17 -06:00

341 lines
No EOL
15 KiB
Kotlin

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
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,
private val fragment: AnimeWatchFragment,
private val watchSources: WatchSources
) : RecyclerView.Adapter<AnimeWatchAdapter.ViewHolder>() {
var subscribe: MediaDetailsActivity.PopImageButton? = null
private var _binding: ItemAnimeWatchBinding? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val bind = ItemAnimeWatchBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(bind)
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val binding = holder.binding
_binding = binding
//Youtube
if (media.anime!!.youtube != null && fragment.uiSettings.showYtButton) {
binding.animeSourceYT.visibility = View.VISIBLE
binding.animeSourceYT.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(media.anime.youtube))
fragment.requireContext().startActivity(intent)
}
}
binding.animeSourceDubbed.isChecked = media.selected!!.preferDub
binding.animeSourceDubbedText.text = if (media.selected!!.preferDub) currActivity()!!.getString(R.string.dubbed) else currActivity()!!.getString(R.string.subbed)
//PreferDub
var changing = false
binding.animeSourceDubbed.setOnCheckedChangeListener { _, isChecked ->
binding.animeSourceDubbedText.text = if (isChecked) currActivity()!!.getString(R.string.dubbed) else currActivity()!!.getString(R.string.subbed)
if (!changing) fragment.onDubClicked(isChecked)
}
//Wrong Title
binding.animeSourceSearch.setOnClickListener {
SourceSearchDialogFragment().show(fragment.requireActivity().supportFragmentManager, null)
}
//Source Selection
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 {
this.selectDub = media.selected!!.preferDub
binding.animeSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
binding.animeSourceDubbedCont.visibility =
if (isDubAvailableSeparately) View.VISIBLE else View.GONE
}
}
binding.animeSource.setAdapter(ArrayAdapter(fragment.requireContext(), R.layout.item_dropdown, watchSources.names))
binding.animeSourceTitle.isSelected = true
binding.animeSource.setOnItemClickListener { _, _, i, _ ->
fragment.onSourceChange(i).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
source = i
setLanguageList(0,i)
}
subscribeButton(false)
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,
binding.animeSourceSubscribe,
R.drawable.ic_round_notifications_active_24,
R.drawable.ic_round_notifications_none_24,
R.color.bg_opp,
R.color.violet_400,
fragment.subscribed
) {
fragment.onNotificationPressed(it, binding.animeSource.text.toString())
}
subscribeButton(false)
binding.animeSourceSubscribe.setOnLongClickListener {
openSettings(fragment.requireContext(),getChannelId(true,media.id))
}
//Icons
var reversed = media.selected!!.recyclerReversed
var style = media.selected!!.recyclerStyle ?: fragment.uiSettings.animeDefaultView
binding.animeSourceTop.rotation = if (reversed) -90f else 90f
binding.animeSourceTop.setOnClickListener {
reversed = !reversed
binding.animeSourceTop.rotation = if (reversed) -90f else 90f
fragment.onIconPressed(style, reversed)
}
var selected = when (style) {
0 -> binding.animeSourceList
1 -> binding.animeSourceGrid
2 -> binding.animeSourceCompact
else -> binding.animeSourceList
}
selected.alpha = 1f
fun selected(it: ImageView) {
selected.alpha = 0.33f
selected = it
selected.alpha = 1f
}
binding.animeSourceList.setOnClickListener {
selected(it as ImageView)
style = 0
fragment.onIconPressed(style, reversed)
}
binding.animeSourceGrid.setOnClickListener {
selected(it as ImageView)
style = 1
fragment.onIconPressed(style, reversed)
}
binding.animeSourceCompact.setOnClickListener {
selected(it as ImageView)
style = 2
fragment.onIconPressed(style, reversed)
}
binding.animeScanlatorTop.visibility= View.GONE
//Episode Handling
handleEpisodes()
}
fun subscribeButton(enabled : Boolean) {
subscribe?.enabled(enabled)
}
//Chips
@SuppressLint("SetTextI18n")
fun updateChips(limit: Int, names: Array<String>, arr: Array<Int>, selected: Int = 0) {
val binding = _binding
if (binding != null) {
val screenWidth = fragment.screenWidth.px
var select: Chip? = null
for (position in arr.indices) {
val last = if (position + 1 == arr.size) names.size else (limit * (position + 1))
val chip =
ItemChipBinding.inflate(LayoutInflater.from(fragment.context), binding.animeSourceChipGroup, false).root
chip.isCheckable = true
fun selected() {
chip.isChecked = true
binding.animeWatchChipScroll.smoothScrollTo((chip.left - screenWidth / 2) + (chip.width / 2), 0)
}
chip.text = "${names[limit * (position)]} - ${names[last - 1]}"
chip.setTextColor(ContextCompat.getColorStateList(fragment.requireContext(), R.color.chip_text_color))
chip.setOnClickListener {
selected()
fragment.onChipClicked(position, limit * (position), last - 1)
}
binding.animeSourceChipGroup.addView(chip)
if (selected == position) {
selected()
select = chip
}
}
if (select != null)
binding.animeWatchChipScroll.apply { post { scrollTo((select.left - screenWidth / 2) + (select.width / 2), 0) } }
}
}
fun clearChips() {
_binding?.animeSourceChipGroup?.removeAllViews()
}
@SuppressLint("SetTextI18n")
fun handleEpisodes() {
val binding = _binding
if (binding != null) {
if (media.anime?.episodes != null) {
val episodes = media.anime.episodes!!.keys.toTypedArray()
val anilistEp = (media.userProgress ?: 0).plus(1)
val appEp = loadData<String>("${media.id}_current_ep")?.toIntOrNull() ?: 1
var continueEp = (if (anilistEp > appEp) anilistEp else appEp).toString()
if (episodes.contains(continueEp)) {
binding.animeSourceContinue.visibility = View.VISIBLE
handleProgress(
binding.itemEpisodeProgressCont,
binding.itemEpisodeProgress,
binding.itemEpisodeProgressEmpty,
media.id,
continueEp
)
if ((binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams).weight > fragment.playerSettings.watchPercentage) {
val e = episodes.indexOf(continueEp)
if (e != -1 && e + 1 < episodes.size) {
continueEp = episodes[e + 1]
handleProgress(
binding.itemEpisodeProgressCont,
binding.itemEpisodeProgress,
binding.itemEpisodeProgressEmpty,
media.id,
continueEp
)
}
}
val ep = media.anime.episodes!![continueEp]!!
binding.itemEpisodeImage.loadImage(ep.thumb ?: FileUrl[media.banner ?: media.cover], 0)
if (ep.filler) binding.itemEpisodeFillerView.visibility = View.VISIBLE
binding.animeSourceContinueText.text =
currActivity()!!.getString(R.string.continue_episode) + "${ep.number}${if (ep.filler) " - Filler" else ""}${if (ep.title != null) "\n${ep.title}" else ""}"
binding.animeSourceContinue.setOnClickListener {
fragment.onEpisodeClick(continueEp)
}
if (fragment.continueEp) {
if ((binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams).weight < fragment.playerSettings.watchPercentage) {
binding.animeSourceContinue.performClick()
fragment.continueEp = false
}
}
} else {
binding.animeSourceContinue.visibility = View.GONE
}
binding.animeSourceProgressBar.visibility = View.GONE
if (media.anime.episodes!!.isNotEmpty())
binding.animeSourceNotFound.visibility = View.GONE
else
binding.animeSourceNotFound.visibility = View.VISIBLE
} else {
binding.animeSourceContinue.visibility = View.GONE
binding.animeSourceNotFound.visibility = View.GONE
clearChips()
binding.animeSourceProgressBar.visibility = View.VISIBLE
}
}
}
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) {
init {
//Timer
countDown(media, binding.animeSourceContainer)
}
}
}