Various fixes
This commit is contained in:
@@ -6,10 +6,15 @@ import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.net.toFile
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.activity_details.*
|
||||
import kotlinx.coroutines.launch
|
||||
import moxy.MvpDelegate
|
||||
import moxy.ktx.moxyPresenter
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
@@ -18,6 +23,7 @@ import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.ui.common.BaseActivity
|
||||
import org.koitharu.kotatsu.ui.download.DownloadService
|
||||
import org.koitharu.kotatsu.utils.ShareHelper
|
||||
import org.koitharu.kotatsu.utils.ShortcutUtils
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
|
||||
class MangaDetailsActivity : BaseActivity(), MangaDetailsView {
|
||||
@@ -33,7 +39,10 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView {
|
||||
pager.adapter = MangaDetailsAdapter(resources, supportFragmentManager)
|
||||
tabs.setupWithViewPager(pager)
|
||||
intent?.getParcelableExtra<Manga>(EXTRA_MANGA)?.let {
|
||||
presenter.loadDetails(it)
|
||||
presenter.loadDetails(
|
||||
manga = it,
|
||||
force = savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true
|
||||
)
|
||||
} ?: finish()
|
||||
}
|
||||
|
||||
@@ -61,6 +70,8 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView {
|
||||
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
|
||||
menu.findItem(R.id.action_save).isEnabled =
|
||||
manga?.source != null && manga?.source != MangaSource.LOCAL
|
||||
menu.findItem(R.id.action_shortcut).isVisible = BuildConfig.DEBUG ||
|
||||
ShortcutManagerCompat.isRequestPinShortcutSupported(this)
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
@@ -81,6 +92,25 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView {
|
||||
}
|
||||
true
|
||||
}
|
||||
R.id.action_shortcut -> {
|
||||
manga?.let {
|
||||
lifecycleScope.launch {
|
||||
if (!ShortcutManagerCompat.requestPinShortcut(
|
||||
this@MangaDetailsActivity,
|
||||
ShortcutUtils.createShortcutInfo(this@MangaDetailsActivity, it),
|
||||
null
|
||||
)
|
||||
) {
|
||||
Snackbar.make(
|
||||
pager,
|
||||
R.string.operation_not_supported,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.koitharu.kotatsu.ui.details
|
||||
|
||||
import android.text.Spanned
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.core.view.isVisible
|
||||
import coil.api.load
|
||||
@@ -25,10 +26,14 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai
|
||||
|
||||
override fun onMangaUpdated(manga: Manga) {
|
||||
this.manga = manga
|
||||
imageView_cover.load(manga.largeCoverUrl ?: manga.coverUrl)
|
||||
imageView_cover.load(manga.largeCoverUrl ?: manga.coverUrl) {
|
||||
fallback(R.drawable.ic_placeholder)
|
||||
crossfade(true)
|
||||
}
|
||||
textView_title.text = manga.title
|
||||
textView_subtitle.text = manga.altTitle
|
||||
textView_description.text = manga.description?.parseAsHtml()
|
||||
textView_description.text = manga.description?.parseAsHtml()?.takeUnless(Spanned::isBlank)
|
||||
?: getString(R.string.no_description)
|
||||
if (manga.rating == Manga.NO_RATING) {
|
||||
ratingBar.isVisible = false
|
||||
} else {
|
||||
|
||||
@@ -17,6 +17,9 @@ class MangaGridHolder(parent: ViewGroup) : BaseViewHolder<Manga, MangaHistory?>(
|
||||
coverRequest?.dispose()
|
||||
textView_title.text = data.title
|
||||
coverRequest = imageView_cover.load(data.coverUrl) {
|
||||
placeholder(R.drawable.ic_placeholder)
|
||||
fallback(R.drawable.ic_placeholder)
|
||||
error(R.drawable.ic_placeholder)
|
||||
crossfade(true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ class MangaListDetailsHolder(parent: ViewGroup) : BaseViewHolder<Manga, MangaHis
|
||||
textView_title.text = data.title
|
||||
textView_subtitle.textAndVisible = data.altTitle
|
||||
coverRequest = imageView_cover.load(data.coverUrl) {
|
||||
placeholder(R.drawable.ic_placeholder)
|
||||
fallback(R.drawable.ic_placeholder)
|
||||
error(R.drawable.ic_placeholder)
|
||||
crossfade(true)
|
||||
}
|
||||
if(data.rating == Manga.NO_RATING) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.fragment_list.*
|
||||
import moxy.MvpDelegate
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
@@ -31,6 +32,7 @@ import org.koitharu.kotatsu.ui.common.list.decor.SpacingItemDecoration
|
||||
import org.koitharu.kotatsu.ui.details.MangaDetailsActivity
|
||||
import org.koitharu.kotatsu.ui.main.list.filter.FilterAdapter
|
||||
import org.koitharu.kotatsu.ui.main.list.filter.OnFilterChangedListener
|
||||
import org.koitharu.kotatsu.utils.UiUtils
|
||||
import org.koitharu.kotatsu.utils.ext.*
|
||||
|
||||
abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), MangaListView<E>,
|
||||
@@ -70,7 +72,7 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
if (savedInstanceState?.containsKey("MoxyDelegateBundle") != true) {
|
||||
if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) {
|
||||
onRequestMoreItems(0)
|
||||
}
|
||||
}
|
||||
@@ -210,7 +212,7 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
recyclerView.clearItemDecorations()
|
||||
adapter?.listMode = mode
|
||||
recyclerView.layoutManager = when (mode) {
|
||||
ListMode.GRID -> GridLayoutManager(ctx, 3)
|
||||
ListMode.GRID -> GridLayoutManager(ctx, UiUtils.resolveGridSpanCount(ctx))
|
||||
else -> LinearLayoutManager(ctx)
|
||||
}
|
||||
recyclerView.adapter = adapter
|
||||
|
||||
@@ -20,6 +20,9 @@ class MangaListHolder(parent: ViewGroup) :
|
||||
textView_title.text = data.title
|
||||
textView_subtitle.textAndVisible = data.tags.joinToString(", ") { it.title }
|
||||
coverRequest = imageView_cover.load(data.coverUrl) {
|
||||
placeholder(R.drawable.ic_placeholder)
|
||||
fallback(R.drawable.ic_placeholder)
|
||||
error(R.drawable.ic_placeholder)
|
||||
crossfade(true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.activity_reader.*
|
||||
import moxy.MvpDelegate
|
||||
import moxy.ktx.moxyPresenter
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
@@ -69,7 +70,10 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
|
||||
loader = PageLoader()
|
||||
adapter = PagesAdapter(loader)
|
||||
pager.adapter = adapter
|
||||
presenter.loadChapter(state)
|
||||
pager.offscreenPageLimit = 2
|
||||
if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) {
|
||||
presenter.loadChapter(state)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
||||
@@ -3,23 +3,30 @@ package org.koitharu.kotatsu.ui.reader.thumbnails
|
||||
import android.view.ViewGroup
|
||||
import coil.Coil
|
||||
import coil.api.get
|
||||
import coil.size.PixelSize
|
||||
import coil.size.Size
|
||||
import kotlinx.android.synthetic.main.item_page_thumb.*
|
||||
import kotlinx.coroutines.*
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.MangaPage
|
||||
import org.koitharu.kotatsu.domain.MangaProviderFactory
|
||||
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
|
||||
import org.koitharu.kotatsu.utils.DrawUtils
|
||||
import org.koitharu.kotatsu.utils.ext.resolveDp
|
||||
|
||||
class PageThumbnailHolder(parent: ViewGroup, private val scope: CoroutineScope) :
|
||||
BaseViewHolder<MangaPage, Unit>(parent, R.layout.item_page_thumb) {
|
||||
|
||||
private var job: Job? = null
|
||||
private val thumbSize: Size
|
||||
|
||||
init {
|
||||
val color = DrawUtils.invertColor(textView_number.currentTextColor)
|
||||
textView_number.setShadowLayer(parent.resources.resolveDp(26f), 0f, 0f, color)
|
||||
// FIXME
|
||||
// val color = DrawUtils.invertColor(textView_number.currentTextColor)
|
||||
// textView_number.setShadowLayer(parent.resources.resolveDp(26f), 0f, 0f, color)
|
||||
val width = itemView.context.resources.getDimensionPixelSize(R.dimen.preferred_grid_width)
|
||||
thumbSize = PixelSize(
|
||||
width = width,
|
||||
height = (width * 13f / 18f).toInt()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onBind(data: MangaPage, extra: Unit) {
|
||||
@@ -32,7 +39,7 @@ class PageThumbnailHolder(parent: ViewGroup, private val scope: CoroutineScope)
|
||||
MangaProviderFactory.create(data.source).getPageFullUrl(data)
|
||||
}
|
||||
val drawable = Coil.get(url) {
|
||||
|
||||
size(thumbSize)
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
imageView_thumb.setImageDrawable(drawable)
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import kotlinx.android.synthetic.main.sheet_pages.*
|
||||
@@ -13,6 +14,7 @@ import org.koitharu.kotatsu.core.model.MangaPage
|
||||
import org.koitharu.kotatsu.ui.common.BaseBottomSheet
|
||||
import org.koitharu.kotatsu.ui.common.list.OnRecyclerItemClickListener
|
||||
import org.koitharu.kotatsu.ui.common.list.decor.SpacingItemDecoration
|
||||
import org.koitharu.kotatsu.utils.UiUtils
|
||||
import org.koitharu.kotatsu.utils.ext.resolveDp
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
@@ -31,6 +33,7 @@ class PagesThumbnailsSheet : BaseBottomSheet(R.layout.sheet_pages),
|
||||
dismissAllowingStateLoss()
|
||||
return
|
||||
}
|
||||
(recyclerView.layoutManager as? GridLayoutManager)?.spanCount = UiUtils.resolveGridSpanCount(view.context)
|
||||
val title = arguments?.getString(ARG_TITLE)
|
||||
toolbar.title = title
|
||||
toolbar.setNavigationOnClickListener { dismiss() }
|
||||
@@ -56,8 +59,8 @@ class PagesThumbnailsSheet : BaseBottomSheet(R.layout.sheet_pages),
|
||||
}
|
||||
}
|
||||
})
|
||||
behavior.peekHeight = BottomSheetBehavior.PEEK_HEIGHT_AUTO
|
||||
behavior.isFitToContents = false
|
||||
// behavior.peekHeight = BottomSheetBehavior.PEEK_HEIGHT_AUTO
|
||||
// behavior.isFitToContents = false
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import android.graphics.Color
|
||||
import androidx.annotation.ColorInt
|
||||
|
||||
object DrawUtils {
|
||||
|
||||
@JvmStatic
|
||||
@ColorInt
|
||||
fun invertColor(@ColorInt color: Int): Int {
|
||||
val red = Color.red(color)
|
||||
val green = Color.green(color)
|
||||
val blue = Color.blue(color)
|
||||
val alpha = Color.alpha(color)
|
||||
return Color.argb(alpha, 255 - red, 255 - green, 255 - blue)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import android.content.Context
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import coil.Coil
|
||||
import coil.api.get
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.ui.details.MangaDetailsActivity
|
||||
|
||||
object ShortcutUtils {
|
||||
|
||||
@JvmStatic
|
||||
suspend fun createShortcutInfo(context: Context, manga: Manga): ShortcutInfoCompat {
|
||||
// val icon = withContext(Dispatchers.IO) {
|
||||
// Coil.loader().get(manga.coverUrl) {
|
||||
// context.getSystemService<ActivityManager>()?.let {
|
||||
// size(it.launcherLargeIconSize)
|
||||
// }
|
||||
// }.toBitmap()
|
||||
// }
|
||||
return ShortcutInfoCompat.Builder(context, manga.id.toString())
|
||||
.setShortLabel(manga.title)
|
||||
.setLongLabel(manga.title)
|
||||
.setIcon(IconCompat.createWithResource(context, R.drawable.ic_launcher_foreground))
|
||||
.setIntent(MangaDetailsActivity.newIntent(context, manga))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
28
app/src/main/java/org/koitharu/kotatsu/utils/UiUtils.kt
Normal file
28
app/src/main/java/org/koitharu/kotatsu/utils/UiUtils.kt
Normal file
@@ -0,0 +1,28 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import androidx.annotation.ColorInt
|
||||
import org.koitharu.kotatsu.R
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object UiUtils {
|
||||
|
||||
@JvmStatic
|
||||
@ColorInt
|
||||
fun invertColor(@ColorInt color: Int): Int {
|
||||
val red = Color.red(color)
|
||||
val green = Color.green(color)
|
||||
val blue = Color.blue(color)
|
||||
val alpha = Color.alpha(color)
|
||||
return Color.argb(alpha, 255 - red, 255 - green, 255 - blue)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun resolveGridSpanCount(context: Context): Int {
|
||||
val cellWidth = context.resources.getDimensionPixelSize(R.dimen.preferred_grid_width)
|
||||
val screenWidth = context.resources.displayMetrics.widthPixels.toDouble()
|
||||
val estimatedCount = (screenWidth / cellWidth).roundToInt()
|
||||
return estimatedCount.coerceAtLeast(2)
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ suspend inline fun <T, R> T.retryUntilSuccess(maxAttempts: Int, action: T.() ->
|
||||
}
|
||||
|
||||
fun Throwable.getDisplayMessage(resources: Resources) = when (this) {
|
||||
is UnsupportedOperationException -> resources.getString(R.string.operation_not_supported)
|
||||
is UnsupportedFileException -> resources.getString(R.string.text_file_not_supported)
|
||||
is IOException -> resources.getString(R.string.network_error)
|
||||
else -> if (BuildConfig.DEBUG) {
|
||||
|
||||
Reference in New Issue
Block a user