Merging stuff. Cleaning up code. The usual (#297)

* chore: merge core extension view

* fix: clean up a sloppy fix

* chore: merge name adapters

* fix: offset the indentation of example
This commit is contained in:
TwistedUmbrellaX 2024-03-27 18:45:01 -04:00 committed by GitHub
parent ff72f9dbdf
commit 7bcc01b94e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 259 additions and 272 deletions

View file

@ -0,0 +1,146 @@
package ani.dantotsu.media
import java.util.Locale
import java.util.regex.Matcher
import java.util.regex.Pattern
object MediaNameAdapter {
private const val REGEX_ITEM = "[\\s:.\\-]*(\\d+\\.?\\d*)[\\s:.\\-]*"
private const val REGEX_PART_NUMBER = "(?<!part\\s)\\b(\\d+)\\b"
private const val REGEX_EPISODE =
"(episode|episodio|ep|e)${REGEX_ITEM}\\(?\\s*(sub|subbed|dub|dubbed)*\\s*\\)?\\s*"
private const val REGEX_SEASON = "(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
private const val REGEX_SUBDUB = "^(soft)?[\\s-]*(sub|dub|mixed)(bed|s)?\\s*$"
private const val REGEX_CHAPTER = "(chapter|chap|ch|c)${REGEX_ITEM}"
fun setSubDub(text: String, typeToSetTo: SubDubType): String? {
val subdubPattern: Pattern = Pattern.compile(REGEX_SUBDUB, Pattern.CASE_INSENSITIVE)
val subdubMatcher: Matcher = subdubPattern.matcher(text)
return if (subdubMatcher.find()) {
val soft = subdubMatcher.group(1)
val subdub = subdubMatcher.group(2)
val bed = subdubMatcher.group(3) ?: ""
val toggled = when (typeToSetTo) {
SubDubType.SUB -> "sub"
SubDubType.DUB -> "dub"
SubDubType.NULL -> ""
}
val toggledCasePreserved =
if (subdub?.get(0)?.isUpperCase() == true || soft?.get(0)
?.isUpperCase() == true
) toggled.replaceFirstChar {
if (it.isLowerCase()) it.titlecase(
Locale.ROOT
) else it.toString()
} else toggled
subdubMatcher.replaceFirst(toggledCasePreserved + bed)
} else {
null
}
}
fun getSubDub(text: String): SubDubType {
val subdubPattern: Pattern = Pattern.compile(REGEX_SUBDUB, Pattern.CASE_INSENSITIVE)
val subdubMatcher: Matcher = subdubPattern.matcher(text)
return if (subdubMatcher.find()) {
val subdub = subdubMatcher.group(2)?.lowercase(Locale.ROOT)
when (subdub) {
"sub" -> SubDubType.SUB
"dub" -> SubDubType.DUB
else -> SubDubType.NULL
}
} else {
SubDubType.NULL
}
}
enum class SubDubType {
SUB, DUB, NULL
}
fun findSeasonNumber(text: String): Int? {
val seasonPattern: Pattern = Pattern.compile(REGEX_SEASON, Pattern.CASE_INSENSITIVE)
val seasonMatcher: Matcher = seasonPattern.matcher(text)
return if (seasonMatcher.find()) {
seasonMatcher.group(2)?.toInt()
} else {
null
}
}
fun findEpisodeNumber(text: String): Float? {
val episodePattern: Pattern = Pattern.compile(REGEX_EPISODE, Pattern.CASE_INSENSITIVE)
val episodeMatcher: Matcher = episodePattern.matcher(text)
return if (episodeMatcher.find()) {
if (episodeMatcher.group(2) != null) {
episodeMatcher.group(2)?.toFloat()
} else {
val failedEpisodeNumberPattern: Pattern =
Pattern.compile(REGEX_PART_NUMBER, Pattern.CASE_INSENSITIVE)
val failedEpisodeNumberMatcher: Matcher =
failedEpisodeNumberPattern.matcher(text)
if (failedEpisodeNumberMatcher.find()) {
failedEpisodeNumberMatcher.group(1)?.toFloat()
} else {
null
}
}
} else {
null
}
}
fun removeEpisodeNumber(text: String): String {
val regexPattern = Regex(REGEX_EPISODE, RegexOption.IGNORE_CASE)
val removedNumber = text.replace(regexPattern, "").ifEmpty {
text
}
val letterPattern = Regex("[a-zA-Z]")
return if (letterPattern.containsMatchIn(removedNumber)) {
removedNumber
} else {
text
}
}
fun removeEpisodeNumberCompletely(text: String): String {
val regexPattern = Regex(REGEX_EPISODE, RegexOption.IGNORE_CASE)
val removedNumber = text.replace(regexPattern, "")
return if (removedNumber.equals(text, true)) { // if nothing was removed
val failedEpisodeNumberPattern =
Regex(REGEX_PART_NUMBER, RegexOption.IGNORE_CASE)
failedEpisodeNumberPattern.replace(removedNumber) { mr ->
mr.value.replaceFirst(mr.groupValues[1], "")
}
} else {
removedNumber
}
}
fun findChapterNumber(text: String): Float? {
val pattern: Pattern = Pattern.compile(REGEX_CHAPTER, Pattern.CASE_INSENSITIVE)
val matcher: Matcher = pattern.matcher(text)
return if (matcher.find()) {
matcher.group(2)?.toFloat()
} else {
val failedChapterNumberPattern: Pattern =
Pattern.compile(REGEX_PART_NUMBER, Pattern.CASE_INSENSITIVE)
val failedChapterNumberMatcher: Matcher =
failedChapterNumberPattern.matcher(text)
if (failedChapterNumberMatcher.find()) {
failedChapterNumberMatcher.group(1)?.toFloat()
} else {
null
}
}
}
}

View file

@ -1,127 +0,0 @@
package ani.dantotsu.media.anime
import java.util.Locale
import java.util.regex.Matcher
import java.util.regex.Pattern
class AnimeNameAdapter {
companion object {
const val episodeRegex =
"(episode|episodio|ep|e)[\\s:.\\-]*(\\d+\\.?\\d*)[\\s:.\\-]*\\(?\\s*(sub|subbed|dub|dubbed)*\\s*\\)?\\s*"
const val failedEpisodeNumberRegex =
"(?<!part\\s)\\b(\\d+)\\b"
const val seasonRegex = "(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
const val subdubRegex = "^(soft)?[\\s-]*(sub|dub|mixed)(bed|s)?\\s*$"
fun setSubDub(text: String, typeToSetTo: SubDubType): String? {
val subdubPattern: Pattern = Pattern.compile(subdubRegex, Pattern.CASE_INSENSITIVE)
val subdubMatcher: Matcher = subdubPattern.matcher(text)
return if (subdubMatcher.find()) {
val soft = subdubMatcher.group(1)
val subdub = subdubMatcher.group(2)
val bed = subdubMatcher.group(3) ?: ""
val toggled = when (typeToSetTo) {
SubDubType.SUB -> "sub"
SubDubType.DUB -> "dub"
SubDubType.NULL -> ""
}
val toggledCasePreserved =
if (subdub?.get(0)?.isUpperCase() == true || soft?.get(0)
?.isUpperCase() == true
) toggled.replaceFirstChar {
if (it.isLowerCase()) it.titlecase(
Locale.ROOT
) else it.toString()
} else toggled
subdubMatcher.replaceFirst(toggledCasePreserved + bed)
} else {
null
}
}
fun getSubDub(text: String): SubDubType {
val subdubPattern: Pattern = Pattern.compile(subdubRegex, Pattern.CASE_INSENSITIVE)
val subdubMatcher: Matcher = subdubPattern.matcher(text)
return if (subdubMatcher.find()) {
val subdub = subdubMatcher.group(2)?.lowercase(Locale.ROOT)
when (subdub) {
"sub" -> SubDubType.SUB
"dub" -> SubDubType.DUB
else -> SubDubType.NULL
}
} else {
SubDubType.NULL
}
}
enum class SubDubType {
SUB, DUB, NULL
}
fun findSeasonNumber(text: String): Int? {
val seasonPattern: Pattern = Pattern.compile(seasonRegex, Pattern.CASE_INSENSITIVE)
val seasonMatcher: Matcher = seasonPattern.matcher(text)
return if (seasonMatcher.find()) {
seasonMatcher.group(2)?.toInt()
} else {
null
}
}
fun findEpisodeNumber(text: String): Float? {
val episodePattern: Pattern = Pattern.compile(episodeRegex, Pattern.CASE_INSENSITIVE)
val episodeMatcher: Matcher = episodePattern.matcher(text)
return if (episodeMatcher.find()) {
if (episodeMatcher.group(2) != null) {
episodeMatcher.group(2)?.toFloat()
} else {
val failedEpisodeNumberPattern: Pattern =
Pattern.compile(failedEpisodeNumberRegex, Pattern.CASE_INSENSITIVE)
val failedEpisodeNumberMatcher: Matcher =
failedEpisodeNumberPattern.matcher(text)
if (failedEpisodeNumberMatcher.find()) {
failedEpisodeNumberMatcher.group(1)?.toFloat()
} else {
null
}
}
} else {
null
}
}
fun removeEpisodeNumber(text: String): String {
val regexPattern = Regex(episodeRegex, RegexOption.IGNORE_CASE)
val removedNumber = text.replace(regexPattern, "").ifEmpty {
text
}
val letterPattern = Regex("[a-zA-Z]")
return if (letterPattern.containsMatchIn(removedNumber)) {
removedNumber
} else {
text
}
}
fun removeEpisodeNumberCompletely(text: String): String {
val regexPattern = Regex(episodeRegex, RegexOption.IGNORE_CASE)
val removedNumber = text.replace(regexPattern, "")
return if (removedNumber.equals(text, true)) { // if nothing was removed
val failedEpisodeNumberPattern =
Regex(failedEpisodeNumberRegex, RegexOption.IGNORE_CASE)
failedEpisodeNumberPattern.replace(removedNumber) { mr ->
mr.value.replaceFirst(mr.groupValues[1], "")
}
} else {
removedNumber
}
}
}
}

View file

@ -26,6 +26,7 @@ import ani.dantotsu.isOnline
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.media.SourceSearchDialogFragment import ani.dantotsu.media.SourceSearchDialogFragment
import ani.dantotsu.openSettings import ani.dantotsu.openSettings
import ani.dantotsu.others.LanguageMapper import ani.dantotsu.others.LanguageMapper
@ -403,7 +404,7 @@ class AnimeWatchAdapter(
} }
val ep = media.anime.episodes!![continueEp]!! val ep = media.anime.episodes!![continueEp]!!
val cleanedTitle = ep.title?.let { AnimeNameAdapter.removeEpisodeNumber(it) } val cleanedTitle = ep.title?.let { MediaNameAdapter.removeEpisodeNumber(it) }
binding.itemEpisodeImage.loadImage( binding.itemEpisodeImage.loadImage(
ep.thumb ?: FileUrl[media.banner ?: media.cover], 0 ep.thumb ?: FileUrl[media.banner ?: media.cover], 0

View file

@ -41,6 +41,7 @@ import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.MediaDetailsViewModel import ani.dantotsu.media.MediaDetailsViewModel
import ani.dantotsu.media.MediaType import ani.dantotsu.media.MediaType
import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.navBarHeight import ani.dantotsu.navBarHeight
import ani.dantotsu.notifications.subscription.SubscriptionHelper import ani.dantotsu.notifications.subscription.SubscriptionHelper
import ani.dantotsu.notifications.subscription.SubscriptionHelper.Companion.saveSubscription import ani.dantotsu.notifications.subscription.SubscriptionHelper.Companion.saveSubscription
@ -224,7 +225,7 @@ class AnimeWatchFragment : Fragment() {
if (media.anime!!.kitsuEpisodes!!.containsKey(i)) { if (media.anime!!.kitsuEpisodes!!.containsKey(i)) {
episode.desc = episode.desc =
media.anime!!.kitsuEpisodes!![i]?.desc ?: episode.desc media.anime!!.kitsuEpisodes!![i]?.desc ?: episode.desc
episode.title = if (AnimeNameAdapter.removeEpisodeNumberCompletely( episode.title = if (MediaNameAdapter.removeEpisodeNumberCompletely(
episode.title ?: "" episode.title ?: ""
).isBlank() ).isBlank()
) media.anime!!.kitsuEpisodes!![i]?.title ) media.anime!!.kitsuEpisodes!![i]?.title

View file

@ -21,6 +21,7 @@ import ani.dantotsu.databinding.ItemEpisodeListBinding
import ani.dantotsu.download.anime.AnimeDownloaderService import ani.dantotsu.download.anime.AnimeDownloaderService
import ani.dantotsu.download.video.Helper import ani.dantotsu.download.video.Helper
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.setAnimation import ani.dantotsu.setAnimation
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@ -102,7 +103,7 @@ class EpisodeAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val ep = arr[position] val ep = arr[position]
val title = if (!ep.title.isNullOrEmpty() && ep.title != "null") { val title = if (!ep.title.isNullOrEmpty() && ep.title != "null") {
ep.title?.let { AnimeNameAdapter.removeEpisodeNumber(it) } ep.title?.let { MediaNameAdapter.removeEpisodeNumber(it) }
} else { } else {
ep.number ep.number
} ?: "" } ?: ""

View file

@ -113,6 +113,7 @@ import ani.dantotsu.isOnline
import ani.dantotsu.logError import ani.dantotsu.logError
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsViewModel import ani.dantotsu.media.MediaDetailsViewModel
import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.media.SubtitleDownloader import ani.dantotsu.media.SubtitleDownloader
import ani.dantotsu.okHttpClient import ani.dantotsu.okHttpClient
import ani.dantotsu.others.AniSkip import ani.dantotsu.others.AniSkip
@ -998,7 +999,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
episodeTitleArr = arrayListOf() episodeTitleArr = arrayListOf()
episodes.forEach { episodes.forEach {
val episode = it.value val episode = it.value
val cleanedTitle = AnimeNameAdapter.removeEpisodeNumberCompletely(episode.title ?: "") val cleanedTitle = MediaNameAdapter.removeEpisodeNumberCompletely(episode.title ?: "")
episodeTitleArr.add("Episode ${episode.number}${if (episode.filler) " [Filler]" else ""}${if (cleanedTitle.isNotBlank() && cleanedTitle != "null") ": $cleanedTitle" else ""}") episodeTitleArr.add("Episode ${episode.number}${if (episode.filler) " [Filler]" else ""}${if (cleanedTitle.isNotBlank() && cleanedTitle != "null") ": $cleanedTitle" else ""}")
} }

View file

@ -15,6 +15,7 @@ import ani.dantotsu.currContext
import ani.dantotsu.databinding.ItemChapterListBinding import ani.dantotsu.databinding.ItemChapterListBinding
import ani.dantotsu.databinding.ItemEpisodeCompactBinding import ani.dantotsu.databinding.ItemEpisodeCompactBinding
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.setAnimation import ani.dantotsu.setAnimation
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -267,10 +268,10 @@ class MangaChapterAdapter(
val binding = holder.binding val binding = holder.binding
setAnimation(fragment.requireContext(), holder.binding.root) setAnimation(fragment.requireContext(), holder.binding.root)
val ep = arr[position] val ep = arr[position]
val parsedNumber = MangaNameAdapter.findChapterNumber(ep.number)?.toInt() val parsedNumber = MediaNameAdapter.findChapterNumber(ep.number)?.toInt()
binding.itemEpisodeNumber.text = parsedNumber?.toString() ?: ep.number binding.itemEpisodeNumber.text = parsedNumber?.toString() ?: ep.number
if (media.userProgress != null) { if (media.userProgress != null) {
if ((MangaNameAdapter.findChapterNumber(ep.number) if ((MediaNameAdapter.findChapterNumber(ep.number)
?: 9999f) <= media.userProgress!!.toFloat() ?: 9999f) <= media.userProgress!!.toFloat()
) )
binding.itemEpisodeViewedCover.visibility = View.VISIBLE binding.itemEpisodeViewedCover.visibility = View.VISIBLE
@ -279,7 +280,7 @@ class MangaChapterAdapter(
binding.itemEpisodeCont.setOnLongClickListener { binding.itemEpisodeCont.setOnLongClickListener {
updateProgress( updateProgress(
media, media,
MangaNameAdapter.findChapterNumber(ep.number).toString() MediaNameAdapter.findChapterNumber(ep.number).toString()
) )
true true
} }
@ -315,7 +316,7 @@ class MangaChapterAdapter(
} else binding.itemChapterTitle.visibility = View.VISIBLE } else binding.itemChapterTitle.visibility = View.VISIBLE
if (media.userProgress != null) { if (media.userProgress != null) {
if ((MangaNameAdapter.findChapterNumber(ep.number) if ((MediaNameAdapter.findChapterNumber(ep.number)
?: 9999f) <= media.userProgress!!.toFloat() ?: 9999f) <= media.userProgress!!.toFloat()
) { ) {
binding.itemEpisodeViewedCover.visibility = View.VISIBLE binding.itemEpisodeViewedCover.visibility = View.VISIBLE
@ -326,7 +327,7 @@ class MangaChapterAdapter(
binding.root.setOnLongClickListener { binding.root.setOnLongClickListener {
updateProgress( updateProgress(
media, media,
MangaNameAdapter.findChapterNumber(ep.number).toString() MediaNameAdapter.findChapterNumber(ep.number).toString()
) )
true true
} }

View file

@ -1,29 +0,0 @@
package ani.dantotsu.media.manga
import java.util.regex.Matcher
import java.util.regex.Pattern
class MangaNameAdapter {
companion object {
private const val chapterRegex = "(chapter|chap|ch|c)[\\s:.\\-]*(\\d+\\.?\\d*)[\\s:.\\-]*"
private const val filedChapterNumberRegex = "(?<!part\\s)\\b(\\d+)\\b"
fun findChapterNumber(text: String): Float? {
val pattern: Pattern = Pattern.compile(chapterRegex, Pattern.CASE_INSENSITIVE)
val matcher: Matcher = pattern.matcher(text)
return if (matcher.find()) {
matcher.group(2)?.toFloat()
} else {
val failedChapterNumberPattern: Pattern =
Pattern.compile(filedChapterNumberRegex, Pattern.CASE_INSENSITIVE)
val failedChapterNumberMatcher: Matcher =
failedChapterNumberPattern.matcher(text)
if (failedChapterNumberMatcher.find()) {
failedChapterNumberMatcher.group(1)?.toFloat()
} else {
null
}
}
}
}
}

View file

@ -26,6 +26,7 @@ import ani.dantotsu.isOnline
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.media.SourceSearchDialogFragment import ani.dantotsu.media.SourceSearchDialogFragment
import ani.dantotsu.media.anime.handleProgress import ani.dantotsu.media.anime.handleProgress
import ani.dantotsu.openSettings import ani.dantotsu.openSettings
@ -385,8 +386,8 @@ class MangaReadAdapter(
) )
} }
val startChapter = MangaNameAdapter.findChapterNumber(names[limit * (position)]) val startChapter = MediaNameAdapter.findChapterNumber(names[limit * (position)])
val endChapter = MangaNameAdapter.findChapterNumber(names[last - 1]) val endChapter = MediaNameAdapter.findChapterNumber(names[last - 1])
val startChapterString = if (startChapter != null) { val startChapterString = if (startChapter != null) {
"Ch.$startChapter" "Ch.$startChapter"
} else { } else {
@ -448,7 +449,7 @@ class MangaReadAdapter(
chapter.scanlator !in hiddenScanlators chapter.scanlator !in hiddenScanlators
} }
val formattedChapters = filteredChapters.map { val formattedChapters = filteredChapters.map {
MangaNameAdapter.findChapterNumber(it)?.toInt()?.toString() MediaNameAdapter.findChapterNumber(it)?.toInt()?.toString()
} }
if (formattedChapters.contains(continueEp)) { if (formattedChapters.contains(continueEp)) {
continueEp = chapters[formattedChapters.indexOf(continueEp)] continueEp = chapters[formattedChapters.indexOf(continueEp)]

View file

@ -41,6 +41,7 @@ import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.MediaDetailsViewModel import ani.dantotsu.media.MediaDetailsViewModel
import ani.dantotsu.media.MediaType import ani.dantotsu.media.MediaType
import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.media.manga.mangareader.ChapterLoaderDialog import ani.dantotsu.media.manga.mangareader.ChapterLoaderDialog
import ani.dantotsu.navBarHeight import ani.dantotsu.navBarHeight
import ani.dantotsu.notifications.subscription.SubscriptionHelper import ani.dantotsu.notifications.subscription.SubscriptionHelper
@ -227,7 +228,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
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 {
MangaNameAdapter.findChapterNumber(it.number)?.toInt() == selected MediaNameAdapter.findChapterNumber(it.number)?.toInt() == selected
} ?: 0) + 1 } ?: 0) + 1
if (progressChapterIndex < 0 || n < 1 || chapters == null) return if (progressChapterIndex < 0 || n < 1 || chapters == null) return

View file

@ -57,9 +57,9 @@ import ani.dantotsu.logError
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsViewModel import ani.dantotsu.media.MediaDetailsViewModel
import ani.dantotsu.media.MediaSingleton import ani.dantotsu.media.MediaSingleton
import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.media.manga.MangaCache import ani.dantotsu.media.manga.MangaCache
import ani.dantotsu.media.manga.MangaChapter import ani.dantotsu.media.manga.MangaChapter
import ani.dantotsu.media.manga.MangaNameAdapter
import ani.dantotsu.others.ImageViewDialog import ani.dantotsu.others.ImageViewDialog
import ani.dantotsu.parsers.HMangaSources import ani.dantotsu.parsers.HMangaSources
import ani.dantotsu.parsers.MangaImage import ani.dantotsu.parsers.MangaImage
@ -180,7 +180,7 @@ class MangaReaderActivity : AppCompatActivity() {
defaultSettings = loadReaderSettings("reader_settings") ?: defaultSettings defaultSettings = loadReaderSettings("reader_settings") ?: defaultSettings
onBackPressedDispatcher.addCallback(this) { onBackPressedDispatcher.addCallback(this) {
val chapter = (MangaNameAdapter.findChapterNumber(media.manga!!.selectedChapter!!) val chapter = (MediaNameAdapter.findChapterNumber(media.manga!!.selectedChapter!!)
?.minus(1L) ?: 0).toString() ?.minus(1L) ?: 0).toString()
if (chapter == "0.0" && PrefManager.getVal(PrefName.ChapterZeroReader) if (chapter == "0.0" && PrefManager.getVal(PrefName.ChapterZeroReader)
// Not asking individually or incognito // Not asking individually or incognito
@ -969,7 +969,7 @@ class MangaReaderActivity : AppCompatActivity() {
PrefManager.setCustomVal("${media.id}_save_progress", true) PrefManager.setCustomVal("${media.id}_save_progress", true)
updateProgress( updateProgress(
media, media,
MangaNameAdapter.findChapterNumber(media.manga!!.selectedChapter!!) MediaNameAdapter.findChapterNumber(media.manga!!.selectedChapter!!)
.toString() .toString()
) )
dialog.dismiss() dialog.dismiss()
@ -991,7 +991,7 @@ class MangaReaderActivity : AppCompatActivity() {
) )
updateProgress( updateProgress(
media, media,
MangaNameAdapter.findChapterNumber(media.manga!!.selectedChapter!!) MediaNameAdapter.findChapterNumber(media.manga!!.selectedChapter!!)
.toString() .toString()
) )
runnable.run() runnable.run()

View file

@ -3,13 +3,11 @@ package ani.dantotsu.notifications.subscription
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.currContext import ani.dantotsu.currContext
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.media.Selected import ani.dantotsu.media.Selected
import ani.dantotsu.media.manga.MangaNameAdapter
import ani.dantotsu.parsers.AnimeParser import ani.dantotsu.parsers.AnimeParser
import ani.dantotsu.parsers.AnimeSources import ani.dantotsu.parsers.AnimeSources
import ani.dantotsu.parsers.Episode import ani.dantotsu.parsers.Episode
import ani.dantotsu.parsers.HAnimeSources
import ani.dantotsu.parsers.HMangaSources
import ani.dantotsu.parsers.MangaChapter import ani.dantotsu.parsers.MangaChapter
import ani.dantotsu.parsers.MangaParser import ani.dantotsu.parsers.MangaParser
import ani.dantotsu.parsers.MangaSources import ani.dantotsu.parsers.MangaSources
@ -105,7 +103,7 @@ class SubscriptionHelper {
} }
return chp?.apply { return chp?.apply {
selected.latest = MangaNameAdapter.findChapterNumber(number) ?: 0f selected.latest = MediaNameAdapter.findChapterNumber(number) ?: 0f
saveSelected(id, selected) saveSelected(id, selected)
} }
} }

View file

@ -3,7 +3,7 @@ package ani.dantotsu.parsers
import android.content.Context import android.content.Context
import ani.dantotsu.FileUrl import ani.dantotsu.FileUrl
import ani.dantotsu.currContext import ani.dantotsu.currContext
import ani.dantotsu.media.anime.AnimeNameAdapter import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.media.manga.ImageData import ani.dantotsu.media.manga.ImageData
import ani.dantotsu.media.manga.MangaCache import ani.dantotsu.media.manga.MangaCache
import ani.dantotsu.snackString import ani.dantotsu.snackString
@ -73,12 +73,12 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
configurableSource.getPreferenceKey(), configurableSource.getPreferenceKey(),
Context.MODE_PRIVATE Context.MODE_PRIVATE
) )
sharedPreferences.all.filterValues { AnimeNameAdapter.getSubDub(it.toString()) != AnimeNameAdapter.Companion.SubDubType.NULL } sharedPreferences.all.filterValues { MediaNameAdapter.getSubDub(it.toString()) != MediaNameAdapter.SubDubType.NULL }
.forEach { value -> .forEach { value ->
return when (AnimeNameAdapter.getSubDub(value.value.toString())) { return when (MediaNameAdapter.getSubDub(value.value.toString())) {
AnimeNameAdapter.Companion.SubDubType.SUB -> false MediaNameAdapter.SubDubType.SUB -> false
AnimeNameAdapter.Companion.SubDubType.DUB -> true MediaNameAdapter.SubDubType.DUB -> true
AnimeNameAdapter.Companion.SubDubType.NULL -> false MediaNameAdapter.SubDubType.NULL -> false
} }
} }
} }
@ -92,8 +92,8 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
val configurableSource = extension.sources[sourceLanguage] as? ConfigurableAnimeSource val configurableSource = extension.sources[sourceLanguage] as? ConfigurableAnimeSource
?: return ?: return
val type = when (setDub) { val type = when (setDub) {
true -> AnimeNameAdapter.Companion.SubDubType.DUB true -> MediaNameAdapter.SubDubType.DUB
false -> AnimeNameAdapter.Companion.SubDubType.SUB false -> MediaNameAdapter.SubDubType.SUB
} }
currContext()?.let { context -> currContext()?.let { context ->
val sharedPreferences = val sharedPreferences =
@ -101,9 +101,9 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
configurableSource.getPreferenceKey(), configurableSource.getPreferenceKey(),
Context.MODE_PRIVATE Context.MODE_PRIVATE
) )
sharedPreferences.all.filterValues { AnimeNameAdapter.getSubDub(it.toString()) != AnimeNameAdapter.Companion.SubDubType.NULL } sharedPreferences.all.filterValues { MediaNameAdapter.getSubDub(it.toString()) != MediaNameAdapter.SubDubType.NULL }
.forEach { value -> .forEach { value ->
val setValue = AnimeNameAdapter.setSubDub(value.value.toString(), type) val setValue = MediaNameAdapter.setSubDub(value.value.toString(), type)
if (setValue != null) { if (setValue != null) {
sharedPreferences.edit().putString(value.key, setValue).apply() sharedPreferences.edit().putString(value.key, setValue).apply()
} }
@ -122,9 +122,9 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
Context.MODE_PRIVATE Context.MODE_PRIVATE
) )
sharedPreferences.all.filterValues { sharedPreferences.all.filterValues {
AnimeNameAdapter.setSubDub( MediaNameAdapter.setSubDub(
it.toString(), it.toString(),
AnimeNameAdapter.Companion.SubDubType.NULL MediaNameAdapter.SubDubType.NULL
) != null ) != null
} }
.forEach { _ -> return true } .forEach { _ -> return true }
@ -150,7 +150,7 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
val sortedEpisodes = if (res[0].episode_number == -1f) { val sortedEpisodes = if (res[0].episode_number == -1f) {
// Find the number in the string and sort by that number // Find the number in the string and sort by that number
val sortedByStringNumber = res.sortedBy { val sortedByStringNumber = res.sortedBy {
val matchResult = AnimeNameAdapter.findEpisodeNumber(it.name) val matchResult = MediaNameAdapter.findEpisodeNumber(it.name)
val number = matchResult ?: Float.MAX_VALUE val number = matchResult ?: Float.MAX_VALUE
it.episode_number = number // Store the found number in episode_number it.episode_number = number // Store the found number in episode_number
number number
@ -171,13 +171,13 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
var episodeCounter = 1f var episodeCounter = 1f
// Group by season, sort within each season, and then renumber while keeping episode number 0 as is // Group by season, sort within each season, and then renumber while keeping episode number 0 as is
val seasonGroups = val seasonGroups =
res.groupBy { AnimeNameAdapter.findSeasonNumber(it.name) ?: 0 } res.groupBy { MediaNameAdapter.findSeasonNumber(it.name) ?: 0 }
seasonGroups.keys.sortedBy { it } seasonGroups.keys.sortedBy { it }
.flatMap { season -> .flatMap { season ->
seasonGroups[season]?.sortedBy { it.episode_number }?.map { episode -> seasonGroups[season]?.sortedBy { it.episode_number }?.map { episode ->
if (episode.episode_number != 0f) { // Skip renumbering for episode number 0 if (episode.episode_number != 0f) { // Skip renumbering for episode number 0
val potentialNumber = val potentialNumber =
AnimeNameAdapter.findEpisodeNumber(episode.name) MediaNameAdapter.findEpisodeNumber(episode.name)
if (potentialNumber != null) { if (potentialNumber != null) {
episode.episode_number = potentialNumber episode.episode_number = potentialNumber
} else { } else {

View file

@ -1,7 +1,7 @@
package ani.dantotsu.parsers package ani.dantotsu.parsers
import ani.dantotsu.FileUrl import ani.dantotsu.FileUrl
import ani.dantotsu.media.manga.MangaNameAdapter import ani.dantotsu.media.MediaNameAdapter
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
@ -33,9 +33,9 @@ abstract class MangaParser : BaseParser() {
): MangaChapter? { ): MangaChapter? {
val chapter = loadChapters(mangaLink, extra, sManga) val chapter = loadChapters(mangaLink, extra, sManga)
val max = chapter val max = chapter
.maxByOrNull { MangaNameAdapter.findChapterNumber(it.number) ?: 0f } .maxByOrNull { MediaNameAdapter.findChapterNumber(it.number) ?: 0f }
return max return max
?.takeIf { latest < (MangaNameAdapter.findChapterNumber(it.number) ?: 0.001f) } ?.takeIf { latest < (MediaNameAdapter.findChapterNumber(it.number) ?: 0.001f) }
} }
/** /**

View file

@ -5,7 +5,7 @@ import android.os.Environment
import ani.dantotsu.currContext import ani.dantotsu.currContext
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.media.MediaType import ani.dantotsu.media.MediaType
import ani.dantotsu.media.anime.AnimeNameAdapter import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.tryWithSuspend import ani.dantotsu.tryWithSuspend
import eu.kanade.tachiyomi.animesource.model.SAnime import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.animesource.model.SEpisode import eu.kanade.tachiyomi.animesource.model.SEpisode
@ -54,7 +54,7 @@ class OfflineAnimeParser : AnimeParser() {
episodes.add(episode) episodes.add(episode)
} }
} }
episodes.sortBy { AnimeNameAdapter.findEpisodeNumber(it.number) } episodes.sortBy { MediaNameAdapter.findEpisodeNumber(it.number) }
return episodes return episodes
} }
return emptyList() return emptyList()

View file

@ -3,7 +3,7 @@ package ani.dantotsu.parsers
import android.os.Environment import android.os.Environment
import ani.dantotsu.currContext import ani.dantotsu.currContext
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.media.manga.MangaNameAdapter import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
@ -43,7 +43,7 @@ class OfflineMangaParser : MangaParser() {
chapters.add(chapter) chapters.add(chapter)
} }
} }
chapters.sortBy { MangaNameAdapter.findChapterNumber(it.number) } chapters.sortBy { MediaNameAdapter.findChapterNumber(it.number) }
return chapters return chapters
} }
return emptyList() return emptyList()

View file

@ -3,7 +3,7 @@ package ani.dantotsu.parsers
import android.os.Environment import android.os.Environment
import ani.dantotsu.currContext import ani.dantotsu.currContext
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.media.manga.MangaNameAdapter import ani.dantotsu.media.MediaNameAdapter
import me.xdrop.fuzzywuzzy.FuzzySearch import me.xdrop.fuzzywuzzy.FuzzySearch
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -38,7 +38,7 @@ class OfflineNovelParser : NovelParser() {
chapters.add(chapter) chapters.add(chapter)
} }
} }
chapters.sortBy { MangaNameAdapter.findChapterNumber(it.name) } chapters.sortBy { MediaNameAdapter.findChapterNumber(it.name) }
return chapters.first() return chapters.first()
} }
return Book( return Book(

View file

@ -50,22 +50,21 @@ class FeedFragment : Fragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
activity = requireActivity() activity = requireActivity()
binding.listRecyclerView.adapter = adapter
binding.listRecyclerView.layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
binding.listProgressBar.visibility = ViewGroup.VISIBLE
userId = arguments?.getInt("userId", -1) userId = arguments?.getInt("userId", -1)
activityId = arguments?.getInt("activityId", -1) ?: -1 activityId = arguments?.getInt("activityId", -1) ?: -1
if (userId == -1) userId = null if (userId == -1) userId = null
global = arguments?.getBoolean("global", false) ?: false global = arguments?.getBoolean("global", false) ?: false
if (userId != null) { val navBar = if (userId != null)
binding.listRecyclerView.setBaseline((activity as ProfileActivity).navBar) (activity as ProfileActivity).navBar
}else{ else
binding.listRecyclerView.setBaseline((activity as FeedActivity).navBar) (activity as FeedActivity).navBar
} binding.listRecyclerView.setBaseline(navBar)
binding.listRecyclerView.adapter = adapter
binding.listRecyclerView.layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
binding.listProgressBar.visibility = ViewGroup.VISIBLE
} }
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
@ -73,11 +72,11 @@ class FeedFragment : Fragment() {
super.onResume() super.onResume()
if (this::binding.isInitialized) { if (this::binding.isInitialized) {
binding.root.requestLayout() binding.root.requestLayout()
if (userId != null) { val navBar = if (userId != null)
binding.listRecyclerView.setBaseline((activity as ProfileActivity).navBar) (activity as ProfileActivity).navBar
}else{ else
binding.listRecyclerView.setBaseline((activity as FeedActivity).navBar) (activity as FeedActivity).navBar
} binding.listRecyclerView.setBaseline(navBar)
if (!loadedFirstTime) { if (!loadedFirstTime) {
activity.lifecycleScope.launch(Dispatchers.IO) { activity.lifecycleScope.launch(Dispatchers.IO) {
val nulledId = if (activityId == -1) null else activityId val nulledId = if (activityId == -1) null else activityId

View file

@ -13,7 +13,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
import ani.dantotsu.databinding.FragmentAnimeExtensionsBinding import ani.dantotsu.databinding.FragmentExtensionsBinding
import ani.dantotsu.settings.paging.AnimeExtensionAdapter import ani.dantotsu.settings.paging.AnimeExtensionAdapter
import ani.dantotsu.settings.paging.AnimeExtensionsViewModel import ani.dantotsu.settings.paging.AnimeExtensionsViewModel
import ani.dantotsu.settings.paging.AnimeExtensionsViewModelFactory import ani.dantotsu.settings.paging.AnimeExtensionsViewModelFactory
@ -30,7 +30,7 @@ import uy.kohesive.injekt.api.get
class AnimeExtensionsFragment : Fragment(), class AnimeExtensionsFragment : Fragment(),
SearchQueryHandler, OnAnimeInstallClickListener { SearchQueryHandler, OnAnimeInstallClickListener {
private var _binding: FragmentAnimeExtensionsBinding? = null private var _binding: FragmentExtensionsBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private val viewModel: AnimeExtensionsViewModel by viewModels { private val viewModel: AnimeExtensionsViewModel by viewModels {
@ -48,12 +48,12 @@ class AnimeExtensionsFragment : Fragment(),
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
_binding = FragmentAnimeExtensionsBinding.inflate(inflater, container, false) _binding = FragmentExtensionsBinding.inflate(inflater, container, false)
binding.allAnimeExtensionsRecyclerView.isNestedScrollingEnabled = false binding.allExtensionsRecyclerView.isNestedScrollingEnabled = false
binding.allAnimeExtensionsRecyclerView.adapter = adapter binding.allExtensionsRecyclerView.adapter = adapter
binding.allAnimeExtensionsRecyclerView.layoutManager = LinearLayoutManager(context) binding.allExtensionsRecyclerView.layoutManager = LinearLayoutManager(context)
(binding.allAnimeExtensionsRecyclerView.layoutManager as LinearLayoutManager).isItemPrefetchEnabled = (binding.allExtensionsRecyclerView.layoutManager as LinearLayoutManager).isItemPrefetchEnabled =
true true
lifecycleScope.launch { lifecycleScope.launch {
@ -91,8 +91,8 @@ class AnimeExtensionsFragment : Fragment(),
Notifications.CHANNEL_DOWNLOADER_PROGRESS Notifications.CHANNEL_DOWNLOADER_PROGRESS
) )
.setSmallIcon(R.drawable.ic_round_sync_24) .setSmallIcon(R.drawable.ic_round_sync_24)
.setContentTitle("Installing extension") .setContentTitle(getString(R.string.installing_extension))
.setContentText("Step: $installStep") .setContentText(getString(R.string.install_step, installStep))
.setPriority(NotificationCompat.PRIORITY_LOW) .setPriority(NotificationCompat.PRIORITY_LOW)
notificationManager.notify(1, builder.build()) notificationManager.notify(1, builder.build())
}, },
@ -103,11 +103,11 @@ class AnimeExtensionsFragment : Fragment(),
Notifications.CHANNEL_DOWNLOADER_ERROR Notifications.CHANNEL_DOWNLOADER_ERROR
) )
.setSmallIcon(R.drawable.ic_round_info_24) .setSmallIcon(R.drawable.ic_round_info_24)
.setContentTitle("Installation failed: ${error.message}") .setContentTitle(getString(R.string.installation_failed, error.message))
.setContentText("Error: ${error.message}") .setContentText(getString(R.string.error_message, error.message))
.setPriority(NotificationCompat.PRIORITY_HIGH) .setPriority(NotificationCompat.PRIORITY_HIGH)
notificationManager.notify(1, builder.build()) notificationManager.notify(1, builder.build())
snackString("Installation failed: ${error.message}") snackString(getString(R.string.installation_failed, error.message))
}, },
{ {
val builder = NotificationCompat.Builder( val builder = NotificationCompat.Builder(
@ -115,12 +115,12 @@ class AnimeExtensionsFragment : Fragment(),
Notifications.CHANNEL_DOWNLOADER_PROGRESS Notifications.CHANNEL_DOWNLOADER_PROGRESS
) )
.setSmallIcon(R.drawable.ic_download_24) .setSmallIcon(R.drawable.ic_download_24)
.setContentTitle("Installation complete") .setContentTitle(getString(R.string.installation_complete))
.setContentText("The extension has been successfully installed.") .setContentText(getString(R.string.extension_has_been_installed))
.setPriority(NotificationCompat.PRIORITY_LOW) .setPriority(NotificationCompat.PRIORITY_LOW)
notificationManager.notify(1, builder.build()) notificationManager.notify(1, builder.build())
viewModel.invalidatePager() viewModel.invalidatePager()
snackString("Extension installed") snackString(getString(R.string.extension_installed))
} }
) )
} }

View file

@ -24,7 +24,7 @@ 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.connections.crashlytics.CrashlyticsInterface import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
import ani.dantotsu.databinding.FragmentAnimeExtensionsBinding import ani.dantotsu.databinding.FragmentExtensionsBinding
import ani.dantotsu.others.LanguageMapper import ani.dantotsu.others.LanguageMapper
import ani.dantotsu.parsers.AnimeSources import ani.dantotsu.parsers.AnimeSources
import ani.dantotsu.settings.extensionprefs.AnimeSourcePreferencesFragment import ani.dantotsu.settings.extensionprefs.AnimeSourcePreferencesFragment
@ -49,7 +49,7 @@ import java.util.Locale
class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler { class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
private var _binding: FragmentAnimeExtensionsBinding? = null private var _binding: FragmentExtensionsBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private lateinit var extensionsRecyclerView: RecyclerView private lateinit var extensionsRecyclerView: RecyclerView
private val skipIcons: Boolean = PrefManager.getVal(PrefName.SkipExtensionIcons) private val skipIcons: Boolean = PrefManager.getVal(PrefName.SkipExtensionIcons)
@ -183,9 +183,9 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
_binding = FragmentAnimeExtensionsBinding.inflate(inflater, container, false) _binding = FragmentExtensionsBinding.inflate(inflater, container, false)
extensionsRecyclerView = binding.allAnimeExtensionsRecyclerView extensionsRecyclerView = binding.allExtensionsRecyclerView
extensionsRecyclerView.layoutManager = LinearLayoutManager(requireContext()) extensionsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
extensionsRecyclerView.adapter = extensionsAdapter extensionsRecyclerView.adapter = extensionsAdapter

View file

@ -26,7 +26,7 @@ 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.connections.crashlytics.CrashlyticsInterface import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
import ani.dantotsu.databinding.FragmentMangaExtensionsBinding import ani.dantotsu.databinding.FragmentExtensionsBinding
import ani.dantotsu.others.LanguageMapper import ani.dantotsu.others.LanguageMapper
import ani.dantotsu.parsers.MangaSources import ani.dantotsu.parsers.MangaSources
import ani.dantotsu.settings.extensionprefs.MangaSourcePreferencesFragment import ani.dantotsu.settings.extensionprefs.MangaSourcePreferencesFragment
@ -48,7 +48,7 @@ import java.util.Collections
import java.util.Locale import java.util.Locale
class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler { class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
private var _binding: FragmentMangaExtensionsBinding? = null private var _binding: FragmentExtensionsBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private lateinit var extensionsRecyclerView: RecyclerView private lateinit var extensionsRecyclerView: RecyclerView
private val skipIcons: Boolean = PrefManager.getVal(PrefName.SkipExtensionIcons) private val skipIcons: Boolean = PrefManager.getVal(PrefName.SkipExtensionIcons)
@ -181,9 +181,9 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
_binding = FragmentMangaExtensionsBinding.inflate(inflater, container, false) _binding = FragmentExtensionsBinding.inflate(inflater, container, false)
extensionsRecyclerView = binding.allMangaExtensionsRecyclerView extensionsRecyclerView = binding.allExtensionsRecyclerView
extensionsRecyclerView.layoutManager = LinearLayoutManager(requireContext()) extensionsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
extensionsRecyclerView.adapter = extensionsAdapter extensionsRecyclerView.adapter = extensionsAdapter

View file

@ -13,7 +13,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
import ani.dantotsu.databinding.FragmentMangaExtensionsBinding import ani.dantotsu.databinding.FragmentExtensionsBinding
import ani.dantotsu.settings.paging.MangaExtensionAdapter import ani.dantotsu.settings.paging.MangaExtensionAdapter
import ani.dantotsu.settings.paging.MangaExtensionsViewModel import ani.dantotsu.settings.paging.MangaExtensionsViewModel
import ani.dantotsu.settings.paging.MangaExtensionsViewModelFactory import ani.dantotsu.settings.paging.MangaExtensionsViewModelFactory
@ -30,7 +30,7 @@ import uy.kohesive.injekt.api.get
class MangaExtensionsFragment : Fragment(), class MangaExtensionsFragment : Fragment(),
SearchQueryHandler, OnMangaInstallClickListener { SearchQueryHandler, OnMangaInstallClickListener {
private var _binding: FragmentMangaExtensionsBinding? = null private var _binding: FragmentExtensionsBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private val viewModel: MangaExtensionsViewModel by viewModels { private val viewModel: MangaExtensionsViewModel by viewModels {
@ -49,12 +49,12 @@ class MangaExtensionsFragment : Fragment(),
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
_binding = FragmentMangaExtensionsBinding.inflate(inflater, container, false) _binding = FragmentExtensionsBinding.inflate(inflater, container, false)
binding.allMangaExtensionsRecyclerView.isNestedScrollingEnabled = false binding.allExtensionsRecyclerView.isNestedScrollingEnabled = false
binding.allMangaExtensionsRecyclerView.adapter = adapter binding.allExtensionsRecyclerView.adapter = adapter
binding.allMangaExtensionsRecyclerView.layoutManager = LinearLayoutManager(context) binding.allExtensionsRecyclerView.layoutManager = LinearLayoutManager(context)
(binding.allMangaExtensionsRecyclerView.layoutManager as LinearLayoutManager).isItemPrefetchEnabled = (binding.allExtensionsRecyclerView.layoutManager as LinearLayoutManager).isItemPrefetchEnabled =
true true
lifecycleScope.launch { lifecycleScope.launch {
@ -92,8 +92,8 @@ class MangaExtensionsFragment : Fragment(),
Notifications.CHANNEL_DOWNLOADER_PROGRESS Notifications.CHANNEL_DOWNLOADER_PROGRESS
) )
.setSmallIcon(R.drawable.ic_round_sync_24) .setSmallIcon(R.drawable.ic_round_sync_24)
.setContentTitle("Installing extension") .setContentTitle(getString(R.string.installing_extension))
.setContentText("Step: $installStep") .setContentText(getString(R.string.install_step, installStep))
.setPriority(NotificationCompat.PRIORITY_LOW) .setPriority(NotificationCompat.PRIORITY_LOW)
notificationManager.notify(1, builder.build()) notificationManager.notify(1, builder.build())
}, },
@ -104,11 +104,11 @@ class MangaExtensionsFragment : Fragment(),
Notifications.CHANNEL_DOWNLOADER_ERROR Notifications.CHANNEL_DOWNLOADER_ERROR
) )
.setSmallIcon(R.drawable.ic_round_info_24) .setSmallIcon(R.drawable.ic_round_info_24)
.setContentTitle("Installation failed: ${error.message}") .setContentTitle(getString(R.string.installation_failed, error.message))
.setContentText("Error: ${error.message}") .setContentText(getString(R.string.error_message, error.message))
.setPriority(NotificationCompat.PRIORITY_HIGH) .setPriority(NotificationCompat.PRIORITY_HIGH)
notificationManager.notify(1, builder.build()) notificationManager.notify(1, builder.build())
snackString("Installation failed: ${error.message}") snackString(getString(R.string.installation_failed, error.message))
}, },
{ {
val builder = NotificationCompat.Builder( val builder = NotificationCompat.Builder(
@ -116,12 +116,12 @@ class MangaExtensionsFragment : Fragment(),
Notifications.CHANNEL_DOWNLOADER_PROGRESS Notifications.CHANNEL_DOWNLOADER_PROGRESS
) )
.setSmallIcon(R.drawable.ic_download_24) .setSmallIcon(R.drawable.ic_download_24)
.setContentTitle("Installation complete") .setContentTitle(getString(R.string.installation_complete))
.setContentText("The extension has been successfully installed.") .setContentText(getString(R.string.extension_has_been_installed))
.setPriority(NotificationCompat.PRIORITY_LOW) .setPriority(NotificationCompat.PRIORITY_LOW)
notificationManager.notify(1, builder.build()) notificationManager.notify(1, builder.build())
viewModel.invalidatePager() viewModel.invalidatePager()
snackString("Extension installed") snackString(getString(R.string.extension_installed))
} }
) )
} }

View file

@ -177,7 +177,8 @@
android:layout_height="64dp" android:layout_height="64dp"
android:fontFamily="@font/poppins_bold" android:fontFamily="@font/poppins_bold"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingHorizontal="32dp" android:paddingStart="48dp"
android:paddingEnd="32dp"
android:text="@string/sub_text_example" android:text="@string/sub_text_example"
android:textColor="?attr/colorSecondary" android:textColor="?attr/colorSecondary"
app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24" app:drawableEndCompat="@drawable/ic_round_arrow_drop_down_24"

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/allAnimeExtensionsRecyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>

View file

@ -7,7 +7,7 @@
android:paddingEnd="16dp"> android:paddingEnd="16dp">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/allMangaExtensionsRecyclerView" android:id="@+id/allExtensionsRecyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1" /> android:layout_weight="1" />

View file

@ -409,6 +409,13 @@
<string name="crop_borders">Crop Borders</string> <string name="crop_borders">Crop Borders</string>
<string name="note">NOTE</string> <string name="note">NOTE</string>
<string name="installing_extension">Installing extension</string>
<string name="installation_failed">Installation failed: %1$s</string>
<string name="installation_complete">Installation complete</string>
<string name="extension_has_been_installed">The extension has been successfully installed.</string>
<string name="extension_installed">Extension installed</string>
<string name="error_message">Error: %1$s</string>
<string name="install_step">Step: %1$s</string>
<string name="jobless_message">DAMN! YOU TRULY ARE JOBLESS\nYOU REACHED THE END</string> <string name="jobless_message">DAMN! YOU TRULY ARE JOBLESS\nYOU REACHED THE END</string>
<string name="file_manager_not_found">Couldn\'t find any File Manager to open SD card</string> <string name="file_manager_not_found">Couldn\'t find any File Manager to open SD card</string>