Option to edit the series type of manga etc.

All this is doing is adding and removing the correct tags to shift the series type

Reordering the series/reader type to comply with this
This commit is contained in:
Jays2Kings 2021-04-14 22:06:26 -04:00
parent 7b13c4163e
commit 0afe075f46
6 changed files with 136 additions and 31 deletions

View File

@ -66,38 +66,44 @@ interface Manga : SManga {
} }
fun getGenres(): List<String>? { fun getGenres(): List<String>? {
return genre?.split(", ")?.map { it.trim() } return genre?.split(",")
?.mapNotNull { tag -> tag.trim().takeUnless { it.isBlank() } }
} }
fun getOriginalGenres(): List<String>? { fun getOriginalGenres(): List<String>? {
return (originalGenre ?: genre)?.split(", ")?.map { it.trim() } return (originalGenre ?: genre)?.split(",")
?.mapNotNull { tag -> tag.trim().takeUnless { it.isBlank() } }
} }
/** /**
* The type of comic the manga is (ie. manga, manhwa, manhua) * The type of comic the manga is (ie. manga, manhwa, manhua)
*/ */
fun seriesType(): Int { fun seriesType(useOriginalTags: Boolean = false, customTags: String? = null): Int {
val sourceName = Injekt.get<SourceManager>().getOrStub(source).name val sourceName = Injekt.get<SourceManager>().getOrStub(source).name
val currentTags = val tags = customTags ?: if (useOriginalTags) originalGenre else genre
genre?.split(",")?.map { it.trim().toLowerCase(Locale.US) } ?: emptyList() val currentTags = tags?.split(",")?.map { it.trim().toLowerCase(Locale.US) } ?: emptyList()
return if (currentTags.any { tag -> isMangaTag(tag) }) { return if (currentTags.any { tag -> isMangaTag(tag) }) {
TYPE_MANGA TYPE_MANGA
} else if (currentTags.any { tag -> isComicTag(tag) } || } else if (currentTags.any { tag -> isComicTag(tag) } ||
isComicSource(sourceName) isComicSource(sourceName)
) { ) {
TYPE_COMIC TYPE_COMIC
} else if (sourceName.contains("webtoon", true) && } else if (currentTags.any { tag -> isWebtoonTag(tag) } ||
(
sourceName.contains("webtoon", true) &&
currentTags.none { tag -> isManhuaTag(tag) } && currentTags.none { tag -> isManhuaTag(tag) } &&
currentTags.none { tag -> isManhwaTag(tag) } currentTags.none { tag -> isManhwaTag(tag) }
)
) { ) {
TYPE_WEBTOON TYPE_WEBTOON
} else if (currentTags.any { tag -> isManhuaTag(tag) } || sourceName.contains("manhua", true) } else if (currentTags.any { tag -> isManhuaTag(tag) } || sourceName.contains(
"manhua",
true
)
) { ) {
TYPE_MANHUA TYPE_MANHUA
} else if (currentTags.any { tag -> isManhwaTag(tag) } || isWebtoonSource(sourceName)) { } else if (currentTags.any { tag -> isManhwaTag(tag) } || isWebtoonSource(sourceName)) {
TYPE_MANHWA TYPE_MANHWA
} else if (currentTags.any { tag -> tag.startsWith("webtoon") }) {
TYPE_WEBTOON
} else { } else {
TYPE_MANGA TYPE_MANGA
} }
@ -109,24 +115,37 @@ interface Manga : SManga {
*/ */
fun defaultReaderType(): Int { fun defaultReaderType(): Int {
val sourceName = Injekt.get<SourceManager>().getOrStub(source).name val sourceName = Injekt.get<SourceManager>().getOrStub(source).name
val currentTags = genre?.split(",")?.map { it.trim().toLowerCase(Locale.US) } val currentTags = genre?.split(",")?.map { it.trim().toLowerCase(Locale.US) } ?: emptyList()
return if (currentTags?.any return if (currentTags.any
{ tag -> { tag ->
isManhwaTag(tag) || tag.contains("webtoon") isManhwaTag(tag) || tag.contains("webtoon")
} == true || isWebtoonSource(sourceName) } || (
isWebtoonSource(sourceName) &&
currentTags.none { tag -> isManhuaTag(tag) } &&
currentTags.none { tag -> isComicTag(tag) }
)
) { ) {
ReaderActivity.WEBTOON ReaderActivity.WEBTOON
} else if (currentTags?.any } else if (currentTags.any
{ tag -> { tag ->
tag == "chinese" || tag == "manhua" || tag == "chinese" || tag == "manhua" ||
tag.startsWith("english") || tag == "comic" tag.startsWith("english") || tag == "comic"
} == true || (isComicSource(sourceName) && !sourceName.contains("tapas", true)) || } || (
sourceName.contains("manhua", true) isComicSource(sourceName) && !sourceName.contains("tapas", true) &&
currentTags.none { tag -> isMangaTag(tag) }
) ||
(sourceName.contains("manhua", true) && currentTags.none { tag -> isMangaTag(tag) })
) { ) {
ReaderActivity.LEFT_TO_RIGHT ReaderActivity.LEFT_TO_RIGHT
} else 0 } else 0
} }
fun isSeriesTag(tag: String): Boolean {
val tagLower = tag.toLowerCase(Locale.ROOT)
return isMangaTag(tagLower) || isManhuaTag(tagLower) ||
isManhwaTag(tagLower) || isComicTag(tagLower) || isWebtoonTag(tagLower)
}
fun isMangaTag(tag: String): Boolean { fun isMangaTag(tag: String): Boolean {
return tag in listOf("manga", "манга", "jp") || tag.startsWith("japanese") return tag in listOf("manga", "манга", "jp") || tag.startsWith("japanese")
} }
@ -150,6 +169,10 @@ interface Manga : SManga {
return tag in listOf("comic", "комикс", "en", "gb") || tag.startsWith("english") return tag in listOf("comic", "комикс", "en", "gb") || tag.startsWith("english")
} }
fun isWebtoonTag(tag: String): Boolean {
return tag.startsWith("webtoon")
}
fun isWebtoonSource(sourceName: String): Boolean { fun isWebtoonSource(sourceName: String): Boolean {
return sourceName.contains("webtoon", true) || return sourceName.contains("webtoon", true) ||
sourceName.contains("manhwa", true) || sourceName.contains("manhwa", true) ||

View File

@ -26,7 +26,6 @@ import eu.kanade.tachiyomi.util.view.expand
import eu.kanade.tachiyomi.util.view.setEdgeToEdge import eu.kanade.tachiyomi.util.view.setEdgeToEdge
import eu.kanade.tachiyomi.util.view.updateLayoutParams import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.updatePaddingRelative import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.ArrayList import java.util.ArrayList
import java.util.Date import java.util.Date

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.manga
import android.app.Dialog import android.app.Dialog
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.core.view.isVisible
import coil.api.loadAny import coil.api.loadAny
import coil.request.Parameters import coil.request.Parameters
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
@ -19,6 +20,7 @@ import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.util.isLocal import eu.kanade.tachiyomi.util.isLocal
import eu.kanade.tachiyomi.util.lang.chop import eu.kanade.tachiyomi.util.lang.chop
import eu.kanade.tachiyomi.util.view.visibleIf import eu.kanade.tachiyomi.util.view.visibleIf
import me.gujun.android.taggroup.TagGroup
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -92,7 +94,11 @@ class EditMangaDialog : DialogController {
if (manga.description != manga.originalDescription) { if (manga.description != manga.originalDescription) {
binding.mangaDescription.append(manga.description ?: "") binding.mangaDescription.append(manga.description ?: "")
} }
binding.mangaGenresTags.setTags(manga.genre?.split(", ") ?: emptyList()) binding.mangaGenresTags.setTags(
manga.genre?.split(",")
?.map { it.trim() }
?.filter { it.isNotBlank() } ?: emptyList()
)
binding.title.hint = "${resources?.getString(R.string.title)}: ${manga.originalTitle}" binding.title.hint = "${resources?.getString(R.string.title)}: ${manga.originalTitle}"
if (manga.originalAuthor != null) { if (manga.originalAuthor != null) {
@ -109,7 +115,24 @@ class EditMangaDialog : DialogController {
)?.chop(20)}" )?.chop(20)}"
} }
} }
binding.mangaGenresTags.setOnTagChangeListener(object : TagGroup.OnTagChangeListener {
override fun onAppend(tagGroup: TagGroup?, tag: String?): Boolean {
val tags: List<String> = tagGroup?.tags.orEmpty().toList() + (tag ?: "")
binding.seriesType.setSelection(manga.seriesType(customTags = tags.joinToString(", ")) - 1)
return true
}
override fun onDelete(tagGroup: TagGroup?, tag: String?) {
val tags: List<String> = tagGroup?.tags.orEmpty().toList() - (tag ?: "")
binding.seriesType.setSelection(manga.seriesType(customTags = tags.joinToString(", ")) - 1)
}
})
binding.mangaStatus.setSelection(manga.status.coerceIn(SManga.UNKNOWN, SManga.LICENSED)) binding.mangaStatus.setSelection(manga.status.coerceIn(SManga.UNKNOWN, SManga.LICENSED))
val oldType = manga.seriesType()
binding.seriesType.setSelection(oldType - 1)
binding.seriesType.onItemSelectedListener = {
binding.resetsReadingMode.isVisible = it + 1 != oldType
}
binding.mangaGenresTags.clearFocus() binding.mangaGenresTags.clearFocus()
binding.coverLayout.setOnClickListener { binding.coverLayout.setOnClickListener {
infoController.changeCover() infoController.changeCover()
@ -138,7 +161,11 @@ class EditMangaDialog : DialogController {
if (manga.genre.isNullOrBlank() || manga.source == LocalSource.ID) binding.mangaGenresTags.setTags( if (manga.genre.isNullOrBlank() || manga.source == LocalSource.ID) binding.mangaGenresTags.setTags(
emptyList() emptyList()
) )
else binding.mangaGenresTags.setTags(manga.originalGenre?.split(", ")) else {
binding.mangaGenresTags.setTags(manga.originalGenre?.split(", "))
binding.seriesType.setSelection(manga.seriesType(true) - 1)
binding.resetsReadingMode.isVisible = false
}
} }
fun updateCover(uri: Uri) { fun updateCover(uri: Uri) {
@ -156,6 +183,7 @@ class EditMangaDialog : DialogController {
binding.mangaDescription.text.toString(), binding.mangaDescription.text.toString(),
binding.mangaGenresTags.tags, binding.mangaGenresTags.tags,
binding.mangaStatus.selectedPosition, binding.mangaStatus.selectedPosition,
if (binding.resetsReadingMode.isVisible) binding.seriesType.selectedPosition + 1 else null,
willResetCover willResetCover
) )
} }

View File

@ -630,6 +630,7 @@ class MangaDetailsPresenter(
description: String?, description: String?,
tags: Array<String>?, tags: Array<String>?,
status: Int?, status: Int?,
seriesType: Int?,
resetCover: Boolean = false resetCover: Boolean = false
) { ) {
if (manga.source == LocalSource.ID) { if (manga.source == LocalSource.ID) {
@ -639,15 +640,25 @@ class MangaDetailsPresenter(
manga.description = description?.trimOrNull() manga.description = description?.trimOrNull()
val tagsString = tags?.joinToString(", ") { it.capitalize() } val tagsString = tags?.joinToString(", ") { it.capitalize() }
manga.genre = if (tags.isNullOrEmpty()) null else tagsString?.trim() manga.genre = if (tags.isNullOrEmpty()) null else tagsString?.trim()
if (seriesType != null) {
manga.genre = setSeriesType(seriesType, manga.genre).joinToString(", ") { it.capitalize() }
manga.viewer = -1
db.updateMangaViewer(manga).executeAsBlocking()
}
manga.status = status ?: SManga.UNKNOWN manga.status = status ?: SManga.UNKNOWN
LocalSource(downloadManager.context).updateMangaInfo(manga) LocalSource(downloadManager.context).updateMangaInfo(manga)
db.updateMangaInfo(manga).executeAsBlocking() db.updateMangaInfo(manga).executeAsBlocking()
} else { } else {
val genre = if (!tags.isNullOrEmpty() && tags.joinToString(", ") != manga.genre) { var genre = if (!tags.isNullOrEmpty() && tags.joinToString(", ") != manga.genre) {
tags.map { it.capitalize() }.toTypedArray() tags.map { it.capitalize() }.toTypedArray()
} else { } else {
null null
} }
if (seriesType != null) {
genre = setSeriesType(seriesType, genre?.joinToString(", "))
manga.viewer = -1
db.updateMangaViewer(manga).executeAsBlocking()
}
val manga = CustomMangaManager.MangaJson( val manga = CustomMangaManager.MangaJson(
manga.id!!, manga.id!!,
title?.trimOrNull(), title?.trimOrNull(),
@ -668,6 +679,19 @@ class MangaDetailsPresenter(
controller.updateHeader() controller.updateHeader()
} }
private fun setSeriesType(seriesType: Int, genres: String? = null): Array<String> {
val tags = (genres ?: manga.genre)?.split(",")?.map { it.trim() }?.toMutableList() ?: mutableListOf()
tags.removeAll { manga.isSeriesTag(it) }
when (seriesType) {
Manga.TYPE_MANGA -> tags.add("Manga")
Manga.TYPE_MANHUA -> tags.add("Manhua")
Manga.TYPE_MANHWA -> tags.add("Manhwa")
Manga.TYPE_COMIC -> tags.add("Comic")
Manga.TYPE_WEBTOON -> tags.add("Webtoon")
}
return tags.toTypedArray()
}
fun editCoverWithStream(uri: Uri): Boolean { fun editCoverWithStream(uri: Uri): Boolean {
val inputStream = val inputStream =
downloadManager.context.contentResolver.openInputStream(uri) ?: return false downloadManager.context.contentResolver.openInputStream(uri) ?: return false

View File

@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
@ -35,16 +36,6 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:text="@string/reset_cover" /> android:text="@string/reset_cover" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/manga_status"
app:title="@string/status"
android:layout_marginEnd="32dp"
android:layout_marginStart="32dp"
android:layout_marginBottom="6dp"
android:entries="@array/manga_statuses"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<EditText <EditText
android:id="@+id/title" android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -84,6 +75,38 @@
android:inputType="text|textMultiLine" android:inputType="text|textMultiLine"
android:scrollHorizontally="false" /> android:scrollHorizontally="false" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/manga_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="6dp"
android:entries="@array/manga_statuses"
app:title="@string/status" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/series_type"
app:title="@string/series_type"
android:layout_marginEnd="16dp"
android:layout_marginStart="18dp"
android:entries="@array/series_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/resets_reading_mode"
android:text="@string/changing_will_reset_reading_mode"
android:textColor="?android:attr/textColorSecondary"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:textAlignment="center"
android:visibility="gone"
tools:visibility="visible"
android:layout_marginBottom="6dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<me.gujun.android.taggroup.TagGroup <me.gujun.android.taggroup.TagGroup
android:id="@+id/manga_genres_tags" android:id="@+id/manga_genres_tags"
style="@style/TagGroup" style="@style/TagGroup"

View File

@ -33,6 +33,14 @@
<item>@string/licensed</item> <item>@string/licensed</item>
</string-array> </string-array>
<string-array name="series_type">
<item>@string/manga</item>
<item>@string/manhwa</item>
<item>@string/manhua</item>
<item>@string/comic</item>
<item>@string/webtoon</item>
</string-array>
<string-array name="webtoon_side_padding"> <string-array name="webtoon_side_padding">
<item>@string/webtoon_side_padding_0</item> <item>@string/webtoon_side_padding_0</item>
<item>@string/webtoon_side_padding_10</item> <item>@string/webtoon_side_padding_10</item>