diff --git a/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt index 2823b97b9..6d934330a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt @@ -83,6 +83,7 @@ class BackupRepository(private val db: MangaDatabase) { jo.put("url", url) jo.put("public_url", publicUrl) jo.put("rating", rating) + jo.put("nsfw", isNsfw) jo.put("cover_url", coverUrl) jo.put("large_cover_url", largeCoverUrl) jo.put("state", state) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt index 4a0e1c368..86b732b27 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt @@ -8,6 +8,7 @@ import org.koitharu.kotatsu.core.db.entity.TagEntity import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity import org.koitharu.kotatsu.favourites.data.FavouriteEntity import org.koitharu.kotatsu.history.data.HistoryEntity +import org.koitharu.kotatsu.utils.ext.getBooleanOrDefault import org.koitharu.kotatsu.utils.ext.getStringOrNull import org.koitharu.kotatsu.utils.ext.iterator import org.koitharu.kotatsu.utils.ext.map @@ -72,6 +73,7 @@ class RestoreRepository(private val db: MangaDatabase) { url = json.getString("url"), publicUrl = json.getStringOrNull("public_url").orEmpty(), rating = json.getDouble("rating").toFloat(), + isNsfw = json.getBooleanOrDefault("nsfw", false), coverUrl = json.getString("cover_url"), largeCoverUrl = json.getStringOrNull("large_cover_url"), state = json.getStringOrNull("state"), diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/DatabaseModule.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/DatabaseModule.kt index 59906c088..de6aead18 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/DatabaseModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/DatabaseModule.kt @@ -18,7 +18,8 @@ val databaseModule Migration3To4(), Migration4To5(), Migration5To6(), - Migration6To7() + Migration6To7(), + Migration7To8(), ).addCallback( DatabasePrePopulateCallback(androidContext().resources) ).build() 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 0090e416d..f0844571e 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 @@ -15,8 +15,8 @@ import org.koitharu.kotatsu.history.data.HistoryEntity entities = [ MangaEntity::class, TagEntity::class, HistoryEntity::class, MangaTagsEntity::class, FavouriteCategoryEntity::class, FavouriteEntity::class, MangaPrefsEntity::class, - TrackEntity::class, TrackLogEntity::class - ], version = 7 + TrackEntity::class, TrackLogEntity::class, SuggestionEntity::class + ], version = 8 ) abstract class MangaDatabase : RoomDatabase() { 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 index b4b4152a1..d20b3b979 100644 --- 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 @@ -13,14 +13,15 @@ data class MangaEntity( @PrimaryKey(autoGenerate = false) @ColumnInfo(name = "manga_id") val id: Long, @ColumnInfo(name = "title") val title: String, - @ColumnInfo(name = "alt_title") val altTitle: String? = null, + @ColumnInfo(name = "alt_title") val altTitle: String?, @ColumnInfo(name = "url") val url: String, @ColumnInfo(name = "public_url") val publicUrl: String, - @ColumnInfo(name = "rating") val rating: Float = Manga.NO_RATING, //normalized value [0..1] or -1 + @ColumnInfo(name = "rating") val rating: Float, //normalized value [0..1] or -1 + @ColumnInfo(name = "nsfw") val isNsfw: Boolean, @ColumnInfo(name = "cover_url") val coverUrl: String, - @ColumnInfo(name = "large_cover_url") val largeCoverUrl: String? = null, - @ColumnInfo(name = "state") val state: String? = null, - @ColumnInfo(name = "author") val author: String? = null, + @ColumnInfo(name = "large_cover_url") val largeCoverUrl: String?, + @ColumnInfo(name = "state") val state: String?, + @ColumnInfo(name = "author") val author: String?, @ColumnInfo(name = "source") val source: String ) { @@ -30,6 +31,7 @@ data class MangaEntity( altTitle = this.altTitle, state = this.state?.let { MangaState.valueOf(it) }, rating = this.rating, + isNsfw = this.isNsfw, url = this.url, publicUrl = this.publicUrl, coverUrl = this.coverUrl, @@ -50,6 +52,7 @@ data class MangaEntity( coverUrl = manga.coverUrl, altTitle = manga.altTitle, rating = manga.rating, + isNsfw = manga.isNsfw, state = manga.state?.name, title = manga.title, author = manga.author diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/SuggestionEntity.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/SuggestionEntity.kt new file mode 100644 index 000000000..896732e15 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/SuggestionEntity.kt @@ -0,0 +1,24 @@ +package org.koitharu.kotatsu.core.db.entity + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey + +@Entity( + tableName = "suggestions", + foreignKeys = [ + ForeignKey( + entity = MangaEntity::class, + parentColumns = ["manga_id"], + childColumns = ["manga_id"], + onDelete = ForeignKey.CASCADE + ) + ] +) +data class SuggestionEntity( + @PrimaryKey(autoGenerate = false) + @ColumnInfo(name = "manga_id", index = true) val mangaId: Long, + @ColumnInfo(name = "relevance") val relevance: Float, + @ColumnInfo(name = "created_at") val createdAt: Long = System.currentTimeMillis(), +) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/migrations/Migration7To8.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/migrations/Migration7To8.kt new file mode 100644 index 000000000..4a4e781f2 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/migrations/Migration7To8.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.core.db.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +class Migration7To8 : Migration(7, 8) { + + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE manga ADD COLUMN nsfw INTEGER NOT NULL DEFAULT 0") + database.execSQL("CREATE TABLE IF NOT EXISTS suggestions (manga_id INTEGER NOT NULL, relevance REAL NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(manga_id), FOREIGN KEY(manga_id) REFERENCES manga(manga_id) ON UPDATE NO ACTION ON DELETE CASCADE )") + database.execSQL("CREATE INDEX IF NOT EXISTS index_suggestions_manga_id ON suggestions (manga_id)") + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/Manga.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/Manga.kt index 2854df336..f631d2d9d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/Manga.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/Manga.kt @@ -11,6 +11,7 @@ data class Manga( val url: String, // relative url for internal use val publicUrl: String, val rating: Float = NO_RATING, //normalized value [0..1] or -1 + val isNsfw: Boolean = false, val coverUrl: String, val largeCoverUrl: String? = null, val description: String? = null, //HTML diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt index c52492c33..66f96a6e2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt @@ -34,6 +34,10 @@ fun JSONObject.getStringOrNull(name: String): String? = opt(name)?.takeUnless { it === JSONObject.NULL }?.toString() +fun JSONObject.getBooleanOrDefault(name: String, defaultValue: Boolean): Boolean = opt(name)?.takeUnless { + it === JSONObject.NULL +} as? Boolean ?: defaultValue + operator fun JSONArray.iterator(): Iterator = JSONIterator(this) private class JSONIterator(private val array: JSONArray) : Iterator {