[skip ci] feat: better empty source dialog + bruh (#428)

* feat: better empty source dialog + bruh

* fix: itemMedia bindings
This commit is contained in:
ibo 2024-06-16 07:11:11 +02:00 committed by GitHub
parent 899af3ee1a
commit eda213a765
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 310 additions and 278 deletions

View file

@ -8,7 +8,6 @@ import android.view.ViewGroup
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.startActivity import androidx.core.content.ContextCompat.startActivity
import androidx.core.view.isGone import androidx.core.view.isGone
@ -19,7 +18,7 @@ import ani.dantotsu.FileUrl
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.currActivity import ani.dantotsu.currActivity
import ani.dantotsu.databinding.DialogLayoutBinding import ani.dantotsu.databinding.DialogLayoutBinding
import ani.dantotsu.databinding.ItemAnimeWatchBinding import ani.dantotsu.databinding.ItemMediaSourceBinding
import ani.dantotsu.databinding.ItemChipBinding import ani.dantotsu.databinding.ItemChipBinding
import ani.dantotsu.displayTimer import ani.dantotsu.displayTimer
import ani.dantotsu.isOnline import ani.dantotsu.isOnline
@ -33,6 +32,7 @@ import ani.dantotsu.others.LanguageMapper
import ani.dantotsu.others.webview.CookieCatcher import ani.dantotsu.others.webview.CookieCatcher
import ani.dantotsu.parsers.AnimeSources import ani.dantotsu.parsers.AnimeSources
import ani.dantotsu.parsers.DynamicAnimeParser import ani.dantotsu.parsers.DynamicAnimeParser
import ani.dantotsu.parsers.OfflineAnimeParser
import ani.dantotsu.parsers.WatchSources import ani.dantotsu.parsers.WatchSources
import ani.dantotsu.px import ani.dantotsu.px
import ani.dantotsu.settings.FAQActivity import ani.dantotsu.settings.FAQActivity
@ -55,10 +55,10 @@ class AnimeWatchAdapter(
) : RecyclerView.Adapter<AnimeWatchAdapter.ViewHolder>() { ) : RecyclerView.Adapter<AnimeWatchAdapter.ViewHolder>() {
private var autoSelect = true private var autoSelect = true
var subscribe: MediaDetailsActivity.PopImageButton? = null var subscribe: MediaDetailsActivity.PopImageButton? = null
private var _binding: ItemAnimeWatchBinding? = null private var _binding: ItemMediaSourceBinding? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val bind = ItemAnimeWatchBinding.inflate(LayoutInflater.from(parent.context), parent, false) val bind = ItemMediaSourceBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(bind) return ViewHolder(bind)
} }
@ -73,7 +73,7 @@ class AnimeWatchAdapter(
null null
) )
} }
//Youtube // Youtube
if (media.anime?.youtube != null && PrefManager.getVal(PrefName.ShowYtButton)) { if (media.anime?.youtube != null && PrefManager.getVal(PrefName.ShowYtButton)) {
binding.animeSourceYT.visibility = View.VISIBLE binding.animeSourceYT.visibility = View.VISIBLE
binding.animeSourceYT.setOnClickListener { binding.animeSourceYT.setOnClickListener {
@ -87,7 +87,7 @@ class AnimeWatchAdapter(
R.string.subbed R.string.subbed
) )
//PreferDub // PreferDub
var changing = false var changing = false
binding.animeSourceDubbed.setOnCheckedChangeListener { _, isChecked -> binding.animeSourceDubbed.setOnCheckedChangeListener { _, isChecked ->
binding.animeSourceDubbedText.text = binding.animeSourceDubbedText.text =
@ -97,8 +97,8 @@ class AnimeWatchAdapter(
if (!changing) fragment.onDubClicked(isChecked) if (!changing) fragment.onDubClicked(isChecked)
} }
//Wrong Title // Wrong Title
binding.animeSourceSearch.setOnClickListener { binding.mediaSourceSearch.setOnClickListener {
SourceSearchDialogFragment().show( SourceSearchDialogFragment().show(
fragment.requireActivity().supportFragmentManager, fragment.requireActivity().supportFragmentManager,
null null
@ -106,37 +106,37 @@ class AnimeWatchAdapter(
} }
val offline = !isOnline(binding.root.context) || PrefManager.getVal(PrefName.OfflineMode) val offline = !isOnline(binding.root.context) || PrefManager.getVal(PrefName.OfflineMode)
binding.animeSourceNameContainer.isGone = offline binding.mediaSourceNameContainer.isGone = offline
binding.animeSourceSettings.isGone = offline binding.mediaSourceSettings.isGone = offline
binding.animeSourceSearch.isGone = offline binding.mediaSourceSearch.isGone = offline
binding.animeSourceTitle.isGone = offline binding.mediaSourceTitle.isGone = offline
//Source Selection // Source Selection
var source = var source =
media.selected!!.sourceIndex.let { if (it >= watchSources.names.size) 0 else it } media.selected!!.sourceIndex.let { if (it >= watchSources.names.size) 0 else it }
setLanguageList(media.selected!!.langIndex, source) setLanguageList(media.selected!!.langIndex, source)
if (watchSources.names.isNotEmpty() && source in 0 until watchSources.names.size) { if (watchSources.names.isNotEmpty() && source in 0 until watchSources.names.size) {
binding.animeSource.setText(watchSources.names[source]) binding.mediaSource.setText(watchSources.names[source])
watchSources[source].apply { watchSources[source].apply {
this.selectDub = media.selected!!.preferDub this.selectDub = media.selected!!.preferDub
binding.animeSourceTitle.text = showUserText binding.mediaSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } } showUserTextListener = { MainScope().launch { binding.mediaSourceTitle.text = it } }
binding.animeSourceDubbedCont.isVisible = isDubAvailableSeparately() binding.animeSourceDubbedCont.isVisible = isDubAvailableSeparately()
} }
} }
binding.animeSource.setAdapter( binding.mediaSource.setAdapter(
ArrayAdapter( ArrayAdapter(
fragment.requireContext(), fragment.requireContext(),
R.layout.item_dropdown, R.layout.item_dropdown,
watchSources.names watchSources.names
) )
) )
binding.animeSourceTitle.isSelected = true binding.mediaSourceTitle.isSelected = true
binding.animeSource.setOnItemClickListener { _, _, i, _ -> binding.mediaSource.setOnItemClickListener { _, _, i, _ ->
fragment.onSourceChange(i).apply { fragment.onSourceChange(i).apply {
binding.animeSourceTitle.text = showUserText binding.mediaSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } } showUserTextListener = { MainScope().launch { binding.mediaSourceTitle.text = it } }
changing = true changing = true
binding.animeSourceDubbed.isChecked = selectDub binding.animeSourceDubbed.isChecked = selectDub
changing = false changing = false
@ -148,15 +148,15 @@ class AnimeWatchAdapter(
fragment.loadEpisodes(i, false) fragment.loadEpisodes(i, false)
} }
binding.animeSourceLanguage.setOnItemClickListener { _, _, i, _ -> binding.mediaSourceLanguage.setOnItemClickListener { _, _, i, _ ->
// Check if 'extension' and 'selected' properties exist and are accessible // Check if 'extension' and 'selected' properties exist and are accessible
(watchSources[source] as? DynamicAnimeParser)?.let { ext -> (watchSources[source] as? DynamicAnimeParser)?.let { ext ->
ext.sourceLanguage = i ext.sourceLanguage = i
fragment.onLangChange(i) fragment.onLangChange(i)
fragment.onSourceChange(media.selected!!.sourceIndex).apply { fragment.onSourceChange(media.selected!!.sourceIndex).apply {
binding.animeSourceTitle.text = showUserText binding.mediaSourceTitle.text = showUserText
showUserTextListener = showUserTextListener =
{ MainScope().launch { binding.animeSourceTitle.text = it } } { MainScope().launch { binding.mediaSourceTitle.text = it } }
changing = true changing = true
binding.animeSourceDubbed.isChecked = selectDub binding.animeSourceDubbed.isChecked = selectDub
changing = false changing = false
@ -168,19 +168,19 @@ class AnimeWatchAdapter(
} ?: run { } } ?: run { }
} }
//settings // Settings
binding.animeSourceSettings.setOnClickListener { binding.mediaSourceSettings.setOnClickListener {
(watchSources[source] as? DynamicAnimeParser)?.let { ext -> (watchSources[source] as? DynamicAnimeParser)?.let { ext ->
fragment.openSettings(ext.extension) fragment.openSettings(ext.extension)
} }
} }
//Icons // Icons
//subscribe // Subscribe
subscribe = MediaDetailsActivity.PopImageButton( subscribe = MediaDetailsActivity.PopImageButton(
fragment.lifecycleScope, fragment.lifecycleScope,
binding.animeSourceSubscribe, binding.mediaSourceSubscribe,
R.drawable.ic_round_notifications_active_24, R.drawable.ic_round_notifications_active_24,
R.drawable.ic_round_notifications_none_24, R.drawable.ic_round_notifications_none_24,
R.color.bg_opp, R.color.bg_opp,
@ -188,17 +188,17 @@ class AnimeWatchAdapter(
fragment.subscribed, fragment.subscribed,
true true
) { ) {
fragment.onNotificationPressed(it, binding.animeSource.text.toString()) fragment.onNotificationPressed(it, binding.mediaSource.text.toString())
} }
subscribeButton(false) subscribeButton(false)
binding.animeSourceSubscribe.setOnLongClickListener { binding.mediaSourceSubscribe.setOnLongClickListener {
openSettings(fragment.requireContext(), CHANNEL_SUBSCRIPTION_CHECK) openSettings(fragment.requireContext(), CHANNEL_SUBSCRIPTION_CHECK)
} }
//Nested Button // Nested Button
binding.animeNestedButton.setOnClickListener { binding.mediaNestedButton.setOnClickListener {
val dialogBinding = DialogLayoutBinding.inflate(fragment.layoutInflater) val dialogBinding = DialogLayoutBinding.inflate(fragment.layoutInflater)
dialogBinding.apply { dialogBinding.apply {
var refresh = false var refresh = false
@ -207,26 +207,26 @@ class AnimeWatchAdapter(
var style = var style =
media.selected!!.recyclerStyle ?: PrefManager.getVal(PrefName.AnimeDefaultView) media.selected!!.recyclerStyle ?: PrefManager.getVal(PrefName.AnimeDefaultView)
animeSourceTop.rotation = if (reversed) -90f else 90f mediaSourceTop.rotation = if (reversed) -90f else 90f
sortText.text = if (reversed) "Down to Up" else "Up to Down" sortText.text = if (reversed) "Down to Up" else "Up to Down"
animeSourceTop.setOnClickListener { mediaSourceTop.setOnClickListener {
reversed = !reversed reversed = !reversed
animeSourceTop.rotation = if (reversed) -90f else 90f mediaSourceTop.rotation = if (reversed) -90f else 90f
sortText.text = if (reversed) "Down to Up" else "Up to Down" sortText.text = if (reversed) "Down to Up" else "Up to Down"
run = true run = true
} }
//Grids // Grids
var selected = when (style) { var selected = when (style) {
0 -> animeSourceList 0 -> mediaSourceList
1 -> animeSourceGrid 1 -> mediaSourceGrid
2 -> animeSourceCompact 2 -> mediaSourceCompact
else -> animeSourceList else -> mediaSourceList
} }
when (style) { when (style) {
0 -> layoutText.setText(R.string.list) 0 -> layoutText.setText(R.string.list)
1 -> layoutText.setText(R.string.grid) 1 -> layoutText.setText(R.string.grid)
2 -> layoutText.setText(R.string.compact) 2 -> layoutText.setText(R.string.compact)
else -> animeSourceList else -> mediaSourceList
} }
selected.alpha = 1f selected.alpha = 1f
fun selected(it: ImageButton) { fun selected(it: ImageButton) {
@ -234,29 +234,29 @@ class AnimeWatchAdapter(
selected = it selected = it
selected.alpha = 1f selected.alpha = 1f
} }
animeSourceList.setOnClickListener { mediaSourceList.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 0 style = 0
layoutText.setText(R.string.list) layoutText.setText(R.string.list)
run = true run = true
} }
animeSourceGrid.setOnClickListener { mediaSourceGrid.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 1 style = 1
layoutText.setText(R.string.grid) layoutText.setText(R.string.grid)
run = true run = true
} }
animeSourceCompact.setOnClickListener { mediaSourceCompact.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 2 style = 2
layoutText.setText(R.string.compact) layoutText.setText(R.string.compact)
run = true run = true
} }
animeWebviewContainer.setOnClickListener { mediaWebviewContainer.setOnClickListener {
if (!WebViewUtil.supportsWebView(fragment.requireContext())) { if (!WebViewUtil.supportsWebView(fragment.requireContext())) {
toast(R.string.webview_not_installed) toast(R.string.webview_not_installed)
} }
//start CookieCatcher activity // Start CookieCatcher activity
if (watchSources.names.isNotEmpty() && source in 0 until watchSources.names.size) { if (watchSources.names.isNotEmpty() && source in 0 until watchSources.names.size) {
val sourceAHH = watchSources[source] as? DynamicAnimeParser val sourceAHH = watchSources[source] as? DynamicAnimeParser
val sourceHttp = val sourceHttp =
@ -279,8 +279,8 @@ class AnimeWatchAdapter(
} }
} }
//hidden // Hidden
animeScanlatorContainer.visibility = View.GONE mangaScanlatorContainer.visibility = View.GONE
animeDownloadContainer.visibility = View.GONE animeDownloadContainer.visibility = View.GONE
fragment.requireContext().customAlertDialog().apply { fragment.requireContext().customAlertDialog().apply {
setTitle("Options") setTitle("Options")
@ -296,7 +296,7 @@ class AnimeWatchAdapter(
} }
} }
} }
//Episode Handling // Episode Handling
handleEpisodes() handleEpisodes()
} }
@ -304,7 +304,7 @@ class AnimeWatchAdapter(
subscribe?.enabled(enabled) subscribe?.enabled(enabled)
} }
//Chips // Chips
fun updateChips(limit: Int, names: Array<String>, arr: Array<Int>, selected: Int = 0) { fun updateChips(limit: Int, names: Array<String>, arr: Array<Int>, selected: Int = 0) {
val binding = _binding val binding = _binding
if (binding != null) { if (binding != null) {
@ -315,13 +315,13 @@ class AnimeWatchAdapter(
val chip = val chip =
ItemChipBinding.inflate( ItemChipBinding.inflate(
LayoutInflater.from(fragment.context), LayoutInflater.from(fragment.context),
binding.animeSourceChipGroup, binding.mediaSourceChipGroup,
false false
).root ).root
chip.isCheckable = true chip.isCheckable = true
fun selected() { fun selected() {
chip.isChecked = true chip.isChecked = true
binding.animeWatchChipScroll.smoothScrollTo( binding.mediaWatchChipScroll.smoothScrollTo(
(chip.left - screenWidth / 2) + (chip.width / 2), (chip.left - screenWidth / 2) + (chip.width / 2),
0 0
) )
@ -340,14 +340,14 @@ class AnimeWatchAdapter(
selected() selected()
fragment.onChipClicked(position, limit * (position), last - 1) fragment.onChipClicked(position, limit * (position), last - 1)
} }
binding.animeSourceChipGroup.addView(chip) binding.mediaSourceChipGroup.addView(chip)
if (selected == position) { if (selected == position) {
selected() selected()
select = chip select = chip
} }
} }
if (select != null) if (select != null)
binding.animeWatchChipScroll.apply { binding.mediaWatchChipScroll.apply {
post { post {
scrollTo( scrollTo(
(select.left - screenWidth / 2) + (select.width / 2), (select.left - screenWidth / 2) + (select.width / 2),
@ -359,7 +359,7 @@ class AnimeWatchAdapter(
} }
fun clearChips() { fun clearChips() {
_binding?.animeSourceChipGroup?.removeAllViews() _binding?.mediaSourceChipGroup?.removeAllViews()
} }
fun handleEpisodes() { fun handleEpisodes() {
@ -375,15 +375,15 @@ class AnimeWatchAdapter(
var continueEp = (if (anilistEp > appEp) anilistEp else appEp).toString() var continueEp = (if (anilistEp > appEp) anilistEp else appEp).toString()
if (episodes.contains(continueEp)) { if (episodes.contains(continueEp)) {
binding.animeSourceContinue.visibility = View.VISIBLE binding.sourceContinue.visibility = View.VISIBLE
handleProgress( handleProgress(
binding.itemEpisodeProgressCont, binding.itemMediaProgressCont,
binding.itemEpisodeProgress, binding.itemMediaProgress,
binding.itemEpisodeProgressEmpty, binding.itemMediaProgressEmpty,
media.id, media.id,
continueEp continueEp
) )
if ((binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams).weight > PrefManager.getVal<Float>( if ((binding.itemMediaProgress.layoutParams as LinearLayout.LayoutParams).weight > PrefManager.getVal<Float>(
PrefName.WatchPercentage PrefName.WatchPercentage
) )
) { ) {
@ -391,9 +391,9 @@ class AnimeWatchAdapter(
if (e != -1 && e + 1 < episodes.size) { if (e != -1 && e + 1 < episodes.size) {
continueEp = episodes[e + 1] continueEp = episodes[e + 1]
handleProgress( handleProgress(
binding.itemEpisodeProgressCont, binding.itemMediaProgressCont,
binding.itemEpisodeProgress, binding.itemMediaProgress,
binding.itemEpisodeProgressEmpty, binding.itemMediaProgressEmpty,
media.id, media.id,
continueEp continueEp
) )
@ -403,51 +403,63 @@ class AnimeWatchAdapter(
val cleanedTitle = ep.title?.let { MediaNameAdapter.removeEpisodeNumber(it) } val cleanedTitle = ep.title?.let { MediaNameAdapter.removeEpisodeNumber(it) }
binding.itemEpisodeImage.loadImage( binding.itemMediaImage.loadImage(
ep.thumb ?: FileUrl[media.banner ?: media.cover], 0 ep.thumb ?: FileUrl[media.banner ?: media.cover], 0
) )
if (ep.filler) binding.itemEpisodeFillerView.visibility = View.VISIBLE if (ep.filler) binding.itemEpisodeFillerView.visibility = View.VISIBLE
binding.animeSourceContinueText.text = binding.mediaSourceContinueText.text =
currActivity()!!.getString( currActivity()!!.getString(
R.string.continue_episode, ep.number, if (ep.filler) R.string.continue_episode, ep.number, if (ep.filler)
currActivity()!!.getString(R.string.filler_tag) currActivity()!!.getString(R.string.filler_tag)
else else
"", cleanedTitle "", cleanedTitle
) )
binding.animeSourceContinue.setOnClickListener { binding.sourceContinue.setOnClickListener {
fragment.onEpisodeClick(continueEp) fragment.onEpisodeClick(continueEp)
} }
if (fragment.continueEp) { if (fragment.continueEp) {
if ( if (
(binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams) (binding.itemMediaProgress.layoutParams as LinearLayout.LayoutParams)
.weight < PrefManager.getVal<Float>(PrefName.WatchPercentage) .weight < PrefManager.getVal<Float>(PrefName.WatchPercentage)
) { ) {
binding.animeSourceContinue.performClick() binding.sourceContinue.performClick()
fragment.continueEp = false fragment.continueEp = false
} }
} }
} else { } else {
binding.animeSourceContinue.visibility = View.GONE binding.sourceContinue.visibility = View.GONE
} }
binding.animeSourceProgressBar.visibility = View.GONE binding.sourceProgressBar.visibility = View.GONE
val sourceFound = media.anime.episodes!!.isNotEmpty() val sourceFound = media.anime.episodes!!.isNotEmpty()
binding.animeSourceNotFound.isGone = sourceFound val isDownloadedSource = watchSources[media.selected!!.sourceIndex] is OfflineAnimeParser
if (isDownloadedSource) {
binding.sourceNotFound.text = if (sourceFound) {
currActivity()!!.getString(R.string.source_not_found)
} else {
currActivity()!!.getString(R.string.download_not_found)
}
} else {
binding.sourceNotFound.text = currActivity()!!.getString(R.string.source_not_found)
}
binding.sourceNotFound.isGone = sourceFound
binding.faqbutton.isGone = sourceFound binding.faqbutton.isGone = sourceFound
if (!sourceFound && PrefManager.getVal(PrefName.SearchSources) && autoSelect) { if (!sourceFound && PrefManager.getVal(PrefName.SearchSources) && autoSelect) {
if (binding.animeSource.adapter.count > media.selected!!.sourceIndex + 1) { if (binding.mediaSource.adapter.count > media.selected!!.sourceIndex + 1) {
val nextIndex = media.selected!!.sourceIndex + 1 val nextIndex = media.selected!!.sourceIndex + 1
binding.animeSource.setText( binding.mediaSource.setText(
binding.animeSource.adapter binding.mediaSource.adapter
.getItem(nextIndex).toString(), false .getItem(nextIndex).toString(), false
) )
fragment.onSourceChange(nextIndex).apply { fragment.onSourceChange(nextIndex).apply {
binding.animeSourceTitle.text = showUserText binding.mediaSourceTitle.text = showUserText
showUserTextListener = showUserTextListener =
{ MainScope().launch { binding.animeSourceTitle.text = it } } { MainScope().launch { binding.mediaSourceTitle.text = it } }
binding.animeSourceDubbed.isChecked = selectDub binding.animeSourceDubbed.isChecked = selectDub
binding.animeSourceDubbedCont.isVisible = isDubAvailableSeparately() binding.animeSourceDubbedCont.isVisible = isDubAvailableSeparately()
setLanguageList(0, nextIndex) setLanguageList(0, nextIndex)
@ -456,13 +468,13 @@ class AnimeWatchAdapter(
fragment.loadEpisodes(nextIndex, false) fragment.loadEpisodes(nextIndex, false)
} }
} }
binding.animeSource.setOnClickListener { autoSelect = false } binding.mediaSource.setOnClickListener { autoSelect = false }
} else { } else {
binding.animeSourceContinue.visibility = View.GONE binding.sourceContinue.visibility = View.GONE
binding.animeSourceNotFound.visibility = View.GONE binding.sourceNotFound.visibility = View.GONE
binding.faqbutton.visibility = View.GONE binding.faqbutton.visibility = View.GONE
clearChips() clearChips()
binding.animeSourceProgressBar.visibility = View.VISIBLE binding.sourceProgressBar.visibility = View.VISIBLE
} }
} }
} }
@ -476,9 +488,9 @@ class AnimeWatchAdapter(
ext.sourceLanguage = lang ext.sourceLanguage = lang
} }
try { try {
binding?.animeSourceLanguage?.setText(parser.extension.sources[lang].lang) binding?.mediaSourceLanguage?.setText(parser.extension.sources[lang].lang)
} catch (e: IndexOutOfBoundsException) { } catch (e: IndexOutOfBoundsException) {
binding?.animeSourceLanguage?.setText( binding?.mediaSourceLanguage?.setText(
parser.extension.sources.firstOrNull()?.lang ?: "Unknown" parser.extension.sources.firstOrNull()?.lang ?: "Unknown"
) )
} }
@ -489,9 +501,9 @@ class AnimeWatchAdapter(
) )
val items = adapter.count val items = adapter.count
binding?.animeSourceLanguageContainer?.visibility = binding?.mediaSourceLanguageContainer?.visibility =
if (items > 1) View.VISIBLE else View.GONE if (items > 1) View.VISIBLE else View.GONE
binding?.animeSourceLanguage?.setAdapter(adapter) binding?.mediaSourceLanguage?.setAdapter(adapter)
} }
} }
@ -499,7 +511,7 @@ class AnimeWatchAdapter(
override fun getItemCount(): Int = 1 override fun getItemCount(): Int = 1
inner class ViewHolder(val binding: ItemAnimeWatchBinding) : inner class ViewHolder(val binding: ItemMediaSourceBinding) :
RecyclerView.ViewHolder(binding.root) { RecyclerView.ViewHolder(binding.root) {
init { init {
displayTimer(media, binding.animeSourceContainer) displayTimer(media, binding.animeSourceContainer)

View file

@ -32,7 +32,7 @@ import ani.dantotsu.FileUrl
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.addons.download.DownloadAddonManager import ani.dantotsu.addons.download.DownloadAddonManager
import ani.dantotsu.connections.anilist.api.MediaStreamingEpisode import ani.dantotsu.connections.anilist.api.MediaStreamingEpisode
import ani.dantotsu.databinding.FragmentAnimeWatchBinding import ani.dantotsu.databinding.FragmentMediaSourceBinding
import ani.dantotsu.download.DownloadedType import ani.dantotsu.download.DownloadedType
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.download.DownloadsManager.Companion.compareName import ani.dantotsu.download.DownloadsManager.Companion.compareName
@ -81,7 +81,7 @@ import kotlin.math.max
import kotlin.math.roundToInt import kotlin.math.roundToInt
class AnimeWatchFragment : Fragment() { class AnimeWatchFragment : Fragment() {
private var _binding: FragmentAnimeWatchBinding? = null private var _binding: FragmentMediaSourceBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private val model: MediaDetailsViewModel by activityViewModels() private val model: MediaDetailsViewModel by activityViewModels()
@ -108,7 +108,7 @@ class AnimeWatchFragment : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
_binding = FragmentAnimeWatchBinding.inflate(inflater, container, false) _binding = FragmentMediaSourceBinding.inflate(inflater, container, false)
return _binding?.root return _binding?.root
} }
@ -129,7 +129,7 @@ class AnimeWatchFragment : Fragment() {
) )
binding.animeSourceRecycler.updatePadding(bottom = binding.animeSourceRecycler.paddingBottom + navBarHeight) binding.mediaSourceRecycler.updatePadding(bottom = binding.mediaSourceRecycler.paddingBottom + navBarHeight)
screenWidth = resources.displayMetrics.widthPixels.dp screenWidth = resources.displayMetrics.widthPixels.dp
var maxGridSize = (screenWidth / 100f).roundToInt() var maxGridSize = (screenWidth / 100f).roundToInt()
@ -153,13 +153,13 @@ class AnimeWatchFragment : Fragment() {
} }
} }
binding.animeSourceRecycler.layoutManager = gridLayoutManager binding.mediaSourceRecycler.layoutManager = gridLayoutManager
binding.ScrollTop.setOnClickListener { binding.ScrollTop.setOnClickListener {
binding.animeSourceRecycler.scrollToPosition(10) binding.mediaSourceRecycler.scrollToPosition(10)
binding.animeSourceRecycler.smoothScrollToPosition(0) binding.mediaSourceRecycler.smoothScrollToPosition(0)
} }
binding.animeSourceRecycler.addOnScrollListener(object : RecyclerView.OnScrollListener() { binding.mediaSourceRecycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy) super.onScrolled(recyclerView, dx, dy)
@ -173,7 +173,7 @@ class AnimeWatchFragment : Fragment() {
} }
}) })
model.scrolledToTop.observe(viewLifecycleOwner) { model.scrolledToTop.observe(viewLifecycleOwner) {
if (it) binding.animeSourceRecycler.scrollToPosition(0) if (it) binding.mediaSourceRecycler.scrollToPosition(0)
} }
continueEp = model.continueMedia ?: false continueEp = model.continueMedia ?: false
@ -206,7 +206,7 @@ class AnimeWatchFragment : Fragment() {
offlineMode = offlineMode offlineMode = offlineMode
) )
binding.animeSourceRecycler.adapter = binding.mediaSourceRecycler.adapter =
ConcatAdapter(headerAdapter, episodeAdapter) ConcatAdapter(headerAdapter, episodeAdapter)
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
@ -267,7 +267,7 @@ class AnimeWatchFragment : Fragment() {
} }
media.anime?.episodes = episodes media.anime?.episodes = episodes
//CHIP GROUP // CHIP GROUP
val total = episodes.size val total = episodes.size
val divisions = total.toDouble() / 10 val divisions = total.toDouble() / 10
start = 0 start = 0
@ -635,7 +635,7 @@ class AnimeWatchFragment : Fragment() {
private fun reload() { private fun reload() {
val selected = model.loadSelected(media) val selected = model.loadSelected(media)
//Find latest episode for subscription // Find latest episode for subscription
selected.latest = selected.latest =
media.anime?.episodes?.values?.maxOfOrNull { it.number.toFloatOrNull() ?: 0f } ?: 0f media.anime?.episodes?.values?.maxOfOrNull { it.number.toFloatOrNull() ?: 0f } ?: 0f
selected.latest = selected.latest =
@ -679,14 +679,14 @@ class AnimeWatchFragment : Fragment() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
binding.mediaInfoProgressBar.visibility = progress binding.mediaInfoProgressBar.visibility = progress
binding.animeSourceRecycler.layoutManager?.onRestoreInstanceState(state) binding.mediaSourceRecycler.layoutManager?.onRestoreInstanceState(state)
requireActivity().setNavigationTheme() requireActivity().setNavigationTheme()
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
state = binding.animeSourceRecycler.layoutManager?.onSaveInstanceState() state = binding.mediaSourceRecycler.layoutManager?.onSaveInstanceState()
} }
companion object { companion object {

View file

@ -107,8 +107,8 @@ class EpisodeAdapter(
val thumb = val thumb =
ep.thumb?.let { if (it.url.isNotEmpty()) GlideUrl(it.url) { it.headers } else null } ep.thumb?.let { if (it.url.isNotEmpty()) GlideUrl(it.url) { it.headers } else null }
Glide.with(binding.itemEpisodeImage).load(thumb ?: media.cover).override(400, 0) Glide.with(binding.itemMediaImage).load(thumb ?: media.cover).override(400, 0)
.into(binding.itemEpisodeImage) .into(binding.itemMediaImage)
binding.itemEpisodeNumber.text = ep.number binding.itemEpisodeNumber.text = ep.number
binding.itemEpisodeTitle.text = if (ep.number == title) "Episode $title" else title binding.itemEpisodeTitle.text = if (ep.number == title) "Episode $title" else title
@ -141,9 +141,9 @@ class EpisodeAdapter(
} }
handleProgress( handleProgress(
binding.itemEpisodeProgressCont, binding.itemMediaProgressCont,
binding.itemEpisodeProgress, binding.itemMediaProgress,
binding.itemEpisodeProgressEmpty, binding.itemMediaProgressEmpty,
media.id, media.id,
ep.number ep.number
) )
@ -155,8 +155,8 @@ class EpisodeAdapter(
val thumb = val thumb =
ep.thumb?.let { if (it.url.isNotEmpty()) GlideUrl(it.url) { it.headers } else null } ep.thumb?.let { if (it.url.isNotEmpty()) GlideUrl(it.url) { it.headers } else null }
Glide.with(binding.itemEpisodeImage).load(thumb ?: media.cover).override(400, 0) Glide.with(binding.itemMediaImage).load(thumb ?: media.cover).override(400, 0)
.into(binding.itemEpisodeImage) .into(binding.itemMediaImage)
binding.itemEpisodeNumber.text = ep.number binding.itemEpisodeNumber.text = ep.number
binding.itemEpisodeTitle.text = title binding.itemEpisodeTitle.text = title
@ -184,9 +184,9 @@ class EpisodeAdapter(
binding.itemEpisodeViewed.visibility = View.GONE binding.itemEpisodeViewed.visibility = View.GONE
} }
handleProgress( handleProgress(
binding.itemEpisodeProgressCont, binding.itemMediaProgressCont,
binding.itemEpisodeProgress, binding.itemMediaProgress,
binding.itemEpisodeProgressEmpty, binding.itemMediaProgressEmpty,
media.id, media.id,
ep.number ep.number
) )
@ -209,9 +209,9 @@ class EpisodeAdapter(
} }
} }
handleProgress( handleProgress(
binding.itemEpisodeProgressCont, binding.itemMediaProgressCont,
binding.itemEpisodeProgress, binding.itemMediaProgress,
binding.itemEpisodeProgressEmpty, binding.itemMediaProgressEmpty,
media.id, media.id,
ep.number ep.number
) )

View file

@ -1,6 +1,5 @@
package ani.dantotsu.media.manga package ani.dantotsu.media.manga
import android.app.AlertDialog
import android.content.Intent import android.content.Intent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -21,7 +20,7 @@ import ani.dantotsu.currActivity
import ani.dantotsu.currContext import ani.dantotsu.currContext
import ani.dantotsu.databinding.CustomDialogLayoutBinding import ani.dantotsu.databinding.CustomDialogLayoutBinding
import ani.dantotsu.databinding.DialogLayoutBinding import ani.dantotsu.databinding.DialogLayoutBinding
import ani.dantotsu.databinding.ItemAnimeWatchBinding import ani.dantotsu.databinding.ItemMediaSourceBinding
import ani.dantotsu.databinding.ItemChipBinding import ani.dantotsu.databinding.ItemChipBinding
import ani.dantotsu.isOnline import ani.dantotsu.isOnline
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
@ -36,6 +35,7 @@ import ani.dantotsu.others.webview.CookieCatcher
import ani.dantotsu.parsers.DynamicMangaParser import ani.dantotsu.parsers.DynamicMangaParser
import ani.dantotsu.parsers.MangaReadSources import ani.dantotsu.parsers.MangaReadSources
import ani.dantotsu.parsers.MangaSources import ani.dantotsu.parsers.MangaSources
import ani.dantotsu.parsers.OfflineMangaParser
import ani.dantotsu.px import ani.dantotsu.px
import ani.dantotsu.settings.FAQActivity import ani.dantotsu.settings.FAQActivity
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
@ -57,13 +57,13 @@ class MangaReadAdapter(
) : RecyclerView.Adapter<MangaReadAdapter.ViewHolder>() { ) : RecyclerView.Adapter<MangaReadAdapter.ViewHolder>() {
var subscribe: MediaDetailsActivity.PopImageButton? = null var subscribe: MediaDetailsActivity.PopImageButton? = null
private var _binding: ItemAnimeWatchBinding? = null private var _binding: ItemMediaSourceBinding? = null
val hiddenScanlators = mutableListOf<String>() val hiddenScanlators = mutableListOf<String>()
var scanlatorSelectionListener: ScanlatorSelectionListener? = null var scanlatorSelectionListener: ScanlatorSelectionListener? = null
var options = listOf<String>() var options = listOf<String>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val bind = ItemAnimeWatchBinding.inflate(LayoutInflater.from(parent.context), parent, false) val bind = ItemMediaSourceBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(bind) return ViewHolder(bind)
} }
@ -72,14 +72,14 @@ class MangaReadAdapter(
_binding = binding _binding = binding
binding.sourceTitle.setText(R.string.chaps) binding.sourceTitle.setText(R.string.chaps)
//Fuck u launch // Fuck u launch
binding.faqbutton.setOnClickListener { binding.faqbutton.setOnClickListener {
val intent = Intent(fragment.requireContext(), FAQActivity::class.java) val intent = Intent(fragment.requireContext(), FAQActivity::class.java)
startActivity(fragment.requireContext(), intent, null) startActivity(fragment.requireContext(), intent, null)
} }
//Wrong Title // Wrong Title
binding.animeSourceSearch.setOnClickListener { binding.mediaSourceSearch.setOnClickListener {
SourceSearchDialogFragment().show( SourceSearchDialogFragment().show(
fragment.requireActivity().supportFragmentManager, fragment.requireActivity().supportFragmentManager,
null null
@ -87,54 +87,54 @@ class MangaReadAdapter(
} }
val offline = !isOnline(binding.root.context) || PrefManager.getVal(PrefName.OfflineMode) val offline = !isOnline(binding.root.context) || PrefManager.getVal(PrefName.OfflineMode)
binding.animeSourceNameContainer.isGone = offline binding.mediaSourceNameContainer.isGone = offline
binding.animeSourceSettings.isGone = offline binding.mediaSourceSettings.isGone = offline
binding.animeSourceSearch.isGone = offline binding.mediaSourceSearch.isGone = offline
binding.animeSourceTitle.isGone = offline binding.mediaSourceTitle.isGone = offline
//Source Selection // Source Selection
var source = var source =
media.selected!!.sourceIndex.let { if (it >= mangaReadSources.names.size) 0 else it } media.selected!!.sourceIndex.let { if (it >= mangaReadSources.names.size) 0 else it }
setLanguageList(media.selected!!.langIndex, source) setLanguageList(media.selected!!.langIndex, source)
if (mangaReadSources.names.isNotEmpty() && source in 0 until mangaReadSources.names.size) { if (mangaReadSources.names.isNotEmpty() && source in 0 until mangaReadSources.names.size) {
binding.animeSource.setText(mangaReadSources.names[source]) binding.mediaSource.setText(mangaReadSources.names[source])
mangaReadSources[source].apply { mangaReadSources[source].apply {
binding.animeSourceTitle.text = showUserText binding.mediaSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } } showUserTextListener = { MainScope().launch { binding.mediaSourceTitle.text = it } }
} }
} }
media.selected?.scanlators?.let { media.selected?.scanlators?.let {
hiddenScanlators.addAll(it) hiddenScanlators.addAll(it)
} }
binding.animeSource.setAdapter( binding.mediaSource.setAdapter(
ArrayAdapter( ArrayAdapter(
fragment.requireContext(), fragment.requireContext(),
R.layout.item_dropdown, R.layout.item_dropdown,
mangaReadSources.names mangaReadSources.names
) )
) )
binding.animeSourceTitle.isSelected = true binding.mediaSourceTitle.isSelected = true
binding.animeSource.setOnItemClickListener { _, _, i, _ -> binding.mediaSource.setOnItemClickListener { _, _, i, _ ->
fragment.onSourceChange(i).apply { fragment.onSourceChange(i).apply {
binding.animeSourceTitle.text = showUserText binding.mediaSourceTitle.text = showUserText
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } } showUserTextListener = { MainScope().launch { binding.mediaSourceTitle.text = it } }
source = i source = i
setLanguageList(0, i) setLanguageList(0, i)
} }
subscribeButton(false) subscribeButton(false)
//invalidate if it's the last source // Invalidate if it's the last source
val invalidate = i == mangaReadSources.names.size - 1 val invalidate = i == mangaReadSources.names.size - 1
fragment.loadChapters(i, invalidate) fragment.loadChapters(i, invalidate)
} }
binding.animeSourceLanguage.setOnItemClickListener { _, _, i, _ -> binding.mediaSourceLanguage.setOnItemClickListener { _, _, i, _ ->
// Check if 'extension' and 'selected' properties exist and are accessible // Check if 'extension' and 'selected' properties exist and are accessible
(mangaReadSources[source] as? DynamicMangaParser)?.let { ext -> (mangaReadSources[source] as? DynamicMangaParser)?.let { ext ->
ext.sourceLanguage = i ext.sourceLanguage = i
fragment.onLangChange(i, ext.saveName) fragment.onLangChange(i, ext.saveName)
fragment.onSourceChange(media.selected!!.sourceIndex).apply { fragment.onSourceChange(media.selected!!.sourceIndex).apply {
binding.animeSourceTitle.text = showUserText binding.mediaSourceTitle.text = showUserText
showUserTextListener = showUserTextListener =
{ MainScope().launch { binding.animeSourceTitle.text = it } } { MainScope().launch { binding.mediaSourceTitle.text = it } }
setLanguageList(i, source) setLanguageList(i, source)
} }
subscribeButton(false) subscribeButton(false)
@ -143,17 +143,17 @@ class MangaReadAdapter(
} }
} }
//settings // Settings
binding.animeSourceSettings.setOnClickListener { binding.mediaSourceSettings.setOnClickListener {
(mangaReadSources[source] as? DynamicMangaParser)?.let { ext -> (mangaReadSources[source] as? DynamicMangaParser)?.let { ext ->
fragment.openSettings(ext.extension) fragment.openSettings(ext.extension)
} }
} }
//Grids // Grids
subscribe = MediaDetailsActivity.PopImageButton( subscribe = MediaDetailsActivity.PopImageButton(
fragment.lifecycleScope, fragment.lifecycleScope,
binding.animeSourceSubscribe, binding.mediaSourceSubscribe,
R.drawable.ic_round_notifications_active_24, R.drawable.ic_round_notifications_active_24,
R.drawable.ic_round_notifications_none_24, R.drawable.ic_round_notifications_none_24,
R.color.bg_opp, R.color.bg_opp,
@ -161,16 +161,16 @@ class MangaReadAdapter(
fragment.subscribed, fragment.subscribed,
true true
) { ) {
fragment.onNotificationPressed(it, binding.animeSource.text.toString()) fragment.onNotificationPressed(it, binding.mediaSource.text.toString())
} }
subscribeButton(false) subscribeButton(false)
binding.animeSourceSubscribe.setOnLongClickListener { binding.mediaSourceSubscribe.setOnLongClickListener {
openSettings(fragment.requireContext(), CHANNEL_SUBSCRIPTION_CHECK) openSettings(fragment.requireContext(), CHANNEL_SUBSCRIPTION_CHECK)
} }
binding.animeNestedButton.setOnClickListener { binding.mediaNestedButton.setOnClickListener {
val dialogBinding = DialogLayoutBinding.inflate(fragment.layoutInflater) val dialogBinding = DialogLayoutBinding.inflate(fragment.layoutInflater)
var refresh = false var refresh = false
var run = false var run = false
@ -178,26 +178,26 @@ class MangaReadAdapter(
var style = var style =
media.selected!!.recyclerStyle ?: PrefManager.getVal(PrefName.MangaDefaultView) media.selected!!.recyclerStyle ?: PrefManager.getVal(PrefName.MangaDefaultView)
dialogBinding.apply { dialogBinding.apply {
animeSourceTop.rotation = if (reversed) -90f else 90f mediaSourceTop.rotation = if (reversed) -90f else 90f
sortText.text = if (reversed) "Down to Up" else "Up to Down" sortText.text = if (reversed) "Down to Up" else "Up to Down"
animeSourceTop.setOnClickListener { mediaSourceTop.setOnClickListener {
reversed = !reversed reversed = !reversed
animeSourceTop.rotation = if (reversed) -90f else 90f mediaSourceTop.rotation = if (reversed) -90f else 90f
sortText.text = if (reversed) "Down to Up" else "Up to Down" sortText.text = if (reversed) "Down to Up" else "Up to Down"
run = true run = true
} }
//Grids // Grids
animeSourceGrid.visibility = View.GONE mediaSourceGrid.visibility = View.GONE
var selected = when (style) { var selected = when (style) {
0 -> animeSourceList 0 -> mediaSourceList
1 -> animeSourceCompact 1 -> mediaSourceCompact
else -> animeSourceList else -> mediaSourceList
} }
when (style) { when (style) {
0 -> layoutText.setText(R.string.list) 0 -> layoutText.setText(R.string.list)
1 -> layoutText.setText(R.string.compact) 1 -> layoutText.setText(R.string.compact)
else -> animeSourceList else -> mediaSourceList
} }
selected.alpha = 1f selected.alpha = 1f
fun selected(it: ImageButton) { fun selected(it: ImageButton) {
@ -205,23 +205,23 @@ class MangaReadAdapter(
selected = it selected = it
selected.alpha = 1f selected.alpha = 1f
} }
animeSourceList.setOnClickListener { mediaSourceList.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 0 style = 0
layoutText.setText(R.string.list) layoutText.setText(R.string.list)
run = true run = true
} }
animeSourceCompact.setOnClickListener { mediaSourceCompact.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 1 style = 1
layoutText.setText(R.string.compact) layoutText.setText(R.string.compact)
run = true run = true
} }
animeWebviewContainer.setOnClickListener { mediaWebviewContainer.setOnClickListener {
if (!WebViewUtil.supportsWebView(fragment.requireContext())) { if (!WebViewUtil.supportsWebView(fragment.requireContext())) {
toast(R.string.webview_not_installed) toast(R.string.webview_not_installed)
} }
//start CookieCatcher activity // Start CookieCatcher activity
if (mangaReadSources.names.isNotEmpty() && source in 0 until mangaReadSources.names.size) { if (mangaReadSources.names.isNotEmpty() && source in 0 until mangaReadSources.names.size) {
val sourceAHH = mangaReadSources[source] as? DynamicMangaParser val sourceAHH = mangaReadSources[source] as? DynamicMangaParser
val sourceHttp = sourceAHH?.extension?.sources?.firstOrNull() as? HttpSource val sourceHttp = sourceAHH?.extension?.sources?.firstOrNull() as? HttpSource
@ -236,10 +236,10 @@ class MangaReadAdapter(
} }
} }
//Multi download // Multi download
downloadNo.text = "0" downloadNo.text = "0"
animeDownloadTop.setOnClickListener { mediaDownloadTop.setOnClickListener {
//Alert dialog asking for the number of chapters to download // Alert dialog asking for the number of chapters to download
fragment.requireContext().customAlertDialog().apply { fragment.requireContext().customAlertDialog().apply {
setTitle("Multi Chapter Downloader") setTitle("Multi Chapter Downloader")
setMessage("Enter the number of chapters to download") setMessage("Enter the number of chapters to download")
@ -256,10 +256,10 @@ class MangaReadAdapter(
} }
} }
//Scanlator // Scanlator
animeScanlatorContainer.isVisible = options.count() > 1 mangaScanlatorContainer.isVisible = options.count() > 1
scanlatorNo.text = "${options.count()}" scanlatorNo.text = "${options.count()}"
animeScanlatorTop.setOnClickListener { mangaScanlatorTop.setOnClickListener {
CustomDialogLayoutBinding.inflate(fragment.layoutInflater) CustomDialogLayoutBinding.inflate(fragment.layoutInflater)
val dialogView = CustomDialogLayoutBinding.inflate(fragment.layoutInflater) val dialogView = CustomDialogLayoutBinding.inflate(fragment.layoutInflater)
val checkboxContainer = dialogView.checkboxContainer val checkboxContainer = dialogView.checkboxContainer
@ -345,7 +345,7 @@ class MangaReadAdapter(
} }
} }
} }
//Chapter Handling // Chapter Handling
handleChapters() handleChapters()
} }
@ -353,7 +353,7 @@ class MangaReadAdapter(
subscribe?.enabled(enabled) subscribe?.enabled(enabled)
} }
//Chips // Chips
fun updateChips(limit: Int, names: Array<String>, arr: Array<Int>, selected: Int = 0) { fun updateChips(limit: Int, names: Array<String>, arr: Array<Int>, selected: Int = 0) {
val binding = _binding val binding = _binding
if (binding != null) { if (binding != null) {
@ -364,13 +364,13 @@ class MangaReadAdapter(
val chip = val chip =
ItemChipBinding.inflate( ItemChipBinding.inflate(
LayoutInflater.from(fragment.context), LayoutInflater.from(fragment.context),
binding.animeSourceChipGroup, binding.mediaSourceChipGroup,
false false
).root ).root
chip.isCheckable = true chip.isCheckable = true
fun selected() { fun selected() {
chip.isChecked = true chip.isChecked = true
binding.animeWatchChipScroll.smoothScrollTo( binding.mediaWatchChipScroll.smoothScrollTo(
(chip.left - screenWidth / 2) + (chip.width / 2), (chip.left - screenWidth / 2) + (chip.width / 2),
0 0
) )
@ -388,7 +388,7 @@ class MangaReadAdapter(
} else { } else {
names[last - 1] names[last - 1]
} }
//chip.text = "${names[limit * (position)]} - ${names[last - 1]}" // chip.text = "${names[limit * (position)]} - ${names[last - 1]}"
val chipText = "$startChapterString - $endChapterString" val chipText = "$startChapterString - $endChapterString"
chip.text = chipText chip.text = chipText
chip.setTextColor( chip.setTextColor(
@ -402,14 +402,14 @@ class MangaReadAdapter(
selected() selected()
fragment.onChipClicked(position, limit * (position), last - 1) fragment.onChipClicked(position, limit * (position), last - 1)
} }
binding.animeSourceChipGroup.addView(chip) binding.mediaSourceChipGroup.addView(chip)
if (selected == position) { if (selected == position) {
selected() selected()
select = chip select = chip
} }
} }
if (select != null) if (select != null)
binding.animeWatchChipScroll.apply { binding.mediaWatchChipScroll.apply {
post { post {
scrollTo( scrollTo(
(select.left - screenWidth / 2) + (select.width / 2), (select.left - screenWidth / 2) + (select.width / 2),
@ -421,7 +421,7 @@ class MangaReadAdapter(
} }
fun clearChips() { fun clearChips() {
_binding?.animeSourceChipGroup?.removeAllViews() _binding?.mediaSourceChipGroup?.removeAllViews()
} }
fun handleChapters() { fun handleChapters() {
@ -447,70 +447,86 @@ class MangaReadAdapter(
} }
if (formattedChapters.contains(continueEp)) { if (formattedChapters.contains(continueEp)) {
continueEp = chapters[formattedChapters.indexOf(continueEp)] continueEp = chapters[formattedChapters.indexOf(continueEp)]
binding.animeSourceContinue.visibility = View.VISIBLE binding.sourceContinue.visibility = View.VISIBLE
handleProgress( handleProgress(
binding.itemEpisodeProgressCont, binding.itemMediaProgressCont,
binding.itemEpisodeProgress, binding.itemMediaProgress,
binding.itemEpisodeProgressEmpty, binding.itemMediaProgressEmpty,
media.id, media.id,
continueEp continueEp
) )
if ((binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams).weight > 0.8f) { if ((binding.itemMediaProgress.layoutParams as LinearLayout.LayoutParams).weight > 0.8f) {
val e = chapters.indexOf(continueEp) val e = chapters.indexOf(continueEp)
if (e != -1 && e + 1 < chapters.size) { if (e != -1 && e + 1 < chapters.size) {
continueEp = chapters[e + 1] continueEp = chapters[e + 1]
} }
} }
val ep = media.manga.chapters!![continueEp]!! val ep = media.manga.chapters!![continueEp]!!
binding.itemEpisodeImage.loadImage(media.banner ?: media.cover) binding.itemMediaImage.loadImage(media.banner ?: media.cover)
binding.animeSourceContinueText.text = binding.mediaSourceContinueText.text =
currActivity()!!.getString( currActivity()!!.getString(
R.string.continue_chapter, R.string.continue_chapter,
ep.number, ep.number,
if (!ep.title.isNullOrEmpty()) ep.title else "" if (!ep.title.isNullOrEmpty()) ep.title else ""
) )
binding.animeSourceContinue.setOnClickListener { binding.sourceContinue.setOnClickListener {
fragment.onMangaChapterClick(continueEp) fragment.onMangaChapterClick(continueEp)
} }
if (fragment.continueEp) { if (fragment.continueEp) {
if ((binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams).weight < 0.8f) { if ((binding.itemMediaProgress.layoutParams as LinearLayout.LayoutParams).weight < 0.8f) {
binding.animeSourceContinue.performClick() binding.sourceContinue.performClick()
fragment.continueEp = false fragment.continueEp = false
} }
} }
} else { } else {
binding.animeSourceContinue.visibility = View.GONE binding.sourceContinue.visibility = View.GONE
} }
binding.animeSourceProgressBar.visibility = View.GONE
val sourceFound = media.manga.chapters!!.isNotEmpty() binding.sourceProgressBar.visibility = View.GONE
binding.animeSourceNotFound.isGone = sourceFound
val sourceFound = filteredChapters.isNotEmpty()
val isDownloadedSource = mangaReadSources[media.selected!!.sourceIndex] is OfflineMangaParser
if (isDownloadedSource) {
binding.sourceNotFound.text = if (sourceFound) {
currActivity()!!.getString(R.string.source_not_found)
} else {
currActivity()!!.getString(R.string.download_not_found)
}
} else {
binding.sourceNotFound.text = currActivity()!!.getString(R.string.source_not_found)
}
binding.sourceNotFound.isGone = sourceFound
binding.faqbutton.isGone = sourceFound binding.faqbutton.isGone = sourceFound
if (!sourceFound && PrefManager.getVal(PrefName.SearchSources)) { if (!sourceFound && PrefManager.getVal(PrefName.SearchSources)) {
if (binding.animeSource.adapter.count > media.selected!!.sourceIndex + 1) { if (binding.mediaSource.adapter.count > media.selected!!.sourceIndex + 1) {
val nextIndex = media.selected!!.sourceIndex + 1 val nextIndex = media.selected!!.sourceIndex + 1
binding.animeSource.setText( binding.mediaSource.setText(
binding.animeSource.adapter binding.mediaSource.adapter
.getItem(nextIndex).toString(), false .getItem(nextIndex).toString(), false
) )
fragment.onSourceChange(nextIndex).apply { fragment.onSourceChange(nextIndex).apply {
binding.animeSourceTitle.text = showUserText binding.mediaSourceTitle.text = showUserText
showUserTextListener = showUserTextListener =
{ MainScope().launch { binding.animeSourceTitle.text = it } } { MainScope().launch { binding.mediaSourceTitle.text = it } }
setLanguageList(0, nextIndex) setLanguageList(0, nextIndex)
} }
subscribeButton(false) subscribeButton(false)
// invalidate if it's the last source // Invalidate if it's the last source
val invalidate = nextIndex == mangaReadSources.names.size - 1 val invalidate = nextIndex == mangaReadSources.names.size - 1
fragment.loadChapters(nextIndex, invalidate) fragment.loadChapters(nextIndex, invalidate)
} }
} }
} else { } else {
binding.animeSourceContinue.visibility = View.GONE binding.sourceContinue.visibility = View.GONE
binding.animeSourceNotFound.visibility = View.GONE binding.sourceNotFound.visibility = View.GONE
binding.faqbutton.visibility = View.GONE binding.faqbutton.visibility = View.GONE
clearChips() clearChips()
binding.animeSourceProgressBar.visibility = View.VISIBLE binding.sourceProgressBar.visibility = View.VISIBLE
} }
} }
} }
@ -524,9 +540,9 @@ class MangaReadAdapter(
ext.sourceLanguage = lang ext.sourceLanguage = lang
} }
try { try {
binding?.animeSourceLanguage?.setText(parser.extension.sources[lang].lang) binding?.mediaSourceLanguage?.setText(parser.extension.sources[lang].lang)
} catch (e: IndexOutOfBoundsException) { } catch (e: IndexOutOfBoundsException) {
binding?.animeSourceLanguage?.setText( binding?.mediaSourceLanguage?.setText(
parser.extension.sources.firstOrNull()?.lang ?: "Unknown" parser.extension.sources.firstOrNull()?.lang ?: "Unknown"
) )
} }
@ -536,9 +552,9 @@ class MangaReadAdapter(
parser.extension.sources.map { LanguageMapper.getLanguageName(it.lang) } parser.extension.sources.map { LanguageMapper.getLanguageName(it.lang) }
) )
val items = adapter.count val items = adapter.count
binding?.animeSourceLanguageContainer?.isVisible = items > 1 binding?.mediaSourceLanguageContainer?.isVisible = items > 1
binding?.animeSourceLanguage?.setAdapter(adapter) binding?.mediaSourceLanguage?.setAdapter(adapter)
} }
} }
@ -546,7 +562,7 @@ class MangaReadAdapter(
override fun getItemCount(): Int = 1 override fun getItemCount(): Int = 1
inner class ViewHolder(val binding: ItemAnimeWatchBinding) : inner class ViewHolder(val binding: ItemMediaSourceBinding) :
RecyclerView.ViewHolder(binding.root) RecyclerView.ViewHolder(binding.root)
} }

View file

@ -2,7 +2,6 @@ package ani.dantotsu.media.manga
import android.Manifest import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -31,7 +30,7 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.databinding.FragmentAnimeWatchBinding import ani.dantotsu.databinding.FragmentMediaSourceBinding
import ani.dantotsu.download.DownloadedType import ani.dantotsu.download.DownloadedType
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.download.DownloadsManager.Companion.compareName import ani.dantotsu.download.DownloadsManager.Companion.compareName
@ -75,7 +74,7 @@ import kotlin.math.max
import kotlin.math.roundToInt import kotlin.math.roundToInt
open class MangaReadFragment : Fragment(), ScanlatorSelectionListener { open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
private var _binding: FragmentAnimeWatchBinding? = null private var _binding: FragmentMediaSourceBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private val model: MediaDetailsViewModel by activityViewModels() private val model: MediaDetailsViewModel by activityViewModels()
@ -102,7 +101,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
_binding = FragmentAnimeWatchBinding.inflate(inflater, container, false) _binding = FragmentMediaSourceBinding.inflate(inflater, container, false)
return _binding?.root return _binding?.root
} }
@ -122,7 +121,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
ContextCompat.RECEIVER_EXPORTED ContextCompat.RECEIVER_EXPORTED
) )
binding.animeSourceRecycler.updatePadding(bottom = binding.animeSourceRecycler.paddingBottom + navBarHeight) binding.mediaSourceRecycler.updatePadding(bottom = binding.mediaSourceRecycler.paddingBottom + navBarHeight)
screenWidth = resources.displayMetrics.widthPixels.dp screenWidth = resources.displayMetrics.widthPixels.dp
var maxGridSize = (screenWidth / 100f).roundToInt() var maxGridSize = (screenWidth / 100f).roundToInt()
@ -145,13 +144,13 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
} }
} }
binding.animeSourceRecycler.layoutManager = gridLayoutManager binding.mediaSourceRecycler.layoutManager = gridLayoutManager
binding.ScrollTop.setOnClickListener { binding.ScrollTop.setOnClickListener {
binding.animeSourceRecycler.scrollToPosition(10) binding.mediaSourceRecycler.scrollToPosition(10)
binding.animeSourceRecycler.smoothScrollToPosition(0) binding.mediaSourceRecycler.smoothScrollToPosition(0)
} }
binding.animeSourceRecycler.addOnScrollListener(object : RecyclerView.OnScrollListener() { binding.mediaSourceRecycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy) super.onScrolled(recyclerView, dx, dy)
@ -165,7 +164,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
} }
}) })
model.scrolledToTop.observe(viewLifecycleOwner) { model.scrolledToTop.observe(viewLifecycleOwner) {
if (it) binding.animeSourceRecycler.scrollToPosition(0) if (it) binding.mediaSourceRecycler.scrollToPosition(0)
} }
continueEp = model.continueMedia ?: false continueEp = model.continueMedia ?: false
@ -200,7 +199,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
} }
} }
binding.animeSourceRecycler.adapter = binding.mediaSourceRecycler.adapter =
ConcatAdapter(headerAdapter, chapterAdapter) ConcatAdapter(headerAdapter, chapterAdapter)
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
@ -215,8 +214,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
reload() reload()
} }
} else { } else {
binding.animeNotSupported.visibility = View.VISIBLE binding.mediaNotSupported.visibility = View.VISIBLE
binding.animeNotSupported.text = binding.mediaNotSupported.text =
getString(R.string.not_supported, media.format ?: "") getString(R.string.not_supported, media.format ?: "")
} }
} }
@ -232,10 +231,10 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
} }
fun multiDownload(n: Int) { fun multiDownload(n: Int) {
//get last viewed chapter // Get last viewed chapter
val selected = media.userProgress val selected = media.userProgress
val chapters = media.manga?.chapters?.values?.toList() val chapters = media.manga?.chapters?.values?.toList()
//filter by selected language // Filter by selected language
val progressChapterIndex = (chapters?.indexOfFirst { val progressChapterIndex = (chapters?.indexOfFirst {
MediaNameAdapter.findChapterNumber(it.number)?.toInt() == selected MediaNameAdapter.findChapterNumber(it.number)?.toInt() == selected
} ?: 0) + 1 } ?: 0) + 1
@ -245,7 +244,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
// Calculate the end index // Calculate the end index
val endIndex = minOf(progressChapterIndex + n, chapters.size) val endIndex = minOf(progressChapterIndex + n, chapters.size)
//make sure there are enough chapters // Make sure there are enough chapters
val chaptersToDownload = chapters.subList(progressChapterIndex, endIndex) val chaptersToDownload = chapters.subList(progressChapterIndex, endIndex)
@ -583,7 +582,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
private fun reload() { private fun reload() {
val selected = model.loadSelected(media) val selected = model.loadSelected(media)
//Find latest chapter for subscription // Find latest chapter for subscription
selected.latest = selected.latest =
media.manga?.chapters?.values?.maxOfOrNull { it.number.toFloatOrNull() ?: 0f } ?: 0f media.manga?.chapters?.values?.maxOfOrNull { it.number.toFloatOrNull() ?: 0f } ?: 0f
selected.latest = selected.latest =
@ -617,14 +616,14 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
binding.mediaInfoProgressBar.visibility = progress binding.mediaInfoProgressBar.visibility = progress
binding.animeSourceRecycler.layoutManager?.onRestoreInstanceState(state) binding.mediaSourceRecycler.layoutManager?.onRestoreInstanceState(state)
requireActivity().setNavigationTheme() requireActivity().setNavigationTheme()
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
state = binding.animeSourceRecycler.layoutManager?.onSaveInstanceState() state = binding.mediaSourceRecycler.layoutManager?.onSaveInstanceState()
} }
companion object { companion object {

View file

@ -50,16 +50,16 @@ class NovelReadAdapter(
val source = val source =
media.selected!!.sourceIndex.let { if (it >= novelReadSources.names.size) 0 else it } media.selected!!.sourceIndex.let { if (it >= novelReadSources.names.size) 0 else it }
if (novelReadSources.names.isNotEmpty() && source in 0 until novelReadSources.names.size) { if (novelReadSources.names.isNotEmpty() && source in 0 until novelReadSources.names.size) {
binding.animeSource.setText(novelReadSources.names[source], false) binding.mediaSource.setText(novelReadSources.names[source], false)
} }
binding.animeSource.setAdapter( binding.mediaSource.setAdapter(
ArrayAdapter( ArrayAdapter(
fragment.requireContext(), fragment.requireContext(),
R.layout.item_dropdown, R.layout.item_dropdown,
novelReadSources.names novelReadSources.names
) )
) )
binding.animeSource.setOnItemClickListener { _, _, i, _ -> binding.mediaSource.setOnItemClickListener { _, _, i, _ ->
fragment.onSourceChange(i) fragment.onSourceChange(i)
search() search()
} }

View file

@ -20,7 +20,7 @@ import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.currContext import ani.dantotsu.currContext
import ani.dantotsu.databinding.FragmentAnimeWatchBinding import ani.dantotsu.databinding.FragmentMediaSourceBinding
import ani.dantotsu.download.DownloadedType import ani.dantotsu.download.DownloadedType
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.download.novel.NovelDownloaderService import ani.dantotsu.download.novel.NovelDownloaderService
@ -47,7 +47,7 @@ class NovelReadFragment : Fragment(),
DownloadTriggerCallback, DownloadTriggerCallback,
DownloadedCheckCallback { DownloadedCheckCallback {
private var _binding: FragmentAnimeWatchBinding? = null private var _binding: FragmentMediaSourceBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private val model: MediaDetailsViewModel by activityViewModels() private val model: MediaDetailsViewModel by activityViewModels()
@ -214,11 +214,11 @@ class NovelReadFragment : Fragment(),
ContextCompat.RECEIVER_EXPORTED ContextCompat.RECEIVER_EXPORTED
) )
binding.animeSourceRecycler.updatePadding(bottom = binding.animeSourceRecycler.paddingBottom + navBarHeight) binding.mediaSourceRecycler.updatePadding(bottom = binding.mediaSourceRecycler.paddingBottom + navBarHeight)
binding.animeSourceRecycler.layoutManager = LinearLayoutManager(requireContext()) binding.mediaSourceRecycler.layoutManager = LinearLayoutManager(requireContext())
model.scrolledToTop.observe(viewLifecycleOwner) { model.scrolledToTop.observe(viewLifecycleOwner) {
if (it) binding.animeSourceRecycler.scrollToPosition(0) if (it) binding.mediaSourceRecycler.scrollToPosition(0)
} }
continueEp = model.continueMedia ?: false continueEp = model.continueMedia ?: false
@ -237,7 +237,7 @@ class NovelReadFragment : Fragment(),
this, this,
this this
) // probably a better way to do this but it works ) // probably a better way to do this but it works
binding.animeSourceRecycler.adapter = binding.mediaSourceRecycler.adapter =
ConcatAdapter(headerAdapter, novelResponseAdapter) ConcatAdapter(headerAdapter, novelResponseAdapter)
loaded = true loaded = true
Handler(Looper.getMainLooper()).postDelayed({ Handler(Looper.getMainLooper()).postDelayed({
@ -290,7 +290,7 @@ class NovelReadFragment : Fragment(),
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
_binding = FragmentAnimeWatchBinding.inflate(inflater, container, false) _binding = FragmentMediaSourceBinding.inflate(inflater, container, false)
return _binding?.root return _binding?.root
} }
@ -304,12 +304,12 @@ class NovelReadFragment : Fragment(),
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
binding.mediaInfoProgressBar.visibility = progress binding.mediaInfoProgressBar.visibility = progress
binding.animeSourceRecycler.layoutManager?.onRestoreInstanceState(state) binding.mediaSourceRecycler.layoutManager?.onRestoreInstanceState(state)
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
state = binding.animeSourceRecycler.layoutManager?.onSaveInstanceState() state = binding.mediaSourceRecycler.layoutManager?.onSaveInstanceState()
} }
companion object { companion object {

View file

@ -39,7 +39,7 @@ class NovelResponseAdapter(
val binding = holder.binding val binding = holder.binding
val novel = list[position] val novel = list[position]
setAnimation(fragment.requireContext(), holder.binding.root) setAnimation(fragment.requireContext(), holder.binding.root)
binding.itemEpisodeImage.loadImage(novel.coverUrl, 400, 0) binding.itemMediaImage.loadImage(novel.coverUrl, 400, 0)
val color =fragment.requireContext().getThemeColor(com.google.android.material.R.attr.colorOnBackground) val color =fragment.requireContext().getThemeColor(com.google.android.material.R.attr.colorOnBackground)
binding.itemEpisodeTitle.text = novel.name binding.itemEpisodeTitle.text = novel.name

View file

@ -39,7 +39,7 @@ object AnimeSources : WatchSources() {
} }
fun performReorderAnimeSources() { fun performReorderAnimeSources() {
//remove the downloaded source from the list to avoid duplicates // Remove the downloaded source from the list to avoid duplicates
list = list.filter { it.name != "Downloaded" } list = list.filter { it.name != "Downloaded" }
list = sortPinnedAnimeSources(list, pinnedAnimeSources) + Lazier( list = sortPinnedAnimeSources(list, pinnedAnimeSources) + Lazier(
{ OfflineAnimeParser() }, { OfflineAnimeParser() },

View file

@ -54,7 +54,7 @@
app:cardElevation="0dp"> app:cardElevation="0dp">
<ImageButton <ImageButton
android:id="@+id/animeSourceList" android:id="@+id/mediaSourceList"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:alpha="0.33" android:alpha="0.33"
@ -73,7 +73,7 @@
app:cardElevation="0dp"> app:cardElevation="0dp">
<ImageButton <ImageButton
android:id="@+id/animeSourceGrid" android:id="@+id/mediaSourceGrid"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:alpha="0.33" android:alpha="0.33"
@ -91,7 +91,7 @@
app:cardElevation="0dp"> app:cardElevation="0dp">
<ImageButton <ImageButton
android:id="@+id/animeSourceCompact" android:id="@+id/mediaSourceCompact"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:alpha="0.33" android:alpha="0.33"
@ -140,7 +140,7 @@
app:cardElevation="0dp"> app:cardElevation="0dp">
<ImageButton <ImageButton
android:id="@+id/animeSourceTop" android:id="@+id/mediaSourceTop"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
@ -189,7 +189,7 @@
app:cardElevation="0dp"> app:cardElevation="0dp">
<ImageButton <ImageButton
android:id="@+id/animeDownloadTop" android:id="@+id/mediaDownloadTop"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
@ -200,7 +200,7 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/animeScanlatorContainer" android:id="@+id/mangaScanlatorContainer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical"> android:layout_gravity="center_vertical">
@ -235,7 +235,7 @@
app:cardElevation="0dp"> app:cardElevation="0dp">
<ImageButton <ImageButton
android:id="@+id/animeScanlatorTop" android:id="@+id/mangaScanlatorTop"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
@ -246,7 +246,7 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/animeWebviewContainer" android:id="@+id/mediaWebviewContainer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@ -280,7 +280,7 @@
android:layout_height="48dp"> android:layout_height="48dp">
<ImageView <ImageView
android:id="@+id/animeWebViewTop" android:id="@+id/mediaWebViewTop"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:layout_gravity="center|center_horizontal" android:layout_gravity="center|center_horizontal"

View file

@ -7,7 +7,7 @@
tools:context=".media.anime.AnimeWatchFragment"> tools:context=".media.anime.AnimeWatchFragment">
<TextView <TextView
android:id="@+id/animeNotSupported" android:id="@+id/mediaNotSupported"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
@ -31,7 +31,7 @@
tools:visibility="gone" /> tools:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/animeSourceRecycler" android:id="@+id/mediaSourceRecycler"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
@ -39,7 +39,7 @@
android:paddingEnd="24dp" android:paddingEnd="24dp"
android:paddingBottom="128dp" android:paddingBottom="128dp"
tools:itemCount="1" tools:itemCount="1"
tools:listitem="@layout/item_anime_watch" /> tools:listitem="@layout/item_media_source" />
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/ScrollTop" android:id="@+id/ScrollTop"

View file

@ -14,21 +14,21 @@
android:background="?attr/colorSurfaceVariant" /> android:background="?attr/colorSurfaceVariant" />
<LinearLayout <LinearLayout
android:id="@+id/itemEpisodeProgressCont" android:id="@+id/itemMediaProgressCont"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:orientation="horizontal"> android:orientation="horizontal">
<View <View
android:id="@+id/itemEpisodeProgress" android:id="@+id/itemMediaProgress"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="2dp" android:layout_height="2dp"
android:layout_weight="0" android:layout_weight="0"
android:background="?attr/colorPrimary" /> android:background="?attr/colorPrimary" />
<View <View
android:id="@+id/itemEpisodeProgressEmpty" android:id="@+id/itemMediaProgressEmpty"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="2dp" android:layout_height="2dp"
android:layout_weight="1" /> android:layout_weight="1" />

View file

@ -13,7 +13,7 @@
app:cardElevation="4dp"> app:cardElevation="4dp">
<ImageView <ImageView
android:id="@+id/itemEpisodeImage" android:id="@+id/itemMediaImage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="96dp" android:layout_height="96dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
@ -85,21 +85,21 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/itemEpisodeProgressCont" android:id="@+id/itemMediaProgressCont"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:orientation="horizontal"> android:orientation="horizontal">
<View <View
android:id="@+id/itemEpisodeProgress" android:id="@+id/itemMediaProgress"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="2dp" android:layout_height="2dp"
android:layout_weight="0" android:layout_weight="0"
android:background="?attr/colorPrimary" /> android:background="?attr/colorPrimary" />
<View <View
android:id="@+id/itemEpisodeProgressEmpty" android:id="@+id/itemMediaProgressEmpty"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="2dp" android:layout_height="2dp"
android:layout_weight="1" /> android:layout_weight="1" />

View file

@ -47,7 +47,7 @@
android:indeterminate="true" /> android:indeterminate="true" />
<ImageView <ImageView
android:id="@+id/itemEpisodeImage" android:id="@+id/itemMediaImage"
android:layout_width="164dp" android:layout_width="164dp"
android:layout_height="109dp" android:layout_height="109dp"
android:layout_gravity="center" android:layout_gravity="center"
@ -77,7 +77,7 @@
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
<LinearLayout <LinearLayout
android:id="@+id/itemEpisodeProgressCont" android:id="@+id/itemMediaProgress_cont"
android:layout_width="164dp" android:layout_width="164dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
@ -85,14 +85,14 @@
android:visibility="gone"> android:visibility="gone">
<View <View
android:id="@+id/itemEpisodeProgress" android:id="@+id/itemMediaProgress"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="2dp" android:layout_height="2dp"
android:layout_weight="0" android:layout_weight="0"
android:background="?attr/colorPrimary" /> android:background="?attr/colorPrimary" />
<View <View
android:id="@+id/itemEpisodeProgressEmpty" android:id="@+id/itemMediaProgressEmpty"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="2dp" android:layout_height="2dp"
android:layout_weight="1" android:layout_weight="1"

View file

@ -38,7 +38,7 @@
tools:visibility="visible" /> tools:visibility="visible" />
<TextView <TextView
android:id="@+id/animeSourceTitle" android:id="@+id/mediaSourceTitle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end"
@ -57,7 +57,7 @@
android:orientation="horizontal"> android:orientation="horizontal">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/animeSourceNameContainer" android:id="@+id/mediaSourceNameContainer"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="56dp" android:layout_height="56dp"
@ -72,7 +72,7 @@
app:startIconDrawable="@drawable/ic_round_source_24"> app:startIconDrawable="@drawable/ic_round_source_24">
<AutoCompleteTextView <AutoCompleteTextView
android:id="@+id/animeSource" android:id="@+id/mediaSource"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
@ -91,7 +91,7 @@
<ImageView <ImageView
android:id="@+id/animeSourceSettings" android:id="@+id/mediaSourceSettings"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
@ -107,7 +107,7 @@
android:baselineAligned="false"> android:baselineAligned="false">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/animeSourceLanguageContainer" android:id="@+id/mediaSourceLanguageContainer"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="56dp" android:layout_height="56dp"
@ -123,7 +123,7 @@
app:startIconDrawable="@drawable/ic_round_source_24"> app:startIconDrawable="@drawable/ic_round_source_24">
<AutoCompleteTextView <AutoCompleteTextView
android:id="@+id/animeSourceLanguage" android:id="@+id/mediaSourceLanguage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
@ -193,7 +193,7 @@
<TextView <TextView
android:id="@+id/animeSourceSearch" android:id="@+id/mediaSourceSearch"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end"
@ -224,7 +224,7 @@
android:textSize="16sp" /> android:textSize="16sp" />
<ImageView <ImageView
android:id="@+id/animeSourceSubscribe" android:id="@+id/mediaSourceSubscribe"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
@ -235,7 +235,7 @@
tools:ignore="ContentDescription,ImageContrastCheck" /> tools:ignore="ContentDescription,ImageContrastCheck" />
<ImageView <ImageView
android:id="@+id/animeNestedButton" android:id="@+id/mediaNestedButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="end" android:layout_gravity="end"
@ -247,7 +247,7 @@
</LinearLayout> </LinearLayout>
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/animeSourceContinue" android:id="@+id/sourceContinue"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="80dp" android:layout_height="80dp"
android:layout_gravity="center" android:layout_gravity="center"
@ -259,7 +259,7 @@
tools:visibility="visible"> tools:visibility="visible">
<ImageView <ImageView
android:id="@+id/itemEpisodeImage" android:id="@+id/itemMediaImage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
@ -280,7 +280,7 @@
android:visibility="gone" /> android:visibility="gone" />
<TextView <TextView
android:id="@+id/animeSourceContinueText" android:id="@+id/mediaSourceContinueText"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
@ -293,21 +293,21 @@
app:drawableEndCompat="@drawable/ic_round_play_arrow_24" /> app:drawableEndCompat="@drawable/ic_round_play_arrow_24" />
<LinearLayout <LinearLayout
android:id="@+id/itemEpisodeProgressCont" android:id="@+id/itemMediaProgressCont"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:orientation="horizontal"> android:orientation="horizontal">
<View <View
android:id="@+id/itemEpisodeProgress" android:id="@+id/itemMediaProgress"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="2dp" android:layout_height="2dp"
android:layout_weight="0" android:layout_weight="0"
android:background="?attr/colorPrimary" /> android:background="?attr/colorPrimary" />
<View <View
android:id="@+id/itemEpisodeProgressEmpty" android:id="@+id/itemMediaProgressEmpty"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="2dp" android:layout_height="2dp"
android:layout_weight="1" /> android:layout_weight="1" />
@ -318,7 +318,7 @@
</LinearLayout> </LinearLayout>
<HorizontalScrollView <HorizontalScrollView
android:id="@+id/animeWatchChipScroll" android:id="@+id/mediaWatchChipScroll"
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:layout_marginBottom="8dp"
@ -328,7 +328,7 @@
android:scrollbars="none"> android:scrollbars="none">
<com.google.android.material.chip.ChipGroup <com.google.android.material.chip.ChipGroup
android:id="@+id/animeSourceChipGroup" android:id="@+id/mediaSourceChipGroup"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:singleLine="true" app:singleLine="true"
@ -336,7 +336,7 @@
</HorizontalScrollView> </HorizontalScrollView>
<ProgressBar <ProgressBar
android:id="@+id/animeSourceProgressBar" android:id="@+id/sourceProgressBar"
style="?android:attr/progressBarStyle" style="?android:attr/progressBarStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -350,7 +350,7 @@
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/animeSourceNotFound" android:id="@+id/sourceNotFound"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_bold" android:fontFamily="@font/poppins_bold"
@ -364,6 +364,7 @@
android:id="@+id/faqbutton" android:id="@+id/faqbutton"
android:layout_width="120dp" android:layout_width="120dp"
android:layout_height="50dp" android:layout_height="50dp"
android:layout_marginTop="-16dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:backgroundTint="?attr/colorPrimaryContainer" android:backgroundTint="?attr/colorPrimaryContainer"
android:fontFamily="@font/poppins_bold" android:fontFamily="@font/poppins_bold"

View file

@ -25,7 +25,7 @@
app:startIconDrawable="@drawable/ic_round_source_24"> app:startIconDrawable="@drawable/ic_round_source_24">
<AutoCompleteTextView <AutoCompleteTextView
android:id="@+id/animeSource" android:id="@+id/mediaSource"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"

View file

@ -38,7 +38,7 @@
android:indeterminate="true" /> android:indeterminate="true" />
<ImageView <ImageView
android:id="@+id/itemEpisodeImage" android:id="@+id/itemMediaImage"
android:layout_width="108dp" android:layout_width="108dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center" android:layout_gravity="center"

View file

@ -156,8 +156,12 @@
<string name="chap">Chapter</string> <string name="chap">Chapter</string>
<string name="wrong"><u>Wrong Title?</u></string> <string name="wrong"><u>Wrong Title?</u></string>
<string name="source_not_found"> <string name="source_not_found">
Couldn\'t find anything X( \n Hmm, nothing came up from this source.\n
Try another source. Let\'s look elsewhere :)
</string>
<string name="download_not_found">
Your downloads are feeling a bit lonely…\n
Nothing here yet :(
</string> </string>
<string name="not_supported">%1$s is not supported!</string> <string name="not_supported">%1$s is not supported!</string>
<string name="server_selector">Select Server</string> <string name="server_selector">Select Server</string>