Misc fixes

This commit is contained in:
Koitharu
2020-03-02 19:03:15 +02:00
parent a3948c9046
commit 9c150512c1
16 changed files with 81 additions and 70 deletions

View File

@@ -37,6 +37,7 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), MangaDetailsV
RecyclerView.VERTICAL
)
)
recyclerView_chapters.setHasFixedSize(true)
recyclerView_chapters.adapter = adapter
}

View File

@@ -54,12 +54,14 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
super.onViewCreated(view, savedInstanceState)
drawer?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
adapter = MangaListAdapter(this)
recyclerView.setHasFixedSize(true)
initListMode(settings.listMode)
recyclerView.adapter = adapter
recyclerView.addOnScrollListener(PaginationScrollListener(4, this))
swipeRefreshLayout.setOnRefreshListener {
onRequestMoreItems(0)
}
recyclerView_filter.setHasFixedSize(true)
recyclerView_filter.addItemDecoration(ItemTypeDividerDecoration(view.context))
recyclerView_filter.addItemDecoration(SectionItemDecoration(false, this))
settings.subscribe(this)
@@ -128,10 +130,12 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
} else {
layout_holder.isVisible = false
}
recyclerView.callOnScrollListeners()
}
override fun onListAppended(list: List<Manga>) {
adapter?.appendData(list)
recyclerView.callOnScrollListeners()
}
@CallSuper

View File

@@ -0,0 +1,5 @@
package org.koitharu.kotatsu.ui.reader
enum class ReaderAction {
REPLACE, PREPEND, APPEND
}

View File

@@ -1,6 +1,7 @@
package org.koitharu.kotatsu.ui.reader
import android.net.Uri
import androidx.annotation.CallSuper
import androidx.annotation.LayoutRes
import org.koitharu.kotatsu.core.model.MangaChapter
import org.koitharu.kotatsu.core.model.MangaPage
@@ -51,25 +52,15 @@ abstract class BaseReaderFragment(@LayoutRes contentLayoutId: Int) : BaseFragmen
super.onDestroyView()
}
final override fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>) {
when {
chaptersMap.isEmpty() -> {
chaptersMap.push(chapterId to pages.size)
onPagesLoaded(chapterId, pages, Action.REPLACE)
}
shouldAppend(chapterId) -> {
chaptersMap.addLast(chapterId to pages.size)
onPagesLoaded(chapterId, pages, Action.APPEND)
}
shouldPrepend(chapterId) -> {
chaptersMap.addFirst(chapterId to pages.size)
onPagesLoaded(chapterId, pages, Action.PREPEND)
}
else -> {
@CallSuper
override fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>, action: ReaderAction) {
when (action) {
ReaderAction.REPLACE -> {
chaptersMap.clear()
chaptersMap.push(chapterId to pages.size)
onPagesLoaded(chapterId, pages, Action.REPLACE)
chaptersMap.add(chapterId to pages.size)
}
ReaderAction.PREPEND -> chaptersMap.addFirst(chapterId to pages.size)
ReaderAction.APPEND -> chaptersMap.addLast(chapterId to pages.size)
}
}
@@ -100,22 +91,6 @@ abstract class BaseReaderFragment(@LayoutRes contentLayoutId: Int) : BaseFragmen
return null
}
private fun shouldAppend(chapterId: Long): Boolean {
val chapters = lastState?.manga?.chapters ?: return false
val lastChapterId = chaptersMap.peekLast()?.first ?: return false
val indexOfCurrent = chapters.indexOfLast { x -> x.id == lastChapterId }
val indexOfNext = chapters.indexOfLast { x -> x.id == chapterId }
return indexOfCurrent != -1 && indexOfNext != -1 && indexOfCurrent + 1 == indexOfNext
}
private fun shouldPrepend(chapterId: Long): Boolean {
val chapters = lastState?.manga?.chapters ?: return false
val firstChapterId = chaptersMap.peekFirst()?.first ?: return false
val indexOfCurrent = chapters.indexOfFirst { x -> x.id == firstChapterId }
val indexOfPrev = chapters.indexOfFirst { x -> x.id == chapterId }
return indexOfCurrent != -1 && indexOfPrev != -1 && indexOfCurrent + 1 == indexOfPrev
}
protected fun getNextChapterId(): Long {
val lastChapterId = chaptersMap.peekLast()?.first ?: return 0
val chapters = lastState?.manga?.chapters ?: return 0
@@ -152,10 +127,4 @@ abstract class BaseReaderFragment(@LayoutRes contentLayoutId: Int) : BaseFragmen
total = chapter.second
)
}
protected abstract fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>, action: Action)
protected enum class Action {
REPLACE, PREPEND, APPEND
}
}

