refactor: split composeApp to client and ui
also renamed client.datasource to client.data, which made me realise
.gitignore was ignoring `data` and therefore some gtfsr source files
😭
This commit is contained in:
parent
d3edabce36
commit
74338d6dce
62 changed files with 121 additions and 23 deletions
55
client/build.gradle.kts
Normal file
55
client/build.gradle.kts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlinMultiplatform)
|
||||
alias(libs.plugins.kotlinSerialization)
|
||||
alias(libs.plugins.androidLibrary)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
androidTarget {
|
||||
@OptIn(ExperimentalKotlinGradlePluginApi::class)
|
||||
compilerOptions {
|
||||
jvmTarget.set(JvmTarget.JVM_11)
|
||||
}
|
||||
}
|
||||
|
||||
compilerOptions {
|
||||
freeCompilerArgs.add("-opt-in=kotlin.time.ExperimentalTime")
|
||||
}
|
||||
|
||||
iosX64()
|
||||
iosArm64()
|
||||
iosSimulatorArm64()
|
||||
|
||||
sourceSets {
|
||||
androidMain.dependencies {
|
||||
implementation(libs.compose.ui.tooling.preview)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.kotlinx.coroutines.android)
|
||||
implementation(libs.play.services.location)
|
||||
}
|
||||
commonMain.dependencies {
|
||||
implementation(libs.koin.core)
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.kotlinx.datetime)
|
||||
implementation(libs.ktor.client.core)
|
||||
implementation(libs.ktor.client.contentnegotiation)
|
||||
implementation(libs.ktor.serialization.kotlinx.json)
|
||||
implementation(projects.shared)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "moe.lava.banksia.client"
|
||||
compileSdk = libs.versions.android.compileSdk.get().toInt()
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
defaultConfig {
|
||||
minSdk = libs.versions.android.minSdk.get().toInt()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package moe.lava.banksia.client.data.route
|
||||
|
||||
import moe.lava.banksia.model.Route
|
||||
import moe.lava.banksia.room.dao.RouteDao
|
||||
import moe.lava.banksia.room.entity.asEntity
|
||||
|
||||
class RouteLocalDataSource(private val dao: RouteDao) {
|
||||
suspend fun get(id: String) = dao.get(id)
|
||||
suspend fun getAll() = dao.getAll()
|
||||
suspend fun save(vararg routes: Route) = dao.insertOrReplaceAll(*routes.map { it.asEntity() }.toTypedArray())
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package moe.lava.banksia.client.data.route
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import moe.lava.banksia.model.Route
|
||||
|
||||
class RouteRemoteDataSource(val client: HttpClient) {
|
||||
suspend fun get(id: String) = client.get("routes/${id}").body<Route>()
|
||||
suspend fun getAll() = client.get("routes").body<List<Route>>()
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package moe.lava.banksia.client.data.stop
|
||||
|
||||
import moe.lava.banksia.model.Stop
|
||||
import moe.lava.banksia.room.dao.RouteDao
|
||||
import moe.lava.banksia.room.dao.StopDao
|
||||
import moe.lava.banksia.room.entity.asEntity
|
||||
|
||||
class StopLocalDataSource(private val dao: StopDao, private val routeDao: RouteDao) {
|
||||
suspend fun get(id: String) = dao.get(id)
|
||||
suspend fun getByRoute(id: String) = routeDao.stops(id)
|
||||
suspend fun save(vararg stops: Stop) = dao.insertOrReplaceAll(*stops.map { it.asEntity() }.toTypedArray())
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package moe.lava.banksia.client.data.stop
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import moe.lava.banksia.model.Stop
|
||||
|
||||
class StopRemoteDataSource(val client: HttpClient) {
|
||||
suspend fun get(id: String) = client.get("stops/${id}").body<Stop>()
|
||||
suspend fun getByRoute(id: String) = client.get("route_stops/${id}").body<List<Stop>>()
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package moe.lava.banksia.client.di
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.plugins.HttpSend
|
||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.client.plugins.defaultRequest
|
||||
import io.ktor.client.plugins.plugin
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.serialization.json.Json
|
||||
import moe.lava.banksia.Constants
|
||||
import moe.lava.banksia.client.data.route.RouteLocalDataSource
|
||||
import moe.lava.banksia.client.data.route.RouteRemoteDataSource
|
||||
import moe.lava.banksia.client.data.stop.StopLocalDataSource
|
||||
import moe.lava.banksia.client.data.stop.StopRemoteDataSource
|
||||
import moe.lava.banksia.client.repository.RouteRepository
|
||||
import moe.lava.banksia.client.repository.StopRepository
|
||||
import moe.lava.banksia.data.ptv.PtvService
|
||||
import moe.lava.banksia.util.log
|
||||
import org.koin.core.module.dsl.singleOf
|
||||
import org.koin.dsl.module
|
||||
|
||||
val ClientModule = module {
|
||||
// HTTP Clients
|
||||
singleOf(::PtvService)
|
||||
single {
|
||||
HttpClient {
|
||||
install(ContentNegotiation) {
|
||||
json(Json {
|
||||
ignoreUnknownKeys = true
|
||||
})
|
||||
}
|
||||
defaultRequest {
|
||||
url(Constants.serverUrl)
|
||||
}
|
||||
}.also { client ->
|
||||
client.plugin(HttpSend).intercept { req ->
|
||||
val fullPath = req.url.build().encodedPathAndQuery
|
||||
log("ktor.client", fullPath)
|
||||
execute(req)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Data sources
|
||||
singleOf(::RouteLocalDataSource)
|
||||
singleOf(::RouteRemoteDataSource)
|
||||
singleOf(::StopLocalDataSource)
|
||||
singleOf(::StopRemoteDataSource)
|
||||
|
||||
// Repositories
|
||||
singleOf(::RouteRepository)
|
||||
singleOf(::StopRepository)
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package moe.lava.banksia.client.repository
|
||||
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import moe.lava.banksia.client.data.route.RouteLocalDataSource
|
||||
import moe.lava.banksia.client.data.route.RouteRemoteDataSource
|
||||
|
||||
class RouteRepository(
|
||||
private val local: RouteLocalDataSource,
|
||||
private val remote: RouteRemoteDataSource,
|
||||
) {
|
||||
private val mutex = Mutex()
|
||||
suspend fun getAll() = mutex.withLock {
|
||||
local
|
||||
.getAll()
|
||||
.map { it.asModel() }
|
||||
.ifEmpty {
|
||||
remote
|
||||
.getAll()
|
||||
.also { local.save(*it.toTypedArray()) }
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun get(id: String) = mutex.withLock { local.get(id)?.asModel() ?: remote.get(id) }
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package moe.lava.banksia.client.repository
|
||||
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import moe.lava.banksia.client.data.stop.StopLocalDataSource
|
||||
import moe.lava.banksia.client.data.stop.StopRemoteDataSource
|
||||
|
||||
class StopRepository(
|
||||
private val local: StopLocalDataSource,
|
||||
private val remote: StopRemoteDataSource,
|
||||
) {
|
||||
private val mutex = Mutex()
|
||||
|
||||
suspend fun get(id: String) = mutex.withLock { local.get(id)?.asModel() ?: remote.get(id) }
|
||||
suspend fun getByRoute(id: String) = mutex.withLock {
|
||||
local
|
||||
.getByRoute(id)
|
||||
.map { it.asModel() }
|
||||
.ifEmpty { null }
|
||||
?: remote.getByRoute(id)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue