🛠️ BookRepository reformat
* Split into multiple smaller repositories * Reformatted code Co-authored-by: Ridho Pratama <dhoable@gmail.com>
This commit is contained in:
parent
1104100b3b
commit
9854c2d845
43 changed files with 755 additions and 523 deletions
|
|
@ -19,7 +19,19 @@ import ua.acclorite.book_story.data.parser.FileParserImpl
|
||||||
import ua.acclorite.book_story.data.parser.TextParser
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
import ua.acclorite.book_story.data.parser.TextParserImpl
|
import ua.acclorite.book_story.data.parser.TextParserImpl
|
||||||
import ua.acclorite.book_story.data.repository.BookRepositoryImpl
|
import ua.acclorite.book_story.data.repository.BookRepositoryImpl
|
||||||
|
import ua.acclorite.book_story.data.repository.ColorPresetRepositoryImpl
|
||||||
|
import ua.acclorite.book_story.data.repository.DataStoreRepositoryImpl
|
||||||
|
import ua.acclorite.book_story.data.repository.FavoriteDirectoryRepositoryImpl
|
||||||
|
import ua.acclorite.book_story.data.repository.FileSystemRepositoryImpl
|
||||||
|
import ua.acclorite.book_story.data.repository.HistoryRepositoryImpl
|
||||||
|
import ua.acclorite.book_story.data.repository.RemoteRepositoryImpl
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
|
import ua.acclorite.book_story.domain.repository.DataStoreRepository
|
||||||
|
import ua.acclorite.book_story.domain.repository.FavoriteDirectoryRepository
|
||||||
|
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
||||||
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
|
import ua.acclorite.book_story.domain.repository.RemoteRepository
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
|
|
@ -37,6 +49,42 @@ abstract class RepositoryModule {
|
||||||
bookRepositoryImpl: BookRepositoryImpl
|
bookRepositoryImpl: BookRepositoryImpl
|
||||||
): BookRepository
|
): BookRepository
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
abstract fun bindHistoryRepository(
|
||||||
|
historyRepositoryImpl: HistoryRepositoryImpl
|
||||||
|
): HistoryRepository
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
abstract fun bindColorPresetRepository(
|
||||||
|
colorPresetRepositoryImpl: ColorPresetRepositoryImpl
|
||||||
|
): ColorPresetRepository
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
abstract fun bindDataStoreRepository(
|
||||||
|
dataStoreRepositoryImpl: DataStoreRepositoryImpl
|
||||||
|
): DataStoreRepository
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
abstract fun bindFileSystemRepository(
|
||||||
|
fileSystemRepositoryImpl: FileSystemRepositoryImpl
|
||||||
|
): FileSystemRepository
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
abstract fun bindRemoteRepository(
|
||||||
|
remoteRepositoryImpl: RemoteRepositoryImpl
|
||||||
|
): RemoteRepository
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
abstract fun bindFavoriteDirectoryRepository(
|
||||||
|
favoriteDirectoryRepositoryImpl: FavoriteDirectoryRepositoryImpl
|
||||||
|
): FavoriteDirectoryRepository
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@Singleton
|
@Singleton
|
||||||
abstract fun bindBookMapper(
|
abstract fun bindBookMapper(
|
||||||
|
|
|
||||||
|
|
@ -4,44 +4,26 @@ import android.app.Application
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Environment
|
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.datastore.preferences.core.Preferences
|
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
|
||||||
import kotlinx.coroutines.awaitAll
|
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.yield
|
import kotlinx.coroutines.yield
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.data.local.data_store.DataStore
|
|
||||||
import ua.acclorite.book_story.data.local.dto.FavoriteDirectoryEntity
|
|
||||||
import ua.acclorite.book_story.data.local.notification.UpdatesNotificationService
|
|
||||||
import ua.acclorite.book_story.data.local.room.BookDao
|
import ua.acclorite.book_story.data.local.room.BookDao
|
||||||
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.color_preset.ColorPresetMapper
|
|
||||||
import ua.acclorite.book_story.data.mapper.history.HistoryMapper
|
|
||||||
import ua.acclorite.book_story.data.parser.FileParser
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
import ua.acclorite.book_story.data.parser.MarkdownParser
|
import ua.acclorite.book_story.data.parser.MarkdownParser
|
||||||
import ua.acclorite.book_story.data.parser.TextParser
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
import ua.acclorite.book_story.data.remote.GithubAPI
|
|
||||||
import ua.acclorite.book_story.data.remote.dto.LatestReleaseInfo
|
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.model.BookWithText
|
import ua.acclorite.book_story.domain.model.BookWithText
|
||||||
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.model.Chapter
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook
|
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import ua.acclorite.book_story.domain.util.CoverImage
|
import ua.acclorite.book_story.domain.util.CoverImage
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.util.UIText
|
||||||
import ua.acclorite.book_story.presentation.core.constants.Constants
|
|
||||||
import ua.acclorite.book_story.presentation.data.MainState
|
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
@ -51,33 +33,23 @@ import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
private const val GET_BOOK_FROM_FILE = "GET BOOK FROM FILE, REPOSITORY"
|
private const val GET_TEXT = "GET TEXT, REPO"
|
||||||
private const val GET_TEXT = "GET TEXT, REPOSITORY"
|
private const val GET_BOOKS = "GET BOOKS, REPO"
|
||||||
private const val GET_BOOKS = "GET BOOKS, REPOSITORY"
|
private const val GET_BOOKS_BY_ID = "GET BOOKS, REPO"
|
||||||
private const val GET_BOOKS_BY_ID = "GET BOOKS, REPOSITORY"
|
private const val INSERT_BOOK = "INSERT BOOK, REPO"
|
||||||
private const val INSERT_BOOK = "INSERT BOOK, REPOSITORY"
|
private const val UPDATE_BOOK = "UPDATE BOOK, REPO"
|
||||||
private const val UPDATE_BOOK = "UPDATE BOOK, REPOSITORY"
|
private const val DELETE_BOOKS = "DELETE BOOKS, REPO"
|
||||||
private const val DELETE_BOOKS = "DELETE BOOKS, REPOSITORY"
|
private const val CAN_RESET_COVER = "CAN RESET COVER, REPO"
|
||||||
private const val CAN_RESET_COVER = "CAN RESET COVER, REPOSITORY"
|
private const val RESET_COVER = "RESET COVER, REPO"
|
||||||
private const val RESET_COVER = "RESET COVER, REPOSITORY"
|
private const val CHECK_FOR_TEXT_UPDATE = "CHECK TEXT UPD, REPO"
|
||||||
private const val GET_ALL_SETTINGS = "GET ALL SETTINGS, REPOSITORY"
|
|
||||||
private const val GET_FILES_FROM_DEVICE = "GET FILES FROM DEVICE, REPOSITORY"
|
|
||||||
private const val CHECK_FOR_UPDATES = "CHECK FOR UPDATES, REPOSITORY"
|
|
||||||
private const val CHECK_FOR_TEXT_UPDATE = "CHECK FOR TEXT UPDATE, REPOSITORY"
|
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
@Singleton
|
@Singleton
|
||||||
class BookRepositoryImpl @Inject constructor(
|
class BookRepositoryImpl @Inject constructor(
|
||||||
private val application: Application,
|
private val application: Application,
|
||||||
private val database: BookDao,
|
private val database: BookDao,
|
||||||
private val dataStore: DataStore,
|
|
||||||
|
|
||||||
private val githubAPI: GithubAPI,
|
|
||||||
private val updatesNotificationService: UpdatesNotificationService,
|
|
||||||
|
|
||||||
private val bookMapper: BookMapper,
|
private val bookMapper: BookMapper,
|
||||||
private val historyMapper: HistoryMapper,
|
|
||||||
private val colorPresetMapper: ColorPresetMapper,
|
|
||||||
|
|
||||||
private val fileParser: FileParser,
|
private val fileParser: FileParser,
|
||||||
private val textParser: TextParser,
|
private val textParser: TextParser,
|
||||||
|
|
@ -610,355 +582,4 @@ class BookRepositoryImpl @Inject constructor(
|
||||||
Log.i(RESET_COVER, "Successfully reset cover image.")
|
Log.i(RESET_COVER, "Successfully reset cover image.")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Puts DataStore constant to [DataStore].
|
|
||||||
*/
|
|
||||||
override suspend fun <T> putDataToDataStore(key: Preferences.Key<T>, value: T) {
|
|
||||||
dataStore.putData(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all settings from DataStore and returns [MainState].
|
|
||||||
*/
|
|
||||||
override suspend fun getAllSettings(): MainState {
|
|
||||||
Log.i(GET_ALL_SETTINGS, "Getting all settings.")
|
|
||||||
val result = CompletableDeferred<MainState>()
|
|
||||||
|
|
||||||
withContext(Dispatchers.Default) {
|
|
||||||
val keys = dataStore.getAllData()
|
|
||||||
val data = mutableMapOf<String, Any>()
|
|
||||||
|
|
||||||
Log.i(GET_ALL_SETTINGS, "Got ${keys?.size} settings keys.")
|
|
||||||
|
|
||||||
val jobs = keys?.map { key ->
|
|
||||||
async {
|
|
||||||
val nullableData = dataStore.getNullableData(key)
|
|
||||||
|
|
||||||
if (nullableData == null) {
|
|
||||||
data.remove(key.name)
|
|
||||||
} else {
|
|
||||||
data[key.name] = nullableData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jobs?.awaitAll()
|
|
||||||
|
|
||||||
result.complete(MainState.initialize(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.await()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all matching files from device.
|
|
||||||
* Filters by [query] and sorts out not supported file formats and already added files.
|
|
||||||
*/
|
|
||||||
override suspend fun getFilesFromDevice(query: String): List<SelectableFile> {
|
|
||||||
Log.i(GET_FILES_FROM_DEVICE, "Getting files from device by query: \"$query\".")
|
|
||||||
|
|
||||||
val existingBooks = database
|
|
||||||
.searchBooks("")
|
|
||||||
.map { bookMapper.toBook(it) }
|
|
||||||
val supportedExtensions = Constants.EXTENSIONS
|
|
||||||
|
|
||||||
fun File.isValid(): Boolean {
|
|
||||||
if (!exists()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val isFileSupported = supportedExtensions.any { ext ->
|
|
||||||
name.endsWith(
|
|
||||||
ext,
|
|
||||||
ignoreCase = true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isFileSupported) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val isFileNotAdded = existingBooks.all {
|
|
||||||
it.filePath.lowercase().trim() != path.lowercase().trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isFileNotAdded) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val isQuery = if (query.isEmpty()) true else name.trim().lowercase()
|
|
||||||
.contains(query.trim().lowercase())
|
|
||||||
|
|
||||||
return isQuery
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun File.getAllFiles(): List<SelectableFile> {
|
|
||||||
val filesList = mutableListOf<SelectableFile>()
|
|
||||||
|
|
||||||
val files = listFiles()
|
|
||||||
if (files != null) {
|
|
||||||
for (file in files) {
|
|
||||||
if (!file.exists()) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
when {
|
|
||||||
file.isFile -> {
|
|
||||||
if (file.isValid()) {
|
|
||||||
filesList.add(
|
|
||||||
SelectableFile(
|
|
||||||
fileOrDirectory = file,
|
|
||||||
parentDirectory = this,
|
|
||||||
isDirectory = false,
|
|
||||||
isFavorite = false,
|
|
||||||
isSelected = false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.isDirectory -> {
|
|
||||||
val subDirectoryFiles = file.getAllFiles()
|
|
||||||
if (subDirectoryFiles.isNotEmpty()) {
|
|
||||||
filesList.add(
|
|
||||||
SelectableFile(
|
|
||||||
fileOrDirectory = file,
|
|
||||||
parentDirectory = this,
|
|
||||||
isDirectory = true,
|
|
||||||
isFavorite = database.favoriteDirectoryExits(file.path),
|
|
||||||
isSelected = false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
filesList.addAll(subDirectoryFiles)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return filesList
|
|
||||||
}
|
|
||||||
|
|
||||||
val rootDirectory = Environment.getExternalStorageDirectory()
|
|
||||||
if (
|
|
||||||
!rootDirectory.exists() ||
|
|
||||||
!rootDirectory.isDirectory ||
|
|
||||||
(Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED &&
|
|
||||||
Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED_READ_ONLY)
|
|
||||||
) {
|
|
||||||
Log.e(GET_FILES_FROM_DEVICE, "Could not correctly get root directory.")
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(GET_FILES_FROM_DEVICE, "Successfully got all matching files.")
|
|
||||||
return rootDirectory.getAllFiles()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets book from given file. If error happened, returns [NullableBook.Null].
|
|
||||||
*/
|
|
||||||
override suspend fun getBookFromFile(file: File): NullableBook {
|
|
||||||
val parsedBook = fileParser.parse(file)
|
|
||||||
if (parsedBook == null) {
|
|
||||||
Log.e(GET_BOOK_FROM_FILE, "Parsed file(${file.name}) is null.")
|
|
||||||
return NullableBook.Null(
|
|
||||||
file.name,
|
|
||||||
UIText.StringResource(R.string.error_something_went_wrong)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val parsedText = textParser.parse(file)
|
|
||||||
if (parsedText is Resource.Error) {
|
|
||||||
Log.e(GET_BOOK_FROM_FILE, "Parsed text(${file.name}) has error.")
|
|
||||||
return NullableBook.Null(
|
|
||||||
file.name,
|
|
||||||
parsedText.message
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(GET_BOOK_FROM_FILE, "Successfully got book from file.")
|
|
||||||
return NullableBook.NotNull(
|
|
||||||
bookWithTextAndCover = BookWithTextAndCover(
|
|
||||||
book = parsedBook.book.copy(
|
|
||||||
chapters = parsedText.data!!.map { it.chapter }.run {
|
|
||||||
if (this.size == 1) return@run emptyList()
|
|
||||||
this
|
|
||||||
}
|
|
||||||
),
|
|
||||||
coverImage = parsedBook.coverImage,
|
|
||||||
text = parsedText.data.map {
|
|
||||||
it.text
|
|
||||||
}.flatten()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert history in database.
|
|
||||||
*/
|
|
||||||
override suspend fun insertHistory(history: History) {
|
|
||||||
database.insertHistory(
|
|
||||||
listOf(
|
|
||||||
historyMapper.toHistoryEntity(
|
|
||||||
history
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all history from database.
|
|
||||||
*/
|
|
||||||
override suspend fun getHistory(): List<History> {
|
|
||||||
return database.getHistory().map {
|
|
||||||
historyMapper.toHistory(
|
|
||||||
it
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get latest history of the matching [bookId].
|
|
||||||
*/
|
|
||||||
override suspend fun getLatestBookHistory(bookId: Int): History? {
|
|
||||||
val history = database.getLatestHistoryForBook(bookId)
|
|
||||||
return history?.let { historyMapper.toHistory(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete whole history.
|
|
||||||
*/
|
|
||||||
override suspend fun deleteWholeHistory() {
|
|
||||||
database.deleteWholeHistory()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all history of the matching [bookId].
|
|
||||||
*/
|
|
||||||
override suspend fun deleteBookHistory(bookId: Int) {
|
|
||||||
database.deleteBookHistory(bookId)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete specific history item.
|
|
||||||
*/
|
|
||||||
override suspend fun deleteHistory(history: History) {
|
|
||||||
database.deleteHistory(
|
|
||||||
listOf(
|
|
||||||
historyMapper.toHistoryEntity(
|
|
||||||
history
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check for updates from GitHub.
|
|
||||||
*
|
|
||||||
* @param postNotification Whether notification should be send.
|
|
||||||
*/
|
|
||||||
override suspend fun checkForUpdates(postNotification: Boolean): LatestReleaseInfo? {
|
|
||||||
Log.i(CHECK_FOR_UPDATES, "Checking for updates. Post notification: $postNotification")
|
|
||||||
|
|
||||||
return withContext(Dispatchers.IO) {
|
|
||||||
try {
|
|
||||||
val result = githubAPI.getLatestRelease()
|
|
||||||
|
|
||||||
val version = result.tagName.substringAfter("v")
|
|
||||||
val currentVersion = application.getString(R.string.app_version)
|
|
||||||
|
|
||||||
if (version != currentVersion && postNotification) {
|
|
||||||
Log.i(CHECK_FOR_UPDATES, "Posting notification.")
|
|
||||||
updatesNotificationService.postNotification(
|
|
||||||
result
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e(CHECK_FOR_UPDATES, "Could not get latest release information.")
|
|
||||||
e.printStackTrace()
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update color preset.
|
|
||||||
*/
|
|
||||||
override suspend fun updateColorPreset(colorPreset: ColorPreset) {
|
|
||||||
database.updateColorPreset(
|
|
||||||
colorPresetMapper.toColorPresetEntity(
|
|
||||||
colorPreset,
|
|
||||||
if (colorPreset.id != -1) database.getColorPresetOrder(colorPreset.id)
|
|
||||||
else database.getColorPresetsSize()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select color preset. Only one can be selected at time.
|
|
||||||
*/
|
|
||||||
override suspend fun selectColorPreset(colorPreset: ColorPreset) {
|
|
||||||
database.getColorPresets().map {
|
|
||||||
it.copy(
|
|
||||||
isSelected = it.id == colorPreset.id
|
|
||||||
)
|
|
||||||
}.forEach {
|
|
||||||
database.updateColorPreset(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all color presets.
|
|
||||||
* Sorted by order (either manual or newest ones at the end).
|
|
||||||
*/
|
|
||||||
override suspend fun getColorPresets(): List<ColorPreset> {
|
|
||||||
return database.getColorPresets()
|
|
||||||
.sortedBy { it.order }
|
|
||||||
.map { colorPresetMapper.toColorPreset(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reorder color presets.
|
|
||||||
* Changes the order of the color presets.
|
|
||||||
*/
|
|
||||||
override suspend fun reorderColorPresets(orderedColorPresets: List<ColorPreset>) {
|
|
||||||
database.deleteColorPresets()
|
|
||||||
|
|
||||||
orderedColorPresets.forEachIndexed { index, colorPreset ->
|
|
||||||
database.updateColorPreset(
|
|
||||||
colorPresetMapper.toColorPresetEntity(colorPreset, order = index)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete color preset.
|
|
||||||
*/
|
|
||||||
override suspend fun deleteColorPreset(colorPreset: ColorPreset) {
|
|
||||||
database.deleteColorPreset(
|
|
||||||
colorPresetMapper.toColorPresetEntity(
|
|
||||||
colorPreset, -1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create or delete favorite directory if already exists.
|
|
||||||
*
|
|
||||||
* @param path Path to directory.
|
|
||||||
*/
|
|
||||||
override suspend fun updateFavoriteDirectory(path: String) {
|
|
||||||
if (database.favoriteDirectoryExits(path)) {
|
|
||||||
database.deleteFavoriteDirectory(
|
|
||||||
FavoriteDirectoryEntity(path)
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
database.insertFavoriteDirectory(
|
|
||||||
FavoriteDirectoryEntity(path)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.data.local.room.BookDao
|
||||||
|
import ua.acclorite.book_story.data.mapper.color_preset.ColorPresetMapper
|
||||||
|
import ua.acclorite.book_story.domain.model.ColorPreset
|
||||||
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color Preset repository.
|
||||||
|
* Manages all [ColorPreset] related work.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class ColorPresetRepositoryImpl @Inject constructor(
|
||||||
|
private val database: BookDao,
|
||||||
|
|
||||||
|
private val colorPresetMapper: ColorPresetMapper
|
||||||
|
) : ColorPresetRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update color preset.
|
||||||
|
*/
|
||||||
|
override suspend fun updateColorPreset(colorPreset: ColorPreset) {
|
||||||
|
database.updateColorPreset(
|
||||||
|
colorPresetMapper.toColorPresetEntity(
|
||||||
|
colorPreset,
|
||||||
|
if (colorPreset.id != -1) database.getColorPresetOrder(colorPreset.id)
|
||||||
|
else database.getColorPresetsSize()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select color preset. Only one can be selected at time.
|
||||||
|
*/
|
||||||
|
override suspend fun selectColorPreset(colorPreset: ColorPreset) {
|
||||||
|
database.getColorPresets().map {
|
||||||
|
it.copy(
|
||||||
|
isSelected = it.id == colorPreset.id
|
||||||
|
)
|
||||||
|
}.forEach {
|
||||||
|
database.updateColorPreset(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all color presets.
|
||||||
|
* Sorted by order (either manual or newest ones at the end).
|
||||||
|
*/
|
||||||
|
override suspend fun getColorPresets(): List<ColorPreset> {
|
||||||
|
return database.getColorPresets()
|
||||||
|
.sortedBy { it.order }
|
||||||
|
.map { colorPresetMapper.toColorPreset(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reorder color presets.
|
||||||
|
* Changes the order of the color presets.
|
||||||
|
*/
|
||||||
|
override suspend fun reorderColorPresets(orderedColorPresets: List<ColorPreset>) {
|
||||||
|
database.deleteColorPresets()
|
||||||
|
|
||||||
|
orderedColorPresets.forEachIndexed { index, colorPreset ->
|
||||||
|
database.updateColorPreset(
|
||||||
|
colorPresetMapper.toColorPresetEntity(colorPreset, order = index)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete color preset.
|
||||||
|
*/
|
||||||
|
override suspend fun deleteColorPreset(colorPreset: ColorPreset) {
|
||||||
|
database.deleteColorPreset(
|
||||||
|
colorPresetMapper.toColorPresetEntity(
|
||||||
|
colorPreset, -1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.datastore.preferences.core.Preferences
|
||||||
|
import kotlinx.coroutines.CompletableDeferred
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.awaitAll
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import ua.acclorite.book_story.data.local.data_store.DataStore
|
||||||
|
import ua.acclorite.book_story.domain.repository.DataStoreRepository
|
||||||
|
import ua.acclorite.book_story.presentation.data.MainState
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
private const val GET_ALL_SETTINGS = "GET SETTINGS, REPO"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Store repository.
|
||||||
|
* Manages all [DataStore] related work.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class DataStoreRepositoryImpl @Inject constructor(
|
||||||
|
private val dataStore: DataStore
|
||||||
|
) : DataStoreRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts DataStore constant to [DataStore].
|
||||||
|
*/
|
||||||
|
override suspend fun <T> putDataToDataStore(key: Preferences.Key<T>, value: T) {
|
||||||
|
dataStore.putData(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all settings from DataStore and returns [MainState].
|
||||||
|
*/
|
||||||
|
override suspend fun getAllSettings(): MainState {
|
||||||
|
Log.i(GET_ALL_SETTINGS, "Getting all settings.")
|
||||||
|
val result = CompletableDeferred<MainState>()
|
||||||
|
|
||||||
|
withContext(Dispatchers.Default) {
|
||||||
|
val keys = dataStore.getAllData()
|
||||||
|
val data = mutableMapOf<String, Any>()
|
||||||
|
|
||||||
|
Log.i(GET_ALL_SETTINGS, "Got ${keys?.size} settings keys.")
|
||||||
|
|
||||||
|
val jobs = keys?.map { key ->
|
||||||
|
async {
|
||||||
|
val nullableData = dataStore.getNullableData(key)
|
||||||
|
|
||||||
|
if (nullableData == null) {
|
||||||
|
data.remove(key.name)
|
||||||
|
} else {
|
||||||
|
data[key.name] = nullableData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jobs?.awaitAll()
|
||||||
|
|
||||||
|
result.complete(MainState.initialize(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.await()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.data.local.dto.FavoriteDirectoryEntity
|
||||||
|
import ua.acclorite.book_story.data.local.room.BookDao
|
||||||
|
import ua.acclorite.book_story.domain.repository.FavoriteDirectoryRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Favorite Directory repository.
|
||||||
|
* Manages all [ua.acclorite.book_story.data.local.dto.FavoriteDirectoryEntity] related work.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class FavoriteDirectoryRepositoryImpl @Inject constructor(
|
||||||
|
private val database: BookDao,
|
||||||
|
) : FavoriteDirectoryRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or delete favorite directory if already exists.
|
||||||
|
*
|
||||||
|
* @param path Path to directory.
|
||||||
|
*/
|
||||||
|
override suspend fun updateFavoriteDirectory(path: String) {
|
||||||
|
if (database.favoriteDirectoryExits(path)) {
|
||||||
|
database.deleteFavoriteDirectory(
|
||||||
|
FavoriteDirectoryEntity(path)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
database.insertFavoriteDirectory(
|
||||||
|
FavoriteDirectoryEntity(path)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
|
import android.os.Environment
|
||||||
|
import android.util.Log
|
||||||
|
import ua.acclorite.book_story.R
|
||||||
|
import ua.acclorite.book_story.data.local.room.BookDao
|
||||||
|
import ua.acclorite.book_story.data.mapper.book.BookMapper
|
||||||
|
import ua.acclorite.book_story.data.parser.FileParser
|
||||||
|
import ua.acclorite.book_story.data.parser.TextParser
|
||||||
|
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
||||||
|
import ua.acclorite.book_story.domain.model.NullableBook
|
||||||
|
import ua.acclorite.book_story.domain.model.NullableBook.NotNull
|
||||||
|
import ua.acclorite.book_story.domain.model.NullableBook.Null
|
||||||
|
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||||
|
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
||||||
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
|
import ua.acclorite.book_story.domain.util.UIText
|
||||||
|
import ua.acclorite.book_story.presentation.core.constants.Constants
|
||||||
|
import java.io.File
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
private const val GET_BOOK_FROM_FILE = "BOOK FROM FILE, REPO"
|
||||||
|
private const val GET_FILES_FROM_DEVICE = "FILES FROM DEVICE, REPO"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File System repository.
|
||||||
|
* Manages all File System([java.io.File]) related work.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class FileSystemRepositoryImpl @Inject constructor(
|
||||||
|
private val database: BookDao,
|
||||||
|
|
||||||
|
private val bookMapper: BookMapper,
|
||||||
|
|
||||||
|
private val fileParser: FileParser,
|
||||||
|
private val textParser: TextParser,
|
||||||
|
) : FileSystemRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all matching files from device.
|
||||||
|
* Filters by [query] and sorts out not supported file formats and already added files.
|
||||||
|
*/
|
||||||
|
override suspend fun getFilesFromDevice(query: String): List<SelectableFile> {
|
||||||
|
Log.i(GET_FILES_FROM_DEVICE, "Getting files from device by query: \"$query\".")
|
||||||
|
|
||||||
|
val existingBooks = database
|
||||||
|
.searchBooks("")
|
||||||
|
.map { bookMapper.toBook(it) }
|
||||||
|
val supportedExtensions = Constants.EXTENSIONS
|
||||||
|
|
||||||
|
fun File.isValid(): Boolean {
|
||||||
|
if (!exists()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val isFileSupported = supportedExtensions.any { ext ->
|
||||||
|
name.endsWith(
|
||||||
|
ext,
|
||||||
|
ignoreCase = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isFileSupported) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val isFileNotAdded = existingBooks.all {
|
||||||
|
it.filePath.lowercase().trim() != path.lowercase().trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isFileNotAdded) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val isQuery = if (query.isEmpty()) true else name.trim().lowercase()
|
||||||
|
.contains(query.trim().lowercase())
|
||||||
|
|
||||||
|
return isQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun File.getAllFiles(): List<SelectableFile> {
|
||||||
|
val filesList = mutableListOf<SelectableFile>()
|
||||||
|
|
||||||
|
val files = listFiles()
|
||||||
|
if (files != null) {
|
||||||
|
for (file in files) {
|
||||||
|
if (!file.exists()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
when {
|
||||||
|
file.isFile -> {
|
||||||
|
if (file.isValid()) {
|
||||||
|
filesList.add(
|
||||||
|
SelectableFile(
|
||||||
|
fileOrDirectory = file,
|
||||||
|
parentDirectory = this,
|
||||||
|
isDirectory = false,
|
||||||
|
isFavorite = false,
|
||||||
|
isSelected = false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.isDirectory -> {
|
||||||
|
val subDirectoryFiles = file.getAllFiles()
|
||||||
|
if (subDirectoryFiles.isNotEmpty()) {
|
||||||
|
filesList.add(
|
||||||
|
SelectableFile(
|
||||||
|
fileOrDirectory = file,
|
||||||
|
parentDirectory = this,
|
||||||
|
isDirectory = true,
|
||||||
|
isFavorite = database.favoriteDirectoryExits(file.path),
|
||||||
|
isSelected = false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
filesList.addAll(subDirectoryFiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filesList
|
||||||
|
}
|
||||||
|
|
||||||
|
val rootDirectory = Environment.getExternalStorageDirectory()
|
||||||
|
if (
|
||||||
|
!rootDirectory.exists() ||
|
||||||
|
!rootDirectory.isDirectory ||
|
||||||
|
(Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED &&
|
||||||
|
Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED_READ_ONLY)
|
||||||
|
) {
|
||||||
|
Log.e(GET_FILES_FROM_DEVICE, "Could not correctly get root directory.")
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(GET_FILES_FROM_DEVICE, "Successfully got all matching files.")
|
||||||
|
return rootDirectory.getAllFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets book from given file. If error happened, returns [NullableBook.Null].
|
||||||
|
*/
|
||||||
|
override suspend fun getBookFromFile(file: File): NullableBook {
|
||||||
|
val parsedBook = fileParser.parse(file)
|
||||||
|
if (parsedBook == null) {
|
||||||
|
Log.e(GET_BOOK_FROM_FILE, "Parsed file(${file.name}) is null.")
|
||||||
|
return Null(
|
||||||
|
file.name,
|
||||||
|
UIText.StringResource(R.string.error_something_went_wrong)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val parsedText = textParser.parse(file)
|
||||||
|
if (parsedText is Resource.Error) {
|
||||||
|
Log.e(GET_BOOK_FROM_FILE, "Parsed text(${file.name}) has error.")
|
||||||
|
return Null(
|
||||||
|
file.name,
|
||||||
|
parsedText.message
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(GET_BOOK_FROM_FILE, "Successfully got book from file.")
|
||||||
|
return NotNull(
|
||||||
|
bookWithTextAndCover = BookWithTextAndCover(
|
||||||
|
book = parsedBook.book.copy(
|
||||||
|
chapters = parsedText.data!!.map { it.chapter }.run {
|
||||||
|
if (this.size == 1) return@run emptyList()
|
||||||
|
this
|
||||||
|
}
|
||||||
|
),
|
||||||
|
coverImage = parsedBook.coverImage,
|
||||||
|
text = parsedText.data.map {
|
||||||
|
it.text
|
||||||
|
}.flatten()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.data.local.room.BookDao
|
||||||
|
import ua.acclorite.book_story.data.mapper.history.HistoryMapper
|
||||||
|
import ua.acclorite.book_story.domain.model.History
|
||||||
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* History repository.
|
||||||
|
* Manages all [History] related work.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class HistoryRepositoryImpl @Inject constructor(
|
||||||
|
private val database: BookDao,
|
||||||
|
|
||||||
|
private val historyMapper: HistoryMapper,
|
||||||
|
) : HistoryRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert history in database.
|
||||||
|
*/
|
||||||
|
override suspend fun insertHistory(history: History) {
|
||||||
|
database.insertHistory(
|
||||||
|
listOf(
|
||||||
|
historyMapper.toHistoryEntity(
|
||||||
|
history
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all history from database.
|
||||||
|
*/
|
||||||
|
override suspend fun getHistory(): List<History> {
|
||||||
|
return database.getHistory().map {
|
||||||
|
historyMapper.toHistory(
|
||||||
|
it
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get latest history of the matching [bookId].
|
||||||
|
*/
|
||||||
|
override suspend fun getLatestBookHistory(bookId: Int): History? {
|
||||||
|
val history = database.getLatestHistoryForBook(bookId)
|
||||||
|
return history?.let { historyMapper.toHistory(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete whole history.
|
||||||
|
*/
|
||||||
|
override suspend fun deleteWholeHistory() {
|
||||||
|
database.deleteWholeHistory()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all history of the matching [bookId].
|
||||||
|
*/
|
||||||
|
override suspend fun deleteBookHistory(bookId: Int) {
|
||||||
|
database.deleteBookHistory(bookId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete specific history item.
|
||||||
|
*/
|
||||||
|
override suspend fun deleteHistory(history: History) {
|
||||||
|
database.deleteHistory(
|
||||||
|
listOf(
|
||||||
|
historyMapper.toHistoryEntity(
|
||||||
|
history
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.util.Log
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import ua.acclorite.book_story.R
|
||||||
|
import ua.acclorite.book_story.data.local.notification.UpdatesNotificationService
|
||||||
|
import ua.acclorite.book_story.data.remote.GithubAPI
|
||||||
|
import ua.acclorite.book_story.data.remote.dto.LatestReleaseInfo
|
||||||
|
import ua.acclorite.book_story.domain.repository.RemoteRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
private const val CHECK_FOR_UPDATES = "CHECK FOR UPD, REPO"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote repository.
|
||||||
|
* Manages all API(online) related work.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class RemoteRepositoryImpl @Inject constructor(
|
||||||
|
private val application: Application,
|
||||||
|
|
||||||
|
private val githubAPI: GithubAPI,
|
||||||
|
private val updatesNotificationService: UpdatesNotificationService,
|
||||||
|
) : RemoteRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for updates from GitHub.
|
||||||
|
*
|
||||||
|
* @param postNotification Whether notification should be send.
|
||||||
|
*/
|
||||||
|
override suspend fun checkForUpdates(postNotification: Boolean): LatestReleaseInfo? {
|
||||||
|
Log.i(CHECK_FOR_UPDATES, "Checking for updates. Post notification: $postNotification")
|
||||||
|
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
val result = githubAPI.getLatestRelease()
|
||||||
|
|
||||||
|
val version = result.tagName.substringAfter("v")
|
||||||
|
val currentVersion = application.getString(R.string.app_version)
|
||||||
|
|
||||||
|
if (version != currentVersion && postNotification) {
|
||||||
|
Log.i(CHECK_FOR_UPDATES, "Posting notification.")
|
||||||
|
updatesNotificationService.postNotification(
|
||||||
|
result
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(CHECK_FOR_UPDATES, "Could not get latest release information.")
|
||||||
|
e.printStackTrace()
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,24 +1,15 @@
|
||||||
package ua.acclorite.book_story.domain.repository
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.datastore.preferences.core.Preferences
|
|
||||||
import ua.acclorite.book_story.data.remote.dto.LatestReleaseInfo
|
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.model.BookWithText
|
import ua.acclorite.book_story.domain.model.BookWithText
|
||||||
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.model.Chapter
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook
|
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
|
||||||
import ua.acclorite.book_story.domain.util.CoverImage
|
import ua.acclorite.book_story.domain.util.CoverImage
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.presentation.data.MainState
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
interface BookRepository {
|
interface BookRepository {
|
||||||
|
|
||||||
/* ------ Books ------------------------------ */
|
|
||||||
suspend fun getBooks(
|
suspend fun getBooks(
|
||||||
query: String
|
query: String
|
||||||
): List<Book>
|
): List<Book>
|
||||||
|
|
@ -61,82 +52,4 @@ interface BookRepository {
|
||||||
suspend fun resetCoverImage(
|
suspend fun resetCoverImage(
|
||||||
bookId: Int
|
bookId: Int
|
||||||
): Boolean
|
): Boolean
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - */
|
|
||||||
|
|
||||||
|
|
||||||
/* ------ DataStore -------------------------- */
|
|
||||||
suspend fun <T> putDataToDataStore(
|
|
||||||
key: Preferences.Key<T>,
|
|
||||||
value: T
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun getAllSettings(): MainState
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - */
|
|
||||||
|
|
||||||
|
|
||||||
/* ------ File System ------------------------ */
|
|
||||||
suspend fun getFilesFromDevice(
|
|
||||||
query: String = ""
|
|
||||||
): List<SelectableFile>
|
|
||||||
|
|
||||||
suspend fun getBookFromFile(
|
|
||||||
file: File
|
|
||||||
): NullableBook
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - */
|
|
||||||
|
|
||||||
|
|
||||||
/* ------ History ---------------------------- */
|
|
||||||
suspend fun insertHistory(
|
|
||||||
history: History
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun getHistory(): List<History>
|
|
||||||
|
|
||||||
suspend fun getLatestBookHistory(
|
|
||||||
bookId: Int
|
|
||||||
): History?
|
|
||||||
|
|
||||||
suspend fun deleteWholeHistory()
|
|
||||||
|
|
||||||
suspend fun deleteBookHistory(
|
|
||||||
bookId: Int
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun deleteHistory(
|
|
||||||
history: History
|
|
||||||
)
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - */
|
|
||||||
|
|
||||||
|
|
||||||
/* ------ API (GitHub) ----------------------- */
|
|
||||||
suspend fun checkForUpdates(
|
|
||||||
postNotification: Boolean
|
|
||||||
): LatestReleaseInfo?
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - */
|
|
||||||
|
|
||||||
|
|
||||||
/* ------ Color Presets ---------------------- */
|
|
||||||
suspend fun updateColorPreset(
|
|
||||||
colorPreset: ColorPreset
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun selectColorPreset(
|
|
||||||
colorPreset: ColorPreset
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun getColorPresets(): List<ColorPreset>
|
|
||||||
|
|
||||||
suspend fun reorderColorPresets(
|
|
||||||
orderedColorPresets: List<ColorPreset>
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun deleteColorPreset(
|
|
||||||
colorPreset: ColorPreset
|
|
||||||
)
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - */
|
|
||||||
|
|
||||||
|
|
||||||
/* ------ Favorite Directories --------------- */
|
|
||||||
suspend fun updateFavoriteDirectory(path: String)
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - */
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.domain.model.ColorPreset
|
||||||
|
|
||||||
|
interface ColorPresetRepository {
|
||||||
|
|
||||||
|
suspend fun updateColorPreset(
|
||||||
|
colorPreset: ColorPreset
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun selectColorPreset(
|
||||||
|
colorPreset: ColorPreset
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun getColorPresets(): List<ColorPreset>
|
||||||
|
|
||||||
|
suspend fun reorderColorPresets(
|
||||||
|
orderedColorPresets: List<ColorPreset>
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun deleteColorPreset(
|
||||||
|
colorPreset: ColorPreset
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
|
import androidx.datastore.preferences.core.Preferences
|
||||||
|
import ua.acclorite.book_story.presentation.data.MainState
|
||||||
|
|
||||||
|
interface DataStoreRepository {
|
||||||
|
|
||||||
|
suspend fun <T> putDataToDataStore(
|
||||||
|
key: Preferences.Key<T>,
|
||||||
|
value: T
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun getAllSettings(): MainState
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
|
interface FavoriteDirectoryRepository {
|
||||||
|
|
||||||
|
suspend fun updateFavoriteDirectory(path: String)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.domain.model.NullableBook
|
||||||
|
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
interface FileSystemRepository {
|
||||||
|
|
||||||
|
suspend fun getFilesFromDevice(
|
||||||
|
query: String = ""
|
||||||
|
): List<SelectableFile>
|
||||||
|
|
||||||
|
suspend fun getBookFromFile(
|
||||||
|
file: File
|
||||||
|
): NullableBook
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.domain.model.History
|
||||||
|
|
||||||
|
interface HistoryRepository {
|
||||||
|
|
||||||
|
suspend fun insertHistory(
|
||||||
|
history: History
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun getHistory(): List<History>
|
||||||
|
|
||||||
|
suspend fun getLatestBookHistory(
|
||||||
|
bookId: Int
|
||||||
|
): History?
|
||||||
|
|
||||||
|
suspend fun deleteWholeHistory()
|
||||||
|
|
||||||
|
suspend fun deleteBookHistory(
|
||||||
|
bookId: Int
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun deleteHistory(
|
||||||
|
history: History
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ua.acclorite.book_story.domain.repository
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.data.remote.dto.LatestReleaseInfo
|
||||||
|
|
||||||
|
interface RemoteRepository {
|
||||||
|
|
||||||
|
suspend fun checkForUpdates(
|
||||||
|
postNotification: Boolean
|
||||||
|
): LatestReleaseInfo?
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,9 @@ import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CheckForTextUpdate @Inject constructor(private val repository: BookRepository) {
|
class CheckForTextUpdate @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(bookId: Int): Resource<Pair<List<String>, List<Chapter>>?> {
|
suspend fun execute(bookId: Int): Resource<Pair<List<String>, List<Chapter>>?> {
|
||||||
return repository.checkForTextUpdate(bookId)
|
return repository.checkForTextUpdate(bookId)
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,18 @@ package ua.acclorite.book_story.domain.use_case.book
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DeleteBooks @Inject constructor(private val repository: BookRepository) {
|
class DeleteBooks @Inject constructor(
|
||||||
|
private val bookRepository: BookRepository,
|
||||||
|
private val historyRepository: HistoryRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(books: List<Book>) {
|
suspend fun execute(books: List<Book>) {
|
||||||
repository.deleteBooks(books)
|
bookRepository.deleteBooks(books)
|
||||||
books.forEach {
|
books.forEach {
|
||||||
repository.deleteBookHistory(it.id)
|
historyRepository.deleteBookHistory(it.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,7 +4,9 @@ import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetBookById @Inject constructor(private val repository: BookRepository) {
|
class GetBookById @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(id: Int): Book? {
|
suspend fun execute(id: Int): Book? {
|
||||||
return repository.getBooksById(listOf(id)).firstOrNull()
|
return repository.getBooksById(listOf(id)).firstOrNull()
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetBooks @Inject constructor(private val repository: BookRepository) {
|
class GetBooks @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(query: String): List<Book> {
|
suspend fun execute(query: String): List<Book> {
|
||||||
return repository.getBooks(query)
|
return repository.getBooks(query)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetBooksById @Inject constructor(private val repository: BookRepository) {
|
class GetBooksById @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(ids: List<Int>): List<Book> {
|
suspend fun execute(ids: List<Int>): List<Book> {
|
||||||
return repository.getBooksById(ids)
|
return repository.getBooksById(ids)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import androidx.compose.ui.text.AnnotatedString
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetText @Inject constructor(private val repository: BookRepository) {
|
class GetText @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(textPath: String): List<AnnotatedString> {
|
suspend fun execute(textPath: String): List<AnnotatedString> {
|
||||||
return repository.getBookText(textPath = textPath)
|
return repository.getBookText(textPath = textPath)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ import ua.acclorite.book_story.domain.model.BookWithTextAndCover
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class InsertBook @Inject constructor(private val repository: BookRepository) {
|
class InsertBook @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(
|
suspend fun execute(
|
||||||
bookWithTextAndCover: BookWithTextAndCover
|
bookWithTextAndCover: BookWithTextAndCover
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class UpdateBook @Inject constructor(private val repository: BookRepository) {
|
class UpdateBook @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(book: Book) {
|
suspend fun execute(book: Book) {
|
||||||
repository.updateBook(book)
|
repository.updateBook(book)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import ua.acclorite.book_story.domain.model.BookWithText
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class UpdateBookWithText @Inject constructor(private val repository: BookRepository) {
|
class UpdateBookWithText @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(bookWithText: BookWithText): Boolean {
|
suspend fun execute(bookWithText: BookWithText): Boolean {
|
||||||
return repository.updateBookWithText(bookWithText)
|
return repository.updateBookWithText(bookWithText)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
import ua.acclorite.book_story.domain.util.CoverImage
|
import ua.acclorite.book_story.domain.util.CoverImage
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class UpdateCoverImageOfBook @Inject constructor(private val repository: BookRepository) {
|
class UpdateCoverImageOfBook @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(bookWithOldCover: Book, newCoverImage: CoverImage?) {
|
suspend fun execute(bookWithOldCover: Book, newCoverImage: CoverImage?) {
|
||||||
repository.updateCoverImageOfBook(bookWithOldCover, newCoverImage)
|
repository.updateCoverImageOfBook(bookWithOldCover, newCoverImage)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.model.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DeleteColorPreset @Inject constructor(private val repository: BookRepository) {
|
class DeleteColorPreset @Inject constructor(
|
||||||
|
private val repository: ColorPresetRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(colorPreset: ColorPreset) {
|
suspend fun execute(colorPreset: ColorPreset) {
|
||||||
repository.deleteColorPreset(colorPreset)
|
repository.deleteColorPreset(colorPreset)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.model.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetColorPresets @Inject constructor(private val repository: BookRepository) {
|
class GetColorPresets @Inject constructor(
|
||||||
|
private val repository: ColorPresetRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(): List<ColorPreset> {
|
suspend fun execute(): List<ColorPreset> {
|
||||||
return repository.getColorPresets()
|
return repository.getColorPresets()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.model.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ReorderColorPresets @Inject constructor(private val repository: BookRepository) {
|
class ReorderColorPresets @Inject constructor(
|
||||||
|
private val repository: ColorPresetRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(reorderedColorPresets: List<ColorPreset>) {
|
suspend fun execute(reorderedColorPresets: List<ColorPreset>) {
|
||||||
repository.reorderColorPresets(reorderedColorPresets)
|
repository.reorderColorPresets(reorderedColorPresets)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.model.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SelectColorPreset @Inject constructor(private val repository: BookRepository) {
|
class SelectColorPreset @Inject constructor(
|
||||||
|
private val repository: ColorPresetRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(colorPreset: ColorPreset) {
|
suspend fun execute(colorPreset: ColorPreset) {
|
||||||
repository.selectColorPreset(colorPreset)
|
repository.selectColorPreset(colorPreset)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.color_preset
|
package ua.acclorite.book_story.domain.use_case.color_preset
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.ColorPreset
|
import ua.acclorite.book_story.domain.model.ColorPreset
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.ColorPresetRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class UpdateColorPreset @Inject constructor(private val repository: BookRepository) {
|
class UpdateColorPreset @Inject constructor(
|
||||||
|
private val repository: ColorPresetRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(colorPreset: ColorPreset) {
|
suspend fun execute(colorPreset: ColorPreset) {
|
||||||
repository.updateColorPreset(colorPreset)
|
repository.updateColorPreset(colorPreset)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.common
|
package ua.acclorite.book_story.domain.use_case.data_store
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.core.os.LocaleListCompat
|
import androidx.core.os.LocaleListCompat
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.DataStoreRepository
|
||||||
import ua.acclorite.book_story.presentation.core.constants.DataStoreConstants
|
import ua.acclorite.book_story.presentation.core.constants.DataStoreConstants
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ChangeLanguage @Inject constructor(private val repository: BookRepository) {
|
class ChangeLanguage @Inject constructor(
|
||||||
|
private val repository: DataStoreRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(language: String) {
|
suspend fun execute(language: String) {
|
||||||
val appLocale = LocaleListCompat.forLanguageTags(language)
|
val appLocale = LocaleListCompat.forLanguageTags(language)
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.data_store
|
package ua.acclorite.book_story.domain.use_case.data_store
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.DataStoreRepository
|
||||||
import ua.acclorite.book_story.presentation.data.MainState
|
import ua.acclorite.book_story.presentation.data.MainState
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetAllSettings @Inject constructor(
|
class GetAllSettings @Inject constructor(
|
||||||
private val repository: BookRepository
|
private val repository: DataStoreRepository
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun execute(): MainState {
|
suspend fun execute(): MainState {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.data_store
|
package ua.acclorite.book_story.domain.use_case.data_store
|
||||||
|
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.DataStoreRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SetDatastore @Inject constructor(private val repository: BookRepository) {
|
class SetDatastore @Inject constructor(
|
||||||
|
private val repository: DataStoreRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun <T> execute(key: Preferences.Key<T>, value: T) {
|
suspend fun <T> execute(key: Preferences.Key<T>, value: T) {
|
||||||
repository.putDataToDataStore(key, value)
|
repository.putDataToDataStore(key, value)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.favorite_directory
|
package ua.acclorite.book_story.domain.use_case.favorite_directory
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.FavoriteDirectoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class UpdateFavoriteDirectory @Inject constructor(private val repository: BookRepository) {
|
class UpdateFavoriteDirectory @Inject constructor(
|
||||||
|
private val repository: FavoriteDirectoryRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(path: String) {
|
suspend fun execute(path: String) {
|
||||||
return repository.updateFavoriteDirectory(path)
|
return repository.updateFavoriteDirectory(path)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.file_system
|
package ua.acclorite.book_story.domain.use_case.file_system
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook
|
import ua.acclorite.book_story.domain.model.NullableBook
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetBookFromFile @Inject constructor(
|
class GetBookFromFile @Inject constructor(
|
||||||
private val repository: BookRepository
|
private val repository: FileSystemRepository
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun execute(file: File): NullableBook {
|
suspend fun execute(file: File): NullableBook {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.file_system
|
package ua.acclorite.book_story.domain.use_case.file_system
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.FileSystemRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetFilesFromDevice @Inject constructor(
|
class GetFilesFromDevice @Inject constructor(
|
||||||
private val repository: BookRepository
|
private val repository: FileSystemRepository
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun execute(query: String): List<SelectableFile> {
|
suspend fun execute(query: String): List<SelectableFile> {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.history
|
package ua.acclorite.book_story.domain.use_case.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.model.History
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DeleteHistory @Inject constructor(private val repository: BookRepository) {
|
class DeleteHistory @Inject constructor(
|
||||||
|
private val repository: HistoryRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(history: History) {
|
suspend fun execute(history: History) {
|
||||||
repository.deleteHistory(history)
|
repository.deleteHistory(history)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.history
|
package ua.acclorite.book_story.domain.use_case.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DeleteWholeHistory @Inject constructor(private val repository: BookRepository) {
|
class DeleteWholeHistory @Inject constructor(
|
||||||
|
private val repository: HistoryRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute() {
|
suspend fun execute() {
|
||||||
repository.deleteWholeHistory()
|
repository.deleteWholeHistory()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.history
|
package ua.acclorite.book_story.domain.use_case.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.model.History
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetHistory @Inject constructor(private val repository: BookRepository) {
|
class GetHistory @Inject constructor(
|
||||||
|
private val repository: HistoryRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(): List<History> {
|
suspend fun execute(): List<History> {
|
||||||
return repository.getHistory()
|
return repository.getHistory()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.history
|
package ua.acclorite.book_story.domain.use_case.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.model.History
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GetLatestHistory @Inject constructor(private val repository: BookRepository) {
|
class GetLatestHistory @Inject constructor(
|
||||||
|
private val repository: HistoryRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(bookId: Int): History? {
|
suspend fun execute(bookId: Int): History? {
|
||||||
return repository.getLatestBookHistory(bookId)
|
return repository.getLatestBookHistory(bookId)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.history
|
package ua.acclorite.book_story.domain.use_case.history
|
||||||
|
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.model.History
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.HistoryRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class InsertHistory @Inject constructor(private val repository: BookRepository) {
|
class InsertHistory @Inject constructor(
|
||||||
|
private val repository: HistoryRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(history: History) {
|
suspend fun execute(history: History) {
|
||||||
repository.insertHistory(history)
|
repository.insertHistory(history)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package ua.acclorite.book_story.domain.use_case.remote
|
package ua.acclorite.book_story.domain.use_case.remote
|
||||||
|
|
||||||
import ua.acclorite.book_story.data.remote.dto.LatestReleaseInfo
|
import ua.acclorite.book_story.data.remote.dto.LatestReleaseInfo
|
||||||
import ua.acclorite.book_story.domain.repository.BookRepository
|
import ua.acclorite.book_story.domain.repository.RemoteRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CheckForUpdates @Inject constructor(private val repository: BookRepository) {
|
class CheckForUpdates @Inject constructor(
|
||||||
|
private val repository: RemoteRepository
|
||||||
|
) {
|
||||||
|
|
||||||
suspend fun execute(postNotification: Boolean): LatestReleaseInfo? {
|
suspend fun execute(postNotification: Boolean): LatestReleaseInfo? {
|
||||||
return repository.checkForUpdates(postNotification)
|
return repository.checkForUpdates(postNotification)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ua.acclorite.book_story.domain.use_case.common.ChangeLanguage
|
import ua.acclorite.book_story.domain.use_case.data_store.ChangeLanguage
|
||||||
import ua.acclorite.book_story.domain.use_case.data_store.GetAllSettings
|
import ua.acclorite.book_story.domain.use_case.data_store.GetAllSettings
|
||||||
import ua.acclorite.book_story.domain.use_case.data_store.SetDatastore
|
import ua.acclorite.book_story.domain.use_case.data_store.SetDatastore
|
||||||
import ua.acclorite.book_story.domain.use_case.remote.CheckForUpdates
|
import ua.acclorite.book_story.domain.use_case.remote.CheckForUpdates
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue