Misc fixes
This commit is contained in:
@@ -37,6 +37,7 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), MangaDetailsV
|
||||
RecyclerView.VERTICAL
|
||||
)
|
||||
)
|
||||
recyclerView_chapters.setHasFixedSize(true)
|
||||
recyclerView_chapters.adapter = adapter
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.koitharu.kotatsu.ui.reader
|
||||
|
||||
enum class ReaderAction {
|
||||
REPLACE, PREPEND, APPEND
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user