diff --git a/.idea/dictionaries/admin.xml b/.idea/dictionaries/admin.xml
index 798ea1f12..e49854e04 100644
--- a/.idea/dictionaries/admin.xml
+++ b/.idea/dictionaries/admin.xml
@@ -4,6 +4,7 @@
koin
kotatsu
manga
+ upsert
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt b/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt
index 22e24649b..321e2dfb9 100644
--- a/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt
@@ -54,5 +54,5 @@ class KotatsuApp : Application() {
applicationContext,
MangaDatabase::class.java,
"kotatsu-db"
- )
+ ).fallbackToDestructiveMigration() //TODO remove
}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/HistoryDao.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/HistoryDao.kt
index 6fd4877be..24ad5443e 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/db/HistoryDao.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/db/HistoryDao.kt
@@ -1,12 +1,41 @@
package org.koitharu.kotatsu.core.db
-import androidx.room.Dao
-import androidx.room.Query
+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
-interface HistoryDao {
+abstract class HistoryDao {
+
+ /**
+ * @hide
+ */
+ @Transaction
+ @Query("SELECT * FROM history ORDER BY :orderBy LIMIT :limit OFFSET :offset")
+ abstract suspend fun getAll(offset: Int, limit: Int, orderBy: String): List
+
+ @Query("DELETE FROM history")
+ abstract suspend fun clear()
+
+ @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)
+
+ @Transaction
+ suspend open fun upsert(entity: HistoryWithManga) {
+ if (update(entity) == 0) {
+ insertManga(entity.manga)
+ insert(entity.history)
+ }
+ }
- @Query("SELECT * FROM history")
- suspend fun getAll(): List
}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDatabase.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDatabase.kt
index 59c0f7499..29cc9cfef 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDatabase.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDatabase.kt
@@ -3,6 +3,13 @@ package org.koitharu.kotatsu.core.db
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.TagEntity
-@Database(entities = [HistoryEntity::class], version = 1)
-abstract class MangaDatabase : RoomDatabase()
\ No newline at end of file
+@Database(entities = [MangaEntity::class, TagEntity::class, HistoryEntity::class], version = 1)
+abstract class MangaDatabase : RoomDatabase() {
+
+ abstract fun historyDao(): HistoryDao
+
+ abstract fun tagsDao(): TagsDao
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/TagsDao.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/TagsDao.kt
new file mode 100644
index 000000000..0cb75f74e
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/core/db/TagsDao.kt
@@ -0,0 +1,14 @@
+package org.koitharu.kotatsu.core.db
+
+import androidx.room.Dao
+import androidx.room.Query
+import androidx.room.Transaction
+import org.koitharu.kotatsu.core.db.entity.TagEntity
+
+@Dao
+interface TagsDao {
+
+ @Transaction
+ @Query("SELECT * FROM tags")
+ fun getAllTags(): List
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryEntity.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryEntity.kt
index c4e29ed73..1f130127c 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryEntity.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryEntity.kt
@@ -1,9 +1,25 @@
package org.koitharu.kotatsu.core.db.entity
+import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
+import org.koitharu.kotatsu.core.model.MangaHistory
+import java.util.*
@Entity(tableName = "history")
data class HistoryEntity(
- @PrimaryKey val id: Long
-)
\ No newline at end of file
+ @PrimaryKey(autoGenerate = false)
+ @ColumnInfo(name = "manga_id") val mangaId: Long,
+ @ColumnInfo(name = "created_at") val createdAt: Long = System.currentTimeMillis(),
+ @ColumnInfo(name = "updated_at") val updatedAt: Long,
+ @ColumnInfo(name = "chapter_id") val chapterId: Long,
+ @ColumnInfo(name = "page") val page: Int
+) {
+
+ fun toMangaHistory() = MangaHistory(
+ createdAt = Date(createdAt),
+ updatedAt = Date(updatedAt),
+ chapterId = chapterId,
+ page = page
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryWithManga.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryWithManga.kt
new file mode 100644
index 000000000..3b6e4d34b
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryWithManga.kt
@@ -0,0 +1,13 @@
+package org.koitharu.kotatsu.core.db.entity
+
+import androidx.room.Embedded
+import androidx.room.Relation
+
+data class HistoryWithManga(
+ @Embedded val history: HistoryEntity,
+ @Relation(
+ parentColumn = "manga_id",
+ entityColumn = "manga_id"
+ )
+ val manga: MangaEntity
+)
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaEntity.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaEntity.kt
new file mode 100644
index 000000000..b25baf73d
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaEntity.kt
@@ -0,0 +1,55 @@
+package org.koitharu.kotatsu.core.db.entity
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+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
+
+@Entity(tableName = "manga")
+data class MangaEntity(
+ @PrimaryKey(autoGenerate = false)
+ @ColumnInfo(name = "manga_id") val id: Long,
+ @ColumnInfo(name = "title") val title: String,
+ @ColumnInfo(name = "localized_title") val localizedTitle: String? = null,
+ @ColumnInfo(name = "url") val url: String,
+ @ColumnInfo(name = "rating") val rating: Float = Manga.NO_RATING, //normalized value [0..1] or -1
+ @ColumnInfo(name = "cover_url") val coverUrl: String,
+ @ColumnInfo(name = "large_cover_url") val largeCoverUrl: String? = null,
+ @ColumnInfo(name = "summary") val summary: String,
+ @ColumnInfo(name = "state") val state: String? = null,
+ @ColumnInfo(name = "source") val source: String
+) {
+
+ fun toManga() = Manga(
+ id = this.id,
+ title = this.title,
+ localizedTitle = this.localizedTitle,
+ summary = this.summary,
+ state = this.state?.let { MangaState.valueOf(it) },
+ rating = this.rating,
+ url = this.url,
+ coverUrl = this.coverUrl,
+ largeCoverUrl = this.largeCoverUrl,
+ source = MangaSource.valueOf(this.source)
+// tags = this.tags.map(TagEntity::toMangaTag).toSet()
+ )
+
+ companion object {
+
+ fun from(manga: Manga) = MangaEntity(
+ id = manga.id,
+ url = manga.url,
+ source = manga.source.name,
+ largeCoverUrl = manga.largeCoverUrl,
+ coverUrl = manga.coverUrl,
+ localizedTitle = manga.localizedTitle,
+ rating = manga.rating,
+ state = manga.state?.name,
+ summary = manga.summary,
+// tags = manga.tags.map(TagEntity.Companion::fromMangaTag),
+ title = manga.title
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaTagsEntity.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaTagsEntity.kt
new file mode 100644
index 000000000..db26ace78
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaTagsEntity.kt
@@ -0,0 +1,10 @@
+package org.koitharu.kotatsu.core.db.entity
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+
+@Entity(tableName = "manga_tags", primaryKeys = ["manga_id", "tag_id"])
+data class MangaTagsEntity(
+ @ColumnInfo(name = "manga_id") val mangaId: Long,
+ @ColumnInfo(name = "tag_id") val tagId: Long
+)
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TagEntity.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TagEntity.kt
new file mode 100644
index 000000000..1af937d06
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TagEntity.kt
@@ -0,0 +1,34 @@
+package org.koitharu.kotatsu.core.db.entity
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import org.koitharu.kotatsu.core.model.MangaSource
+import org.koitharu.kotatsu.core.model.MangaTag
+import org.koitharu.kotatsu.utils.ext.longHashCode
+
+@Entity(tableName = "tags")
+data class TagEntity(
+ @PrimaryKey(autoGenerate = false)
+ @ColumnInfo(name = "tag_id") val id: Long,
+ @ColumnInfo(name = "title") val title: String,
+ @ColumnInfo(name = "key") val key: String,
+ @ColumnInfo(name = "source") val source: String
+) {
+
+ fun toMangaTag() = MangaTag(
+ key = this.key,
+ title = this.title,
+ source = MangaSource.valueOf(this.source)
+ )
+
+ companion object {
+
+ fun fromMangaTag(tag: MangaTag) = TagEntity(
+ title = tag.title,
+ key = tag.key,
+ source = tag.source.name,
+ id = "${tag.key}_${tag.source.name}".longHashCode()
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaHistory.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaHistory.kt
new file mode 100644
index 000000000..82219dbef
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaHistory.kt
@@ -0,0 +1,13 @@
+package org.koitharu.kotatsu.core.model
+
+import android.os.Parcelable
+import kotlinx.android.parcel.Parcelize
+import java.util.*
+
+@Parcelize
+data class MangaHistory(
+ val createdAt: Date,
+ val updatedAt: Date,
+ val chapterId: Long,
+ val page: Int
+) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaInfo.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaInfo.kt
new file mode 100644
index 000000000..3871a462f
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaInfo.kt
@@ -0,0 +1,6 @@
+package org.koitharu.kotatsu.core.model
+
+data class MangaInfo (
+ val manga: Manga,
+ val extra: E
+)
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt
index b163c7929..423e3ddfb 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt
@@ -4,7 +4,6 @@ import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import org.koitharu.kotatsu.domain.MangaRepository
import org.koitharu.kotatsu.domain.repository.ReadmangaRepository
-import kotlin.reflect.KClass
@Parcelize
enum class MangaSource(val title: String, val cls: Class): Parcelable {
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTag.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTag.kt
index af867377f..aaa871d44 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTag.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTag.kt
@@ -6,5 +6,6 @@ import kotlinx.android.parcel.Parcelize
@Parcelize
data class MangaTag(
val title: String,
- val key: String
+ val key: String,
+ val source: MangaSource
) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt
index 54c1f2a72..15e326310 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt
@@ -3,8 +3,6 @@ package org.koitharu.kotatsu.core.prefs
import android.content.Context
import android.content.SharedPreferences
import android.content.res.Resources
-import androidx.core.content.edit
-import androidx.lifecycle.LifecycleOwner
import androidx.preference.PreferenceManager
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.utils.delegates.prefs.EnumPreferenceDelegate
@@ -13,7 +11,7 @@ class AppSettings private constructor(private val resources: Resources, private
constructor(context: Context) : this(context.resources, PreferenceManager.getDefaultSharedPreferences(context))
- var listMode by EnumPreferenceDelegate(ListMode::class.java, resources.getString(R.string.key_list_mode), ListMode.LIST)
+ var listMode by EnumPreferenceDelegate(ListMode::class.java, resources.getString(R.string.key_list_mode), ListMode.DETAILED_LIST)
fun subscribe(listener: SharedPreferences.OnSharedPreferenceChangeListener) {
prefs.registerOnSharedPreferenceChangeListener(listener)
diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/BaseMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/BaseMangaRepository.kt
new file mode 100644
index 000000000..544e1748f
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/domain/BaseMangaRepository.kt
@@ -0,0 +1,13 @@
+package org.koitharu.kotatsu.domain
+
+import org.koitharu.kotatsu.core.model.MangaPage
+import org.koitharu.kotatsu.core.model.SortOrder
+
+abstract class BaseMangaRepository(protected val loaderContext: MangaLoaderContext) : MangaRepository {
+
+ override val sortOrders: Set get() = emptySet()
+
+ override val isSearchAvailable get() = true
+
+ override suspend fun getPageFullUrl(page: MangaPage) : String = page.url
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/HistoryRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/HistoryRepository.kt
new file mode 100644
index 000000000..cacc6a872
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/domain/HistoryRepository.kt
@@ -0,0 +1,71 @@
+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.*
+import java.io.Closeable
+
+class HistoryRepository() : KoinComponent, MangaRepository, Closeable {
+
+ private val db: MangaDatabase by inject()
+
+ override val sortOrders: Set = setOf(SortOrder.NEWEST, SortOrder.POPULARITY)
+
+ override val isSearchAvailable = false
+
+ override suspend fun getList(
+ offset: Int,
+ query: String?,
+ sortOrder: SortOrder?,
+ tags: Set?
+ ): List = getHistory(offset, query, sortOrder, tags).map { x -> x.manga }
+
+ suspend fun getHistory(
+ offset: Int,
+ query: String? = null,
+ sortOrder: SortOrder? = null,
+ tags: Set? = null
+ ): List> {
+ val entities = db.historyDao().getAll(offset, 20, "updated_by")
+ return entities.map { x -> MangaInfo(x.manga.toManga(), x.history.toMangaHistory()) }
+ }
+
+ override suspend fun getDetails(manga: Manga): Manga {
+ throw UnsupportedOperationException("History repository does not support getDetails() method")
+ }
+
+ override suspend fun getPages(chapter: MangaChapter): List {
+ throw UnsupportedOperationException("History repository does not support getPages() method")
+ }
+
+ override suspend fun getPageFullUrl(page: MangaPage) = page.url
+
+ 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 clear() {
+ db.historyDao().clear()
+ }
+
+ override fun close() {
+ db.close()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/MangaRepository.kt
index eb4e35438..453658073 100644
--- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaRepository.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/domain/MangaRepository.kt
@@ -1,18 +1,21 @@
package org.koitharu.kotatsu.domain
-import org.koitharu.kotatsu.core.model.*
+import org.koitharu.kotatsu.core.model.Manga
+import org.koitharu.kotatsu.core.model.MangaChapter
+import org.koitharu.kotatsu.core.model.MangaPage
+import org.koitharu.kotatsu.core.model.SortOrder
-abstract class MangaRepository(protected val loaderContext: MangaLoaderContext) {
+interface MangaRepository {
- open val sortOrders: Set get() = emptySet()
+ val sortOrders: Set
- open val isSearchAvailable get() = true
+ val isSearchAvailable: Boolean
- abstract suspend fun getList(offset: Int, query: String? = null, sortOrder: SortOrder? = null, tags: Set? = null): List
+ suspend fun getList(offset: Int, query: String? = null, sortOrder: SortOrder? = null, tags: Set? = null): List
- abstract suspend fun getDetails(manga: Manga) : Manga
+ suspend fun getDetails(manga: Manga) : Manga
- abstract suspend fun getPages(chapter: MangaChapter) : List
+ suspend fun getPages(chapter: MangaChapter) : List
- open suspend fun getPageFullUrl(page: MangaPage) : String = page.url
+ suspend fun getPageFullUrl(page: MangaPage) : String
}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/repository/ReadmangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/repository/ReadmangaRepository.kt
index de2876aac..9bf8e3ff4 100644
--- a/app/src/main/java/org/koitharu/kotatsu/domain/repository/ReadmangaRepository.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/domain/repository/ReadmangaRepository.kt
@@ -1,14 +1,13 @@
package org.koitharu.kotatsu.domain.repository
-import androidx.core.text.HtmlCompat
import androidx.core.text.parseAsHtml
import org.koitharu.kotatsu.core.model.*
+import org.koitharu.kotatsu.domain.BaseMangaRepository
import org.koitharu.kotatsu.domain.MangaLoaderContext
-import org.koitharu.kotatsu.domain.MangaRepository
import org.koitharu.kotatsu.domain.exceptions.ParseException
import org.koitharu.kotatsu.utils.ext.*
-class ReadmangaRepository(loaderContext: MangaLoaderContext) : MangaRepository(loaderContext) {
+class ReadmangaRepository(loaderContext: MangaLoaderContext) : BaseMangaRepository(loaderContext) {
override suspend fun getList(
offset: Int,
@@ -47,7 +46,8 @@ class ReadmangaRepository(loaderContext: MangaLoaderContext) : MangaRepository(l
?.map {
MangaTag(
title = it.text(),
- key = it.attr("href").substringAfterLast('/')
+ key = it.attr("href").substringAfterLast('/'),
+ source = MangaSource.READMANGA_RU
)
}?.toSet()
}.orEmpty(),
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/MainActivity.kt
index d4c38b256..dc3471926 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/main/MainActivity.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/MainActivity.kt
@@ -10,7 +10,8 @@ import kotlinx.android.synthetic.main.activity_main.*
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.MangaSource
import org.koitharu.kotatsu.ui.common.BaseActivity
-import org.koitharu.kotatsu.ui.main.list.MangaListFragment
+import org.koitharu.kotatsu.ui.main.list.history.HistoryListFragment
+import org.koitharu.kotatsu.ui.main.list.remote.RemoteListFragment
class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener {
@@ -29,7 +30,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
navigationView.setNavigationItemSelectedListener(this)
if (!supportFragmentManager.isStateSaved) {
- setPrimaryFragment(MangaListFragment.newInstance(MangaSource.READMANGA_RU))
+ setPrimaryFragment(RemoteListFragment.newInstance(MangaSource.READMANGA_RU))
}
}
@@ -51,9 +52,9 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
override fun onNavigationItemSelected(item: MenuItem): Boolean {
if (item.groupId == R.id.group_remote_sources) {
val source = MangaSource.values().getOrNull(item.itemId) ?: return false
- setPrimaryFragment(MangaListFragment.newInstance(source))
+ setPrimaryFragment(RemoteListFragment.newInstance(source))
} else when (item.itemId) {
- R.id.nav_history -> Unit
+ R.id.nav_history -> setPrimaryFragment(HistoryListFragment.newInstance())
R.id.nav_favourites -> Unit
R.id.nav_local_storage -> Unit
else -> return false
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/ListModeSelectDialog.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/ListModeSelectDialog.kt
index 42a5b744a..7bbc298bd 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/ListModeSelectDialog.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/ListModeSelectDialog.kt
@@ -46,6 +46,8 @@ class ListModeSelectDialog : AlertDialogFragment(R.layout.dialog_list_mode), Vie
private const val TAG = "ListModeSelectDialog"
- fun show(fm: FragmentManager) = ListModeSelectDialog().show(fm, TAG)
+ fun show(fm: FragmentManager) = ListModeSelectDialog().show(fm,
+ TAG
+ )
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaGridHolder.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaGridHolder.kt
index fac613527..60eda6c6a 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaGridHolder.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaGridHolder.kt
@@ -5,17 +5,17 @@ import coil.api.load
import coil.request.RequestDisposable
import kotlinx.android.synthetic.main.item_manga_grid.*
import org.koitharu.kotatsu.R
-import org.koitharu.kotatsu.core.model.Manga
+import org.koitharu.kotatsu.core.model.MangaInfo
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
-class MangaGridHolder(parent: ViewGroup) : BaseViewHolder(parent, R.layout.item_manga_grid) {
+class MangaGridHolder(parent: ViewGroup) : BaseViewHolder>(parent, R.layout.item_manga_grid) {
private var coverRequest: RequestDisposable? = null
- override fun onBind(data: Manga) {
+ override fun onBind(data: MangaInfo) {
coverRequest?.dispose()
- textView_title.text = data.title
- coverRequest = imageView_cover.load(data.coverUrl) {
+ textView_title.text = data.manga.title
+ coverRequest = imageView_cover.load(data.manga.coverUrl) {
crossfade(true)
}
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListAdapter.kt
index 7a963ad65..ea0568cbb 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListAdapter.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListAdapter.kt
@@ -1,21 +1,21 @@
package org.koitharu.kotatsu.ui.main.list
import android.view.ViewGroup
-import org.koitharu.kotatsu.core.model.Manga
+import org.koitharu.kotatsu.core.model.MangaInfo
import org.koitharu.kotatsu.core.prefs.ListMode
import org.koitharu.kotatsu.ui.common.list.BaseRecyclerAdapter
import org.koitharu.kotatsu.ui.common.list.OnRecyclerItemClickListener
-class MangaListAdapter(onItemClickListener: OnRecyclerItemClickListener) :
- BaseRecyclerAdapter(onItemClickListener) {
+class MangaListAdapter(onItemClickListener: OnRecyclerItemClickListener>) :
+ BaseRecyclerAdapter>(onItemClickListener) {
var listMode: ListMode = ListMode.LIST
override fun onCreateViewHolder(parent: ViewGroup) = when(listMode) {
- ListMode.LIST -> MangaListHolder(parent)
- ListMode.DETAILED_LIST -> MangaListDetailsHolder(parent)
+ ListMode.LIST -> MangaListHolder(parent)
+ ListMode.DETAILED_LIST -> MangaListDetailsHolder(parent)
ListMode.GRID -> MangaGridHolder(parent)
}
- override fun onGetItemId(item: Manga) = item.id
+ override fun onGetItemId(item: MangaInfo) = item.manga.id
}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListDetailsHolder.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListDetailsHolder.kt
index a875683f6..ddf0428b7 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListDetailsHolder.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListDetailsHolder.kt
@@ -8,29 +8,30 @@ import coil.request.RequestDisposable
import kotlinx.android.synthetic.main.item_manga_list_details.*
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.Manga
+import org.koitharu.kotatsu.core.model.MangaInfo
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
import org.koitharu.kotatsu.utils.ext.textAndVisible
import kotlin.math.roundToInt
-class MangaListDetailsHolder(parent: ViewGroup) : BaseViewHolder(parent, R.layout.item_manga_list_details) {
+class MangaListDetailsHolder(parent: ViewGroup) : BaseViewHolder>(parent, R.layout.item_manga_list_details) {
private var coverRequest: RequestDisposable? = null
@SuppressLint("SetTextI18n")
- override fun onBind(data: Manga) {
+ override fun onBind(data: MangaInfo) {
coverRequest?.dispose()
- textView_title.text = data.title
- textView_subtitle.textAndVisible = data.localizedTitle
- coverRequest = imageView_cover.load(data.coverUrl) {
+ textView_title.text = data.manga.title
+ textView_subtitle.textAndVisible = data.manga.localizedTitle
+ coverRequest = imageView_cover.load(data.manga.coverUrl) {
crossfade(true)
}
- if(data.rating == Manga.NO_RATING) {
+ if(data.manga.rating == Manga.NO_RATING) {
textView_rating.isVisible = false
} else {
- textView_rating.text = "${(data.rating * 10).roundToInt()}/10"
+ textView_rating.text = "${(data.manga.rating * 10).roundToInt()}/10"
textView_rating.isVisible = true
}
- textView_tags.text = data.tags.joinToString(", ") {
+ textView_tags.text = data.manga.tags.joinToString(", ") {
it.title
}
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListFragment.kt
index e3be5c421..2378a8ffe 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListFragment.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListFragment.kt
@@ -13,26 +13,23 @@ 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.ktx.moxyPresenter
import org.koitharu.kotatsu.R
-import org.koitharu.kotatsu.core.model.Manga
-import org.koitharu.kotatsu.core.model.MangaSource
+import org.koitharu.kotatsu.core.model.MangaInfo
import org.koitharu.kotatsu.core.prefs.ListMode
import org.koitharu.kotatsu.ui.common.BaseFragment
import org.koitharu.kotatsu.ui.common.list.OnRecyclerItemClickListener
import org.koitharu.kotatsu.ui.common.list.PaginationScrollListener
import org.koitharu.kotatsu.ui.common.list.SpacingItemDecoration
import org.koitharu.kotatsu.ui.details.MangaDetailsActivity
-import org.koitharu.kotatsu.utils.ext.*
+import org.koitharu.kotatsu.utils.ext.clearItemDecorations
+import org.koitharu.kotatsu.utils.ext.firstItem
+import org.koitharu.kotatsu.utils.ext.getDisplayMessage
+import org.koitharu.kotatsu.utils.ext.hasItems
-class MangaListFragment : BaseFragment(R.layout.fragment_list), MangaListView,
- PaginationScrollListener.Callback, OnRecyclerItemClickListener {
+abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), MangaListView,
+ PaginationScrollListener.Callback, OnRecyclerItemClickListener> {
- private val presenter by moxyPresenter(factory = ::MangaListPresenter)
-
- private val source by arg(ARG_SOURCE)
-
- private lateinit var adapter: MangaListAdapter
+ private lateinit var adapter: MangaListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -46,7 +43,7 @@ class MangaListFragment : BaseFragment(R.layout.fragment_list), MangaListView,
recyclerView.adapter = adapter
recyclerView.addOnScrollListener(PaginationScrollListener(4, this))
swipeRefreshLayout.setOnRefreshListener {
- presenter.loadList(source, 0)
+ onRequestMoreItems(0)
}
settings.subscribe(this)
}
@@ -58,7 +55,9 @@ class MangaListFragment : BaseFragment(R.layout.fragment_list), MangaListView,
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
- presenter.loadList(source, 0)
+ if (!recyclerView.hasItems) {
+ onRequestMoreItems(0)
+ }
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
@@ -74,19 +73,16 @@ class MangaListFragment : BaseFragment(R.layout.fragment_list), MangaListView,
else -> super.onOptionsItemSelected(item)
}
- override fun onItemClick(item: Manga, position: Int, view: View) {
- startActivity(MangaDetailsActivity.newIntent(context ?: return, item))
+ override fun onItemClick(item: MangaInfo, position: Int, view: View) {
+ startActivity(MangaDetailsActivity.newIntent(context ?: return, item.manga))
}
- override fun onRequestMoreItems(offset: Int) {
- presenter.loadList(source, offset)
- }
-
- override fun onListChanged(list: List) {
+ override fun onListChanged(list: List>) {
adapter.replaceData(list)
+ layout_holder.isVisible = list.isEmpty()
}
- override fun onListAppended(list: List) {
+ override fun onListAppended(list: List>) {
adapter.appendData(list)
}
@@ -101,10 +97,9 @@ class MangaListFragment : BaseFragment(R.layout.fragment_list), MangaListView,
progressBar.isVisible = isLoading && !hasItems
swipeRefreshLayout.isRefreshing = isLoading && hasItems
swipeRefreshLayout.isEnabled = !progressBar.isVisible
- }
-
- override fun getTitle(): CharSequence? {
- return source.title
+ if (isLoading) {
+ layout_holder.isVisible = false
+ }
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
@@ -133,13 +128,4 @@ class MangaListFragment : BaseFragment(R.layout.fragment_list), MangaListView,
adapter.notifyDataSetChanged()
recyclerView.firstItem = position
}
-
- companion object {
-
- private const val ARG_SOURCE = "provider"
-
- fun newInstance(provider: MangaSource) = MangaListFragment().withArgs(1) {
- putParcelable(ARG_SOURCE, provider)
- }
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListHolder.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListHolder.kt
index 1fa828792..1405fadc9 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListHolder.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListHolder.kt
@@ -5,19 +5,19 @@ import coil.api.load
import coil.request.RequestDisposable
import kotlinx.android.synthetic.main.item_manga_list.*
import org.koitharu.kotatsu.R
-import org.koitharu.kotatsu.core.model.Manga
+import org.koitharu.kotatsu.core.model.MangaInfo
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
import org.koitharu.kotatsu.utils.ext.textAndVisible
-class MangaListHolder(parent: ViewGroup) : BaseViewHolder(parent, R.layout.item_manga_list) {
+class MangaListHolder(parent: ViewGroup) : BaseViewHolder>(parent, R.layout.item_manga_list) {
private var coverRequest: RequestDisposable? = null
- override fun onBind(data: Manga) {
+ override fun onBind(data: MangaInfo) {
coverRequest?.dispose()
- textView_title.text = data.title
- textView_subtitle.textAndVisible = data.localizedTitle
- coverRequest = imageView_cover.load(data.coverUrl) {
+ textView_title.text = data.manga.title
+ textView_subtitle.textAndVisible = data.manga.localizedTitle
+ coverRequest = imageView_cover.load(data.manga.coverUrl) {
crossfade(true)
}
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListView.kt
index 8583261f3..d13cfe196 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListView.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListView.kt
@@ -2,15 +2,15 @@ package org.koitharu.kotatsu.ui.main.list
import moxy.MvpView
import moxy.viewstate.strategy.*
-import org.koitharu.kotatsu.core.model.Manga
+import org.koitharu.kotatsu.core.model.MangaInfo
-interface MangaListView : MvpView {
+interface MangaListView : MvpView {
@StateStrategyType(AddToEndSingleTagStrategy::class, tag = "content")
- fun onListChanged(list: List)
+ fun onListChanged(list: List>)
@StateStrategyType(AddToEndStrategy::class, tag = "content")
- fun onListAppended(list: List)
+ fun onListAppended(list: List>)
@StateStrategyType(AddToEndSingleStrategy::class)
fun onLoadingChanged(isLoading: Boolean)
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListFragment.kt
new file mode 100644
index 000000000..138886624
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListFragment.kt
@@ -0,0 +1,49 @@
+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
+import org.koitharu.kotatsu.core.model.MangaHistory
+import org.koitharu.kotatsu.ui.main.list.MangaListFragment
+import org.koitharu.kotatsu.ui.main.list.MangaListView
+
+class HistoryListFragment : MangaListFragment(), MangaListView{
+
+ 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)
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ inflater.inflate(R.menu.opt_history, menu)
+ super.onCreateOptionsMenu(menu, inflater)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem) = when(item.itemId) {
+ R.id.action_clear_history -> {
+ presenter.clearHistory()
+ true
+ }
+ else -> super.onOptionsItemSelected(item)
+ }
+
+ override fun getTitle(): CharSequence? {
+ return getString(R.string.history)
+ }
+
+ companion object {
+
+ fun newInstance() = HistoryListFragment()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListPresenter.kt
new file mode 100644
index 000000000..62299dced
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/history/HistoryListPresenter.kt
@@ -0,0 +1,70 @@
+package org.koitharu.kotatsu.ui.main.list.history
+
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import moxy.InjectViewState
+import okhttp3.internal.closeQuietly
+import org.koitharu.kotatsu.BuildConfig
+import org.koitharu.kotatsu.core.model.MangaHistory
+import org.koitharu.kotatsu.domain.HistoryRepository
+import org.koitharu.kotatsu.ui.common.BasePresenter
+import org.koitharu.kotatsu.ui.main.list.MangaListView
+
+@InjectViewState
+class HistoryListPresenter : BasePresenter>() {
+
+ private lateinit var repository: HistoryRepository
+
+ override fun onFirstViewAttach() {
+ repository = HistoryRepository()
+ super.onFirstViewAttach()
+ }
+
+ fun loadList(offset: Int) {
+ launch {
+ viewState.onLoadingChanged(true)
+ try {
+ val list = withContext(Dispatchers.IO) {
+ repository.getHistory(offset = offset)
+ }
+ if (offset == 0) {
+ viewState.onListChanged(list)
+ } else {
+ viewState.onListAppended(list)
+ }
+ } catch (e: Exception) {
+ if (BuildConfig.DEBUG) {
+ e.printStackTrace()
+ }
+ viewState.onError(e)
+ } finally {
+ viewState.onLoadingChanged(false)
+ }
+ }
+ }
+
+ fun clearHistory() {
+ launch {
+ viewState.onLoadingChanged(true)
+ try {
+ withContext(Dispatchers.IO) {
+ repository.clear()
+ }
+ viewState.onListChanged(emptyList())
+ } catch (e: Exception) {
+ if (BuildConfig.DEBUG) {
+ e.printStackTrace()
+ }
+ viewState.onError(e)
+ } finally {
+ viewState.onLoadingChanged(false)
+ }
+ }
+ }
+
+ override fun onDestroy() {
+ repository.closeQuietly()
+ super.onDestroy()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListFragment.kt
new file mode 100644
index 000000000..48279956f
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListFragment.kt
@@ -0,0 +1,39 @@
+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
+
+class RemoteListFragment : MangaListFragment() {
+
+ private val presenter by moxyPresenter(factory = ::RemoteListPresenter)
+
+ private val source by arg(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)
+ }
+
+ override fun getTitle(): CharSequence? {
+ return source.title
+ }
+
+ companion object {
+
+ private const val ARG_SOURCE = "provider"
+
+ fun newInstance(provider: MangaSource) = RemoteListFragment().withArgs(1) {
+ putParcelable(ARG_SOURCE, provider)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListPresenter.kt
similarity index 77%
rename from app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListPresenter.kt
rename to app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListPresenter.kt
index be1e88480..6085e24b2 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/MangaListPresenter.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/remote/RemoteListPresenter.kt
@@ -1,16 +1,18 @@
-package org.koitharu.kotatsu.ui.main.list
+package org.koitharu.kotatsu.ui.main.list.remote
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import moxy.InjectViewState
import org.koitharu.kotatsu.BuildConfig
+import org.koitharu.kotatsu.core.model.MangaInfo
import org.koitharu.kotatsu.core.model.MangaSource
import org.koitharu.kotatsu.domain.MangaProviderFactory
import org.koitharu.kotatsu.ui.common.BasePresenter
+import org.koitharu.kotatsu.ui.main.list.MangaListView
@InjectViewState
-class MangaListPresenter : BasePresenter() {
+class RemoteListPresenter : BasePresenter>() {
fun loadList(source: MangaSource, offset: Int) {
launch {
@@ -19,6 +21,7 @@ class MangaListPresenter : BasePresenter() {
val list = withContext(Dispatchers.IO) {
MangaProviderFactory.create(source)
.getList(offset)
+ .map { MangaInfo(it, Unit) }
}
if (offset == 0) {
viewState.onListChanged(list)
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt
index 65d207e7c..d3d519f23 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt
@@ -6,12 +6,10 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.core.view.isVisible
-import com.google.android.material.snackbar.Snackbar
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.MangaChapter
import org.koitharu.kotatsu.core.model.MangaPage
import org.koitharu.kotatsu.ui.common.BaseActivity
import org.koitharu.kotatsu.utils.ext.showDialog
@@ -58,6 +56,11 @@ class ReaderActivity : BaseActivity(), ReaderView {
super.onDestroy()
}
+ override fun onPause() {
+ presenter.addToHistory(manga, chapterId, pager.currentItem)
+ super.onPause()
+ }
+
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.opt_reader_top, menu)
return super.onCreateOptionsMenu(menu)
diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt
index 632d20cff..b325b8d87 100644
--- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt
@@ -5,12 +5,14 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import moxy.InjectViewState
import org.koitharu.kotatsu.BuildConfig
+import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.core.model.MangaChapter
+import org.koitharu.kotatsu.domain.HistoryRepository
import org.koitharu.kotatsu.domain.MangaProviderFactory
import org.koitharu.kotatsu.ui.common.BasePresenter
@InjectViewState
-class ReaderPresenter() : BasePresenter() {
+class ReaderPresenter : BasePresenter() {
fun loadChapter(chapter: MangaChapter) {
launch {
@@ -31,4 +33,12 @@ class ReaderPresenter() : BasePresenter() {
}
}
+ fun addToHistory(manga: Manga, chapterId: Long, page: Int) {
+ launch(Dispatchers.IO) {
+ HistoryRepository().use {
+ it.addOrUpdate(manga, chapterId, page)
+ }
+ }
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index 57a1b4cfa..000000000
--- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_list.xml b/app/src/main/res/layout/fragment_list.xml
index 8707eb71e..5debf1924 100644
--- a/app/src/main/res/layout/fragment_list.xml
+++ b/app/src/main/res/layout/fragment_list.xml
@@ -1,5 +1,6 @@
-
+ android:text="?android:textColorSecondary"
+ android:textAppearance="@style/TextAppearance.AppCompat.Medium"
+ tools:text="@tools:sample/lorem[3]" />
diff --git a/app/src/main/res/menu/opt_history.xml b/app/src/main/res/menu/opt_history.xml
new file mode 100644
index 000000000..f1cd6968b
--- /dev/null
+++ b/app/src/main/res/menu/opt_history.xml
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 65f62af29..64c37a017 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -19,4 +19,7 @@
Chapter %d of %d
Close
Try again
+ Clear history
+ Nothing found
+ History is empty
\ No newline at end of file