Start working on proper MVVM

This commit is contained in:
Syer10
2022-06-30 18:58:37 -04:00
parent b2ec937c2b
commit 20a2262638
197 changed files with 1224 additions and 1075 deletions

View File

@@ -13,8 +13,8 @@ plugins {
dependencies { dependencies {
implementation(projects.core) implementation(projects.core)
implementation(projects.i18n) implementation(projects.i18n)
implementation(projects.data)
implementation(projects.domain) implementation(projects.domain)
implementation(projects.data)
implementation(projects.uiCore) implementation(projects.uiCore)
implementation(projects.presentation) implementation(projects.presentation)

View File

@@ -15,7 +15,7 @@ import androidx.lifecycle.lifecycleScope
import ca.gosyer.jui.android.data.notification.Notifications import ca.gosyer.jui.android.data.notification.Notifications
import ca.gosyer.jui.core.prefs.Preference import ca.gosyer.jui.core.prefs.Preference
import ca.gosyer.jui.core.prefs.getAsFlow import ca.gosyer.jui.core.prefs.getAsFlow
import ca.gosyer.jui.data.ui.model.ThemeMode import ca.gosyer.jui.domain.ui.model.ThemeMode
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import org.lighthousegames.logging.logging import org.lighthousegames.logging.logging
import java.util.Locale import java.util.Locale

View File

@@ -9,6 +9,7 @@ package ca.gosyer.jui.android
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import ca.gosyer.jui.core.di.AppScope import ca.gosyer.jui.core.di.AppScope
import ca.gosyer.jui.data.DataComponent
import ca.gosyer.jui.domain.DomainComponent import ca.gosyer.jui.domain.DomainComponent
import ca.gosyer.jui.ui.base.UiComponent import ca.gosyer.jui.ui.base.UiComponent
import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Component
@@ -20,7 +21,7 @@ abstract class AppComponent(
@get:AppScope @get:AppScope
@get:Provides @get:Provides
val context: Context val context: Context
) : DomainComponent, UiComponent { ) : DataComponent, DomainComponent, UiComponent {
abstract val appMigrations: AppMigrations abstract val appMigrations: AppMigrations

View File

@@ -7,7 +7,7 @@
package ca.gosyer.jui.android package ca.gosyer.jui.android
import ca.gosyer.jui.android.data.update.UpdateCheckWorker import ca.gosyer.jui.android.data.update.UpdateCheckWorker
import ca.gosyer.jui.data.migration.MigrationPreferences import ca.gosyer.jui.domain.migration.service.MigrationPreferences
import ca.gosyer.jui.uicore.vm.ContextWrapper import ca.gosyer.jui.uicore.vm.ContextWrapper
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject

View File

@@ -20,13 +20,13 @@ import ca.gosyer.jui.android.util.notificationManager
import ca.gosyer.jui.core.lang.chop import ca.gosyer.jui.core.lang.chop
import ca.gosyer.jui.core.lang.throwIfCancellation import ca.gosyer.jui.core.lang.throwIfCancellation
import ca.gosyer.jui.core.prefs.getAsFlow import ca.gosyer.jui.core.prefs.getAsFlow
import ca.gosyer.jui.data.download.model.DownloadState
import ca.gosyer.jui.data.download.model.DownloadStatus
import ca.gosyer.jui.data.server.requests.downloadsQuery
import ca.gosyer.jui.domain.base.WebsocketService.Actions import ca.gosyer.jui.domain.base.WebsocketService.Actions
import ca.gosyer.jui.domain.base.WebsocketService.Status import ca.gosyer.jui.domain.base.WebsocketService.Status
import ca.gosyer.jui.domain.download.DownloadService import ca.gosyer.jui.domain.download.model.DownloadState
import ca.gosyer.jui.domain.download.DownloadService.Companion.status import ca.gosyer.jui.domain.download.model.DownloadStatus
import ca.gosyer.jui.domain.download.service.DownloadService
import ca.gosyer.jui.domain.download.service.DownloadService.Companion.status
import ca.gosyer.jui.domain.server.model.requests.downloadsQuery
import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.i18n.MR
import dev.icerock.moko.resources.desc.desc import dev.icerock.moko.resources.desc.desc
import dev.icerock.moko.resources.format import dev.icerock.moko.resources.format

View File

@@ -18,7 +18,7 @@ import ca.gosyer.jui.android.AppComponent
import ca.gosyer.jui.android.data.notification.Notifications import ca.gosyer.jui.android.data.notification.Notifications
import ca.gosyer.jui.android.util.notificationBuilder import ca.gosyer.jui.android.util.notificationBuilder
import ca.gosyer.jui.android.util.notificationManager import ca.gosyer.jui.android.util.notificationManager
import ca.gosyer.jui.domain.update.UpdateChecker.Update import ca.gosyer.jui.domain.updates.interactor.UpdateChecker.Update
import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.i18n.MR
import dev.icerock.moko.resources.desc.desc import dev.icerock.moko.resources.desc.desc
import kotlinx.coroutines.flow.singleOrNull import kotlinx.coroutines.flow.singleOrNull

View File

@@ -4,12 +4,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models package ca.gosyer.jui.core
import kotlinx.serialization.Serializable import ca.gosyer.jui.core.prefs.PreferenceStoreFactory
@Serializable interface CoreComponent {
data class Page( val preferenceFactory: PreferenceStoreFactory
val index: Int, }
var imageUrl: String,
)

View File

@@ -38,15 +38,12 @@ kotlin {
api(libs.serialization.json) api(libs.serialization.json)
api(libs.kotlinInject.runtime) api(libs.kotlinInject.runtime)
api(libs.ktor.core) api(libs.ktor.core)
api(libs.ktor.contentNegotiation)
api(libs.ktor.serialization.json)
api(libs.ktor.auth)
api(libs.ktor.logging)
api(libs.ktor.websockets) api(libs.ktor.websockets)
api(libs.okio) api(libs.okio)
api(libs.dateTime) api(libs.dateTime)
api(projects.core) api(projects.core)
api(projects.i18n) api(projects.i18n)
api(projects.domain)
} }
} }
val commonTest by getting { val commonTest by getting {
@@ -59,7 +56,6 @@ kotlin {
val desktopMain by getting { val desktopMain by getting {
dependencies { dependencies {
api(kotlin("stdlib-jdk8")) api(kotlin("stdlib-jdk8"))
api(libs.ktor.okHttp)
} }
} }
val desktopTest by getting { val desktopTest by getting {
@@ -68,7 +64,6 @@ kotlin {
val androidMain by getting { val androidMain by getting {
dependencies { dependencies {
api(kotlin("stdlib-jdk8")) api(kotlin("stdlib-jdk8"))
api(libs.ktor.okHttp)
} }
} }
val androidTest by getting { val androidTest by getting {

View File

@@ -1,94 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.data
import ca.gosyer.jui.core.di.AppScope
import ca.gosyer.jui.core.prefs.PreferenceStoreFactory
import ca.gosyer.jui.data.catalog.CatalogPreferences
import ca.gosyer.jui.data.extension.ExtensionPreferences
import ca.gosyer.jui.data.library.LibraryPreferences
import ca.gosyer.jui.data.migration.MigrationPreferences
import ca.gosyer.jui.data.reader.ReaderPreferences
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.HttpProvider
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.ui.UiPreferences
import ca.gosyer.jui.data.update.UpdatePreferences
import me.tatarka.inject.annotations.Provides
actual interface DataComponent {
val preferenceFactory: PreferenceStoreFactory
val httpProvider: HttpProvider
val http: Http
val serverPreferences: ServerPreferences
val extensionPreferences: ExtensionPreferences
val catalogPreferences: CatalogPreferences
val libraryPreferences: LibraryPreferences
val readerPreferences: ReaderPreferences
val uiPreferences: UiPreferences
val migrationPreferences: MigrationPreferences
val updatePreferences: UpdatePreferences
@get:AppScope
@get:Provides
val serverPreferencesFactory: ServerPreferences
get() = ServerPreferences(preferenceFactory.create("server"))
@get:AppScope
@get:Provides
val extensionPreferencesFactory: ExtensionPreferences
get() = ExtensionPreferences(preferenceFactory.create("extension"))
@get:AppScope
@get:Provides
val catalogPreferencesFactory: CatalogPreferences
get() = CatalogPreferences(preferenceFactory.create("catalog"))
@get:AppScope
@get:Provides
val libraryPreferencesFactory: LibraryPreferences
get() = LibraryPreferences(preferenceFactory.create("library"))
@get:AppScope
@get:Provides
val readerPreferencesFactory: ReaderPreferences
get() = ReaderPreferences(preferenceFactory.create("reader")) { name ->
preferenceFactory.create("reader", name)
}
@get:AppScope
@get:Provides
val uiPreferencesFactory: UiPreferences
get() = UiPreferences(preferenceFactory.create("ui"))
@get:AppScope
@get:Provides
val migrationPreferencesFactory: MigrationPreferences
get() = MigrationPreferences(preferenceFactory.create("migration"))
@get:AppScope
@get:Provides
val updatePreferencesFactory: UpdatePreferences
get() = UpdatePreferences(preferenceFactory.create("update"))
@get:AppScope
@get:Provides
val httpFactory: Http
get() = httpProvider.get(serverPreferences)
companion object
}

View File

@@ -6,4 +6,57 @@
package ca.gosyer.jui.data package ca.gosyer.jui.data
expect interface DataComponent import ca.gosyer.jui.data.backup.BackupRepositoryImpl
import ca.gosyer.jui.data.category.CategoryRepositoryImpl
import ca.gosyer.jui.data.chapter.ChapterRepositoryImpl
import ca.gosyer.jui.data.download.DownloadRepositoryImpl
import ca.gosyer.jui.data.extension.ExtensionRepositoryImpl
import ca.gosyer.jui.data.library.LibraryRepositoryImpl
import ca.gosyer.jui.data.manga.MangaRepositoryImpl
import ca.gosyer.jui.data.settings.SettingsRepositoryImpl
import ca.gosyer.jui.data.source.SourceRepositoryImpl
import ca.gosyer.jui.data.updates.UpdatesRepositoryImpl
import ca.gosyer.jui.domain.backup.service.BackupRepository
import ca.gosyer.jui.domain.category.service.CategoryRepository
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
import ca.gosyer.jui.domain.download.service.DownloadRepository
import ca.gosyer.jui.domain.extension.service.ExtensionRepository
import ca.gosyer.jui.domain.library.service.LibraryRepository
import ca.gosyer.jui.domain.manga.service.MangaRepository
import ca.gosyer.jui.domain.settings.service.SettingsRepository
import ca.gosyer.jui.domain.source.service.SourceRepository
import ca.gosyer.jui.domain.updates.service.UpdatesRepository
import me.tatarka.inject.annotations.Provides
interface DataComponent {
val BackupRepositoryImpl.bind: BackupRepository
@Provides get() = this
val CategoryRepositoryImpl.bind: CategoryRepository
@Provides get() = this
val ChapterRepositoryImpl.bind: ChapterRepository
@Provides get() = this
val DownloadRepositoryImpl.bind: DownloadRepository
@Provides get() = this
val ExtensionRepositoryImpl.bind: ExtensionRepository
@Provides get() = this
val LibraryRepositoryImpl.bind: LibraryRepository
@Provides get() = this
val MangaRepositoryImpl.bind: MangaRepository
@Provides get() = this
val SettingsRepositoryImpl.bind: SettingsRepository
@Provides get() = this
val SourceRepositoryImpl.bind: SourceRepository
@Provides get() = this
val UpdatesRepositoryImpl.bind: UpdatesRepository
@Provides get() = this
}

View File

@@ -4,16 +4,18 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.backup
import ca.gosyer.jui.core.io.SYSTEM import ca.gosyer.jui.core.io.SYSTEM
import ca.gosyer.jui.core.lang.IO import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.BackupValidationResult import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.backup.model.BackupValidationResult
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.backup.service.BackupRepository
import ca.gosyer.jui.data.server.requests.backupFileExportRequest import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.requests.backupFileImportRequest import ca.gosyer.jui.domain.server.model.requests.backupFileExportRequest
import ca.gosyer.jui.data.server.requests.validateBackupFileRequest import ca.gosyer.jui.domain.server.model.requests.backupFileImportRequest
import ca.gosyer.jui.domain.server.model.requests.validateBackupFileRequest
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.call.body import io.ktor.client.call.body
import io.ktor.client.plugins.expectSuccess import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.HttpRequestBuilder
@@ -32,10 +34,10 @@ import okio.FileSystem
import okio.Path import okio.Path
import okio.buffer import okio.buffer
class BackupInteractionHandler @Inject constructor( class BackupRepositoryImpl @Inject constructor(
client: Http, client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) { ) : BaseRepository(client, serverPreferences), BackupRepository {
private fun buildFormData(file: Path) = formData { private fun buildFormData(file: Path) = formData {
append( append(
@@ -47,7 +49,7 @@ class BackupInteractionHandler @Inject constructor(
) )
} }
fun importBackupFile(file: Path, block: HttpRequestBuilder.() -> Unit = {}) = flow { override fun importBackupFile(file: Path, block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.submitFormWithBinaryData( val response = client.submitFormWithBinaryData(
buildUrl { path(backupFileImportRequest()) }, buildUrl { path(backupFileImportRequest()) },
formData = buildFormData(file) formData = buildFormData(file)
@@ -58,7 +60,7 @@ class BackupInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun validateBackupFile(file: Path, block: HttpRequestBuilder.() -> Unit = {}) = flow { override fun validateBackupFile(file: Path, block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.submitFormWithBinaryData( val response = client.submitFormWithBinaryData(
buildUrl { path(validateBackupFileRequest()) }, buildUrl { path(validateBackupFileRequest()) },
formData = buildFormData(file) formData = buildFormData(file)
@@ -69,7 +71,7 @@ class BackupInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun exportBackupFile(block: HttpRequestBuilder.() -> Unit = {}) = flow { override fun exportBackupFile(block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.get( val response = client.get(
buildUrl { path(backupFileExportRequest()) }, buildUrl { path(backupFileExportRequest()) },
) { ) {

View File

@@ -4,13 +4,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.base
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.http.URLBuilder import io.ktor.http.URLBuilder
open class BaseInteractionHandler( open class BaseRepository(
protected val client: Http, protected val client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) { ) {

View File

@@ -4,22 +4,24 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.category
import ca.gosyer.jui.core.lang.IO import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.Category import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.data.models.Manga import ca.gosyer.jui.domain.category.model.Category
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.category.service.CategoryRepository
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.manga.model.Manga
import ca.gosyer.jui.data.server.requests.addMangaToCategoryQuery import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.requests.categoryDeleteRequest import ca.gosyer.jui.domain.server.model.requests.addMangaToCategoryQuery
import ca.gosyer.jui.data.server.requests.categoryModifyRequest import ca.gosyer.jui.domain.server.model.requests.categoryDeleteRequest
import ca.gosyer.jui.data.server.requests.categoryReorderRequest import ca.gosyer.jui.domain.server.model.requests.categoryModifyRequest
import ca.gosyer.jui.data.server.requests.createCategoryRequest import ca.gosyer.jui.domain.server.model.requests.categoryReorderRequest
import ca.gosyer.jui.data.server.requests.getCategoriesQuery import ca.gosyer.jui.domain.server.model.requests.createCategoryRequest
import ca.gosyer.jui.data.server.requests.getMangaCategoriesQuery import ca.gosyer.jui.domain.server.model.requests.getCategoriesQuery
import ca.gosyer.jui.data.server.requests.getMangaInCategoryQuery import ca.gosyer.jui.domain.server.model.requests.getMangaCategoriesQuery
import ca.gosyer.jui.data.server.requests.removeMangaFromCategoryRequest import ca.gosyer.jui.domain.server.model.requests.getMangaInCategoryQuery
import ca.gosyer.jui.domain.server.model.requests.removeMangaFromCategoryRequest
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.call.body import io.ktor.client.call.body
import io.ktor.client.plugins.expectSuccess import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.delete import io.ktor.client.request.delete
@@ -33,12 +35,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject
class CategoryInteractionHandler @Inject constructor( class CategoryRepositoryImpl @Inject constructor(
client: Http, client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) { ) : BaseRepository(client, serverPreferences), CategoryRepository {
fun getMangaCategories(mangaId: Long) = flow { override fun getMangaCategories(mangaId: Long) = flow {
val response = client.get( val response = client.get(
buildUrl { path(getMangaCategoriesQuery(mangaId)) }, buildUrl { path(getMangaCategoriesQuery(mangaId)) },
) { ) {
@@ -47,9 +49,7 @@ class CategoryInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getMangaCategories(manga: Manga) = getMangaCategories(manga.id) override fun addMangaToCategory(mangaId: Long, categoryId: Long) = flow {
fun addMangaToCategory(mangaId: Long, categoryId: Long) = flow {
val response = client.get( val response = client.get(
buildUrl { path(addMangaToCategoryQuery(mangaId, categoryId)) } buildUrl { path(addMangaToCategoryQuery(mangaId, categoryId)) }
) { ) {
@@ -57,11 +57,8 @@ class CategoryInteractionHandler @Inject constructor(
} }
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun addMangaToCategory(manga: Manga, category: Category) = addMangaToCategory(manga.id, category.id)
fun addMangaToCategory(manga: Manga, categoryId: Long) = addMangaToCategory(manga.id, categoryId)
fun addMangaToCategory(mangaId: Long, category: Category) = addMangaToCategory(mangaId, category.id)
fun removeMangaFromCategory(mangaId: Long, categoryId: Long) = flow { override fun removeMangaFromCategory(mangaId: Long, categoryId: Long) = flow {
val response = client.delete( val response = client.delete(
buildUrl { path(removeMangaFromCategoryRequest(mangaId, categoryId)) } buildUrl { path(removeMangaFromCategoryRequest(mangaId, categoryId)) }
) { ) {
@@ -69,11 +66,8 @@ class CategoryInteractionHandler @Inject constructor(
} }
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun removeMangaFromCategory(manga: Manga, category: Category) = removeMangaFromCategory(manga.id, category.id)
fun removeMangaFromCategory(manga: Manga, categoryId: Long) = removeMangaFromCategory(manga.id, categoryId)
fun removeMangaFromCategory(mangaId: Long, category: Category) = removeMangaFromCategory(mangaId, category.id)
fun getCategories(dropDefault: Boolean = false) = flow { override fun getCategories(dropDefault: Boolean) = flow {
val response = client.get( val response = client.get(
buildUrl { path(getCategoriesQuery()) }, buildUrl { path(getCategoriesQuery()) },
) { ) {
@@ -86,7 +80,7 @@ class CategoryInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun createCategory(name: String) = flow { override fun createCategory(name: String) = flow {
val response = client.submitForm( val response = client.submitForm(
buildUrl { path(createCategoryRequest()) }, buildUrl { path(createCategoryRequest()) },
formParameters = Parameters.build { formParameters = Parameters.build {
@@ -98,7 +92,7 @@ class CategoryInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun modifyCategory(categoryId: Long, name: String? = null, isLanding: Boolean? = null) = flow { override fun modifyCategory(categoryId: Long, name: String?, isLanding: Boolean?) = flow {
val response = client.submitForm( val response = client.submitForm(
buildUrl { path(categoryModifyRequest(categoryId)) }, buildUrl { path(categoryModifyRequest(categoryId)) },
formParameters = Parameters.build { formParameters = Parameters.build {
@@ -115,9 +109,8 @@ class CategoryInteractionHandler @Inject constructor(
} }
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun modifyCategory(category: Category, name: String? = null, isLanding: Boolean? = null) = modifyCategory(category.id, name, isLanding)
fun reorderCategory(to: Int, from: Int) = flow { override fun reorderCategory(to: Int, from: Int) = flow {
val response = client.submitForm( val response = client.submitForm(
buildUrl { path(categoryReorderRequest()) }, buildUrl { path(categoryReorderRequest()) },
formParameters = Parameters.build { formParameters = Parameters.build {
@@ -131,7 +124,7 @@ class CategoryInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun deleteCategory(categoryId: Long) = flow { override fun deleteCategory(categoryId: Long) = flow {
val response = client.delete( val response = client.delete(
buildUrl { path(categoryDeleteRequest(categoryId)) }, buildUrl { path(categoryDeleteRequest(categoryId)) },
) { ) {
@@ -139,9 +132,8 @@ class CategoryInteractionHandler @Inject constructor(
} }
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun deleteCategory(category: Category) = deleteCategory(category.id)
fun getMangaFromCategory(categoryId: Long) = flow { override fun getMangaFromCategory(categoryId: Long) = flow {
val response = client.get( val response = client.get(
buildUrl { path(getMangaInCategoryQuery(categoryId)) }, buildUrl { path(getMangaInCategoryQuery(categoryId)) },
) { ) {
@@ -149,5 +141,4 @@ class CategoryInteractionHandler @Inject constructor(
}.body<List<Manga>>() }.body<List<Manga>>()
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getMangaFromCategory(category: Category) = getMangaFromCategory(category.id)
} }

View File

@@ -0,0 +1,146 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.data.chapter
import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.domain.chapter.model.Chapter
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.deleteDownloadedChapterRequest
import ca.gosyer.jui.domain.server.model.requests.getChapterQuery
import ca.gosyer.jui.domain.server.model.requests.getMangaChaptersQuery
import ca.gosyer.jui.domain.server.model.requests.getPageQuery
import ca.gosyer.jui.domain.server.model.requests.queueDownloadChapterRequest
import ca.gosyer.jui.domain.server.model.requests.stopDownloadingChapterRequest
import ca.gosyer.jui.domain.server.model.requests.updateChapterMetaRequest
import ca.gosyer.jui.domain.server.model.requests.updateChapterRequest
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.call.body
import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.delete
import io.ktor.client.request.forms.submitForm
import io.ktor.client.request.get
import io.ktor.http.HttpMethod
import io.ktor.http.Parameters
import io.ktor.http.path
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject
class ChapterRepositoryImpl @Inject constructor(
client: Http,
serverPreferences: ServerPreferences
) : BaseRepository(client, serverPreferences), ChapterRepository {
override fun getChapters(mangaId: Long, refresh: Boolean) = flow {
val response = client.get(
buildUrl {
path(getMangaChaptersQuery(mangaId))
if (refresh) {
parameter("onlineFetch", true)
}
}
) {
expectSuccess = true
}.body<List<Chapter>>()
emit(response)
}.flowOn(Dispatchers.IO)
override fun getChapter(mangaId: Long, chapterIndex: Int) = flow {
val response = client.get(
buildUrl { path(getChapterQuery(mangaId, chapterIndex)) }
) {
expectSuccess = true
}.body<Chapter>()
emit(response)
}.flowOn(Dispatchers.IO)
override fun updateChapter(
mangaId: Long,
chapterIndex: Int,
read: Boolean?,
bookmarked: Boolean?,
lastPageRead: Int?,
markPreviousRead: Boolean?
) = flow {
val response = client.submitForm(
buildUrl { path(updateChapterRequest(mangaId, chapterIndex)) },
formParameters = Parameters.build {
if (read != null) {
append("read", read.toString())
}
if (bookmarked != null) {
append("bookmarked", bookmarked.toString())
}
if (lastPageRead != null) {
append("lastPageRead", lastPageRead.toString())
}
if (markPreviousRead != null) {
append("markPrevRead", markPreviousRead.toString())
}
}
) {
method = HttpMethod.Patch
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
override fun getPage(mangaId: Long, chapterIndex: Int, pageNum: Int, block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.get(
buildUrl { path(getPageQuery(mangaId, chapterIndex, pageNum)) }
) {
expectSuccess = true
block()
}
emit(response)
}.flowOn(Dispatchers.IO)
override fun deleteChapterDownload(mangaId: Long, chapterIndex: Int) = flow {
val response = client.delete(
buildUrl { path(deleteDownloadedChapterRequest(mangaId, chapterIndex)) }
) {
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
override fun queueChapterDownload(mangaId: Long, chapterIndex: Int) = flow {
val response = client.get(
buildUrl { path(queueDownloadChapterRequest(mangaId, chapterIndex)) }
) {
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
override fun stopChapterDownload(mangaId: Long, chapterIndex: Int) = flow {
val response = client.delete(
buildUrl { path(stopDownloadingChapterRequest(mangaId, chapterIndex)) }
) {
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
override fun updateChapterMeta(mangaId: Long, chapterIndex: Int, key: String, value: String) = flow {
val response = client.submitForm(
buildUrl { path(updateChapterMetaRequest(mangaId, chapterIndex)) },
formParameters = Parameters.build {
append("key", key)
append("value", value)
}
) {
method = HttpMethod.Patch
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
}

View File

@@ -4,14 +4,16 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.download
import ca.gosyer.jui.core.lang.IO import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.download.service.DownloadRepository
import ca.gosyer.jui.data.server.requests.downloadsClearRequest import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.requests.downloadsStartRequest import ca.gosyer.jui.domain.server.model.requests.downloadsClearRequest
import ca.gosyer.jui.data.server.requests.downloadsStopRequest import ca.gosyer.jui.domain.server.model.requests.downloadsStartRequest
import ca.gosyer.jui.domain.server.model.requests.downloadsStopRequest
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.plugins.expectSuccess import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.http.path import io.ktor.http.path
@@ -20,12 +22,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject
class DownloadInteractionHandler @Inject constructor( class DownloadRepositoryImpl @Inject constructor(
client: Http, client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) { ) : BaseRepository(client, serverPreferences), DownloadRepository {
fun startDownloading() = flow { override fun startDownloading() = flow {
val response = client.get( val response = client.get(
buildUrl { path(downloadsStartRequest()) }, buildUrl { path(downloadsStartRequest()) },
) { ) {
@@ -34,7 +36,7 @@ class DownloadInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun stopDownloading() = flow { override fun stopDownloading() = flow {
val response = client.get( val response = client.get(
buildUrl { path(downloadsStopRequest()) }, buildUrl { path(downloadsStopRequest()) },
) { ) {
@@ -43,7 +45,7 @@ class DownloadInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun clearDownloadQueue() = flow { override fun clearDownloadQueue() = flow {
val response = client.get( val response = client.get(
buildUrl { path(downloadsClearRequest()) }, buildUrl { path(downloadsClearRequest()) },
) { ) {

View File

@@ -4,17 +4,19 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.extension
import ca.gosyer.jui.core.lang.IO import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.Extension import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.extension.model.Extension
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.extension.service.ExtensionRepository
import ca.gosyer.jui.data.server.requests.apkIconQuery import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.requests.apkInstallQuery import ca.gosyer.jui.domain.server.model.requests.apkIconQuery
import ca.gosyer.jui.data.server.requests.apkUninstallQuery import ca.gosyer.jui.domain.server.model.requests.apkInstallQuery
import ca.gosyer.jui.data.server.requests.apkUpdateQuery import ca.gosyer.jui.domain.server.model.requests.apkUninstallQuery
import ca.gosyer.jui.data.server.requests.extensionListQuery import ca.gosyer.jui.domain.server.model.requests.apkUpdateQuery
import ca.gosyer.jui.domain.server.model.requests.extensionListQuery
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.call.body import io.ktor.client.call.body
import io.ktor.client.plugins.expectSuccess import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.HttpRequestBuilder
@@ -26,12 +28,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject
class ExtensionInteractionHandler @Inject constructor( class ExtensionRepositoryImpl @Inject constructor(
client: Http, client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) { ) : BaseRepository(client, serverPreferences), ExtensionRepository {
fun getExtensionList() = flow { override fun getExtensionList() = flow {
val response = client.get( val response = client.get(
buildUrl { path(extensionListQuery()) }, buildUrl { path(extensionListQuery()) },
) { ) {
@@ -40,7 +42,7 @@ class ExtensionInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun installExtension(extension: Extension) = flow { override fun installExtension(extension: Extension) = flow {
val response = client.get( val response = client.get(
buildUrl { path(apkInstallQuery(extension.pkgName)) }, buildUrl { path(apkInstallQuery(extension.pkgName)) },
) { ) {
@@ -49,7 +51,7 @@ class ExtensionInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun updateExtension(extension: Extension) = flow { override fun updateExtension(extension: Extension) = flow {
val response = client.get( val response = client.get(
buildUrl { path(apkUpdateQuery(extension.pkgName)) }, buildUrl { path(apkUpdateQuery(extension.pkgName)) },
) { ) {
@@ -58,7 +60,7 @@ class ExtensionInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun uninstallExtension(extension: Extension) = flow { override fun uninstallExtension(extension: Extension) = flow {
val response = client.get( val response = client.get(
buildUrl { path(apkUninstallQuery(extension.pkgName)) }, buildUrl { path(apkUninstallQuery(extension.pkgName)) },
) { ) {
@@ -67,7 +69,7 @@ class ExtensionInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getApkIcon(extension: Extension, block: HttpRequestBuilder.() -> Unit) = flow { override fun getApkIcon(extension: Extension, block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.get( val response = client.get(
buildUrl { path(apkIconQuery(extension.apkName)) }, buildUrl { path(apkIconQuery(extension.apkName)) },
) { ) {

View File

@@ -4,14 +4,15 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.library
import ca.gosyer.jui.core.lang.IO import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.Manga import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.library.service.LibraryRepository
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.requests.addMangaToLibraryQuery import ca.gosyer.jui.domain.server.model.requests.addMangaToLibraryQuery
import ca.gosyer.jui.data.server.requests.removeMangaFromLibraryRequest import ca.gosyer.jui.domain.server.model.requests.removeMangaFromLibraryRequest
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.plugins.expectSuccess import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.delete import io.ktor.client.request.delete
import io.ktor.client.request.get import io.ktor.client.request.get
@@ -21,12 +22,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject
class LibraryInteractionHandler @Inject constructor( class LibraryRepositoryImpl @Inject constructor(
client: Http, client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) { ) : BaseRepository(client, serverPreferences), LibraryRepository {
fun addMangaToLibrary(mangaId: Long) = flow { override fun addMangaToLibrary(mangaId: Long) = flow {
val response = client.get( val response = client.get(
buildUrl { path(addMangaToLibraryQuery(mangaId)) }, buildUrl { path(addMangaToLibraryQuery(mangaId)) },
) { ) {
@@ -35,9 +36,7 @@ class LibraryInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun addMangaToLibrary(manga: Manga) = addMangaToLibrary(manga.id) override fun removeMangaFromLibrary(mangaId: Long) = flow {
fun removeMangaFromLibrary(mangaId: Long) = flow {
val response = client.delete( val response = client.delete(
buildUrl { path(removeMangaFromLibraryRequest(mangaId)) }, buildUrl { path(removeMangaFromLibraryRequest(mangaId)) },
) { ) {
@@ -45,6 +44,4 @@ class LibraryInteractionHandler @Inject constructor(
} }
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun removeMangaFromLibrary(manga: Manga) = removeMangaFromLibrary(manga.id)
} }

View File

@@ -4,15 +4,17 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.manga
import ca.gosyer.jui.core.lang.IO import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.Manga import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.manga.model.Manga
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.manga.service.MangaRepository
import ca.gosyer.jui.data.server.requests.mangaQuery import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.requests.mangaThumbnailQuery import ca.gosyer.jui.domain.server.model.requests.mangaQuery
import ca.gosyer.jui.data.server.requests.updateMangaMetaRequest import ca.gosyer.jui.domain.server.model.requests.mangaThumbnailQuery
import ca.gosyer.jui.domain.server.model.requests.updateMangaMetaRequest
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.call.body import io.ktor.client.call.body
import io.ktor.client.plugins.expectSuccess import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.HttpRequestBuilder
@@ -27,12 +29,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject
class MangaInteractionHandler @Inject constructor( class MangaRepositoryImpl @Inject constructor(
client: Http, client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) { ) : BaseRepository(client, serverPreferences), MangaRepository {
fun getManga(mangaId: Long, refresh: Boolean = false) = flow { override fun getManga(mangaId: Long, refresh: Boolean) = flow {
val response = client.get( val response = client.get(
buildUrl { buildUrl {
path(mangaQuery(mangaId)) path(mangaQuery(mangaId))
@@ -46,9 +48,7 @@ class MangaInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getManga(manga: Manga, refresh: Boolean = false) = getManga(manga.id, refresh) override fun getMangaThumbnail(mangaId: Long, block: HttpRequestBuilder.() -> Unit) = flow {
fun getMangaThumbnail(mangaId: Long, block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.get( val response = client.get(
buildUrl { path(mangaThumbnailQuery(mangaId)) }, buildUrl { path(mangaThumbnailQuery(mangaId)) },
) { ) {
@@ -58,7 +58,7 @@ class MangaInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun updateMangaMeta(mangaId: Long, key: String, value: String) = flow { override fun updateMangaMeta(mangaId: Long, key: String, value: String) = flow {
val response = client.submitForm( val response = client.submitForm(
buildUrl { path(updateMangaMetaRequest(mangaId),) }, buildUrl { path(updateMangaMetaRequest(mangaId),) },
formParameters = Parameters.build { formParameters = Parameters.build {
@@ -71,6 +71,4 @@ class MangaInteractionHandler @Inject constructor(
} }
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun updateMangaMeta(manga: Manga, key: String, value: String) = updateMangaMeta(manga.id, key, value)
} }

View File

@@ -1,215 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.data.server.interactions
import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.Chapter
import ca.gosyer.jui.data.models.Manga
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.server.requests.deleteDownloadedChapterRequest
import ca.gosyer.jui.data.server.requests.getChapterQuery
import ca.gosyer.jui.data.server.requests.getMangaChaptersQuery
import ca.gosyer.jui.data.server.requests.getPageQuery
import ca.gosyer.jui.data.server.requests.queueDownloadChapterRequest
import ca.gosyer.jui.data.server.requests.stopDownloadingChapterRequest
import ca.gosyer.jui.data.server.requests.updateChapterMetaRequest
import ca.gosyer.jui.data.server.requests.updateChapterRequest
import io.ktor.client.call.body
import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.delete
import io.ktor.client.request.forms.submitForm
import io.ktor.client.request.get
import io.ktor.http.HttpMethod
import io.ktor.http.Parameters
import io.ktor.http.path
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject
class ChapterInteractionHandler @Inject constructor(
client: Http,
serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) {
fun getChapters(mangaId: Long, refresh: Boolean = false) = flow {
val response = client.get(
buildUrl {
path(getMangaChaptersQuery(mangaId))
if (refresh) {
parameter("onlineFetch", true)
}
}
) {
expectSuccess = true
}.body<List<Chapter>>()
emit(response)
}.flowOn(Dispatchers.IO)
fun getChapters(manga: Manga, refresh: Boolean = false) = getChapters(manga.id, refresh)
fun getChapter(mangaId: Long, chapterIndex: Int) = flow {
val response = client.get(
buildUrl { path(getChapterQuery(mangaId, chapterIndex)) }
) {
expectSuccess = true
}.body<Chapter>()
emit(response)
}.flowOn(Dispatchers.IO)
fun getChapter(chapter: Chapter) = getChapter(chapter.mangaId, chapter.index)
fun getChapter(manga: Manga, chapterIndex: Int) = getChapter(manga.id, chapterIndex)
fun getChapter(manga: Manga, chapter: Chapter) = getChapter(manga.id, chapter.index)
fun updateChapter(
mangaId: Long,
chapterIndex: Int,
read: Boolean? = null,
bookmarked: Boolean? = null,
lastPageRead: Int? = null,
markPreviousRead: Boolean? = null
) = flow {
val response = client.submitForm(
buildUrl { path(updateChapterRequest(mangaId, chapterIndex)) },
formParameters = Parameters.build {
if (read != null) {
append("read", read.toString())
}
if (bookmarked != null) {
append("bookmarked", bookmarked.toString())
}
if (lastPageRead != null) {
append("lastPageRead", lastPageRead.toString())
}
if (markPreviousRead != null) {
append("markPrevRead", markPreviousRead.toString())
}
}
) {
method = HttpMethod.Patch
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
fun updateChapter(
manga: Manga,
chapterIndex: Int,
read: Boolean? = null,
bookmarked: Boolean? = null,
lastPageRead: Int? = null,
markPreviousRead: Boolean? = null
) = updateChapter(
manga.id,
chapterIndex,
read,
bookmarked,
lastPageRead,
markPreviousRead
)
fun updateChapter(
manga: Manga,
chapter: Chapter,
read: Boolean? = null,
bookmarked: Boolean? = null,
lastPageRead: Int? = null,
markPreviousRead: Boolean? = null
) = updateChapter(
manga.id,
chapter.index,
read,
bookmarked,
lastPageRead,
markPreviousRead
)
fun getPage(mangaId: Long, chapterIndex: Int, pageNum: Int, block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.get(
buildUrl { path(getPageQuery(mangaId, chapterIndex, pageNum)) }
) {
expectSuccess = true
block()
}
emit(response)
}.flowOn(Dispatchers.IO)
fun getPage(chapter: Chapter, pageNum: Int, block: HttpRequestBuilder.() -> Unit) = getPage(chapter.mangaId, chapter.index, pageNum, block)
fun getPage(manga: Manga, chapterIndex: Int, pageNum: Int, block: HttpRequestBuilder.() -> Unit) = getPage(manga.id, chapterIndex, pageNum, block)
fun getPage(manga: Manga, chapter: Chapter, pageNum: Int, block: HttpRequestBuilder.() -> Unit) = getPage(manga.id, chapter.index, pageNum, block)
fun deleteChapterDownload(mangaId: Long, chapterIndex: Int) = flow {
val response = client.delete(
buildUrl { path(deleteDownloadedChapterRequest(mangaId, chapterIndex)) }
) {
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
fun deleteChapterDownload(chapter: Chapter) = deleteChapterDownload(chapter.mangaId, chapter.index)
fun deleteChapterDownload(manga: Manga, chapterIndex: Int) = deleteChapterDownload(manga.id, chapterIndex)
fun deleteChapterDownload(manga: Manga, chapter: Chapter) = deleteChapterDownload(manga.id, chapter.index)
fun queueChapterDownload(mangaId: Long, chapterIndex: Int) = flow {
val response = client.get(
buildUrl { path(queueDownloadChapterRequest(mangaId, chapterIndex)) }
) {
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
fun queueChapterDownload(chapter: Chapter) = queueChapterDownload(chapter.mangaId, chapter.index)
fun queueChapterDownload(manga: Manga, chapterIndex: Int) = queueChapterDownload(manga.id, chapterIndex)
fun queueChapterDownload(manga: Manga, chapter: Chapter) = queueChapterDownload(manga.id, chapter.index)
fun stopChapterDownload(mangaId: Long, chapterIndex: Int) = flow {
val response = client.delete(
buildUrl { path(stopDownloadingChapterRequest(mangaId, chapterIndex)) }
) {
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
fun stopChapterDownload(chapter: Chapter) = stopChapterDownload(chapter.mangaId, chapter.index)
fun stopChapterDownload(manga: Manga, chapterIndex: Int) = stopChapterDownload(manga.id, chapterIndex)
fun stopChapterDownload(manga: Manga, chapter: Chapter) = stopChapterDownload(manga.id, chapter.index)
fun updateChapterMeta(mangaId: Long, chapterIndex: Int, key: String, value: String) = flow {
val response = client.submitForm(
buildUrl { path(updateChapterMetaRequest(mangaId, chapterIndex)) },
formParameters = Parameters.build {
append("key", key)
append("value", value)
}
) {
method = HttpMethod.Patch
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
fun updateChapterMeta(chapter: Chapter, key: String, value: String) = updateChapterMeta(chapter.mangaId, chapter.index, key, value)
fun updateChapterMeta(manga: Manga, chapterIndex: Int, key: String, value: String) = updateChapterMeta(manga.id, chapterIndex, key, value)
fun updateChapterMeta(manga: Manga, chapter: Chapter, key: String, value: String) = updateChapterMeta(manga.id, chapter.index, key, value)
}

View File

@@ -4,14 +4,16 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.settings
import ca.gosyer.jui.core.lang.IO import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.About import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.server.model.requests.aboutQuery
import ca.gosyer.jui.data.server.requests.aboutQuery import ca.gosyer.jui.domain.server.model.requests.checkUpdateQuery
import ca.gosyer.jui.data.server.requests.checkUpdateQuery import ca.gosyer.jui.domain.server.service.ServerPreferences
import ca.gosyer.jui.domain.settings.model.About
import ca.gosyer.jui.domain.settings.service.SettingsRepository
import io.ktor.client.call.body import io.ktor.client.call.body
import io.ktor.client.plugins.expectSuccess import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.get import io.ktor.client.request.get
@@ -22,12 +24,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject
class SettingsInteractionHandler @Inject constructor( class SettingsRepositoryImpl @Inject constructor(
client: Http, client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) { ) : BaseRepository(client, serverPreferences), SettingsRepository {
fun aboutServer() = flow { override fun aboutServer() = flow {
val response = client.get( val response = client.get(
buildUrl { path(aboutQuery()) }, buildUrl { path(aboutQuery()) },
) { ) {
@@ -36,7 +38,7 @@ class SettingsInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun checkUpdate() = flow { override fun checkUpdate() = flow {
val response = client.post( val response = client.post(
buildUrl { path(checkUpdateQuery()) }, buildUrl { path(checkUpdateQuery()) },
) { ) {

View File

@@ -4,27 +4,28 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.source
import ca.gosyer.jui.core.lang.IO import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.MangaPage import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.data.models.Source import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.models.sourcefilters.SourceFilter import ca.gosyer.jui.domain.server.model.requests.getFilterListQuery
import ca.gosyer.jui.data.models.sourcefilters.SourceFilterChange import ca.gosyer.jui.domain.server.model.requests.getSourceSettingsQuery
import ca.gosyer.jui.data.models.sourcepreference.SourcePreference import ca.gosyer.jui.domain.server.model.requests.setFilterRequest
import ca.gosyer.jui.data.models.sourcepreference.SourcePreferenceChange import ca.gosyer.jui.domain.server.model.requests.sourceInfoQuery
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.server.model.requests.sourceLatestQuery
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.server.model.requests.sourceListQuery
import ca.gosyer.jui.data.server.requests.getFilterListQuery import ca.gosyer.jui.domain.server.model.requests.sourcePopularQuery
import ca.gosyer.jui.data.server.requests.getSourceSettingsQuery import ca.gosyer.jui.domain.server.model.requests.sourceSearchQuery
import ca.gosyer.jui.data.server.requests.globalSearchQuery import ca.gosyer.jui.domain.server.model.requests.updateSourceSettingQuery
import ca.gosyer.jui.data.server.requests.setFilterRequest import ca.gosyer.jui.domain.server.service.ServerPreferences
import ca.gosyer.jui.data.server.requests.sourceInfoQuery import ca.gosyer.jui.domain.source.model.MangaPage
import ca.gosyer.jui.data.server.requests.sourceLatestQuery import ca.gosyer.jui.domain.source.model.Source
import ca.gosyer.jui.data.server.requests.sourceListQuery import ca.gosyer.jui.domain.source.model.sourcefilters.SourceFilter
import ca.gosyer.jui.data.server.requests.sourcePopularQuery import ca.gosyer.jui.domain.source.model.sourcefilters.SourceFilterChange
import ca.gosyer.jui.data.server.requests.sourceSearchQuery import ca.gosyer.jui.domain.source.model.sourcepreference.SourcePreference
import ca.gosyer.jui.data.server.requests.updateSourceSettingQuery import ca.gosyer.jui.domain.source.model.sourcepreference.SourcePreferenceChange
import ca.gosyer.jui.domain.source.service.SourceRepository
import io.ktor.client.call.body import io.ktor.client.call.body
import io.ktor.client.plugins.expectSuccess import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.get import io.ktor.client.request.get
@@ -40,12 +41,12 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject
class SourceInteractionHandler @Inject constructor( class SourceRepositoryImpl @Inject constructor(
client: Http, client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) { ) : BaseRepository(client, serverPreferences), SourceRepository {
fun getSourceList() = flow { override fun getSourceList() = flow {
val response = client.get( val response = client.get(
buildUrl { path(sourceListQuery()) }, buildUrl { path(sourceListQuery()) },
) { ) {
@@ -54,7 +55,7 @@ class SourceInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getSourceInfo(sourceId: Long) = flow { override fun getSourceInfo(sourceId: Long) = flow {
val response = client.get( val response = client.get(
buildUrl { path(sourceInfoQuery(sourceId)) }, buildUrl { path(sourceInfoQuery(sourceId)) },
) { ) {
@@ -63,9 +64,7 @@ class SourceInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getSourceInfo(source: Source) = getSourceInfo(source.id) override fun getPopularManga(sourceId: Long, pageNum: Int) = flow {
fun getPopularManga(sourceId: Long, pageNum: Int) = flow {
val response = client.get( val response = client.get(
buildUrl { path(sourcePopularQuery(sourceId, pageNum)) }, buildUrl { path(sourcePopularQuery(sourceId, pageNum)) },
) { ) {
@@ -74,12 +73,7 @@ class SourceInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getPopularManga(source: Source, pageNum: Int) = getPopularManga( override fun getLatestManga(sourceId: Long, pageNum: Int) = flow {
source.id,
pageNum
)
fun getLatestManga(sourceId: Long, pageNum: Int) = flow {
val response = client.get( val response = client.get(
buildUrl { path(sourceLatestQuery(sourceId, pageNum)) }, buildUrl { path(sourceLatestQuery(sourceId, pageNum)) },
) { ) {
@@ -88,27 +82,7 @@ class SourceInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getLatestManga(source: Source, pageNum: Int) = getLatestManga( override fun getSearchResults(sourceId: Long, searchTerm: String, pageNum: Int) = flow {
source.id,
pageNum
)
// TODO: 2021-03-14
fun getGlobalSearchResults(searchTerm: String) = flow {
val response = client.get(
buildUrl {
path(globalSearchQuery())
if (searchTerm.isNotBlank()) {
parameter("searchTerm", searchTerm)
}
},
) {
expectSuccess = true
}
emit(response)
}.flowOn(Dispatchers.IO)
fun getSearchResults(sourceId: Long, searchTerm: String, pageNum: Int) = flow {
val response = client.get( val response = client.get(
buildUrl { buildUrl {
path(sourceSearchQuery(sourceId)) path(sourceSearchQuery(sourceId))
@@ -123,13 +97,7 @@ class SourceInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getSearchResults(source: Source, searchTerm: String, pageNum: Int) = getSearchResults( override fun getFilterList(sourceId: Long, reset: Boolean) = flow {
source.id,
searchTerm,
pageNum
)
fun getFilterList(sourceId: Long, reset: Boolean = false) = flow {
val response = client.get( val response = client.get(
buildUrl { buildUrl {
path(getFilterListQuery(sourceId)) path(getFilterListQuery(sourceId))
@@ -138,17 +106,12 @@ class SourceInteractionHandler @Inject constructor(
} }
}, },
) { ) {
url {
}
expectSuccess = true expectSuccess = true
}.body<List<SourceFilter>>() }.body<List<SourceFilter>>()
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getFilterList(source: Source, reset: Boolean = false) = getFilterList(source.id, reset) override fun setFilter(sourceId: Long, sourceFilter: SourceFilterChange) = flow {
fun setFilter(sourceId: Long, sourceFilter: SourceFilterChange) = flow {
val response = client.post( val response = client.post(
buildUrl { path(setFilterRequest(sourceId)) }, buildUrl { path(setFilterRequest(sourceId)) },
) { ) {
@@ -159,12 +122,12 @@ class SourceInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun setFilter(sourceId: Long, position: Int, value: Any) = setFilter( override fun setFilter(sourceId: Long, position: Int, value: Any) = setFilter(
sourceId, sourceId,
SourceFilterChange(position, value) SourceFilterChange(position, value)
) )
fun setFilter(sourceId: Long, parentPosition: Int, childPosition: Int, value: Any) = setFilter( override fun setFilter(sourceId: Long, parentPosition: Int, childPosition: Int, value: Any) = setFilter(
sourceId, sourceId,
SourceFilterChange( SourceFilterChange(
parentPosition, parentPosition,
@@ -172,7 +135,7 @@ class SourceInteractionHandler @Inject constructor(
) )
) )
fun getSourceSettings(sourceId: Long) = flow { override fun getSourceSettings(sourceId: Long) = flow {
val response = client.get( val response = client.get(
buildUrl { path(getSourceSettingsQuery(sourceId)) }, buildUrl { path(getSourceSettingsQuery(sourceId)) },
) { ) {
@@ -181,9 +144,7 @@ class SourceInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun getSourceSettings(source: Source) = getSourceSettings(source.id) override fun setSourceSetting(sourceId: Long, sourcePreference: SourcePreferenceChange) = flow {
fun setSourceSetting(sourceId: Long, sourcePreference: SourcePreferenceChange) = flow {
val response = client.post( val response = client.post(
buildUrl { path(updateSourceSettingQuery(sourceId)) }, buildUrl { path(updateSourceSettingQuery(sourceId)) },
) { ) {
@@ -194,7 +155,7 @@ class SourceInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun setSourceSetting(sourceId: Long, position: Int, value: Any) = setSourceSetting( override fun setSourceSetting(sourceId: Long, position: Int, value: Any) = setSourceSetting(
sourceId, sourceId,
SourcePreferenceChange(position, value) SourcePreferenceChange(position, value)
) )

View File

@@ -4,15 +4,16 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.interactions package ca.gosyer.jui.data.updates
import ca.gosyer.jui.core.lang.IO import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.Category import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.data.models.Updates import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.server.model.requests.fetchUpdatesRequest
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.server.model.requests.recentUpdatesQuery
import ca.gosyer.jui.data.server.requests.fetchUpdatesRequest import ca.gosyer.jui.domain.server.service.ServerPreferences
import ca.gosyer.jui.data.server.requests.recentUpdatesQuery import ca.gosyer.jui.domain.updates.model.Updates
import ca.gosyer.jui.domain.updates.service.UpdatesRepository
import io.ktor.client.call.body import io.ktor.client.call.body
import io.ktor.client.plugins.expectSuccess import io.ktor.client.plugins.expectSuccess
import io.ktor.client.request.forms.submitForm import io.ktor.client.request.forms.submitForm
@@ -25,12 +26,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject
class UpdatesInteractionHandler @Inject constructor( class UpdatesRepositoryImpl @Inject constructor(
client: Http, client: Http,
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) { ) : BaseRepository(client, serverPreferences), UpdatesRepository {
fun getRecentUpdates(pageNum: Int) = flow { override fun getRecentUpdates(pageNum: Int) = flow {
val response = client.get( val response = client.get(
buildUrl { path(recentUpdatesQuery(pageNum)) } buildUrl { path(recentUpdatesQuery(pageNum)) }
) { ) {
@@ -39,7 +40,7 @@ class UpdatesInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun updateLibrary() = flow { override fun updateLibrary() = flow {
val response = client.post( val response = client.post(
buildUrl { path(fetchUpdatesRequest()) } buildUrl { path(fetchUpdatesRequest()) }
) { ) {
@@ -48,7 +49,7 @@ class UpdatesInteractionHandler @Inject constructor(
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun updateCategory(categoryId: Long) = flow { override fun updateCategory(categoryId: Long) = flow {
val response = client.submitForm( val response = client.submitForm(
buildUrl { path(fetchUpdatesRequest()) }, buildUrl { path(fetchUpdatesRequest()) },
formParameters = Parameters.build { formParameters = Parameters.build {
@@ -59,6 +60,4 @@ class UpdatesInteractionHandler @Inject constructor(
} }
emit(response) emit(response)
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun updateCategory(category: Category) = updateCategory(category.id)
} }

View File

@@ -1,102 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.data
import ca.gosyer.jui.core.di.AppScope
import ca.gosyer.jui.core.prefs.PreferenceStoreFactory
import ca.gosyer.jui.data.catalog.CatalogPreferences
import ca.gosyer.jui.data.extension.ExtensionPreferences
import ca.gosyer.jui.data.library.LibraryPreferences
import ca.gosyer.jui.data.migration.MigrationPreferences
import ca.gosyer.jui.data.reader.ReaderPreferences
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.HttpProvider
import ca.gosyer.jui.data.server.ServerHostPreferences
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.ui.UiPreferences
import ca.gosyer.jui.data.update.UpdatePreferences
import me.tatarka.inject.annotations.Provides
actual interface DataComponent {
val preferenceFactory: PreferenceStoreFactory
val httpProvider: HttpProvider
val http: Http
val serverHostPreferences: ServerHostPreferences
val serverPreferences: ServerPreferences
val extensionPreferences: ExtensionPreferences
val catalogPreferences: CatalogPreferences
val libraryPreferences: LibraryPreferences
val readerPreferences: ReaderPreferences
val uiPreferences: UiPreferences
val migrationPreferences: MigrationPreferences
val updatePreferences: UpdatePreferences
@get:AppScope
@get:Provides
val serverHostPreferencesFactory: ServerHostPreferences
get() = ServerHostPreferences(preferenceFactory.create("host"))
@get:AppScope
@get:Provides
val serverPreferencesFactory: ServerPreferences
get() = ServerPreferences(preferenceFactory.create("server"))
@get:AppScope
@get:Provides
val extensionPreferencesFactory: ExtensionPreferences
get() = ExtensionPreferences(preferenceFactory.create("extension"))
@get:AppScope
@get:Provides
val catalogPreferencesFactory: CatalogPreferences
get() = CatalogPreferences(preferenceFactory.create("catalog"))
@get:AppScope
@get:Provides
val libraryPreferencesFactory: LibraryPreferences
get() = LibraryPreferences(preferenceFactory.create("library"))
@get:AppScope
@get:Provides
val readerPreferencesFactory: ReaderPreferences
get() = ReaderPreferences(preferenceFactory.create("reader")) { name ->
preferenceFactory.create("reader", name)
}
@get:AppScope
@get:Provides
val uiPreferencesFactory: UiPreferences
get() = UiPreferences(preferenceFactory.create("ui"))
@get:AppScope
@get:Provides
val migrationPreferencesFactory: MigrationPreferences
get() = MigrationPreferences(preferenceFactory.create("migration"))
@get:AppScope
@get:Provides
val updatePreferencesFactory: UpdatePreferences
get() = UpdatePreferences(preferenceFactory.create("update"))
@get:AppScope
@get:Provides
val httpFactory: Http
get() = httpProvider.get(serverPreferences)
companion object
}

View File

@@ -20,8 +20,8 @@ plugins {
dependencies { dependencies {
implementation(projects.core) implementation(projects.core)
implementation(projects.i18n) implementation(projects.i18n)
implementation(projects.data)
implementation(projects.domain) implementation(projects.domain)
implementation(projects.data)
implementation(projects.uiCore) implementation(projects.uiCore)
implementation(projects.presentation) implementation(projects.presentation)

View File

@@ -7,6 +7,7 @@
package ca.gosyer.jui.desktop package ca.gosyer.jui.desktop
import ca.gosyer.jui.core.di.AppScope import ca.gosyer.jui.core.di.AppScope
import ca.gosyer.jui.data.DataComponent
import ca.gosyer.jui.domain.DomainComponent import ca.gosyer.jui.domain.DomainComponent
import ca.gosyer.jui.ui.base.UiComponent import ca.gosyer.jui.ui.base.UiComponent
import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Component
@@ -14,7 +15,7 @@ import me.tatarka.inject.annotations.Provides
@AppScope @AppScope
@Component @Component
abstract class AppComponent : DomainComponent, UiComponent { abstract class AppComponent : DataComponent, DomainComponent, UiComponent {
abstract val appMigrations: AppMigrations abstract val appMigrations: AppMigrations

View File

@@ -6,8 +6,8 @@
package ca.gosyer.jui.desktop package ca.gosyer.jui.desktop
import ca.gosyer.jui.data.migration.MigrationPreferences
import ca.gosyer.jui.desktop.build.BuildConfig import ca.gosyer.jui.desktop.build.BuildConfig
import ca.gosyer.jui.domain.migration.service.MigrationPreferences
import ca.gosyer.jui.uicore.vm.ContextWrapper import ca.gosyer.jui.uicore.vm.ContextWrapper
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject

View File

@@ -26,10 +26,10 @@ import androidx.compose.ui.window.rememberWindowState
import ca.gosyer.jui.core.io.userDataDir import ca.gosyer.jui.core.io.userDataDir
import ca.gosyer.jui.core.lang.withUIContext import ca.gosyer.jui.core.lang.withUIContext
import ca.gosyer.jui.core.prefs.getAsFlow import ca.gosyer.jui.core.prefs.getAsFlow
import ca.gosyer.jui.data.server.ServerService.ServerResult
import ca.gosyer.jui.data.ui.model.ThemeMode
import ca.gosyer.jui.desktop.build.BuildConfig import ca.gosyer.jui.desktop.build.BuildConfig
import ca.gosyer.jui.desktop.logging.initializeLogger import ca.gosyer.jui.desktop.logging.initializeLogger
import ca.gosyer.jui.domain.server.service.ServerService.ServerResult
import ca.gosyer.jui.domain.ui.model.ThemeMode
import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.i18n.MR
import ca.gosyer.jui.ui.base.dialog.getMaterialDialogProperties import ca.gosyer.jui.ui.base.dialog.getMaterialDialogProperties
import ca.gosyer.jui.ui.base.theme.AppTheme import ca.gosyer.jui.ui.base.theme.AppTheme

View File

@@ -33,17 +33,21 @@ kotlin {
} }
val commonMain by getting { val commonMain by getting {
dependencies { dependencies {
api(kotlin("stdlib-common"))
api(kotlin("stdlib-common")) api(kotlin("stdlib-common"))
api(libs.coroutines.core) api(libs.coroutines.core)
api(libs.serialization.json) api(libs.serialization.json)
api(libs.kotlinInject.runtime) api(libs.kotlinInject.runtime)
api(libs.ktor.core) api(libs.ktor.core)
api(libs.ktor.contentNegotiation)
api(libs.ktor.serialization.json)
api(libs.ktor.auth)
api(libs.ktor.logging)
api(libs.ktor.websockets) api(libs.ktor.websockets)
api(libs.okio) api(libs.okio)
api(libs.dateTime) api(libs.dateTime)
api(projects.core) api(projects.core)
api(projects.i18n) api(projects.i18n)
api(projects.data)
} }
} }
val commonTest by getting { val commonTest by getting {
@@ -56,6 +60,7 @@ kotlin {
val desktopMain by getting { val desktopMain by getting {
dependencies { dependencies {
api(kotlin("stdlib-jdk8")) api(kotlin("stdlib-jdk8"))
api(libs.ktor.okHttp)
} }
} }
val desktopTest by getting { val desktopTest by getting {
@@ -64,6 +69,7 @@ kotlin {
val androidMain by getting { val androidMain by getting {
dependencies { dependencies {
api(kotlin("stdlib-jdk8")) api(kotlin("stdlib-jdk8"))
api(libs.ktor.okHttp)
} }
} }
val androidTest by getting { val androidTest by getting {

View File

@@ -6,23 +6,102 @@
package ca.gosyer.jui.domain package ca.gosyer.jui.domain
import ca.gosyer.jui.core.CoreComponent
import ca.gosyer.jui.core.di.AppScope import ca.gosyer.jui.core.di.AppScope
import ca.gosyer.jui.data.DataComponent import ca.gosyer.jui.domain.download.service.DownloadService
import ca.gosyer.jui.domain.download.DownloadService import ca.gosyer.jui.domain.extension.service.ExtensionPreferences
import ca.gosyer.jui.domain.library.LibraryUpdateService import ca.gosyer.jui.domain.library.service.LibraryPreferences
import ca.gosyer.jui.domain.migration.RunMigrations import ca.gosyer.jui.domain.library.service.LibraryUpdateService
import ca.gosyer.jui.domain.update.UpdateChecker import ca.gosyer.jui.domain.migration.interactor.RunMigrations
import ca.gosyer.jui.domain.migration.service.MigrationPreferences
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.HttpProvider
import ca.gosyer.jui.domain.server.service.ServerPreferences
import ca.gosyer.jui.domain.source.service.CatalogPreferences
import ca.gosyer.jui.domain.ui.service.UiPreferences
import ca.gosyer.jui.domain.updates.interactor.UpdateChecker
import ca.gosyer.jui.domain.updates.service.UpdatePreferences
import me.tatarka.inject.annotations.Provides import me.tatarka.inject.annotations.Provides
actual interface DomainComponent : DataComponent { actual interface DomainComponent : CoreComponent {
// Providers
val httpProvider: HttpProvider
// Factories
val migrations: RunMigrations
val updateChecker: UpdateChecker
// Singletons
val downloadService: DownloadService val downloadService: DownloadService
val libraryUpdateService: LibraryUpdateService val libraryUpdateService: LibraryUpdateService
val migrations: RunMigrations val http: Http
val updateChecker: UpdateChecker val serverPreferences: ServerPreferences
val extensionPreferences: ExtensionPreferences
val catalogPreferences: CatalogPreferences
val libraryPreferences: LibraryPreferences
val readerPreferences: ReaderPreferences
val uiPreferences: UiPreferences
val migrationPreferences: MigrationPreferences
val updatePreferences: UpdatePreferences
@get:AppScope
@get:Provides
val serverPreferencesFactory: ServerPreferences
get() = ServerPreferences(preferenceFactory.create("server"))
@get:AppScope
@get:Provides
val extensionPreferencesFactory: ExtensionPreferences
get() = ExtensionPreferences(preferenceFactory.create("extension"))
@get:AppScope
@get:Provides
val catalogPreferencesFactory: CatalogPreferences
get() = CatalogPreferences(preferenceFactory.create("catalog"))
@get:AppScope
@get:Provides
val libraryPreferencesFactory: LibraryPreferences
get() = LibraryPreferences(preferenceFactory.create("library"))
@get:AppScope
@get:Provides
val readerPreferencesFactory: ReaderPreferences
get() = ReaderPreferences(preferenceFactory.create("reader")) { name ->
preferenceFactory.create("reader", name)
}
@get:AppScope
@get:Provides
val uiPreferencesFactory: UiPreferences
get() = UiPreferences(preferenceFactory.create("ui"))
@get:AppScope
@get:Provides
val migrationPreferencesFactory: MigrationPreferences
get() = MigrationPreferences(preferenceFactory.create("migration"))
@get:AppScope
@get:Provides
val updatePreferencesFactory: UpdatePreferences
get() = UpdatePreferences(preferenceFactory.create("update"))
@get:AppScope
@get:Provides
val httpFactory: Http
get() = httpProvider.get(serverPreferences)
@get:AppScope @get:AppScope
@get:Provides @get:Provides
@@ -34,13 +113,5 @@ actual interface DomainComponent : DataComponent {
val downloadServiceFactory: DownloadService val downloadServiceFactory: DownloadService
get() = DownloadService(serverPreferences, http) get() = DownloadService(serverPreferences, http)
@get:AppScope companion object
@get:Provides
val migrationsFactory: RunMigrations
get() = RunMigrations(migrationPreferences, readerPreferences)
@get:AppScope
@get:Provides
val updateCheckerFactory: UpdateChecker
get() = UpdateChecker(updatePreferences, http)
} }

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models package ca.gosyer.jui.domain.backup.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -0,0 +1,19 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.backup.service
import ca.gosyer.jui.domain.backup.model.BackupValidationResult
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.statement.HttpResponse
import kotlinx.coroutines.flow.Flow
import okio.Path
interface BackupRepository {
fun importBackupFile(file: Path, block: HttpRequestBuilder.() -> Unit = {}): Flow<HttpResponse>
fun validateBackupFile(file: Path, block: HttpRequestBuilder.() -> Unit = {}): Flow<BackupValidationResult>
fun exportBackupFile(block: HttpRequestBuilder.() -> Unit = {}): Flow<HttpResponse>
}

View File

@@ -7,8 +7,8 @@
package ca.gosyer.jui.domain.base package ca.gosyer.jui.domain.base
import ca.gosyer.jui.core.lang.throwIfCancellation import ca.gosyer.jui.core.lang.throwIfCancellation
import ca.gosyer.jui.data.server.Http import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.data.server.ServerPreferences import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.plugins.websocket.ws import io.ktor.client.plugins.websocket.ws
import io.ktor.http.URLProtocol import io.ktor.http.URLProtocol
import io.ktor.websocket.Frame import io.ktor.websocket.Frame

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models package ca.gosyer.jui.domain.category.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -0,0 +1,24 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.category.service
import ca.gosyer.jui.domain.category.model.Category
import ca.gosyer.jui.domain.manga.model.Manga
import io.ktor.client.statement.HttpResponse
import kotlinx.coroutines.flow.Flow
interface CategoryRepository {
fun getMangaCategories(mangaId: Long): Flow<List<Category>>
fun addMangaToCategory(mangaId: Long, categoryId: Long): Flow<HttpResponse>
fun removeMangaFromCategory(mangaId: Long, categoryId: Long): Flow<HttpResponse>
fun getCategories(dropDefault: Boolean = false): Flow<List<Category>>
fun createCategory(name: String): Flow<HttpResponse>
fun modifyCategory(categoryId: Long, name: String? = null, isLanding: Boolean? = null): Flow<HttpResponse>
fun reorderCategory(to: Int, from: Int): Flow<HttpResponse>
fun deleteCategory(categoryId: Long): Flow<HttpResponse>
fun getMangaFromCategory(categoryId: Long): Flow<List<Manga>>
}

View File

@@ -0,0 +1,32 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.chapter.interactor
import ca.gosyer.jui.domain.chapter.model.Chapter
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.flow
import me.tatarka.inject.annotations.Inject
class UpdateChapterMeta @Inject constructor(private val chapterRepository: ChapterRepository) {
fun subscribe(
chapter: Chapter,
pageOffset: Int = chapter.meta.juiPageOffset
) = flow {
if (pageOffset != chapter.meta.juiPageOffset) {
emitAll(
chapterRepository.updateChapterMeta(
chapter.mangaId,
chapter.index,
"juiPageOffset",
pageOffset.toString()
)
)
}
}
}

View File

@@ -4,11 +4,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models package ca.gosyer.jui.domain.chapter.model
import ca.gosyer.jui.data.server.interactions.ChapterInteractionHandler
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
@@ -29,18 +26,7 @@ data class Chapter(
val lastReadAt: Int?, val lastReadAt: Int?,
val downloaded: Boolean, val downloaded: Boolean,
val meta: ChapterMeta val meta: ChapterMeta
) { )
fun updateRemote(
chapterHandler: ChapterInteractionHandler,
pageOffset: Int = meta.juiPageOffset
) = flow {
if (pageOffset != meta.juiPageOffset) {
chapterHandler.updateChapterMeta(this@Chapter, "juiPageOffset", pageOffset.toString())
.collect()
}
emit(Unit)
}
}
@Serializable @Serializable
data class ChapterMeta( data class ChapterMeta(

View File

@@ -0,0 +1,37 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.chapter.service
import ca.gosyer.jui.domain.chapter.model.Chapter
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.statement.HttpResponse
import kotlinx.coroutines.flow.Flow
interface ChapterRepository {
fun getChapters(mangaId: Long, refresh: Boolean = false): Flow<List<Chapter>>
fun getChapter(mangaId: Long, chapterIndex: Int): Flow<Chapter>
fun updateChapter(
mangaId: Long,
chapterIndex: Int,
read: Boolean? = null,
bookmarked: Boolean? = null,
lastPageRead: Int? = null,
markPreviousRead: Boolean? = null
): Flow<HttpResponse>
fun getPage(
mangaId: Long,
chapterIndex: Int,
pageNum: Int,
block: HttpRequestBuilder.() -> Unit
): Flow<HttpResponse>
fun deleteChapterDownload(mangaId: Long, chapterIndex: Int): Flow<HttpResponse>
fun queueChapterDownload(mangaId: Long, chapterIndex: Int): Flow<HttpResponse>
fun stopChapterDownload(mangaId: Long, chapterIndex: Int): Flow<HttpResponse>
fun updateChapterMeta(mangaId: Long, chapterIndex: Int, key: String, value: String): Flow<HttpResponse>
}

View File

@@ -4,10 +4,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.download.model package ca.gosyer.jui.domain.download.model
import ca.gosyer.jui.data.models.Chapter import ca.gosyer.jui.domain.chapter.model.Chapter
import ca.gosyer.jui.data.models.Manga import ca.gosyer.jui.domain.manga.model.Manga
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.download.model package ca.gosyer.jui.domain.download.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.download.model package ca.gosyer.jui.domain.download.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.download.model package ca.gosyer.jui.domain.download.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -0,0 +1,16 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.download.service
import io.ktor.client.statement.HttpResponse
import kotlinx.coroutines.flow.Flow
interface DownloadRepository {
fun startDownloading(): Flow<HttpResponse>
fun stopDownloading(): Flow<HttpResponse>
fun clearDownloadQueue(): Flow<HttpResponse>
}

View File

@@ -4,15 +4,15 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.domain.download package ca.gosyer.jui.domain.download.service
import ca.gosyer.jui.data.download.model.DownloadChapter
import ca.gosyer.jui.data.download.model.DownloadStatus
import ca.gosyer.jui.data.download.model.DownloaderStatus
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.server.requests.downloadsQuery
import ca.gosyer.jui.domain.base.WebsocketService import ca.gosyer.jui.domain.base.WebsocketService
import ca.gosyer.jui.domain.download.model.DownloadChapter
import ca.gosyer.jui.domain.download.model.DownloadStatus
import ca.gosyer.jui.domain.download.model.DownloaderStatus
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.downloadsQuery
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.websocket.Frame import io.ktor.websocket.Frame
import io.ktor.websocket.readText import io.ktor.websocket.readText
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models package ca.gosyer.jui.domain.extension.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.extension package ca.gosyer.jui.domain.extension.service
import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.text.intl.Locale
import ca.gosyer.jui.core.prefs.Preference import ca.gosyer.jui.core.prefs.Preference

View File

@@ -0,0 +1,21 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.extension.service
import ca.gosyer.jui.domain.extension.model.Extension
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.statement.HttpResponse
import io.ktor.utils.io.ByteReadChannel
import kotlinx.coroutines.flow.Flow
interface ExtensionRepository {
fun getExtensionList(): Flow<List<Extension>>
fun installExtension(extension: Extension): Flow<HttpResponse>
fun updateExtension(extension: Extension): Flow<HttpResponse>
fun uninstallExtension(extension: Extension): Flow<HttpResponse>
fun getApkIcon(extension: Extension, block: HttpRequestBuilder.() -> Unit): Flow<ByteReadChannel>
}

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.library.model package ca.gosyer.jui.domain.library.model
import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.i18n.MR
import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.library.model package ca.gosyer.jui.domain.library.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.library.model package ca.gosyer.jui.domain.library.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.library.model package ca.gosyer.jui.domain.library.model
import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.i18n.MR
import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.library.model package ca.gosyer.jui.domain.library.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,13 +4,12 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.library package ca.gosyer.jui.domain.library.service
import ca.gosyer.jui.core.prefs.Preference import ca.gosyer.jui.core.prefs.Preference
import ca.gosyer.jui.core.prefs.PreferenceStore import ca.gosyer.jui.core.prefs.PreferenceStore
import ca.gosyer.jui.data.library.model.DisplayMode import ca.gosyer.jui.domain.library.model.FilterState
import ca.gosyer.jui.data.library.model.FilterState import ca.gosyer.jui.domain.library.model.Sort
import ca.gosyer.jui.data.library.model.Sort
class LibraryPreferences(private val preferenceStore: PreferenceStore) { class LibraryPreferences(private val preferenceStore: PreferenceStore) {
@@ -38,8 +37,8 @@ class LibraryPreferences(private val preferenceStore: PreferenceStore) {
return preferenceStore.getBoolean("sort_ascending", true) return preferenceStore.getBoolean("sort_ascending", true)
} }
fun displayMode(): Preference<DisplayMode> { fun displayMode(): Preference<ca.gosyer.jui.domain.library.model.DisplayMode> {
return preferenceStore.getJsonObject("display_mode", DisplayMode.CompactGrid, DisplayMode.serializer()) return preferenceStore.getJsonObject("display_mode", ca.gosyer.jui.domain.library.model.DisplayMode.CompactGrid, ca.gosyer.jui.domain.library.model.DisplayMode.serializer())
} }
fun gridColumns(): Preference<Int> { fun gridColumns(): Preference<Int> {

View File

@@ -0,0 +1,15 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.library.service
import io.ktor.client.statement.HttpResponse
import kotlinx.coroutines.flow.Flow
interface LibraryRepository {
fun addMangaToLibrary(mangaId: Long): Flow<HttpResponse>
fun removeMangaFromLibrary(mangaId: Long): Flow<HttpResponse>
}

View File

@@ -4,13 +4,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.domain.library package ca.gosyer.jui.domain.library.service
import ca.gosyer.jui.data.library.model.UpdateStatus
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.server.requests.updatesQuery
import ca.gosyer.jui.domain.base.WebsocketService import ca.gosyer.jui.domain.base.WebsocketService
import ca.gosyer.jui.domain.library.model.UpdateStatus
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.updatesQuery
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.websocket.Frame import io.ktor.websocket.Frame
import io.ktor.websocket.readText import io.ktor.websocket.readText
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow

View File

@@ -0,0 +1,31 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.manga.interactor
import ca.gosyer.jui.domain.manga.model.Manga
import ca.gosyer.jui.domain.manga.service.MangaRepository
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.flow
import me.tatarka.inject.annotations.Inject
class UpdateMangaMeta @Inject constructor(private val mangaRepository: MangaRepository) {
fun subscribe(
manga: Manga,
readerMode: String = manga.meta.juiReaderMode
) = flow {
if (readerMode != manga.meta.juiReaderMode) {
emitAll(
mangaRepository.updateMangaMeta(
manga.id,
"juiReaderMode",
readerMode
)
)
}
}
}

View File

@@ -4,13 +4,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models package ca.gosyer.jui.domain.manga.model
import ca.gosyer.jui.data.server.interactions.MangaInteractionHandler import ca.gosyer.jui.domain.source.model.Source
import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.i18n.MR
import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.StringResource
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
@@ -35,18 +33,7 @@ data class Manga(
val inLibraryAt: Long, val inLibraryAt: Long,
val unreadCount: Int?, val unreadCount: Int?,
val downloadCount: Int? val downloadCount: Int?
) { )
suspend fun updateRemote(
mangaHandler: MangaInteractionHandler,
readerMode: String = meta.juiReaderMode
) = flow {
if (readerMode != meta.juiReaderMode) {
mangaHandler.updateMangaMeta(this@Manga, "juiReaderMode", readerMode)
.collect()
}
emit(Unit)
}
}
@Serializable @Serializable
data class MangaMeta( data class MangaMeta(

View File

@@ -0,0 +1,19 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.manga.service
import ca.gosyer.jui.domain.manga.model.Manga
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.statement.HttpResponse
import io.ktor.utils.io.ByteReadChannel
import kotlinx.coroutines.flow.Flow
interface MangaRepository {
fun getManga(mangaId: Long, refresh: Boolean = false): Flow<Manga>
fun getMangaThumbnail(mangaId: Long, block: HttpRequestBuilder.() -> Unit): Flow<ByteReadChannel>
fun updateMangaMeta(mangaId: Long, key: String, value: String): Flow<HttpResponse>
}

View File

@@ -4,11 +4,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.domain.migration package ca.gosyer.jui.domain.migration.interactor
import ca.gosyer.jui.data.migration.MigrationPreferences
import ca.gosyer.jui.data.reader.ReaderPreferences
import ca.gosyer.jui.domain.build.BuildKonfig import ca.gosyer.jui.domain.build.BuildKonfig
import ca.gosyer.jui.domain.migration.service.MigrationPreferences
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Inject
class RunMigrations @Inject constructor( class RunMigrations @Inject constructor(

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.migration package ca.gosyer.jui.domain.migration.service
import ca.gosyer.jui.core.prefs.Preference import ca.gosyer.jui.core.prefs.Preference
import ca.gosyer.jui.core.prefs.PreferenceStore import ca.gosyer.jui.core.prefs.PreferenceStore

View File

@@ -7,8 +7,8 @@
package ca.gosyer.jui.domain.reader package ca.gosyer.jui.domain.reader
import ca.gosyer.jui.core.prefs.getAsFlow import ca.gosyer.jui.core.prefs.getAsFlow
import ca.gosyer.jui.data.reader.ReaderModePreferences import ca.gosyer.jui.domain.reader.service.ReaderModePreferences
import ca.gosyer.jui.data.reader.ReaderPreferences import ca.gosyer.jui.domain.reader.service.ReaderPreferences
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.reader.model package ca.gosyer.jui.domain.reader.model
enum class DefaultReaderMode( enum class DefaultReaderMode(
val res: String, val res: String,

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.reader.model package ca.gosyer.jui.domain.reader.model
import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.i18n.MR
import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.reader.model package ca.gosyer.jui.domain.reader.model
import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.i18n.MR
import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.reader.model package ca.gosyer.jui.domain.reader.model
import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.i18n.MR
import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.reader.model package ca.gosyer.jui.domain.reader.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,14 +4,14 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.reader package ca.gosyer.jui.domain.reader.service
import ca.gosyer.jui.core.prefs.Preference import ca.gosyer.jui.core.prefs.Preference
import ca.gosyer.jui.core.prefs.PreferenceStore import ca.gosyer.jui.core.prefs.PreferenceStore
import ca.gosyer.jui.data.reader.model.DefaultReaderMode import ca.gosyer.jui.domain.reader.model.DefaultReaderMode
import ca.gosyer.jui.data.reader.model.Direction import ca.gosyer.jui.domain.reader.model.Direction
import ca.gosyer.jui.data.reader.model.ImageScale import ca.gosyer.jui.domain.reader.model.ImageScale
import ca.gosyer.jui.data.reader.model.NavigationMode import ca.gosyer.jui.domain.reader.model.NavigationMode
class ReaderModePreferences(private val mode: String, private val preferenceStore: PreferenceStore) { class ReaderModePreferences(private val mode: String, private val preferenceStore: PreferenceStore) {
constructor(mode: String, factory: (String) -> PreferenceStore) : constructor(mode: String, factory: (String) -> PreferenceStore) :

View File

@@ -4,11 +4,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.reader package ca.gosyer.jui.domain.reader.service
import ca.gosyer.jui.core.prefs.Preference import ca.gosyer.jui.core.prefs.Preference
import ca.gosyer.jui.core.prefs.PreferenceStore import ca.gosyer.jui.core.prefs.PreferenceStore
import ca.gosyer.jui.data.reader.model.DefaultReaderMode import ca.gosyer.jui.domain.reader.model.DefaultReaderMode
import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer

View File

@@ -4,11 +4,12 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server package ca.gosyer.jui.domain.server
import ca.gosyer.jui.data.build.BuildKonfig import ca.gosyer.jui.domain.build.BuildKonfig
import ca.gosyer.jui.data.server.model.Auth import ca.gosyer.jui.domain.server.model.Auth
import ca.gosyer.jui.data.server.model.Proxy import ca.gosyer.jui.domain.server.model.Proxy
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.engine.HttpClientEngineConfig import io.ktor.client.engine.HttpClientEngineConfig
import io.ktor.client.engine.HttpClientEngineFactory import io.ktor.client.engine.HttpClientEngineFactory

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.model package ca.gosyer.jui.domain.server.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.model package ca.gosyer.jui.domain.server.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server package ca.gosyer.jui.domain.server.model
import ca.gosyer.jui.core.prefs.Preference import ca.gosyer.jui.core.prefs.Preference
import ca.gosyer.jui.core.prefs.getAsFlow import ca.gosyer.jui.core.prefs.getAsFlow

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@Post @Post
fun backupImportRequest() = fun backupImportRequest() =

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@Get @Get
fun getMangaCategoriesQuery(mangaId: Long) = fun getMangaCategoriesQuery(mangaId: Long) =

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@Get @Get
fun getMangaChaptersQuery(mangaId: Long) = fun getMangaChaptersQuery(mangaId: Long) =

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@WS @WS
fun downloadsQuery() = fun downloadsQuery() =

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@Get @Get
fun extensionListQuery() = fun extensionListQuery() =

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@Get @Get
fun addMangaToLibraryQuery(mangaId: Long) = fun addMangaToLibraryQuery(mangaId: Long) =

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@Get @Get
fun mangaQuery(mangaId: Long) = fun mangaQuery(mangaId: Long) =

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
annotation class Get annotation class Get

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@Get @Get
fun aboutQuery() = fun aboutQuery() =

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@Get @Get
fun sourceListQuery() = fun sourceListQuery() =

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server.requests package ca.gosyer.jui.domain.server.model.requests
@Get @Get
fun recentUpdatesQuery(pageNum: Int) = fun recentUpdatesQuery(pageNum: Int) =

View File

@@ -4,12 +4,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.server package ca.gosyer.jui.domain.server.service
import ca.gosyer.jui.core.prefs.Preference import ca.gosyer.jui.core.prefs.Preference
import ca.gosyer.jui.core.prefs.PreferenceStore import ca.gosyer.jui.core.prefs.PreferenceStore
import ca.gosyer.jui.data.server.model.Auth import ca.gosyer.jui.domain.server.model.Auth
import ca.gosyer.jui.data.server.model.Proxy import ca.gosyer.jui.domain.server.model.Proxy
import ca.gosyer.jui.domain.server.model.ServerUrlPreference
import io.ktor.http.Url import io.ktor.http.Url
class ServerPreferences(private val preferenceStore: PreferenceStore) { class ServerPreferences(private val preferenceStore: PreferenceStore) {

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models package ca.gosyer.jui.domain.settings.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -0,0 +1,16 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.jui.domain.settings.service
import ca.gosyer.jui.domain.settings.model.About
import io.ktor.client.statement.HttpResponse
import kotlinx.coroutines.flow.Flow
interface SettingsRepository {
fun aboutServer(): Flow<About>
fun checkUpdate(): Flow<HttpResponse>
}

View File

@@ -4,8 +4,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models package ca.gosyer.jui.domain.source.model
import ca.gosyer.jui.domain.manga.model.Manga
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models package ca.gosyer.jui.domain.source.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import ca.gosyer.jui.core.io.Serializable as JvmSerializable import ca.gosyer.jui.core.io.Serializable as JvmSerializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcefilters package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcepreference package ca.gosyer.jui.domain.source.model.sourcepreference
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcepreference package ca.gosyer.jui.domain.source.model.sourcepreference
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.jui.data.models.sourcepreference package ca.gosyer.jui.domain.source.model.sourcepreference
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

Some files were not shown because too many files have changed in this diff Show More