refactor: color preset entity
* I/O for repository calls * Removed nullability from ColorPresetEntity
This commit is contained in:
parent
b0c567bdc9
commit
a45078cae5
18 changed files with 468 additions and 151 deletions
|
|
@ -0,0 +1,220 @@
|
||||||
|
{
|
||||||
|
"formatVersion": 1,
|
||||||
|
"database": {
|
||||||
|
"version": 14,
|
||||||
|
"identityHash": "cd99cc3f6288826f0ad96bc8fe7aca3a",
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"tableName": "BookEntity",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `author` TEXT, `description` TEXT, `filePath` TEXT NOT NULL, `scrollIndex` INTEGER NOT NULL, `scrollOffset` INTEGER NOT NULL, `progress` REAL NOT NULL, `image` TEXT, `categories` TEXT NOT NULL DEFAULT '[]')",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "id",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "title",
|
||||||
|
"columnName": "title",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "author",
|
||||||
|
"columnName": "author",
|
||||||
|
"affinity": "TEXT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "description",
|
||||||
|
"columnName": "description",
|
||||||
|
"affinity": "TEXT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "filePath",
|
||||||
|
"columnName": "filePath",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "scrollIndex",
|
||||||
|
"columnName": "scrollIndex",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "scrollOffset",
|
||||||
|
"columnName": "scrollOffset",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "progress",
|
||||||
|
"columnName": "progress",
|
||||||
|
"affinity": "REAL",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "image",
|
||||||
|
"columnName": "image",
|
||||||
|
"affinity": "TEXT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "categories",
|
||||||
|
"columnName": "categories",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "'[]'"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"autoGenerate": true,
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "HistoryEntity",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `bookId` INTEGER NOT NULL, `time` INTEGER NOT NULL)",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "id",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "bookId",
|
||||||
|
"columnName": "bookId",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "time",
|
||||||
|
"columnName": "time",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"autoGenerate": true,
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "ColorPresetEntity",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `backgroundColor` INTEGER NOT NULL, `fontColor` INTEGER NOT NULL, `isSelected` INTEGER NOT NULL, `order` INTEGER NOT NULL)",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "id",
|
||||||
|
"affinity": "INTEGER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "name",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "backgroundColor",
|
||||||
|
"columnName": "backgroundColor",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "fontColor",
|
||||||
|
"columnName": "fontColor",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "isSelected",
|
||||||
|
"columnName": "isSelected",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "order",
|
||||||
|
"columnName": "order",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"autoGenerate": true,
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "CategoryEntity",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `order` INTEGER NOT NULL)",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "id",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "title",
|
||||||
|
"columnName": "title",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "order",
|
||||||
|
"columnName": "order",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"autoGenerate": true,
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "CategorySortEntity",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`categoryId` INTEGER NOT NULL, `sortOrder` TEXT NOT NULL, `sortOrderDescending` INTEGER NOT NULL, PRIMARY KEY(`categoryId`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "categoryId",
|
||||||
|
"columnName": "categoryId",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "sortOrder",
|
||||||
|
"columnName": "sortOrder",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "sortOrderDescending",
|
||||||
|
"columnName": "sortOrderDescending",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"autoGenerate": false,
|
||||||
|
"columnNames": [
|
||||||
|
"categoryId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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, 'cd99cc3f6288826f0ad96bc8fe7aca3a')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,6 @@ package ua.acclorite.book_story.core
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
|
||||||
typealias CoverImage = Bitmap
|
typealias CoverImage = Bitmap
|
||||||
typealias Selected = Boolean
|
|
||||||
typealias BottomSheet = String
|
typealias BottomSheet = String
|
||||||
typealias Dialog = String
|
typealias Dialog = String
|
||||||
typealias Drawer = String
|
typealias Drawer = String
|
||||||
|
|
@ -19,7 +19,6 @@ import org.commonmark.node.HtmlBlock
|
||||||
import org.commonmark.node.IndentedCodeBlock
|
import org.commonmark.node.IndentedCodeBlock
|
||||||
import org.commonmark.node.ThematicBreak
|
import org.commonmark.node.ThematicBreak
|
||||||
import org.commonmark.parser.Parser
|
import org.commonmark.parser.Parser
|
||||||
import ua.acclorite.book_story.data.local.room.BookDao
|
|
||||||
import ua.acclorite.book_story.data.local.room.BookDatabase
|
import ua.acclorite.book_story.data.local.room.BookDatabase
|
||||||
import ua.acclorite.book_story.data.local.room.DatabaseHelper
|
import ua.acclorite.book_story.data.local.room.DatabaseHelper
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
@ -49,7 +48,7 @@ object AppModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideBookDao(app: Application): BookDao {
|
fun provideBookDatabase(app: Application): BookDatabase {
|
||||||
// Additional Migrations
|
// Additional Migrations
|
||||||
DatabaseHelper.MIGRATION_7_8.removeBooksDir(app)
|
DatabaseHelper.MIGRATION_7_8.removeBooksDir(app)
|
||||||
|
|
||||||
|
|
@ -57,14 +56,11 @@ object AppModule {
|
||||||
app,
|
app,
|
||||||
BookDatabase::class.java,
|
BookDatabase::class.java,
|
||||||
"book_db"
|
"book_db"
|
||||||
)
|
).addMigrations(
|
||||||
.addMigrations(
|
DatabaseHelper.MIGRATION_2_3, // creates LanguageHistoryEntity table(if does not exist)
|
||||||
DatabaseHelper.MIGRATION_2_3, // creates LanguageHistoryEntity table(if does not exist)
|
DatabaseHelper.MIGRATION_4_5, // creates ColorPresetEntity table(if does not exist)
|
||||||
DatabaseHelper.MIGRATION_4_5, // creates ColorPresetEntity table(if does not exist)
|
DatabaseHelper.MIGRATION_5_6, // creates FavoriteDirectoryEntity table(if does not exist)
|
||||||
DatabaseHelper.MIGRATION_5_6, // creates FavoriteDirectoryEntity table(if does not exist)
|
DatabaseHelper.MIGRATION_13_14, // remove nullability from ColorPresetEntity
|
||||||
)
|
).allowMainThreadQueries().build()
|
||||||
.allowMainThreadQueries()
|
|
||||||
.build()
|
|
||||||
.dao
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ import androidx.room.PrimaryKey
|
||||||
data class ColorPresetEntity(
|
data class ColorPresetEntity(
|
||||||
@PrimaryKey(true)
|
@PrimaryKey(true)
|
||||||
val id: Int? = null,
|
val id: Int? = null,
|
||||||
val name: String?,
|
val name: String,
|
||||||
val backgroundColor: Long,
|
val backgroundColor: Long,
|
||||||
val fontColor: Long,
|
val fontColor: Long,
|
||||||
val isSelected: Boolean,
|
val isSelected: Boolean,
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,8 @@ import androidx.room.Upsert
|
||||||
import ua.acclorite.book_story.data.local.dto.BookEntity
|
import ua.acclorite.book_story.data.local.dto.BookEntity
|
||||||
import ua.acclorite.book_story.data.local.dto.CategoryEntity
|
import ua.acclorite.book_story.data.local.dto.CategoryEntity
|
||||||
import ua.acclorite.book_story.data.local.dto.CategorySortEntity
|
import ua.acclorite.book_story.data.local.dto.CategorySortEntity
|
||||||
import ua.acclorite.book_story.data.local.dto.ColorPresetEntity
|
|
||||||
import ua.acclorite.book_story.data.local.dto.HistoryEntity
|
import ua.acclorite.book_story.data.local.dto.HistoryEntity
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to manipulate Room database.
|
|
||||||
*/
|
|
||||||
@Dao
|
@Dao
|
||||||
interface BookDao {
|
interface BookDao {
|
||||||
|
|
||||||
|
|
@ -73,27 +69,6 @@ interface BookDao {
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - */
|
/* - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
|
|
||||||
/* ------ ColorPresetEntity ----------------- */
|
|
||||||
@Upsert
|
|
||||||
suspend fun updateColorPreset(colorPreset: ColorPresetEntity)
|
|
||||||
|
|
||||||
@Query("SELECT `order` FROM colorpresetentity WHERE :id=id")
|
|
||||||
suspend fun getColorPresetOrder(id: Int): Int
|
|
||||||
|
|
||||||
@Query("SELECT COUNT(*) FROM colorpresetentity")
|
|
||||||
suspend fun getColorPresetsSize(): Int
|
|
||||||
|
|
||||||
@Query("SELECT * FROM colorpresetentity")
|
|
||||||
suspend fun getColorPresets(): List<ColorPresetEntity>
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
suspend fun deleteColorPreset(colorPreset: ColorPresetEntity)
|
|
||||||
|
|
||||||
@Query("DELETE FROM colorpresetentity")
|
|
||||||
suspend fun deleteColorPresets()
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - */
|
|
||||||
|
|
||||||
|
|
||||||
/* ------ CategoryEntity ----------------- */
|
/* ------ CategoryEntity ----------------- */
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
suspend fun insertCategory(
|
suspend fun insertCategory(
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import java.io.File
|
||||||
CategoryEntity::class,
|
CategoryEntity::class,
|
||||||
CategorySortEntity::class
|
CategorySortEntity::class
|
||||||
],
|
],
|
||||||
version = 13,
|
version = 14,
|
||||||
autoMigrations = [
|
autoMigrations = [
|
||||||
AutoMigration(1, 2),
|
AutoMigration(1, 2),
|
||||||
AutoMigration(2, 3),
|
AutoMigration(2, 3),
|
||||||
|
|
@ -44,11 +44,13 @@ import java.io.File
|
||||||
AutoMigration(10, 11),
|
AutoMigration(10, 11),
|
||||||
AutoMigration(11, 12),
|
AutoMigration(11, 12),
|
||||||
AutoMigration(12, 13),
|
AutoMigration(12, 13),
|
||||||
|
AutoMigration(13, 14),
|
||||||
],
|
],
|
||||||
exportSchema = true
|
exportSchema = true
|
||||||
)
|
)
|
||||||
abstract class BookDatabase : RoomDatabase() {
|
abstract class BookDatabase : RoomDatabase() {
|
||||||
abstract val dao: BookDao
|
abstract val bookDao: BookDao
|
||||||
|
abstract val colorPresetDao: ColorPresetDao
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("ClassName")
|
@Suppress("ClassName")
|
||||||
|
|
@ -124,4 +126,36 @@ object DatabaseHelper {
|
||||||
|
|
||||||
@DeleteColumn("BookEntity", "category")
|
@DeleteColumn("BookEntity", "category")
|
||||||
class MIGRATION_9_10 : AutoMigrationSpec
|
class MIGRATION_9_10 : AutoMigrationSpec
|
||||||
|
|
||||||
|
val MIGRATION_13_14 = object : Migration(13, 14) {
|
||||||
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
|
database.execSQL(
|
||||||
|
"""
|
||||||
|
CREATE TABLE IF NOT EXISTS ColorPresetEntity (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
backgroundColor INTEGER NOT NULL,
|
||||||
|
fontColor INTEGER NOT NULL,
|
||||||
|
isSelected INTEGER NOT NULL,
|
||||||
|
`order` INTEGER NOT NULL
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
database.execSQL(
|
||||||
|
"""
|
||||||
|
INSERT INTO ColorPresetEntity_new (id, name, backgroundColor, fontColor, isSelected, `order`)
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
COALESCE(name, ''),
|
||||||
|
backgroundColor,
|
||||||
|
fontColor,
|
||||||
|
isSelected,
|
||||||
|
`order`
|
||||||
|
FROM ColorPresetEntity
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
database.execSQL("DROP TABLE ColorPresetEntity")
|
||||||
|
database.execSQL("ALTER TABLE ColorPresetEntity_new RENAME TO ColorPresetEntity")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Book's Story — free and open-source Material You eBook reader.
|
||||||
|
* Copyright (C) 2024-2025 Acclorite
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ua.acclorite.book_story.data.local.room
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Upsert
|
||||||
|
import ua.acclorite.book_story.data.local.dto.ColorPresetEntity
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface ColorPresetDao {
|
||||||
|
@Upsert
|
||||||
|
suspend fun updateColorPreset(colorPreset: ColorPresetEntity)
|
||||||
|
|
||||||
|
@Query("SELECT `order` FROM colorpresetentity WHERE id = :id")
|
||||||
|
suspend fun getColorPresetOrder(id: Int): Int
|
||||||
|
|
||||||
|
@Query("SELECT COUNT(*) FROM colorpresetentity")
|
||||||
|
suspend fun getColorPresetsSize(): Int
|
||||||
|
|
||||||
|
@Query("SELECT * FROM colorpresetentity ORDER BY `order` ASC")
|
||||||
|
suspend fun getColorPresets(): List<ColorPresetEntity>
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun deleteColorPreset(colorPreset: ColorPresetEntity)
|
||||||
|
|
||||||
|
@Query("DELETE FROM colorpresetentity")
|
||||||
|
suspend fun deleteColorPresets()
|
||||||
|
}
|
||||||
|
|
@ -6,8 +6,10 @@
|
||||||
|
|
||||||
package ua.acclorite.book_story.data.repository
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import ua.acclorite.book_story.core.CoverImage
|
import ua.acclorite.book_story.core.CoverImage
|
||||||
import ua.acclorite.book_story.data.local.room.BookDao
|
import ua.acclorite.book_story.data.local.room.BookDatabase
|
||||||
import ua.acclorite.book_story.data.mapper.book.BookMapper
|
import ua.acclorite.book_story.data.mapper.book.BookMapper
|
||||||
import ua.acclorite.book_story.data.mapper.file.FileMapper
|
import ua.acclorite.book_story.data.mapper.file.FileMapper
|
||||||
import ua.acclorite.book_story.data.parser.FileParser
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
|
|
@ -22,7 +24,7 @@ import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class BookRepositoryImpl @Inject constructor(
|
class BookRepositoryImpl @Inject constructor(
|
||||||
private val database: BookDao,
|
private val database: BookDatabase,
|
||||||
private val bookMapper: BookMapper,
|
private val bookMapper: BookMapper,
|
||||||
private val fileMapper: FileMapper,
|
private val fileMapper: FileMapper,
|
||||||
private val fileParser: FileParser,
|
private val fileParser: FileParser,
|
||||||
|
|
@ -31,46 +33,62 @@ class BookRepositoryImpl @Inject constructor(
|
||||||
) : BookRepository {
|
) : BookRepository {
|
||||||
|
|
||||||
override suspend fun searchBooks(query: String): Result<List<Book>> = runCatching {
|
override suspend fun searchBooks(query: String): Result<List<Book>> = runCatching {
|
||||||
database.searchBooks(query).map { bookMapper.toBook(it) }
|
withContext(Dispatchers.IO) {
|
||||||
|
database.bookDao.searchBooks(query).map { bookMapper.toBook(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getBook(bookId: Int): Result<Book> = runCatching {
|
override suspend fun getBook(bookId: Int): Result<Book> = runCatching {
|
||||||
database.findBookById(bookId).let {
|
withContext(Dispatchers.IO) {
|
||||||
if (it == null) throw NoSuchElementException("Couldn't get book [$bookId].")
|
database.bookDao.findBookById(bookId).let {
|
||||||
else bookMapper.toBook(it)
|
if (it == null) throw NoSuchElementException("Couldn't get book [$bookId].")
|
||||||
|
else bookMapper.toBook(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getText(bookId: Int): Result<List<ReaderText>> {
|
override suspend fun getText(bookId: Int): Result<List<ReaderText>> {
|
||||||
return getBook(bookId)
|
return withContext(Dispatchers.IO) {
|
||||||
.mapCatching { fileProvider.getFileFromBook(it).getOrThrow() }
|
getBook(bookId)
|
||||||
.mapCatching { textParser.parse(it) }
|
.mapCatching { fileProvider.getFileFromBook(it).getOrThrow() }
|
||||||
|
.mapCatching { textParser.parse(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getFileFromBook(bookId: Int): Result<File> {
|
override suspend fun getFileFromBook(bookId: Int): Result<File> {
|
||||||
return getBook(bookId)
|
return withContext(Dispatchers.IO) {
|
||||||
.mapCatching { fileProvider.getFileFromBook(it).getOrThrow() }
|
getBook(bookId)
|
||||||
.mapCatching { fileMapper.toFile(it) }
|
.mapCatching { fileProvider.getFileFromBook(it).getOrThrow() }
|
||||||
|
.mapCatching { fileMapper.toFile(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun addBook(book: Book): Result<Unit> = runCatching {
|
override suspend fun addBook(book: Book): Result<Unit> = runCatching {
|
||||||
database.insertBook(bookMapper.toBookEntity(book))
|
withContext(Dispatchers.IO) {
|
||||||
|
database.bookDao.insertBook(bookMapper.toBookEntity(book))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateBook(book: Book): Result<Unit> = runCatching {
|
override suspend fun updateBook(book: Book): Result<Unit> = runCatching {
|
||||||
database.updateBook(bookMapper.toBookEntity(book)).also {
|
withContext(Dispatchers.IO) {
|
||||||
if (it == 0) throw Exception("Could not update book in database.")
|
database.bookDao.updateBook(bookMapper.toBookEntity(book)).also {
|
||||||
|
if (it == 0) throw Exception("Could not update book in database.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteBook(book: Book): Result<Unit> = runCatching {
|
override suspend fun deleteBook(book: Book): Result<Unit> = runCatching {
|
||||||
database.deleteBook(bookMapper.toBookEntity(book)).also {
|
withContext(Dispatchers.IO) {
|
||||||
if (it == 0) throw Exception("Could not delete book in database.")
|
database.bookDao.deleteBook(bookMapper.toBookEntity(book)).also {
|
||||||
|
if (it == 0) throw Exception("Could not delete book in database.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getDefaultCover(book: Book): Result<CoverImage?> = runCatching {
|
override suspend fun getDefaultCover(book: Book): Result<CoverImage?> = runCatching {
|
||||||
return fileProvider.getFileFromBook(book)
|
return withContext(Dispatchers.IO) {
|
||||||
.mapCatching { fileParser.parse(it)?.coverImage }
|
fileProvider.getFileFromBook(book)
|
||||||
|
.mapCatching { fileParser.parse(it)?.coverImage }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
package ua.acclorite.book_story.data.repository
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.local.room.BookDao
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import ua.acclorite.book_story.data.local.room.BookDatabase
|
||||||
import ua.acclorite.book_story.data.mapper.category.CategoryMapper
|
import ua.acclorite.book_story.data.mapper.category.CategoryMapper
|
||||||
import ua.acclorite.book_story.data.mapper.category_sort.CategorySortMapper
|
import ua.acclorite.book_story.data.mapper.category_sort.CategorySortMapper
|
||||||
import ua.acclorite.book_story.domain.model.library.Category
|
import ua.acclorite.book_story.domain.model.library.Category
|
||||||
|
|
@ -17,57 +19,72 @@ import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class CategoryRepositoryImpl @Inject constructor(
|
class CategoryRepositoryImpl @Inject constructor(
|
||||||
private val database: BookDao,
|
private val database: BookDatabase,
|
||||||
private val categoryMapper: CategoryMapper,
|
private val categoryMapper: CategoryMapper,
|
||||||
private val categorySortMapper: CategorySortMapper,
|
private val categorySortMapper: CategorySortMapper,
|
||||||
) : CategoryRepository {
|
) : CategoryRepository {
|
||||||
|
|
||||||
override suspend fun addCategory(category: Category): Result<Unit> = runCatching {
|
override suspend fun addCategory(category: Category): Result<Unit> = runCatching {
|
||||||
database.insertCategory(
|
withContext(Dispatchers.IO) {
|
||||||
categoryMapper.toCategoryEntity(
|
database.bookDao.insertCategory(
|
||||||
category.copy(
|
categoryMapper.toCategoryEntity(
|
||||||
order = database.getCategoriesCount()
|
category.copy(
|
||||||
|
order = database.bookDao.getCategoriesCount()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getCategories(): Result<List<Category>> = runCatching {
|
override suspend fun getCategories(): Result<List<Category>> = runCatching {
|
||||||
database.getCategories().map { categoryMapper.toCategory(it) }.sortedBy { it.order }
|
withContext(Dispatchers.IO) {
|
||||||
|
database.bookDao.getCategories().map { categoryMapper.toCategory(it) }
|
||||||
|
.sortedBy { it.order }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateCategory(category: Category): Result<Unit> = runCatching {
|
override suspend fun updateCategory(category: Category): Result<Unit> = runCatching {
|
||||||
database.updateCategoryTitle(
|
withContext(Dispatchers.IO) {
|
||||||
id = category.id,
|
database.bookDao.updateCategoryTitle(
|
||||||
title = category.title
|
id = category.id,
|
||||||
)
|
title = category.title
|
||||||
updateOrder(getCategories().getOrThrow())
|
)
|
||||||
|
updateOrder(getCategories().getOrThrow())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateOrder(categories: List<Category>): Result<Unit> = runCatching {
|
override suspend fun updateOrder(categories: List<Category>): Result<Unit> = runCatching {
|
||||||
categories.forEachIndexed { index, category ->
|
withContext(Dispatchers.IO) {
|
||||||
database.updateCategoryOrder(category.id, index)
|
categories.forEachIndexed { index, category ->
|
||||||
|
database.bookDao.updateCategoryOrder(category.id, index)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteCategory(category: Category): Result<Unit> = runCatching {
|
override suspend fun deleteCategory(category: Category): Result<Unit> = runCatching {
|
||||||
database.deleteCategory(categoryMapper.toCategoryEntity(category))
|
withContext(Dispatchers.IO) {
|
||||||
database.deleteCategorySortEntity(category.id)
|
database.bookDao.deleteCategory(categoryMapper.toCategoryEntity(category))
|
||||||
|
database.bookDao.deleteCategorySortEntity(category.id)
|
||||||
|
|
||||||
updateOrder(getCategories().getOrThrow())
|
updateOrder(getCategories().getOrThrow())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateCategorySorting(
|
override suspend fun updateCategorySorting(
|
||||||
categorySort: CategorySort
|
categorySort: CategorySort
|
||||||
): Result<Unit> = runCatching {
|
): Result<Unit> = runCatching {
|
||||||
database.updateCategorySort(
|
withContext(Dispatchers.IO) {
|
||||||
categorySortMapper.toCategorySortEntity(categorySort)
|
database.bookDao.updateCategorySort(
|
||||||
)
|
categorySortMapper.toCategorySortEntity(categorySort)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getCategorySorting(): Result<List<CategorySort>> = runCatching {
|
override suspend fun getCategorySorting(): Result<List<CategorySort>> = runCatching {
|
||||||
database.getCategorySortEntities().map {
|
withContext(Dispatchers.IO) {
|
||||||
categorySortMapper.toCategorySort(it)
|
database.bookDao.getCategorySortEntities().map {
|
||||||
|
categorySortMapper.toCategorySort(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
package ua.acclorite.book_story.data.repository
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.local.room.BookDao
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import ua.acclorite.book_story.data.local.room.BookDatabase
|
||||||
import ua.acclorite.book_story.data.mapper.color_preset.ColorPresetMapper
|
import ua.acclorite.book_story.data.mapper.color_preset.ColorPresetMapper
|
||||||
import ua.acclorite.book_story.domain.model.reader.ColorPreset
|
import ua.acclorite.book_story.domain.model.reader.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
|
|
@ -15,56 +17,67 @@ import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class ColorPresetRepositoryImpl @Inject constructor(
|
class ColorPresetRepositoryImpl @Inject constructor(
|
||||||
private val database: BookDao,
|
private val database: BookDatabase,
|
||||||
private val colorPresetMapper: ColorPresetMapper
|
private val colorPresetMapper: ColorPresetMapper
|
||||||
) : ColorPresetRepository {
|
) : ColorPresetRepository {
|
||||||
|
|
||||||
override suspend fun getColorPresets(): Result<List<ColorPreset>> = runCatching {
|
override suspend fun getColorPresets(): Result<List<ColorPreset>> = runCatching {
|
||||||
database.getColorPresets()
|
withContext(Dispatchers.IO) {
|
||||||
.sortedBy { it.order }
|
database.colorPresetDao.getColorPresets().map {
|
||||||
.map { colorPresetMapper.toColorPreset(it) }
|
colorPresetMapper.toColorPreset(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateColorPreset(
|
override suspend fun updateColorPreset(
|
||||||
colorPreset: ColorPreset
|
colorPreset: ColorPreset
|
||||||
): Result<Unit> = runCatching {
|
): Result<Unit> = runCatching {
|
||||||
database.updateColorPreset(
|
withContext(Dispatchers.IO) {
|
||||||
colorPresetMapper.toColorPresetEntity(
|
database.colorPresetDao.updateColorPreset(
|
||||||
colorPreset = colorPreset,
|
colorPresetMapper.toColorPresetEntity(
|
||||||
order = if (colorPreset.id != -1) database.getColorPresetOrder(colorPreset.id)
|
colorPreset = colorPreset,
|
||||||
else database.getColorPresetsSize()
|
order = if (colorPreset.id != -1) {
|
||||||
|
database.colorPresetDao.getColorPresetOrder(colorPreset.id)
|
||||||
|
} else database.colorPresetDao.getColorPresetsSize()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun selectColorPreset(
|
override suspend fun selectColorPreset(
|
||||||
colorPreset: ColorPreset
|
colorPreset: ColorPreset
|
||||||
): Result<Unit> = runCatching {
|
): Result<Unit> = runCatching {
|
||||||
database.getColorPresets().map {
|
withContext(Dispatchers.IO) {
|
||||||
it.copy(isSelected = it.id == colorPreset.id)
|
database.colorPresetDao.getColorPresets().map {
|
||||||
}.forEach {
|
it.copy(isSelected = it.id == colorPreset.id)
|
||||||
database.updateColorPreset(it)
|
}.forEach {
|
||||||
|
database.colorPresetDao.updateColorPreset(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun reorderColorPresets(
|
override suspend fun reorderColorPresets(
|
||||||
colorPresets: List<ColorPreset>
|
colorPresets: List<ColorPreset>
|
||||||
): Result<Unit> = runCatching {
|
): Result<Unit> = runCatching {
|
||||||
database.deleteColorPresets()
|
withContext(Dispatchers.IO) {
|
||||||
colorPresets.forEachIndexed { index, colorPreset ->
|
database.colorPresetDao.deleteColorPresets()
|
||||||
database.updateColorPreset(
|
colorPresets.forEachIndexed { index, colorPreset ->
|
||||||
colorPresetMapper.toColorPresetEntity(colorPreset, order = index)
|
database.colorPresetDao.updateColorPreset(
|
||||||
)
|
colorPresetMapper.toColorPresetEntity(colorPreset, order = index)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteColorPreset(
|
override suspend fun deleteColorPreset(
|
||||||
colorPreset: ColorPreset
|
colorPreset: ColorPreset
|
||||||
): Result<Unit> = runCatching {
|
): Result<Unit> = runCatching {
|
||||||
database.deleteColorPreset(
|
withContext(Dispatchers.IO) {
|
||||||
colorPresetMapper.toColorPresetEntity(
|
database.colorPresetDao.deleteColorPreset(
|
||||||
colorPreset, -1
|
colorPresetMapper.toColorPresetEntity(
|
||||||
|
colorPreset, -1
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,8 +6,10 @@
|
||||||
|
|
||||||
package ua.acclorite.book_story.data.repository
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import ua.acclorite.book_story.core.data.ExtensionsData
|
import ua.acclorite.book_story.core.data.ExtensionsData
|
||||||
import ua.acclorite.book_story.data.local.room.BookDao
|
import ua.acclorite.book_story.data.local.room.BookDatabase
|
||||||
import ua.acclorite.book_story.data.mapper.file.FileMapper
|
import ua.acclorite.book_story.data.mapper.file.FileMapper
|
||||||
import ua.acclorite.book_story.data.model.common.BookWithCover
|
import ua.acclorite.book_story.data.model.common.BookWithCover
|
||||||
import ua.acclorite.book_story.data.model.file.CachedFile
|
import ua.acclorite.book_story.data.model.file.CachedFile
|
||||||
|
|
@ -18,28 +20,26 @@ import ua.acclorite.book_story.domain.service.FileProvider
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
/**
|
|
||||||
* File System repository.
|
|
||||||
* Manages all File System related work.
|
|
||||||
*/
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class FileSystemRepositoryImpl @Inject constructor(
|
class FileSystemRepositoryImpl @Inject constructor(
|
||||||
private val database: BookDao,
|
private val database: BookDatabase,
|
||||||
private val fileMapper: FileMapper,
|
private val fileMapper: FileMapper,
|
||||||
private val fileParser: FileParser,
|
private val fileParser: FileParser,
|
||||||
private val fileProvider: FileProvider
|
private val fileProvider: FileProvider
|
||||||
) : FileSystemRepository {
|
) : FileSystemRepository {
|
||||||
|
|
||||||
override suspend fun searchFiles(query: String): Result<List<File>> {
|
override suspend fun searchFiles(query: String): Result<List<File>> {
|
||||||
return fileProvider.getStorageFiles().mapCatching { storages ->
|
return withContext(Dispatchers.IO) {
|
||||||
val existingFiles = database.searchBooks("").map { it.filePath }
|
fileProvider.getStorageFiles().mapCatching { storages ->
|
||||||
|
val existingFiles = database.bookDao.searchBooks("").map { it.filePath }
|
||||||
|
|
||||||
storages.map { storage ->
|
storages.map { storage ->
|
||||||
storage.getFilesFromStorage(
|
storage.getFilesFromStorage(
|
||||||
query = query,
|
query = query,
|
||||||
existingFiles = existingFiles
|
existingFiles = existingFiles
|
||||||
)
|
)
|
||||||
}.flatten()
|
}.flatten()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +74,9 @@ class FileSystemRepositoryImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getBookFromFile(file: File): Result<BookWithCover> = runCatching {
|
override suspend fun getBookFromFile(file: File): Result<BookWithCover> = runCatching {
|
||||||
fileParser.parse(fileMapper.toCachedFile(file))
|
withContext(Dispatchers.IO) {
|
||||||
?: throw Exception("Could not parse ${file.name}.")
|
fileParser.parse(fileMapper.toCachedFile(file))
|
||||||
|
?: throw Exception("Could not parse ${file.name}.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
package ua.acclorite.book_story.data.repository
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.local.room.BookDao
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import ua.acclorite.book_story.data.local.room.BookDatabase
|
||||||
import ua.acclorite.book_story.data.mapper.history.HistoryMapper
|
import ua.acclorite.book_story.data.mapper.history.HistoryMapper
|
||||||
import ua.acclorite.book_story.domain.model.history.History
|
import ua.acclorite.book_story.domain.model.history.History
|
||||||
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
|
|
@ -15,40 +17,52 @@ import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class HistoryRepositoryImpl @Inject constructor(
|
class HistoryRepositoryImpl @Inject constructor(
|
||||||
private val database: BookDao,
|
private val database: BookDatabase,
|
||||||
private val historyMapper: HistoryMapper
|
private val historyMapper: HistoryMapper
|
||||||
) : HistoryRepository {
|
) : HistoryRepository {
|
||||||
|
|
||||||
override suspend fun getHistoryForBook(bookId: Int): Result<History> = runCatching {
|
override suspend fun getHistoryForBook(bookId: Int): Result<History> = runCatching {
|
||||||
database.getHistoryForBook(bookId).let {
|
withContext(Dispatchers.IO) {
|
||||||
if (it == null) throw NoSuchElementException("Could not get history from [$bookId].")
|
database.bookDao.getHistoryForBook(bookId).let {
|
||||||
else historyMapper.toHistory(it)
|
if (it == null) throw NoSuchElementException("Could not get history from [$bookId].")
|
||||||
|
else historyMapper.toHistory(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun addHistory(history: History): Result<Unit> = runCatching {
|
override suspend fun addHistory(history: History): Result<Unit> = runCatching {
|
||||||
database.insertHistory(historyMapper.toHistoryEntity(history))
|
withContext(Dispatchers.IO) {
|
||||||
|
database.bookDao.insertHistory(historyMapper.toHistoryEntity(history))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getHistory(): Result<List<History>> = runCatching {
|
override suspend fun getHistory(): Result<List<History>> = runCatching {
|
||||||
database.getHistory().map { historyMapper.toHistory(it) }
|
withContext(Dispatchers.IO) {
|
||||||
|
database.bookDao.getHistory().map { historyMapper.toHistory(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteWholeHistory(): Result<Unit> = runCatching {
|
override suspend fun deleteWholeHistory(): Result<Unit> = runCatching {
|
||||||
database.deleteWholeHistory().also {
|
withContext(Dispatchers.IO) {
|
||||||
if (it == 0) throw Exception("Could not delete whole history in database.")
|
database.bookDao.deleteWholeHistory().also {
|
||||||
|
if (it == 0) throw Exception("Could not delete whole history in database.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteHistoryForBook(bookId: Int): Result<Unit> = runCatching {
|
override suspend fun deleteHistoryForBook(bookId: Int): Result<Unit> = runCatching {
|
||||||
database.deleteHistoryForBook(bookId = bookId).also {
|
withContext(Dispatchers.IO) {
|
||||||
if (it == 0) throw Exception("Could not delete history for book [$bookId] in database.")
|
database.bookDao.deleteHistoryForBook(bookId = bookId).also {
|
||||||
|
if (it == 0) throw Exception("Could not delete history for book [$bookId] in database.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteHistory(history: History): Result<Unit> = runCatching {
|
override suspend fun deleteHistory(history: History): Result<Unit> = runCatching {
|
||||||
database.deleteHistory(historyMapper.toHistoryEntity(history)).also {
|
withContext(Dispatchers.IO) {
|
||||||
if (it == 0) throw Exception("Could not delete history in database.")
|
database.bookDao.deleteHistory(historyMapper.toHistoryEntity(history)).also {
|
||||||
|
if (it == 0) throw Exception("Could not delete history in database.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,20 +8,19 @@ package ua.acclorite.book_story.domain.model.reader
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import ua.acclorite.book_story.core.Selected
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class ColorPreset(
|
data class ColorPreset(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
val name: String?,
|
val name: String,
|
||||||
val backgroundColor: Color,
|
val backgroundColor: Color,
|
||||||
val fontColor: Color,
|
val fontColor: Color,
|
||||||
val isSelected: Selected
|
val isSelected: Boolean
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val default = ColorPreset(
|
val default = ColorPreset(
|
||||||
id = -1,
|
id = -1,
|
||||||
name = null,
|
name = "",
|
||||||
backgroundColor = Color(0xFFFAF8FF), // Blue Light Surface (hardcoded)
|
backgroundColor = Color(0xFFFAF8FF), // Blue Light Surface (hardcoded)
|
||||||
fontColor = Color(0xFF44464F), // Blue Light OnSurfaceVariant (hardcoded)
|
fontColor = Color(0xFF44464F), // Blue Light OnSurfaceVariant (hardcoded)
|
||||||
isSelected = false
|
isSelected = false
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,10 @@
|
||||||
package ua.acclorite.book_story.presentation.library.model
|
package ua.acclorite.book_story.presentation.library.model
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import ua.acclorite.book_story.core.Selected
|
|
||||||
import ua.acclorite.book_story.domain.model.library.Book
|
import ua.acclorite.book_story.domain.model.library.Book
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class SelectableBook(
|
data class SelectableBook(
|
||||||
val data: Book,
|
val data: Book,
|
||||||
val selected: Selected
|
val selected: Boolean
|
||||||
)
|
)
|
||||||
|
|
@ -7,11 +7,10 @@
|
||||||
package ua.acclorite.book_story.presentation.library.model
|
package ua.acclorite.book_story.presentation.library.model
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import ua.acclorite.book_story.core.Selected
|
|
||||||
import ua.acclorite.book_story.data.model.common.NullableBook
|
import ua.acclorite.book_story.data.model.common.NullableBook
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class SelectableNullableBook(
|
data class SelectableNullableBook(
|
||||||
val data: NullableBook,
|
val data: NullableBook,
|
||||||
val selected: Selected
|
val selected: Boolean
|
||||||
)
|
)
|
||||||
|
|
@ -23,7 +23,6 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.core.Selected
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modal Drawer Selectable Item.
|
* Modal Drawer Selectable Item.
|
||||||
|
|
@ -38,7 +37,7 @@ import ua.acclorite.book_story.core.Selected
|
||||||
@Composable
|
@Composable
|
||||||
fun ModalDrawerSelectableItem(
|
fun ModalDrawerSelectableItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
selected: Selected,
|
selected: Boolean,
|
||||||
enabled: Boolean = true,
|
enabled: Boolean = true,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
content: @Composable RowScope.() -> Unit
|
content: @Composable RowScope.() -> Unit
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ fun SettingsEffects(effects: SharedFlow<SettingsEffect>) {
|
||||||
is SettingsEffect.OnSwitchedColorPreset -> {
|
is SettingsEffect.OnSwitchedColorPreset -> {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.color_preset_selected_query,
|
R.string.color_preset_selected_query,
|
||||||
if (effect.newColorPreset.name.isNullOrBlank()) {
|
if (effect.newColorPreset.name.isBlank()) {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.color_preset_query,
|
R.string.color_preset_query,
|
||||||
effect.newColorPreset.id.toString()
|
effect.newColorPreset.id.toString()
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ import sh.calvin.reorderable.ReorderableCollectionItemScope
|
||||||
import sh.calvin.reorderable.ReorderableItem
|
import sh.calvin.reorderable.ReorderableItem
|
||||||
import sh.calvin.reorderable.rememberReorderableLazyListState
|
import sh.calvin.reorderable.rememberReorderableLazyListState
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.core.Selected
|
|
||||||
import ua.acclorite.book_story.domain.model.reader.ColorPreset
|
import ua.acclorite.book_story.domain.model.reader.ColorPreset
|
||||||
import ua.acclorite.book_story.presentation.settings.SettingsEvent
|
import ua.acclorite.book_story.presentation.settings.SettingsEvent
|
||||||
import ua.acclorite.book_story.presentation.settings.SettingsModel
|
import ua.acclorite.book_story.presentation.settings.SettingsModel
|
||||||
|
|
@ -233,7 +232,7 @@ fun ColorPresetOption(backgroundColor: Color) {
|
||||||
@Composable
|
@Composable
|
||||||
private fun ReorderableCollectionItemScope.ColorPresetOptionRowItem(
|
private fun ReorderableCollectionItemScope.ColorPresetOptionRowItem(
|
||||||
colorPreset: ColorPreset,
|
colorPreset: ColorPreset,
|
||||||
isSelected: Selected,
|
isSelected: Boolean,
|
||||||
canDrag: Boolean,
|
canDrag: Boolean,
|
||||||
enableAnimation: Boolean,
|
enableAnimation: Boolean,
|
||||||
onDragStopped: () -> Unit,
|
onDragStopped: () -> Unit,
|
||||||
|
|
@ -241,14 +240,14 @@ private fun ReorderableCollectionItemScope.ColorPresetOptionRowItem(
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val title = remember(colorPreset) {
|
val title = remember(colorPreset) {
|
||||||
if ((colorPreset.name ?: "").isBlank()) {
|
if (colorPreset.name.isBlank()) {
|
||||||
return@remember context.getString(
|
return@remember context.getString(
|
||||||
R.string.color_preset_query,
|
R.string.color_preset_query,
|
||||||
colorPreset.id.toString()
|
colorPreset.id.toString()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
colorPreset.name!!
|
colorPreset.name
|
||||||
}
|
}
|
||||||
|
|
||||||
val borderColor = remember(isSelected, colorPreset.fontColor) {
|
val borderColor = remember(isSelected, colorPreset.fontColor) {
|
||||||
|
|
@ -344,7 +343,7 @@ private fun ColorPresetOptionConfigurationItem(
|
||||||
onAdd: () -> Unit
|
onAdd: () -> Unit
|
||||||
) {
|
) {
|
||||||
val title = remember(selectedColorPreset.id) {
|
val title = remember(selectedColorPreset.id) {
|
||||||
mutableStateOf(selectedColorPreset.name ?: "")
|
mutableStateOf(selectedColorPreset.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(title) {
|
LaunchedEffect(title) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue