Update history

This commit is contained in:
Koitharu
2020-02-02 18:17:25 +02:00
parent a957021582
commit 64b38c561c
35 changed files with 359 additions and 137 deletions

View File

@@ -3,7 +3,6 @@ package org.koitharu.kotatsu.core.db
import androidx.room.*
import org.koitharu.kotatsu.core.db.entity.HistoryEntity
import org.koitharu.kotatsu.core.db.entity.HistoryWithManga
import org.koitharu.kotatsu.core.db.entity.MangaEntity
@Dao
@@ -25,19 +24,15 @@ abstract class HistoryDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract suspend fun insert(entity: HistoryEntity): Long
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract suspend fun insertManga(manga: MangaEntity): Long
@Query("UPDATE history SET page = :page, chapter_id = :chapterId, updated_at = :updatedAt WHERE manga_id = :mangaId")
abstract suspend fun update(mangaId: Long, page: Int, chapterId: Long, updatedAt: Long): Int
suspend fun update(entity: HistoryWithManga) = update(entity.manga.id, entity.history.page, entity.history.chapterId, entity.history.updatedAt)
suspend fun update(entity: HistoryEntity) = update(entity.mangaId, entity.page, entity.chapterId, entity.updatedAt)
@Transaction
open suspend fun upsert(entity: HistoryWithManga) {
open suspend fun upsert(entity: HistoryEntity) {
if (update(entity) == 0) {
insertManga(entity.manga)
insert(entity.history)
insert(entity)
}
}

View File

@@ -0,0 +1,40 @@
package org.koitharu.kotatsu.core.db
import androidx.room.*
import org.koitharu.kotatsu.core.db.entity.MangaEntity
import org.koitharu.kotatsu.core.db.entity.MangaTagsEntity
import org.koitharu.kotatsu.core.db.entity.TagEntity
@Dao
abstract class MangaDao {
@Query("SELECT * FROM manga")
abstract suspend fun getAllManga(): List<MangaEntity>
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract suspend fun insert(manga: MangaEntity): Long
@Update(onConflict = OnConflictStrategy.IGNORE)
abstract suspend fun update(manga: MangaEntity): Int
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract suspend fun insertTagRelation(tag: MangaTagsEntity): Long
@Query("DELETE FROM manga_tags WHERE manga_id = :mangaId")
abstract suspend fun clearTagRelation(mangaId: Long)
@Transaction
open suspend fun upsert(manga: MangaEntity, tags: Iterable<TagEntity>? = null) {
if (update(manga) <= 0) {
insert(manga)
if (tags != null) {
clearTagRelation(manga.id)
tags.map {
MangaTagsEntity(manga.id, it.id)
}.forEach {
insertTagRelation(it)
}
}
}
}
}

View File

@@ -4,12 +4,15 @@ import androidx.room.Database
import androidx.room.RoomDatabase
import org.koitharu.kotatsu.core.db.entity.HistoryEntity
import org.koitharu.kotatsu.core.db.entity.MangaEntity
import org.koitharu.kotatsu.core.db.entity.MangaTagsEntity
import org.koitharu.kotatsu.core.db.entity.TagEntity
@Database(entities = [MangaEntity::class, TagEntity::class, HistoryEntity::class], version = 1)
@Database(entities = [MangaEntity::class, TagEntity::class, HistoryEntity::class, MangaTagsEntity::class], version = 1)
abstract class MangaDatabase : RoomDatabase() {
abstract fun historyDao(): HistoryDao
abstract fun tagsDao(): TagsDao
abstract fun mangaDao(): MangaDao
}

View File

@@ -1,14 +1,26 @@
package org.koitharu.kotatsu.core.db
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.*
import org.koitharu.kotatsu.core.db.entity.TagEntity
@Dao
interface TagsDao {
@Transaction
@Query("SELECT * FROM tags")
fun getAllTags(): List<TagEntity>
suspend fun getAllTags(): List<TagEntity>
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(tag: TagEntity): Long
@Update(onConflict = OnConflictStrategy.IGNORE)
suspend fun update(tag: TagEntity): Int
@Transaction
suspend fun upsert(tags: Iterable<TagEntity>) {
tags.forEach { tag ->
if (update(tag) <= 0) {
insert(tag)
}
}
}
}

View File

@@ -1,6 +1,7 @@
package org.koitharu.kotatsu.core.db.entity
import androidx.room.Embedded
import androidx.room.Junction
import androidx.room.Relation
data class HistoryWithManga(
@@ -9,5 +10,11 @@ data class HistoryWithManga(
parentColumn = "manga_id",
entityColumn = "manga_id"
)
val manga: MangaEntity
val manga: MangaEntity,
@Relation(
parentColumn = "manga_id",
entityColumn = "tag_id",
associateBy = Junction(MangaTagsEntity::class)
)
val tags: List<TagEntity>
)

View File

@@ -6,6 +6,7 @@ import androidx.room.PrimaryKey
import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.core.model.MangaSource
import org.koitharu.kotatsu.core.model.MangaState
import org.koitharu.kotatsu.core.model.MangaTag
@Entity(tableName = "manga")
data class MangaEntity(
@@ -22,7 +23,7 @@ data class MangaEntity(
@ColumnInfo(name = "source") val source: String
) {
fun toManga() = Manga(
fun toManga(tags: Set<MangaTag> = emptySet()) = Manga(
id = this.id,
title = this.title,
localizedTitle = this.localizedTitle,
@@ -32,8 +33,8 @@ data class MangaEntity(
url = this.url,
coverUrl = this.coverUrl,
largeCoverUrl = this.largeCoverUrl,
source = MangaSource.valueOf(this.source)
// tags = this.tags.map(TagEntity::toMangaTag).toSet()
source = MangaSource.valueOf(this.source),
tags = tags
)
companion object {

View File

@@ -9,8 +9,8 @@ import org.koitharu.kotatsu.core.parser.site.SelfMangaRepository
@Suppress("SpellCheckingInspection")
@Parcelize
enum class MangaSource(val title: String, val cls: Class<out MangaRepository>): Parcelable {
READMANGA_RU("ReadManga", ReadmangaRepository::class.java),
MINTMANGA("MintManga", MintMangaRepository::class.java),
SELFMANGA("SelfManga", SelfMangaRepository::class.java)
enum class MangaSource(val title: String, val locale: String, val cls: Class<out MangaRepository>): Parcelable {
READMANGA_RU("ReadManga", "ru", ReadmangaRepository::class.java),
MINTMANGA("MintManga", "ru", MintMangaRepository::class.java),
SELFMANGA("SelfManga", "ru", SelfMangaRepository::class.java)
}

View File

@@ -1,53 +0,0 @@
package org.koitharu.kotatsu.domain
import org.koin.core.KoinComponent
import org.koin.core.inject
import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.core.db.entity.HistoryEntity
import org.koitharu.kotatsu.core.db.entity.HistoryWithManga
import org.koitharu.kotatsu.core.db.entity.MangaEntity
import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.core.model.MangaHistory
import java.util.*
class HistoryRepository : KoinComponent {
private val db: MangaDatabase by inject()
suspend fun getList(offset: Int) : List<Manga> {
val entities = db.historyDao().getAll(offset, 20, "updated_by")
return entities.map { it.manga.toManga() }
}
suspend fun addOrUpdate(manga: Manga, chapterId: Long, page: Int) {
val dao = db.historyDao()
val entity = HistoryEntity(
mangaId = manga.id,
createdAt = System.currentTimeMillis(),
updatedAt = System.currentTimeMillis(),
chapterId = chapterId,
page = page
)
dao.upsert(
HistoryWithManga(
history = entity,
manga = MangaEntity.from(manga)
)
)
}
suspend fun getOne(manga: Manga): MangaHistory? {
return db.historyDao().getOneOrNull(manga.id)?.let {
MangaHistory(
createdAt = Date(it.createdAt),
updatedAt = Date(it.updatedAt),
chapterId = it.chapterId,
page = it.page
)
}
}
suspend fun clear() {
db.historyDao().clear()
}
}

View File

@@ -1,4 +1,4 @@
package org.koitharu.kotatsu.domain
package org.koitharu.kotatsu.domain.history
enum class ChapterExtra {

View File

@@ -0,0 +1,74 @@
package org.koitharu.kotatsu.domain.history
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.koin.core.KoinComponent
import org.koin.core.inject
import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.core.db.entity.HistoryEntity
import org.koitharu.kotatsu.core.db.entity.MangaEntity
import org.koitharu.kotatsu.core.db.entity.TagEntity
import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.core.model.MangaHistory
import java.util.*
class HistoryRepository : KoinComponent {
private val db: MangaDatabase by inject()
suspend fun getList(offset: Int): List<Manga> {
val entities = db.historyDao().getAll(offset, 20, "updated_at")
return entities.map { it.manga.toManga(it.tags.map(TagEntity::toMangaTag).toSet()) }
}
suspend fun addOrUpdate(manga: Manga, chapterId: Long, page: Int) {
val tags = manga.tags.map(TagEntity.Companion::fromMangaTag)
db.tagsDao().upsert(tags)
db.mangaDao().upsert(MangaEntity.from(manga), tags)
db.historyDao().upsert(
HistoryEntity(
mangaId = manga.id,
createdAt = System.currentTimeMillis(),
updatedAt = System.currentTimeMillis(),
chapterId = chapterId,
page = page
)
)
notifyHistoryChanged()
}
suspend fun getOne(manga: Manga): MangaHistory? {
return db.historyDao().getOneOrNull(manga.id)?.let {
MangaHistory(
createdAt = Date(it.createdAt),
updatedAt = Date(it.updatedAt),
chapterId = it.chapterId,
page = it.page
)
}
}
suspend fun clear() {
db.historyDao().clear()
notifyHistoryChanged()
}
companion object {
private val listeners = HashSet<OnHistoryChangeListener>()
fun subscribe(listener: OnHistoryChangeListener) {
listeners += listener
}
fun unsubscribe(listener: OnHistoryChangeListener) {
listeners += listener
}
private suspend fun notifyHistoryChanged() {
withContext(Dispatchers.Main) {
listeners.forEach { x -> x.onHistoryChanged() }
}
}
}
}

View File

@@ -0,0 +1,6 @@
package org.koitharu.kotatsu.domain.history
interface OnHistoryChangeListener {
fun onHistoryChanged()
}

View File

@@ -0,0 +1,33 @@
package org.koitharu.kotatsu.ui.common
import android.os.Bundle
import android.view.View
abstract class BaseFullscreenActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) hideSystemUI()
}
private fun hideSystemUI() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
}
protected fun showSystemUI() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
}
abstract fun onFullscreenModeChanged(isFullscreen: Boolean)
}

View File

@@ -9,7 +9,7 @@ abstract class BaseRecyclerAdapter<T, E>(private val onItemClickListener: OnRecy
RecyclerView.Adapter<BaseViewHolder<T, E>>(),
KoinComponent {
private val dataSet = ArrayList<T>()
protected val dataSet = ArrayList<T>()
init {
@Suppress("LeakingThis")
@@ -34,21 +34,25 @@ abstract class BaseRecyclerAdapter<T, E>(private val onItemClickListener: OnRecy
val updater = AdapterUpdater(dataSet, newData, this::onGetItemId)
dataSet.replaceWith(newData)
updater(this)
onDataSetChanged()
}
fun appendData(newData: List<T>) {
val pos = dataSet.size
dataSet.addAll(newData)
notifyItemRangeInserted(pos, newData.size)
onDataSetChanged()
}
fun appendItem(newItem: T) {
dataSet.add(newItem)
notifyItemInserted(dataSet.lastIndex)
onDataSetChanged()
}
fun removeItem(item: T) {
removeItemAt(dataSet.indexOf(item))
onDataSetChanged()
}
fun removeItemAt(position: Int) {
@@ -56,11 +60,13 @@ abstract class BaseRecyclerAdapter<T, E>(private val onItemClickListener: OnRecy
dataSet.removeAt(position)
notifyItemRemoved(position)
}
onDataSetChanged()
}
fun clearData() {
dataSet.clear()
notifyDataSetChanged()
onDataSetChanged()
}
final override fun getItemCount() = dataSet.size
@@ -70,6 +76,8 @@ abstract class BaseRecyclerAdapter<T, E>(private val onItemClickListener: OnRecy
.also(this::onViewHolderCreated)
}
protected open fun onDataSetChanged() = Unit
protected abstract fun getExtra(item: T, position: Int): E
protected open fun onViewHolderCreated(holder: BaseViewHolder<T, E>) = Unit

View File

@@ -4,7 +4,7 @@ import android.view.ViewGroup
import kotlinx.android.synthetic.main.item_chapter.*
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.MangaChapter
import org.koitharu.kotatsu.domain.ChapterExtra
import org.koitharu.kotatsu.domain.history.ChapterExtra
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
import org.koitharu.kotatsu.utils.ext.getThemeColor

View File

@@ -3,19 +3,21 @@ package org.koitharu.kotatsu.ui.details
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.koitharu.kotatsu.core.model.MangaChapter
import org.koitharu.kotatsu.domain.ChapterExtra
import org.koitharu.kotatsu.domain.history.ChapterExtra
import org.koitharu.kotatsu.ui.common.list.BaseRecyclerAdapter
import org.koitharu.kotatsu.ui.common.list.OnRecyclerItemClickListener
class ChaptersAdapter(onItemClickListener: OnRecyclerItemClickListener<MangaChapter>) :
BaseRecyclerAdapter<MangaChapter, ChapterExtra>(onItemClickListener) {
var currentChapterPosition = RecyclerView.NO_POSITION
var currentChapterId: Long? = null
set(value) {
field = value
notifyDataSetChanged()
updateCurrentPosition()
}
private var currentChapterPosition = RecyclerView.NO_POSITION
override fun onCreateViewHolder(parent: ViewGroup) = ChapterHolder(parent)
override fun onGetItemId(item: MangaChapter) = item.id
@@ -27,4 +29,19 @@ class ChaptersAdapter(onItemClickListener: OnRecyclerItemClickListener<MangaChap
currentChapterPosition > position -> ChapterExtra.READ
else -> ChapterExtra.UNREAD
}
override fun onDataSetChanged() {
super.onDataSetChanged()
updateCurrentPosition()
}
private fun updateCurrentPosition() {
val pos = currentChapterId?.let {
dataSet.indexOfFirst { x -> x.id == it }
} ?: RecyclerView.NO_POSITION
if (pos != currentChapterPosition) {
currentChapterPosition = pos
notifyDataSetChanged()
}
}
}

View File

@@ -51,9 +51,7 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), MangaDetailsV
}
override fun onHistoryChanged(history: MangaHistory?) {
adapter.currentChapterPosition = history?.let {
manga?.chapters?.indexOfFirst { x -> x.id == it.chapterId }
} ?: RecyclerView.NO_POSITION
adapter.currentChapterId = history?.chapterId
}
override fun onItemClick(item: MangaChapter, position: Int, view: View) {

View File

@@ -24,17 +24,9 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView {
tabs.setupWithViewPager(pager)
intent?.getParcelableExtra<Manga>(EXTRA_MANGA)?.let {
presenter.loadDetails(it)
presenter.loadHistory(it)
} ?: finish()
}
override fun onResume() {
super.onResume()
intent?.getParcelableExtra<Manga>(EXTRA_MANGA)?.let {
presenter.loadHistory(it)
}
}
override fun onMangaUpdated(manga: Manga) {
title = manga.title
}

View File

@@ -6,26 +6,29 @@ import kotlinx.coroutines.withContext
import moxy.InjectViewState
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.domain.HistoryRepository
import org.koitharu.kotatsu.domain.MangaProviderFactory
import org.koitharu.kotatsu.domain.history.HistoryRepository
import org.koitharu.kotatsu.domain.history.OnHistoryChangeListener
import org.koitharu.kotatsu.ui.common.BasePresenter
@InjectViewState
class MangaDetailsPresenter : BasePresenter<MangaDetailsView>() {
class MangaDetailsPresenter : BasePresenter<MangaDetailsView>(), OnHistoryChangeListener {
private lateinit var historyRepository: HistoryRepository
private var isLoaded = false
private var manga: Manga? = null
override fun onFirstViewAttach() {
historyRepository = HistoryRepository()
super.onFirstViewAttach()
HistoryRepository.subscribe(this)
}
fun loadDetails(manga: Manga, force: Boolean = false) {
if (!force && isLoaded) {
if (!force && this.manga == manga) {
return
}
loadHistory(manga)
viewState.onMangaUpdated(manga)
launch {
try {
@@ -34,7 +37,7 @@ class MangaDetailsPresenter : BasePresenter<MangaDetailsView>() {
MangaProviderFactory.create(manga.source).getDetails(manga)
}
viewState.onMangaUpdated(data)
isLoaded = true
this@MangaDetailsPresenter.manga = data
} catch (e: Exception) {
if (BuildConfig.DEBUG) {
e.printStackTrace()
@@ -46,7 +49,7 @@ class MangaDetailsPresenter : BasePresenter<MangaDetailsView>() {
}
}
fun loadHistory(manga: Manga) {
private fun loadHistory(manga: Manga) {
launch {
try {
val history = withContext(Dispatchers.IO) {
@@ -60,4 +63,13 @@ class MangaDetailsPresenter : BasePresenter<MangaDetailsView>() {
}
}
}
override fun onHistoryChanged() {
loadHistory(manga ?: return)
}
override fun onDestroy() {
HistoryRepository.unsubscribe(this)
super.onDestroy()
}
}

View File

@@ -31,6 +31,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
if (!supportFragmentManager.isStateSaved) {
navigationView.setCheckedItem(R.id.nav_history)
setPrimaryFragment(HistoryListFragment.newInstance())
}
}

View File

@@ -79,7 +79,12 @@ abstract class MangaListFragment <E> : BaseFragment(R.layout.fragment_list), Man
override fun onListChanged(list: List<Manga>) {
adapter.replaceData(list)
layout_holder.isVisible = list.isEmpty()
if (list.isEmpty()) {
setUpEmptyListHolder()
layout_holder.isVisible = true
} else {
layout_holder.isVisible = false
}
}
override fun onListAppended(list: List<Manga>) {
@@ -89,6 +94,10 @@ abstract class MangaListFragment <E> : BaseFragment(R.layout.fragment_list), Man
override fun onError(e: Exception) {
if (recyclerView.hasItems) {
Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show()
} else {
textView_holder.text = e.getDisplayMessage(resources)
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, R.drawable.ic_error_large, 0, 0)
layout_holder.isVisible = true
}
}
@@ -108,6 +117,11 @@ abstract class MangaListFragment <E> : BaseFragment(R.layout.fragment_list), Man
}
}
protected open fun setUpEmptyListHolder() {
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null)
textView_holder.setText(R.string.nothing_found)
}
private fun initListMode(mode: ListMode) {
val ctx = context ?: return
val position = recyclerView.firstItem

View File

@@ -1,10 +1,8 @@
package org.koitharu.kotatsu.ui.main.list.history
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import kotlinx.android.synthetic.main.fragment_list.*
import moxy.ktx.moxyPresenter
import org.koitharu.kotatsu.R
@@ -16,11 +14,6 @@ class HistoryListFragment : MangaListFragment<MangaHistory>(), MangaListView<Man
private val presenter by moxyPresenter(factory = ::HistoryListPresenter)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
textView_holder.setText(R.string.history_is_empty)
}
override fun onRequestMoreItems(offset: Int) {
presenter.loadList(offset)
}
@@ -42,6 +35,11 @@ class HistoryListFragment : MangaListFragment<MangaHistory>(), MangaListView<Man
return getString(R.string.history)
}
override fun setUpEmptyListHolder() {
textView_holder.setText(R.string.history_is_empty)
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0)
}
companion object {
fun newInstance() = HistoryListFragment()

View File

@@ -6,7 +6,7 @@ import kotlinx.coroutines.withContext
import moxy.InjectViewState
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.core.model.MangaHistory
import org.koitharu.kotatsu.domain.HistoryRepository
import org.koitharu.kotatsu.domain.history.HistoryRepository
import org.koitharu.kotatsu.ui.common.BasePresenter
import org.koitharu.kotatsu.ui.main.list.MangaListView

View File

@@ -1,10 +1,6 @@
package org.koitharu.kotatsu.ui.main.list.remote
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.fragment_list.*
import moxy.ktx.moxyPresenter
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.MangaSource
import org.koitharu.kotatsu.ui.main.list.MangaListFragment
import org.koitharu.kotatsu.utils.ext.withArgs
@@ -15,11 +11,6 @@ class RemoteListFragment : MangaListFragment<Unit>() {
private val source by arg<MangaSource>(ARG_SOURCE)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
textView_holder.setText(R.string.nothing_found)
}
override fun onRequestMoreItems(offset: Int) {
presenter.loadList(source, offset)
}

View File

@@ -6,17 +6,19 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import kotlinx.android.synthetic.main.activity_reader.*
import moxy.ktx.moxyPresenter
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.core.model.MangaHistory
import org.koitharu.kotatsu.core.model.MangaPage
import org.koitharu.kotatsu.ui.common.BaseActivity
import org.koitharu.kotatsu.ui.common.BaseFullscreenActivity
import org.koitharu.kotatsu.utils.ext.showDialog
class ReaderActivity : BaseActivity(), ReaderView {
class ReaderActivity : BaseFullscreenActivity(), ReaderView {
private val presenter by moxyPresenter { ReaderPresenter() }
@@ -29,7 +31,7 @@ class ReaderActivity : BaseActivity(), ReaderView {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_reader)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
bottomBar.inflateMenu(R.menu.opt_reader_bottom)
toolbar_bottom.inflateMenu(R.menu.opt_reader_bottom)
state = savedInstanceState?.getParcelable(EXTRA_STATE)
?: intent.getParcelableExtra<ReaderState>(EXTRA_STATE)
@@ -45,6 +47,11 @@ class ReaderActivity : BaseActivity(), ReaderView {
getString(R.string.chapter_d_of_d, state.chapter?.number ?: 0, size)
}
appbar_bottom.setOnApplyWindowInsetsListener { view, insets ->
view.updatePadding(bottom = insets.systemWindowInsetBottom)
insets
}
loader = PageLoader(this)
adapter = PagesAdapter(loader)
pager.adapter = adapter
@@ -92,6 +99,11 @@ class ReaderActivity : BaseActivity(), ReaderView {
}
}
override fun onFullscreenModeChanged(isFullscreen: Boolean) {
appbar_top.isGone = isFullscreen
appbar_bottom.isGone = isFullscreen
}
companion object {
private const val EXTRA_STATE = "state"

View File

@@ -5,7 +5,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import moxy.InjectViewState
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.domain.HistoryRepository
import org.koitharu.kotatsu.domain.history.HistoryRepository
import org.koitharu.kotatsu.domain.MangaProviderFactory
import org.koitharu.kotatsu.ui.common.BasePresenter