Improve details activity
This commit is contained in:
@@ -20,7 +20,7 @@ abstract class BaseBrowserActivity : BaseActivity<ActivityBrowserBinding>(), Bro
|
||||
|
||||
private lateinit var onBackPressedCallback: WebViewBackPressedCallback
|
||||
|
||||
final override fun onCreate(savedInstanceState: Bundle?) {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (!setContentViewWebViewSafe { ActivityBrowserBinding.inflate(layoutInflater) }) {
|
||||
return
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.koitharu.kotatsu.core.image
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import android.view.View
|
||||
import androidx.collection.ArrayMap
|
||||
import coil3.memory.MemoryCache
|
||||
import coil3.request.SuccessResult
|
||||
import coil3.util.CoilUtils
|
||||
import kotlinx.parcelize.Parceler
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
class CoilMemoryCacheKey(
|
||||
val data: MemoryCache.Key
|
||||
) : Parcelable {
|
||||
|
||||
companion object : Parceler<CoilMemoryCacheKey> {
|
||||
override fun CoilMemoryCacheKey.write(parcel: Parcel, flags: Int) = with(data) {
|
||||
parcel.writeString(key)
|
||||
parcel.writeInt(extras.size)
|
||||
for (entry in extras.entries) {
|
||||
parcel.writeString(entry.key)
|
||||
parcel.writeString(entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun create(parcel: Parcel): CoilMemoryCacheKey = CoilMemoryCacheKey(
|
||||
MemoryCache.Key(
|
||||
key = parcel.readString().orEmpty(),
|
||||
extras = run {
|
||||
val size = parcel.readInt()
|
||||
val map = ArrayMap<String, String>(size)
|
||||
repeat(size) {
|
||||
map.put(parcel.readString(), parcel.readString())
|
||||
}
|
||||
map
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
fun from(view: View): CoilMemoryCacheKey? {
|
||||
return (CoilUtils.result(view) as? SuccessResult)?.memoryCacheKey?.let {
|
||||
CoilMemoryCacheKey(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import org.koitharu.kotatsu.core.parser.external.ExternalMangaSource
|
||||
import org.koitharu.kotatsu.core.util.ext.getDisplayName
|
||||
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
||||
import org.koitharu.kotatsu.core.util.ext.toLocale
|
||||
import org.koitharu.kotatsu.core.util.ext.toLocaleOrNull
|
||||
import org.koitharu.kotatsu.parsers.model.ContentType
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
@@ -80,7 +81,7 @@ tailrec fun MangaSource.unwrap(): MangaSource = if (this is MangaSourceInfo) {
|
||||
this
|
||||
}
|
||||
|
||||
fun MangaSource.getLocale(): Locale? = (unwrap() as? MangaParserSource)?.locale?.toLocale()
|
||||
fun MangaSource.getLocale(): Locale? = (unwrap() as? MangaParserSource)?.locale?.toLocaleOrNull()
|
||||
|
||||
fun MangaSource.getSummary(context: Context): String? = when (val source = unwrap()) {
|
||||
is MangaParserSource -> {
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.koitharu.kotatsu.bookmarks.ui.AllBookmarksActivity
|
||||
import org.koitharu.kotatsu.browser.BrowserActivity
|
||||
import org.koitharu.kotatsu.browser.cloudflare.CloudFlareActivity
|
||||
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
|
||||
import org.koitharu.kotatsu.core.image.CoilMemoryCacheKey
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.model.MangaSourceInfo
|
||||
import org.koitharu.kotatsu.core.model.appUrl
|
||||
@@ -180,11 +181,12 @@ class AppRouter private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
fun openImage(url: String, source: MangaSource?, anchor: View? = null) {
|
||||
fun openImage(url: String, source: MangaSource?, anchor: View? = null, preview: CoilMemoryCacheKey? = null) {
|
||||
startActivity(
|
||||
Intent(contextOrNull(), ImageActivity::class.java)
|
||||
.setData(url.toUri())
|
||||
.putExtra(KEY_SOURCE, source?.name),
|
||||
.putExtra(KEY_SOURCE, source?.name)
|
||||
.putExtra(KEY_PREVIEW, preview),
|
||||
anchor?.let { scaleUpActivityOptionsOf(it) },
|
||||
)
|
||||
}
|
||||
@@ -768,6 +770,7 @@ class AppRouter private constructor(
|
||||
const val KEY_MANGA = "manga"
|
||||
const val KEY_MANGA_LIST = "manga_list"
|
||||
const val KEY_PAGES = "pages"
|
||||
const val KEY_PREVIEW = "preview"
|
||||
const val KEY_QUERY = "query"
|
||||
const val KEY_READER_MODE = "reader_mode"
|
||||
const val KEY_SORT_ORDER = "sort_order"
|
||||
|
||||
@@ -21,7 +21,13 @@ inline fun <T> LocaleListCompat.mapToSet(block: (Locale) -> T): Set<T> {
|
||||
|
||||
fun LocaleListCompat.getOrThrow(index: Int) = get(index) ?: throw NoSuchElementException()
|
||||
|
||||
fun String.toLocale() = Locale(this)
|
||||
fun String.toLocale(): Locale = Locale.forLanguageTag(this)
|
||||
|
||||
fun String.toLocaleOrNull() = if (isEmpty()) {
|
||||
null
|
||||
} else {
|
||||
toLocale().takeUnless { it.displayName == this }
|
||||
}
|
||||
|
||||
fun Locale?.getDisplayName(context: Context): String = when (this) {
|
||||
null -> context.getString(R.string.all_languages)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.koitharu.kotatsu.details.data
|
||||
|
||||
import org.koitharu.kotatsu.core.model.getLocale
|
||||
import org.koitharu.kotatsu.core.model.isLocal
|
||||
import org.koitharu.kotatsu.local.domain.model.LocalManga
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
@@ -7,6 +8,7 @@ import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.util.ifNullOrEmpty
|
||||
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
|
||||
import org.koitharu.kotatsu.reader.data.filterChapters
|
||||
import java.util.Locale
|
||||
|
||||
data class MangaDetails(
|
||||
private val manga: Manga,
|
||||
@@ -39,6 +41,13 @@ data class MangaDetails(
|
||||
|
||||
fun toManga() = manga
|
||||
|
||||
fun getLocale(): Locale? {
|
||||
findAppropriateLocale(chapters.keys.singleOrNull())?.let {
|
||||
return it
|
||||
}
|
||||
return manga.source.getLocale()
|
||||
}
|
||||
|
||||
fun filterChapters(branch: String?) = MangaDetails(
|
||||
manga = manga.filterChapters(branch),
|
||||
localManga = localManga?.run {
|
||||
@@ -69,4 +78,16 @@ data class MangaDetails(
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun findAppropriateLocale(name: String?): Locale? {
|
||||
if (name.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
return Locale.getAvailableLocales().find { lc ->
|
||||
name.contains(lc.getDisplayName(lc), ignoreCase = true) ||
|
||||
name.contains(lc.getDisplayName(Locale.ENGLISH), ignoreCase = true) ||
|
||||
name.contains(lc.getDisplayLanguage(lc), ignoreCase = true) ||
|
||||
name.contains(lc.getDisplayLanguage(Locale.ENGLISH), ignoreCase = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.bookmarks.domain.Bookmark
|
||||
import org.koitharu.kotatsu.core.image.CoilMemoryCacheKey
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.model.LocalMangaSource
|
||||
import org.koitharu.kotatsu.core.model.UnknownMangaSource
|
||||
@@ -100,10 +101,12 @@ import org.koitharu.kotatsu.list.ui.adapter.mangaGridItemAD
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||
import org.koitharu.kotatsu.list.ui.size.StaticItemSizeResolver
|
||||
import org.koitharu.kotatsu.parsers.model.ContentRating
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.util.ifNullOrEmpty
|
||||
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
|
||||
import org.koitharu.kotatsu.parsers.util.toTitleCase
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToInt
|
||||
@@ -179,16 +182,6 @@ class DetailsActivity :
|
||||
viewModel.isStatsAvailable.observe(this, menuInvalidator)
|
||||
viewModel.remoteManga.observe(this, menuInvalidator)
|
||||
viewModel.tags.observe(this, ::onTagsChanged)
|
||||
viewModel.branches.observe(this) {
|
||||
val branch = it.singleOrNull()
|
||||
infoBinding.textViewTranslation.textAndVisible = branch?.name
|
||||
infoBinding.textViewTranslation.drawableStart = branch?.locale?.let {
|
||||
LocaleUtils.getEmojiFlag(it)
|
||||
}?.let {
|
||||
TextDrawable.compound(infoBinding.textViewTranslation, it)
|
||||
}
|
||||
infoBinding.textViewTranslationLabel.isVisible = infoBinding.textViewTranslation.isVisible
|
||||
}
|
||||
viewModel.chapters.observe(this, PrefetchObserver(this))
|
||||
viewModel.onDownloadStarted
|
||||
.filterNot { appRouter.isChapterPagesSheetShown() }
|
||||
@@ -202,7 +195,7 @@ class DetailsActivity :
|
||||
addMenuProvider(menuProvider)
|
||||
}
|
||||
|
||||
override fun isNsfwContent(): Flow<Boolean> = viewModel.manga.map { it?.isNsfw == true }
|
||||
override fun isNsfwContent(): Flow<Boolean> = viewModel.manga.map { it?.contentRating == ContentRating.ADULT }
|
||||
|
||||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
@@ -232,6 +225,7 @@ class DetailsActivity :
|
||||
router.openImage(
|
||||
url = viewModel.coverUrl.value ?: return,
|
||||
source = manga.source,
|
||||
preview = CoilMemoryCacheKey.from(viewBinding.imageViewCover),
|
||||
anchor = v,
|
||||
)
|
||||
}
|
||||
@@ -407,10 +401,20 @@ class DetailsActivity :
|
||||
with(viewBinding) {
|
||||
textViewTitle.text = manga.title
|
||||
textViewSubtitle.textAndVisible = manga.altTitles.joinToString("\n")
|
||||
textViewNsfw.isVisible = manga.isNsfw
|
||||
textViewNsfw16.isVisible = manga.contentRating == ContentRating.SUGGESTIVE
|
||||
textViewNsfw18.isVisible = manga.contentRating == ContentRating.ADULT
|
||||
textViewDescription.text = details.description.ifNullOrEmpty { getString(R.string.no_description) }
|
||||
}
|
||||
with(infoBinding) {
|
||||
val translation = details.getLocale()
|
||||
infoBinding.textViewTranslation.textAndVisible = translation?.getDisplayLanguage(translation)
|
||||
?.toTitleCase(translation)
|
||||
infoBinding.textViewTranslation.drawableStart = translation?.let {
|
||||
LocaleUtils.getEmojiFlag(it)
|
||||
}?.let {
|
||||
TextDrawable.compound(infoBinding.textViewTranslation, it)
|
||||
}
|
||||
infoBinding.textViewTranslationLabel.isVisible = infoBinding.textViewTranslation.isVisible
|
||||
textViewAuthor.textAndVisible = manga.author
|
||||
textViewAuthorLabel.isVisible = textViewAuthor.isVisible
|
||||
if (manga.hasRating) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.koitharu.kotatsu.details.ui.model
|
||||
|
||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import java.util.Locale
|
||||
|
||||
data class MangaBranch(
|
||||
val name: String?,
|
||||
@@ -11,8 +10,6 @@ data class MangaBranch(
|
||||
val isCurrent: Boolean,
|
||||
) : ListModel {
|
||||
|
||||
val locale: Locale? by lazy(::findAppropriateLocale)
|
||||
|
||||
override fun areItemsTheSame(other: ListModel): Boolean {
|
||||
return other is MangaBranch && other.name == name
|
||||
}
|
||||
@@ -28,16 +25,4 @@ data class MangaBranch(
|
||||
override fun toString(): String {
|
||||
return "$name: $count"
|
||||
}
|
||||
|
||||
private fun findAppropriateLocale(): Locale? {
|
||||
if (name.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
return Locale.getAvailableLocales().find { lc ->
|
||||
name.contains(lc.getDisplayName(lc), ignoreCase = true) ||
|
||||
name.contains(lc.getDisplayName(Locale.ENGLISH), ignoreCase = true) ||
|
||||
name.contains(lc.getDisplayLanguage(lc), ignoreCase = true) ||
|
||||
name.contains(lc.getDisplayLanguage(Locale.ENGLISH), ignoreCase = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class BookmarksViewModel @Inject constructor(
|
||||
if (b.isNullOrEmpty()) {
|
||||
continue
|
||||
}
|
||||
result += ListHeader(chapter.name)
|
||||
result += ListHeader(chapter)
|
||||
result.addAll(b)
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
|
||||
@@ -130,7 +130,7 @@ class PagesViewModel @Inject constructor(
|
||||
for (page in snapshot) {
|
||||
if (page.chapterId != previousChapterId) {
|
||||
chaptersLoader.peekChapter(page.chapterId)?.let {
|
||||
add(ListHeader(it.name))
|
||||
add(ListHeader(it))
|
||||
}
|
||||
previousChapterId = page.chapterId
|
||||
}
|
||||
|
||||
@@ -11,21 +11,20 @@ import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
|
||||
import coil3.Image
|
||||
import coil3.ImageLoader
|
||||
import coil3.asDrawable
|
||||
import coil3.request.CachePolicy
|
||||
import coil3.request.ErrorResult
|
||||
import coil3.request.ImageRequest
|
||||
import coil3.request.SuccessResult
|
||||
import coil3.request.lifecycle
|
||||
import coil3.target.ViewTarget
|
||||
import coil3.target.GenericViewTarget
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.image.CoilMemoryCacheKey
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.core.nav.AppRouter
|
||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||
@@ -36,6 +35,7 @@ import org.koitharu.kotatsu.core.util.ext.end
|
||||
import org.koitharu.kotatsu.core.util.ext.enqueueWith
|
||||
import org.koitharu.kotatsu.core.util.ext.getDisplayIcon
|
||||
import org.koitharu.kotatsu.core.util.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.core.util.ext.getParcelableExtraCompat
|
||||
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
||||
import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
@@ -63,7 +63,6 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(),
|
||||
setContentView(ActivityImageBinding.inflate(layoutInflater))
|
||||
viewBinding.buttonBack.setOnClickListener(this)
|
||||
viewBinding.buttonMenu.setOnClickListener(this)
|
||||
val imageUrl = requireNotNull(intent.data)
|
||||
|
||||
val menuProvider = ImageMenuProvider(
|
||||
activity = this,
|
||||
@@ -74,14 +73,14 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(),
|
||||
viewModel.isLoading.observe(this, ::onLoadingStateChanged)
|
||||
viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.root, null))
|
||||
viewModel.onImageSaved.observeEvent(this, ::onImageSaved)
|
||||
loadImage(imageUrl)
|
||||
loadImage()
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.button_back -> dispatchNavigateUp()
|
||||
R.id.button_menu -> menuMediator.onLongClick(v)
|
||||
else -> loadImage(intent.data)
|
||||
else -> loadImage()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,10 +121,11 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(),
|
||||
return insets.consumeAll(typeMask)
|
||||
}
|
||||
|
||||
private fun loadImage(url: Uri?) {
|
||||
private fun loadImage() {
|
||||
ImageRequest.Builder(this)
|
||||
.data(url)
|
||||
.memoryCachePolicy(CachePolicy.DISABLED)
|
||||
.data(intent.data)
|
||||
.memoryCacheKey(intent.getParcelableExtraCompat<CoilMemoryCacheKey>(AppRouter.KEY_PREVIEW)?.data)
|
||||
.memoryCachePolicy(CachePolicy.READ_ONLY)
|
||||
.lifecycle(this)
|
||||
.listener(this)
|
||||
.mangaSourceExtra(MangaSource(intent.getStringExtra(AppRouter.KEY_SOURCE)))
|
||||
@@ -158,11 +158,13 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(),
|
||||
|
||||
private class SsivTarget(
|
||||
override val view: SubsamplingScaleImageView,
|
||||
) : ViewTarget<SubsamplingScaleImageView> {
|
||||
) : GenericViewTarget<SubsamplingScaleImageView>() {
|
||||
|
||||
override fun onError(error: Image?) = setDrawable(error?.asDrawable(view.resources))
|
||||
|
||||
override fun onSuccess(result: Image) = setDrawable(result.asDrawable(view.resources))
|
||||
override var drawable: Drawable? = null
|
||||
set(value) {
|
||||
field = value
|
||||
setImageDrawable(value)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return (this === other) || (other is SsivTarget && view == other.view)
|
||||
@@ -172,7 +174,7 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(),
|
||||
|
||||
override fun toString() = "SsivTarget(view=$view)"
|
||||
|
||||
private fun setDrawable(drawable: Drawable?) {
|
||||
private fun setImageDrawable(drawable: Drawable?) {
|
||||
if (drawable != null) {
|
||||
view.setImage(ImageSource.bitmap(drawable.toBitmap()))
|
||||
} else {
|
||||
|
||||
@@ -2,8 +2,11 @@ package org.koitharu.kotatsu.list.ui.model
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.StringRes
|
||||
import org.koitharu.kotatsu.core.model.getLocalizedTitle
|
||||
import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
|
||||
@ConsistentCopyVisibility
|
||||
data class ListHeader private constructor(
|
||||
private val textRaw: Any,
|
||||
@StringRes val buttonTextRes: Int,
|
||||
@@ -25,6 +28,13 @@ data class ListHeader private constructor(
|
||||
badge: String? = null,
|
||||
) : this(textRaw = textRes, buttonTextRes, payload, badge)
|
||||
|
||||
constructor(
|
||||
chapter: MangaChapter,
|
||||
@StringRes buttonTextRes: Int = 0,
|
||||
payload: Any? = null,
|
||||
badge: String? = null,
|
||||
) : this(textRaw = chapter, buttonTextRes, payload, badge)
|
||||
|
||||
constructor(
|
||||
dateTimeAgo: DateTimeAgo,
|
||||
@StringRes buttonTextRes: Int = 0,
|
||||
@@ -36,6 +46,7 @@ data class ListHeader private constructor(
|
||||
is CharSequence -> textRaw
|
||||
is Int -> if (textRaw != 0) context.getString(textRaw) else null
|
||||
is DateTimeAgo -> textRaw.format(context)
|
||||
is MangaChapter -> textRaw.getLocalizedTitle(context.resources)
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.koitharu.kotatsu.list.domain.ReadingProgress.Companion.PROGRESS_NONE
|
||||
import org.koitharu.kotatsu.local.data.LocalStorageChanges
|
||||
import org.koitharu.kotatsu.local.domain.DeleteLocalMangaUseCase
|
||||
import org.koitharu.kotatsu.local.domain.model.LocalManga
|
||||
import org.koitharu.kotatsu.parsers.model.ContentRating
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.util.ifNullOrEmpty
|
||||
@@ -177,7 +178,7 @@ class ReaderViewModel @Inject constructor(
|
||||
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, null),
|
||||
)
|
||||
|
||||
val isMangaNsfw = manga.map { it?.isNsfw == true }
|
||||
val isMangaNsfw = manga.map { it?.contentRating == ContentRating.ADULT }
|
||||
|
||||
val isBookmarkAdded = readingState.flatMapLatest { state ->
|
||||
val manga = mangaDetails.value?.toManga()
|
||||
|
||||
@@ -74,19 +74,27 @@
|
||||
tools:ignore="ContentDescription,UnusedAttribute" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_nsfw"
|
||||
android:id="@+id/textView_nsfw_16"
|
||||
style="@style/Widget.Kotatsu.TextView.Badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/card_indicator_offset"
|
||||
android:background="@drawable/bg_chip"
|
||||
android:backgroundTint="@color/warning"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="4dp"
|
||||
android:paddingVertical="2dp"
|
||||
android:backgroundTint="@color/nsfw_16"
|
||||
android:text="@string/nsfw_16"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/imageView_cover"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_nsfw_18"
|
||||
style="@style/Widget.Kotatsu.TextView.Badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/card_indicator_offset"
|
||||
android:backgroundTint="@color/nsfw_18"
|
||||
android:text="@string/nsfw"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="?textAppearanceLabelMedium"
|
||||
android:textColor="?colorOnError"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />
|
||||
|
||||
|
||||
@@ -66,19 +66,27 @@
|
||||
tools:ignore="ContentDescription,UnusedAttribute" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_nsfw"
|
||||
android:id="@+id/textView_nsfw_16"
|
||||
style="@style/Widget.Kotatsu.TextView.Badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/card_indicator_offset"
|
||||
android:background="@drawable/bg_chip"
|
||||
android:backgroundTint="@color/warning"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="4dp"
|
||||
android:paddingVertical="2dp"
|
||||
android:backgroundTint="@color/nsfw_16"
|
||||
android:text="@string/nsfw_16"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/imageView_cover"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_nsfw_18"
|
||||
style="@style/Widget.Kotatsu.TextView.Badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/card_indicator_offset"
|
||||
android:backgroundTint="@color/nsfw_18"
|
||||
android:text="@string/nsfw"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="?textAppearanceLabelMedium"
|
||||
android:textColor="?colorOnError"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
<color name="common_green">#81C784</color>
|
||||
<color name="common_red">#E57373</color>
|
||||
<color name="dim2">#C8000000</color>
|
||||
<color name="nsfw_18">#BF360C</color>
|
||||
<color name="nsfw_16">#FF6F00</color>
|
||||
|
||||
<!-- Color schemes colors -->
|
||||
<color name="background_miku">#191C1C</color>
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
<color name="launcher_background">#FFFFFF</color>
|
||||
<color name="common_green">#388E3C</color>
|
||||
<color name="common_red">#D32F2F</color>
|
||||
<color name="nsfw_18">#FF8A65</color>
|
||||
<color name="nsfw_16">#FFD54F</color>
|
||||
|
||||
<!-- Color schemes colors -->
|
||||
<color name="background_miku">#F7FAF8</color>
|
||||
|
||||
@@ -215,6 +215,7 @@
|
||||
<string name="preload_pages">Preload pages</string>
|
||||
<string name="logged_in_as">Logged in as %s</string>
|
||||
<string name="nsfw">18+</string>
|
||||
<string name="nsfw_16">16+</string>
|
||||
<string name="various_languages">Various languages</string>
|
||||
<string name="search_chapters">Find chapter</string>
|
||||
<string name="chapters_empty">No chapters in this manga</string>
|
||||
|
||||
@@ -229,6 +229,18 @@
|
||||
<item name="android:textAppearance">?textAppearanceLabelMedium</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Kotatsu.TextView.Badge" parent="Widget.MaterialComponents.TextView">
|
||||
<item name="android:background">@drawable/bg_chip</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:textAlignment">center</item>
|
||||
<item name="android:paddingStart">4dp</item>
|
||||
<item name="android:paddingEnd">4dp</item>
|
||||
<item name="android:paddingTop">2dp</item>
|
||||
<item name="android:paddingBottom">2dp</item>
|
||||
<item name="android:textAppearance">?textAppearanceLabelMedium</item>
|
||||
<item name="android:textColor">?colorOnBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="ThemeOverlay.Kotatsu.MainToolbar" parent="">
|
||||
<item name="colorControlHighlight">@color/selector_overlay</item>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user