View File

@@ -75,7 +75,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
}
if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) {
presenter.loadChapter(state.manga, state.chapterId)
presenter.loadChapter(state.manga, state.chapterId, ReaderAction.REPLACE)
}
}
@@ -85,7 +85,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
}
}
override fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>) = Unit
override fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>, action: ReaderAction) = Unit
override fun onPause() {
reader?.let {
@@ -214,7 +214,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
chapterId = chapter.id,
page = 0
)
presenter.loadChapter(state.manga, chapter.id)
presenter.loadChapter(state.manga, chapter.id, ReaderAction.REPLACE)
}
override fun onPageSelected(page: MangaPage) {

View File

@@ -29,7 +29,7 @@ class ReaderPresenter : BasePresenter<ReaderView>() {
private var isInitialized = false
fun loadChapter(manga: Manga, chapterId: Long) {
fun loadChapter(manga: Manga, chapterId: Long, action: ReaderAction) {
presenterScope.launch {
viewState.onLoadingStateChanged(isLoading = true)
try {
@@ -60,7 +60,7 @@ class ReaderPresenter : BasePresenter<ReaderView>() {
isInitialized = true
}
withContext(Dispatchers.Main) {
viewState.onPagesLoaded(chapterId, pages)
viewState.onPagesLoaded(chapterId, pages, action)
}
}
} catch (e: Exception) {

View File

@@ -17,7 +17,7 @@ interface ReaderView : MvpView {
fun onChaptersLoader(chapters: List<MangaChapter>)
@AddToEndSingle
fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>)
fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>, action: ReaderAction)
@AddToEndSingle
fun onLoadingStateChanged(isLoading: Boolean)

View File

@@ -6,10 +6,8 @@ import kotlinx.android.synthetic.main.fragment_reader_standard.*
import moxy.ktx.moxyPresenter
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.MangaPage
import org.koitharu.kotatsu.ui.reader.BaseReaderFragment
import org.koitharu.kotatsu.ui.reader.OnBoundsScrollListener
import org.koitharu.kotatsu.ui.reader.PageLoader
import org.koitharu.kotatsu.ui.reader.ReaderPresenter
import org.koitharu.kotatsu.ui.reader.*
import org.koitharu.kotatsu.utils.ext.callOnPageChaneListeners
import org.koitharu.kotatsu.utils.ext.doOnPageChanged
class StandardReaderFragment : BaseReaderFragment(R.layout.fragment_reader_standard),
@@ -39,9 +37,10 @@ class StandardReaderFragment : BaseReaderFragment(R.layout.fragment_reader_stand
super.onDestroyView()
}
override fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>, action: Action) {
override fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>, action: ReaderAction) {
super.onPagesLoaded(chapterId, pages, action)
when (action) {
Action.REPLACE -> adapter?.let {
ReaderAction.REPLACE -> adapter?.let {
it.replaceData(pages)
lastState?.let { state ->
if (chapterId == state.chapterId) {
@@ -49,13 +48,14 @@ class StandardReaderFragment : BaseReaderFragment(R.layout.fragment_reader_stand
}
}
}
Action.PREPEND -> adapter?.run {
ReaderAction.PREPEND -> adapter?.run {
val pos = pager.currentItem
prependData(pages)
pager.setCurrentItem(pos + pages.size, false)
}
Action.APPEND -> adapter?.appendData(pages)
ReaderAction.APPEND -> adapter?.appendData(pages)
}
pager.callOnPageChaneListeners()
}
override fun onDestroy() {
@@ -66,14 +66,14 @@ class StandardReaderFragment : BaseReaderFragment(R.layout.fragment_reader_stand
override fun onScrolledToStart() {
val prevChapterId = getPrevChapterId()
if (prevChapterId != 0L) {
presenter.loadChapter(lastState?.manga ?: return, prevChapterId)
presenter.loadChapter(lastState?.manga ?: return, prevChapterId, ReaderAction.PREPEND)
}
}
override fun onScrolledToEnd() {
val nextChapterId = getNextChapterId()
if (nextChapterId != 0L) {
presenter.loadChapter(lastState?.manga ?: return, nextChapterId)
presenter.loadChapter(lastState?.manga ?: return, nextChapterId, ReaderAction.APPEND)
}
}

View File

@@ -6,10 +6,8 @@ import kotlinx.android.synthetic.main.fragment_reader_webtoon.*
import moxy.ktx.moxyPresenter
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.MangaPage
import org.koitharu.kotatsu.ui.reader.BaseReaderFragment
import org.koitharu.kotatsu.ui.reader.OnBoundsScrollListener
import org.koitharu.kotatsu.ui.reader.PageLoader
import org.koitharu.kotatsu.ui.reader.ReaderPresenter
import org.koitharu.kotatsu.ui.reader.*
import org.koitharu.kotatsu.utils.ext.callOnScrollListeners
import org.koitharu.kotatsu.utils.ext.doOnCurrentItemChanged
import org.koitharu.kotatsu.utils.ext.firstItem
@@ -29,14 +27,16 @@ class WebtoonReaderFragment : BaseReaderFragment(R.layout.fragment_reader_webtoo
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
adapter = WebtoonAdapter(loader)
recyclerView.setHasFixedSize(true)
recyclerView.adapter = adapter
recyclerView.addOnScrollListener(ListPaginationListener(2, this))
recyclerView.doOnCurrentItemChanged(::notifyPageChanged)
}
override fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>, action: Action) {
override fun onPagesLoaded(chapterId: Long, pages: List<MangaPage>, action: ReaderAction) {
super.onPagesLoaded(chapterId, pages, action)
when(action) {
Action.REPLACE -> {
ReaderAction.REPLACE -> {
adapter?.let {
it.replaceData(pages)
lastState?.let { state ->
@@ -46,22 +46,23 @@ class WebtoonReaderFragment : BaseReaderFragment(R.layout.fragment_reader_webtoo
}
}
}
Action.PREPEND -> adapter?.prependData(pages)
Action.APPEND -> adapter?.appendData(pages)
ReaderAction.PREPEND -> adapter?.prependData(pages)
ReaderAction.APPEND -> adapter?.appendData(pages)
}
recyclerView.callOnScrollListeners()
}
override fun onScrolledToStart() {
val prevChapterId = getPrevChapterId()
if (prevChapterId != 0L) {
presenter.loadChapter(lastState?.manga ?: return, prevChapterId)
presenter.loadChapter(lastState?.manga ?: return, prevChapterId, ReaderAction.PREPEND)
}
}
override fun onScrolledToEnd() {
val nextChapterId = getNextChapterId()
if (nextChapterId != 0L) {
presenter.loadChapter(lastState?.manga ?: return, nextChapterId)
presenter.loadChapter(lastState?.manga ?: return, nextChapterId, ReaderAction.APPEND)
}
}

View File

@@ -4,7 +4,6 @@ import android.app.SearchManager
import android.content.Context
import android.database.Cursor
import android.view.MenuItem
import android.view.inputmethod.EditorInfo
import androidx.appcompat.widget.SearchView
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.MangaSource
@@ -17,8 +16,6 @@ object SearchHelper {
val view = menuItem.actionView as? SearchView ?: return
val context = view.context
view.queryHint = context.getString(R.string.search_manga)
view.imeOptions = EditorInfo.IME_ACTION_SEARCH
view.inputType = EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE
view.suggestionsAdapter = MangaSuggestionsProvider.getSuggestionAdapter(context)
view.setOnQueryTextListener(QueryListener(context, source))
view.setOnSuggestionListener(SuggestionListener(view))

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.utils.ext
import android.app.Activity
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.util.Log
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
@@ -188,4 +189,34 @@ fun RecyclerView.doOnCurrentItemChanged(callback: (Int) -> Unit) {
}
}
})
}
fun RecyclerView.callOnScrollListeners() {
try {
val field = RecyclerView::class.java.getDeclaredField("mScrollListeners")
field.isAccessible = true
val listeners = field.get(this) as List<*>
for (x in listeners) {
(x as RecyclerView.OnScrollListener).onScrolled(this, 0, 0)
}
} catch (e: Throwable) {
Log.e(null, "RecyclerView.callOnScrollListeners() failed", e)
}
}
fun ViewPager2.callOnPageChaneListeners() {
try {
val field = ViewPager2::class.java.getDeclaredField("mExternalPageChangeCallbacks")
field.isAccessible = true
val compositeCallback = field.get(this)
val field2 = compositeCallback.javaClass.getDeclaredField("mCallbacks")
field2.isAccessible = true
val listeners = field2.get(compositeCallback) as List<*>
val position = currentItem
for (x in listeners) {
(x as ViewPager2.OnPageChangeCallback).onPageSelected(position)
}
} catch (e: Throwable) {
Log.e(null, "ViewPager2.callOnPageChaneListeners() failed", e)
}
}

View File

@@ -42,18 +42,21 @@
<TextView
android:id="@+id/textView_subtitle"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="6dp"
android:layout_marginBottom="6dp"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:textColorSecondary"
tools:text="@tools:sample/lorem[6]" />
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" />
<View
android:id="@+id/divider"