Update history
parent
a957021582
commit
64b38c561c
@ -1 +1,2 @@
|
||||
/build
|
||||
/build
|
||||
/schemas/
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package org.koitharu.kotatsu.domain
|
||||
package org.koitharu.kotatsu.domain.history
|
||||
|
||||
enum class ChapterExtra {
|
||||
|
||||
@ -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() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
package org.koitharu.kotatsu.domain.history
|
||||
|
||||
interface OnHistoryChangeListener {
|
||||
|
||||
fun onHistoryChanged()
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:textColorPrimary"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M17,18V5H7V18L12,15.82L17,18M17,3A2,2 0 0,1 19,5V21L12,18L5,21V5C5,3.89 5.9,3 7,3H17M11,7H13V9H15V11H13V13H11V11H9V9H11V7Z" />
|
||||
</vector>
|
||||
@ -0,0 +1,11 @@
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:textColorPrimary"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M3,17v2h6v-2L3,17zM3,5v2h10L13,5L3,5zM13,21v-2h8v-2h-8v-2h-2v6h2zM7,9v2L3,11v2h4v2h2L9,9L7,9zM21,13v-2L11,11v2h10zM15,9h2L17,7h4L21,5h-4L17,3h-2v6z" />
|
||||
</vector>
|
||||
@ -1,8 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item android:id="@+id/action_settings"
|
||||
android:title="@string/settings" />
|
||||
<item
|
||||
android:id="@+id/action_bookmark_add"
|
||||
android:icon="@drawable/ic_bookmark_add"
|
||||
android:title="@string/add_bookmark"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:icon="@drawable/ic_tune"
|
||||
android:title="@string/settings"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
</menu>
|
||||
Loading…
Reference in New Issue