Upgrade db, extract common gallery info

This commit is contained in:
FooIbar authored and tarsin committed 2023-07-20 19:00:57 +08:00
1 parent 11426e1c4c
commit ee504e3361
33 files changed
+741 -334

No files matched your search

@@ -0,0 +1,402 @@
{
"formatVersion": 1,
"database": {
"version": 14,
"identityHash": "54e4f2704cc47c5a6a2f4b96de978cce",
"entities": [
{
"tableName": "GALLERIES",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
"fields": [
{
"fieldPath": "gid",
"columnName": "GID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "token",
"columnName": "TOKEN",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "TITLE",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "titleJpn",
"columnName": "TITLE_JPN",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "thumbKey",
"columnName": "THUMB",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "category",
"columnName": "CATEGORY",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "posted",
"columnName": "POSTED",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "uploader",
"columnName": "UPLOADER",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "rating",
"columnName": "RATING",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "simpleLanguage",
"columnName": "SIMPLE_LANGUAGE",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "favoriteSlot",
"columnName": "FAVORITE_SLOT",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"GID"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "DOWNLOADS",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "gid",
"columnName": "GID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "state",
"columnName": "STATE",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "legacy",
"columnName": "LEGACY",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "TIME",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "label",
"columnName": "LABEL",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "position",
"columnName": "POSITION",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"GID"
]
},
"indices": [],
"foreignKeys": [
{
"table": "GALLERIES",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"GID"
],
"referencedColumns": [
"GID"
]
}
]
},
{
"tableName": "DOWNLOAD_LABELS",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
"fields": [
{
"fieldPath": "label",
"columnName": "LABEL",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "position",
"columnName": "POSITION",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "DOWNLOAD_DIRNAME",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
"fields": [
{
"fieldPath": "gid",
"columnName": "GID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "dirname",
"columnName": "DIRNAME",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"GID"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "FILTER",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
"fields": [
{
"fieldPath": "mode",
"columnName": "MODE",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "text",
"columnName": "TEXT",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "enable",
"columnName": "ENABLE",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "HISTORY",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "gid",
"columnName": "GID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "TIME",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"GID"
]
},
"indices": [],
"foreignKeys": [
{
"table": "GALLERIES",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"GID"
],
"referencedColumns": [
"GID"
]
}
]
},
{
"tableName": "LOCAL_FAVORITES",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "gid",
"columnName": "GID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "TIME",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"GID"
]
},
"indices": [],
"foreignKeys": [
{
"table": "GALLERIES",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"GID"
],
"referencedColumns": [
"GID"
]
}
]
},
{
"tableName": "QUICK_SEARCH",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "NAME",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "mode",
"columnName": "MODE",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "category",
"columnName": "CATEGORY",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "keyword",
"columnName": "KEYWORD",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "advanceSearch",
"columnName": "ADVANCE_SEARCH",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minRating",
"columnName": "MIN_RATING",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "pageFrom",
"columnName": "PAGE_FROM",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "pageTo",
"columnName": "PAGE_TO",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "position",
"columnName": "POSITION",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"_id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '54e4f2704cc47c5a6a2f4b96de978cce')"
]
}
}
+65 -81
View File
@@ -19,10 +19,9 @@ import android.content.Context
import android.net.Uri
import android.os.ParcelFileDescriptor
import android.os.ParcelFileDescriptor.MODE_READ_ONLY
import androidx.paging.PagingSource
import arrow.fx.coroutines.release
import arrow.fx.coroutines.resource
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.dao.DownloadDirname
import com.hippo.ehviewer.dao.DownloadInfo
import com.hippo.ehviewer.dao.DownloadLabel
@@ -39,7 +38,15 @@ import splitties.arch.room.roomDb
object EhDB {
private val db = roomDb<EhDatabase>("eh.db")
suspend fun getAllDownloadInfo() = db.downloadsDao().list().onEach {
private suspend fun putGalleryInfo(galleryInfo: BaseGalleryInfo) {
db.galleryDao().upsert(galleryInfo)
}
private suspend fun deleteGalleryInfo(galleryInfo: BaseGalleryInfo) {
runCatching { db.galleryDao().delete(galleryInfo) }
}
suspend fun getAllDownloadInfo() = db.downloadsDao().joinList().onEach {
if (it.state == DownloadInfo.STATE_WAIT || it.state == DownloadInfo.STATE_DOWNLOAD) {
it.state = DownloadInfo.STATE_NONE
}
@@ -47,28 +54,27 @@ object EhDB {
suspend fun updateDownloadInfo(downloadInfo: List<DownloadInfo>) {
val dao = db.downloadsDao()
dao.update(downloadInfo)
dao.update(downloadInfo.map(DownloadInfo::downloadInfo))
}
suspend fun putDownloadInfo(downloadInfo: DownloadInfo) {
db.downloadsDao().run {
if (load(downloadInfo.gid) != null) {
update(downloadInfo)
} else {
insert(downloadInfo)
}
}
putGalleryInfo(downloadInfo.galleryInfo)
db.downloadsDao().upsert(downloadInfo.downloadInfo)
}
suspend fun removeDownloadInfo(downloadInfo: DownloadInfo) {
val dao = db.downloadsDao()
dao.delete(downloadInfo)
dao.delete(downloadInfo.downloadInfo)
dao.fill(downloadInfo.position)
deleteGalleryInfo(downloadInfo.galleryInfo)
}
suspend fun removeDownloadInfo(downloadInfo: List<DownloadInfo>) {
val dao = db.downloadsDao()
dao.delete(downloadInfo)
downloadInfo.forEach {
dao.delete(it.downloadInfo)
deleteGalleryInfo(it.galleryInfo)
}
dao.fill(downloadInfo.first().position, downloadInfo.size)
}
@@ -80,13 +86,7 @@ object EhDB {
suspend fun putDownloadDirname(gid: Long, dirname: String) {
val dao = db.downloadDirnameDao()
var raw = dao.load(gid)
if (raw != null) {
dao.update(raw.copy(dirname = dirname))
} else {
raw = DownloadDirname(gid, dirname)
dao.insert(raw)
}
dao.upsert(DownloadDirname(gid, dirname))
}
suspend fun removeDownloadDirname(gid: Long) {
@@ -120,14 +120,14 @@ object EhDB {
dao.fill(raw.position)
}
suspend fun removeLocalFavorites(gid: Long) {
db.localFavoritesDao().deleteByKey(gid)
suspend fun removeLocalFavorites(galleryInfo: BaseGalleryInfo) {
db.localFavoritesDao().deleteByKey(galleryInfo.gid)
deleteGalleryInfo(galleryInfo)
}
suspend fun removeLocalFavorites(gidArray: LongArray) {
val dao = db.localFavoritesDao()
for (gid in gidArray) {
dao.deleteByKey(gid)
suspend fun removeLocalFavorites(galleryInfoList: List<BaseGalleryInfo>) {
galleryInfoList.forEach {
removeLocalFavorites(it)
}
}
@@ -136,24 +136,19 @@ object EhDB {
return dao.contains(gid)
}
suspend fun putLocalFavorites(galleryInfo: GalleryInfo) {
val dao = db.localFavoritesDao()
if (null == dao.load(galleryInfo.gid)) {
val info: LocalFavoriteInfo
if (galleryInfo is LocalFavoriteInfo) {
info = galleryInfo
} else {
info = LocalFavoriteInfo(galleryInfo)
info.time = System.currentTimeMillis()
}
dao.insert(info)
suspend fun putLocalFavorites(galleryInfo: BaseGalleryInfo) {
putGalleryInfo(galleryInfo)
db.localFavoritesDao().upsert(LocalFavoriteInfo(galleryInfo.gid))
}
suspend fun putLocalFavorites(galleryInfoList: List<BaseGalleryInfo>) {
galleryInfoList.forEach {
putLocalFavorites(it)
}
}
suspend fun putLocalFavorites(galleryInfoList: List<GalleryInfo>) {
for (gi in galleryInfoList) {
putLocalFavorites(gi)
}
private suspend fun importLocalFavorites(localFavorites: List<LocalFavoriteInfo>) {
db.localFavoritesDao().insertOrIgnore(localFavorites)
}
suspend fun getAllQuickSearch() = db.quickSearchDao().list()
@@ -179,57 +174,46 @@ object EhDB {
dao.update(quickSearchList)
}
val historyLazyList: PagingSource<Int, HistoryInfo>
get() = db.historyDao().listLazy()
val historyLazyList
get() = db.historyDao().joinListLazy()
val localFavLazyList: PagingSource<Int, LocalFavoriteInfo>
get() = db.localFavoritesDao().listLazy()
val localFavLazyList
get() = db.localFavoritesDao().joinListLazy()
val localFavCount: Flow<Int>
get() = db.localFavoritesDao().count()
fun searchLocalFav(keyword: String) = db.localFavoritesDao().listLazy("%$keyword%")
fun searchLocalFav(keyword: String) = db.localFavoritesDao().joinListLazy("%$keyword%")
suspend fun putHistoryInfo(galleryInfo: GalleryInfo) {
val dao = db.historyDao()
val info: HistoryInfo = if (galleryInfo is HistoryInfo) {
galleryInfo
} else {
HistoryInfo(galleryInfo)
}
info.time = System.currentTimeMillis()
if (null != dao.load(info.gid)) {
dao.update(info)
} else {
dao.insert(info)
}
suspend fun putHistoryInfo(galleryInfo: BaseGalleryInfo) {
putGalleryInfo(galleryInfo)
db.historyDao().upsert(HistoryInfo(galleryInfo.gid))
}
suspend fun modifyHistoryInfoFavslotNonRefresh(gid: Long, slot: Int) {
val dao = db.historyDao()
val dao = db.galleryDao()
dao.load(gid)?.let {
it.favoriteSlot = slot
dao.update(it)
}
}
private suspend fun putHistoryInfo(historyInfoList: List<HistoryInfo>) {
private suspend fun importHistoryInfo(historyInfoList: List<HistoryInfo>) {
val dao = db.historyDao()
for (info in historyInfoList) {
if (null == dao.load(info.gid)) {
dao.insert(info)
}
}
dao.insertOrIgnore(historyInfoList)
}
suspend fun deleteHistoryInfo(info: HistoryInfo) {
suspend fun deleteHistoryInfo(galleryInfo: BaseGalleryInfo) {
val dao = db.historyDao()
dao.delete(info)
dao.deleteByKey(galleryInfo.gid)
deleteGalleryInfo(galleryInfo)
}
suspend fun clearHistoryInfo() {
val dao = db.historyDao()
val historyList = dao.list()
dao.deleteAll()
historyList.forEach { runCatching { db.galleryDao().deleteByKey(it.gid) } }
}
suspend fun getAllFilter() = db.filterDao().list()
@@ -262,14 +246,14 @@ object EhDB {
it.close()
context.deleteDatabase(ehExportName)
} use { newDb ->
db.galleryDao().list().let { newDb.galleryDao().insert(it) }
db.downloadsDao().list().forEach { newDb.downloadsDao().insert(it) }
db.downloadLabelDao().list().forEach { newDb.downloadLabelDao().insert(it) }
db.downloadDirnameDao().list().forEach { newDb.downloadDirnameDao().insert(it) }
db.historyDao().list().forEach { newDb.historyDao().insert(it) }
db.quickSearchDao().list().forEach { newDb.quickSearchDao().insert(it) }
db.localFavoritesDao().list().forEach { newDb.localFavoritesDao().insert(it) }
db.filterDao().list().forEach { newDb.filterDao().insert(it) }
db.galleryDao().list().let { newDb.galleryDao().insertOrIgnore(it) }
db.downloadsDao().list().let { newDb.downloadsDao().insert(it) }
db.downloadLabelDao().list().let { newDb.downloadLabelDao().insert(it) }
db.downloadDirnameDao().list().let { newDb.downloadDirnameDao().insert(it) }
db.historyDao().list().let { newDb.historyDao().insertOrIgnore(it) }
db.quickSearchDao().list().let { newDb.quickSearchDao().insert(it) }
db.localFavoritesDao().list().let { newDb.localFavoritesDao().insertOrIgnore(it) }
db.filterDao().list().let { newDb.filterDao().insert(it) }
newDb.close()
val dbFile = context.getDatabasePath(ehExportName)
context.contentResolver.openFileDescriptor(uri, "rw")!!.use { toFd ->
@@ -290,14 +274,14 @@ object EhDB {
context.deleteDatabase(tempDBName)
} use { oldDB ->
runCatching {
db.galleryDao().insert(oldDB.galleryDao().list())
db.galleryDao().insertOrIgnore(oldDB.galleryDao().list())
}
runCatching {
val downloadLabelList = oldDB.downloadLabelDao().list()
DownloadManager.addDownloadLabel(downloadLabelList)
}
runCatching {
val downloadInfoList = oldDB.downloadsDao().list()
val downloadInfoList = oldDB.downloadsDao().joinList()
DownloadManager.addDownload(downloadInfoList, false)
}
runCatching {
@@ -307,7 +291,7 @@ object EhDB {
}
runCatching {
val historyInfoList = oldDB.historyDao().list()
putHistoryInfo(historyInfoList)
importHistoryInfo(historyInfoList)
}
runCatching {
val quickSearchList = oldDB.quickSearchDao().list()
@@ -319,8 +303,8 @@ object EhDB {
importQuickSearch(importList)
}
runCatching {
oldDB.localFavoritesDao().list().forEach {
putLocalFavorites(it)
oldDB.localFavoritesDao().list().let {
importLocalFavorites(it)
}
}
runCatching {
@@ -20,6 +20,7 @@ import arrow.fx.coroutines.parMap
import arrow.fx.coroutines.parZip
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.exception.EhException
import com.hippo.ehviewer.client.exception.InsufficientFundsException
@@ -456,7 +457,7 @@ object EhEngine {
}
}.executeAndParsingWith(GalleryListParser::parse).apply { fillGalleryList(galleryInfoList, EhUrl.imageSearchUrl, true) }
private suspend fun fillGalleryList(list: MutableList<GalleryInfo>, url: String, filter: Boolean) {
private suspend fun fillGalleryList(list: MutableList<BaseGalleryInfo>, url: String, filter: Boolean) {
// Filter title and uploader
if (filter) list.removeAllSuspend { EhFilter.filterTitle(it) || EhFilter.filterUploader(it) }
@@ -0,0 +1,14 @@
package com.hippo.ehviewer.client.data
interface AbstractDownloadInfo {
var state: Int
var legacy: Int
var time: Long
var label: String?
var position: Int
var speed: Long
var remaining: Long
var finished: Int
var downloaded: Int
var total: Int
}
@@ -1,23 +0,0 @@
package com.hippo.ehviewer.client.data
interface AbstractGalleryInfo {
var gid: Long
var token: String?
var title: String?
var titleJpn: String?
var thumbKey: String?
var category: Int
var posted: String?
var uploader: String?
var disowned: Boolean
var rating: Float
var rated: Boolean
var simpleTags: ArrayList<String>?
var pages: Int
var thumbWidth: Int
var thumbHeight: Int
var simpleLanguage: String?
var favoriteSlot: Int
var favoriteName: String?
var favoriteNote: String?
}
@@ -15,13 +15,16 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.NOT_FAVORITED
import kotlinx.parcelize.Parcelize
@Parcelize
@Entity(tableName = "GALLERIES")
open class BaseGalleryInfo(
@PrimaryKey
@ColumnInfo(name = "GID")
@@ -72,7 +75,7 @@ open class BaseGalleryInfo(
@ColumnInfo(name = "SIMPLE_LANGUAGE")
override var simpleLanguage: String? = null,
@Ignore
@ColumnInfo(name = "FAVORITE_SLOT")
override var favoriteSlot: Int = NOT_FAVORITED,
@Ignore
@@ -80,4 +83,6 @@ open class BaseGalleryInfo(
@Ignore
override var favoriteNote: String? = null,
) : GalleryInfo
) : GalleryInfo, Parcelable {
constructor() : this(0)
}
@@ -15,6 +15,7 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.S_LANGS
import kotlinx.parcelize.Parcelize
@@ -37,14 +38,14 @@ private val LANGUAGES = arrayOf(
@Parcelize
class GalleryDetail(
val galleryInfo: GalleryInfo = BaseGalleryInfo(),
val galleryInfo: BaseGalleryInfo = BaseGalleryInfo(),
var apiUid: Long = -1L,
var apiKey: String? = null,
var torrentCount: Int = 0,
var torrentUrl: String? = null,
var archiveUrl: String? = null,
var parent: String? = null,
var newerVersions: ArrayList<GalleryInfo> = ArrayList(),
var newerVersions: ArrayList<BaseGalleryInfo> = ArrayList(),
var visible: String? = null,
var language: String? = null,
var size: String? = null,
@@ -54,7 +55,7 @@ class GalleryDetail(
var comments: GalleryCommentList,
val previewPages: Int,
val previewList: List<GalleryPreview>,
) : AbstractGalleryInfo by galleryInfo, GalleryInfo {
) : GalleryInfo by galleryInfo, Parcelable {
override fun generateSLang() {
val index = LANGUAGES.indexOf(language)
if (index != -1) simpleLanguage = S_LANGS[index]
@@ -15,10 +15,29 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import java.util.regex.Pattern
interface GalleryInfo : AbstractGalleryInfo, Parcelable {
interface GalleryInfo {
var gid: Long
var token: String?
var title: String?
var titleJpn: String?
var thumbKey: String?
var category: Int
var posted: String?
var uploader: String?
var disowned: Boolean
var rating: Float
var rated: Boolean
var simpleTags: ArrayList<String>?
var pages: Int
var thumbWidth: Int
var thumbHeight: Int
var simpleLanguage: String?
var favoriteSlot: Int
var favoriteName: String?
var favoriteNote: String?
fun generateSLang() {
simpleLanguage = simpleTags?.let { generateSLangFromTags(it) }
?: title?.let { generateSLangFromTitle(it) }
@@ -17,7 +17,7 @@ package com.hippo.ehviewer.client.parser
import android.util.Log
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.LOCAL_FAVORITED
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.NOT_FAVORITED
import com.hippo.ehviewer.client.exception.ParseException
@@ -120,8 +120,8 @@ object GalleryListParser {
var prev: String? = null
var next: String? = null
var noWatchedTags = false
val galleryInfoList = mutableListOf<GalleryInfo>()
val galleryInfoList = mutableListOf<BaseGalleryInfo>()
}
}
private external fun parseGalleryInfo(e: String): GalleryInfo
private external fun parseGalleryInfo(e: String): BaseGalleryInfo
@@ -1,43 +0,0 @@
package com.hippo.ehviewer.dao
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.hippo.ehviewer.client.data.BaseGalleryInfo
@Entity(tableName = "GALLERIES")
data class CommonGalleryInfo(
@PrimaryKey
@ColumnInfo(name = "GID")
override var gid: Long,
@ColumnInfo(name = "TOKEN")
override var token: String?,
@ColumnInfo(name = "TITLE")
override var title: String?,
@ColumnInfo(name = "TITLE_JPN")
override var titleJpn: String?,
@ColumnInfo(name = "THUMB")
override var thumbKey: String?,
@ColumnInfo(name = "CATEGORY")
override var category: Int = 0,
@ColumnInfo(name = "POSTED")
override var posted: String?,
@ColumnInfo(name = "UPLOADER")
override var uploader: String?,
@ColumnInfo(name = "RATING")
override var rating: Float,
@ColumnInfo(name = "SIMPLE_LANGUAGE")
override var simpleLanguage: String?,
@ColumnInfo(name = "FAVORITE_SLOT")
override var favoriteSlot: Int,
) : BaseGalleryInfo()
@@ -9,6 +9,7 @@ import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.room.migration.AutoMigrationSpec
import androidx.sqlite.db.SupportSQLiteDatabase
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.NOT_FAVORITED
@DeleteTable(tableName = "BOOKMARKS")
@@ -56,6 +57,36 @@ class AddGalleryTable : AutoMigrationSpec {
}
}
@DeleteColumn(tableName = "HISTORY", columnName = "TOKEN")
@DeleteColumn(tableName = "HISTORY", columnName = "TITLE")
@DeleteColumn(tableName = "HISTORY", columnName = "TITLE_JPN")
@DeleteColumn(tableName = "HISTORY", columnName = "THUMB")
@DeleteColumn(tableName = "HISTORY", columnName = "CATEGORY")
@DeleteColumn(tableName = "HISTORY", columnName = "POSTED")
@DeleteColumn(tableName = "HISTORY", columnName = "UPLOADER")
@DeleteColumn(tableName = "HISTORY", columnName = "RATING")
@DeleteColumn(tableName = "HISTORY", columnName = "SIMPLE_LANGUAGE")
@DeleteColumn(tableName = "HISTORY", columnName = "FAVORITE_SLOT")
@DeleteColumn(tableName = "LOCAL_FAVORITES", columnName = "TOKEN")
@DeleteColumn(tableName = "LOCAL_FAVORITES", columnName = "TITLE")
@DeleteColumn(tableName = "LOCAL_FAVORITES", columnName = "TITLE_JPN")
@DeleteColumn(tableName = "LOCAL_FAVORITES", columnName = "THUMB")
@DeleteColumn(tableName = "LOCAL_FAVORITES", columnName = "CATEGORY")
@DeleteColumn(tableName = "LOCAL_FAVORITES", columnName = "POSTED")
@DeleteColumn(tableName = "LOCAL_FAVORITES", columnName = "UPLOADER")
@DeleteColumn(tableName = "LOCAL_FAVORITES", columnName = "RATING")
@DeleteColumn(tableName = "LOCAL_FAVORITES", columnName = "SIMPLE_LANGUAGE")
@DeleteColumn(tableName = "DOWNLOADS", columnName = "TOKEN")
@DeleteColumn(tableName = "DOWNLOADS", columnName = "TITLE")
@DeleteColumn(tableName = "DOWNLOADS", columnName = "TITLE_JPN")
@DeleteColumn(tableName = "DOWNLOADS", columnName = "THUMB")
@DeleteColumn(tableName = "DOWNLOADS", columnName = "CATEGORY")
@DeleteColumn(tableName = "DOWNLOADS", columnName = "POSTED")
@DeleteColumn(tableName = "DOWNLOADS", columnName = "UPLOADER")
@DeleteColumn(tableName = "DOWNLOADS", columnName = "RATING")
@DeleteColumn(tableName = "DOWNLOADS", columnName = "SIMPLE_LANGUAGE")
class GalleryTableMigration : AutoMigrationSpec
class ThumbKeyMigration : AutoMigrationSpec {
override fun onPostMigrate(db: SupportSQLiteDatabase) {
val needMigrationTables = arrayOf(
@@ -77,8 +108,8 @@ class ThumbKeyMigration : AutoMigrationSpec {
}
@Database(
entities = [CommonGalleryInfo::class, DownloadInfo::class, DownloadLabel::class, DownloadDirname::class, Filter::class, HistoryInfo::class, LocalFavoriteInfo::class, QuickSearch::class],
version = 13,
entities = [BaseGalleryInfo::class, DownloadEntity::class, DownloadLabel::class, DownloadDirname::class, Filter::class, HistoryInfo::class, LocalFavoriteInfo::class, QuickSearch::class],
version = 14,
exportSchema = true,
autoMigrations = [
AutoMigration(
@@ -123,6 +154,11 @@ class ThumbKeyMigration : AutoMigrationSpec {
to = 13,
spec = AddGalleryTable::class,
),
AutoMigration(
from = 13,
to = 14,
spec = GalleryTableMigration::class,
),
],
)
@TypeConverters(FilterModeConverter::class)
@@ -3,18 +3,18 @@ package com.hippo.ehviewer.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import androidx.room.Upsert
@Dao
interface DownloadDirnameDao {
@Query("SELECT * FROM DOWNLOAD_DIRNAME WHERE GID = :gid")
suspend fun load(gid: Long): DownloadDirname?
@Update
suspend fun update(downloadDirname: DownloadDirname)
@Upsert
suspend fun upsert(downloadDirname: DownloadDirname)
@Insert
suspend fun insert(t: DownloadDirname): Long
suspend fun insert(downloadDirnameList: List<DownloadDirname>)
@Query("DELETE FROM DOWNLOAD_DIRNAME WHERE GID = :gid")
suspend fun deleteByKey(gid: Long)
@@ -1,50 +1,61 @@
package com.hippo.ehviewer.dao
import androidx.room.ColumnInfo
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Ignore
import com.hippo.ehviewer.client.data.AbstractGalleryInfo
import androidx.room.PrimaryKey
import androidx.room.Relation
import com.hippo.ehviewer.client.data.AbstractDownloadInfo
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo
import java.time.Instant
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
@Entity(tableName = "DOWNLOADS")
class DownloadInfo(
@Ignore
val galleryInfo: GalleryInfo = BaseGalleryInfo(),
) : BaseGalleryInfo(), AbstractGalleryInfo by galleryInfo {
constructor() : this(galleryInfo = BaseGalleryInfo())
@Entity(tableName = "DOWNLOADS", foreignKeys = [ForeignKey(BaseGalleryInfo::class, ["GID"], ["GID"])])
class DownloadEntity(
@PrimaryKey
@ColumnInfo(name = "GID")
var gid: Long,
@ColumnInfo(name = "STATE")
var state = 0
override var state: Int = 0,
@ColumnInfo(name = "LEGACY")
var legacy = 0
override var legacy: Int = 0,
@ColumnInfo(name = "TIME")
var time: Long = 0
override var time: Long = Instant.now().toEpochMilli(),
@ColumnInfo(name = "LABEL")
var label: String? = null
override var label: String? = null,
@ColumnInfo(name = "POSITION")
var position: Int = 0
override var position: Int = 0,
) : AbstractDownloadInfo {
@Ignore
override var speed: Long = 0
@Ignore
var speed: Long = 0
override var remaining: Long = 0
@Ignore
var remaining: Long = 0
override var finished = 0
@Ignore
var finished = 0
override var downloaded = 0
@Ignore
var downloaded = 0
override var total = 0
}
@Ignore
var total = 0
data class DownloadInfo(
@Relation(parentColumn = "GID", entityColumn = "GID")
val galleryInfo: BaseGalleryInfo,
@Embedded
val downloadInfo: DownloadEntity = DownloadEntity(galleryInfo.gid),
) : GalleryInfo by galleryInfo, AbstractDownloadInfo by downloadInfo {
companion object {
const val STATE_INVALID = -1
const val STATE_NONE = 0
@@ -4,34 +4,34 @@ import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import androidx.room.Upsert
@Dao
interface DownloadsDao {
@Query("SELECT * FROM DOWNLOADS ORDER BY POSITION DESC")
suspend fun list(): List<DownloadInfo>
suspend fun list(): List<DownloadEntity>
@Query("SELECT * FROM DOWNLOADS ORDER BY POSITION DESC LIMIT :limit OFFSET :offset")
suspend fun list(offset: Int, limit: Int): List<DownloadInfo>
@Query("SELECT * FROM DOWNLOADS WHERE GID = :gid")
suspend fun load(gid: Long): DownloadInfo?
@Transaction
@Query("SELECT * FROM DOWNLOADS ORDER BY POSITION DESC")
suspend fun joinList(): List<DownloadInfo>
@Query("UPDATE DOWNLOADS SET POSITION = POSITION - :offset WHERE POSITION > :position")
suspend fun fill(position: Int, offset: Int = 1)
@Update
suspend fun update(downloadInfo: List<DownloadInfo>)
@Update
suspend fun update(downloadInfo: DownloadInfo)
suspend fun update(downloadInfo: List<DownloadEntity>)
@Insert
suspend fun insert(t: DownloadInfo): Long
suspend fun insert(downloadInfo: List<DownloadEntity>)
@Upsert
suspend fun upsert(t: DownloadEntity)
@Delete
suspend fun delete(downloadInfo: DownloadInfo)
suspend fun delete(downloadInfo: DownloadEntity)
@Delete
suspend fun delete(downloadInfo: List<DownloadInfo>)
suspend fun delete(downloadInfo: List<DownloadEntity>)
}
@@ -17,6 +17,9 @@ interface FilterDao {
@Insert
suspend fun insert(t: Filter): Long
@Insert
suspend fun insert(filters: List<Filter>)
@Delete
suspend fun delete(filter: Filter)
@@ -1,22 +0,0 @@
package com.hippo.ehviewer.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
@Dao
interface GalleryDao {
@Query("SELECT * FROM GALLERIES WHERE GID = :gid")
suspend fun load(gid: Long): CommonGalleryInfo?
@Query("SELECT * FROM GALLERIES")
suspend fun list(): List<CommonGalleryInfo>
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(galleryInfoList: List<CommonGalleryInfo>)
@Update
suspend fun update(galleryInfo: CommonGalleryInfo)
}
@@ -0,0 +1,34 @@
package com.hippo.ehviewer.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import androidx.room.Upsert
import com.hippo.ehviewer.client.data.BaseGalleryInfo
@Dao
interface GalleryDao {
@Query("SELECT * FROM GALLERIES WHERE GID = :gid")
suspend fun load(gid: Long): BaseGalleryInfo?
@Query("SELECT * FROM GALLERIES")
suspend fun list(): List<BaseGalleryInfo>
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertOrIgnore(galleryInfoList: List<BaseGalleryInfo>)
@Update
suspend fun update(galleryInfo: BaseGalleryInfo)
@Upsert
suspend fun upsert(galleryInfo: BaseGalleryInfo)
@Delete
suspend fun delete(galleryInfo: BaseGalleryInfo)
@Query("DELETE FROM GALLERIES WHERE GID = :gid")
suspend fun deleteByKey(gid: Long)
}
@@ -2,30 +2,30 @@ package com.hippo.ehviewer.dao
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import androidx.room.RewriteQueriesToDropUnusedColumns
import androidx.room.Upsert
import com.hippo.ehviewer.client.data.BaseGalleryInfo
@Dao
interface HistoryDao {
@Query("SELECT * FROM HISTORY WHERE GID = :gid")
suspend fun load(gid: Long): HistoryInfo?
@Query("SELECT * FROM HISTORY ORDER BY TIME DESC")
suspend fun list(): List<HistoryInfo>
@Query("SELECT * FROM HISTORY ORDER BY TIME DESC")
fun listLazy(): PagingSource<Int, HistoryInfo>
@RewriteQueriesToDropUnusedColumns
@Query("SELECT * FROM HISTORY JOIN GALLERIES USING(GID) ORDER BY TIME DESC")
fun joinListLazy(): PagingSource<Int, BaseGalleryInfo>
@Update
suspend fun update(historyInfo: HistoryInfo)
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertOrIgnore(historyInfoList: List<HistoryInfo>)
@Insert
suspend fun insert(t: HistoryInfo): Long
@Upsert
suspend fun upsert(historyInfo: HistoryInfo)
@Delete
suspend fun delete(historyInfo: HistoryInfo)
@Query("DELETE FROM HISTORY WHERE GID = :gid")
suspend fun deleteByKey(gid: Long)
@Query("DELETE FROM HISTORY")
suspend fun deleteAll()
@@ -1,24 +1,9 @@
package com.hippo.ehviewer.dao
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import com.hippo.ehviewer.client.data.AbstractGalleryInfo
import androidx.room.ForeignKey
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.NOT_FAVORITED
import java.time.Instant
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
@Entity(tableName = "HISTORY")
class HistoryInfo(
@Ignore
val galleryInfo: GalleryInfo = BaseGalleryInfo(),
) : BaseGalleryInfo(), AbstractGalleryInfo by galleryInfo {
constructor() : this(galleryInfo = BaseGalleryInfo())
@ColumnInfo(name = "TIME")
var time: Long = 0
@ColumnInfo(name = "FAVORITE_SLOT")
override var favoriteSlot: Int = NOT_FAVORITED
}
@Entity(tableName = "HISTORY", foreignKeys = [ForeignKey(BaseGalleryInfo::class, ["GID"], ["GID"])])
class HistoryInfo(gid: Long, time: Long = Instant.now().toEpochMilli()) : TimeInfo(gid, time)
@@ -1,24 +1,9 @@
package com.hippo.ehviewer.dao
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import com.hippo.ehviewer.client.data.AbstractGalleryInfo
import androidx.room.ForeignKey
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.LOCAL_FAVORITED
import java.time.Instant
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
@Entity(tableName = "LOCAL_FAVORITES")
class LocalFavoriteInfo(
@Ignore
val galleryInfo: GalleryInfo = BaseGalleryInfo(),
) : BaseGalleryInfo(), AbstractGalleryInfo by galleryInfo {
constructor() : this(galleryInfo = BaseGalleryInfo())
@ColumnInfo(name = "TIME")
var time: Long = 0
@Ignore
override var favoriteSlot = LOCAL_FAVORITED
}
@Entity(tableName = "LOCAL_FAVORITES", foreignKeys = [ForeignKey(BaseGalleryInfo::class, ["GID"], ["GID"])])
class LocalFavoriteInfo(gid: Long = 0, time: Long = Instant.now().toEpochMilli()) : TimeInfo(gid, time)
@@ -3,7 +3,11 @@ package com.hippo.ehviewer.dao
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.RewriteQueriesToDropUnusedColumns
import androidx.room.Upsert
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import kotlinx.coroutines.flow.Flow
@Dao
@@ -14,20 +18,22 @@ interface LocalFavoritesDao {
@Query("SELECT * FROM LOCAL_FAVORITES ORDER BY TIME DESC")
suspend fun list(): List<LocalFavoriteInfo>
@Query("SELECT * FROM LOCAL_FAVORITES ORDER BY TIME DESC")
fun listLazy(): PagingSource<Int, LocalFavoriteInfo>
@RewriteQueriesToDropUnusedColumns
@Query("SELECT * FROM LOCAL_FAVORITES JOIN GALLERIES USING(GID) ORDER BY TIME DESC")
fun joinListLazy(): PagingSource<Int, BaseGalleryInfo>
@Query("SELECT * FROM LOCAL_FAVORITES WHERE TITLE LIKE :title ORDER BY TIME DESC")
fun listLazy(title: String): PagingSource<Int, LocalFavoriteInfo>
@Query("SELECT * FROM LOCAL_FAVORITES WHERE GID = :gid")
suspend fun load(gid: Long): LocalFavoriteInfo?
@RewriteQueriesToDropUnusedColumns
@Query("SELECT * FROM LOCAL_FAVORITES JOIN GALLERIES USING(GID) WHERE TITLE LIKE :title ORDER BY TIME DESC")
fun joinListLazy(title: String): PagingSource<Int, BaseGalleryInfo>
@Query("SELECT EXISTS(SELECT * FROM LOCAL_FAVORITES WHERE GID = :gid)")
suspend fun contains(gid: Long): Boolean
@Insert
suspend fun insert(t: LocalFavoriteInfo): Long
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertOrIgnore(localFavorites: List<LocalFavoriteInfo>)
@Upsert
suspend fun upsert(t: LocalFavoriteInfo)
@Query("DELETE FROM LOCAL_FAVORITES WHERE GID = :gid")
suspend fun deleteByKey(gid: Long)
@@ -0,0 +1,13 @@
package com.hippo.ehviewer.dao
import androidx.room.ColumnInfo
import androidx.room.PrimaryKey
open class TimeInfo(
@PrimaryKey
@ColumnInfo(name = "GID")
var gid: Long,
@ColumnInfo(name = "TIME")
val time: Long,
)
@@ -21,7 +21,7 @@ import android.util.SparseLongArray
import com.google.android.material.math.MathUtils
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.dao.DownloadInfo
import com.hippo.ehviewer.dao.DownloadLabel
import com.hippo.ehviewer.image.Image
@@ -175,7 +175,7 @@ object DownloadManager : OnSpiderListener {
}
}
suspend fun startDownload(galleryInfo: GalleryInfo, label: String?) {
suspend fun startDownload(galleryInfo: BaseGalleryInfo, label: String?) {
if (mCurrentTask != null && mCurrentTask!!.gid == galleryInfo.gid) {
// It is current task
return
@@ -206,7 +206,6 @@ object DownloadManager : OnSpiderListener {
info = DownloadInfo(galleryInfo)
info.label = label
info.state = DownloadInfo.STATE_WAIT
info.time = System.currentTimeMillis()
info.position = allInfoList.size
// Add to label download list
@@ -236,7 +235,7 @@ object DownloadManager : OnSpiderListener {
launchIO {
// Add it to history
EhDB.putHistoryInfo(info)
EhDB.putHistoryInfo(info.galleryInfo)
}
}
}
@@ -371,7 +370,7 @@ object DownloadManager : OnSpiderListener {
}
}
suspend fun addDownload(galleryInfo: GalleryInfo, label: String?) {
suspend fun addDownload(galleryInfo: BaseGalleryInfo, label: String?) {
if (containDownloadInfo(galleryInfo.gid)) {
// Contain
return
@@ -381,7 +380,6 @@ object DownloadManager : OnSpiderListener {
val info = DownloadInfo(galleryInfo)
info.label = label
info.state = DownloadInfo.STATE_NONE
info.time = System.currentTimeMillis()
info.position = allInfoList.size
// Add to label download list
@@ -31,7 +31,7 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.hippo.ehviewer.R
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.dao.DownloadInfo
import com.hippo.ehviewer.ui.MainActivity
import com.hippo.ehviewer.ui.scene.DownloadsScene
@@ -96,7 +96,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener, CoroutineSc
private suspend fun handleIntent(intent: Intent?) {
when (intent?.action) {
ACTION_START -> {
val gi = intent.getParcelableExtraCompat<GalleryInfo>(KEY_GALLERY_INFO)
val gi = intent.getParcelableExtraCompat<BaseGalleryInfo>(KEY_GALLERY_INFO)
val label = intent.getStringExtra(KEY_LABEL)
if (gi != null) {
deferredMgr.await().startDownload(gi, label)
@@ -36,6 +36,7 @@ import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.LOCAL_FAVORITED
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.NOT_FAVORITED
@@ -62,14 +63,14 @@ import rikka.core.util.ContextUtils.requireActivity
import splitties.init.appCtx
object CommonOperations {
fun startDownload(activity: MainActivity?, galleryInfo: GalleryInfo, forceDefault: Boolean) {
fun startDownload(activity: MainActivity?, galleryInfo: BaseGalleryInfo, forceDefault: Boolean) {
startDownload(activity!!, listOf(galleryInfo), forceDefault)
}
@OptIn(DelicateCoroutinesApi::class)
fun startDownload(
activity: MainActivity,
galleryInfos: List<GalleryInfo>,
galleryInfos: List<BaseGalleryInfo>,
forceDefault: Boolean,
) {
launchNow {
@@ -82,11 +83,11 @@ object CommonOperations {
private fun doStartDownload(
activity: MainActivity,
galleryInfos: List<GalleryInfo>,
galleryInfos: List<BaseGalleryInfo>,
forceDefault: Boolean,
) {
val toStart = LongList()
val toAdd: MutableList<GalleryInfo> = ArrayList()
val toAdd: MutableList<BaseGalleryInfo> = ArrayList()
for (gi in galleryInfos) {
if (DownloadManager.containDownloadInfo(gi.gid)) {
toStart.add(gi.gid)
@@ -194,7 +195,7 @@ suspend fun keepNoMediaFileStatus() {
}
}
suspend fun DialogState.addToFavorites(galleryInfo: GalleryInfo): Boolean {
suspend fun DialogState.addToFavorites(galleryInfo: BaseGalleryInfo): Boolean {
val localFavorited = EhDB.containLocalFavorites(galleryInfo.gid)
val localFav = if (localFavorited) {
Icons.Default.Favorite
@@ -219,7 +220,7 @@ suspend fun DialogState.addToFavorites(galleryInfo: GalleryInfo): Boolean {
}
private suspend fun doAddToFavorites(
galleryInfo: GalleryInfo,
galleryInfo: BaseGalleryInfo,
slot: Int = NOT_FAVORITED,
note: String = "",
localFavorited: Boolean = true,
@@ -229,14 +230,14 @@ private suspend fun doAddToFavorites(
if (galleryInfo.favoriteSlot > LOCAL_FAVORITED) {
EhEngine.addFavorites(galleryInfo.gid, galleryInfo.token)
} else if (localFavorited) {
EhDB.removeLocalFavorites(galleryInfo.gid)
EhDB.removeLocalFavorites(galleryInfo)
}
false
}
LOCAL_FAVORITED -> {
if (localFavorited) {
EhDB.removeLocalFavorites(galleryInfo.gid)
EhDB.removeLocalFavorites(galleryInfo)
} else {
EhDB.putLocalFavorites(galleryInfo)
}
@@ -265,9 +266,9 @@ private suspend fun doAddToFavorites(
return add
}
suspend fun removeFromFavorites(galleryInfo: GalleryInfo) = doAddToFavorites(galleryInfo)
suspend fun removeFromFavorites(galleryInfo: BaseGalleryInfo) = doAddToFavorites(galleryInfo)
fun Context.navToReader(info: GalleryInfo, page: Int = -1) {
fun Context.navToReader(info: BaseGalleryInfo, page: Int = -1) {
val intent = Intent(this, ReaderActivity::class.java)
intent.action = ReaderActivity.ACTION_EH
intent.putExtra(ReaderActivity.KEY_GALLERY_INFO, info)
@@ -275,7 +276,7 @@ fun Context.navToReader(info: GalleryInfo, page: Int = -1) {
startActivity(intent)
}
suspend fun DialogState.doGalleryInfoAction(info: GalleryInfo, context: Context) {
suspend fun DialogState.doGalleryInfoAction(info: BaseGalleryInfo, context: Context) {
val downloaded = DownloadManager.getDownloadState(info.gid) != DownloadInfo.STATE_INVALID
val favourite = info.favoriteSlot != NOT_FAVORITED
val selected = if (!downloaded) {
@@ -40,13 +40,13 @@ fun Context.openBrowser(url: String) {
fun Context.jumpToReaderByPage(url: String, detail: GalleryDetail): Boolean {
GalleryPageUrlParser.parse(url)?.let {
if (it.gid == detail.gid) {
navToReader(detail, it.page)
navToReader(detail.galleryInfo, it.page)
return true
}
}
if (url.startsWith("#c")) {
runCatching {
navToReader(detail, url.replace("#c", "").toInt() - 1)
navToReader(detail.galleryInfo, url.replace("#c", "").toInt() - 1)
return true
}
}
@@ -536,7 +536,7 @@ class DownloadsScene :
if (position < 0 || position >= list.size) {
return false
}
context.navToReader(list[position])
context.navToReader(list[position].galleryInfo)
return true
}
@@ -844,14 +844,14 @@ class DownloadsScene :
GalleryDetailScene.KEY_ACTION,
GalleryDetailScene.ACTION_GALLERY_INFO,
)
args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, list[index])
args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, list[index].galleryInfo)
navAnimated(R.id.galleryDetailScene, args)
}
binding.start -> {
val intent = Intent(activity, DownloadService::class.java)
intent.action = DownloadService.ACTION_START
intent.putExtra(DownloadService.KEY_GALLERY_INFO, list[index])
intent.putExtra(DownloadService.KEY_GALLERY_INFO, list[index].galleryInfo)
ContextCompat.startForegroundService(activity, intent)
}
@@ -48,7 +48,6 @@ import androidx.lifecycle.viewModelScope
import androidx.paging.LoadState
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import androidx.paging.PagingState
import androidx.paging.cachedIn
@@ -64,8 +63,8 @@ import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.FavListUrlBuilder
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.ehUrl
import com.hippo.ehviewer.databinding.SceneFavoritesBinding
import com.hippo.ehviewer.ui.CommonOperations
@@ -102,8 +101,8 @@ import java.util.Locale
class VMStorage : ViewModel() {
var urlBuilder = FavListUrlBuilder(favCat = Settings.recentFavCat)
private val cloudDataFlow = Pager(PagingConfig(25)) {
object : PagingSource<String, GalleryInfo>() {
override fun getRefreshKey(state: PagingState<String, GalleryInfo>): String? = null
object : PagingSource<String, BaseGalleryInfo>() {
override fun getRefreshKey(state: PagingState<String, BaseGalleryInfo>): String? = null
override suspend fun load(params: LoadParams<String>) = withIOContext {
when (params) {
is LoadParams.Prepend -> urlBuilder.setIndex(params.key, isNext = false)
@@ -182,8 +181,7 @@ class FavoritesScene : SearchBarScene() {
collectJob?.cancel()
collectJob = viewLifecycleOwner.lifecycleScope.launchIO {
vm.dataflow().collectLatest {
@Suppress("UNCHECKED_CAST")
mAdapter?.submitData(it as PagingData<GalleryInfo>)
mAdapter?.submitData(it)
}
}
mAdapter?.refresh()
@@ -483,8 +481,7 @@ class FavoritesScene : SearchBarScene() {
val info = takeCheckedInfo()
lifecycleScope.launchIO {
if (urlBuilder.favCat == FavListUrlBuilder.FAV_CAT_LOCAL) { // Delete local fav
val gidArray = info.map { it.gid }.toLongArray()
EhDB.removeLocalFavorites(gidArray)
EhDB.removeLocalFavorites(info)
} else {
val delList = info.map { it.gid to it.token!! }
EhEngine.addFavoritesRange(delList, -1)
@@ -503,8 +500,7 @@ class FavoritesScene : SearchBarScene() {
lifecycleScope.launchIO {
if (srcCat == FavListUrlBuilder.FAV_CAT_LOCAL) {
// Move from local to cloud
val gidArray = info.map { it.gid }.toLongArray()
EhDB.removeLocalFavorites(gidArray)
EhDB.removeLocalFavorites(info)
val galleryList = info.map { it.gid to it.token!! }
runCatching {
EhEngine.addFavoritesRange(galleryList, dstCat)
@@ -28,7 +28,7 @@ import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.Settings.detailSize
import com.hippo.ehviewer.Settings.thumbSizeDp
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.ui.legacy.AutoStaggeredGridLayoutManager
import com.hippo.ehviewer.ui.legacy.MarginItemDecoration
import com.hippo.ehviewer.ui.legacy.STRATEGY_MIN_SIZE
@@ -36,24 +36,24 @@ import com.hippo.ehviewer.ui.legacy.STRATEGY_SUITABLE_SIZE
import com.hippo.ehviewer.util.dp2px
import splitties.init.appCtx
private val diffCallback = object : DiffUtil.ItemCallback<GalleryInfo>() {
override fun areItemsTheSame(oldItem: GalleryInfo, newItem: GalleryInfo) = oldItem.gid == newItem.gid
override fun areContentsTheSame(oldItem: GalleryInfo, newItem: GalleryInfo) = oldItem.gid == newItem.gid
private val diffCallback = object : DiffUtil.ItemCallback<BaseGalleryInfo>() {
override fun areItemsTheSame(oldItem: BaseGalleryInfo, newItem: BaseGalleryInfo) = oldItem.gid == newItem.gid
override fun areContentsTheSame(oldItem: BaseGalleryInfo, newItem: BaseGalleryInfo) = oldItem.gid == newItem.gid
}
class GalleryAdapter(
private val recyclerView: RecyclerView,
private val showFavorite: Boolean,
private val onItemClick: (GalleryInfo) -> Unit,
private val onItemLongClick: (GalleryInfo) -> Unit,
) : PagingDataAdapter<GalleryInfo, GalleryHolder>(diffCallback) {
private val onItemClick: (BaseGalleryInfo) -> Unit,
private val onItemLongClick: (BaseGalleryInfo) -> Unit,
) : PagingDataAdapter<BaseGalleryInfo, GalleryHolder>(diffCallback) {
private val resources = recyclerView.context.resources
private val layoutManager: AutoStaggeredGridLayoutManager = AutoStaggeredGridLayoutManager(0, StaggeredGridLayoutManager.VERTICAL)
private val mPaddingTopSB: Int = resources.getDimensionPixelOffset(R.dimen.gallery_padding_top_search_bar)
private var mListDecoration: ItemDecoration? = null
private var mGirdDecoration: MarginItemDecoration? = null
private var mType = TYPE_INVALID
var tracker: GallerySelectionTracker<GalleryInfo>? = null
var tracker: GallerySelectionTracker<BaseGalleryInfo>? = null
var type: Int
get() = mType
@@ -110,6 +110,7 @@ import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhFilter.remember
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.GalleryComment
import com.hippo.ehviewer.client.data.GalleryDetail
import com.hippo.ehviewer.client.data.GalleryInfo
@@ -183,7 +184,7 @@ class GalleryDetailScene : BaseScene() {
private var mToken: String? = null
private var mPage = 0
private var composeBindingGI by mutableStateOf<GalleryInfo?>(null)
private var composeBindingGI by mutableStateOf<BaseGalleryInfo?>(null)
private var composeBindingGD by mutableStateOf<GalleryDetail?>(null)
private var readButtonText by mutableStateOf("")
private var downloadButtonText by mutableStateOf("")
@@ -637,7 +638,7 @@ class GalleryDetailScene : BaseScene() {
EhPreviewItem(
galleryPreview = it,
position = it.position,
onClick = { context?.navToReader(gd, it.position) },
onClick = { context?.navToReader(gd.galleryInfo, it.position) },
)
}
item(span = { GridItemSpan(maxLineSpan) }) {
@@ -787,7 +788,7 @@ class GalleryDetailScene : BaseScene() {
if (EhDownloadManager.getDownloadState(galleryDetail.gid) == DownloadInfo.STATE_INVALID) {
CommonOperations.startDownload(
activity as MainActivity,
galleryDetail,
galleryDetail.galleryInfo,
false,
)
} else {
@@ -838,7 +839,7 @@ class GalleryDetailScene : BaseScene() {
EhEngine.getGalleryDetail(url)
}.onSuccess { galleryDetail ->
galleryDetailCache.put(galleryDetail.gid, galleryDetail)
EhDB.putHistoryInfo(galleryDetail)
EhDB.putHistoryInfo(galleryDetail.galleryInfo)
if (Settings.preloadThumbAggressively) {
lifecycleScope.launchIO {
galleryDetail.previewList.forEach {
@@ -847,7 +848,7 @@ class GalleryDetailScene : BaseScene() {
}
}
composeBindingGD = galleryDetail
composeBindingGI = galleryDetail
composeBindingGI = galleryDetail.galleryInfo
updateDownloadState()
bindViewSecond()
}.onFailure {
@@ -873,7 +874,7 @@ class GalleryDetailScene : BaseScene() {
favoritesLock.withLock {
var remove = false
runCatching {
remove = !dialogState.addToFavorites(galleryDetail)
remove = !dialogState.addToFavorites(galleryDetail.galleryInfo)
if (remove) {
showTip(R.string.remove_from_favorite_success, LENGTH_SHORT)
} else {
@@ -947,9 +948,9 @@ class GalleryDetailScene : BaseScene() {
requireActivity().findViewById(R.id.snackbar),
getString(R.string.read_from, mPage),
Snackbar.LENGTH_LONG,
).setAction(R.string.read) { context?.navToReader(gd, mPage) }.show()
).setAction(R.string.read) { context?.navToReader(gd.galleryInfo, mPage) }.show()
}
composeBindingGI = gd
composeBindingGI = gd.galleryInfo
composeBindingGD = gd
updateDownloadText()
updateFavoriteDrawable()
@@ -65,7 +65,7 @@ import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.ListUrlBuilder
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_NORMAL
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_SUBSCRIPTION
@@ -123,8 +123,8 @@ import java.util.Locale
class VMStorage1 : ViewModel() {
var urlBuilder = ListUrlBuilder()
val dataFlow = Pager(PagingConfig(25)) {
object : PagingSource<String, GalleryInfo>() {
override fun getRefreshKey(state: PagingState<String, GalleryInfo>): String? = null
object : PagingSource<String, BaseGalleryInfo>() {
override fun getRefreshKey(state: PagingState<String, BaseGalleryInfo>): String? = null
override suspend fun load(params: LoadParams<String>) = withIOContext {
if (urlBuilder.mode == MODE_TOPLIST) {
// TODO: Since we know total pages, let pager support jump
@@ -72,7 +72,7 @@ class GalleryPreviewScreen : Fragment() {
setMD3Content {
val galleryDetail = remember { requireArguments().getParcelableCompat<GalleryDetail>(KEY_GALLERY_DETAIL)!! }
val context = LocalContext.current
fun onPreviewCLick(index: Int) = context.navToReader(galleryDetail, index)
fun onPreviewCLick(index: Int) = context.navToReader(galleryDetail.galleryInfo, index)
var toNextPage by rememberSaveable { mutableStateOf(requireArguments().getBoolean(KEY_NEXT_PAGE)) }
val scrollBehaviour = TopAppBarDefaults.pinnedScrollBehavior()
val columnCount = calculateSuitableSpanCount()
@@ -66,7 +66,7 @@ import com.google.android.material.shape.MaterialShapeDrawable
import com.hippo.ehviewer.BuildConfig
import com.hippo.ehviewer.R
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.databinding.ReaderActivityBinding
import com.hippo.ehviewer.gallery.ArchivePageLoader
import com.hippo.ehviewer.gallery.EhPageLoader
@@ -121,7 +121,7 @@ class ReaderActivity : EhActivity() {
private var mAction: String? = null
private var mFilename: String? = null
private var mUri: Uri? = null
private var mGalleryInfo: GalleryInfo? = null
private var mGalleryInfo: BaseGalleryInfo? = null
private var mPage: Int = 0
private var mCacheFileName: String? = null