Fix MangaDetailsPresenter sharing
This commit is contained in:
@@ -16,7 +16,7 @@ android {
|
|||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode gitCommits
|
versionCode gitCommits
|
||||||
versionName '0.5-b1'
|
versionName '0.5-b2'
|
||||||
|
|
||||||
kapt {
|
kapt {
|
||||||
arguments {
|
arguments {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class BrowserActivity : BaseActivity(), BrowserCallback {
|
|||||||
webView.webViewClient = BrowserClient(this)
|
webView.webViewClient = BrowserClient(this)
|
||||||
val url = intent?.dataString
|
val url = intent?.dataString
|
||||||
if (url.isNullOrEmpty()) {
|
if (url.isNullOrEmpty()) {
|
||||||
finish()
|
finishAfterTransition()
|
||||||
} else {
|
} else {
|
||||||
webView.loadUrl(url)
|
webView.loadUrl(url)
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ class BrowserActivity : BaseActivity(), BrowserCallback {
|
|||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
|
||||||
android.R.id.home -> {
|
android.R.id.home -> {
|
||||||
webView.stopLoading()
|
webView.stopLoading()
|
||||||
finish()
|
finishAfterTransition()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.action_browser -> {
|
R.id.action_browser -> {
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package org.koitharu.kotatsu.ui.common
|
package org.koitharu.kotatsu.ui.common
|
||||||
|
|
||||||
import android.view.KeyEvent
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import moxy.MvpAppCompatActivity
|
import moxy.MvpAppCompatActivity
|
||||||
import org.koin.core.KoinComponent
|
import org.koin.core.KoinComponent
|
||||||
import org.koitharu.kotatsu.BuildConfig
|
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
|
|
||||||
abstract class BaseActivity : MvpAppCompatActivity(), KoinComponent {
|
abstract class BaseActivity : MvpAppCompatActivity(), KoinComponent {
|
||||||
@@ -29,13 +27,4 @@ abstract class BaseActivity : MvpAppCompatActivity(), KoinComponent {
|
|||||||
onBackPressed()
|
onBackPressed()
|
||||||
true
|
true
|
||||||
} else super.onOptionsItemSelected(item)
|
} else super.onOptionsItemSelected(item)
|
||||||
|
|
||||||
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
|
||||||
//TODO remove. Just for testing
|
|
||||||
if (BuildConfig.DEBUG && keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
|
|
||||||
recreate()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return super.onKeyDown(keyCode, event)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.koitharu.kotatsu.ui.common
|
||||||
|
|
||||||
|
import android.util.ArrayMap
|
||||||
|
import moxy.MvpPresenter
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
abstract class SharedPresenterHolder<T : MvpPresenter<*>> {
|
||||||
|
|
||||||
|
private val cache = ArrayMap<Int, WeakReference<T>>(3)
|
||||||
|
|
||||||
|
fun getInstance(key: Int): T {
|
||||||
|
var instance = cache[key]?.get()
|
||||||
|
if (instance == null) {
|
||||||
|
instance = onCreatePresenter(key)
|
||||||
|
cache[key] = WeakReference(instance)
|
||||||
|
}
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear(key: Int) {
|
||||||
|
cache.remove(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun onCreatePresenter(key: Int): T
|
||||||
|
}
|
||||||
@@ -25,7 +25,9 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), MangaDetailsV
|
|||||||
OnRecyclerItemClickListener<MangaChapter>, ActionMode.Callback {
|
OnRecyclerItemClickListener<MangaChapter>, ActionMode.Callback {
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance)
|
private val presenter by moxyPresenter {
|
||||||
|
MangaDetailsPresenter.getInstance(activity.hashCode())
|
||||||
|
}
|
||||||
|
|
||||||
private var manga: Manga? = null
|
private var manga: Manga? = null
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ import org.koitharu.kotatsu.utils.ext.getThemeColor
|
|||||||
class MangaDetailsActivity : BaseActivity(), MangaDetailsView,
|
class MangaDetailsActivity : BaseActivity(), MangaDetailsView,
|
||||||
TabLayoutMediator.TabConfigurationStrategy {
|
TabLayoutMediator.TabConfigurationStrategy {
|
||||||
|
|
||||||
private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance)
|
private val presenter by moxyPresenter {
|
||||||
|
MangaDetailsPresenter.getInstance(hashCode())
|
||||||
|
}
|
||||||
|
|
||||||
private var manga: Manga? = null
|
private var manga: Manga? = null
|
||||||
|
|
||||||
@@ -52,7 +54,7 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView,
|
|||||||
presenter.loadDetails(it, true)
|
presenter.loadDetails(it, true)
|
||||||
} ?: intent?.getLongExtra(EXTRA_MANGA_ID, 0)?.takeUnless { it == 0L }?.let {
|
} ?: intent?.getLongExtra(EXTRA_MANGA_ID, 0)?.takeUnless { it == 0L }?.let {
|
||||||
presenter.findMangaById(it)
|
presenter.findMangaById(it)
|
||||||
} ?: finish()
|
} ?: finishAfterTransition()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,13 +75,13 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView,
|
|||||||
this, getString(R.string._s_deleted_from_local_storage, manga.title),
|
this, getString(R.string._s_deleted_from_local_storage, manga.title),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
finish()
|
finishAfterTransition()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
override fun onError(e: Throwable) {
|
||||||
if (manga == null) {
|
if (manga == null) {
|
||||||
Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show()
|
Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show()
|
||||||
finish()
|
finishAfterTransition()
|
||||||
} else {
|
} else {
|
||||||
Snackbar.make(pager, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG).show()
|
Snackbar.make(pager, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai
|
|||||||
View.OnLongClickListener {
|
View.OnLongClickListener {
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance)
|
private val presenter by moxyPresenter {
|
||||||
|
MangaDetailsPresenter.getInstance(activity.hashCode())
|
||||||
|
}
|
||||||
|
|
||||||
private var manga: Manga? = null
|
private var manga: Manga? = null
|
||||||
private var history: MangaHistory? = null
|
private var history: MangaHistory? = null
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.koitharu.kotatsu.ui.details
|
package org.koitharu.kotatsu.ui.details
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
@@ -21,13 +22,13 @@ import org.koitharu.kotatsu.domain.history.HistoryRepository
|
|||||||
import org.koitharu.kotatsu.domain.history.OnHistoryChangeListener
|
import org.koitharu.kotatsu.domain.history.OnHistoryChangeListener
|
||||||
import org.koitharu.kotatsu.domain.tracking.TrackingRepository
|
import org.koitharu.kotatsu.domain.tracking.TrackingRepository
|
||||||
import org.koitharu.kotatsu.ui.common.BasePresenter
|
import org.koitharu.kotatsu.ui.common.BasePresenter
|
||||||
|
import org.koitharu.kotatsu.ui.common.SharedPresenterHolder
|
||||||
import org.koitharu.kotatsu.utils.ext.safe
|
import org.koitharu.kotatsu.utils.ext.safe
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
@InjectViewState
|
@InjectViewState
|
||||||
class MangaDetailsPresenter private constructor() : BasePresenter<MangaDetailsView>(),
|
class MangaDetailsPresenter private constructor(private val key: Int) :
|
||||||
OnHistoryChangeListener,
|
BasePresenter<MangaDetailsView>(), OnHistoryChangeListener, OnFavouritesChangeListener {
|
||||||
OnFavouritesChangeListener {
|
|
||||||
|
|
||||||
private lateinit var historyRepository: HistoryRepository
|
private lateinit var historyRepository: HistoryRepository
|
||||||
private lateinit var favouritesRepository: FavouritesRepository
|
private lateinit var favouritesRepository: FavouritesRepository
|
||||||
@@ -55,7 +56,7 @@ class MangaDetailsPresenter private constructor() : BasePresenter<MangaDetailsVi
|
|||||||
} ?: throw MangaNotFoundException("Cannot find manga by id")
|
} ?: throw MangaNotFoundException("Cannot find manga by id")
|
||||||
viewState.onMangaUpdated(manga)
|
viewState.onMangaUpdated(manga)
|
||||||
loadDetails(manga, true)
|
loadDetails(manga, true)
|
||||||
} catch (_: CancellationException){
|
} catch (_: CancellationException) {
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@@ -83,7 +84,7 @@ class MangaDetailsPresenter private constructor() : BasePresenter<MangaDetailsVi
|
|||||||
viewState.onMangaUpdated(data)
|
viewState.onMangaUpdated(data)
|
||||||
this@MangaDetailsPresenter.manga = data
|
this@MangaDetailsPresenter.manga = data
|
||||||
viewState.onNewChaptersChanged(trackingRepository.getNewChaptersCount(manga.id))
|
viewState.onNewChaptersChanged(trackingRepository.getNewChaptersCount(manga.id))
|
||||||
} catch (_: CancellationException){
|
} catch (_: CancellationException) {
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@@ -198,18 +199,12 @@ class MangaDetailsPresenter private constructor() : BasePresenter<MangaDetailsVi
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
HistoryRepository.unsubscribe(this)
|
HistoryRepository.unsubscribe(this)
|
||||||
FavouritesRepository.unsubscribe(this)
|
FavouritesRepository.unsubscribe(this)
|
||||||
instance = null
|
clear(key)
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object Holder : SharedPresenterHolder<MangaDetailsPresenter>() {
|
||||||
|
|
||||||
private var instance: MangaDetailsPresenter? = null
|
override fun onCreatePresenter(key: Int) = MangaDetailsPresenter(key)
|
||||||
|
|
||||||
fun getInstance(): MangaDetailsPresenter = instance ?: synchronized(this) {
|
|
||||||
MangaDetailsPresenter().also {
|
|
||||||
instance = it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,9 @@ import org.koitharu.kotatsu.ui.list.MangaListFragment
|
|||||||
|
|
||||||
class RelatedMangaFragment : MangaListFragment<Unit>(), MangaDetailsView {
|
class RelatedMangaFragment : MangaListFragment<Unit>(), MangaDetailsView {
|
||||||
|
|
||||||
private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance)
|
private val presenter by moxyPresenter {
|
||||||
|
MangaDetailsPresenter.getInstance(activity.hashCode())
|
||||||
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ class LocalListPresenter : BasePresenter<MangaListView<File>>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun loadList(offset: Int) {
|
fun loadList(offset: Int) {
|
||||||
if (offset != 0) {
|
|
||||||
viewState.onListAppended(emptyList())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
|
if (offset != 0) {
|
||||||
|
viewState.onListAppended(emptyList())
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
viewState.onLoadingStateChanged(true)
|
viewState.onLoadingStateChanged(true)
|
||||||
try {
|
try {
|
||||||
val list = withContext(Dispatchers.IO) {
|
val list = withContext(Dispatchers.IO) {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
|
|||||||
?: intent.getParcelableExtra<ReaderState>(EXTRA_STATE)
|
?: intent.getParcelableExtra<ReaderState>(EXTRA_STATE)
|
||||||
?: let {
|
?: let {
|
||||||
Toast.makeText(this, R.string.error_occurred, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.error_occurred, Toast.LENGTH_SHORT).show()
|
||||||
finish()
|
finishAfterTransition()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class SearchActivity : BaseActivity(), SearchView.OnQueryTextListener {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_search)
|
setContentView(R.layout.activity_search)
|
||||||
source = intent.getParcelableExtra(EXTRA_SOURCE) ?: run {
|
source = intent.getParcelableExtra(EXTRA_SOURCE) ?: run {
|
||||||
finish()
|
finishAfterTransition()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val query = intent.getStringExtra(EXTRA_QUERY)
|
val query = intent.getStringExtra(EXTRA_QUERY)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class GlobalSearchActivity : BaseActivity() {
|
|||||||
val query = intent.getStringExtra(EXTRA_QUERY)
|
val query = intent.getStringExtra(EXTRA_QUERY)
|
||||||
|
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
finish()
|
finishAfterTransition()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class ShelfConfigActivity : BaseActivity(), FavouriteCategoriesView,
|
|||||||
AppWidgetManager.INVALID_APPWIDGET_ID
|
AppWidgetManager.INVALID_APPWIDGET_ID
|
||||||
) ?: AppWidgetManager.INVALID_APPWIDGET_ID
|
) ?: AppWidgetManager.INVALID_APPWIDGET_ID
|
||||||
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
|
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
|
||||||
finish()
|
finishAfterTransition()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
config = AppWidgetConfig.getInstance(this, appWidgetId)
|
config = AppWidgetConfig.getInstance(this, appWidgetId)
|
||||||
|
|||||||
Reference in New Issue
Block a user