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 {
implementation(projects.core)
implementation(projects.i18n)
implementation(projects.data)
implementation(projects.domain)
implementation(projects.data)
implementation(projects.uiCore)
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.core.prefs.Preference
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 org.lighthousegames.logging.logging
import java.util.Locale

View File

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

View File

@@ -7,7 +7,7 @@
package ca.gosyer.jui.android
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 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.throwIfCancellation
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.Status
import ca.gosyer.jui.domain.download.DownloadService
import ca.gosyer.jui.domain.download.DownloadService.Companion.status
import ca.gosyer.jui.domain.download.model.DownloadState
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 dev.icerock.moko.resources.desc.desc
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.util.notificationBuilder
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 dev.icerock.moko.resources.desc.desc
import kotlinx.coroutines.flow.singleOrNull

View File

@@ -4,12 +4,10 @@
* 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
data class Page(
val index: Int,
var imageUrl: String,
)
interface CoreComponent {
val preferenceFactory: PreferenceStoreFactory
}

View File

@@ -38,15 +38,12 @@ kotlin {
api(libs.serialization.json)
api(libs.kotlinInject.runtime)
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.okio)
api(libs.dateTime)
api(projects.core)
api(projects.i18n)
api(projects.domain)
}
}
val commonTest by getting {
@@ -59,7 +56,6 @@ kotlin {
val desktopMain by getting {
dependencies {
api(kotlin("stdlib-jdk8"))
api(libs.ktor.okHttp)
}
}
val desktopTest by getting {
@@ -68,7 +64,6 @@ kotlin {
val androidMain by getting {
dependencies {
api(kotlin("stdlib-jdk8"))
api(libs.ktor.okHttp)
}
}
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
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/.
*/
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.lang.IO
import ca.gosyer.jui.data.models.BackupValidationResult
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.server.requests.backupFileExportRequest
import ca.gosyer.jui.data.server.requests.backupFileImportRequest
import ca.gosyer.jui.data.server.requests.validateBackupFileRequest
import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.domain.backup.model.BackupValidationResult
import ca.gosyer.jui.domain.backup.service.BackupRepository
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.backupFileExportRequest
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.plugins.expectSuccess
import io.ktor.client.request.HttpRequestBuilder
@@ -32,10 +34,10 @@ import okio.FileSystem
import okio.Path
import okio.buffer
class BackupInteractionHandler @Inject constructor(
class BackupRepositoryImpl @Inject constructor(
client: Http,
serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) {
) : BaseRepository(client, serverPreferences), BackupRepository {
private fun buildFormData(file: Path) = formData {
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(
buildUrl { path(backupFileImportRequest()) },
formData = buildFormData(file)
@@ -58,7 +60,7 @@ class BackupInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun validateBackupFile(file: Path, block: HttpRequestBuilder.() -> Unit = {}) = flow {
override fun validateBackupFile(file: Path, block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.submitFormWithBinaryData(
buildUrl { path(validateBackupFileRequest()) },
formData = buildFormData(file)
@@ -69,7 +71,7 @@ class BackupInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun exportBackupFile(block: HttpRequestBuilder.() -> Unit = {}) = flow {
override fun exportBackupFile(block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.get(
buildUrl { path(backupFileExportRequest()) },
) {

View File

@@ -4,13 +4,13 @@
* 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.data.server.ServerPreferences
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.http.URLBuilder
open class BaseInteractionHandler(
open class BaseRepository(
protected val client: Http,
serverPreferences: ServerPreferences
) {

View File

@@ -4,22 +4,24 @@
* 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.data.models.Category
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.addMangaToCategoryQuery
import ca.gosyer.jui.data.server.requests.categoryDeleteRequest
import ca.gosyer.jui.data.server.requests.categoryModifyRequest
import ca.gosyer.jui.data.server.requests.categoryReorderRequest
import ca.gosyer.jui.data.server.requests.createCategoryRequest
import ca.gosyer.jui.data.server.requests.getCategoriesQuery
import ca.gosyer.jui.data.server.requests.getMangaCategoriesQuery
import ca.gosyer.jui.data.server.requests.getMangaInCategoryQuery
import ca.gosyer.jui.data.server.requests.removeMangaFromCategoryRequest
import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.domain.category.model.Category
import ca.gosyer.jui.domain.category.service.CategoryRepository
import ca.gosyer.jui.domain.manga.model.Manga
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.addMangaToCategoryQuery
import ca.gosyer.jui.domain.server.model.requests.categoryDeleteRequest
import ca.gosyer.jui.domain.server.model.requests.categoryModifyRequest
import ca.gosyer.jui.domain.server.model.requests.categoryReorderRequest
import ca.gosyer.jui.domain.server.model.requests.createCategoryRequest
import ca.gosyer.jui.domain.server.model.requests.getCategoriesQuery
import ca.gosyer.jui.domain.server.model.requests.getMangaCategoriesQuery
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.plugins.expectSuccess
import io.ktor.client.request.delete
@@ -33,12 +35,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject
class CategoryInteractionHandler @Inject constructor(
class CategoryRepositoryImpl @Inject constructor(
client: Http,
serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) {
) : BaseRepository(client, serverPreferences), CategoryRepository {
fun getMangaCategories(mangaId: Long) = flow {
override fun getMangaCategories(mangaId: Long) = flow {
val response = client.get(
buildUrl { path(getMangaCategoriesQuery(mangaId)) },
) {
@@ -47,9 +49,7 @@ class CategoryInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun getMangaCategories(manga: Manga) = getMangaCategories(manga.id)
fun addMangaToCategory(mangaId: Long, categoryId: Long) = flow {
override fun addMangaToCategory(mangaId: Long, categoryId: Long) = flow {
val response = client.get(
buildUrl { path(addMangaToCategoryQuery(mangaId, categoryId)) }
) {
@@ -57,11 +57,8 @@ class CategoryInteractionHandler @Inject constructor(
}
emit(response)
}.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(
buildUrl { path(removeMangaFromCategoryRequest(mangaId, categoryId)) }
) {
@@ -69,11 +66,8 @@ class CategoryInteractionHandler @Inject constructor(
}
emit(response)
}.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(
buildUrl { path(getCategoriesQuery()) },
) {
@@ -86,7 +80,7 @@ class CategoryInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun createCategory(name: String) = flow {
override fun createCategory(name: String) = flow {
val response = client.submitForm(
buildUrl { path(createCategoryRequest()) },
formParameters = Parameters.build {
@@ -98,7 +92,7 @@ class CategoryInteractionHandler @Inject constructor(
emit(response)
}.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(
buildUrl { path(categoryModifyRequest(categoryId)) },
formParameters = Parameters.build {
@@ -115,9 +109,8 @@ class CategoryInteractionHandler @Inject constructor(
}
emit(response)
}.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(
buildUrl { path(categoryReorderRequest()) },
formParameters = Parameters.build {
@@ -131,7 +124,7 @@ class CategoryInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun deleteCategory(categoryId: Long) = flow {
override fun deleteCategory(categoryId: Long) = flow {
val response = client.delete(
buildUrl { path(categoryDeleteRequest(categoryId)) },
) {
@@ -139,9 +132,8 @@ class CategoryInteractionHandler @Inject constructor(
}
emit(response)
}.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(
buildUrl { path(getMangaInCategoryQuery(categoryId)) },
) {
@@ -149,5 +141,4 @@ class CategoryInteractionHandler @Inject constructor(
}.body<List<Manga>>()
emit(response)
}.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/.
*/
package ca.gosyer.jui.data.server.interactions
package ca.gosyer.jui.data.download
import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.server.requests.downloadsClearRequest
import ca.gosyer.jui.data.server.requests.downloadsStartRequest
import ca.gosyer.jui.data.server.requests.downloadsStopRequest
import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.domain.download.service.DownloadRepository
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.downloadsClearRequest
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.request.get
import io.ktor.http.path
@@ -20,12 +22,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject
class DownloadInteractionHandler @Inject constructor(
class DownloadRepositoryImpl @Inject constructor(
client: Http,
serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) {
) : BaseRepository(client, serverPreferences), DownloadRepository {
fun startDownloading() = flow {
override fun startDownloading() = flow {
val response = client.get(
buildUrl { path(downloadsStartRequest()) },
) {
@@ -34,7 +36,7 @@ class DownloadInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun stopDownloading() = flow {
override fun stopDownloading() = flow {
val response = client.get(
buildUrl { path(downloadsStopRequest()) },
) {
@@ -43,7 +45,7 @@ class DownloadInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun clearDownloadQueue() = flow {
override fun clearDownloadQueue() = flow {
val response = client.get(
buildUrl { path(downloadsClearRequest()) },
) {

View File

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

View File

@@ -4,14 +4,15 @@
* 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.data.models.Manga
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.server.requests.addMangaToLibraryQuery
import ca.gosyer.jui.data.server.requests.removeMangaFromLibraryRequest
import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.domain.library.service.LibraryRepository
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.addMangaToLibraryQuery
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.request.delete
import io.ktor.client.request.get
@@ -21,12 +22,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject
class LibraryInteractionHandler @Inject constructor(
class LibraryRepositoryImpl @Inject constructor(
client: Http,
serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) {
) : BaseRepository(client, serverPreferences), LibraryRepository {
fun addMangaToLibrary(mangaId: Long) = flow {
override fun addMangaToLibrary(mangaId: Long) = flow {
val response = client.get(
buildUrl { path(addMangaToLibraryQuery(mangaId)) },
) {
@@ -35,9 +36,7 @@ class LibraryInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun addMangaToLibrary(manga: Manga) = addMangaToLibrary(manga.id)
fun removeMangaFromLibrary(mangaId: Long) = flow {
override fun removeMangaFromLibrary(mangaId: Long) = flow {
val response = client.delete(
buildUrl { path(removeMangaFromLibraryRequest(mangaId)) },
) {
@@ -45,6 +44,4 @@ class LibraryInteractionHandler @Inject constructor(
}
emit(response)
}.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/.
*/
package ca.gosyer.jui.data.server.interactions
package ca.gosyer.jui.data.manga
import ca.gosyer.jui.core.lang.IO
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.mangaQuery
import ca.gosyer.jui.data.server.requests.mangaThumbnailQuery
import ca.gosyer.jui.data.server.requests.updateMangaMetaRequest
import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.domain.manga.model.Manga
import ca.gosyer.jui.domain.manga.service.MangaRepository
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.mangaQuery
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.plugins.expectSuccess
import io.ktor.client.request.HttpRequestBuilder
@@ -27,12 +29,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject
class MangaInteractionHandler @Inject constructor(
class MangaRepositoryImpl @Inject constructor(
client: Http,
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(
buildUrl {
path(mangaQuery(mangaId))
@@ -46,9 +48,7 @@ class MangaInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun getManga(manga: Manga, refresh: Boolean = false) = getManga(manga.id, refresh)
fun getMangaThumbnail(mangaId: Long, block: HttpRequestBuilder.() -> Unit) = flow {
override fun getMangaThumbnail(mangaId: Long, block: HttpRequestBuilder.() -> Unit) = flow {
val response = client.get(
buildUrl { path(mangaThumbnailQuery(mangaId)) },
) {
@@ -58,7 +58,7 @@ class MangaInteractionHandler @Inject constructor(
emit(response)
}.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(
buildUrl { path(updateMangaMetaRequest(mangaId),) },
formParameters = Parameters.build {
@@ -71,6 +71,4 @@ class MangaInteractionHandler @Inject constructor(
}
emit(response)
}.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/.
*/
package ca.gosyer.jui.data.server.interactions
package ca.gosyer.jui.data.settings
import ca.gosyer.jui.core.lang.IO
import ca.gosyer.jui.data.models.About
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.server.requests.aboutQuery
import ca.gosyer.jui.data.server.requests.checkUpdateQuery
import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.aboutQuery
import ca.gosyer.jui.domain.server.model.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.plugins.expectSuccess
import io.ktor.client.request.get
@@ -22,12 +24,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject
class SettingsInteractionHandler @Inject constructor(
class SettingsRepositoryImpl @Inject constructor(
client: Http,
serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) {
) : BaseRepository(client, serverPreferences), SettingsRepository {
fun aboutServer() = flow {
override fun aboutServer() = flow {
val response = client.get(
buildUrl { path(aboutQuery()) },
) {
@@ -36,7 +38,7 @@ class SettingsInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun checkUpdate() = flow {
override fun checkUpdate() = flow {
val response = client.post(
buildUrl { path(checkUpdateQuery()) },
) {

View File

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

View File

@@ -4,15 +4,16 @@
* 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.data.models.Category
import ca.gosyer.jui.data.models.Updates
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.data.server.requests.fetchUpdatesRequest
import ca.gosyer.jui.data.server.requests.recentUpdatesQuery
import ca.gosyer.jui.data.base.BaseRepository
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.model.requests.fetchUpdatesRequest
import ca.gosyer.jui.domain.server.model.requests.recentUpdatesQuery
import ca.gosyer.jui.domain.server.service.ServerPreferences
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.plugins.expectSuccess
import io.ktor.client.request.forms.submitForm
@@ -25,12 +26,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import me.tatarka.inject.annotations.Inject
class UpdatesInteractionHandler @Inject constructor(
class UpdatesRepositoryImpl @Inject constructor(
client: Http,
serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) {
) : BaseRepository(client, serverPreferences), UpdatesRepository {
fun getRecentUpdates(pageNum: Int) = flow {
override fun getRecentUpdates(pageNum: Int) = flow {
val response = client.get(
buildUrl { path(recentUpdatesQuery(pageNum)) }
) {
@@ -39,7 +40,7 @@ class UpdatesInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun updateLibrary() = flow {
override fun updateLibrary() = flow {
val response = client.post(
buildUrl { path(fetchUpdatesRequest()) }
) {
@@ -48,7 +49,7 @@ class UpdatesInteractionHandler @Inject constructor(
emit(response)
}.flowOn(Dispatchers.IO)
fun updateCategory(categoryId: Long) = flow {
override fun updateCategory(categoryId: Long) = flow {
val response = client.submitForm(
buildUrl { path(fetchUpdatesRequest()) },
formParameters = Parameters.build {
@@ -59,6 +60,4 @@ class UpdatesInteractionHandler @Inject constructor(
}
emit(response)
}.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 {
implementation(projects.core)
implementation(projects.i18n)
implementation(projects.data)
implementation(projects.domain)
implementation(projects.data)
implementation(projects.uiCore)
implementation(projects.presentation)

View File

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

View File

@@ -6,8 +6,8 @@
package ca.gosyer.jui.desktop
import ca.gosyer.jui.data.migration.MigrationPreferences
import ca.gosyer.jui.desktop.build.BuildConfig
import ca.gosyer.jui.domain.migration.service.MigrationPreferences
import ca.gosyer.jui.uicore.vm.ContextWrapper
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.lang.withUIContext
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.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.ui.base.dialog.getMaterialDialogProperties
import ca.gosyer.jui.ui.base.theme.AppTheme

View File

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

View File

@@ -6,23 +6,102 @@
package ca.gosyer.jui.domain
import ca.gosyer.jui.core.CoreComponent
import ca.gosyer.jui.core.di.AppScope
import ca.gosyer.jui.data.DataComponent
import ca.gosyer.jui.domain.download.DownloadService
import ca.gosyer.jui.domain.library.LibraryUpdateService
import ca.gosyer.jui.domain.migration.RunMigrations
import ca.gosyer.jui.domain.update.UpdateChecker
import ca.gosyer.jui.domain.download.service.DownloadService
import ca.gosyer.jui.domain.extension.service.ExtensionPreferences
import ca.gosyer.jui.domain.library.service.LibraryPreferences
import ca.gosyer.jui.domain.library.service.LibraryUpdateService
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
actual interface DomainComponent : DataComponent {
actual interface DomainComponent : CoreComponent {
// Providers
val httpProvider: HttpProvider
// Factories
val migrations: RunMigrations
val updateChecker: UpdateChecker
// Singletons
val downloadService: DownloadService
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:Provides
@@ -34,13 +113,5 @@ actual interface DomainComponent : DataComponent {
val downloadServiceFactory: DownloadService
get() = DownloadService(serverPreferences, http)
@get:AppScope
@get:Provides
val migrationsFactory: RunMigrations
get() = RunMigrations(migrationPreferences, readerPreferences)
@get:AppScope
@get:Provides
val updateCheckerFactory: UpdateChecker
get() = UpdateChecker(updatePreferences, http)
companion object
}

View File

@@ -4,7 +4,7 @@
* 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

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
import ca.gosyer.jui.core.lang.throwIfCancellation
import ca.gosyer.jui.data.server.Http
import ca.gosyer.jui.data.server.ServerPreferences
import ca.gosyer.jui.domain.server.Http
import ca.gosyer.jui.domain.server.service.ServerPreferences
import io.ktor.client.plugins.websocket.ws
import io.ktor.http.URLProtocol
import io.ktor.websocket.Frame

View File

@@ -4,7 +4,7 @@
* 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

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/.
*/
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
@Serializable
@@ -29,18 +26,7 @@ data class Chapter(
val lastReadAt: Int?,
val downloaded: Boolean,
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
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/.
*/
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.data.models.Manga
import ca.gosyer.jui.domain.chapter.model.Chapter
import ca.gosyer.jui.domain.manga.model.Manga
import kotlinx.serialization.Serializable
@Serializable

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,7 +4,7 @@
* 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

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/.
*/
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.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.readText
import kotlinx.coroutines.flow.MutableStateFlow

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,7 +4,7 @@
* 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 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/.
*/
package ca.gosyer.jui.data.library.model
package ca.gosyer.jui.domain.library.model
import ca.gosyer.jui.i18n.MR
import dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,7 +4,7 @@
* 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 dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,13 +4,12 @@
* 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.PreferenceStore
import ca.gosyer.jui.data.library.model.DisplayMode
import ca.gosyer.jui.data.library.model.FilterState
import ca.gosyer.jui.data.library.model.Sort
import ca.gosyer.jui.domain.library.model.FilterState
import ca.gosyer.jui.domain.library.model.Sort
class LibraryPreferences(private val preferenceStore: PreferenceStore) {
@@ -38,8 +37,8 @@ class LibraryPreferences(private val preferenceStore: PreferenceStore) {
return preferenceStore.getBoolean("sort_ascending", true)
}
fun displayMode(): Preference<DisplayMode> {
return preferenceStore.getJsonObject("display_mode", DisplayMode.CompactGrid, DisplayMode.serializer())
fun displayMode(): Preference<ca.gosyer.jui.domain.library.model.DisplayMode> {
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> {

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/.
*/
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.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.readText
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/.
*/
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 dev.icerock.moko.resources.StringResource
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@@ -35,18 +33,7 @@ data class Manga(
val inLibraryAt: Long,
val unreadCount: 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
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/.
*/
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.migration.service.MigrationPreferences
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
import me.tatarka.inject.annotations.Inject
class RunMigrations @Inject constructor(

View File

@@ -4,7 +4,7 @@
* 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.PreferenceStore

View File

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

View File

@@ -4,7 +4,7 @@
* 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(
val res: String,

View File

@@ -4,7 +4,7 @@
* 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 dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* 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 dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* 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 dev.icerock.moko.resources.StringResource

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,14 +4,14 @@
* 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.PreferenceStore
import ca.gosyer.jui.data.reader.model.DefaultReaderMode
import ca.gosyer.jui.data.reader.model.Direction
import ca.gosyer.jui.data.reader.model.ImageScale
import ca.gosyer.jui.data.reader.model.NavigationMode
import ca.gosyer.jui.domain.reader.model.DefaultReaderMode
import ca.gosyer.jui.domain.reader.model.Direction
import ca.gosyer.jui.domain.reader.model.ImageScale
import ca.gosyer.jui.domain.reader.model.NavigationMode
class ReaderModePreferences(private val mode: String, private val preferenceStore: 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/.
*/
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.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.serializer

View File

@@ -4,11 +4,12 @@
* 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.data.server.model.Auth
import ca.gosyer.jui.data.server.model.Proxy
import ca.gosyer.jui.domain.build.BuildKonfig
import ca.gosyer.jui.domain.server.model.Auth
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.engine.HttpClientEngineConfig
import io.ktor.client.engine.HttpClientEngineFactory

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,7 +4,7 @@
* 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.getAsFlow

View File

@@ -4,7 +4,7 @@
* 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
fun backupImportRequest() =

View File

@@ -4,7 +4,7 @@
* 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
fun getMangaCategoriesQuery(mangaId: Long) =

View File

@@ -4,7 +4,7 @@
* 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
fun getMangaChaptersQuery(mangaId: Long) =

View File

@@ -4,7 +4,7 @@
* 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
fun downloadsQuery() =

View File

@@ -4,7 +4,7 @@
* 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
fun extensionListQuery() =

View File

@@ -4,7 +4,7 @@
* 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
fun addMangaToLibraryQuery(mangaId: Long) =

View File

@@ -4,7 +4,7 @@
* 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
fun mangaQuery(mangaId: Long) =

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,7 +4,7 @@
* 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
fun aboutQuery() =

View File

@@ -4,7 +4,7 @@
* 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
fun sourceListQuery() =

View File

@@ -4,7 +4,7 @@
* 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
fun recentUpdatesQuery(pageNum: Int) =

View File

@@ -4,12 +4,13 @@
* 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.PreferenceStore
import ca.gosyer.jui.data.server.model.Auth
import ca.gosyer.jui.data.server.model.Proxy
import ca.gosyer.jui.domain.server.model.Auth
import ca.gosyer.jui.domain.server.model.Proxy
import ca.gosyer.jui.domain.server.model.ServerUrlPreference
import io.ktor.http.Url
class ServerPreferences(private val preferenceStore: PreferenceStore) {

View File

@@ -4,7 +4,7 @@
* 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

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/.
*/
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
@Serializable

View File

@@ -4,7 +4,7 @@
* 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 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/.
*/
package ca.gosyer.jui.data.models.sourcefilters
package ca.gosyer.jui.domain.source.model.sourcefilters
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

View File

@@ -4,7 +4,7 @@
* 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.Serializable

View File

@@ -4,7 +4,7 @@
* 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.Serializable

View File

@@ -4,7 +4,7 @@
* 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.Serializable

View File

@@ -4,7 +4,7 @@
* 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.Serializable

View File

@@ -4,7 +4,7 @@
* 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.Serializable

View File

@@ -4,7 +4,7 @@
* 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

View File

@@ -4,7 +4,7 @@
* 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.encodeToString

View File

@@ -4,7 +4,7 @@
* 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.Serializable

View File

@@ -4,7 +4,7 @@
* 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.Serializable

View File

@@ -4,7 +4,7 @@
* 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.Serializable

View File

@@ -4,7 +4,7 @@
* 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.Serializable

View File

@@ -4,7 +4,7 @@
* 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.Serializable

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