Support images in manga description
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package org.koitharu.kotatsu.core.ui
|
||||
|
||||
import android.text.Html
|
||||
import coil.ComponentRegistry
|
||||
import coil.ImageLoader
|
||||
import coil.disk.DiskCache
|
||||
@@ -10,6 +11,7 @@ import org.koin.dsl.module
|
||||
import org.koitharu.kotatsu.core.parser.FaviconMapper
|
||||
import org.koitharu.kotatsu.local.data.CacheDir
|
||||
import org.koitharu.kotatsu.local.data.CbzFetcher
|
||||
import org.koitharu.kotatsu.utils.image.CoilImageGetter
|
||||
|
||||
val uiModule
|
||||
get() = module {
|
||||
@@ -40,4 +42,5 @@ val uiModule
|
||||
.build()
|
||||
).build()
|
||||
}
|
||||
factory<Html.ImageGetter> { CoilImageGetter(androidContext(), get()) }
|
||||
}
|
||||
@@ -8,6 +8,6 @@ val detailsModule
|
||||
get() = module {
|
||||
|
||||
viewModel { intent ->
|
||||
DetailsViewModel(intent.get(), get(), get(), get(), get(), get(), get(), get(), get())
|
||||
DetailsViewModel(intent.get(), get(), get(), get(), get(), get(), get(), get(), get(), get())
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import coil.size.Scale
|
||||
import coil.util.CoilUtils
|
||||
import com.google.android.material.chip.Chip
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
@@ -80,6 +81,7 @@ class DetailsFragment :
|
||||
viewModel.readingHistory.observe(viewLifecycleOwner, ::onHistoryChanged)
|
||||
viewModel.bookmarks.observe(viewLifecycleOwner, ::onBookmarksChanged)
|
||||
viewModel.scrobblingInfo.observe(viewLifecycleOwner, ::onScrobblingInfoChanged)
|
||||
viewModel.description.observe(viewLifecycleOwner, ::onDescriptionChanged)
|
||||
addMenuProvider(DetailsMenuProvider())
|
||||
}
|
||||
|
||||
@@ -108,8 +110,6 @@ class DetailsFragment :
|
||||
textViewTitle.text = manga.title
|
||||
textViewSubtitle.textAndVisible = manga.altTitle
|
||||
textViewAuthor.textAndVisible = manga.author
|
||||
textViewDescription.text = manga.description?.parseAsHtml()?.takeUnless(Spanned::isBlank)
|
||||
?: getString(R.string.no_description)
|
||||
when (manga.state) {
|
||||
MangaState.FINISHED -> {
|
||||
textViewState.apply {
|
||||
@@ -172,6 +172,14 @@ class DetailsFragment :
|
||||
}
|
||||
}
|
||||
|
||||
private fun onDescriptionChanged(description: CharSequence?) {
|
||||
if (description.isNullOrBlank()) {
|
||||
binding.textViewDescription.setText(R.string.no_description)
|
||||
} else {
|
||||
binding.textViewDescription.text = description
|
||||
}
|
||||
}
|
||||
|
||||
private fun onHistoryChanged(history: MangaHistory?) {
|
||||
with(binding.buttonRead) {
|
||||
if (history == null) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.koitharu.kotatsu.details.ui
|
||||
|
||||
import android.text.Html
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.lifecycle.asLiveData
|
||||
@@ -43,6 +45,7 @@ class DetailsViewModel(
|
||||
private val bookmarksRepository: BookmarksRepository,
|
||||
private val settings: AppSettings,
|
||||
private val scrobbler: Scrobbler,
|
||||
private val imageGetter: Html.ImageGetter,
|
||||
) : BaseViewModel() {
|
||||
|
||||
private val delegate = MangaDetailsDelegate(
|
||||
@@ -79,7 +82,19 @@ class DetailsViewModel(
|
||||
|
||||
val bookmarks = delegate.manga.flatMapLatest {
|
||||
if (it != null) bookmarksRepository.observeBookmarks(it) else flowOf(emptyList())
|
||||
}.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default)
|
||||
}.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, emptyList())
|
||||
|
||||
val description = delegate.manga
|
||||
.distinctUntilChangedBy { it?.description.orEmpty() }
|
||||
.transformLatest {
|
||||
val description = it?.description
|
||||
if (description.isNullOrEmpty()) {
|
||||
emit(null)
|
||||
} else {
|
||||
emit(description.parseAsHtml())
|
||||
emit(description.parseAsHtml(imageGetter = imageGetter))
|
||||
}
|
||||
}.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, null)
|
||||
|
||||
val onMangaRemoved = SingleLiveEvent<Manga>()
|
||||
val isScrobblingAvailable: Boolean
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.koitharu.kotatsu.utils.image
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Html
|
||||
import coil.ImageLoader
|
||||
import coil.executeBlocking
|
||||
import coil.request.ImageRequest
|
||||
|
||||
class CoilImageGetter(
|
||||
private val context: Context,
|
||||
private val coil: ImageLoader,
|
||||
) : Html.ImageGetter {
|
||||
|
||||
override fun getDrawable(source: String?): Drawable? {
|
||||
return coil.executeBlocking(
|
||||
ImageRequest.Builder(context)
|
||||
.data(source)
|
||||
.allowHardware(false)
|
||||
.build()
|
||||
).drawable?.apply {
|
||||
setBounds(0, 0, intrinsicHeight, intrinsicHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user