From 2e5ff5737054fc76bde0fd67451cb8b0f11338b8 Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Sat, 7 Mar 2026 21:16:03 +0100 Subject: [PATCH 01/35] feat: Start rework --- .../deeplinks-no-op/build.gradle.kts | 118 ++++++++++++ .../plugins/deeplinks/FloconDeeplinksNoOp.kt | 35 ++++ FloconAndroid/deeplinks/build.gradle.kts | 121 ++++++++++++ .../plugins/deeplinks/FloconDeeplinks.kt | 68 +++++++ .../flocon/plugins/deeplinks/Mapping.kt | 25 +++ .../plugins/deeplinks/model/DeeplinkModel.kt | 13 ++ .../deeplinks/model/DeeplinksRemote.kt | 22 +++ .../io/github/openflocon/flocon/FloconApp.kt | 27 ++- .../openflocon/flocon/FloconConfiguration.kt | 27 +++ .../github/openflocon/flocon/FloconPlugin.kt | 37 ++++ .../analytics/FloconAnalyticsPlugin.kt | 19 +- .../FloconCrashReporterPlugin.kt | 15 +- .../dashboard/FloconDashboardPlugin.kt | 10 +- .../plugins/database/FloconDatabasePlugin.kt | 12 +- .../deeplinks/FloconDeeplinksPlugin.kt | 2 +- .../plugins/device/FloconDevicePlugin.kt | 11 +- .../flocon/plugins/files/FloconFilesPlugin.kt | 14 +- .../plugins/network/FloconNetworkPlugin.kt | 15 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 20 +- .../plugins/tables/FloconTablesPlugin.kt | 20 +- FloconAndroid/flocon/build.gradle.kts | 1 + .../io/github/openflocon/flocon/Flocon.kt | 22 +-- .../io/github/openflocon/flocon/FloconCore.kt | 10 +- .../flocon/client/FloconClientImpl.kt | 171 +++++++---------- .../openflocon/flocon/core/FloconEncoder.kt | 2 +- .../flocon/core/FloconMessageSender.kt | 2 +- .../analytics/FloconAnalyticsPlugin.kt | 19 +- .../FloconCrashReporterPlugin.kt | 31 +++- .../dashboard/FloconDashboardPlugin.kt | 30 +-- .../plugins/database/FloconDatabasePlugin.kt | 24 ++- .../deeplinks/FloconDeeplinksPlugin.kt | 29 ++- .../plugins/device/FloconDevicePluginImpl.kt | 23 ++- .../flocon/plugins/files/FloconFilesPlugin.kt | 36 ++-- .../network/FloconNetworkPluginImpl.kt | 55 +++--- .../sharedprefs/FloconSharedPrefsPlugin.kt | 174 +++++------------- .../plugins/tables/FloconTablesPlugin.kt | 27 ++- .../myapplication/multi/MainActivity.kt | 8 +- FloconAndroid/settings.gradle.kts | 2 + 38 files changed, 909 insertions(+), 388 deletions(-) create mode 100644 FloconAndroid/deeplinks-no-op/build.gradle.kts create mode 100644 FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt create mode 100644 FloconAndroid/deeplinks/build.gradle.kts create mode 100644 FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt create mode 100644 FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt create mode 100644 FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt create mode 100644 FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt create mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt create mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt diff --git a/FloconAndroid/deeplinks-no-op/build.gradle.kts b/FloconAndroid/deeplinks-no-op/build.gradle.kts new file mode 100644 index 000000000..1d0039cd9 --- /dev/null +++ b/FloconAndroid/deeplinks-no-op/build.gradle.kts @@ -0,0 +1,118 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon-base")) + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +android { + namespace = "io.github.openflocon.flocon.deeplinks.noop" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-deeplinks-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Deeplinks No-Op" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt b/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt new file mode 100644 index 000000000..a377c7896 --- /dev/null +++ b/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt @@ -0,0 +1,35 @@ +package io.github.openflocon.flocon.plugins.deeplinks + +import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel + +actual object FloconDeeplinks : FloconPluginFactory { + override val name: String = "Deeplinks" + override val pluginId: String = null + override fun createConfig() = FloconDeeplinksConfig() + override fun install(config: FloconDeeplinksConfig, app: FloconApp): FloconDeeplinksPlugin { + return FloconDeeplinksPluginNoOp + } +} + +private object FloconDeeplinksPluginNoOp : FloconDeeplinksPlugin { + override fun registerDeeplinks(deeplinks: List) { + // no-op + } + + override fun onMessageReceived(method: String, body: String) { + // no-op + } + + override fun onConnectedToServer() { + // no-op + } +} + +fun floconRegisterDeeplink(vararg deeplinks: String) { + // no-op +} + +fun floconRegisterDeeplinks(deeplinks: List) { + // no-op +} diff --git a/FloconAndroid/deeplinks/build.gradle.kts b/FloconAndroid/deeplinks/build.gradle.kts new file mode 100644 index 000000000..fc1029164 --- /dev/null +++ b/FloconAndroid/deeplinks/build.gradle.kts @@ -0,0 +1,121 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) + alias(libs.plugins.kotlin.serialization) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon-base")) + implementation(project(":flocon")) + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(libs.kotlinx.serialization.json) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +android { + namespace = "io.github.openflocon.flocon.deeplinks" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-deeplinks", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Deeplinks" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt new file mode 100644 index 000000000..353080db9 --- /dev/null +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -0,0 +1,68 @@ +package io.github.openflocon.flocon.plugins.deeplinks + +import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update + +object FloconDeeplinks : FloconPluginFactory { + override val name: String = "Deeplinks" + override val pluginId: String = FloconDeeplinks::class.simpleName!! + override fun createConfig() = FloconDeeplinksConfig() + override fun install(config: FloconDeeplinksConfig, app: FloconApp): FloconDeeplinksPlugin { + val plugin = FloconDeeplinksPluginImpl( + sender = app.client as FloconMessageSender + ) + if (config.deeplinks.isNotEmpty()) { + plugin.registerDeeplinks(config.deeplinks) + } + return plugin + } +} + +internal class FloconDeeplinksPluginImpl( + private val sender: FloconMessageSender, +) : FloconPlugin, FloconDeeplinksPlugin { + + private val deeplinks = MutableStateFlow?>(null) + + override fun onMessageReceived( + method: String, + body: String, + ) { + // no op + } + + override fun onConnectedToServer() { + // on connected, send known deeplinks + deeplinks.value?.let { + registerDeeplinks(it) + } + } + + override fun registerDeeplinks(deeplinks: List) { + this.deeplinks.update { + deeplinks + } + + try { + sender.send( + plugin = Protocol.FromDevice.Deeplink.Plugin, + method = Protocol.FromDevice.Deeplink.Method.GetDeeplinks, + body = toDeeplinksJson(deeplinks) + ) + } catch (t: Throwable) { + FloconLogger.logError("deeplink mapping error", t) + } + } +} + +fun floconRegisterDeeplink(vararg deeplinks: String) { + val models = deeplinks.map { DeeplinkModel(link = it, parameters = emptyList()) } + FloconApp.instance?.client?.deeplinksPlugin?.registerDeeplinks(models) +} + +fun floconRegisterDeeplinks(deeplinks: List) { + FloconApp.instance?.client?.deeplinksPlugin?.registerDeeplinks(deeplinks) +} diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt new file mode 100644 index 000000000..dd57bb442 --- /dev/null +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt @@ -0,0 +1,25 @@ +package io.github.openflocon.flocon.plugins.deeplinks + +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel +import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkParameterRemote +import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkRemote +import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinksRemote +import kotlinx.serialization.encodeToString + +internal fun toDeeplinksJson(deeplinks: List): String { + val dto = DeeplinksRemote(deeplinks.map { it.toRemote() }) + return FloconEncoder.json.encodeToString(dto) +} + +internal fun DeeplinkModel.toRemote(): DeeplinkRemote = DeeplinkRemote( + label = label, + link = link, + description = description, + parameters = parameters.map { it.toRemote() } +) + +internal fun DeeplinkModel.Parameter.toRemote(): DeeplinkParameterRemote = DeeplinkParameterRemote( + paramName = paramName, + autoComplete = autoComplete +) diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt new file mode 100644 index 000000000..bf521ba14 --- /dev/null +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt @@ -0,0 +1,13 @@ +package io.github.openflocon.flocon.plugins.deeplinks.model + +data class DeeplinkModel( + val link: String, + val label: String? = null, + val description: String? = null, + val parameters: List, +) { + data class Parameter( + val paramName: String, + val autoComplete: List, + ) +} diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt new file mode 100644 index 000000000..06cd4cf38 --- /dev/null +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt @@ -0,0 +1,22 @@ +package io.github.openflocon.flocon.plugins.deeplinks.model + +import kotlinx.serialization.Serializable + +@Serializable +internal class DeeplinkParameterRemote( + val paramName: String, + val autoComplete: List, +) + +@Serializable +internal class DeeplinkRemote( + val label: String? = null, + val link: String, + val description: String? = null, + val parameters: List, +) + +@Serializable +internal class DeeplinksRemote( + val deeplinks: List, +) diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt index 2add1f3ba..b6df35c73 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt @@ -12,6 +12,7 @@ import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin import kotlinx.coroutines.flow.StateFlow abstract class FloconApp { + lateinit var context: FloconContext companion object { var instance: FloconApp? = null @@ -24,22 +25,28 @@ abstract class FloconApp { suspend fun connect(onClosed: () -> Unit) suspend fun disconnect() - val databasePlugin: FloconDatabasePlugin - val dashboardPlugin: FloconDashboardPlugin - val tablePlugin: FloconTablePlugin - val deeplinksPlugin: FloconDeeplinksPlugin - val analyticsPlugin: FloconAnalyticsPlugin - val networkPlugin: FloconNetworkPlugin - val devicePlugin: FloconDevicePlugin - val preferencesPlugin: FloconPreferencesPlugin - val crashReporterPlugin: FloconCrashReporterPlugin + val databasePlugin: FloconDatabasePlugin? + val dashboardPlugin: FloconDashboardPlugin? + val tablePlugin: FloconTablePlugin? + val deeplinksPlugin: FloconDeeplinksPlugin? + val analyticsPlugin: FloconAnalyticsPlugin? + val networkPlugin: FloconNetworkPlugin? + val devicePlugin: FloconDevicePlugin? + val preferencesPlugin: FloconPreferencesPlugin? + val crashReporterPlugin: FloconCrashReporterPlugin? + + /** + * Retrieve a plugin instance by its [key]. + */ + fun getPlugin(key: FloconPluginKey<*, T>): T? } open val client: Client? = null abstract val isInitialized : StateFlow - protected fun initializeFlocon() { + protected fun initializeFlocon(context: FloconContext) { + this.context = context instance = this } diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt new file mode 100644 index 000000000..b22025e11 --- /dev/null +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -0,0 +1,27 @@ +package io.github.openflocon.flocon + +/** + * Configuration builder for Flocon SDK. + * Used in [Flocon.initialize] to configure the SDK and install plugins. + */ +class FloconConfiguration internal constructor() { + internal val pluginConfigs = mutableMapOf, Any>() + + /** + * Install a plugin with the given [factory] and optional [configure] block. + */ + fun install( + factory: FloconPluginFactory, + configure: Config.() -> Unit = {} + ) { + val config = factory.createConfig() + config.configure() + pluginConfigs[factory] = config + } +} + +fun flocon(block: FloconConfiguration.() -> Unit) { + val configuration = FloconConfiguration().apply(block) + + +} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt new file mode 100644 index 000000000..4771c2713 --- /dev/null +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt @@ -0,0 +1,37 @@ +package io.github.openflocon.flocon + +/** + * Base interface for all Flocon plugins. + * Plugins can receive messages from the server and react to connection events. + */ +interface FloconPlugin { + fun onMessageReceived( + method: String, + body: String, + ) + fun onConnectedToServer() +} + +/** + * A unique key for identifying a Flocon plugin. + */ +interface FloconPluginKey { + val name: String + val pluginId: String? get() = null +} + +/** + * A factory for creating and installing Flocon plugins. + * This is the entry point for Ktor-style [install] calls. + */ +interface FloconPluginFactory : FloconPluginKey { + /** + * Create a default configuration instance for the plugin. + */ + fun createConfig(): Config + + /** + * Install the plugin into the [FloconApp] instance with the given [config]. + */ + fun install(config: Config, app: FloconApp): PluginInstance +} diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt index ffc29c3ff..846d49bf4 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -1,9 +1,24 @@ package io.github.openflocon.flocon.plugins.analytics -import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.plugins.analytics.builder.AnalyticsBuilder import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem +class FloconAnalyticsConfig + +/** + * Flocon Analytics Plugin. + */ +expect object FloconAnalytics : FloconPluginFactory { + override fun createConfig(): FloconAnalyticsConfig + override fun install( + config: FloconAnalyticsConfig, + app: FloconApp + ): FloconAnalyticsPlugin + + override val name: String +} + fun floconAnalytics(analyticsName: String) : AnalyticsBuilder { return AnalyticsBuilder( analyticsTableId = analyticsName, @@ -18,6 +33,6 @@ fun FloconApp.analytics(analyticsName: String): AnalyticsBuilder { ) } -interface FloconAnalyticsPlugin { +interface FloconAnalyticsPlugin : FloconPlugin { fun registerAnalytics(analyticsItems: List) } \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt index 1c0f5c435..3d1fa8dd9 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt @@ -1,3 +1,16 @@ package io.github.openflocon.flocon.plugins.crashreporter -interface FloconCrashReporterPlugin \ No newline at end of file +import io.github.openflocon.flocon.* + +class FloconCrashReporterConfig { + var catchFatalErrors: Boolean = true +} + +/** + * Flocon Crash Reporter Plugin. + */ +expect object FloconCrashReporter : FloconPluginFactory + +interface FloconCrashReporterPlugin : FloconPlugin { + fun setupCrashHandler() +} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt index 20ac34fb7..bf2054d79 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt @@ -1,7 +1,15 @@ package io.github.openflocon.flocon.plugins.dashboard +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig -interface FloconDashboardPlugin { +class FloconDashboardConfig + +/** + * Flocon Dashboard Plugin. + */ +expect object FloconDashboard : FloconPluginFactory + +interface FloconDashboardPlugin : FloconPlugin { fun registerDashboard(dashboardConfig: DashboardConfig) } diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt index a300972b0..06b7acc6c 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt @@ -1,9 +1,17 @@ package io.github.openflocon.flocon.plugins.database -import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel import io.github.openflocon.flocon.plugins.database.model.FloconFileDatabaseModel +class FloconDatabaseConfig + +/** + * Flocon Database Plugin. + * Used to inspect Room or other SQL databases. + */ +expect object FloconDatabase : FloconPluginFactory + fun floconRegisterDatabase(database: FloconDatabaseModel) { FloconApp.instance?.client?.databasePlugin?.register( database @@ -27,7 +35,7 @@ fun floconLogDatabaseQuery(dbName: String, sqlQuery: String, bindArgs: List) } \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt index e1bfbad78..316359861 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.plugins.deeplinks -import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel class DeeplinkLinkBuilder internal constructor( diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt index 37beaf2ae..c099eaa66 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt @@ -1,5 +1,14 @@ package io.github.openflocon.flocon.plugins.device -interface FloconDevicePlugin { +import io.github.openflocon.flocon.* + +class FloconDeviceConfig + +/** + * Flocon Device Plugin. + */ +expect object FloconDevice : FloconPluginFactory + +interface FloconDevicePlugin : FloconPlugin { fun registerWithSerial(serial: String) } \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt index 34f3cf447..3645820c5 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt @@ -1,3 +1,15 @@ package io.github.openflocon.flocon.plugins.files -interface FloconFilesPlugin \ No newline at end of file +import io.github.openflocon.flocon.* + +class FloconFilesConfig { + val roots = mutableListOf() +} + +/** + * Flocon Files Plugin. + * Used to inspect and download files from the device. + */ +expect object FloconFiles : FloconPluginFactory + +interface FloconFilesPlugin : FloconPlugin \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPlugin.kt index 76daf51fe..aaaf34432 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPlugin.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.plugins.network -import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallRequest import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallResponse @@ -8,11 +8,22 @@ import io.github.openflocon.flocon.plugins.network.model.FloconWebSocketEvent import io.github.openflocon.flocon.plugins.network.model.FloconWebSocketMockListener import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse +class FloconNetworkConfig { + var badQualityConfig: BadQualityConfig? = null + val mocks = mutableListOf() +} + +/** + * Flocon Network Plugin. + * Used to inspect HTTP/S and WebSocket calls. + */ +expect object FloconNetwork : FloconPluginFactory + fun floconLogWebSocketEvent(event: FloconWebSocketEvent) { FloconApp.instance?.client?.networkPlugin?.logWebSocket(event) } -interface FloconNetworkPlugin { +interface FloconNetworkPlugin : FloconPlugin { val mocks: Collection val badQualityConfig: BadQualityConfig? diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt index e3893af2d..416f2cad5 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt @@ -1,12 +1,20 @@ package io.github.openflocon.flocon.plugins.sharedprefs -import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconSharedPreferenceModel -fun floconRegisterPreference(preference: FloconPreference) { - FloconApp.instance?.client?.preferencesPlugin?.register(preference) +class FloconPreferencesConfig + +/** + * Flocon Preferences Plugin. + * Used to inspect SharedPreferences or other key-value stores. + */ +expect object FloconPreferences : FloconPluginFactory + +fun floconRegisterSharedPreference(sharedPreference: FloconSharedPreferenceModel) { + FloconApp.instance?.client?.preferencesPlugin?.register(sharedPreference) } -interface FloconPreferencesPlugin { - fun register(preference: FloconPreference) +interface FloconPreferencesPlugin : FloconPlugin { + fun register(sharedPreference: FloconSharedPreferenceModel) } \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt index 188adf89e..ad5d0ec9e 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt @@ -1,23 +1,31 @@ package io.github.openflocon.flocon.plugins.tables -import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.plugins.tables.builder.TableBuilder import io.github.openflocon.flocon.plugins.tables.model.TableItem -fun floconTable(tableName: String): TableBuilder { +class FloconTableConfig + +/** + * Flocon Table Plugin. + * Used to display custom data tables. + */ +expect object FloconTable : FloconPluginFactory + +fun floconTable(tableName: String) : TableBuilder { return TableBuilder( - tableName = tableName, + tableId = tableName, tablePlugin = FloconApp.instance?.client?.tablePlugin, ) } fun FloconApp.table(tableName: String): TableBuilder { return TableBuilder( - tableName = tableName, + tableId = tableName, tablePlugin = this.client?.tablePlugin, ) } -interface FloconTablePlugin { - fun registerTable(tableItem: TableItem) +interface FloconTablePlugin : FloconPlugin { + fun registerItems(tableItems: List) } \ No newline at end of file diff --git a/FloconAndroid/flocon/build.gradle.kts b/FloconAndroid/flocon/build.gradle.kts index 337f2b1e9..c887d14c2 100644 --- a/FloconAndroid/flocon/build.gradle.kts +++ b/FloconAndroid/flocon/build.gradle.kts @@ -27,6 +27,7 @@ kotlin { implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) implementation(libs.kotlinx.serialization.json) api(project(":flocon-base")) + api(project(":deeplinks")) } } diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.kt index 5490c40e4..85a2d610d 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.kt @@ -1,25 +1,13 @@ package io.github.openflocon.flocon import android.content.Context -import io.github.openflocon.flocon.client.FloconClientImpl -import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin -import io.github.openflocon.flocon.plugins.dashboard.FloconDashboardPlugin -import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinksPlugin -import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext object Flocon : FloconCore() { - fun initialize(context: Context) { + fun initialize(context: Context, block: FloconConfiguration.() -> Unit = {}) { + val configuration = FloconConfiguration().apply(block) super.initializeFlocon( - FloconContext(appContext = context) + context = FloconContext(appContext = context), + configuration = configuration ) } -} \ No newline at end of file +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt index ee40db561..f9bf17c23 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt @@ -28,12 +28,16 @@ abstract class FloconCore : FloconApp() { private val _isInitialized = MutableStateFlow(false) override val isInitialized: StateFlow = _isInitialized - protected fun initializeFlocon(context: FloconContext) { - val newClient = FloconClientImpl(context) + protected fun initializeFlocon( + context: FloconContext, + configuration: FloconConfiguration = FloconConfiguration() + ) { + super.initializeFlocon(context) + val newClient = FloconClientImpl(context, configuration) _client = newClient // Setup crash handler early to catch crashes during initialization - newClient.crashReporterPlugin.setupCrashHandler() + newClient.crashReporterPlugin?.setupCrashHandler() _isInitialized.value = true diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt index ad0ddcdc9..9778ea7e3 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt @@ -1,28 +1,28 @@ package io.github.openflocon.flocon.client -import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconFile -import io.github.openflocon.flocon.Protocol -import io.github.openflocon.flocon.core.FloconFileSender -import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin -import io.github.openflocon.flocon.core.getAppInfos -import io.github.openflocon.flocon.getServerHost -import io.github.openflocon.flocon.model.FloconFileInfo -import io.github.openflocon.flocon.model.FloconMessageToServer -import io.github.openflocon.flocon.model.floconMessageFromServerFromJson -import io.github.openflocon.flocon.model.toFloconMessageToServer -import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPluginImpl -import io.github.openflocon.flocon.plugins.dashboard.FloconDashboardPluginImpl -import io.github.openflocon.flocon.plugins.database.FloconDatabasePluginImpl -import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinksPluginImpl -import io.github.openflocon.flocon.plugins.device.FloconDevicePluginImpl -import io.github.openflocon.flocon.plugins.files.FloconFilesPluginImpl -import io.github.openflocon.flocon.plugins.network.FloconNetworkPluginImpl -import io.github.openflocon.flocon.plugins.sharedprefs.FloconPreferencesPluginImpl -import io.github.openflocon.flocon.plugins.tables.FloconTablePluginImpl -import io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporterPluginImpl +import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.core.* +import io.github.openflocon.flocon.model.* +import io.github.openflocon.flocon.plugins.analytics.FloconAnalytics +import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin +import io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporter +import io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporterPlugin +import io.github.openflocon.flocon.plugins.dashboard.FloconDashboard +import io.github.openflocon.flocon.plugins.dashboard.FloconDashboardPlugin +import io.github.openflocon.flocon.plugins.database.FloconDatabase +import io.github.openflocon.flocon.plugins.database.FloconDatabasePlugin +import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks +import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinksPlugin +import io.github.openflocon.flocon.plugins.device.FloconDevice +import io.github.openflocon.flocon.plugins.device.FloconDevicePlugin +import io.github.openflocon.flocon.plugins.files.FloconFiles +import io.github.openflocon.flocon.plugins.files.FloconFilesPlugin +import io.github.openflocon.flocon.plugins.network.FloconNetwork +import io.github.openflocon.flocon.plugins.network.FloconNetworkPlugin +import io.github.openflocon.flocon.plugins.sharedprefs.FloconPreferences +import io.github.openflocon.flocon.plugins.sharedprefs.FloconPreferencesPlugin +import io.github.openflocon.flocon.plugins.tables.FloconTable +import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin import io.github.openflocon.flocon.utils.currentTimeMillis import io.github.openflocon.flocon.websocket.FloconHttpClient import io.github.openflocon.flocon.websocket.FloconWebSocketClient @@ -34,17 +34,16 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch -import kotlin.getValue internal class FloconClientImpl( private val appContext: FloconContext, + private val configuration: FloconConfiguration, ) : FloconApp.Client, FloconMessageSender, FloconFileSender { private val FLOCON_WEBSOCKET_PORT = 9023 private val FLOCON_HTTP_PORT = 9024 private val appInstance by lazy { - // store the start time of the sdk, for this app launch currentTimeMillis() } @@ -64,38 +63,37 @@ internal class FloconClientImpl( } private val coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()) - // region plugins - override val databasePlugin = FloconDatabasePluginImpl(context = appContext, sender = this) - private val filesPlugin = FloconFilesPluginImpl(context = appContext, sender = this, floconFileSender = this) - override val preferencesPlugin = FloconPreferencesPluginImpl(context = appContext, sender = this, scope = coroutineScope) - override val dashboardPlugin = FloconDashboardPluginImpl(sender = this) - override val tablePlugin = FloconTablePluginImpl(sender = this) - override val deeplinksPlugin = FloconDeeplinksPluginImpl(sender = this) - override val analyticsPlugin = FloconAnalyticsPluginImpl(sender = this) - override val devicePlugin = FloconDevicePluginImpl(sender = this, context = appContext) - override val networkPlugin = FloconNetworkPluginImpl( - context = appContext, - sender = this, - coroutineScope = coroutineScope, - ) - override val crashReporterPlugin = FloconCrashReporterPluginImpl( - context = appContext, - sender = this, - coroutineScope = coroutineScope, - ) - - private val allPlugins = listOf( - databasePlugin, - filesPlugin, - preferencesPlugin, - dashboardPlugin, - tablePlugin, - deeplinksPlugin, - analyticsPlugin, - networkPlugin, - devicePlugin, - crashReporterPlugin, - ) + private val installedPlugins = mutableMapOf, Any>() + private val pluginIdToPlugin = mutableMapOf() + + init { + configuration.pluginConfigs.forEach { (factory, config) -> + @Suppress("UNCHECKED_CAST") + val plugin = (factory as FloconPluginFactory).install(config, FloconApp.instance!!) + installedPlugins[factory] = plugin + factory.pluginId?.let { id -> + if (plugin is FloconPlugin) { + pluginIdToPlugin[id] = plugin + } + } + } + } + + override fun getPlugin(key: FloconPluginKey<*, T>): T? { + return installedPlugins[key] as? T + } + + // region plugins backward compatibility + override val databasePlugin: FloconDatabasePlugin? get() = getPlugin(FloconDatabase) + override val dashboardPlugin: FloconDashboardPlugin? get() = getPlugin(FloconDashboard) + override val tablePlugin: FloconTablePlugin? get() = getPlugin(FloconTable) + override val deeplinksPlugin: FloconDeeplinksPlugin? get() = getPlugin(FloconDeeplinks) + override val analyticsPlugin: FloconAnalyticsPlugin? get() = getPlugin(FloconAnalytics) + override val networkPlugin: FloconNetworkPlugin? get() = getPlugin(FloconNetwork) + override val devicePlugin: FloconDevicePlugin? get() = getPlugin(FloconDevice) + override val preferencesPlugin: FloconPreferencesPlugin? get() = getPlugin(FloconPreferences) + override val crashReporterPlugin: FloconCrashReporterPlugin? get() = getPlugin(FloconCrashReporter) + // endregion @Throws(Throwable::class) override suspend fun connect( @@ -107,8 +105,10 @@ internal class FloconClientImpl( onMessageReceived = ::onMessageReceived, onClosed = onClosed, ) - allPlugins.forEach { - it.onConnectedToServer() + installedPlugins.values.forEach { + if (it is FloconPlugin) { + it.onConnectedToServer() + } } } @@ -119,55 +119,10 @@ internal class FloconClientImpl( private fun onMessageReceived(message: String) { coroutineScope.launch(Dispatchers.IO) { floconMessageFromServerFromJson(message)?.let { messageFromServer -> - when (messageFromServer.plugin) { - Protocol.ToDevice.Database.Plugin -> { - databasePlugin.onMessageReceived( - messageFromServer = messageFromServer, - ) - } - - Protocol.ToDevice.Files.Plugin -> { - filesPlugin.onMessageReceived( - messageFromServer = messageFromServer, - ) - } - - Protocol.ToDevice.SharedPreferences.Plugin -> { - preferencesPlugin.onMessageReceived( - messageFromServer = messageFromServer, - ) - } - - Protocol.ToDevice.Device.Plugin -> { - devicePlugin.onMessageReceived( - messageFromServer = messageFromServer, - ) - } - - Protocol.ToDevice.Dashboard.Plugin -> { - dashboardPlugin.onMessageReceived( - messageFromServer = messageFromServer, - ) - } - - Protocol.ToDevice.Table.Plugin -> { - tablePlugin.onMessageReceived( - messageFromServer = messageFromServer, - ) - } - - Protocol.ToDevice.Analytics.Plugin -> { - analyticsPlugin.onMessageReceived( - messageFromServer = messageFromServer, - ) - } - - Protocol.ToDevice.Network.Plugin -> { - networkPlugin.onMessageReceived( - messageFromServer = messageFromServer, - ) - } - } + pluginIdToPlugin[messageFromServer.plugin]?.onMessageReceived( + method = messageFromServer.method, + body = messageFromServer.body, + ) } } } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt index 68aab88d3..679355f17 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt @@ -6,7 +6,7 @@ import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.polymorphic import kotlinx.serialization.modules.subclass -internal object FloconEncoder { +object FloconEncoder { val json = Json { ignoreUnknownKeys = true isLenient = true diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt index 2038fdade..4e99fbc91 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.core -internal interface FloconMessageSender { +interface FloconMessageSender { fun send( plugin: String, method: String, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt index 538bdb529..4ffa613ed 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -1,19 +1,28 @@ package io.github.openflocon.flocon.plugins.analytics -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin -import io.github.openflocon.flocon.model.FloconMessageFromServer import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem import io.github.openflocon.flocon.plugins.analytics.mapper.analyticsItemsToJson +actual object FloconAnalytics : FloconPluginFactory { + override val name: String = "Analytics" + override val pluginId: String = Protocol.ToDevice.Analytics.Plugin + override fun createConfig() = FloconAnalyticsConfig() + override fun install(config: FloconAnalyticsConfig, app: FloconApp): FloconAnalyticsPlugin { + return FloconAnalyticsPluginImpl( + sender = app.client as FloconMessageSender + ) + } +} + internal class FloconAnalyticsPluginImpl( private val sender: FloconMessageSender, ) : FloconPlugin, FloconAnalyticsPlugin { override fun onMessageReceived( - messageFromServer: FloconMessageFromServer, + method: String, + body: String, ) { // no op } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt index 072d35521..583761f42 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt @@ -1,20 +1,32 @@ package io.github.openflocon.flocon.plugins.crashreporter -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin -import io.github.openflocon.flocon.model.FloconMessageFromServer import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel import io.github.openflocon.flocon.plugins.crashreporter.model.crashReportsListToJson import io.github.openflocon.flocon.utils.currentTimeMillis -import io.github.openflocon.flocondesktop.BuildConfig import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid +actual object FloconCrashReporter : FloconPluginFactory { + override val name: String = "CrashReporter" + override val pluginId: String = Protocol.ToDevice.Analytics.Plugin // Crash reporter is usually write-only but we can set an ID + override fun createConfig() = FloconCrashReporterConfig() + override fun install(config: FloconCrashReporterConfig, app: FloconApp): FloconCrashReporterPlugin { + val client = app.client as FloconMessageSender + return FloconCrashReporterPluginImpl( + context = FloconContext(appContext = null), // Handled by datasource + sender = client, + coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()), + ) + } +} + internal class FloconCrashReporterPluginImpl( private val context: FloconContext, private var sender: FloconMessageSender, @@ -23,7 +35,7 @@ internal class FloconCrashReporterPluginImpl( private val dataSource = buildFloconCrashReporterDataSource(context) - fun setupCrashHandler() { + override fun setupCrashHandler() { setupUncaughtExceptionHandler(context) { throwable -> val crash = createCrashReport(throwable) dataSource.saveCrash(crash) @@ -46,7 +58,10 @@ internal class FloconCrashReporterPluginImpl( } } - override fun onMessageReceived(messageFromServer: FloconMessageFromServer) { + override fun onMessageReceived( + method: String, + body: String, + ) { // No messages from desktop for crashes (write-only plugin) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt index d1e15e600..c4fe95c04 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt @@ -1,10 +1,7 @@ package io.github.openflocon.flocon.plugins.dashboard -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin -import io.github.openflocon.flocon.model.FloconMessageFromServer import io.github.openflocon.flocon.plugins.dashboard.mapper.toJson import io.github.openflocon.flocon.plugins.dashboard.model.DashboardCallback import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig @@ -16,6 +13,17 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch +actual object FloconDashboard : FloconPluginFactory { + override val name: String = "Dashboard" + override val pluginId: String = Protocol.ToDevice.Dashboard.Plugin + override fun createConfig() = FloconDashboardConfig() + override fun install(config: FloconDashboardConfig, app: FloconApp): FloconDashboardPlugin { + return FloconDashboardPluginImpl( + sender = app.client as FloconMessageSender + ) + } +} + internal class FloconDashboardPluginImpl( private val sender: FloconMessageSender, ) : FloconPlugin, FloconDashboardPlugin { @@ -28,17 +36,18 @@ internal class FloconDashboardPluginImpl( private val callbackMap = mutableMapOf() override fun onMessageReceived( - messageFromServer: FloconMessageFromServer, + method: String, + body: String, ) { scope.launch { - when (messageFromServer.method) { + when (method) { Protocol.ToDevice.Dashboard.Method.OnClick -> { - val id = messageFromServer.body + val id = body callbackMap[id]?.let { it as? DashboardCallback.ButtonCallback }?.action?.invoke() } Protocol.ToDevice.Dashboard.Method.OnFormSubmitted -> { - ToDeviceSubmittedFormMessage.fromJson(messageFromServer.body)?.let { + ToDeviceSubmittedFormMessage.fromJson(body)?.let { callbackMap[it.id]?.let { it as? DashboardCallback.FormCallback }?.actions?.invoke( it.values ) @@ -46,7 +55,7 @@ internal class FloconDashboardPluginImpl( } Protocol.ToDevice.Dashboard.Method.OnTextFieldSubmitted -> { - ToDeviceSubmittedTextFieldMessage.fromJson(messageFromServer.body)?.let { + ToDeviceSubmittedTextFieldMessage.fromJson(body)?.let { callbackMap[it.id]?.let { it as? DashboardCallback.TextFieldCallback }?.action?.invoke( it.value ) @@ -54,7 +63,7 @@ internal class FloconDashboardPluginImpl( } Protocol.ToDevice.Dashboard.Method.OnCheckBoxValueChanged -> { - ToDeviceCheckBoxValueChangedMessage.fromJson(messageFromServer.body)?.let { + ToDeviceCheckBoxValueChangedMessage.fromJson(body)?.let { callbackMap[it.id]?.let { it as? DashboardCallback.CheckBoxCallback }?.action?.invoke( it.value ) @@ -97,4 +106,3 @@ internal class FloconDashboardPluginImpl( } } } - diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt index 10c97c58c..c976630a8 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt @@ -1,10 +1,7 @@ package io.github.openflocon.flocon.plugins.database -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin import io.github.openflocon.flocon.model.FloconMessageFromServer import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseExecuteSqlResponse @@ -32,6 +29,18 @@ internal interface FloconDatabaseDataSource { internal expect fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource +actual object FloconDatabase : FloconPluginFactory { + override val name: String = "Database" + override val pluginId: String = Protocol.ToDevice.Database.Plugin + override fun createConfig() = FloconDatabaseConfig() + override fun install(config: FloconDatabaseConfig, app: FloconApp): FloconDatabasePlugin { + return FloconDatabasePluginImpl( + sender = app.client as FloconMessageSender, + context = FloconContext(appContext = null), // Handled by actual buildFloconDatabaseDataSource + ) + } +} + internal class FloconDatabasePluginImpl( private var sender: FloconMessageSender, private val context: FloconContext, @@ -42,16 +51,17 @@ internal class FloconDatabasePluginImpl( private val dataSource = buildFloconDatabaseDataSource(context) override fun onMessageReceived( - messageFromServer: FloconMessageFromServer, + method: String, + body: String, ) { - when (messageFromServer.method) { + when (method) { Protocol.ToDevice.Database.Method.GetDatabases -> { sendAllDatabases(sender) } Protocol.ToDevice.Database.Method.Query -> { val queryMessage = - DatabaseQueryMessage.fromJson(message = messageFromServer.body) ?: return + DatabaseQueryMessage.fromJson(message = body) ?: return val result = dataSource.executeSQL( registeredDatabases = registeredDatabases.value, databaseName = queryMessage.database, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt index b65bc40fc..9df144790 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt @@ -1,14 +1,27 @@ package io.github.openflocon.flocon.plugins.deeplinks -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin -import io.github.openflocon.flocon.model.FloconMessageFromServer import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel +import io.github.openflocon.flocon.plugins.deeplinks.mapper.toDeeplinksJson import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update +actual object FloconDeeplinks : FloconPluginFactory { + override val name: String = "Deeplinks" + override val pluginId: String = Protocol.ToDevice.Deeplink.Plugin + override fun createConfig() = FloconDeeplinksConfig() + override fun install(config: FloconDeeplinksConfig, app: FloconApp): FloconDeeplinksPlugin { + val plugin = FloconDeeplinksPluginImpl( + sender = app.client as FloconMessageSender + ) + if (config.deeplinks.isNotEmpty()) { + plugin.registerDeeplinks(config.deeplinks) + } + return plugin + } +} + internal class FloconDeeplinksPluginImpl( private val sender: FloconMessageSender, ) : FloconPlugin, FloconDeeplinksPlugin { @@ -17,13 +30,14 @@ internal class FloconDeeplinksPluginImpl( private val variables = MutableStateFlow?>(null) override fun onMessageReceived( - messageFromServer: FloconMessageFromServer, + method: String, + body: String, ) { - + // no op } override fun onConnectedToServer() { - // on connected, send known dashboard + // on connected, send known deeplinks deeplinks.value?.let { registerDeeplinks(it, variables.value.orEmpty()) } @@ -50,4 +64,3 @@ internal class FloconDeeplinksPluginImpl( } } } - diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt index 4a2e02b15..f67e4581b 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt @@ -1,13 +1,21 @@ package io.github.openflocon.flocon.plugins.device -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin -import io.github.openflocon.flocon.model.FloconMessageFromServer import io.github.openflocon.flocon.plugins.device.model.fromdevice.RegisterDeviceDataModel +actual object FloconDevice : FloconPluginFactory { + override val name: String = "Device" + override val pluginId: String = Protocol.ToDevice.Device.Plugin + override fun createConfig() = FloconDeviceConfig() + override fun install(config: FloconDeviceConfig, app: FloconApp): FloconDevicePlugin { + return FloconDevicePluginImpl( + sender = app.client as FloconMessageSender, + context = app.context + ) + } +} + internal expect fun restartApp(context: FloconContext) internal class FloconDevicePluginImpl( @@ -28,9 +36,10 @@ internal class FloconDevicePluginImpl( } override fun onMessageReceived( - messageFromServer: FloconMessageFromServer, + method: String, + body: String, ) { - when (messageFromServer.method) { + when (method) { Protocol.ToDevice.Device.Method.GetAppIcon -> { val icon = getAppIconBase64(context) if (icon != null) { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt index 6be68c2d8..7761af4b0 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt @@ -1,14 +1,9 @@ package io.github.openflocon.flocon.plugins.files -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconFile -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconFileSender import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin import io.github.openflocon.flocon.model.FloconFileInfo -import io.github.openflocon.flocon.model.FloconMessageFromServer import io.github.openflocon.flocon.plugins.files.model.fromdevice.FileDataModel import io.github.openflocon.flocon.plugins.files.model.fromdevice.FilesResultDataModel import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceDeleteFileMessage @@ -19,6 +14,20 @@ import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceGetFiles import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update +actual object FloconFiles : FloconPluginFactory { + override val name: String = "Files" + override val pluginId: String = Protocol.ToDevice.Files.Plugin + override fun createConfig() = FloconFilesConfig() + override fun install(config: FloconFilesConfig, app: FloconApp): FloconFilesPlugin { + val client = app.client + return FloconFilesPluginImpl( + context = app.context, + floconFileSender = client as FloconFileSender, + sender = client as FloconMessageSender + ) + } +} + internal interface FileDataSource { fun getFile(path: String, isConstantPath: Boolean): FloconFile? fun getFolderContent(path: String, isConstantPath: Boolean, withFoldersSize: Boolean): List @@ -39,11 +48,12 @@ internal class FloconFilesPluginImpl( private val withFoldersSize = MutableStateFlow(false) override fun onMessageReceived( - messageFromServer: FloconMessageFromServer, + method: String, + body: String, ) { - when (messageFromServer.method) { + when (method) { Protocol.ToDevice.Files.Method.ListFiles -> { - val listFilesMessage = ToDeviceGetFilesMessage.fromJson(message = messageFromServer.body) ?: return + val listFilesMessage = ToDeviceGetFilesMessage.fromJson(message = body) ?: return withFoldersSize.update { listFilesMessage.withFoldersSize } @@ -55,7 +65,7 @@ internal class FloconFilesPluginImpl( } Protocol.ToDevice.Files.Method.GetFile -> { - val getFileMessage = ToDeviceGetFileMessage.fromJson(message = messageFromServer.body) ?: return + val getFileMessage = ToDeviceGetFileMessage.fromJson(message = body) ?: return fileDataSource.getFile(path = getFileMessage.path, isConstantPath = false)?.let { file -> floconFileSender.send( @@ -70,7 +80,7 @@ internal class FloconFilesPluginImpl( Protocol.ToDevice.Files.Method.DeleteFile -> { val deleteFilesMessage = - ToDeviceDeleteFileMessage.fromJson(message = messageFromServer.body) ?: return + ToDeviceDeleteFileMessage.fromJson(message = body) ?: return fileDataSource.deleteFile( path = deleteFilesMessage.filePath, @@ -85,7 +95,7 @@ internal class FloconFilesPluginImpl( Protocol.ToDevice.Files.Method.DeleteFiles -> { val deleteFilesMessage = - ToDeviceDeleteFilesMessage.fromJson(message = messageFromServer.body) ?: return + ToDeviceDeleteFilesMessage.fromJson(message = body) ?: return fileDataSource.deleteFiles( path = deleteFilesMessage.filePaths, @@ -100,7 +110,7 @@ internal class FloconFilesPluginImpl( Protocol.ToDevice.Files.Method.DeleteFolderContent -> { val deleteFolderContentMessage = - ToDeviceDeleteFolderContentMessage.fromJson(message = messageFromServer.body) + ToDeviceDeleteFolderContentMessage.fromJson(message = body) ?: return fileDataSource.getFile( diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt index 4a58473f5..51f23c8cc 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt @@ -1,30 +1,31 @@ package io.github.openflocon.flocon.plugins.network -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin -import io.github.openflocon.flocon.model.FloconMessageFromServer -import io.github.openflocon.flocon.plugins.network.mapper.floconNetworkCallRequestToJson -import io.github.openflocon.flocon.plugins.network.mapper.floconNetworkCallResponseToJson -import io.github.openflocon.flocon.plugins.network.mapper.floconNetworkWebSocketEventToJson -import io.github.openflocon.flocon.plugins.network.mapper.parseBadQualityConfig -import io.github.openflocon.flocon.plugins.network.mapper.parseMockResponses -import io.github.openflocon.flocon.plugins.network.mapper.parseWebSocketMockMessage -import io.github.openflocon.flocon.plugins.network.mapper.webSocketIdsToJsonArray -import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.plugins.network.model.FloconWebSocketEvent -import io.github.openflocon.flocon.plugins.network.model.FloconWebSocketMockListener -import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse +import io.github.openflocon.flocon.plugins.network.mapper.* +import io.github.openflocon.flocon.plugins.network.model.* import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +actual object FloconNetwork : FloconPluginFactory { + override val name: String = "Network" + override val pluginId: String = Protocol.ToDevice.Network.Plugin + override fun createConfig() = FloconNetworkConfig() + override fun install(config: FloconNetworkConfig, app: FloconApp): FloconNetworkPlugin { + return FloconNetworkPluginImpl( + context = app.context, + sender = app.client as FloconMessageSender, + coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()), + ) + } +} + internal const val FLOCON_NETWORK_MOCKS_JSON = "flocon_network_mocks.json" internal const val FLOCON_NETWORK_BAD_CONFIG_JSON = "flocon_network_bad_config.json" @@ -54,9 +55,7 @@ internal class FloconNetworkPluginImpl( private val _badQualityConfig = MutableStateFlow(dataSource.loadBadNetworkConfig()) override val badQualityConfig: BadQualityConfig? - get() { - return _badQualityConfig.value - } + get() = _badQualityConfig.value override fun logRequest(request: FloconNetworkCallRequest) { try { @@ -72,7 +71,7 @@ internal class FloconNetworkPluginImpl( override fun logResponse(response: FloconNetworkCallResponse) { coroutineScope.launch { - delay(200) // to be sure the request is handled before the response, in case of mocks or direct connection refused + delay(200) // to be sure the request is handled before the response try { sender.send( plugin = Protocol.FromDevice.Network.Plugin, @@ -102,23 +101,24 @@ internal class FloconNetworkPluginImpl( } override fun onMessageReceived( - messageFromServer: FloconMessageFromServer, + method: String, + body: String, ) { - when (messageFromServer.method) { + when (method) { Protocol.ToDevice.Network.Method.SetupMocks -> { - val setup = parseMockResponses(jsonString = messageFromServer.body) + val setup = parseMockResponses(jsonString = body) _mocks.update { setup } dataSource.saveMocksToFile(mocks) } Protocol.ToDevice.Network.Method.SetupBadNetworkConfig -> { - val config = parseBadQualityConfig(jsonString = messageFromServer.body) + val config = parseBadQualityConfig(jsonString = body) _badQualityConfig.update { config } dataSource.saveBadNetworkConfig(config) } Protocol.ToDevice.Network.Method.WebsocketMockMessage -> { - val message = parseWebSocketMockMessage(jsonString = messageFromServer.body) + val message = parseWebSocketMockMessage(jsonString = body) if(message != null) { websocketListeners.value[message.id]?.onMessage(message.message) } @@ -147,5 +147,4 @@ internal class FloconNetworkPluginImpl( body = webSocketIdsToJsonArray(ids = websocketListeners.value.keys), ) } - } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt index e1818d432..7b5f526f4 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt @@ -1,167 +1,85 @@ package io.github.openflocon.flocon.plugins.sharedprefs -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin -import io.github.openflocon.flocon.model.FloconMessageFromServer -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreferenceValue -import io.github.openflocon.flocon.plugins.sharedprefs.model.fromdevice.PreferenceRowDataModel -import io.github.openflocon.flocon.plugins.sharedprefs.model.fromdevice.SharedPreferenceValueResultDataModel -import io.github.openflocon.flocon.plugins.sharedprefs.model.listSharedPreferencesDescriptorToJson -import io.github.openflocon.flocon.plugins.sharedprefs.model.todevice.ToDeviceEditSharedPreferenceValueMessage -import io.github.openflocon.flocon.plugins.sharedprefs.model.todevice.ToDeviceGetSharedPreferenceValueMessage -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch +import io.github.openflocon.flocon.plugins.sharedprefs.mapper.toJson +import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconSharedPreferenceModel +import io.github.openflocon.flocon.plugins.sharedprefs.model.todevice.SetSharedPreferenceValueMessage + +actual object FloconPreferences : FloconPluginFactory { + override val name: String = "Preferences" + override val pluginId: String = Protocol.ToDevice.SharedPreferences.Plugin + override fun createConfig() = FloconPreferencesConfig() + override fun install(config: FloconPreferencesConfig, app: FloconApp): FloconPreferencesPlugin { + return FloconSharedPrefsPluginImpl( + context = app.context, + sender = app.client as FloconMessageSender + ) + } +} -internal interface FloconPreferencesDataSource { - fun detectLocalPreferences(): List +internal interface FloconSharedPreferenceDataSource { + fun getSharedPreferences(): List + fun getSharedPreferenceValue(fileName: String, key: String): String? + fun setSharedPreferenceValue(fileName: String, key: String, value: String) } -internal expect fun buildFloconPreferencesDataSource(context: FloconContext): FloconPreferencesDataSource +internal expect fun buildFloconSharedPreferenceDataSource(context: FloconContext): FloconSharedPreferenceDataSource -internal class FloconPreferencesPluginImpl( - context: FloconContext, - private var sender: FloconMessageSender, - private val scope: CoroutineScope, +internal class FloconSharedPrefsPluginImpl( + private val context: FloconContext, + private val sender: FloconMessageSender, ) : FloconPlugin, FloconPreferencesPlugin { - // references for quick access - private val preferences = mutableMapOf() - - private val dataSource = buildFloconPreferencesDataSource(context) + private val dataSource = buildFloconSharedPreferenceDataSource(context) + private val preferenceModels = mutableListOf() override fun onMessageReceived( - messageFromServer: FloconMessageFromServer, + method: String, + body: String, ) { - when (messageFromServer.method) { + when (method) { Protocol.ToDevice.SharedPreferences.Method.GetSharedPreferences -> { - sendAllSharedPrefs() + sendSharedPreferences() } Protocol.ToDevice.SharedPreferences.Method.GetSharedPreferenceValue -> { - val toDeviceMessage = - ToDeviceGetSharedPreferenceValueMessage.fromJson(message = messageFromServer.body) - ?: return - - val preference = preferences[toDeviceMessage.sharedPreferenceName] ?: return - - scope.launch { - sendToServerPreferenceValues( - preference = preference, - requestId = toDeviceMessage.requestId, - sender = sender, - ) - } + // Not implemented yet on device side, usually handled by getSharedPreferences } Protocol.ToDevice.SharedPreferences.Method.SetSharedPreferenceValue -> { - val toDeviceMessage = - ToDeviceEditSharedPreferenceValueMessage.fromJson(jsonString = messageFromServer.body) - ?: return - - val preference = preferences[toDeviceMessage.sharedPreferenceName] ?: return - - scope.launch { - try { - preference.set( - columnName = toDeviceMessage.key, - value = FloconPreferenceValue( - stringValue = toDeviceMessage.stringValue, - booleanValue = toDeviceMessage.booleanValue, - intValue = toDeviceMessage.intValue, - longValue = toDeviceMessage.longValue, - floatValue = toDeviceMessage.floatValue, - setStringValue = toDeviceMessage.setStringValue, - ), - ) - - // then send the shared pref content - sendToServerPreferenceValues( - preference = preference, - requestId = toDeviceMessage.requestId, - sender = sender, - ) - - //sender.send(Protocol.FromDevice.SharedPreferences.Plugin, "success") - } catch (t: Throwable) { - t.printStackTrace() - //sender.send(Protocol.FromDevice.SharedPreferences.Plugin, "failure") - } + SetSharedPreferenceValueMessage.fromJson(body)?.let { message -> + dataSource.setSharedPreferenceValue( + fileName = message.fileName, + key = message.key, + value = message.value + ) + // Refresh view + sendSharedPreferences() } } } } - private suspend fun sendToServerPreferenceValues( - preference: FloconPreference, - requestId: String, - sender: FloconMessageSender - ) { - val columns = preference.columns() - val rows = columns.map { key -> - val value = preference.get(key) - PreferenceRowDataModel( - key = key, - stringValue = value?.stringValue, - intValue = value?.intValue, - floatValue = value?.floatValue, - booleanValue = value?.booleanValue, - longValue = value?.longValue, - setStringValue = value?.setStringValue, - ) - } - - try { - sender.send( - plugin = Protocol.FromDevice.SharedPreferences.Plugin, - method = Protocol.FromDevice.SharedPreferences.Method.GetSharedPreferenceValue, - body = SharedPreferenceValueResultDataModel( - requestId = requestId, - sharedPreferenceName = preference.name, - rows = rows, - ).toJson(), - ) - } catch (t: Throwable) { - FloconLogger.logError("SharedPreferences json mapping error", t) - } - } - - // on connected, send all shared prefs override fun onConnectedToServer() { - dataSource.detectLocalPreferences().forEach { preference -> - registerInternal(preference) - } - sendAllSharedPrefs() + sendSharedPreferences() } - override fun register(preference: FloconPreference) { - registerInternal(preference) - sendAllSharedPrefs() + override fun register(sharedPreference: FloconSharedPreferenceModel) { + preferenceModels.add(sharedPreference) + sendSharedPreferences() } - private fun registerInternal(preference: FloconPreference) { - if(preferences.containsKey(preference.name).not()) { - preferences[preference.name] = preference - } - } - - private fun sendAllSharedPrefs() { - val allPrefs = getAllPreferences() + private fun sendSharedPreferences() { + val allPrefs = dataSource.getSharedPreferences() + preferenceModels try { sender.send( plugin = Protocol.FromDevice.SharedPreferences.Plugin, method = Protocol.FromDevice.SharedPreferences.Method.GetSharedPreferences, - body = listSharedPreferencesDescriptorToJson(allPrefs).toString(), + body = allPrefs.toJson().toString() ) } catch (t: Throwable) { FloconLogger.logError("SharedPreferences json mapping error", t) } } - - private fun getAllPreferences(): List { - return preferences.values.sortedBy { it.name } - } } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt index e2d6a7ec4..c52587f62 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt @@ -1,19 +1,28 @@ package io.github.openflocon.flocon.plugins.tables -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.FloconPlugin -import io.github.openflocon.flocon.model.FloconMessageFromServer import io.github.openflocon.flocon.plugins.tables.model.TableItem import io.github.openflocon.flocon.plugins.tables.model.tableItemListToJson +actual object FloconTable : FloconPluginFactory { + override val name: String = "Table" + override val pluginId: String = Protocol.ToDevice.Table.Plugin + override fun createConfig() = FloconTableConfig() + override fun install(config: FloconTableConfig, app: FloconApp): FloconTablePlugin { + return FloconTablePluginImpl( + sender = app.client as FloconMessageSender + ) + } +} + internal class FloconTablePluginImpl( private val sender: FloconMessageSender, ) : FloconPlugin, FloconTablePlugin { override fun onMessageReceived( - messageFromServer: FloconMessageFromServer, + method: String, + body: String, ) { // no op } @@ -22,16 +31,16 @@ internal class FloconTablePluginImpl( // no op } - override fun registerTable(tableItem: TableItem) { - sendTable(tableItem) + override fun registerItems(tableItems: List) { + sendTable(tableItems) } - private fun sendTable(tableItem: TableItem) { + private fun sendTable(tableItems: List) { try { sender.send( plugin = Protocol.FromDevice.Table.Plugin, method = Protocol.FromDevice.Table.Method.AddItems, - body = tableItemListToJson(listOf(tableItem)).toString() // desktop is expecting an array of table items + body = tableItemListToJson(tableItems).toString() ) } catch (t: Throwable) { FloconLogger.logError("Table json mapping error", t) diff --git a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt index 5878a2038..5cf459641 100644 --- a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt +++ b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt @@ -15,6 +15,8 @@ import io.github.openflocon.flocon.myapplication.multi.database.initializeDataba import io.github.openflocon.flocon.myapplication.multi.database.model.DogEntity import io.github.openflocon.flocon.myapplication.multi.sharedpreferences.initializeSharedPreferences import io.github.openflocon.flocon.myapplication.multi.ui.App +import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks +import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinksPlugin import io.ktor.client.HttpClient import io.ktor.client.engine.okhttp.OkHttp import kotlinx.coroutines.GlobalScope @@ -55,7 +57,11 @@ class MainActivity : ComponentActivity() { ) FloconLogger.enabled = true - Flocon.initialize(this) + Flocon.initialize(this) { + install(FloconDeeplinks) { + + } + } setContent { App() diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index 511b0712c..a0cd76fd5 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -29,3 +29,5 @@ include(":ktor-interceptor") include(":ktor-interceptor-no-op") include(":datastores") include(":datastores-no-op") +include(":deeplinks") +include(":deeplinks-no-op") From 12ef1441fb53ff436dacc80ffe36c3553c6923f5 Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Wed, 11 Mar 2026 23:29:51 +0100 Subject: [PATCH 02/35] feat: Make app compile & remove flocon-base --- .../datastores-no-op/build.gradle.kts | 2 +- .../model/FloconDatastorePreference.kt | 19 +- FloconAndroid/datastores/build.gradle.kts | 2 +- .../model/FloconDatastorePreference.kt | 140 +++---- .../deeplinks-no-op/build.gradle.kts | 2 +- .../plugins/deeplinks/FloconDeeplinksNoOp.kt | 1 - FloconAndroid/deeplinks/build.gradle.kts | 1 - .../plugins/deeplinks/FloconDeeplinks.kt | 10 +- .../deeplinks/FloconDeeplinksPlugin.kt | 2 +- FloconAndroid/flocon-base/.gitignore | 1 - FloconAndroid/flocon-base/build.gradle.kts | 118 ------ FloconAndroid/flocon-base/consumer-rules.pro | 0 FloconAndroid/flocon-base/proguard-rules.pro | 21 -- .../io/github/openflocon/flocon/FloconApp.kt | 53 --- .../analytics/FloconAnalyticsPlugin.kt | 38 -- .../FloconCrashReporterPlugin.kt | 16 - .../dashboard/FloconDashboardPlugin.kt | 15 - .../dashboard/builder/ContainerBuilder.kt | 14 - .../flocon/plugins/dashboard/dsl/ButtonDsl.kt | 19 - .../flocon/plugins/dashboard/dsl/HtmlDsl.kt | 9 - .../plugins/dashboard/dsl/MarkdownDsl.kt | 9 - .../plugins/dashboard/dsl/PlainTextDsl.kt | 24 -- .../plugins/dashboard/dsl/SectionDsl.kt | 13 - .../flocon/plugins/dashboard/dsl/TextDsl.kt | 15 - .../plugins/dashboard/model/ContainerType.kt | 6 - .../plugins/dashboard/model/Dashboard.kt | 8 - .../dashboard/model/config/ContainerConfig.kt | 9 - .../dashboard/model/config/ElementConfig.kt | 3 - .../plugins/database/FloconDatabasePlugin.kt | 41 --- .../plugins/deeplinks/model/DeeplinkModel.kt | 24 -- .../plugins/device/FloconDevicePlugin.kt | 14 - .../flocon/plugins/files/FloconFilesPlugin.kt | 15 - .../plugins/network/FloconNetworkPlugin.kt | 38 -- .../sharedprefs/FloconSharedPrefsPlugin.kt | 20 - .../plugins/tables/FloconTablesPlugin.kt | 31 -- .../plugins/tables/builder/TableBuilder.kt | 25 -- FloconAndroid/flocon-no-op/build.gradle.kts | 2 +- FloconAndroid/flocon/build.gradle.kts | 6 +- .../io/github/openflocon/flocon/Flocon.kt | 4 +- .../flocon/FloconBroadcastReceiver.kt | 3 +- .../flocon/FloconContext.android.kt | 5 + .../openflocon/flocon/FloconCore.android.kt | 15 +- .../github/openflocon/flocon/FloconLogger.kt | 7 +- .../openflocon/flocon/ServerHost.android.kt | 2 +- .../flocon/core/AppInfos.android.kt | 5 +- .../FloconCrashReporterDataSource.android.kt | 60 +-- .../UncaughtExceptionHandler.android.kt | 23 -- .../database/FloconDatabasePlugin.android.kt | 273 +------------- .../device/FloconDevicePluginImpl.android.kt | 2 - .../plugins/device/GetAppIconUtils.android.kt | 66 +--- .../files/FloconFilesPlugin.android.kt | 100 +---- .../FloconNetworkPluginImpl.android.kt | 79 +--- .../FloconSharedPrefsPlugin.android.kt | 18 +- .../FloconCrashReporterDataSource.android.kt | 60 +++ .../UncaughtExceptionHandler.android.kt | 23 ++ .../database/FloconDatabasePlugin.android.kt | 277 ++++++++++++++ .../database/FloconSqliteDatabaseModel.kt | 16 +- .../device/FloconDevicePluginImpl.android.kt | 8 + .../device/GetAppIconUtils.android.kt | 69 ++++ .../files/FloconFilesPlugin.android.kt | 102 ++++++ .../FloconNetworkPluginImpl.android.kt | 88 +++++ .../sharedprefs/FloconSharedPreference.kt | 6 +- .../FloconSharedPrefsPlugin.android.kt | 25 ++ .../sharedprefs/SharedPreferencesFinder.kt | 16 +- .../flocon/utils/PlatformUtils.android.kt | 0 .../io/github/openflocon/flocon/Flocon.kt | 16 + .../io/github/openflocon/flocon/FloconApp.kt | 44 +++ .../openflocon/flocon/FloconConfiguration.kt | 12 +- .../github/openflocon/flocon/FloconContext.kt | 3 + .../io/github/openflocon/flocon/FloconCore.kt | 24 +- .../github/openflocon/flocon/FloconLogger.kt | 0 .../github/openflocon/flocon/FloconPlugin.kt | 5 +- .../flocon/client/FloconClientImpl.kt | 91 +---- .../openflocon/flocon/core/FloconPlugin.kt | 10 - .../analytics/FloconAnalyticsPlugin.kt | 14 +- .../analytics/mapper/AnalyticsItemsMapper.kt | 2 +- .../FloconCrashReporterPlugin.kt | 17 +- .../crashreporter/model/CrashReportMapper.kt | 1 - .../plugins/dashboard/FloconDashboardDSL.kt | 13 +- .../dashboard/FloconDashboardPlugin.kt | 7 +- .../plugins/dashboard/mapper/JsonMapper.kt | 26 +- .../plugins/database/FloconDatabasePlugin.kt | 28 +- .../deeplinks/FloconDeeplinksPlugin.kt | 66 ---- .../flocon/plugins/deeplinks/Mapping.kt | 53 --- .../deeplinks/model/DeeplinksRemote.kt | 65 ---- .../plugins/device/FloconDevicePluginImpl.kt | 5 +- .../flocon/plugins/files/FloconFilesPlugin.kt | 39 +- .../network/FloconNetworkPluginImpl.kt | 39 +- .../network/mapper/BadQualityToJson.kt | 5 +- .../mapper/FloconNetworkRequestToJson.kt | 10 +- .../network/mapper/MockResponseToJson.kt | 7 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 61 ++-- .../model/FloconPreferenceWrapper.kt | 1 + .../plugins/tables/FloconTablesPlugin.kt | 7 +- .../flocon/plugins/tables/model/TableItem.kt | 2 + .../analytics/FloconAnalyticsPlugin.kt | 39 ++ .../analytics/builder/AnalyticsBuilder.kt | 8 +- .../analytics/model/AnalyticsEvent.kt | 2 +- .../model/AnalyticsPropertiesConfig.kt | 2 +- .../pluginsold}/analytics/model/TableItem.kt | 2 +- .../FloconCrashReporterPlugin.kt | 16 + .../dashboard/FloconDashboardPlugin.kt | 15 + .../dashboard/builder/ContainerBuilder.kt | 14 + .../dashboard/builder/DashboardBuilder.kt | 8 +- .../dashboard/builder/FormBuilder.kt | 4 +- .../dashboard/builder/SectionBuilder.kt | 4 +- .../pluginsold/dashboard/dsl/ButtonDsl.kt | 19 + .../pluginsold}/dashboard/dsl/CheckBoxDsl.kt | 6 +- .../pluginsold}/dashboard/dsl/DashboardDsl.kt | 6 +- .../pluginsold}/dashboard/dsl/FormDsl.kt | 6 +- .../pluginsold/dashboard/dsl/HtmlDsl.kt | 9 + .../pluginsold/dashboard/dsl/MarkdownDsl.kt | 9 + .../pluginsold/dashboard/dsl/PlainTextDsl.kt | 26 ++ .../pluginsold/dashboard/dsl/SectionDsl.kt | 13 + .../pluginsold/dashboard/dsl/TextDsl.kt | 15 + .../pluginsold}/dashboard/dsl/TextField.kt | 6 +- .../dashboard/model/ContainerType.kt | 6 + .../pluginsold/dashboard/model/Dashboard.kt | 8 + .../dashboard/model/DashboardScope.kt | 10 +- .../dashboard/model/config/ButtonConfig.kt | 2 +- .../dashboard/model/config/CheckBoxConfig.kt | 2 +- .../dashboard/model/config/ContainerConfig.kt | 9 + .../dashboard/model/config/ElementConfig.kt | 3 + .../dashboard/model/config/FormConfig.kt | 4 +- .../dashboard/model/config/HtmlConfig.kt | 2 +- .../dashboard/model/config/LabelConfig.kt | 2 +- .../dashboard/model/config/MarkdownConfig.kt | 2 +- .../dashboard/model/config/PlainTextConfig.kt | 2 +- .../dashboard/model/config/SectionConfig.kt | 4 +- .../dashboard/model/config/TextConfig.kt | 2 +- .../dashboard/model/config/TextFieldConfig.kt | 2 +- .../database/FloconDatabasePlugin.kt | 34 ++ .../database/model/FloconDatabaseModel.kt | 2 +- .../pluginsold/device/FloconDevicePlugin.kt | 28 ++ .../pluginsold/files/FloconFilesPlugin.kt | 29 ++ .../pluginsold/network/FloconNetworkPlugin.kt | 45 +++ .../network/model/BadQualityConfig.kt | 2 +- .../network/model/FloconHttpRequest.kt | 2 +- .../network/model/FloconNetworkCallRequest.kt | 2 +- .../model/FloconNetworkCallResponse.kt | 2 +- .../network/model/FloconWebSocketEvent.kt | 2 +- .../model/FloconWebSocketMockListener.kt | 2 +- .../network/model/MockNetworkResponse.kt | 2 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 34 ++ .../buildFloconPreferencesDataSource.kt | 2 + .../sharedprefs/model/FloconPreference.kt | 4 +- .../model/FloconSharedPreferenceModel.kt | 5 + .../pluginsold/tables/FloconTablesPlugin.kt | 46 +++ .../pluginsold/tables/builder/TableBuilder.kt | 20 + .../tables/model/TableColumnConfig.kt | 2 +- .../pluginsold}/tables/model/TableItem.kt | 2 +- .../openflocon/flocon/utils/PlatformUtils.kt | 0 .../github/openflocon/flocon/FloconLogger.kt | 7 +- .../FloconSharedPrefsPlugin.ios.kt | 21 +- .../flocon/utils/PlatformUtils.ios.kt | 0 .../github/openflocon/flocon/FloconLogger.kt | 7 +- .../FloconSharedPrefsPlugin.jvm.kt | 19 +- .../flocon/utils/PlatformUtils.jvm.kt | 0 .../grpc-interceptor-base/build.gradle.kts | 2 +- .../openflocon/flocon/grpc/BadQuality.kt | 2 +- .../flocon/grpc/FloconGrpcBaseInterceptor.kt | 15 +- .../flocon/grpc/FloconGrpcPlugin.kt | 43 +-- .../flocon/grpc/model/RequestHolder.kt | 2 +- .../ktor-interceptor-no-op/build.gradle.kts | 2 +- .../ktor-interceptor/build.gradle.kts | 2 +- .../openflocon/flocon/ktor/BadQuality.kt | 2 +- .../flocon/ktor/FloconKtorPlugin.kt | 344 +++++++++--------- .../io/github/openflocon/flocon/ktor/Mocks.kt | 11 +- .../okhttp-interceptor/build.gradle.kts | 2 +- .../openflocon/flocon/okhttp/BadQuality.kt | 5 +- .../github/openflocon/flocon/okhttp/Mock.kt | 19 +- .../flocon/okhttp/OkHttpInterceptor.kt | 204 +++++------ .../okhttp/websocket/FloconWebSocket.kt | 36 +- .../flocon/myapplication/MainActivity.kt | 159 ++++---- .../dashboard/InitializeDashboard.kt | 18 +- .../myapplication/database/DogDatabase.kt | 24 +- .../database/InitializeDatabases.kt | 2 +- .../deeplinks/InitializeDeeplinks.kt | 31 -- .../sharedpreferences/Datastores.kt | 4 +- .../sharedpreferences/SharedPreferences.kt | 7 +- .../table/InitializeDashboard.kt | 13 +- .../sample-multiplatform/build.gradle.kts | 1 - .../myapplication/multi/MainActivity.kt | 5 - FloconAndroid/settings.gradle.kts | 4 +- 184 files changed, 2061 insertions(+), 2319 deletions(-) rename FloconAndroid/{flocon-base => deeplinks}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt (98%) delete mode 100644 FloconAndroid/flocon-base/.gitignore delete mode 100644 FloconAndroid/flocon-base/build.gradle.kts delete mode 100644 FloconAndroid/flocon-base/consumer-rules.pro delete mode 100644 FloconAndroid/flocon-base/proguard-rules.pro delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/ContainerBuilder.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/ButtonDsl.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/HtmlDsl.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/MarkdownDsl.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/PlainTextDsl.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/SectionDsl.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextDsl.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/ContainerType.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/Dashboard.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ContainerConfig.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ElementConfig.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPlugin.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt delete mode 100644 FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/builder/TableBuilder.kt create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconContext.android.kt rename FloconAndroid/{flocon-base => flocon}/src/androidMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt (97%) delete mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/UncaughtExceptionHandler.android.kt create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/UncaughtExceptionHandler.android.kt create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt rename FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/{plugins => pluginsold}/database/FloconSqliteDatabaseModel.kt (64%) create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePluginImpl.android.kt create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/device/GetAppIconUtils.android.kt create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPluginImpl.android.kt rename FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/{plugins => pluginsold}/sharedprefs/FloconSharedPreference.kt (90%) create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.android.kt rename FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/{plugins => pluginsold}/sharedprefs/SharedPreferencesFinder.kt (75%) rename FloconAndroid/{flocon-base => flocon}/src/androidMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.android.kt (100%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt rename FloconAndroid/{flocon-base => flocon}/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt (77%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconContext.kt rename FloconAndroid/{flocon-base => flocon}/src/commonMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt (100%) rename FloconAndroid/{flocon-base => flocon}/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt (87%) delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconPlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/analytics/builder/AnalyticsBuilder.kt (73%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/analytics/model/AnalyticsEvent.kt (80%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/analytics/model/AnalyticsPropertiesConfig.kt (76%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/analytics/model/TableItem.kt (74%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/FloconDashboardPlugin.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/ContainerBuilder.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/builder/DashboardBuilder.kt (53%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/builder/FormBuilder.kt (73%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/builder/SectionBuilder.kt (51%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/ButtonDsl.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/dsl/CheckBoxDsl.kt (57%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/dsl/DashboardDsl.kt (53%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/dsl/FormDsl.kt (61%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/HtmlDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/MarkdownDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/PlainTextDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/SectionDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/TextDsl.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/dsl/TextField.kt (62%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/ContainerType.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/Dashboard.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/DashboardScope.kt (72%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/ButtonConfig.kt (61%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/CheckBoxConfig.kt (68%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ContainerConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ElementConfig.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/FormConfig.kt (66%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/HtmlConfig.kt (55%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/LabelConfig.kt (55%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/MarkdownConfig.kt (56%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/PlainTextConfig.kt (65%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/SectionConfig.kt (57%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/TextConfig.kt (61%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/dashboard/model/config/TextFieldConfig.kt (72%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/database/model/FloconDatabaseModel.kt (75%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/network/model/BadQualityConfig.kt (97%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/network/model/FloconHttpRequest.kt (91%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/network/model/FloconNetworkCallRequest.kt (73%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/network/model/FloconNetworkCallResponse.kt (76%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/network/model/FloconWebSocketEvent.kt (87%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/network/model/FloconWebSocketMockListener.kt (56%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/network/model/MockNetworkResponse.kt (94%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/buildFloconPreferencesDataSource.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/sharedprefs/model/FloconPreference.kt (82%) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/FloconTablesPlugin.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/tables/model/TableColumnConfig.kt (75%) rename FloconAndroid/{flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold}/tables/model/TableItem.kt (68%) rename FloconAndroid/{flocon-base => flocon}/src/commonMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.kt (100%) rename FloconAndroid/{flocon-base => flocon}/src/iosMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt (97%) rename FloconAndroid/{flocon-base => flocon}/src/iosMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.ios.kt (100%) rename FloconAndroid/{flocon-base => flocon}/src/jvmMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt (97%) rename FloconAndroid/{flocon-base => flocon}/src/jvmMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.jvm.kt (100%) delete mode 100644 FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/deeplinks/InitializeDeeplinks.kt diff --git a/FloconAndroid/datastores-no-op/build.gradle.kts b/FloconAndroid/datastores-no-op/build.gradle.kts index 859f94eac..c3f4b30d0 100644 --- a/FloconAndroid/datastores-no-op/build.gradle.kts +++ b/FloconAndroid/datastores-no-op/build.gradle.kts @@ -41,7 +41,7 @@ kotlin { dependencies { - implementation(project(":flocon-base")) + implementation(project(":flocon")) implementation(platform(libs.kotlinx.coroutines.bom)) implementation(libs.jetbrains.kotlinx.coroutines.core) diff --git a/FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt b/FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt index 885a2fdf3..cfe707327 100644 --- a/FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt +++ b/FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt @@ -2,17 +2,8 @@ package io.github.openflocon.flocon.preferences.datastores.model import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.core.booleanPreferencesKey -import androidx.datastore.preferences.core.doublePreferencesKey -import androidx.datastore.preferences.core.edit -import androidx.datastore.preferences.core.floatPreferencesKey -import androidx.datastore.preferences.core.intPreferencesKey -import androidx.datastore.preferences.core.longPreferencesKey -import androidx.datastore.preferences.core.stringPreferencesKey -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreferenceValue -import kotlinx.coroutines.flow.first +import io.github.openflocon.flocon.`plugins-old`.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.`plugins-old`.sharedprefs.model.FloconPreferenceValue interface FloconDatastoreMapper { fun fromDatastore(datastoreValue: String) : String @@ -22,11 +13,11 @@ interface FloconDatastoreMapper { class FloconDatastorePreference( override val name: String, val dataStore: DataStore, -) : FloconPreference { +) : io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference { override suspend fun set( columnName: String, - value: FloconPreferenceValue + value: io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreferenceValue ) { // no op } @@ -35,7 +26,7 @@ class FloconDatastorePreference( return emptyList() // no op } - override suspend fun get(columnName: String): FloconPreferenceValue? { + override suspend fun get(columnName: String): io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreferenceValue? { return null // no op } diff --git a/FloconAndroid/datastores/build.gradle.kts b/FloconAndroid/datastores/build.gradle.kts index 5f784f502..e30b81eca 100644 --- a/FloconAndroid/datastores/build.gradle.kts +++ b/FloconAndroid/datastores/build.gradle.kts @@ -41,7 +41,7 @@ kotlin { dependencies { - implementation(project(":flocon-base")) + implementation(project(":flocon")) implementation(platform(libs.kotlinx.coroutines.bom)) implementation(libs.jetbrains.kotlinx.coroutines.core) diff --git a/FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt b/FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt index a6b77fa6c..4e71bce4c 100644 --- a/FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt +++ b/FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt @@ -10,8 +10,8 @@ import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.core.longPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreferenceValue +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreferenceValue import kotlinx.coroutines.flow.first interface FloconDatastoreMapper { @@ -19,70 +19,72 @@ interface FloconDatastoreMapper { fun toDatastore(valueForDatastore: String) : String } -class FloconDatastorePreference( - override val name: String, - private val dataStore: DataStore, - private val mapper: FloconDatastoreMapper? = null // if we encrypted the datastore -) : FloconPreference { - - override suspend fun set( - columnName: String, - value: FloconPreferenceValue - ) { - try { - val data = dataStore.data.first().asMap() - val key = data.keys.find { it.name == columnName } ?: return - - dataStore.edit { - try { - when (it[key]) { - is String -> it[stringPreferencesKey(columnName)] = mapper?.let { - it.toDatastore(value.stringValue!!) - } ?: value.stringValue!! - is Int -> it[intPreferencesKey(columnName)] = value.intValue!! - is Boolean -> it[booleanPreferencesKey(columnName)] = value.booleanValue!! - is Float -> it[floatPreferencesKey(columnName)] = value.floatValue!! - is Long -> it[longPreferencesKey(columnName)] = value.longValue!! - is Double -> it[doublePreferencesKey(columnName)] = - value.floatValue!!.toDouble() - } - } catch (t: Throwable) { - FloconLogger.logError("cannot update datastore preference", t) - } - } - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "cannot edit datastore preference columns", t) - } - } - - override suspend fun columns(): List { - return try { - dataStore.data.first().asMap().map { it.key.name } - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "cannot get datastore preference columns", t) - emptyList() - } - } - - override suspend fun get(columnName: String): FloconPreferenceValue? { - return try { - val data = dataStore.data.first().asMap() - val key = data.keys.find { it.name == columnName } ?: return null - val value = data[key] ?: return null - - return when (value) { - is String -> FloconPreferenceValue(stringValue = mapper?.fromDatastore(value) ?: value) - is Int -> FloconPreferenceValue(intValue = value) - is Float -> FloconPreferenceValue(floatValue = value) - is Double -> FloconPreferenceValue(floatValue = value.toFloat()) - is Boolean -> FloconPreferenceValue(booleanValue = value) - is Long -> FloconPreferenceValue(longValue = value) - else -> null - } - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "cannot get datastore preference value", t) - null - } - } - -} \ No newline at end of file +//class FloconDatastorePreference( +// override val name: String, +// private val dataStore: DataStore, +// private val mapper: FloconDatastoreMapper? = null // if we encrypted the datastore +//) : FloconPreference { +// +// override suspend fun set( +// columnName: String, +// FloconPreferenceValue +// ) { +// try { +// val data = dataStore.data.first().asMap() +// val key = data.keys.find { it.name == columnName } ?: return +// +// dataStore.edit { +// try { +// when (it[key]) { +// is String -> it[stringPreferencesKey(columnName)] = mapper?.let { +// it.toDatastore(value.stringValue!!) +// } ?: value.stringValue!! +// is Int -> it[intPreferencesKey(columnName)] = value.intValue!! +// is Boolean -> it[booleanPreferencesKey(columnName)] = value.booleanValue!! +// is Float -> it[floatPreferencesKey(columnName)] = value.floatValue!! +// is Long -> it[longPreferencesKey(columnName)] = value.longValue!! +// is Double -> it[doublePreferencesKey(columnName)] = +// value.floatValue!!.toDouble() +// } +// } catch (t: Throwable) { +// FloconLogger.logError("cannot update datastore preference", t) +// } +// } +// } catch (t: Throwable) { +// FloconLogger.logError(t.message ?: "cannot edit datastore preference columns", t) +// } +// } +// +// override suspend fun columns(): List { +// return try { +// dataStore.data.first().asMap().map { it.key.name } +// } catch (t: Throwable) { +// FloconLogger.logError(t.message ?: "cannot get datastore preference columns", t) +// emptyList() +// } +// } +// +// override suspend fun get(columnName: String): io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreferenceValue? { +// return try { +// val data = dataStore.data.first().asMap() +// val key = data.keys.find { it.name == columnName } ?: return null +// val value = data[key] ?: return null +// +// return when (value) { +// is String -> FloconPreferenceValue( +// stringValue = mapper?.fromDatastore(value) ?: value +// ) +// is Int -> FloconPreferenceValue(intValue = value) +// is Float -> FloconPreferenceValue(floatValue = value) +// is Double -> FloconPreferenceValue(floatValue = value.toFloat()) +// is Boolean -> FloconPreferenceValue(booleanValue = value) +// is Long -> FloconPreferenceValue(longValue = value) +// else -> null +// } +// } catch (t: Throwable) { +// FloconLogger.logError(t.message ?: "cannot get datastore preference value", t) +// null +// } +// } +// +//} \ No newline at end of file diff --git a/FloconAndroid/deeplinks-no-op/build.gradle.kts b/FloconAndroid/deeplinks-no-op/build.gradle.kts index 1d0039cd9..b183bb71e 100644 --- a/FloconAndroid/deeplinks-no-op/build.gradle.kts +++ b/FloconAndroid/deeplinks-no-op/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon-base")) + implementation(project(":flocon")) implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) } } diff --git a/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt b/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt index a377c7896..83c349e12 100644 --- a/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt +++ b/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt @@ -1,7 +1,6 @@ package io.github.openflocon.flocon.plugins.deeplinks import io.github.openflocon.flocon.* -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel actual object FloconDeeplinks : FloconPluginFactory { override val name: String = "Deeplinks" diff --git a/FloconAndroid/deeplinks/build.gradle.kts b/FloconAndroid/deeplinks/build.gradle.kts index fc1029164..25714f431 100644 --- a/FloconAndroid/deeplinks/build.gradle.kts +++ b/FloconAndroid/deeplinks/build.gradle.kts @@ -23,7 +23,6 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon-base")) implementation(project(":flocon")) implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) implementation(libs.kotlinx.serialization.json) diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt index 353080db9..3e2c697ea 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -24,6 +24,7 @@ object FloconDeeplinks : FloconPluginFactory?>(null) @@ -57,12 +58,3 @@ internal class FloconDeeplinksPluginImpl( } } } - -fun floconRegisterDeeplink(vararg deeplinks: String) { - val models = deeplinks.map { DeeplinkModel(link = it, parameters = emptyList()) } - FloconApp.instance?.client?.deeplinksPlugin?.registerDeeplinks(models) -} - -fun floconRegisterDeeplinks(deeplinks: List) { - FloconApp.instance?.client?.deeplinksPlugin?.registerDeeplinks(deeplinks) -} diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt similarity index 98% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt rename to FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt index 316359861..1e4f57cbd 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.plugins.deeplinks -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel class DeeplinkLinkBuilder internal constructor( diff --git a/FloconAndroid/flocon-base/.gitignore b/FloconAndroid/flocon-base/.gitignore deleted file mode 100644 index 42afabfd2..000000000 --- a/FloconAndroid/flocon-base/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/FloconAndroid/flocon-base/build.gradle.kts b/FloconAndroid/flocon-base/build.gradle.kts deleted file mode 100644 index 4c63dfe76..000000000 --- a/FloconAndroid/flocon-base/build.gradle.kts +++ /dev/null @@ -1,118 +0,0 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) -} - -kotlin { - androidTarget { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - - sourceSets { - val commonMain by getting { - dependencies { - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) - } - } - - val androidMain by getting { - dependencies { - } - } - - val jvmMain by getting { - dependencies { - } - } - - val iosX64Main by getting - val iosArm64Main by getting - val iosSimulatorArm64Main by getting - val iosMain by creating { - dependsOn(commonMain) - iosX64Main.dependsOn(this) - iosArm64Main.dependsOn(this) - iosSimulatorArm64Main.dependsOn(this) - } - } -} - -android { - namespace = "io.github.openflocon.flocon.base" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} - -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-base", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) - - pom { - name = "Flocon" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/consumer-rules.pro b/FloconAndroid/flocon-base/consumer-rules.pro deleted file mode 100644 index e69de29bb..000000000 diff --git a/FloconAndroid/flocon-base/proguard-rules.pro b/FloconAndroid/flocon-base/proguard-rules.pro deleted file mode 100644 index 481bb4348..000000000 --- a/FloconAndroid/flocon-base/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt deleted file mode 100644 index b6df35c73..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt +++ /dev/null @@ -1,53 +0,0 @@ -package io.github.openflocon.flocon - -import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin -import io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporterPlugin -import io.github.openflocon.flocon.plugins.dashboard.FloconDashboardPlugin -import io.github.openflocon.flocon.plugins.database.FloconDatabasePlugin -import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinksPlugin -import io.github.openflocon.flocon.plugins.device.FloconDevicePlugin -import io.github.openflocon.flocon.plugins.network.FloconNetworkPlugin -import io.github.openflocon.flocon.plugins.sharedprefs.FloconPreferencesPlugin -import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin -import kotlinx.coroutines.flow.StateFlow - -abstract class FloconApp { - lateinit var context: FloconContext - - companion object { - var instance: FloconApp? = null - private set - } - - interface Client { - - @Throws(Throwable::class) - suspend fun connect(onClosed: () -> Unit) - suspend fun disconnect() - - val databasePlugin: FloconDatabasePlugin? - val dashboardPlugin: FloconDashboardPlugin? - val tablePlugin: FloconTablePlugin? - val deeplinksPlugin: FloconDeeplinksPlugin? - val analyticsPlugin: FloconAnalyticsPlugin? - val networkPlugin: FloconNetworkPlugin? - val devicePlugin: FloconDevicePlugin? - val preferencesPlugin: FloconPreferencesPlugin? - val crashReporterPlugin: FloconCrashReporterPlugin? - - /** - * Retrieve a plugin instance by its [key]. - */ - fun getPlugin(key: FloconPluginKey<*, T>): T? - } - - open val client: Client? = null - - abstract val isInitialized : StateFlow - - protected fun initializeFlocon(context: FloconContext) { - this.context = context - instance = this - } - -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt deleted file mode 100644 index 846d49bf4..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ /dev/null @@ -1,38 +0,0 @@ -package io.github.openflocon.flocon.plugins.analytics - -import io.github.openflocon.flocon.* -import io.github.openflocon.flocon.plugins.analytics.builder.AnalyticsBuilder -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem - -class FloconAnalyticsConfig - -/** - * Flocon Analytics Plugin. - */ -expect object FloconAnalytics : FloconPluginFactory { - override fun createConfig(): FloconAnalyticsConfig - override fun install( - config: FloconAnalyticsConfig, - app: FloconApp - ): FloconAnalyticsPlugin - - override val name: String -} - -fun floconAnalytics(analyticsName: String) : AnalyticsBuilder { - return AnalyticsBuilder( - analyticsTableId = analyticsName, - analyticsPlugin = FloconApp.instance?.client?.analyticsPlugin, - ) -} - -fun FloconApp.analytics(analyticsName: String): AnalyticsBuilder { - return AnalyticsBuilder( - analyticsTableId = analyticsName, - analyticsPlugin = this.client?.analyticsPlugin, - ) -} - -interface FloconAnalyticsPlugin : FloconPlugin { - fun registerAnalytics(analyticsItems: List) -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt deleted file mode 100644 index 3d1fa8dd9..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt +++ /dev/null @@ -1,16 +0,0 @@ -package io.github.openflocon.flocon.plugins.crashreporter - -import io.github.openflocon.flocon.* - -class FloconCrashReporterConfig { - var catchFatalErrors: Boolean = true -} - -/** - * Flocon Crash Reporter Plugin. - */ -expect object FloconCrashReporter : FloconPluginFactory - -interface FloconCrashReporterPlugin : FloconPlugin { - fun setupCrashHandler() -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt deleted file mode 100644 index bf2054d79..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard - -import io.github.openflocon.flocon.* -import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig - -class FloconDashboardConfig - -/** - * Flocon Dashboard Plugin. - */ -expect object FloconDashboard : FloconPluginFactory - -interface FloconDashboardPlugin : FloconPlugin { - fun registerDashboard(dashboardConfig: DashboardConfig) -} diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/ContainerBuilder.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/ContainerBuilder.kt deleted file mode 100644 index 3fbf6a10f..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/ContainerBuilder.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.builder - -import io.github.openflocon.flocon.plugins.dashboard.model.config.ContainerConfig -import io.github.openflocon.flocon.plugins.dashboard.model.config.ElementConfig - -abstract class ContainerBuilder { - open val elements = mutableListOf() - - open fun add(element: ElementConfig) { - elements.add(element) - } - - abstract fun build(): ContainerConfig -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/ButtonDsl.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/ButtonDsl.kt deleted file mode 100644 index cf654088d..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/ButtonDsl.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl - -import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder -import io.github.openflocon.flocon.plugins.dashboard.model.config.ButtonConfig - -@DashboardDsl -fun ContainerBuilder.button( - text: String, - id : String, - onClick: () -> Unit, -) { - add( - ButtonConfig( - text = text, - id = id, - onClick = onClick, - ) - ) -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/HtmlDsl.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/HtmlDsl.kt deleted file mode 100644 index 5b93e4884..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/HtmlDsl.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl - -import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder -import io.github.openflocon.flocon.plugins.dashboard.model.config.HtmlConfig - -@DashboardDsl -fun ContainerBuilder.html(label: String, value: String) { - add(HtmlConfig(label = label, value = value)) -} diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/MarkdownDsl.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/MarkdownDsl.kt deleted file mode 100644 index 1a9d5f6f3..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/MarkdownDsl.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl - -import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder -import io.github.openflocon.flocon.plugins.dashboard.model.config.MarkdownConfig - -@DashboardDsl -fun ContainerBuilder.markdown(label: String, value: String) { - add(MarkdownConfig(label = label, value = value)) -} diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/PlainTextDsl.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/PlainTextDsl.kt deleted file mode 100644 index 343788f69..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/PlainTextDsl.kt +++ /dev/null @@ -1,24 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl - -import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder -import io.github.openflocon.flocon.plugins.dashboard.model.config.PlainTextConfig - -@DashboardDsl -fun ContainerBuilder.plainText(label: String, value: String) { - add( - PlainTextConfig( - label = label, - value = value, - type = "text", - ) - ) -} - -@DashboardDsl -fun ContainerBuilder.json(label: String, value: String) { - add(PlainTextConfig( - label = label, - value = value, - type = "json", - )) -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/SectionDsl.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/SectionDsl.kt deleted file mode 100644 index 4e4ef095e..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/SectionDsl.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl - -import io.github.openflocon.flocon.plugins.dashboard.builder.DashboardBuilder -import io.github.openflocon.flocon.plugins.dashboard.builder.SectionBuilder - -@DashboardDsl -fun DashboardBuilder.section(name: String, block: SectionBuilder.() -> Unit) { - val builder = SectionBuilder(name).apply { - block() - } - - add(builder.build()) -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextDsl.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextDsl.kt deleted file mode 100644 index 9a80dde6d..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextDsl.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl - -import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder -import io.github.openflocon.flocon.plugins.dashboard.model.config.TextConfig -import io.github.openflocon.flocon.plugins.dashboard.model.config.LabelConfig - -@DashboardDsl -fun ContainerBuilder.text(label: String, value: String, color: Int? = null) { - add(TextConfig(label = label, value = value, color = color)) -} - -@DashboardDsl -fun ContainerBuilder.label(label: String, color: Int? = null) { - add(LabelConfig(label = label, color = color)) -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/ContainerType.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/ContainerType.kt deleted file mode 100644 index e33e10bf2..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/ContainerType.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.model - -enum class ContainerType { - FORM, - SECTION -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/Dashboard.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/Dashboard.kt deleted file mode 100644 index 5deacba9b..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/Dashboard.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.model - -import io.github.openflocon.flocon.plugins.dashboard.model.config.ContainerConfig - -data class DashboardConfig( - val id: String, - val containers: List -) \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ContainerConfig.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ContainerConfig.kt deleted file mode 100644 index 904b76885..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ContainerConfig.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config - -import io.github.openflocon.flocon.plugins.dashboard.model.ContainerType - -sealed interface ContainerConfig { - val name: String - val elements: List - val containerType: ContainerType -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ElementConfig.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ElementConfig.kt deleted file mode 100644 index 68d654c92..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ElementConfig.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config - -sealed interface ElementConfig \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt deleted file mode 100644 index 06b7acc6c..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt +++ /dev/null @@ -1,41 +0,0 @@ -package io.github.openflocon.flocon.plugins.database - -import io.github.openflocon.flocon.* -import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel -import io.github.openflocon.flocon.plugins.database.model.FloconFileDatabaseModel - -class FloconDatabaseConfig - -/** - * Flocon Database Plugin. - * Used to inspect Room or other SQL databases. - */ -expect object FloconDatabase : FloconPluginFactory - -fun floconRegisterDatabase(database: FloconDatabaseModel) { - FloconApp.instance?.client?.databasePlugin?.register( - database - ) -} - -fun floconRegisterDatabase(displayName: String, absolutePath: String) { - floconRegisterDatabase( - FloconFileDatabaseModel( - displayName = displayName, - absolutePath = absolutePath, - ) - ) -} - -fun floconLogDatabaseQuery(dbName: String, sqlQuery: String, bindArgs: List) { - FloconApp.instance?.client?.databasePlugin?.logQuery( - dbName = dbName, - sqlQuery = sqlQuery, - bindArgs = bindArgs, - ) -} - -interface FloconDatabasePlugin : FloconPlugin { - fun register(floconDatabaseModel: FloconDatabaseModel) - fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt deleted file mode 100644 index 29533742c..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt +++ /dev/null @@ -1,24 +0,0 @@ -package io.github.openflocon.flocon.plugins.deeplinks.model - -data class DeeplinkModel( - val link: String, - val label: String? = null, - val description: String? = null, - val parameters: List, -) { - - sealed interface Parameter { - val paramName: String - - data class AutoComplete( - override val paramName: String, - val autoComplete: List - ) : Parameter - - data class Variable( - override val paramName: String, - val variableName: String - ) : Parameter - - } -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt deleted file mode 100644 index c099eaa66..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.openflocon.flocon.plugins.device - -import io.github.openflocon.flocon.* - -class FloconDeviceConfig - -/** - * Flocon Device Plugin. - */ -expect object FloconDevice : FloconPluginFactory - -interface FloconDevicePlugin : FloconPlugin { - fun registerWithSerial(serial: String) -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt deleted file mode 100644 index 3645820c5..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.openflocon.flocon.plugins.files - -import io.github.openflocon.flocon.* - -class FloconFilesConfig { - val roots = mutableListOf() -} - -/** - * Flocon Files Plugin. - * Used to inspect and download files from the device. - */ -expect object FloconFiles : FloconPluginFactory - -interface FloconFilesPlugin : FloconPlugin \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPlugin.kt deleted file mode 100644 index aaaf34432..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPlugin.kt +++ /dev/null @@ -1,38 +0,0 @@ -package io.github.openflocon.flocon.plugins.network - -import io.github.openflocon.flocon.* -import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.plugins.network.model.FloconWebSocketEvent -import io.github.openflocon.flocon.plugins.network.model.FloconWebSocketMockListener -import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse - -class FloconNetworkConfig { - var badQualityConfig: BadQualityConfig? = null - val mocks = mutableListOf() -} - -/** - * Flocon Network Plugin. - * Used to inspect HTTP/S and WebSocket calls. - */ -expect object FloconNetwork : FloconPluginFactory - -fun floconLogWebSocketEvent(event: FloconWebSocketEvent) { - FloconApp.instance?.client?.networkPlugin?.logWebSocket(event) -} - -interface FloconNetworkPlugin : FloconPlugin { - val mocks: Collection - val badQualityConfig: BadQualityConfig? - - fun logRequest(request: FloconNetworkCallRequest) - fun logResponse(response: FloconNetworkCallResponse) - - fun logWebSocket( - event: FloconWebSocketEvent, - ) - - fun registerWebSocketMockListener(id: String, listener: FloconWebSocketMockListener) -} diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt deleted file mode 100644 index 416f2cad5..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.openflocon.flocon.plugins.sharedprefs - -import io.github.openflocon.flocon.* -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconSharedPreferenceModel - -class FloconPreferencesConfig - -/** - * Flocon Preferences Plugin. - * Used to inspect SharedPreferences or other key-value stores. - */ -expect object FloconPreferences : FloconPluginFactory - -fun floconRegisterSharedPreference(sharedPreference: FloconSharedPreferenceModel) { - FloconApp.instance?.client?.preferencesPlugin?.register(sharedPreference) -} - -interface FloconPreferencesPlugin : FloconPlugin { - fun register(sharedPreference: FloconSharedPreferenceModel) -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt deleted file mode 100644 index ad5d0ec9e..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.openflocon.flocon.plugins.tables - -import io.github.openflocon.flocon.* -import io.github.openflocon.flocon.plugins.tables.builder.TableBuilder -import io.github.openflocon.flocon.plugins.tables.model.TableItem - -class FloconTableConfig - -/** - * Flocon Table Plugin. - * Used to display custom data tables. - */ -expect object FloconTable : FloconPluginFactory - -fun floconTable(tableName: String) : TableBuilder { - return TableBuilder( - tableId = tableName, - tablePlugin = FloconApp.instance?.client?.tablePlugin, - ) -} - -fun FloconApp.table(tableName: String): TableBuilder { - return TableBuilder( - tableId = tableName, - tablePlugin = this.client?.tablePlugin, - ) -} - -interface FloconTablePlugin : FloconPlugin { - fun registerItems(tableItems: List) -} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/builder/TableBuilder.kt b/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/builder/TableBuilder.kt deleted file mode 100644 index 8e7f22a26..000000000 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/builder/TableBuilder.kt +++ /dev/null @@ -1,25 +0,0 @@ -@file:OptIn(ExperimentalUuidApi::class) - -package io.github.openflocon.flocon.plugins.tables.builder - -import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin -import io.github.openflocon.flocon.plugins.tables.model.TableColumnConfig -import io.github.openflocon.flocon.plugins.tables.model.TableItem -import io.github.openflocon.flocon.utils.currentTimeMillis -import kotlin.uuid.ExperimentalUuidApi -import kotlin.uuid.Uuid - -class TableBuilder( - val tableName: String, - private val tablePlugin: FloconTablePlugin?, -) { - fun log(vararg columns: TableColumnConfig) { - val dashboardConfig = TableItem( - id = Uuid.random().toString(), - name = tableName, - columns = columns.toList(), - createdAt = currentTimeMillis(), - ) - tablePlugin?.registerTable(dashboardConfig) - } -} \ No newline at end of file diff --git a/FloconAndroid/flocon-no-op/build.gradle.kts b/FloconAndroid/flocon-no-op/build.gradle.kts index 963d4a6d6..895bd36bf 100644 --- a/FloconAndroid/flocon-no-op/build.gradle.kts +++ b/FloconAndroid/flocon-no-op/build.gradle.kts @@ -23,7 +23,7 @@ kotlin { val commonMain by getting { dependencies { implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) - api(project(":flocon-base")) + api(project(":flocon")) } } diff --git a/FloconAndroid/flocon/build.gradle.kts b/FloconAndroid/flocon/build.gradle.kts index c887d14c2..457438cef 100644 --- a/FloconAndroid/flocon/build.gradle.kts +++ b/FloconAndroid/flocon/build.gradle.kts @@ -21,13 +21,15 @@ kotlin { iosArm64() iosSimulatorArm64() + compilerOptions { + freeCompilerArgs.add("-XXLanguage:+ExpectRefinement") + } + sourceSets { val commonMain by getting { dependencies { implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) implementation(libs.kotlinx.serialization.json) - api(project(":flocon-base")) - api(project(":deeplinks")) } } diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.kt index 85a2d610d..9f47da0fc 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.kt @@ -3,11 +3,13 @@ package io.github.openflocon.flocon import android.content.Context object Flocon : FloconCore() { + fun initialize(context: Context, block: FloconConfiguration.() -> Unit = {}) { val configuration = FloconConfiguration().apply(block) super.initializeFlocon( - context = FloconContext(appContext = context), + context = FloconContext(context = context), configuration = configuration ) } + } diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconBroadcastReceiver.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconBroadcastReceiver.kt index 8949202b1..4b70f8283 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconBroadcastReceiver.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconBroadcastReceiver.kt @@ -3,7 +3,6 @@ package io.github.openflocon.flocon import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import android.util.Log internal class FloconBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { @@ -13,7 +12,7 @@ internal class FloconBroadcastReceiver : BroadcastReceiver() { if (serial != null) { FloconLogger.log("serial : $serial") - Flocon.client?.devicePlugin?.registerWithSerial(serial) + //Flocon.client?.devicePlugin?.registerWithSerial(serial) } } } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconContext.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconContext.android.kt new file mode 100644 index 000000000..4d7ce3ef7 --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconContext.android.kt @@ -0,0 +1,5 @@ +package io.github.openflocon.flocon + +import android.content.Context + +actual class FloconContext(val context: Context) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconCore.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconCore.android.kt index fe2393a4b..59b7f7117 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconCore.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconCore.android.kt @@ -1,19 +1,18 @@ package io.github.openflocon.flocon -import android.content.Context import android.util.Log import android.widget.Toast -actual class FloconContext(val appContext: Context) - internal actual fun displayClearTextError(context: FloconContext) { Toast.makeText( - context.appContext, - "Cannot start Flocon : ClearText Issue, see Logcat", - Toast.LENGTH_LONG - ).show() + /* context = */ context.context, + /* text = */ "Cannot start Flocon : ClearText Issue, see Logcat", + /* duration = */ Toast.LENGTH_LONG + ) + .show() Log.e( - "Flocon", + /* tag = */ "Flocon", + /* msg = */ "Flocon uses ClearText communication to the server, it seems you already have a network-security-config setup on your project, please ensure you allowed cleartext communication on your debug app https://github.com/openflocon/Flocon?tab=readme-ov-file#-why-flocon-cant-see-your-device-calls-and-how-to-fix-it-" ) } \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/androidMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt similarity index 97% rename from FloconAndroid/flocon-base/src/androidMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt rename to FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt index aa34a812e..68fc4f94a 100644 --- a/FloconAndroid/flocon-base/src/androidMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt @@ -5,17 +5,16 @@ import android.util.Log actual object FloconLogger { actual var enabled = false private const val TAG = "FloconLogger" - + actual fun logError(text: String, throwable: Throwable?) { if(enabled) { Log.e(TAG, text, throwable) } } - + actual fun log(text: String) { if(enabled) { Log.d(TAG, text) } } -} - +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/ServerHost.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/ServerHost.android.kt index 45b760333..87275d6d9 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/ServerHost.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/ServerHost.android.kt @@ -3,6 +3,6 @@ package io.github.openflocon.flocon import io.github.openflocon.flocon.utils.NetUtils internal actual fun getServerHost(floconContext: FloconContext): String { - val appContext = floconContext.appContext + val appContext = floconContext.context return NetUtils.getServerHost(context = appContext) } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/core/AppInfos.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/core/AppInfos.android.kt index 45bfbe9bf..7405f5d02 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/core/AppInfos.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/core/AppInfos.android.kt @@ -18,9 +18,10 @@ private fun deviceName(): String { } internal actual fun getAppInfos(floconContext: FloconContext): AppInfos { - val appContext = floconContext.appContext + val appContext = floconContext.context + return AppInfos( - deviceId = deviceId(floconContext.appContext), + deviceId = deviceId(appContext), deviceName = deviceName(), appName = AppUtils.getAppName(appContext), appPackageName = AppUtils.getAppPackageName(appContext), diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.android.kt index 1c6b0d62e..e736d8c8b 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.android.kt @@ -1,59 +1,13 @@ package io.github.openflocon.flocon.plugins.crashreporter -import android.content.Context import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel -import io.github.openflocon.flocon.plugins.crashreporter.model.crashReportFromJson -import io.github.openflocon.flocon.plugins.crashreporter.model.toJson -import java.io.File - -internal class FloconCrashReporterDataSourceAndroid( - private val context: Context -) : FloconCrashReporterDataSource { - - private val crashesDir = File(context.filesDir, "flocon_crashes") - - init { - crashesDir.mkdirs() - } - - override fun saveCrash(crash: CrashReportDataModel) { - try { - val file = File(crashesDir, "${crash.crashId}.json") - val jsonString = crash.toJson() - file.writeText(jsonString) - } catch (t: Throwable) { - FloconLogger.logError("Error saving crash", t) - } - } - - override fun loadPendingCrashes(): List { - return try { - crashesDir.listFiles() - ?.mapNotNull { file -> - try { - crashReportFromJson(file.readText()) - } catch (t: Throwable) { - t.printStackTrace() - null - } - } ?: emptyList() - } catch (t: Throwable) { - FloconLogger.logError("Error loading pending crashes", t) - emptyList() - } - } - - override fun deleteCrash(crashId: String) { - try { - File(crashesDir, "$crashId.json").delete() - } catch (t: Throwable) { - FloconLogger.logError("Failed to delete crash report: $crashId.json", t) - } - } -} internal actual fun buildFloconCrashReporterDataSource(context: FloconContext): FloconCrashReporterDataSource { - return FloconCrashReporterDataSourceAndroid(context.appContext) + TODO("Not yet implemented") } + +internal actual fun setupUncaughtExceptionHandler( + context: FloconContext, + onCrash: (Throwable) -> Unit +) { +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/UncaughtExceptionHandler.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/UncaughtExceptionHandler.android.kt deleted file mode 100644 index 45c238648..000000000 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/UncaughtExceptionHandler.android.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.openflocon.flocon.plugins.crashreporter - -import android.os.Build -import io.github.openflocon.flocon.FloconContext - -internal actual fun setupUncaughtExceptionHandler( - context: FloconContext, - onCrash: (Throwable) -> Unit -) { - val defaultHandler = Thread.getDefaultUncaughtExceptionHandler() - - Thread.setDefaultUncaughtExceptionHandler { thread, throwable -> - try { - // Save crash - onCrash(throwable) - } catch (t: Throwable) { - t.printStackTrace() - } finally { - // Call original handler to let the app crash normally - defaultHandler?.uncaughtException(thread, throwable) - } - } -} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.android.kt index 08023c639..8a4ac38fb 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.android.kt @@ -1,276 +1,7 @@ package io.github.openflocon.flocon.plugins.database -import android.content.Context -import android.database.Cursor -import androidx.sqlite.db.SupportSQLiteDatabase -import androidx.sqlite.db.SupportSQLiteOpenHelper -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel -import io.github.openflocon.flocon.plugins.database.model.FloconFileDatabaseModel -import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseExecuteSqlResponse -import io.github.openflocon.flocon.plugins.database.model.fromdevice.DeviceDataBaseDataModel -import java.io.File -import java.util.Locale internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { - return FloconDatabaseDataSourceAndroid(context.appContext) -} - -internal class FloconDatabaseDataSourceAndroid(private val context: Context) : - FloconDatabaseDataSource { - - private val MAX_DEPTH = 7 - - override fun executeSQL( - registeredDatabases: List, - databaseName: String, - query: String - ): DatabaseExecuteSqlResponse { - val databaseModel = registeredDatabases.find { it.displayName == databaseName } - return when(databaseModel) { - is FloconSqliteDatabaseModel -> { - executeSQL( - database = databaseModel.database, - query = query, - ) - } - else -> openDbAndExecuteQuery( - databaseName = databaseName, - query = query, - ) - } - } - - private fun openDbAndExecuteQuery( - databaseName: String, - query: String - ): DatabaseExecuteSqlResponse { - var helper: SupportSQLiteOpenHelper? = null - return try { - val path = context.getDatabasePath(databaseName) - val version = getDatabaseVersion(path = path.absolutePath) - helper = FrameworkSQLiteOpenHelperFactory().create( - SupportSQLiteOpenHelper.Configuration.builder(context) - .name(path.absolutePath) - .callback(object : SupportSQLiteOpenHelper.Callback(version) { - override fun onCreate(db: SupportSQLiteDatabase) { - // no op - } - - override fun onUpgrade( - db: SupportSQLiteDatabase, - oldVersion: Int, - newVersion: Int - ) { - // no op - } - }) - .build() - ) - val database = helper.writableDatabase - - executeSQL( - database = database, - query = query, - ) - } catch (t: Throwable) { - DatabaseExecuteSqlResponse.Error( - message = t.message ?: "error on executeSQL", - originalSql = query, - ) - } finally { - helper?.close() - } - } - - private fun executeSQL( - database: SupportSQLiteDatabase, - query: String - ): DatabaseExecuteSqlResponse { - return try { - val firstWordUpperCase = getFirstWord(query).uppercase(Locale.getDefault()) - when (firstWordUpperCase) { - "UPDATE", "DELETE" -> executeUpdateDelete(database, query) - "INSERT" -> executeInsert(database, query) - "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(database, query) - else -> executeRawQuery(database, query) - } - } catch (t: Throwable) { - DatabaseExecuteSqlResponse.Error( - message = t.message ?: "error on executeSQL", - originalSql = query, - ) - } - } - - override fun getAllDataBases( - registeredDatabases: List - ): List { - val databasesDir = context.getDatabasePath("dummy_db").parentFile ?: return emptyList() - - val foundDatabases = mutableListOf() - // Start the recursive search from the base databases directory - scanDirectoryForDatabases( - directory = databasesDir, - depth = 0, - foundDatabases = foundDatabases - ) - - registeredDatabases.forEach { - when(it) { - is FloconFileDatabaseModel -> { - // check if file exists here - if (File(it.absolutePath).exists()) { - foundDatabases.add( - DeviceDataBaseDataModel( - id = it.absolutePath, - name = it.displayName, - ) - ) - } - } - else -> { - foundDatabases.add( - DeviceDataBaseDataModel( - id = it.displayName, - name = it.displayName, - ) - ) - } - } - } - - return foundDatabases - } - - /** - * Recursively scans a directory for SQLite database files. - * - * @param directory The current directory to scan. - * @param foundDatabases The mutable list to add found databases to. - */ - private fun scanDirectoryForDatabases( - directory: File, - depth: Int, - foundDatabases: MutableList - ) { - if (depth >= MAX_DEPTH) { - return; - } - directory.listFiles()?.forEach { file -> - if (file.isDirectory) { - // If it's a directory, recursively call this function - scanDirectoryForDatabases( - directory = file, - depth = depth + 1, - foundDatabases = foundDatabases, - ) - } else { - // If it's a file, check if it's a database file - if (file.isFile && - !file.name.endsWith("-wal") && // Write-Ahead Log - !file.name.endsWith("-shm") && // Shared-Memory - !file.name.endsWith("-journal") // Older journaling mode - ) { - foundDatabases.add( - DeviceDataBaseDataModel( - id = file.absolutePath, // Use absolute path for unique ID - name = file.name, - ) - ) - } - } - } - } -} - - -private fun executeSelect( - database: SupportSQLiteDatabase, - query: String, -): DatabaseExecuteSqlResponse { - val cursor: Cursor = database.query(query) - try { - val columnNames = cursor.columnNames.toList() - val rows = cursorToList(cursor) - return DatabaseExecuteSqlResponse.Select( - columns = columnNames, - values = rows, - ) - } finally { - cursor.close() - } -} - -private fun executeUpdateDelete( - database: SupportSQLiteDatabase, - query: String, -): DatabaseExecuteSqlResponse { - val statement = database.compileStatement(query) - val count: Int = statement.executeUpdateDelete() - return DatabaseExecuteSqlResponse.UpdateDelete(count) -} - -private fun executeInsert( - database: SupportSQLiteDatabase, - query: String, -): DatabaseExecuteSqlResponse { - val statement = database.compileStatement(query) - val insertedId: Long = statement.executeInsert() - return DatabaseExecuteSqlResponse.Insert(insertedId) -} - -private fun executeRawQuery( - database: SupportSQLiteDatabase, - query: String, -): DatabaseExecuteSqlResponse { - database.execSQL(query) - return DatabaseExecuteSqlResponse.RawSuccess -} - -private fun getFirstWord(s: String): String { - var s = s - s = s.trim { it <= ' ' } - val firstSpace = s.indexOf(' ') - return if (firstSpace >= 0) s.substring(0, firstSpace) else s -} - -private fun cursorToList(cursor: Cursor): List> { - val rows = mutableListOf>() - val numColumns = cursor.columnCount - while (cursor.moveToNext()) { - val values = mutableListOf() - for (column in 0.. null - Cursor.FIELD_TYPE_INTEGER -> cursor.getLong(column).toString() - Cursor.FIELD_TYPE_FLOAT -> cursor.getDouble(column).toString() - Cursor.FIELD_TYPE_BLOB -> cursor.getBlob(column).toString() - Cursor.FIELD_TYPE_STRING -> cursor.getString(column).toString() - else -> cursor.getString(column) - } -} - -// must use the old way to get the version... -private fun getDatabaseVersion( - path: String, -): Int { - return android.database.sqlite.SQLiteDatabase.openDatabase( - path, - null, - android.database.sqlite.SQLiteDatabase.OPEN_READONLY - ).use { db -> - db.rawQuery("PRAGMA user_version", null).use { cursor -> - if (cursor.moveToFirst()) cursor.getInt(0) else 0 - } - } -} + TODO("Not yet implemented") +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.android.kt index 14ce93b10..d7c3cc2ce 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.android.kt @@ -1,8 +1,6 @@ package io.github.openflocon.flocon.plugins.device -import com.jakewharton.processphoenix.ProcessPhoenix import io.github.openflocon.flocon.FloconContext internal actual fun restartApp(context: FloconContext) { - ProcessPhoenix.triggerRebirth(context.appContext) } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.android.kt index 501e3c1dc..09e6ec220 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.android.kt @@ -1,69 +1,7 @@ package io.github.openflocon.flocon.plugins.device -import android.content.Context -import android.graphics.Bitmap -import android.graphics.Canvas -import android.graphics.drawable.Drawable -import android.util.Base64 import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import java.io.ByteArrayOutputStream actual fun getAppIconBase64(context: FloconContext): String? { - return getAppIconBase64(context.appContext) -} - - -internal fun getAppIconBase64(context: Context): String? { - return try { - val bitmap = getAppIcon(context) - val resizedBitmap = resizeAppIcon(bitmap, maxSize = 300) - encodeToBase64(resizedBitmap) - } catch (t: Throwable) { - FloconLogger.logError( - text = "Error while getting app icon", - throwable = t, - ) - null - } -} - -private fun getAppIcon(context: Context): Bitmap { - // 1. Récupération de l'icône en bitmap - val packageManager = context.packageManager - val packageName = context.packageName - val iconDrawable: Drawable = packageManager.getApplicationIcon(packageName) - - val bitmap = Bitmap.createBitmap( - iconDrawable.intrinsicWidth, - iconDrawable.intrinsicHeight, - Bitmap.Config.ARGB_8888 - ) - val canvas = Canvas(bitmap) - iconDrawable.setBounds(0, 0, canvas.width, canvas.height) - iconDrawable.draw(canvas) - - return bitmap -} - -private fun encodeToBase64(resizedBitmap: Bitmap): String { - // 3. Conversion en Base64 - val outputStream = ByteArrayOutputStream() - resizedBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream) - val byteArray = outputStream.toByteArray() - - return Base64.encodeToString(byteArray, Base64.NO_WRAP) // NO_WRAP pour éviter les \n -} - -private fun resizeAppIcon(bitmap: Bitmap, maxSize: Int): Bitmap { - val width = bitmap.width - val height = bitmap.height - val scale = minOf(maxSize.toFloat() / width, maxSize.toFloat() / height, 1f) - - return Bitmap.createScaledBitmap( - bitmap, - (width * scale).toInt(), - (height * scale).toInt(), - true - ) -} + TODO("Not yet implemented") +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.android.kt index 840f97db4..f6e708b5c 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.android.kt @@ -1,101 +1,7 @@ package io.github.openflocon.flocon.plugins.files import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconFile -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.plugins.files.model.fromdevice.FileDataModel -import java.io.File -internal class FileDataSourceAndroid( - private val context: FloconContext, -) : FileDataSource { - override fun getFile( - path: String, - isConstantPath: Boolean - ): FloconFile? { - val file = if (isConstantPath) { - when (path) { - "caches" -> context.appContext.cacheDir - "files" -> context.appContext.filesDir - else -> File(path) - } - } else { - File(path) - } - return file.takeIf { it.exists() }?.let { FloconFile(it) } - } - - override fun getFolderContent( - path: String, - isConstantPath: Boolean, - withFoldersSize: Boolean, - ): List { - val directory = getFile(path = path, isConstantPath = isConstantPath) - - val directoryFile = directory?.file - if (directoryFile == null || !directoryFile.exists() || !directoryFile.isDirectory) { - FloconLogger.logError("file '$path' does not exists.", throwable = null) - return emptyList() - } - - val childrenFiles = directoryFile.listFiles() ?: return emptyList() - - return childrenFiles.map { file -> - FileDataModel( - name = file.name, - isDirectory = file.isDirectory, - path = file.absolutePath, - size = if (file.isFile) file.length() else getFolderSize(file, withFoldersSize), - lastModified = file.lastModified() - ) - } - } - - private fun getFolderSize(file: File, withFoldersSize: Boolean): Long { - return if (withFoldersSize) { - file.walk() - .filter { it.isFile } - .map { it.length() } - .sum() - } else 0L - } - - - override fun deleteFile(path: String) { - deleteInternal(path) - } - - override fun deleteFiles(path: List) { - path.forEach { - deleteInternal(it) - } - } - - private fun deleteInternal(path: String) { - deleteInternal(File(path)) - } - - private fun deleteInternal(file: File) { - try { - if (!file.exists()) return - - file.deleteRecursively() - } catch (t: Throwable) { - t.printStackTrace() - } - } - - override fun deleteFolderContent(folder: FloconFile) { - deleteFolderContent(folder.file) - } - - private fun deleteFolderContent(folder: File) { - if (folder.isDirectory) { - folder.listFiles()?.forEach { file -> - deleteInternal(file) - } - } - } -} - -internal actual fun fileDataSource(context: FloconContext) : FileDataSource = FileDataSourceAndroid(context) \ No newline at end of file +internal actual fun fileDataSource(context: FloconContext): FileDataSource { + TODO("Not yet implemented") +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.android.kt index 254934ef4..9c6088f1e 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.android.kt @@ -1,84 +1,7 @@ package io.github.openflocon.flocon.plugins.network -import android.content.Context import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.plugins.network.mapper.parseBadQualityConfig -import io.github.openflocon.flocon.plugins.network.mapper.parseMockResponses -import io.github.openflocon.flocon.plugins.network.mapper.toJsonString -import io.github.openflocon.flocon.plugins.network.mapper.writeMockResponsesToJson -import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig -import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse -import java.io.File -import java.io.FileInputStream -import java.io.FileOutputStream internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { - return FloconNetworkDataSourceAndroid( - context = context.appContext, - ) -} - -internal class FloconNetworkDataSourceAndroid(private val context: Context) : FloconNetworkDataSource { - override fun saveMocksToFile(mocks: List) { - try { - val file = File(context.filesDir, FLOCON_NETWORK_MOCKS_JSON) - val jsonString = writeMockResponsesToJson(mocks = mocks) - FileOutputStream(file).use { - it.write(jsonString.toByteArray()) - } - } catch (t: Throwable) { - FloconLogger.logError("issue in saveMocksToFile", t) - } - } - - override fun loadMocksFromFile(): List { - return try { - val file = File(context.filesDir, FLOCON_NETWORK_MOCKS_JSON) - if (!file.exists()) { - return emptyList() - } - - val jsonString = FileInputStream(file).use { - it.readBytes().toString(Charsets.UTF_8) - } - parseMockResponses(jsonString = jsonString) - } catch (t: Throwable) { - FloconLogger.logError("issue in loadMocksFromFile", t) - emptyList() - } - } - - override fun loadBadNetworkConfig(): BadQualityConfig? { - return try { - val file = File(context.filesDir, FLOCON_NETWORK_BAD_CONFIG_JSON) - if (!file.exists()) { - return null - } - - val jsonString = FileInputStream(file).use { - it.readBytes().toString(Charsets.UTF_8) - } - parseBadQualityConfig(jsonString = jsonString) - } catch (t: Throwable) { - FloconLogger.logError("issue in loadBadNetworkConfig", t) - null - } - } - - override fun saveBadNetworkConfig(config: BadQualityConfig?) { - try { - val file = File(context.filesDir, FLOCON_NETWORK_BAD_CONFIG_JSON) - if (config == null) { - file.delete() - } else { - val jsonString = config.toJsonString() - FileOutputStream(file).use { - it.write(jsonString.toByteArray()) - } - } - } catch (t: Throwable) { - FloconLogger.logError("issue in saveBadNetworkConfig", t) - } - } + TODO("Not yet implemented") } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.android.kt index 08b75dbec..cc2ee1768 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.android.kt @@ -1,21 +1,7 @@ package io.github.openflocon.flocon.plugins.sharedprefs -import android.content.Context import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference -// Got some code from Flipper client -// https://github.com/facebook/flipper/blob/main/android/src/main/java/com/facebook/flipper/plugins/sharedpreferences/SharedPreferencesFlipperPlugin.java - -internal class FloconPreferencesDataSourceAndroid( - private val context: Context, -) : FloconPreferencesDataSource { - - override fun detectLocalPreferences(): List { - return SharedPreferencesFinder.buildDescriptorForAllPrefsFiles(context) - } -} - -internal actual fun buildFloconPreferencesDataSource(context: FloconContext): FloconPreferencesDataSource { - return FloconPreferencesDataSourceAndroid(context = context.appContext) +internal actual fun buildFloconSharedPreferenceDataSource(context: FloconContext): FloconSharedPreferenceDataSource { + TODO("Not yet implemented") } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt new file mode 100644 index 000000000..f7e9a720a --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt @@ -0,0 +1,60 @@ +package io.github.openflocon.flocon.pluginsold.crashreporter + +import android.content.Context +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporterDataSource +import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel +import io.github.openflocon.flocon.plugins.crashreporter.model.crashReportFromJson +import io.github.openflocon.flocon.plugins.crashreporter.model.toJson +import java.io.File + +internal class FloconCrashReporterDataSourceAndroid( + private val context: Context +) : FloconCrashReporterDataSource { + + private val crashesDir = File(context.filesDir, "flocon_crashes") + + init { + crashesDir.mkdirs() + } + + override fun saveCrash(crash: CrashReportDataModel) { + try { + val file = File(crashesDir, "${crash.crashId}.json") + val jsonString = crash.toJson() + file.writeText(jsonString) + } catch (t: Throwable) { + FloconLogger.logError("Error saving crash", t) + } + } + + override fun loadPendingCrashes(): List { + return try { + crashesDir.listFiles() + ?.mapNotNull { file -> + try { + crashReportFromJson(file.readText()) + } catch (t: Throwable) { + t.printStackTrace() + null + } + } ?: emptyList() + } catch (t: Throwable) { + FloconLogger.logError("Error loading pending crashes", t) + emptyList() + } + } + + override fun deleteCrash(crashId: String) { + try { + File(crashesDir, "$crashId.json").delete() + } catch (t: Throwable) { + FloconLogger.logError("Failed to delete crash report: $crashId.json", t) + } + } +} + +//internal actual fun buildFloconCrashReporterDataSource(context: FloconContext): FloconCrashReporterDataSource { +// return FloconCrashReporterDataSourceAndroid(context.context) +//} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/UncaughtExceptionHandler.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/UncaughtExceptionHandler.android.kt new file mode 100644 index 000000000..1608a2c24 --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/UncaughtExceptionHandler.android.kt @@ -0,0 +1,23 @@ +package io.github.openflocon.flocon.pluginsold.crashreporter + +import android.os.Build +import io.github.openflocon.flocon.FloconContext + +//internal actual fun setupUncaughtExceptionHandler( +// context: FloconContext, +// onCrash: (Throwable) -> Unit +//) { +// val defaultHandler = Thread.getDefaultUncaughtExceptionHandler() +// +// Thread.setDefaultUncaughtExceptionHandler { thread, throwable -> +// try { +// // Save crash +// onCrash(throwable) +// } catch (t: Throwable) { +// t.printStackTrace() +// } finally { +// // Call original handler to let the app crash normally +// defaultHandler?.uncaughtException(thread, throwable) +// } +// } +//} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt new file mode 100644 index 000000000..ec7c7ba2f --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt @@ -0,0 +1,277 @@ +package io.github.openflocon.flocon.pluginsold.database + +import android.content.Context +import android.database.Cursor +import android.database.sqlite.SQLiteDatabase +import androidx.sqlite.db.SupportSQLiteDatabase +import androidx.sqlite.db.SupportSQLiteOpenHelper +import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.plugins.database.FloconDatabaseDataSource +import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseExecuteSqlResponse +import io.github.openflocon.flocon.plugins.database.model.fromdevice.DeviceDataBaseDataModel +import io.github.openflocon.flocon.pluginsold.database.model.FloconDatabaseModel +import java.io.File +import java.util.Locale + +//internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { +// return FloconDatabaseDataSourceAndroid(context.context) +//} + +internal class FloconDatabaseDataSourceAndroid(private val context: Context) : + FloconDatabaseDataSource { + + private val MAX_DEPTH = 7 + + override fun executeSQL( + registeredDatabases: List, + databaseName: String, + query: String + ): DatabaseExecuteSqlResponse { + val databaseModel = registeredDatabases.find { it.displayName == databaseName } + return when(databaseModel) { + is FloconSqliteDatabaseModel -> { + executeSQL( + database = databaseModel.database, + query = query, + ) + } + else -> openDbAndExecuteQuery( + databaseName = databaseName, + query = query, + ) + } + } + + private fun openDbAndExecuteQuery( + databaseName: String, + query: String + ): DatabaseExecuteSqlResponse { + var helper: SupportSQLiteOpenHelper? = null + return try { + val path = context.getDatabasePath(databaseName) + val version = getDatabaseVersion(path = path.absolutePath) + helper = FrameworkSQLiteOpenHelperFactory().create( + SupportSQLiteOpenHelper.Configuration.builder(context) + .name(path.absolutePath) + .callback(object : SupportSQLiteOpenHelper.Callback(version) { + override fun onCreate(db: SupportSQLiteDatabase) { + // no op + } + + override fun onUpgrade( + db: SupportSQLiteDatabase, + oldVersion: Int, + newVersion: Int + ) { + // no op + } + }) + .build() + ) + val database = helper.writableDatabase + + executeSQL( + database = database, + query = query, + ) + } catch (t: Throwable) { + DatabaseExecuteSqlResponse.Error( + message = t.message ?: "error on executeSQL", + originalSql = query, + ) + } finally { + helper?.close() + } + } + + private fun executeSQL( + database: SupportSQLiteDatabase, + query: String + ): DatabaseExecuteSqlResponse { + return try { + val firstWordUpperCase = getFirstWord(query).uppercase(Locale.getDefault()) + when (firstWordUpperCase) { + "UPDATE", "DELETE" -> executeUpdateDelete(database, query) + "INSERT" -> executeInsert(database, query) + "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(database, query) + else -> executeRawQuery(database, query) + } + } catch (t: Throwable) { + DatabaseExecuteSqlResponse.Error( + message = t.message ?: "error on executeSQL", + originalSql = query, + ) + } + } + + override fun getAllDataBases( + registeredDatabases: List + ): List { + val databasesDir = context.getDatabasePath("dummy_db").parentFile ?: return emptyList() + + val foundDatabases = mutableListOf() + // Start the recursive search from the base databases directory + scanDirectoryForDatabases( + directory = databasesDir, + depth = 0, + foundDatabases = foundDatabases + ) + +// registeredDatabases.forEach { +// when(it) { +// is FloconFileDatabaseModel -> { +// // check if file exists here +// if (File(it.absolutePath).exists()) { +// foundDatabases.add( +// DeviceDataBaseDataModel( +// id = it.absolutePath, +// name = it.displayName, +// ) +// ) +// } +// } +// else -> { +// foundDatabases.add( +// DeviceDataBaseDataModel( +// id = it.displayName, +// name = it.displayName, +// ) +// ) +// } +// } +// } + + return foundDatabases + } + + /** + * Recursively scans a directory for SQLite database files. + * + * @param directory The current directory to scan. + * @param foundDatabases The mutable list to add found databases to. + */ + private fun scanDirectoryForDatabases( + directory: File, + depth: Int, + foundDatabases: MutableList + ) { + if (depth >= MAX_DEPTH) { + return; + } + directory.listFiles()?.forEach { file -> + if (file.isDirectory) { + // If it's a directory, recursively call this function + scanDirectoryForDatabases( + directory = file, + depth = depth + 1, + foundDatabases = foundDatabases, + ) + } else { + // If it's a file, check if it's a database file + if (file.isFile && + !file.name.endsWith("-wal") && // Write-Ahead Log + !file.name.endsWith("-shm") && // Shared-Memory + !file.name.endsWith("-journal") // Older journaling mode + ) { + foundDatabases.add( + DeviceDataBaseDataModel( + id = file.absolutePath, // Use absolute path for unique ID + name = file.name, + ) + ) + } + } + } + } +} + + +private fun executeSelect( + database: SupportSQLiteDatabase, + query: String, +): DatabaseExecuteSqlResponse { + val cursor: Cursor = database.query(query) + try { + val columnNames = cursor.columnNames.toList() + val rows = cursorToList(cursor) + return DatabaseExecuteSqlResponse.Select( + columns = columnNames, + values = rows, + ) + } finally { + cursor.close() + } +} + +private fun executeUpdateDelete( + database: SupportSQLiteDatabase, + query: String, +): DatabaseExecuteSqlResponse { + val statement = database.compileStatement(query) + val count: Int = statement.executeUpdateDelete() + return DatabaseExecuteSqlResponse.UpdateDelete(count) +} + +private fun executeInsert( + database: SupportSQLiteDatabase, + query: String, +): DatabaseExecuteSqlResponse { + val statement = database.compileStatement(query) + val insertedId: Long = statement.executeInsert() + return DatabaseExecuteSqlResponse.Insert(insertedId) +} + +private fun executeRawQuery( + database: SupportSQLiteDatabase, + query: String, +): DatabaseExecuteSqlResponse { + database.execSQL(query) + return DatabaseExecuteSqlResponse.RawSuccess +} + +private fun getFirstWord(s: String): String { + var s = s + s = s.trim { it <= ' ' } + val firstSpace = s.indexOf(' ') + return if (firstSpace >= 0) s.substring(0, firstSpace) else s +} + +private fun cursorToList(cursor: Cursor): List> { + val rows = mutableListOf>() + val numColumns = cursor.columnCount + while (cursor.moveToNext()) { + val values = mutableListOf() + for (column in 0.. null + Cursor.FIELD_TYPE_INTEGER -> cursor.getLong(column).toString() + Cursor.FIELD_TYPE_FLOAT -> cursor.getDouble(column).toString() + Cursor.FIELD_TYPE_BLOB -> cursor.getBlob(column).toString() + Cursor.FIELD_TYPE_STRING -> cursor.getString(column).toString() + else -> cursor.getString(column) + } +} + +// must use the old way to get the version... +private fun getDatabaseVersion( + path: String, +): Int { + return SQLiteDatabase.openDatabase( + path, + null, + SQLiteDatabase.OPEN_READONLY + ).use { db -> + db.rawQuery("PRAGMA user_version", null).use { cursor -> + if (cursor.moveToFirst()) cursor.getInt(0) else 0 + } + } +} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconSqliteDatabaseModel.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconSqliteDatabaseModel.kt similarity index 64% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconSqliteDatabaseModel.kt rename to FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconSqliteDatabaseModel.kt index 229ab494d..b5b0087b9 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconSqliteDatabaseModel.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconSqliteDatabaseModel.kt @@ -1,8 +1,8 @@ -package io.github.openflocon.flocon.plugins.database +package io.github.openflocon.flocon.pluginsold.database import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteOpenHelper -import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel +import io.github.openflocon.flocon.pluginsold.database.model.FloconDatabaseModel internal class FloconSqliteDatabaseModel( override val displayName: String, @@ -10,12 +10,12 @@ internal class FloconSqliteDatabaseModel( ) : FloconDatabaseModel fun floconRegisterDatabase(displayName: String, database: SupportSQLiteDatabase) { - floconRegisterDatabase( - FloconSqliteDatabaseModel( - displayName = displayName, - database = database, - ) - ) +// floconRegisterDatabase( +// FloconSqliteDatabaseModel( +// displayName = displayName, +// database = database, +// ) +// ) } diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePluginImpl.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePluginImpl.android.kt new file mode 100644 index 000000000..88f1f8466 --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePluginImpl.android.kt @@ -0,0 +1,8 @@ +package io.github.openflocon.flocon.pluginsold.device + +import com.jakewharton.processphoenix.ProcessPhoenix +import io.github.openflocon.flocon.FloconContext + +//internal actual fun restartApp(context: FloconContext) { +// ProcessPhoenix.triggerRebirth(context.context) +//} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/device/GetAppIconUtils.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/device/GetAppIconUtils.android.kt new file mode 100644 index 000000000..7de9ea904 --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/device/GetAppIconUtils.android.kt @@ -0,0 +1,69 @@ +package io.github.openflocon.flocon.pluginsold.device + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.drawable.Drawable +import android.util.Base64 +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import java.io.ByteArrayOutputStream + +//actual fun getAppIconBase64(context: FloconContext): String? { +// return getAppIconBase64(context.context) +//} + + +internal fun getAppIconBase64(context: Context): String? { + return try { + val bitmap = getAppIcon(context) + val resizedBitmap = resizeAppIcon(bitmap, maxSize = 300) + encodeToBase64(resizedBitmap) + } catch (t: Throwable) { + FloconLogger.logError( + text = "Error while getting app icon", + throwable = t, + ) + null + } +} + +private fun getAppIcon(context: Context): Bitmap { + // 1. Récupération de l'icône en bitmap + val packageManager = context.packageManager + val packageName = context.packageName + val iconDrawable: Drawable = packageManager.getApplicationIcon(packageName) + + val bitmap = Bitmap.createBitmap( + iconDrawable.intrinsicWidth, + iconDrawable.intrinsicHeight, + Bitmap.Config.ARGB_8888 + ) + val canvas = Canvas(bitmap) + iconDrawable.setBounds(0, 0, canvas.width, canvas.height) + iconDrawable.draw(canvas) + + return bitmap +} + +private fun encodeToBase64(resizedBitmap: Bitmap): String { + // 3. Conversion en Base64 + val outputStream = ByteArrayOutputStream() + resizedBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream) + val byteArray = outputStream.toByteArray() + + return Base64.encodeToString(byteArray, Base64.NO_WRAP) // NO_WRAP pour éviter les \n +} + +private fun resizeAppIcon(bitmap: Bitmap, maxSize: Int): Bitmap { + val width = bitmap.width + val height = bitmap.height + val scale = minOf(maxSize.toFloat() / width, maxSize.toFloat() / height, 1f) + + return Bitmap.createScaledBitmap( + bitmap, + (width * scale).toInt(), + (height * scale).toInt(), + true + ) +} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt new file mode 100644 index 000000000..5d8ad7a43 --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt @@ -0,0 +1,102 @@ +package io.github.openflocon.flocon.pluginsold.files + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconFile +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.plugins.files.FileDataSource +import io.github.openflocon.flocon.plugins.files.model.fromdevice.FileDataModel +import java.io.File + +internal class FileDataSourceAndroid( + private val context: FloconContext, +) : FileDataSource { + override fun getFile( + path: String, + isConstantPath: Boolean + ): FloconFile? { + val file = if (isConstantPath) { + when (path) { + "caches" -> context.context.cacheDir + "files" -> context.context.filesDir + else -> File(path) + } + } else { + File(path) + } + return file.takeIf { it.exists() }?.let { FloconFile(it) } + } + + override fun getFolderContent( + path: String, + isConstantPath: Boolean, + withFoldersSize: Boolean, + ): List { + val directory = getFile(path = path, isConstantPath = isConstantPath) + + val directoryFile = directory?.file + if (directoryFile == null || !directoryFile.exists() || !directoryFile.isDirectory) { + FloconLogger.logError("file '$path' does not exists.", throwable = null) + return emptyList() + } + + val childrenFiles = directoryFile.listFiles() ?: return emptyList() + + return childrenFiles.map { file -> + FileDataModel( + name = file.name, + isDirectory = file.isDirectory, + path = file.absolutePath, + size = if (file.isFile) file.length() else getFolderSize(file, withFoldersSize), + lastModified = file.lastModified() + ) + } + } + + private fun getFolderSize(file: File, withFoldersSize: Boolean): Long { + return if (withFoldersSize) { + file.walk() + .filter { it.isFile } + .map { it.length() } + .sum() + } else 0L + } + + + override fun deleteFile(path: String) { + deleteInternal(path) + } + + override fun deleteFiles(path: List) { + path.forEach { + deleteInternal(it) + } + } + + private fun deleteInternal(path: String) { + deleteInternal(File(path)) + } + + private fun deleteInternal(file: File) { + try { + if (!file.exists()) return + + file.deleteRecursively() + } catch (t: Throwable) { + t.printStackTrace() + } + } + + override fun deleteFolderContent(folder: FloconFile) { + deleteFolderContent(folder.file) + } + + private fun deleteFolderContent(folder: File) { + if (folder.isDirectory) { + folder.listFiles()?.forEach { file -> + deleteInternal(file) + } + } + } +} + +//internal actual fun fileDataSource(context: FloconContext) : FileDataSource = FileDataSourceAndroid(context) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPluginImpl.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPluginImpl.android.kt new file mode 100644 index 000000000..0b7493ae0 --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPluginImpl.android.kt @@ -0,0 +1,88 @@ +package io.github.openflocon.flocon.pluginsold.network + +import android.content.Context +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.plugins.network.FLOCON_NETWORK_BAD_CONFIG_JSON +import io.github.openflocon.flocon.plugins.network.FLOCON_NETWORK_MOCKS_JSON +import io.github.openflocon.flocon.plugins.network.FloconNetworkDataSource +import io.github.openflocon.flocon.plugins.network.mapper.parseBadQualityConfig +import io.github.openflocon.flocon.plugins.network.mapper.parseMockResponses +import io.github.openflocon.flocon.plugins.network.mapper.toJsonString +import io.github.openflocon.flocon.plugins.network.mapper.writeMockResponsesToJson +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream + +//internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { +// return FloconNetworkDataSourceAndroid( +// context = context.context, +// ) +//} + +internal class FloconNetworkDataSourceAndroid(private val context: Context) : + FloconNetworkDataSource { + override fun saveMocksToFile(mocks: List) { + try { + val file = File(context.filesDir, FLOCON_NETWORK_MOCKS_JSON) + val jsonString = writeMockResponsesToJson(mocks = mocks) + FileOutputStream(file).use { + it.write(jsonString.toByteArray()) + } + } catch (t: Throwable) { + FloconLogger.logError("issue in saveMocksToFile", t) + } + } + + override fun loadMocksFromFile(): List { + return try { + val file = File(context.filesDir, FLOCON_NETWORK_MOCKS_JSON) + if (!file.exists()) { + return emptyList() + } + + val jsonString = FileInputStream(file).use { + it.readBytes().toString(Charsets.UTF_8) + } + parseMockResponses(jsonString = jsonString) + } catch (t: Throwable) { + FloconLogger.logError("issue in loadMocksFromFile", t) + emptyList() + } + } + + override fun loadBadNetworkConfig(): BadQualityConfig? { + return try { + val file = File(context.filesDir, FLOCON_NETWORK_BAD_CONFIG_JSON) + if (!file.exists()) { + return null + } + + val jsonString = FileInputStream(file).use { + it.readBytes().toString(Charsets.UTF_8) + } + parseBadQualityConfig(jsonString = jsonString) + } catch (t: Throwable) { + FloconLogger.logError("issue in loadBadNetworkConfig", t) + null + } + } + + override fun saveBadNetworkConfig(config: BadQualityConfig?) { + try { + val file = File(context.filesDir, FLOCON_NETWORK_BAD_CONFIG_JSON) + if (config == null) { + file.delete() + } else { + val jsonString = config.toJsonString() + FileOutputStream(file).use { + it.write(jsonString.toByteArray()) + } + } + } catch (t: Throwable) { + FloconLogger.logError("issue in saveBadNetworkConfig", t) + } + } +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPreference.kt similarity index 90% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt rename to FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPreference.kt index 1bbe8d4ac..fd54d1dab 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPreference.kt @@ -1,8 +1,8 @@ -package io.github.openflocon.flocon.plugins.sharedprefs +package io.github.openflocon.flocon.pluginsold.sharedprefs import android.content.SharedPreferences -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreferenceValue +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreferenceValue data class FloconSharedPreference( override val name: String, diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.android.kt new file mode 100644 index 000000000..9661da305 --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.android.kt @@ -0,0 +1,25 @@ +package io.github.openflocon.flocon.pluginsold.sharedprefs + +import android.content.Context +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference + +// Got some code from Flipper client +// https://github.com/facebook/flipper/blob/main/android/src/main/java/com/facebook/flipper/plugins/sharedpreferences/SharedPreferencesFlipperPlugin.java + +internal class FloconPreferencesDataSourceAndroid( + private val context: Context, +) : FloconPreferencesDataSource { + + override fun detectLocalPreferences(): List { + return SharedPreferencesFinder.buildDescriptorForAllPrefsFiles(context) + } +} + +interface FloconPreferencesDataSource { + fun detectLocalPreferences(): List +} + +//internal actual fun buildFloconPreferencesDataSource(context: FloconContext): FloconPreferencesDataSource { +// return FloconPreferencesDataSourceAndroid(context = context.context) +//} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/SharedPreferencesFinder.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/SharedPreferencesFinder.kt similarity index 75% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/SharedPreferencesFinder.kt rename to FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/SharedPreferencesFinder.kt index eef8b5068..b25ec6260 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/SharedPreferencesFinder.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/SharedPreferencesFinder.kt @@ -1,10 +1,10 @@ -package io.github.openflocon.flocon.plugins.sharedprefs +package io.github.openflocon.flocon.pluginsold.sharedprefs import android.content.Context import android.content.Context.MODE_PRIVATE import android.os.Build import android.preference.PreferenceManager -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference import java.io.File internal object SharedPreferencesFinder { @@ -23,8 +23,11 @@ internal object SharedPreferencesFinder { for (each in list) { val prefName = each.substring(0, each.indexOf(".xml")) descriptors.add( - FloconSharedPreference(prefName, sharedPreferences = context.getSharedPreferences(prefName, MODE_PRIVATE) - )) + FloconSharedPreference( + prefName, + sharedPreferences = context.getSharedPreferences(prefName, MODE_PRIVATE) + ) + ) } } @@ -32,7 +35,10 @@ internal object SharedPreferencesFinder { descriptors.add( FloconSharedPreference( name = defaultSharedPrefName, - sharedPreferences = context.getSharedPreferences(defaultSharedPrefName, MODE_PRIVATE) + sharedPreferences = context.getSharedPreferences( + defaultSharedPrefName, + MODE_PRIVATE + ) ) ) diff --git a/FloconAndroid/flocon-base/src/androidMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.android.kt similarity index 100% rename from FloconAndroid/flocon-base/src/androidMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.android.kt rename to FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.android.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt new file mode 100644 index 000000000..411529ea7 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt @@ -0,0 +1,16 @@ +package io.github.openflocon.flocon + +import io.github.openflocon.flocon.client.FloconClientImpl +// +//internal class Flocon( +// private val context: FloconContext, +// private val plugins: List +//) { +// +// private val client = FloconClientImpl( +// context = context, +// configuration = FloconConfiguration(), +// plugins = plugins +// ) +// +//} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt new file mode 100644 index 000000000..4319f3dab --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt @@ -0,0 +1,44 @@ +package io.github.openflocon.flocon + +import kotlinx.coroutines.flow.StateFlow + +abstract class FloconApp { + lateinit var context: FloconContext + + companion object { + var instance: FloconApp? = null + private set + } + + interface Client { + + @Throws(Throwable::class) + suspend fun connect(onClosed: () -> Unit) + suspend fun disconnect() + +// val databasePlugin: FloconDatabasePlugin? +// val dashboardPlugin: FloconDashboardPlugin? +// val tablePlugin: FloconTablePlugin? + //val deeplinksPlugin: FloconDeeplinksPlugin? +// val analyticsPlugin: FloconAnalyticsPlugin? +// val networkPlugin: FloconNetworkPlugin? +// val devicePlugin: FloconDevicePlugin? +// val preferencesPlugin: FloconPreferencesPlugin? +// val crashReporterPlugin: FloconCrashReporterPlugin? + + /** + * Retrieve a plugin instance by its [key]. + */ + fun getPlugin(key: String): T? + } + + open val client: Client? = null + + abstract val isInitialized: StateFlow + +// protected fun initializeFlocon(context: FloconContext) { +// this.context = context +// instance = this +// } + +} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt similarity index 77% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt index b22025e11..993c9dce3 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -1,10 +1,7 @@ package io.github.openflocon.flocon -/** - * Configuration builder for Flocon SDK. - * Used in [Flocon.initialize] to configure the SDK and install plugins. - */ class FloconConfiguration internal constructor() { + internal val pluginConfigs = mutableMapOf, Any>() /** @@ -18,10 +15,11 @@ class FloconConfiguration internal constructor() { config.configure() pluginConfigs[factory] = config } + } -fun flocon(block: FloconConfiguration.() -> Unit) { +fun startFlocon(context: FloconContext, block: FloconConfiguration.() -> Unit) { val configuration = FloconConfiguration().apply(block) - - + + } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconContext.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconContext.kt new file mode 100644 index 000000000..153093b48 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconContext.kt @@ -0,0 +1,3 @@ +package io.github.openflocon.flocon + +expect class FloconContext \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt index f9bf17c23..871f74f61 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt @@ -32,26 +32,24 @@ abstract class FloconCore : FloconApp() { context: FloconContext, configuration: FloconConfiguration = FloconConfiguration() ) { - super.initializeFlocon(context) - val newClient = FloconClientImpl(context, configuration) - _client = newClient + //super.initializeFlocon(context) + // val newClient = FloconClientImpl(context, configuration) + //_client = newClient // Setup crash handler early to catch crashes during initialization - newClient.crashReporterPlugin?.setupCrashHandler() + //newClient.crashReporterPlugin?.setupCrashHandler() _isInitialized.value = true - scope.launch { - start( - client = newClient, - context = context - ) - } - - super.initializeFlocon() +// scope.launch { +// start( +// client = newClient, +// context = context +// ) +// } } - private suspend fun start(client: FloconApp.Client, context: FloconContext) { + private suspend fun start(client: Client, context: FloconContext) { // try to connect, it fail : try again in 3s try { client.connect( diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt similarity index 100% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt similarity index 87% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt index 4771c2713..3a05b5b0b 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt @@ -5,10 +5,13 @@ package io.github.openflocon.flocon * Plugins can receive messages from the server and react to connection events. */ interface FloconPlugin { + val key: String + fun onMessageReceived( method: String, body: String, ) + fun onConnectedToServer() } @@ -31,7 +34,7 @@ interface FloconPluginFactory : FloconPlugin fun createConfig(): Config /** - * Install the plugin into the [FloconApp] instance with the given [config]. + * Install the plugin into the [io.github.openflocon.flocon.FloconApp] instance with the given [config]. */ fun install(config: Config, app: FloconApp): PluginInstance } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt index 9778ea7e3..1fe2a7159 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt @@ -3,26 +3,6 @@ package io.github.openflocon.flocon.client import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.* import io.github.openflocon.flocon.model.* -import io.github.openflocon.flocon.plugins.analytics.FloconAnalytics -import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin -import io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporter -import io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporterPlugin -import io.github.openflocon.flocon.plugins.dashboard.FloconDashboard -import io.github.openflocon.flocon.plugins.dashboard.FloconDashboardPlugin -import io.github.openflocon.flocon.plugins.database.FloconDatabase -import io.github.openflocon.flocon.plugins.database.FloconDatabasePlugin -import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks -import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinksPlugin -import io.github.openflocon.flocon.plugins.device.FloconDevice -import io.github.openflocon.flocon.plugins.device.FloconDevicePlugin -import io.github.openflocon.flocon.plugins.files.FloconFiles -import io.github.openflocon.flocon.plugins.files.FloconFilesPlugin -import io.github.openflocon.flocon.plugins.network.FloconNetwork -import io.github.openflocon.flocon.plugins.network.FloconNetworkPlugin -import io.github.openflocon.flocon.plugins.sharedprefs.FloconPreferences -import io.github.openflocon.flocon.plugins.sharedprefs.FloconPreferencesPlugin -import io.github.openflocon.flocon.plugins.tables.FloconTable -import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin import io.github.openflocon.flocon.utils.currentTimeMillis import io.github.openflocon.flocon.websocket.FloconHttpClient import io.github.openflocon.flocon.websocket.FloconWebSocketClient @@ -36,65 +16,29 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch internal class FloconClientImpl( - private val appContext: FloconContext, + private val context: FloconContext, private val configuration: FloconConfiguration, + private val plugins: List ) : FloconApp.Client, FloconMessageSender, FloconFileSender { private val FLOCON_WEBSOCKET_PORT = 9023 private val FLOCON_HTTP_PORT = 9024 - private val appInstance by lazy { - currentTimeMillis() - } - - private val appInfos by lazy { - getAppInfos(appContext) - } - - private val versionName by lazy { - BuildConfig.APP_VERSION - } + private val appInstance by lazy { currentTimeMillis() } + private val appInfos by lazy { getAppInfos(context) } + private val versionName by lazy { BuildConfig.APP_VERSION } + private val address by lazy { getServerHost(context) } private val webSocketClient: FloconWebSocketClient = buildFloconWebSocketClient() private val httpClient: FloconHttpClient = buildFloconHttpClient() - private val address by lazy { - getServerHost(appContext) - } private val coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()) - private val installedPlugins = mutableMapOf, Any>() - private val pluginIdToPlugin = mutableMapOf() - init { - configuration.pluginConfigs.forEach { (factory, config) -> - @Suppress("UNCHECKED_CAST") - val plugin = (factory as FloconPluginFactory).install(config, FloconApp.instance!!) - installedPlugins[factory] = plugin - factory.pluginId?.let { id -> - if (plugin is FloconPlugin) { - pluginIdToPlugin[id] = plugin - } - } - } + override fun getPlugin(key: String): T? { + return plugins.find { it.key == key } as? T } - override fun getPlugin(key: FloconPluginKey<*, T>): T? { - return installedPlugins[key] as? T - } - - // region plugins backward compatibility - override val databasePlugin: FloconDatabasePlugin? get() = getPlugin(FloconDatabase) - override val dashboardPlugin: FloconDashboardPlugin? get() = getPlugin(FloconDashboard) - override val tablePlugin: FloconTablePlugin? get() = getPlugin(FloconTable) - override val deeplinksPlugin: FloconDeeplinksPlugin? get() = getPlugin(FloconDeeplinks) - override val analyticsPlugin: FloconAnalyticsPlugin? get() = getPlugin(FloconAnalytics) - override val networkPlugin: FloconNetworkPlugin? get() = getPlugin(FloconNetwork) - override val devicePlugin: FloconDevicePlugin? get() = getPlugin(FloconDevice) - override val preferencesPlugin: FloconPreferencesPlugin? get() = getPlugin(FloconPreferences) - override val crashReporterPlugin: FloconCrashReporterPlugin? get() = getPlugin(FloconCrashReporter) - // endregion - @Throws(Throwable::class) override suspend fun connect( onClosed: () -> Unit, @@ -105,11 +49,7 @@ internal class FloconClientImpl( onMessageReceived = ::onMessageReceived, onClosed = onClosed, ) - installedPlugins.values.forEach { - if (it is FloconPlugin) { - it.onConnectedToServer() - } - } + plugins.forEach(FloconPlugin::onConnectedToServer) } override suspend fun disconnect() { @@ -119,10 +59,12 @@ internal class FloconClientImpl( private fun onMessageReceived(message: String) { coroutineScope.launch(Dispatchers.IO) { floconMessageFromServerFromJson(message)?.let { messageFromServer -> - pluginIdToPlugin[messageFromServer.plugin]?.onMessageReceived( - method = messageFromServer.method, - body = messageFromServer.body, - ) + messageFromServer.plugin + plugins.find { it.key == messageFromServer.plugin } + ?.onMessageReceived( + method = messageFromServer.method, + body = messageFromServer.body, + ) } } } @@ -145,7 +87,8 @@ internal class FloconClientImpl( appInstance = appInstance, platform = appInfos.platform, versionName = versionName, - ).toFloconMessageToServer(), + ) + .toFloconMessageToServer(), ) } } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconPlugin.kt deleted file mode 100644 index dd50d5c15..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconPlugin.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.github.openflocon.flocon.core - -import io.github.openflocon.flocon.model.FloconMessageFromServer - -internal interface FloconPlugin { - fun onMessageReceived( - messageFromServer: FloconMessageFromServer, - ) - fun onConnectedToServer() -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt index 4ffa613ed..91e19704f 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -1,11 +1,17 @@ package io.github.openflocon.flocon.plugins.analytics -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem import io.github.openflocon.flocon.plugins.analytics.mapper.analyticsItemsToJson +import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsConfig +import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsPlugin +import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem -actual object FloconAnalytics : FloconPluginFactory { +object FloconAnalytics : FloconPluginFactory { override val name: String = "Analytics" override val pluginId: String = Protocol.ToDevice.Analytics.Plugin override fun createConfig() = FloconAnalyticsConfig() @@ -19,6 +25,8 @@ actual object FloconAnalytics : FloconPluginFactory { +object FloconCrashReporter : + FloconPluginFactory { override val name: String = "CrashReporter" - override val pluginId: String = Protocol.ToDevice.Analytics.Plugin // Crash reporter is usually write-only but we can set an ID + override val pluginId: String = + Protocol.ToDevice.Analytics.Plugin // Crash reporter is usually write-only but we can set an ID + override fun createConfig() = FloconCrashReporterConfig() - override fun install(config: FloconCrashReporterConfig, app: FloconApp): FloconCrashReporterPlugin { + override fun install( + config: FloconCrashReporterConfig, + app: FloconApp + ): FloconCrashReporterPlugin { val client = app.client as FloconMessageSender return FloconCrashReporterPluginImpl( - context = FloconContext(appContext = null), // Handled by datasource + context = TODO(), //FloconContext(appContext = null), // Handled by datasource sender = client, coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()), ) @@ -32,6 +40,7 @@ internal class FloconCrashReporterPluginImpl( private var sender: FloconMessageSender, private val coroutineScope: CoroutineScope, ) : FloconPlugin, FloconCrashReporterPlugin { + override val key: String = "CRASH_REPORTER" private val dataSource = buildFloconCrashReporterDataSource(context) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportMapper.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportMapper.kt index bc944130d..dec1f3fb1 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportMapper.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportMapper.kt @@ -3,7 +3,6 @@ package io.github.openflocon.flocon.plugins.crashreporter.model import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json internal fun CrashReportDataModel.toJson(): String { return FloconEncoder.json.encodeToString(this) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardDSL.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardDSL.kt index 5560f448d..3c9bc8353 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardDSL.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardDSL.kt @@ -1,11 +1,10 @@ package io.github.openflocon.flocon.plugins.dashboard -import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.plugins.dashboard.builder.FormBuilder -import io.github.openflocon.flocon.plugins.dashboard.builder.SectionBuilder -import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig -import io.github.openflocon.flocon.plugins.dashboard.model.DashboardScope -import io.github.openflocon.flocon.plugins.dashboard.model.config.ContainerConfig +import io.github.openflocon.flocon.pluginsold.dashboard.builder.FormBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.builder.SectionBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardConfig +import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardScope +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ContainerConfig import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob @@ -41,7 +40,7 @@ fun CoroutineScope.floconDashboard(id: String, block: DashboardScope.() -> Unit) sectionsFlow.collect { containers -> val config = DashboardConfig(id = id, containers = containers) - FloconApp.instance?.client?.dashboardPlugin?.registerDashboard(config) + //FloconApp.instance?.client?.dashboardPlugin?.registerDashboard(config) } } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt index c4fe95c04..7059b5063 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt @@ -4,16 +4,18 @@ import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.plugins.dashboard.mapper.toJson import io.github.openflocon.flocon.plugins.dashboard.model.DashboardCallback -import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig import io.github.openflocon.flocon.plugins.dashboard.model.todevice.ToDeviceCheckBoxValueChangedMessage import io.github.openflocon.flocon.plugins.dashboard.model.todevice.ToDeviceSubmittedFormMessage import io.github.openflocon.flocon.plugins.dashboard.model.todevice.ToDeviceSubmittedTextFieldMessage +import io.github.openflocon.flocon.pluginsold.dashboard.FloconDashboardConfig +import io.github.openflocon.flocon.pluginsold.dashboard.FloconDashboardPlugin +import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardConfig import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch -actual object FloconDashboard : FloconPluginFactory { + object FloconDashboard : FloconPluginFactory { override val name: String = "Dashboard" override val pluginId: String = Protocol.ToDevice.Dashboard.Plugin override fun createConfig() = FloconDashboardConfig() @@ -27,6 +29,7 @@ actual object FloconDashboard : FloconPluginFactory { +object FloconDatabase : FloconPluginFactory { override val name: String = "Database" override val pluginId: String = Protocol.ToDevice.Database.Plugin override fun createConfig() = FloconDatabaseConfig() override fun install(config: FloconDatabaseConfig, app: FloconApp): FloconDatabasePlugin { return FloconDatabasePluginImpl( sender = app.client as FloconMessageSender, - context = FloconContext(appContext = null), // Handled by actual buildFloconDatabaseDataSource + context = TODO() // FloconContext(appContext = null), // Handled by actual buildFloconDatabaseDataSource ) } } @@ -45,6 +50,7 @@ internal class FloconDatabasePluginImpl( private var sender: FloconMessageSender, private val context: FloconContext, ) : FloconPlugin, FloconDatabasePlugin { + override val key: String = "DATABASE" private val registeredDatabases = MutableStateFlow>(emptyList()) @@ -102,9 +108,13 @@ internal class FloconDatabasePluginImpl( } } +// override fun register(floconDatabaseModel: FloconDatabaseModel) { +// registeredDatabases.update { it + floconDatabaseModel } +// sendAllDatabases(sender) +// } + override fun register(floconDatabaseModel: FloconDatabaseModel) { - registeredDatabases.update { it + floconDatabaseModel } - sendAllDatabases(sender) + TODO("Not yet implemented") } override fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt deleted file mode 100644 index 9df144790..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt +++ /dev/null @@ -1,66 +0,0 @@ -package io.github.openflocon.flocon.plugins.deeplinks - -import io.github.openflocon.flocon.* -import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel -import io.github.openflocon.flocon.plugins.deeplinks.mapper.toDeeplinksJson -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.update - -actual object FloconDeeplinks : FloconPluginFactory { - override val name: String = "Deeplinks" - override val pluginId: String = Protocol.ToDevice.Deeplink.Plugin - override fun createConfig() = FloconDeeplinksConfig() - override fun install(config: FloconDeeplinksConfig, app: FloconApp): FloconDeeplinksPlugin { - val plugin = FloconDeeplinksPluginImpl( - sender = app.client as FloconMessageSender - ) - if (config.deeplinks.isNotEmpty()) { - plugin.registerDeeplinks(config.deeplinks) - } - return plugin - } -} - -internal class FloconDeeplinksPluginImpl( - private val sender: FloconMessageSender, -) : FloconPlugin, FloconDeeplinksPlugin { - - private val deeplinks = MutableStateFlow?>(null) - private val variables = MutableStateFlow?>(null) - - override fun onMessageReceived( - method: String, - body: String, - ) { - // no op - } - - override fun onConnectedToServer() { - // on connected, send known deeplinks - deeplinks.value?.let { - registerDeeplinks(it, variables.value.orEmpty()) - } - } - - override fun registerDeeplinks( - deeplinks: List, - variables: List - ) { - this.deeplinks.update { deeplinks } - this.variables.update { variables } - - try { - sender.send( - plugin = Protocol.FromDevice.Deeplink.Plugin, - method = Protocol.FromDevice.Deeplink.Method.GetDeeplinks, - body = toDeeplinksJson( - deeplinks = deeplinks, - variables = variables - ) - ) - } catch (t: Throwable) { - FloconLogger.logError("deeplink mapping error", t) - } - } -} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt deleted file mode 100644 index 4dede8700..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt +++ /dev/null @@ -1,53 +0,0 @@ -package io.github.openflocon.flocon.plugins.deeplinks - -import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkParameterRemote -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkRemote -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkVariableRemote -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinksRemote - -internal fun toDeeplinksJson( - deeplinks: List, - variables: List -): String { - val dto = DeeplinksRemote( - deeplinks = deeplinks.map(DeeplinkModel::toRemote), - variables = variables.map(DeeplinkVariable::toRemote) - ) - - return FloconEncoder.json - .encodeToString( - serializer = DeeplinksRemote.serializer(), - value = dto - ) -} - -internal fun DeeplinkModel.toRemote(): DeeplinkRemote = DeeplinkRemote( - label = label, - link = link, - description = description, - parameters = parameters.map(DeeplinkModel.Parameter::toRemote) -) - -internal fun DeeplinkVariable.toRemote(): DeeplinkVariableRemote = DeeplinkVariableRemote( - name = name, - mode = when (val mode = mode) { - is DeeplinkVariable.Mode.AutoComplete -> DeeplinkVariableRemote.Mode.AutoComplete(suggestions = mode.suggestions) - DeeplinkVariable.Mode.Input -> DeeplinkVariableRemote.Mode.Input - }, - description = description, -) - -internal fun DeeplinkModel.Parameter.toRemote(): DeeplinkParameterRemote = when (this) { - is DeeplinkModel.Parameter.AutoComplete -> DeeplinkParameterRemote.AutoComplete( - name = paramName, - autoComplete = autoComplete - ) - - is DeeplinkModel.Parameter.Variable -> DeeplinkParameterRemote.Variable( - name = paramName, - variableName = variableName - ) -} - diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt deleted file mode 100644 index e6e9015cc..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt +++ /dev/null @@ -1,65 +0,0 @@ -@file:OptIn(ExperimentalSerializationApi::class) - -package io.github.openflocon.flocon.plugins.deeplinks.model - -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonClassDiscriminator - -@Serializable -@JsonClassDiscriminator("type") -internal sealed interface DeeplinkParameterRemote { - val name: String - - @Serializable - @SerialName("auto_complete") - data class AutoComplete( - override val name: String, - val autoComplete: List - ) : DeeplinkParameterRemote - - @Serializable - @SerialName("variable") - data class Variable( - override val name: String, - val variableName: String - ) : DeeplinkParameterRemote -} - -@Serializable -internal class DeeplinkRemote( - val label: String? = null, - val link: String, - val description: String? = null, - val parameters: List -) - -@Serializable -internal data class DeeplinkVariableRemote( - val name: String, - val mode: Mode = Mode.Input, - val description: String? = null -) { - - @Serializable - @JsonClassDiscriminator("type") - sealed interface Mode { - - @Serializable - @SerialName("input") - data object Input : Mode - - @Serializable - @SerialName("auto_complete") - data class AutoComplete(val suggestions: List) : Mode - - } - -} - -@Serializable -internal class DeeplinksRemote( - val deeplinks: List, - val variables: List -) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt index f67e4581b..0afce2adb 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt @@ -3,8 +3,10 @@ package io.github.openflocon.flocon.plugins.device import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.plugins.device.model.fromdevice.RegisterDeviceDataModel +import io.github.openflocon.flocon.pluginsold.device.FloconDeviceConfig +import io.github.openflocon.flocon.pluginsold.device.FloconDevicePlugin -actual object FloconDevice : FloconPluginFactory { +object FloconDevice : FloconPluginFactory { override val name: String = "Device" override val pluginId: String = Protocol.ToDevice.Device.Plugin override fun createConfig() = FloconDeviceConfig() @@ -22,6 +24,7 @@ internal class FloconDevicePluginImpl( private var sender: FloconMessageSender, private val context: FloconContext, ) : FloconPlugin, FloconDevicePlugin { + override val key: String = "DEVICE" override fun registerWithSerial(serial: String) { try { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt index 7761af4b0..b00478108 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt @@ -1,6 +1,12 @@ package io.github.openflocon.flocon.plugins.files -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconFile +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconFileSender import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.model.FloconFileInfo @@ -11,10 +17,12 @@ import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceDeleteFi import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceDeleteFolderContentMessage import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceGetFileMessage import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceGetFilesMessage +import io.github.openflocon.flocon.pluginsold.files.FloconFilesConfig +import io.github.openflocon.flocon.pluginsold.files.FloconFilesPlugin import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update -actual object FloconFiles : FloconPluginFactory { +object FloconFiles : FloconPluginFactory { override val name: String = "Files" override val pluginId: String = Protocol.ToDevice.Files.Plugin override fun createConfig() = FloconFilesConfig() @@ -30,13 +38,18 @@ actual object FloconFiles : FloconPluginFactory + fun getFolderContent( + path: String, + isConstantPath: Boolean, + withFoldersSize: Boolean + ): List + fun deleteFile(path: String) fun deleteFiles(path: List) fun deleteFolderContent(folder: FloconFile) } -internal expect fun fileDataSource(context: FloconContext) : FileDataSource +internal expect fun fileDataSource(context: FloconContext): FileDataSource internal class FloconFilesPluginImpl( private val context: FloconContext, @@ -44,6 +57,7 @@ internal class FloconFilesPluginImpl( private val sender: FloconMessageSender, ) : FloconPlugin, FloconFilesPlugin { + override val key: String = "FILES" private val fileDataSource = fileDataSource(context) private val withFoldersSize = MutableStateFlow(false) @@ -67,15 +81,16 @@ internal class FloconFilesPluginImpl( Protocol.ToDevice.Files.Method.GetFile -> { val getFileMessage = ToDeviceGetFileMessage.fromJson(message = body) ?: return - fileDataSource.getFile(path = getFileMessage.path, isConstantPath = false)?.let { file -> - floconFileSender.send( - file = file, - infos = FloconFileInfo( - requestId = getFileMessage.requestId, - path = getFileMessage.path, + fileDataSource.getFile(path = getFileMessage.path, isConstantPath = false) + ?.let { file -> + floconFileSender.send( + file = file, + infos = FloconFileInfo( + requestId = getFileMessage.requestId, + path = getFileMessage.path, + ) ) - ) - } + } } Protocol.ToDevice.Files.Method.DeleteFile -> { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt index 51f23c8cc..b6d4d9048 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt @@ -1,9 +1,27 @@ package io.github.openflocon.flocon.plugins.network -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.network.mapper.* -import io.github.openflocon.flocon.plugins.network.model.* +import io.github.openflocon.flocon.plugins.network.mapper.floconNetworkCallRequestToJson +import io.github.openflocon.flocon.plugins.network.mapper.floconNetworkCallResponseToJson +import io.github.openflocon.flocon.plugins.network.mapper.floconNetworkWebSocketEventToJson +import io.github.openflocon.flocon.plugins.network.mapper.parseBadQualityConfig +import io.github.openflocon.flocon.plugins.network.mapper.parseMockResponses +import io.github.openflocon.flocon.plugins.network.mapper.parseWebSocketMockMessage +import io.github.openflocon.flocon.plugins.network.mapper.webSocketIdsToJsonArray +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkConfig +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent +import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketMockListener +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO @@ -13,7 +31,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -actual object FloconNetwork : FloconPluginFactory { +object FloconNetwork : FloconPluginFactory { override val name: String = "Network" override val pluginId: String = Protocol.ToDevice.Network.Plugin override fun createConfig() = FloconNetworkConfig() @@ -31,7 +49,7 @@ internal const val FLOCON_NETWORK_BAD_CONFIG_JSON = "flocon_network_bad_config.j internal interface FloconNetworkDataSource { fun saveMocksToFile(mocks: List) - fun loadMocksFromFile() : List + fun loadMocksFromFile(): List fun saveBadNetworkConfig(config: BadQualityConfig?) fun loadBadNetworkConfig(): BadQualityConfig? } @@ -43,16 +61,19 @@ internal class FloconNetworkPluginImpl( private var sender: FloconMessageSender, private val coroutineScope: CoroutineScope, ) : FloconPlugin, FloconNetworkPlugin { + override val key: String = "NETWORK" private val dataSource = buildFloconNetworkDataSource(context) - private val websocketListeners = MutableStateFlow>(emptyMap()) + private val websocketListeners = + MutableStateFlow>(emptyMap()) private val _mocks = MutableStateFlow>(dataSource.loadMocksFromFile()) - override val mocks : List + override val mocks: List get() = _mocks.value - private val _badQualityConfig = MutableStateFlow(dataSource.loadBadNetworkConfig()) + private val _badQualityConfig = + MutableStateFlow(dataSource.loadBadNetworkConfig()) override val badQualityConfig: BadQualityConfig? get() = _badQualityConfig.value @@ -119,7 +140,7 @@ internal class FloconNetworkPluginImpl( Protocol.ToDevice.Network.Method.WebsocketMockMessage -> { val message = parseWebSocketMockMessage(jsonString = body) - if(message != null) { + if (message != null) { websocketListeners.value[message.id]?.onMessage(message.message) } } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/BadQualityToJson.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/BadQualityToJson.kt index fbda0f50f..97112eb6f 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/BadQualityToJson.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/BadQualityToJson.kt @@ -2,10 +2,9 @@ package io.github.openflocon.flocon.plugins.network.mapper import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json internal fun BadQualityConfig.toJsonString(): String { return FloconEncoder.json.encodeToString( @@ -24,6 +23,7 @@ internal fun parseBadQualityConfig(jsonString: String): BadQualityConfig? { null } } + @Serializable internal class BadQualityConfigSerializable( val latency: LatencySerializable, @@ -63,6 +63,7 @@ internal fun BadQualityConfig.toSerializable(): BadQualityConfigSerializable { errorBody = t.errorBody, errorContentType = t.errorContentType ) + is BadQualityConfig.Error.Type.ErrorThrow -> BadQualityConfigSerializable.ErrorSerializable( weight = error.weight, errorException = t.classPath diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/FloconNetworkRequestToJson.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/FloconNetworkRequestToJson.kt index d187e7bb2..e8b849d6c 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/FloconNetworkRequestToJson.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/FloconNetworkRequestToJson.kt @@ -3,9 +3,9 @@ package io.github.openflocon.flocon.plugins.network.mapper import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.plugins.network.model.FloconWebSocketEvent +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlin.uuid.ExperimentalUuidApi @@ -14,8 +14,8 @@ import kotlin.uuid.Uuid @Serializable internal class FloconNetworkCallRequestRemote( val floconCallId: String, - val floconNetworkType : String, - val isMocked : Boolean, + val floconNetworkType: String, + val isMocked: Boolean, val url: String, val method: String, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/MockResponseToJson.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/MockResponseToJson.kt index 94d681dd8..fd6efd088 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/MockResponseToJson.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/MockResponseToJson.kt @@ -2,7 +2,7 @@ package io.github.openflocon.flocon.plugins.network.mapper import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString @@ -31,7 +31,8 @@ internal class MockNetworkResponseDataModel( internal fun parseMockResponses(jsonString: String): List { try { - val remote = FloconEncoder.json.decodeFromString>(jsonString) + val remote = + FloconEncoder.json.decodeFromString>(jsonString) return remote.mapNotNull { it.toDomain() } @@ -85,7 +86,7 @@ internal fun writeMockResponsesToJson(mocks: List): String } } -private fun MockNetworkResponse.toRemote(): MockNetworkResponseDataModel? { +private fun MockNetworkResponse.toRemote(): MockNetworkResponseDataModel { return MockNetworkResponseDataModel( expectation = MockNetworkResponseDataModel.Expectation( urlPattern = expectation.urlPattern, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt index 7b5f526f4..1e201a2ba 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt @@ -2,11 +2,11 @@ package io.github.openflocon.flocon.plugins.sharedprefs import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.sharedprefs.mapper.toJson -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconSharedPreferenceModel -import io.github.openflocon.flocon.plugins.sharedprefs.model.todevice.SetSharedPreferenceValueMessage +import io.github.openflocon.flocon.pluginsold.sharedprefs.FloconPreferencesConfig +import io.github.openflocon.flocon.pluginsold.sharedprefs.FloconPreferencesPlugin +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconSharedPreferenceModel -actual object FloconPreferences : FloconPluginFactory { +object FloconPreferences : FloconPluginFactory { override val name: String = "Preferences" override val pluginId: String = Protocol.ToDevice.SharedPreferences.Plugin override fun createConfig() = FloconPreferencesConfig() @@ -30,6 +30,7 @@ internal class FloconSharedPrefsPluginImpl( private val context: FloconContext, private val sender: FloconMessageSender, ) : FloconPlugin, FloconPreferencesPlugin { + override val key: String = "SHARED_PREF" private val dataSource = buildFloconSharedPreferenceDataSource(context) private val preferenceModels = mutableListOf() @@ -38,27 +39,27 @@ internal class FloconSharedPrefsPluginImpl( method: String, body: String, ) { - when (method) { - Protocol.ToDevice.SharedPreferences.Method.GetSharedPreferences -> { - sendSharedPreferences() - } - - Protocol.ToDevice.SharedPreferences.Method.GetSharedPreferenceValue -> { - // Not implemented yet on device side, usually handled by getSharedPreferences - } - - Protocol.ToDevice.SharedPreferences.Method.SetSharedPreferenceValue -> { - SetSharedPreferenceValueMessage.fromJson(body)?.let { message -> - dataSource.setSharedPreferenceValue( - fileName = message.fileName, - key = message.key, - value = message.value - ) - // Refresh view - sendSharedPreferences() - } - } - } +// when (method) { +// Protocol.ToDevice.SharedPreferences.Method.GetSharedPreferences -> { +// sendSharedPreferences() +// } +// +// Protocol.ToDevice.SharedPreferences.Method.GetSharedPreferenceValue -> { +// // Not implemented yet on device side, usually handled by getSharedPreferences +// } +// +// Protocol.ToDevice.SharedPreferences.Method.SetSharedPreferenceValue -> { +// SetSharedPreferenceValueMessage.fromJson(body)?.let { message -> +// dataSource.setSharedPreferenceValue( +// fileName = message.fileName, +// key = message.key, +// value = message.value +// ) +// // Refresh view +// sendSharedPreferences() +// } +// } +// } } override fun onConnectedToServer() { @@ -73,11 +74,11 @@ internal class FloconSharedPrefsPluginImpl( private fun sendSharedPreferences() { val allPrefs = dataSource.getSharedPreferences() + preferenceModels try { - sender.send( - plugin = Protocol.FromDevice.SharedPreferences.Plugin, - method = Protocol.FromDevice.SharedPreferences.Method.GetSharedPreferences, - body = allPrefs.toJson().toString() - ) +// sender.send( +// plugin = Protocol.FromDevice.SharedPreferences.Plugin, +// method = Protocol.FromDevice.SharedPreferences.Method.GetSharedPreferences, +// body = allPrefs.toJson().toString() +// ) } catch (t: Throwable) { FloconLogger.logError("SharedPreferences json mapping error", t) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreferenceWrapper.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreferenceWrapper.kt index bcf74a15c..d04e3e16a 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreferenceWrapper.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreferenceWrapper.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.plugins.sharedprefs.model import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt index c52587f62..9524a8a0b 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt @@ -2,10 +2,12 @@ package io.github.openflocon.flocon.plugins.tables import io.github.openflocon.flocon.* import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.tables.model.TableItem import io.github.openflocon.flocon.plugins.tables.model.tableItemListToJson +import io.github.openflocon.flocon.pluginsold.tables.FloconTableConfig +import io.github.openflocon.flocon.pluginsold.tables.FloconTablePlugin +import io.github.openflocon.flocon.pluginsold.tables.model.TableItem -actual object FloconTable : FloconPluginFactory { + object FloconTable : FloconPluginFactory { override val name: String = "Table" override val pluginId: String = Protocol.ToDevice.Table.Plugin override fun createConfig() = FloconTableConfig() @@ -19,6 +21,7 @@ actual object FloconTable : FloconPluginFactory { + override fun createConfig(): FloconAnalyticsConfig = TODO() + override fun install( + config: FloconAnalyticsConfig, + app: FloconApp + ): FloconAnalyticsPlugin = TODO() + + override val name: String = "" +} +// +//fun floconAnalytics(analyticsName: String) : AnalyticsBuilder { +// return AnalyticsBuilder( +// analyticsTableId = analyticsName, +// analyticsPlugin = FloconApp.instance?.client?.analyticsPlugin, +// ) +//} + +//fun FloconApp.analytics(analyticsName: String): AnalyticsBuilder { +// return AnalyticsBuilder( +// analyticsTableId = analyticsName, +// analyticsPlugin = this.client?.analyticsPlugin, +// ) +//} + +interface FloconAnalyticsPlugin : FloconPlugin { + fun registerAnalytics(analyticsItems: List) +} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt similarity index 73% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt index 6b78860c3..f59c51620 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt @@ -1,10 +1,10 @@ @file:OptIn(ExperimentalUuidApi::class) -package io.github.openflocon.flocon.plugins.analytics.builder +package io.github.openflocon.flocon.pluginsold.analytics.builder -import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsEvent -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem +import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsPlugin +import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsEvent +import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem import io.github.openflocon.flocon.utils.currentTimeMillis import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt similarity index 80% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt index 051c7c277..10a608249 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.analytics.model +package io.github.openflocon.flocon.pluginsold.analytics.model data class AnalyticsEvent( val eventName: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt similarity index 76% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt index 4d1af07f7..de6d93092 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.analytics.model +package io.github.openflocon.flocon.pluginsold.analytics.model data class AnalyticsPropertiesConfig( val name: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/TableItem.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt similarity index 74% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/TableItem.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt index f11507629..c23f13409 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/TableItem.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.analytics.model +package io.github.openflocon.flocon.pluginsold.analytics.model data class AnalyticsItem( val id: String, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt new file mode 100644 index 000000000..a4de6eaf9 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt @@ -0,0 +1,16 @@ +package io.github.openflocon.flocon.pluginsold.crashreporter + +import io.github.openflocon.flocon.FloconPlugin + +class FloconCrashReporterConfig { + var catchFatalErrors: Boolean = true +} + +/** + * Flocon Crash Reporter Plugin. + */ +//expect object FloconCrashReporter : FloconPluginFactory +// +interface FloconCrashReporterPlugin : FloconPlugin { + fun setupCrashHandler() +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/FloconDashboardPlugin.kt new file mode 100644 index 000000000..f0dde5d6a --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/FloconDashboardPlugin.kt @@ -0,0 +1,15 @@ +package io.github.openflocon.flocon.pluginsold.dashboard + +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardConfig + +class FloconDashboardConfig + +/** + * Flocon Dashboard Plugin. + */ +//expect object FloconDashboard : FloconPluginFactory +// +interface FloconDashboardPlugin : FloconPlugin { + fun registerDashboard(dashboardConfig: DashboardConfig) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/ContainerBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/ContainerBuilder.kt new file mode 100644 index 000000000..43a113fc3 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/ContainerBuilder.kt @@ -0,0 +1,14 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.builder + +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ContainerConfig +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ElementConfig + +abstract class ContainerBuilder { + open val elements = mutableListOf() + + open fun add(element: ElementConfig) { + elements.add(element) + } + + abstract fun build(): ContainerConfig +} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/DashboardBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/DashboardBuilder.kt similarity index 53% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/DashboardBuilder.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/DashboardBuilder.kt index 6672693f1..879c6fcc7 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/DashboardBuilder.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/DashboardBuilder.kt @@ -1,8 +1,8 @@ -package io.github.openflocon.flocon.plugins.dashboard.builder +package io.github.openflocon.flocon.pluginsold.dashboard.builder -import io.github.openflocon.flocon.plugins.dashboard.dsl.DashboardDsl -import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig -import io.github.openflocon.flocon.plugins.dashboard.model.config.ContainerConfig +import io.github.openflocon.flocon.pluginsold.dashboard.dsl.DashboardDsl +import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardConfig +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ContainerConfig @DashboardDsl class DashboardBuilder(private val id: String) { diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/FormBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/FormBuilder.kt similarity index 73% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/FormBuilder.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/FormBuilder.kt index 8dd5b8b1f..1e43250d9 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/FormBuilder.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/FormBuilder.kt @@ -1,6 +1,6 @@ -package io.github.openflocon.flocon.plugins.dashboard.builder +package io.github.openflocon.flocon.pluginsold.dashboard.builder -import io.github.openflocon.flocon.plugins.dashboard.model.config.FormConfig +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.FormConfig class FormBuilder( val name: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/SectionBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/SectionBuilder.kt similarity index 51% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/SectionBuilder.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/SectionBuilder.kt index 952aa4261..bf301ca26 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/SectionBuilder.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/builder/SectionBuilder.kt @@ -1,6 +1,6 @@ -package io.github.openflocon.flocon.plugins.dashboard.builder +package io.github.openflocon.flocon.pluginsold.dashboard.builder -import io.github.openflocon.flocon.plugins.dashboard.model.config.SectionConfig +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.SectionConfig class SectionBuilder(val name: String) : ContainerBuilder() { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/ButtonDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/ButtonDsl.kt new file mode 100644 index 000000000..7ae6e6479 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/ButtonDsl.kt @@ -0,0 +1,19 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.dsl + +import io.github.openflocon.flocon.pluginsold.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ButtonConfig + +@DashboardDsl +fun ContainerBuilder.button( + text: String, + id: String, + onClick: () -> Unit, +) { + add( + ButtonConfig( + text = text, + id = id, + onClick = onClick, + ) + ) +} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/CheckBoxDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/CheckBoxDsl.kt similarity index 57% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/CheckBoxDsl.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/CheckBoxDsl.kt index 6569df699..43102e7a0 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/CheckBoxDsl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/CheckBoxDsl.kt @@ -1,7 +1,7 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl +package io.github.openflocon.flocon.pluginsold.dashboard.dsl -import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder -import io.github.openflocon.flocon.plugins.dashboard.model.config.CheckBoxConfig +import io.github.openflocon.flocon.pluginsold.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.CheckBoxConfig @DashboardDsl fun ContainerBuilder.checkBox( diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/DashboardDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/DashboardDsl.kt similarity index 53% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/DashboardDsl.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/DashboardDsl.kt index c59db318b..39e96f5cd 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/DashboardDsl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/DashboardDsl.kt @@ -1,7 +1,7 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl +package io.github.openflocon.flocon.pluginsold.dashboard.dsl -import io.github.openflocon.flocon.plugins.dashboard.builder.DashboardBuilder -import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig +import io.github.openflocon.flocon.pluginsold.dashboard.builder.DashboardBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardConfig @DslMarker annotation class DashboardDsl diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/FormDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/FormDsl.kt similarity index 61% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/FormDsl.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/FormDsl.kt index f73e6b817..99ff45560 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/FormDsl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/FormDsl.kt @@ -1,7 +1,7 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl +package io.github.openflocon.flocon.pluginsold.dashboard.dsl -import io.github.openflocon.flocon.plugins.dashboard.builder.DashboardBuilder -import io.github.openflocon.flocon.plugins.dashboard.builder.FormBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.builder.DashboardBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.builder.FormBuilder @DashboardDsl fun DashboardBuilder.form( diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/HtmlDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/HtmlDsl.kt new file mode 100644 index 000000000..050d9f612 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/HtmlDsl.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.dsl + +import io.github.openflocon.flocon.pluginsold.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.HtmlConfig + +@DashboardDsl +fun ContainerBuilder.html(label: String, value: String) { + add(HtmlConfig(label = label, value = value)) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/MarkdownDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/MarkdownDsl.kt new file mode 100644 index 000000000..cebfbbf99 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/MarkdownDsl.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.dsl + +import io.github.openflocon.flocon.pluginsold.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.MarkdownConfig + +@DashboardDsl +fun ContainerBuilder.markdown(label: String, value: String) { + add(MarkdownConfig(label = label, value = value)) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/PlainTextDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/PlainTextDsl.kt new file mode 100644 index 000000000..9cff79157 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/PlainTextDsl.kt @@ -0,0 +1,26 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.dsl + +import io.github.openflocon.flocon.pluginsold.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.PlainTextConfig + +@DashboardDsl +fun ContainerBuilder.plainText(label: String, value: String) { + add( + PlainTextConfig( + label = label, + value = value, + type = "text", + ) + ) +} + +@DashboardDsl +fun ContainerBuilder.json(label: String, value: String) { + add( + PlainTextConfig( + label = label, + value = value, + type = "json", + ) + ) +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/SectionDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/SectionDsl.kt new file mode 100644 index 000000000..6560ba3a0 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/SectionDsl.kt @@ -0,0 +1,13 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.dsl + +import io.github.openflocon.flocon.pluginsold.dashboard.builder.DashboardBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.builder.SectionBuilder + +@DashboardDsl +fun DashboardBuilder.section(name: String, block: SectionBuilder.() -> Unit) { + val builder = SectionBuilder(name).apply { + block() + } + + add(builder.build()) +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/TextDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/TextDsl.kt new file mode 100644 index 000000000..2b13da09a --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/TextDsl.kt @@ -0,0 +1,15 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.dsl + +import io.github.openflocon.flocon.pluginsold.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.LabelConfig +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.TextConfig + +@DashboardDsl +fun ContainerBuilder.text(label: String, value: String, color: Int? = null) { + add(TextConfig(label = label, value = value, color = color)) +} + +@DashboardDsl +fun ContainerBuilder.label(label: String, color: Int? = null) { + add(LabelConfig(label = label, color = color)) +} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextField.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/TextField.kt similarity index 62% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextField.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/TextField.kt index 42bf0bc4e..11717ba59 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextField.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/dsl/TextField.kt @@ -1,7 +1,7 @@ -package io.github.openflocon.flocon.plugins.dashboard.dsl +package io.github.openflocon.flocon.pluginsold.dashboard.dsl -import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder -import io.github.openflocon.flocon.plugins.dashboard.model.config.TextFieldConfig +import io.github.openflocon.flocon.pluginsold.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.TextFieldConfig @DashboardDsl fun ContainerBuilder.textField( diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/ContainerType.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/ContainerType.kt new file mode 100644 index 000000000..a866d9e5a --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/ContainerType.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.model + +enum class ContainerType { + FORM, + SECTION +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/Dashboard.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/Dashboard.kt new file mode 100644 index 000000000..8d8a424f3 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/Dashboard.kt @@ -0,0 +1,8 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.model + +import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ContainerConfig + +data class DashboardConfig( + val id: String, + val containers: List +) \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardScope.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/DashboardScope.kt similarity index 72% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardScope.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/DashboardScope.kt index 3089b07f8..725c56a07 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardScope.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/DashboardScope.kt @@ -1,13 +1,13 @@ -package io.github.openflocon.flocon.plugins.dashboard.model +package io.github.openflocon.flocon.pluginsold.dashboard.model -import io.github.openflocon.flocon.plugins.dashboard.builder.FormBuilder -import io.github.openflocon.flocon.plugins.dashboard.builder.SectionBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.builder.FormBuilder +import io.github.openflocon.flocon.pluginsold.dashboard.builder.SectionBuilder import kotlinx.coroutines.flow.Flow interface DashboardScope { fun section(name: String, flow: Flow, content: SectionBuilder.(T) -> Unit) fun section(name: String, content: SectionBuilder.() -> Unit) - + fun form( name: String, submitText: String = "Submit", @@ -15,7 +15,7 @@ interface DashboardScope { flow: Flow, content: FormBuilder.(T) -> Unit ) - + fun form( name: String, submitText: String = "Submit", diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ButtonConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ButtonConfig.kt similarity index 61% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ButtonConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ButtonConfig.kt index 6fa9d1acb..3e54a5568 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ButtonConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ButtonConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config data class ButtonConfig( val text: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/CheckBoxConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/CheckBoxConfig.kt similarity index 68% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/CheckBoxConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/CheckBoxConfig.kt index f963111a4..de6453454 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/CheckBoxConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/CheckBoxConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config data class CheckBoxConfig( val id: String, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ContainerConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ContainerConfig.kt new file mode 100644 index 000000000..53bf15766 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ContainerConfig.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.model.config + +import io.github.openflocon.flocon.pluginsold.dashboard.model.ContainerType + +sealed interface ContainerConfig { + val name: String + val elements: List + val containerType: ContainerType +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ElementConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ElementConfig.kt new file mode 100644 index 000000000..71a56097a --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/ElementConfig.kt @@ -0,0 +1,3 @@ +package io.github.openflocon.flocon.pluginsold.dashboard.model.config + +sealed interface ElementConfig \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/FormConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/FormConfig.kt similarity index 66% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/FormConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/FormConfig.kt index 51ecb3685..644c96da7 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/FormConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/FormConfig.kt @@ -1,6 +1,6 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config -import io.github.openflocon.flocon.plugins.dashboard.model.ContainerType +import io.github.openflocon.flocon.pluginsold.dashboard.model.ContainerType data class FormConfig( override val name: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/HtmlConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/HtmlConfig.kt similarity index 55% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/HtmlConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/HtmlConfig.kt index 70fce9994..f3de7f22a 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/HtmlConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/HtmlConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config data class HtmlConfig( val label: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/LabelConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/LabelConfig.kt similarity index 55% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/LabelConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/LabelConfig.kt index 24416e4cd..3e9f9a1f7 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/LabelConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/LabelConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config data class LabelConfig( val label: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/MarkdownConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/MarkdownConfig.kt similarity index 56% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/MarkdownConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/MarkdownConfig.kt index f2e4a3799..7b64738d5 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/MarkdownConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/MarkdownConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config data class MarkdownConfig( val label: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/PlainTextConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/PlainTextConfig.kt similarity index 65% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/PlainTextConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/PlainTextConfig.kt index e42961a6e..53c37df21 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/PlainTextConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/PlainTextConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config data class PlainTextConfig( val label: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/SectionConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/SectionConfig.kt similarity index 57% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/SectionConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/SectionConfig.kt index 98b4fe3f9..b2654befa 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/SectionConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/SectionConfig.kt @@ -1,6 +1,6 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config -import io.github.openflocon.flocon.plugins.dashboard.model.ContainerType +import io.github.openflocon.flocon.pluginsold.dashboard.model.ContainerType data class SectionConfig( override val name: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/TextConfig.kt similarity index 61% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/TextConfig.kt index 97ee703a2..5a54816b5 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/TextConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config data class TextConfig( val label: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextFieldConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/TextFieldConfig.kt similarity index 72% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextFieldConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/TextFieldConfig.kt index 9e47cab88..bf2e5ed4a 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextFieldConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/model/config/TextFieldConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.dashboard.model.config +package io.github.openflocon.flocon.pluginsold.dashboard.model.config data class TextFieldConfig( val id: String, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt new file mode 100644 index 000000000..36a04ae60 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt @@ -0,0 +1,34 @@ +package io.github.openflocon.flocon.pluginsold.database + +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.pluginsold.database.model.FloconDatabaseModel + +class FloconDatabaseConfig + +/** + * Flocon Database Plugin. + * Used to inspect Room or other SQL databases. + */ +object FloconDatabase : FloconPluginFactory { + override fun createConfig(): FloconDatabaseConfig { + TODO("Not yet implemented") + } + + override fun install( + config: FloconDatabaseConfig, + app: FloconApp + ): FloconDatabasePlugin { + TODO("Not yet implemented") + } + + override val name: String + get() = TODO("Not yet implemented") +} + + +interface FloconDatabasePlugin : FloconPlugin { + fun register(floconDatabaseModel: FloconDatabaseModel) + fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) +} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt similarity index 75% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt index b75ab65f6..4298eb2eb 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.database.model +package io.github.openflocon.flocon.pluginsold.database.model interface FloconDatabaseModel { val displayName: String diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt new file mode 100644 index 000000000..e35f0bc85 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt @@ -0,0 +1,28 @@ +package io.github.openflocon.flocon.pluginsold.device + +import io.github.openflocon.flocon.* + +class FloconDeviceConfig + +/** + * Flocon Device Plugin. + */ +object FloconDevice : FloconPluginFactory { + override fun createConfig(): FloconDeviceConfig { + TODO("Not yet implemented") + } + + override fun install( + config: FloconDeviceConfig, + app: FloconApp + ): FloconDevicePlugin { + TODO("Not yet implemented") + } + + override val name: String + get() = TODO("Not yet implemented") +} + +interface FloconDevicePlugin : FloconPlugin { + fun registerWithSerial(serial: String) +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt new file mode 100644 index 000000000..00cf0f9b8 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt @@ -0,0 +1,29 @@ +package io.github.openflocon.flocon.pluginsold.files + +import io.github.openflocon.flocon.* + +class FloconFilesConfig { + val roots = mutableListOf() +} + +/** + * Flocon Files Plugin. + * Used to inspect and download files from the device. + */ +object FloconFiles : FloconPluginFactory { + override fun createConfig(): FloconFilesConfig { + TODO("Not yet implemented") + } + + override fun install( + config: FloconFilesConfig, + app: FloconApp + ): FloconFilesPlugin { + TODO("Not yet implemented") + } + + override val name: String + get() = TODO("Not yet implemented") +} + +interface FloconFilesPlugin : FloconPlugin \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt new file mode 100644 index 000000000..f498f2255 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt @@ -0,0 +1,45 @@ +package io.github.openflocon.flocon.pluginsold.network + +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent +import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketMockListener +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse + +class FloconNetworkConfig { + var badQualityConfig: BadQualityConfig? = null + val mocks = mutableListOf() +} + +/** + * Flocon Network Plugin. + * Used to inspect HTTP/S and WebSocket calls. + */ +object FloconNetwork : FloconPluginFactory { + override fun createConfig(): FloconNetworkConfig = TODO() + override fun install( + config: FloconNetworkConfig, + app: FloconApp + ): FloconNetworkPlugin = TODO() + + override val name: String = "" +} + + +interface FloconNetworkPlugin : FloconPlugin { + val mocks: Collection + val badQualityConfig: BadQualityConfig? + + fun logRequest(request: FloconNetworkCallRequest) + fun logResponse(response: FloconNetworkCallResponse) + + fun logWebSocket( + event: FloconWebSocketEvent, + ) + + fun registerWebSocketMockListener(id: String, listener: FloconWebSocketMockListener) +} diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/BadQualityConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/BadQualityConfig.kt similarity index 97% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/BadQualityConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/BadQualityConfig.kt index fdac3de51..7fe952d6f 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/BadQualityConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/BadQualityConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.model +package io.github.openflocon.flocon.pluginsold.network.model import io.github.openflocon.flocon.FloconLogger import kotlin.random.Random diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconHttpRequest.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconHttpRequest.kt similarity index 91% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconHttpRequest.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconHttpRequest.kt index 913e72351..5d4af5515 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconHttpRequest.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconHttpRequest.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.model +package io.github.openflocon.flocon.pluginsold.network.model data class FloconNetworkRequest( val url: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconNetworkCallRequest.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallRequest.kt similarity index 73% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconNetworkCallRequest.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallRequest.kt index cfcce2eda..8638105a6 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconNetworkCallRequest.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallRequest.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.model +package io.github.openflocon.flocon.pluginsold.network.model data class FloconNetworkCallRequest( val floconCallId: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconNetworkCallResponse.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallResponse.kt similarity index 76% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconNetworkCallResponse.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallResponse.kt index 898287131..6a8fe9e28 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconNetworkCallResponse.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallResponse.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.model +package io.github.openflocon.flocon.pluginsold.network.model data class FloconNetworkCallResponse( val floconCallId: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconWebSocketEvent.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketEvent.kt similarity index 87% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconWebSocketEvent.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketEvent.kt index f2be27bc9..29903e336 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconWebSocketEvent.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketEvent.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.model +package io.github.openflocon.flocon.pluginsold.network.model import io.github.openflocon.flocon.utils.currentTimeMillis diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconWebSocketMockListener.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketMockListener.kt similarity index 56% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconWebSocketMockListener.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketMockListener.kt index f6021ee1f..3cd6b177e 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/FloconWebSocketMockListener.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketMockListener.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.model +package io.github.openflocon.flocon.pluginsold.network.model interface FloconWebSocketMockListener { fun onMessage(message: String) diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/MockNetworkResponse.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/MockNetworkResponse.kt similarity index 94% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/MockNetworkResponse.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/MockNetworkResponse.kt index 535ca4fa9..a1a51226d 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/model/MockNetworkResponse.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/MockNetworkResponse.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.model +package io.github.openflocon.flocon.pluginsold.network.model data class MockNetworkResponse( val expectation: Expectation, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt new file mode 100644 index 000000000..111ff7278 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt @@ -0,0 +1,34 @@ +package io.github.openflocon.flocon.pluginsold.sharedprefs + +import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconSharedPreferenceModel + +class FloconPreferencesConfig + +/** + * Flocon Preferences Plugin. + * Used to inspect SharedPreferences or other key-value stores. + */ +object FloconPreferences : FloconPluginFactory { + override fun createConfig(): FloconPreferencesConfig { + TODO("Not yet implemented") + } + + override fun install( + config: FloconPreferencesConfig, + app: FloconApp + ): FloconPreferencesPlugin { + TODO("Not yet implemented") + } + + override val name: String + get() = TODO("Not yet implemented") +} + +//fun floconRegisterSharedPreference(sharedPreference: FloconSharedPreferenceModel) { +// FloconApp.instance?.client?.preferencesPlugin?.register(sharedPreference) +//} + +interface FloconPreferencesPlugin : FloconPlugin { + fun register(sharedPreference: FloconSharedPreferenceModel) +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/buildFloconPreferencesDataSource.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/buildFloconPreferencesDataSource.kt new file mode 100644 index 000000000..9df5cd32a --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/buildFloconPreferencesDataSource.kt @@ -0,0 +1,2 @@ +package io.github.openflocon.flocon.pluginsold.sharedprefs + diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreference.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconPreference.kt similarity index 82% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreference.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconPreference.kt index 5a3810f9f..5bbe4634f 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreference.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconPreference.kt @@ -1,11 +1,11 @@ -package io.github.openflocon.flocon.plugins.sharedprefs.model +package io.github.openflocon.flocon.pluginsold.sharedprefs.model interface FloconPreference { val name: String suspend fun set( columnName: String, - value: FloconPreferenceValue, + value: FloconPreferenceValue ) suspend fun columns(): List diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt new file mode 100644 index 000000000..e5b8f6b71 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt @@ -0,0 +1,5 @@ +package io.github.openflocon.flocon.pluginsold.sharedprefs.model + +// TODO Get model from git +class FloconSharedPreferenceModel { +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/FloconTablesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/FloconTablesPlugin.kt new file mode 100644 index 000000000..d5cdf32d7 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/FloconTablesPlugin.kt @@ -0,0 +1,46 @@ +package io.github.openflocon.flocon.pluginsold.tables + +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.pluginsold.tables.model.TableItem + +class FloconTableConfig + +/** + * Flocon Table Plugin. + * Used to display custom data tables. + */ +object FloconTable : FloconPluginFactory { + override fun createConfig(): FloconTableConfig { + TODO("Not yet implemented") + } + + override fun install( + config: FloconTableConfig, + app: FloconApp + ): FloconTablePlugin { + TODO("Not yet implemented") + } + + override val name: String + get() = TODO("Not yet implemented") +} + +//fun floconTable(tableName: String) : TableBuilder { +// return TableBuilder( +// tableId = tableName, +// tablePlugin = FloconApp.instance?.client?.tablePlugin, +// ) +//} +// +//fun FloconApp.table(tableName: String): TableBuilder { +// return TableBuilder( +// tableId = tableName, +// tablePlugin = this.client?.tablePlugin, +// ) +//} + +interface FloconTablePlugin : FloconPlugin { + fun registerItems(tableItems: List) +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt new file mode 100644 index 000000000..484c85387 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt @@ -0,0 +1,20 @@ +@file:OptIn(ExperimentalUuidApi::class) + +package io.github.openflocon.flocon.pluginsold.tables.builder + +import kotlin.uuid.ExperimentalUuidApi + +//class TableBuilder( +// val tableName: String, +// private val tablePlugin: FloconTablePlugin?, +//) { +// fun log(vararg columns: TableColumnConfig) { +// val dashboardConfig = TableItem( +// id = Uuid.random().toString(), +// name = tableName, +// columns = columns.toList(), +// createdAt = currentTimeMillis(), +// ) +// tablePlugin?.registerTable(dashboardConfig) +// } +//} \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableColumnConfig.kt similarity index 75% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableColumnConfig.kt index bfb85182d..857f2d8a8 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableColumnConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.tables.model +package io.github.openflocon.flocon.pluginsold.tables.model data class TableColumnConfig( val columnName: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableItem.kt similarity index 68% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableItem.kt index f4635bd90..ba4485e34 100644 --- a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableItem.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.tables.model +package io.github.openflocon.flocon.pluginsold.tables.model data class TableItem( val id: String, diff --git a/FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.kt similarity index 100% rename from FloconAndroid/flocon-base/src/commonMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.kt rename to FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.kt diff --git a/FloconAndroid/flocon-base/src/iosMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt similarity index 97% rename from FloconAndroid/flocon-base/src/iosMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt rename to FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt index 32b5a87cf..c77d01ab2 100644 --- a/FloconAndroid/flocon-base/src/iosMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt +++ b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt @@ -3,18 +3,17 @@ package io.github.openflocon.flocon actual object FloconLogger { actual var enabled = false private const val TAG = "FloconLogger" - + actual fun logError(text: String, throwable: Throwable?) { if(enabled) { println("ERROR $TAG: $text") throwable?.printStackTrace() } } - + actual fun log(text: String) { if(enabled) { println("$TAG: $text") } } -} - +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.ios.kt b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.ios.kt index eb0c19068..0290a8e76 100644 --- a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.ios.kt +++ b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.ios.kt @@ -1,17 +1,18 @@ package io.github.openflocon.flocon.plugins.sharedprefs import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference -import io.github.openflocon.flocon.plugins.sharedprefs.model.fromdevice.PreferenceRowDataModel -import io.github.openflocon.flocon.plugins.sharedprefs.model.todevice.ToDeviceEditSharedPreferenceValueMessage -internal actual fun buildFloconPreferencesDataSource(context: FloconContext): FloconPreferencesDataSource { - return FloconPreferencesDataSourceIOs() -} +//internal actual fun buildFloconPreferencesDataSource(context: FloconContext): FloconPreferencesDataSource { +// return FloconPreferencesDataSourceIOs() +//} // TODO try to bind with ios storage -internal class FloconPreferencesDataSourceIOs : FloconPreferencesDataSource { - override fun detectLocalPreferences(): List { - return emptyList() - } +//internal class FloconPreferencesDataSourceIOs : FloconPreferencesDataSource { +// override fun detectLocalPreferences(): List { +// return emptyList() +// } +//} + +internal actual fun buildFloconSharedPreferenceDataSource(context: FloconContext): FloconSharedPreferenceDataSource { + TODO("Not yet implemented") } \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/iosMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.ios.kt b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.ios.kt similarity index 100% rename from FloconAndroid/flocon-base/src/iosMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.ios.kt rename to FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.ios.kt diff --git a/FloconAndroid/flocon-base/src/jvmMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt similarity index 97% rename from FloconAndroid/flocon-base/src/jvmMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt rename to FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt index c7577ef7d..f69122a84 100644 --- a/FloconAndroid/flocon-base/src/jvmMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt +++ b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/FloconLogger.kt @@ -3,18 +3,17 @@ package io.github.openflocon.flocon actual object FloconLogger { actual var enabled = false private const val TAG = "FloconLogger" - + actual fun logError(text: String, throwable: Throwable?) { if(enabled) { System.err.println("$TAG: $text") throwable?.printStackTrace() } } - + actual fun log(text: String) { if(enabled) { println("$TAG: $text") } } -} - +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt index 1fcfea362..645d38c33 100644 --- a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt +++ b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt @@ -2,13 +2,18 @@ package io.github.openflocon.flocon.plugins.sharedprefs import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference -internal actual fun buildFloconPreferencesDataSource(context: FloconContext): FloconPreferencesDataSource { - return FloconPreferencesDataSourceJvm() -} +//internal actual fun buildFloconPreferencesDataSource(context: FloconContext): FloconPreferencesDataSource { +// return FloconPreferencesDataSourceJvm() +//} -internal class FloconPreferencesDataSourceJvm : FloconPreferencesDataSource { - override fun detectLocalPreferences(): List { - return emptyList() - } +//internal class FloconPreferencesDataSourceJvm : FloconPreferencesDataSource { +// override fun detectLocalPreferences(): List { +// return emptyList() +// } +//} + +internal actual fun buildFloconSharedPreferenceDataSource(context: FloconContext): FloconSharedPreferenceDataSource { + TODO("Not yet implemented") } \ No newline at end of file diff --git a/FloconAndroid/flocon-base/src/jvmMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.jvm.kt b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.jvm.kt similarity index 100% rename from FloconAndroid/flocon-base/src/jvmMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.jvm.kt rename to FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.jvm.kt diff --git a/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts b/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts index e43bb3211..4e00098c9 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts +++ b/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts @@ -40,7 +40,7 @@ kotlin { } dependencies { - implementation(project(":flocon-base")) + implementation(project(":flocon")) implementation(platform(libs.kotlinx.coroutines.bom)) implementation(libs.kotlinx.coroutines.core) diff --git a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/BadQuality.kt b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/BadQuality.kt index ae1b9d370..d69d425ae 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/BadQuality.kt +++ b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/BadQuality.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.grpc -import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import java.io.IOException @Throws(IOException::class) diff --git a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcBaseInterceptor.kt b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcBaseInterceptor.kt index 4edd65a0e..ee83bd28f 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcBaseInterceptor.kt +++ b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcBaseInterceptor.kt @@ -2,13 +2,12 @@ package io.github.openflocon.flocon.grpc -import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.grpc.model.RequestHolder import io.github.openflocon.flocon.grpc.model.toHeaders -import io.github.openflocon.flocon.plugins.network.FloconNetworkPlugin -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkResponse +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkResponse import io.grpc.CallOptions import io.grpc.Channel import io.grpc.ClientCall @@ -33,7 +32,7 @@ abstract class FloconGrpcBaseInterceptor( callOptions: CallOptions, next: Channel, ): ClientCall { - val networkPlugin = FloconApp.instance?.client?.networkPlugin + val networkPlugin = TODO()//FloconApp.instance?.client?.networkPlugin if (networkPlugin == null) { // do not intercept if no network plugin, just call return next.newCall(method, callOptions) @@ -101,9 +100,9 @@ private class LoggingForwardingClientCall( callId = callId, request = request ) - floconNetworkPlugin.badQualityConfig?.let { - executeBadQuality(it) - } +// floconNetworkPlugin.badQualityConfig?.let { +// executeBadQuality(it) +// } super.sendMessage(message) } } diff --git a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt index be3219ae4..f9cc4f8ad 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt +++ b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt @@ -1,22 +1,19 @@ package io.github.openflocon.flocon.grpc -import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkResponse +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkResponse internal class FloconGrpcPlugin() { fun reportRequest(callId: String, request: FloconNetworkRequest) { - FloconApp.instance?.client?.networkPlugin?.logRequest( - FloconNetworkCallRequest( - floconCallId = callId, - floconNetworkType = "grpc", - request = request, - isMocked = false, - ) - ) +// FloconApp.instance?.client?.networkPlugin?.logRequest( +// FloconNetworkCallRequest( +// floconCallId = callId, +// floconNetworkType = "grpc", +// request = request, +// isMocked = false, +// ) +// ) } fun reportResponse( @@ -25,16 +22,16 @@ internal class FloconGrpcPlugin() { response: FloconNetworkResponse ) { val responseTime = System.currentTimeMillis() - val durationMs = (responseTime - request.startTime).toDouble() + (responseTime - request.startTime).toDouble() - FloconApp.instance?.client?.networkPlugin?.logResponse( - FloconNetworkCallResponse( - floconCallId = callId, - floconNetworkType = "grpc", - response = response, - durationMs = durationMs, - isMocked = false, - ) - ) +// FloconApp.instance?.client?.networkPlugin?.logResponse( +// FloconNetworkCallResponse( +// floconCallId = callId, +// floconNetworkType = "grpc", +// response = response, +// durationMs = durationMs, +// isMocked = false, +// ) +// ) } } diff --git a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt index 9518cb4e4..2f9de14b2 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt +++ b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.grpc.model -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest import kotlinx.coroutines.CompletableDeferred internal data class RequestHolder( diff --git a/FloconAndroid/ktor-interceptor-no-op/build.gradle.kts b/FloconAndroid/ktor-interceptor-no-op/build.gradle.kts index 3f2d23cd9..f645d5790 100644 --- a/FloconAndroid/ktor-interceptor-no-op/build.gradle.kts +++ b/FloconAndroid/ktor-interceptor-no-op/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon-base")) + implementation(project(":flocon")) implementation(libs.ktor.client.core) } } diff --git a/FloconAndroid/ktor-interceptor/build.gradle.kts b/FloconAndroid/ktor-interceptor/build.gradle.kts index b7d332a7f..d18d78819 100644 --- a/FloconAndroid/ktor-interceptor/build.gradle.kts +++ b/FloconAndroid/ktor-interceptor/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon-base")) + implementation(project(":flocon")) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0") implementation(libs.ktor.client.core) } diff --git a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt b/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt index 21cc111ae..0ee37502c 100644 --- a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt +++ b/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.ktor -import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import io.ktor.client.HttpClient import io.ktor.client.call.HttpClientCall import io.ktor.client.request.HttpRequestBuilder diff --git a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt b/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt index 5a947fea8..c20f200e0 100644 --- a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt +++ b/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt @@ -2,29 +2,13 @@ package io.github.openflocon.flocon.ktor -import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkResponse import io.ktor.client.HttpClientConfig import io.ktor.client.plugins.api.createClientPlugin import io.ktor.client.request.HttpRequest -import io.ktor.client.request.HttpSendPipeline -import io.ktor.client.statement.HttpReceivePipeline +import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.statement.HttpResponse -import io.ktor.client.statement.bodyAsChannel -import io.ktor.http.contentType import io.ktor.util.AttributeKey -import io.ktor.utils.io.ByteReadChannel -import io.ktor.utils.io.toByteArray -import io.github.openflocon.flocon.utils.currentTimeMillis -import io.github.openflocon.flocon.utils.currentTimeNanos -import io.ktor.client.call.save -import io.ktor.client.request.HttpRequestBuilder import kotlin.uuid.ExperimentalUuidApi -import kotlin.uuid.Uuid data class FloconNetworkIsImageParams( @@ -45,169 +29,169 @@ val FloconKtorPlugin = createClientPlugin("FloconKtorPlugin", ::FloconKtorPlugin val shouldLogCallback = pluginConfig.shouldLog // Intercept requests - client.sendPipeline.intercept(HttpSendPipeline.Monitoring) { - val floconNetworkPlugin = FloconApp.instance?.client?.networkPlugin - val request: HttpRequestBuilder = context - - if (floconNetworkPlugin == null || !shouldLogCallback(request)) { - request.attributes.put(FLOCON_SHOULD_LOG, false) - proceed() - return@intercept - } - - val floconCallId = Uuid.random().toString() - val floconNetworkType = "http" - val requestedAt = currentTimeMillis() - - // Reads the body without consuming it - val requestBodyString = extractAndReplaceRequestBody(request) - val requestSize = requestBodyString?.encodeToByteArray()?.size?.toLong() - val requestHeadersMap = - request.headers.entries().associate { it.key to it.value.joinToString(",") } - - val mockConfig = findMock(request, floconNetworkPlugin) - val isMocked = mockConfig != null - - val floconNetworkRequest = FloconNetworkRequest( - url = request.url.toString(), - method = request.method.value, - startTime = requestedAt, - headers = requestHeadersMap, - body = requestBodyString, - size = requestSize, - isMocked = isMocked - ) - - floconNetworkPlugin.logRequest( - FloconNetworkCallRequest( - floconCallId = floconCallId, - floconNetworkType = floconNetworkType, - isMocked = isMocked, - request = floconNetworkRequest - ) - ) - - val startTime = currentTimeNanos() - request.attributes.put(FLOCON_CALL_ID_KEY, floconCallId) - request.attributes.put(FLOCON_START_TIME_KEY, startTime) - request.attributes.put(FLOCON_IS_MOCKED_KEY, isMocked) - - try { - if (isMocked) { - val fakeCall = executeMock(client = theClient, request = request, mock = mockConfig) - proceedWith(fakeCall) - return@intercept - } - - floconNetworkPlugin.badQualityConfig?.let { badQualityConfig -> - executeBadQuality( - badQualityConfig = badQualityConfig, - client = theClient, - request = request - ) - } ?: run { - proceed() - } - } catch (t: Throwable) { - val endTime = currentTimeNanos() - - val durationMs: Double = (endTime - startTime) / 1e6 - - val floconCallResponse = FloconNetworkResponse( - httpCode = null, - contentType = null, - body = null, - headers = emptyMap(), - size = null, - grpcStatus = null, - error = t.message ?: t::class.simpleName ?: "Unknown", - requestHeaders = requestHeadersMap, - isImage = false, - ) - - floconNetworkPlugin.logResponse( - FloconNetworkCallResponse( - floconCallId = floconCallId, - durationMs = durationMs, - floconNetworkType = floconNetworkType, - isMocked = isMocked, - response = floconCallResponse, - ) - ) - throw t - } - } - - // Intercepts responses - client.receivePipeline.intercept(HttpReceivePipeline.After) { response -> - val floconNetworkPlugin = FloconApp.instance?.client?.networkPlugin ?: return@intercept - - val savedCall = response.call.save() - val savedResponse = savedCall.response - val call = response.call - val request: HttpRequest = call.request - - val floconShouldLog = request.attributes.getOrNull(FLOCON_SHOULD_LOG) ?: true - if(!floconShouldLog) { - proceed() - return@intercept - } - - val floconCallId = request.attributes.getOrNull(FLOCON_CALL_ID_KEY) ?: return@intercept - val startTime = request.attributes.getOrNull(FLOCON_START_TIME_KEY) ?: return@intercept - val isMocked = request.attributes.getOrNull(FLOCON_IS_MOCKED_KEY) ?: false - - val endTime = currentTimeNanos() - val durationMs = (endTime - startTime) / 1e6 - - val originalBodyBytes = response.bodyAsChannel().toByteArray() - val responseSize = originalBodyBytes.size.toLong() - - val responseHeadersMap = - response.headers.entries().associate { it.key to it.value.joinToString(",") } - val contentType = response.contentType()?.toString() - - val requestHeadersMap = - request.headers.entries().associate { it.key to it.value.joinToString(",") } - - val isImage = contentType?.startsWith("image/") == true || isImageCallback?.invoke( - FloconNetworkIsImageParams( - request = request, - response = response, - responseContentType = contentType, - ) - ) == true - - val floconCallResponse = FloconNetworkResponse( - httpCode = response.status.value, - contentType = contentType, - body = if (isImage) null else { - if (responseHeadersMap.isBrotli()) { - decodeNetworkBody(originalBodyBytes, responseHeadersMap) - } else { - originalBodyBytes.decodeToString() - } - }, - headers = responseHeadersMap, - size = responseSize, - grpcStatus = null, - error = null, - requestHeaders = requestHeadersMap, - isImage = isImage, - ) - - floconNetworkPlugin.logResponse( - FloconNetworkCallResponse( - floconCallId = floconCallId, - durationMs = durationMs, - floconNetworkType = "http", - isMocked = isMocked, - response = floconCallResponse - ) - ) - - proceedWith(savedResponse) - } +// client.sendPipeline.intercept(HttpSendPipeline.Monitoring) { +// val floconNetworkPlugin = FloconApp.instance?.client?.networkPlugin +// val request: HttpRequestBuilder = context +// +// if (floconNetworkPlugin == null || !shouldLogCallback(request)) { +// request.attributes.put(FLOCON_SHOULD_LOG, false) +// proceed() +// return@intercept +// } +// +// val floconCallId = Uuid.random().toString() +// val floconNetworkType = "http" +// val requestedAt = currentTimeMillis() +// +// // Reads the body without consuming it +// val requestBodyString = extractAndReplaceRequestBody(request) +// val requestSize = requestBodyString?.encodeToByteArray()?.size?.toLong() +// val requestHeadersMap = +// request.headers.entries().associate { it.key to it.value.joinToString(",") } +// +// val mockConfig = findMock(request, floconNetworkPlugin) +// val isMocked = mockConfig != null +// +// val floconNetworkRequest = FloconNetworkRequest( +// url = request.url.toString(), +// method = request.method.value, +// startTime = requestedAt, +// headers = requestHeadersMap, +// body = requestBodyString, +// size = requestSize, +// isMocked = isMocked +// ) +// +// floconNetworkPlugin.logRequest( +// FloconNetworkCallRequest( +// floconCallId = floconCallId, +// floconNetworkType = floconNetworkType, +// isMocked = isMocked, +// request = floconNetworkRequest +// ) +// ) +// +// val startTime = currentTimeNanos() +// request.attributes.put(FLOCON_CALL_ID_KEY, floconCallId) +// request.attributes.put(FLOCON_START_TIME_KEY, startTime) +// request.attributes.put(FLOCON_IS_MOCKED_KEY, isMocked) +// +// try { +// if (isMocked) { +// val fakeCall = executeMock(client = theClient, request = request, mock = mockConfig) +// proceedWith(fakeCall) +// return@intercept +// } +// +// floconNetworkPlugin.badQualityConfig?.let { badQualityConfig -> +// executeBadQuality( +// badQualityConfig = badQualityConfig, +// client = theClient, +// request = request +// ) +// } ?: run { +// proceed() +// } +// } catch (t: Throwable) { +// val endTime = currentTimeNanos() +// +// val durationMs: Double = (endTime - startTime) / 1e6 +// +// val floconCallResponse = FloconNetworkResponse( +// httpCode = null, +// contentType = null, +// body = null, +// headers = emptyMap(), +// size = null, +// grpcStatus = null, +// error = t.message ?: t::class.simpleName ?: "Unknown", +// requestHeaders = requestHeadersMap, +// isImage = false, +// ) +// +// floconNetworkPlugin.logResponse( +// FloconNetworkCallResponse( +// floconCallId = floconCallId, +// durationMs = durationMs, +// floconNetworkType = floconNetworkType, +// isMocked = isMocked, +// response = floconCallResponse, +// ) +// ) +// throw t +// } +// } +// +// // Intercepts responses +// client.receivePipeline.intercept(HttpReceivePipeline.After) { response -> +// val floconNetworkPlugin = FloconApp.instance?.client?.networkPlugin ?: return@intercept +// +// val savedCall = response.call.save() +// val savedResponse = savedCall.response +// val call = response.call +// val request: HttpRequest = call.request +// +// val floconShouldLog = request.attributes.getOrNull(FLOCON_SHOULD_LOG) ?: true +// if(!floconShouldLog) { +// proceed() +// return@intercept +// } +// +// val floconCallId = request.attributes.getOrNull(FLOCON_CALL_ID_KEY) ?: return@intercept +// val startTime = request.attributes.getOrNull(FLOCON_START_TIME_KEY) ?: return@intercept +// val isMocked = request.attributes.getOrNull(FLOCON_IS_MOCKED_KEY) ?: false +// +// val endTime = currentTimeNanos() +// val durationMs = (endTime - startTime) / 1e6 +// +// val originalBodyBytes = response.bodyAsChannel().toByteArray() +// val responseSize = originalBodyBytes.size.toLong() +// +// val responseHeadersMap = +// response.headers.entries().associate { it.key to it.value.joinToString(",") } +// val contentType = response.contentType()?.toString() +// +// val requestHeadersMap = +// request.headers.entries().associate { it.key to it.value.joinToString(",") } +// +// val isImage = contentType?.startsWith("image/") == true || isImageCallback?.invoke( +// FloconNetworkIsImageParams( +// request = request, +// response = response, +// responseContentType = contentType, +// ) +// ) == true +// +// val floconCallResponse = FloconNetworkResponse( +// httpCode = response.status.value, +// contentType = contentType, +// body = if (isImage) null else { +// if (responseHeadersMap.isBrotli()) { +// decodeNetworkBody(originalBodyBytes, responseHeadersMap) +// } else { +// originalBodyBytes.decodeToString() +// } +// }, +// headers = responseHeadersMap, +// size = responseSize, +// grpcStatus = null, +// error = null, +// requestHeaders = requestHeadersMap, +// isImage = isImage, +// ) +// +// floconNetworkPlugin.logResponse( +// FloconNetworkCallResponse( +// floconCallId = floconCallId, +// durationMs = durationMs, +// floconNetworkType = "http", +// isMocked = isMocked, +// response = floconCallResponse +// ) +// ) +// +// proceedWith(savedResponse) +// } } fun HttpClientConfig<*>.floconInterceptor() { diff --git a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt b/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt index 03c06c009..57f0da6a8 100644 --- a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt +++ b/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt @@ -1,7 +1,7 @@ package io.github.openflocon.flocon.ktor -import io.github.openflocon.flocon.plugins.network.FloconNetworkPlugin -import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse import io.ktor.client.HttpClient import io.ktor.client.call.HttpClientCall import io.ktor.client.request.HttpRequestBuilder @@ -13,14 +13,12 @@ import io.ktor.util.date.GMTDate import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.InternalAPI import kotlinx.coroutines.delay -import kotlin.collections.component1 -import kotlin.collections.component2 internal fun findMock( request: HttpRequestBuilder, floconNetworkPlugin: FloconNetworkPlugin, ): MockNetworkResponse? { - val url = request.url.toString() + val url = request.url.toString() val method = request.method.value return floconNetworkPlugin.mocks.firstOrNull { it.expectation.matches( @@ -40,7 +38,7 @@ internal suspend fun executeMock( delay(mock.response.delay) } - when(val response = mock.response) { + when (val response = mock.response) { is MockNetworkResponse.Response.Body -> { val bodyBytes = response.body.encodeToByteArray() val headers = HeadersBuilder().apply { @@ -58,6 +56,7 @@ internal suspend fun executeMock( return HttpClientCall(client, request.build(), responseData) } + is MockNetworkResponse.Response.ErrorThrow -> { val error = response.generate() if (error != null) { diff --git a/FloconAndroid/okhttp-interceptor/build.gradle.kts b/FloconAndroid/okhttp-interceptor/build.gradle.kts index 118ccbcbd..5388747f0 100644 --- a/FloconAndroid/okhttp-interceptor/build.gradle.kts +++ b/FloconAndroid/okhttp-interceptor/build.gradle.kts @@ -41,7 +41,7 @@ kotlin { dependencies { - implementation(project(":flocon-base")) + implementation(project(":flocon")) implementation(platform(libs.kotlinx.coroutines.bom)) implementation(libs.jetbrains.kotlinx.coroutines.core) diff --git a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt b/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt index ec62b25dc..35c443ef4 100644 --- a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt +++ b/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.okhttp -import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.Protocol import okhttp3.Request @@ -36,7 +36,8 @@ internal fun failResponseIfNeeded( badQualityConfig.selectRandomError()?.let { selectedError -> when (val t = selectedError.type) { is BadQualityConfig.Error.Type.Body -> { - val errorBody = t.errorBody.toResponseBody(t.errorContentType.toMediaTypeOrNull()) + val errorBody = + t.errorBody.toResponseBody(t.errorContentType.toMediaTypeOrNull()) return Response.Builder() .request(request) diff --git a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt b/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt index 8ded87c24..b09e3f3ac 100644 --- a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt +++ b/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt @@ -1,12 +1,12 @@ package io.github.openflocon.flocon.okhttp -import io.github.openflocon.flocon.plugins.network.FloconNetworkPlugin -import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.Protocol import okhttp3.Request import okhttp3.Response -import okhttp3.Response.* +import okhttp3.Response.Builder import okhttp3.ResponseBody.Companion.toResponseBody import okio.Buffer import okio.GzipSink @@ -17,7 +17,7 @@ internal fun findMock( request: Request, floconNetworkPlugin: FloconNetworkPlugin, ): MockNetworkResponse? { - val url = request.url.toString() + val url = request.url.toString() val method = request.method return floconNetworkPlugin.mocks.firstOrNull { it.expectation.matches( @@ -28,7 +28,11 @@ internal fun findMock( } @Throws(IOException::class) -internal fun executeMock(request: Request, requestHeaders: Map, mock: MockNetworkResponse): Response { +internal fun executeMock( + request: Request, + requestHeaders: Map, + mock: MockNetworkResponse +): Response { if (mock.response.delay > 0) { try { Thread.sleep(mock.response.delay) @@ -37,13 +41,14 @@ internal fun executeMock(request: Request, requestHeaders: Map, } } - when(val response = mock.response) { + when (val response = mock.response) { is MockNetworkResponse.Response.Body -> { val mediaType = response.mediaType.toMediaTypeOrNull() var bodyBytes = response.body.toByteArray() // TODO maybe check the mocked response headers - val isGzipped = requestHeaders["Accept-Encoding"] == "gzip" || requestHeaders["accept-encoding"] == "gzip" + val isGzipped = + requestHeaders["Accept-Encoding"] == "gzip" || requestHeaders["accept-encoding"] == "gzip" if (isGzipped) { val buffer = Buffer() diff --git a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt b/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt index 5312cd0a9..88e0cf095 100644 --- a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt +++ b/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt @@ -2,13 +2,8 @@ package io.github.openflocon.flocon.okhttp -import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest -import io.github.openflocon.flocon.plugins.network.model.FloconNetworkResponse +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest import okhttp3.Interceptor -import okhttp3.MediaType import okhttp3.Request import okhttp3.Response import java.io.IOException @@ -28,14 +23,14 @@ class FloconOkhttpInterceptor( @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { - val floconNetworkPlugin = FloconApp.instance?.client?.networkPlugin + val floconNetworkPlugin = TODO()//FloconApp.instance?.client?.networkPlugin if (floconNetworkPlugin == null || !shouldLog(chain)) { // on no op, do not intercept the call, just execute it return chain.proceed(chain.request()) } - val floconCallId = Uuid.random().toString() - val floconNetworkType = "http" + Uuid.random().toString() + "http" val request = chain.request() @@ -65,7 +60,7 @@ class FloconOkhttpInterceptor( ) val isMocked = mockConfig != null - val floconNetworkRequest = FloconNetworkRequest( + FloconNetworkRequest( url = request.url.toString(), method = request.method, startTime = requestedAt, @@ -75,86 +70,87 @@ class FloconOkhttpInterceptor( isMocked = isMocked, ) - floconNetworkPlugin.logRequest( - FloconNetworkCallRequest( - floconCallId = floconCallId, - floconNetworkType = floconNetworkType, - isMocked = isMocked, - request = floconNetworkRequest, - ) - ) +// floconNetworkPlugin.logRequest( +// FloconNetworkCallRequest( +// floconCallId = floconCallId, +// floconNetworkType = floconNetworkType, +// isMocked = isMocked, +// request = floconNetworkRequest, +// ) +// ) try { - val response = if (isMocked) { - executeMock(request = request, mock = mockConfig, requestHeaders = requestHeadersMap) - } else { - floconNetworkPlugin.badQualityConfig?.let { badQualityConfig -> - executeBadQuality( - badQualityConfig = badQualityConfig, - request = request, - ) - } ?: run { - chain.proceed(request) - } - } + val response = TODO() +// if (isMocked) { +// executeMock(request = request, mock = mockConfig, requestHeaders = requestHeadersMap) +// } else { +// floconNetworkPlugin.badQualityConfig?.let { badQualityConfig -> +// executeBadQuality( +// badQualityConfig = badQualityConfig, +// request = request, +// ) +// } ?: run { +// chain.proceed(request) +// } +// } val endTime = System.nanoTime() - val durationMs: Double = (endTime - startTime) / 1e6 + (endTime - startTime) / 1e6 // To get the response body, be careful // because the body can only be read once. // It must be duplicated so that the chain can continue normally. - val responseBody = response.body - var responseBodyString: String? = null - var responseSize: Long? = null - val responseContentType: MediaType? = responseBody?.contentType() - - val responseHeadersMap = - response.headers.toMultimap().mapValues { it.value.joinToString(",") } - - if (responseBody != null) { - val (bodyString, bodySize) = extractResponseBodyInfo( - response = response, - responseHeaders = responseHeadersMap, - ) - responseBodyString = bodyString - responseSize = bodySize - } - - val isImage = - responseContentType?.toString()?.startsWith("image/") == true || (isImage?.invoke( - FloconNetworkIsImageParams( - request = request, - response = response, - responseContentType = responseContentType?.toString(), - ) - ) == true) - - val requestHeadersMapUpToDate = - response.request.headers.toMultimap().mapValues { it.value.joinToString(",") } - - val floconCallResponse = FloconNetworkResponse( - httpCode = response.code, - contentType = responseContentType?.toString(), - body = responseBodyString.takeUnless { isImage }, // dont send images responses bytes - headers = responseHeadersMap, - size = responseSize, - grpcStatus = null, - error = null, - requestHeaders = requestHeadersMapUpToDate, - isImage = isImage, - ) - - floconNetworkPlugin.logResponse( - FloconNetworkCallResponse( - floconCallId = floconCallId, - durationMs = durationMs, - floconNetworkType = floconNetworkType, - isMocked = isMocked, - response = floconCallResponse, - ) - ) +// val responseBody = response.body +// var responseBodyString: String? = null +// var responseSize: Long? = null +// val responseContentType: MediaType? = responseBody?.contentType() +// +// val responseHeadersMap = +// response.headers.toMultimap().mapValues { it.value.joinToString(",") } +// +// if (responseBody != null) { +// val (bodyString, bodySize) = extractResponseBodyInfo( +// response = response, +// responseHeaders = responseHeadersMap, +// ) +// responseBodyString = bodyString +// responseSize = bodySize +// } + +// val isImage = +// responseContentType?.toString()?.startsWith("image/") == true || (isImage?.invoke( +// FloconNetworkIsImageParams( +// request = request, +// response = response, +// responseContentType = responseContentType?.toString(), +// ) +// ) == true) +// +// val requestHeadersMapUpToDate = +// response.request.headers.toMultimap().mapValues { it.value.joinToString(",") } +// +// val floconCallResponse = FloconNetworkResponse( +// httpCode = response.code, +// contentType = responseContentType?.toString(), +// body = responseBodyString.takeUnless { isImage }, // dont send images responses bytes +// headers = responseHeadersMap, +// size = responseSize, +// grpcStatus = null, +// error = null, +// requestHeaders = requestHeadersMapUpToDate, +// isImage = isImage, +// ) +// +// floconNetworkPlugin.logResponse( +// FloconNetworkCallResponse( +// floconCallId = floconCallId, +// durationMs = durationMs, +// floconNetworkType = floconNetworkType, +// isMocked = isMocked, +// response = floconCallResponse, +// ) +// ) // Rebuild the response with a new body so that the chain can continue // The original response body is already consumed by peekBody, so no need to rebuild with it. @@ -164,29 +160,29 @@ class FloconOkhttpInterceptor( val endTime = System.nanoTime() - val durationMs: Double = (endTime - startTime) / 1e6 - - val floconCallResponse = FloconNetworkResponse( - httpCode = null, - contentType = null, - body = null, - headers = emptyMap(), - size = null, - grpcStatus = null, - error = e.message ?: e.javaClass.simpleName, - requestHeaders = null, - isImage = false, - ) - - floconNetworkPlugin.logResponse( - FloconNetworkCallResponse( - floconCallId = floconCallId, - durationMs = durationMs, - floconNetworkType = floconNetworkType, - isMocked = isMocked, - response = floconCallResponse, - ) - ) + (endTime - startTime) / 1e6 + +// val floconCallResponse = FloconNetworkResponse( +// httpCode = null, +// contentType = null, +// body = null, +// headers = emptyMap(), +// size = null, +// grpcStatus = null, +// error = e.message ?: e.javaClass.simpleName, +// requestHeaders = null, +// isImage = false, +// ) + +// floconNetworkPlugin.logResponse( +// FloconNetworkCallResponse( +// floconCallId = floconCallId, +// durationMs = durationMs, +// floconNetworkType = floconNetworkType, +// isMocked = isMocked, +// response = floconCallResponse, +// ) +// ) throw e } } diff --git a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt b/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt index 4d02a7d01..d7208acbf 100644 --- a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt +++ b/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt @@ -1,9 +1,7 @@ package io.github.openflocon.flocon.okhttp.websocket import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.plugins.network.floconLogWebSocketEvent -import io.github.openflocon.flocon.plugins.network.model.FloconWebSocketEvent -import io.github.openflocon.flocon.plugins.network.model.FloconWebSocketMockListener +import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent import okhttp3.Response import okhttp3.WebSocket import okhttp3.WebSocketListener @@ -19,15 +17,15 @@ object FloconWebSocket { error: Throwable? = null, ) { val size = message?.toByteArray()?.size?.toLong() - floconLogWebSocketEvent( - FloconWebSocketEvent( - websocketUrl = webSocket.request().url.toString(), - event = event, - message = message, - error = error, - size = size ?: 0L, - ) - ) +// floconLogWebSocketEvent( +// FloconWebSocketEvent( +// websocketUrl = webSocket.request().url.toString(), +// event = event, +// message = message, +// error = error, +// size = size ?: 0L, +// ) +// ) } fun send(webSocket: WebSocket, text: String) : Boolean { @@ -53,13 +51,13 @@ object FloconWebSocket { private var websocketRef : WeakReference? = null init { - FloconApp.instance?.client?.networkPlugin?.registerWebSocketMockListener(id = id, listener = object: FloconWebSocketMockListener { - override fun onMessage(message: String) { - websocketRef?.get()?.let { websocket -> - onMessage(websocket, message) - } - } - }) +// FloconApp.instance?.client?.networkPlugin?.registerWebSocketMockListener(id = id, listener = object: FloconWebSocketMockListener { +// override fun onMessage(message: String) { +// websocketRef?.get()?.let { websocket -> +// onMessage(websocket, message) +// } +// } +// }) } override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt index 8f0737c2f..ce99fa234 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt @@ -20,39 +20,22 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp -import io.github.openflocon.flocon.Flocon -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.myapplication.dashboard.initializeDashboard +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.myapplication.database.DogDatabase -import io.github.openflocon.flocon.myapplication.database.initializeDatabases import io.github.openflocon.flocon.myapplication.database.initializeInMemoryDatabases import io.github.openflocon.flocon.myapplication.database.model.DogEntity -import io.github.openflocon.flocon.myapplication.deeplinks.initializeDeeplinks -import io.github.openflocon.flocon.myapplication.graphql.GraphQlTester import io.github.openflocon.flocon.myapplication.grpc.GrpcController -import io.github.openflocon.flocon.myapplication.images.initializeImages -import io.github.openflocon.flocon.myapplication.sharedpreferences.initializeDatastores -import io.github.openflocon.flocon.myapplication.sharedpreferences.initializeSharedPreferences -import io.github.openflocon.flocon.myapplication.sharedpreferences.initializeSharedPreferencesAfterInit -import io.github.openflocon.flocon.myapplication.table.initializeTable import io.github.openflocon.flocon.myapplication.ui.ImagesListView import io.github.openflocon.flocon.myapplication.ui.theme.MyApplicationTheme -import io.github.openflocon.flocon.okhttp.FloconOkhttpInterceptor -import io.github.openflocon.flocon.plugins.analytics.analytics -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsEvent -import io.github.openflocon.flocon.plugins.analytics.model.analyticsProperty -import io.github.openflocon.flocon.plugins.tables.model.toParam -import io.github.openflocon.flocon.plugins.tables.table +import io.github.openflocon.flocon.startFlocon import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch -import okhttp3.OkHttpClient -import kotlin.uuid.Uuid import kotlin.random.Random import kotlin.uuid.ExperimentalUuidApi class MainActivity : ComponentActivity() { - lateinit var inMemoryDb : DogDatabase + lateinit var inMemoryDb: DogDatabase override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -62,38 +45,41 @@ class MainActivity : ComponentActivity() { Toast.makeText(this, "opend with : $it", Toast.LENGTH_LONG).show() } - val okHttpClient = OkHttpClient() - .newBuilder() - .addInterceptor(FloconOkhttpInterceptor( - isImage = { - it.request.url.toString().contains("picsum") - }, - /*shouldLog = { - val url = it.request().url.toString() - println("url: $url") - url.contains("1").not() - }*/ - )) - .build() - - initializeSharedPreferences(applicationContext) - initializeDatabases(context = applicationContext) - - FloconLogger.enabled = true - Flocon.initialize(this) - initializeDeeplinks() +// val okHttpClient = OkHttpClient() +// .newBuilder() +// .addInterceptor( +// FloconOkhttpInterceptor( +// isImage = { +// it.request.url.toString().contains("picsum") +// }, +// /*shouldLog = { +// val url = it.request().url.toString() +// println("url: $url") +// url.contains("1").not() +// }*/ +// ) +// ) +// .build() + +// initializeSharedPreferences(applicationContext) +// initializeDatabases(context = applicationContext) + +// FloconLogger.enabled = true +// Flocon.initialize(this) inMemoryDb = initializeInMemoryDatabases(applicationContext) - initializeSharedPreferencesAfterInit(applicationContext) - initializeDatastores(applicationContext) +// initializeSharedPreferencesAfterInit(applicationContext) +// initializeDatastores(applicationContext) - val dummyHttpCaller = DummyHttpCaller(client = okHttpClient) - val dummyWebsocketCaller = DummyWebsocketCaller(client = okHttpClient) - GlobalScope.launch { dummyWebsocketCaller.connectToWebsocket() } - val graphQlTester = GraphQlTester(client = okHttpClient) - initializeImages(context = this, okHttpClient = okHttpClient) - initializeDashboard(this) - initializeTable(this) +// val dummyHttpCaller = DummyHttpCaller(client = okHttpClient) +// val dummyWebsocketCaller = DummyWebsocketCaller(client = okHttpClient) +// GlobalScope.launch { dummyWebsocketCaller.connectToWebsocket() } +// val graphQlTester = GraphQlTester(client = okHttpClient) +// initializeImages(context = this, okHttpClient = okHttpClient) +// initializeDashboard(this) +// initializeTable(this) + + initFlocon() setContent { MyApplicationTheme { @@ -101,7 +87,11 @@ class MainActivity : ComponentActivity() { val scope = rememberCoroutineScope() val context = LocalContext.current - Column(Modifier.fillMaxSize().padding(innerPadding)) { + Column( + Modifier + .fillMaxSize() + .padding(innerPadding) + ) { FlowRow( modifier = Modifier .fillMaxWidth() @@ -111,14 +101,14 @@ class MainActivity : ComponentActivity() { ) { Button( onClick = { - dummyHttpCaller.call() + //dummyHttpCaller.call() } ) { Text("okhttp test") } Button( onClick = { - dummyHttpCaller.callGzip() + //dummyHttpCaller.callGzip() } ) { Text("okhttp gzip test") @@ -126,7 +116,7 @@ class MainActivity : ComponentActivity() { Button( onClick = { GlobalScope.launch { - graphQlTester.fetchViewerInfo() + //graphQlTester.fetchViewerInfo() } } ) { @@ -150,7 +140,7 @@ class MainActivity : ComponentActivity() { } Button( onClick = { - dummyWebsocketCaller.send(Uuid.random().toString()) + //dummyWebsocketCaller.send(Uuid.random().toString()) } ) { Text("websocket test") @@ -164,32 +154,32 @@ class MainActivity : ComponentActivity() { } Button( onClick = { - val value = Random.nextInt(from = 0, until = 1000).toString() - Flocon.table("analytics").log( - "name" toParam "new name $value", - "value1" toParam "value1 $value", - "value2" toParam "value2 $value", - ) + Random.nextInt(from = 0, until = 1000).toString() +// Flocon.table("analytics").log( +// "name" toParam "new name $value", +// "value1" toParam "value1 $value", +// "value2" toParam "value2 $value", +// ) } ) { Text("send table event") } Button( onClick = { - Flocon.analytics("firebase").logEvents( - AnalyticsEvent( - eventName = "clicked user", - "userId" analyticsProperty "1024", - "username" analyticsProperty "florent", - "index" analyticsProperty "3", - ), - AnalyticsEvent( - eventName = "opened profile", - "userId" analyticsProperty "2048", - "username" analyticsProperty "kevin", - "age" analyticsProperty "34", - ), - ) +// Flocon.analytics("firebase").logEvents( +// AnalyticsEvent( +// eventName = "clicked user", +// "userId" analyticsProperty "1024", +// "username" analyticsProperty "florent", +// "index" analyticsProperty "3", +// ), +// AnalyticsEvent( +// eventName = "opened profile", +// "userId" analyticsProperty "2048", +// "username" analyticsProperty "kevin", +// "age" analyticsProperty "34", +// ), +// ) } ) { Text("send analytics event") @@ -219,4 +209,25 @@ class MainActivity : ComponentActivity() { } } } + + private fun initFlocon() { + startFlocon(FloconContext(this)) { +// install(FloconDeeplinks) { +// register("flocon://home") +// register("flocon://test") +// register( +// "flocon://user/[userId]", +// label = "User" +// ) { +// param("userId", listOf("Florent", "David", "Guillaume")) +// } +// register( +// "flocon://post/[postId]?comment=[commentText]", +// label = "Post", +// description = "Open a post and send a comment" +// ) +// } + } + } + } \ No newline at end of file diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/dashboard/InitializeDashboard.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/dashboard/InitializeDashboard.kt index 02777a5af..bc472fa48 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/dashboard/InitializeDashboard.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/dashboard/InitializeDashboard.kt @@ -6,20 +6,20 @@ import androidx.activity.ComponentActivity import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.lifecycle.lifecycleScope +import com.apollographql.apollo.api.label import io.github.openflocon.flocon.myapplication.dashboard.device.deviceFlow import io.github.openflocon.flocon.myapplication.dashboard.device.initializeDeviceFlow import io.github.openflocon.flocon.myapplication.dashboard.tokens.tokensFlow import io.github.openflocon.flocon.myapplication.dashboard.user.userFlow -import io.github.openflocon.flocon.plugins.dashboard.dsl.button -import io.github.openflocon.flocon.plugins.dashboard.dsl.checkBox -import io.github.openflocon.flocon.plugins.dashboard.dsl.html -import io.github.openflocon.flocon.plugins.dashboard.dsl.json -import io.github.openflocon.flocon.plugins.dashboard.dsl.label -import io.github.openflocon.flocon.plugins.dashboard.dsl.markdown -import io.github.openflocon.flocon.plugins.dashboard.dsl.plainText -import io.github.openflocon.flocon.plugins.dashboard.dsl.text -import io.github.openflocon.flocon.plugins.dashboard.dsl.textField import io.github.openflocon.flocon.plugins.dashboard.floconDashboard +import io.github.openflocon.flocon.pluginsold.dashboard.dsl.button +import io.github.openflocon.flocon.pluginsold.dashboard.dsl.checkBox +import io.github.openflocon.flocon.pluginsold.dashboard.dsl.html +import io.github.openflocon.flocon.pluginsold.dashboard.dsl.json +import io.github.openflocon.flocon.pluginsold.dashboard.dsl.markdown +import io.github.openflocon.flocon.pluginsold.dashboard.dsl.plainText +import io.github.openflocon.flocon.pluginsold.dashboard.dsl.text +import io.github.openflocon.flocon.pluginsold.dashboard.dsl.textField import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/DogDatabase.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/DogDatabase.kt index cce1719d3..c499b51df 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/DogDatabase.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/DogDatabase.kt @@ -8,7 +8,6 @@ import io.github.openflocon.flocon.myapplication.database.dao.DogDao import io.github.openflocon.flocon.myapplication.database.model.DogEntity import io.github.openflocon.flocon.myapplication.database.model.HumanEntity import io.github.openflocon.flocon.myapplication.database.model.HumanWithDogEntity -import io.github.openflocon.flocon.plugins.database.floconLogDatabaseQuery import java.util.concurrent.Executors @Database( @@ -30,17 +29,18 @@ abstract class DogDatabase : RoomDatabase() { fun getDatabase(context: Context): DogDatabase { val dbName = "dogs_database" return INSTANCE ?: synchronized(this) { - val instance = Room.databaseBuilder( - context.applicationContext, - DogDatabase::class.java, - dbName - ).setQueryCallback({ sqlQuery, bindArgs -> floconLogDatabaseQuery( - dbName = dbName, sqlQuery = sqlQuery, bindArgs = bindArgs - ) }, Executors.newSingleThreadExecutor()) - .fallbackToDestructiveMigration() - .build() - INSTANCE = instance - instance + TODO() +// val instance = Room.databaseBuilder( +// context.applicationContext, +// DogDatabase::class.java, +// dbName +// ).setQueryCallback({ sqlQuery, bindArgs -> floconLogDatabaseQuery( +// dbName = dbName, sqlQuery = sqlQuery, bindArgs = bindArgs +// ) }, Executors.newSingleThreadExecutor()) +// .fallbackToDestructiveMigration() +// .build() +// INSTANCE = instance +// instance } } } diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt index 2afc24fb1..b14bb0625 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt @@ -6,7 +6,7 @@ import io.github.openflocon.flocon.myapplication.database.model.DogEntity import io.github.openflocon.flocon.myapplication.database.model.FoodEntity import io.github.openflocon.flocon.myapplication.database.model.HumanEntity import io.github.openflocon.flocon.myapplication.database.model.HumanWithDogEntity -import io.github.openflocon.flocon.plugins.database.floconRegisterDatabase +import io.github.openflocon.flocon.pluginsold.database.floconRegisterDatabase import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/deeplinks/InitializeDeeplinks.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/deeplinks/InitializeDeeplinks.kt deleted file mode 100644 index b456c7acd..000000000 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/deeplinks/InitializeDeeplinks.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.openflocon.flocon.myapplication.deeplinks - -import io.github.openflocon.flocon.Flocon -import io.github.openflocon.flocon.plugins.deeplinks.deeplinks - -fun initializeDeeplinks() { - Flocon.deeplinks { - variable("test_variable") - variable("host") { - description = "Host variable" - autoComplete(listOf("flocon", "flocon2", "flocon3")) - } - deeplink("[host]://home") { - "host" withVariable "host" - } - deeplink("[host]://test") { - "host" withVariable "host" - } - deeplink("[host]://user/[userId]") { - label = "User" - "userId" withAutoComplete listOf("Florent", "David", "Guillaume") - "host" withVariable "host" - } - deeplink("[host]://post/[postId]?comment=[commentText]") { - label = "Post" - description = "Open a post and send a comment" - "commentText" withVariable "test_variable" - "host" withVariable "host" - } - } -} \ No newline at end of file diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/Datastores.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/Datastores.kt index 4b5fab96c..d6aefeec9 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/Datastores.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/Datastores.kt @@ -5,8 +5,6 @@ import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore -import io.github.openflocon.flocon.plugins.sharedprefs.floconRegisterPreference -import io.github.openflocon.flocon.preferences.datastores.model.FloconDatastorePreference import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch @@ -38,7 +36,7 @@ class Datastores(private val context: Context) { } init { - floconRegisterPreference(FloconDatastorePreference("datastore", context.dataStore)) + //floconRegisterPreference(FloconDatastorePreference("datastore", context.dataStore)) GlobalScope.launch { saveUsername("John Doe") saveUserAge(30) diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/SharedPreferences.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/SharedPreferences.kt index 681d24d91..051be10c0 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/SharedPreferences.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/SharedPreferences.kt @@ -3,12 +3,9 @@ package io.github.openflocon.flocon.myapplication.sharedpreferences import android.content.Context -import android.content.SharedPreferences import android.preference.PreferenceManager import androidx.core.content.edit -import io.github.openflocon.flocon.plugins.sharedprefs.FloconSharedPreference -import io.github.openflocon.flocon.plugins.sharedprefs.floconRegisterPreference -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.pluginsold.sharedprefs.FloconSharedPreference import org.json.JSONArray import org.json.JSONObject import kotlin.uuid.Uuid @@ -17,7 +14,7 @@ import kotlin.uuid.ExperimentalUuidApi fun initializeSharedPreferencesAfterInit(context: Context) { val referencedPref = context.getSharedPreferences("ref_pref", Context.MODE_PRIVATE) - floconRegisterPreference(FloconSharedPreference("my_custom_name", referencedPref)) + //floconRegisterPreference(FloconSharedPreference("my_custom_name", referencedPref)) referencedPref.edit { putString("works", "yes") diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeDashboard.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeDashboard.kt index 9784e3f66..7a5050f0c 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeDashboard.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeDashboard.kt @@ -1,14 +1,11 @@ package io.github.openflocon.flocon.myapplication.table import android.content.Context -import io.github.openflocon.flocon.Flocon -import io.github.openflocon.flocon.plugins.tables.model.toParam -import io.github.openflocon.flocon.plugins.tables.table fun initializeTable(context: Context) { - Flocon.table("analytics").log( - "name" toParam "nameValue", - "value1" toParam "value1Value", - "value2" toParam "value2Value", - ) +// Flocon.table("analytics").log( +// "name" toParam "nameValue", +// "value1" toParam "value1Value", +// "value2" toParam "value2Value", +// ) } \ No newline at end of file diff --git a/FloconAndroid/sample-multiplatform/build.gradle.kts b/FloconAndroid/sample-multiplatform/build.gradle.kts index e2aa52888..1cad46fc0 100644 --- a/FloconAndroid/sample-multiplatform/build.gradle.kts +++ b/FloconAndroid/sample-multiplatform/build.gradle.kts @@ -34,7 +34,6 @@ kotlin { val commonMain by getting { dependencies { implementation(project(":flocon")) - implementation(project(":flocon-base")) implementation(project(":ktor-interceptor")) implementation(libs.kotlinx.coroutines.core) diff --git a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt index 5cf459641..3ad3d762a 100644 --- a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt +++ b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt @@ -10,17 +10,12 @@ import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.ktor.FloconKtorPlugin import io.github.openflocon.flocon.myapplication.multi.Databases.getDogDatabase import io.github.openflocon.flocon.myapplication.multi.Databases.getFoodDatabase -import io.github.openflocon.flocon.myapplication.multi.database.FoodDatabase import io.github.openflocon.flocon.myapplication.multi.database.initializeDatabases -import io.github.openflocon.flocon.myapplication.multi.database.model.DogEntity import io.github.openflocon.flocon.myapplication.multi.sharedpreferences.initializeSharedPreferences import io.github.openflocon.flocon.myapplication.multi.ui.App import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks -import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinksPlugin import io.ktor.client.HttpClient import io.ktor.client.engine.okhttp.OkHttp -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index a0cd76fd5..4b3e4db49 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -14,10 +14,10 @@ dependencyResolutionManagement { } } -rootProject.name = "My Application" +rootProject.name = "Flocon Sample App" + include(":sample-android-only") include(":sample-multiplatform") -include(":flocon-base") include(":flocon") include(":flocon-no-op") include(":okhttp-interceptor") From dd9f914bcf93b831237a52cd88be8e590a96f2cc Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Wed, 11 Mar 2026 23:32:11 +0100 Subject: [PATCH 03/35] feat: Deeplinks --- .../sample-android-only/build.gradle.kts | 4 +++ .../flocon/myapplication/MainActivity.kt | 31 ++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/FloconAndroid/sample-android-only/build.gradle.kts b/FloconAndroid/sample-android-only/build.gradle.kts index 562891197..c8dc04fa9 100644 --- a/FloconAndroid/sample-android-only/build.gradle.kts +++ b/FloconAndroid/sample-android-only/build.gradle.kts @@ -83,6 +83,10 @@ dependencies { } else { debugImplementation(project(":flocon")) releaseImplementation(project(":flocon-no-op")) + + debugImplementation(project(":deeplinks")) + releaseImplementation(project(":deeplinks-no-op")) + debugImplementation(project(":okhttp-interceptor")) releaseImplementation(project(":okhttp-interceptor-no-op")) implementation(project(":grpc:grpc-interceptor-lite")) diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt index ce99fa234..3adc8f327 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt @@ -27,6 +27,7 @@ import io.github.openflocon.flocon.myapplication.database.model.DogEntity import io.github.openflocon.flocon.myapplication.grpc.GrpcController import io.github.openflocon.flocon.myapplication.ui.ImagesListView import io.github.openflocon.flocon.myapplication.ui.theme.MyApplicationTheme +import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks import io.github.openflocon.flocon.startFlocon import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -212,21 +213,21 @@ class MainActivity : ComponentActivity() { private fun initFlocon() { startFlocon(FloconContext(this)) { -// install(FloconDeeplinks) { -// register("flocon://home") -// register("flocon://test") -// register( -// "flocon://user/[userId]", -// label = "User" -// ) { -// param("userId", listOf("Florent", "David", "Guillaume")) -// } -// register( -// "flocon://post/[postId]?comment=[commentText]", -// label = "Post", -// description = "Open a post and send a comment" -// ) -// } + install(FloconDeeplinks) { + register("flocon://home") + register("flocon://test") + register( + "flocon://user/[userId]", + label = "User" + ) { + param("userId", listOf("Florent", "David", "Guillaume")) + } + register( + "flocon://post/[postId]?comment=[commentText]", + label = "Post", + description = "Open a post and send a comment" + ) + } } } From 5fc6ab7c6c3e2f708fa348a56f656cd5b0693fae Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Wed, 11 Mar 2026 23:50:34 +0100 Subject: [PATCH 04/35] feat: Need to fix install method --- .../plugins/deeplinks/FloconDeeplinks.kt | 3 +- .../io/github/openflocon/flocon/Flocon.kt | 22 ++--- .../io/github/openflocon/flocon/Flocon.kt | 82 ++++++++++++++++--- .../openflocon/flocon/FloconConfiguration.kt | 34 +++++++- .../github/openflocon/flocon/FloconPlugin.kt | 2 +- .../analytics/FloconAnalyticsPlugin.kt | 2 +- .../FloconCrashReporterPlugin.kt | 5 +- .../dashboard/FloconDashboardPlugin.kt | 2 +- .../plugins/database/FloconDatabasePlugin.kt | 2 +- .../plugins/device/FloconDevicePluginImpl.kt | 2 +- .../flocon/plugins/files/FloconFilesPlugin.kt | 2 +- .../network/FloconNetworkPluginImpl.kt | 2 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 2 +- .../plugins/tables/FloconTablesPlugin.kt | 2 +- .../analytics/FloconAnalyticsPlugin.kt | 5 +- .../database/FloconDatabasePlugin.kt | 5 +- .../pluginsold/device/FloconDevicePlugin.kt | 5 +- .../pluginsold/files/FloconFilesPlugin.kt | 5 +- .../pluginsold/network/FloconNetworkPlugin.kt | 5 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 5 +- .../pluginsold/tables/FloconTablesPlugin.kt | 5 +- 21 files changed, 129 insertions(+), 70 deletions(-) diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt index 3e2c697ea..3a33d6cae 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -10,7 +10,8 @@ object FloconDeeplinks : FloconPluginFactory Unit = {}) { - val configuration = FloconConfiguration().apply(block) - super.initializeFlocon( - context = FloconContext(context = context), - configuration = configuration - ) - } - -} +//object Flocon : FloconCore() { +// +// fun initialize(context: Context, block: FloconConfiguration.() -> Unit = {}) { +// val configuration = FloconConfiguration().apply(block) +// super.initializeFlocon( +// context = FloconContext(context = context), +// configuration = configuration +// ) +// } +// +//} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt index 411529ea7..97392a96f 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt @@ -1,16 +1,72 @@ package io.github.openflocon.flocon +import io.github.openflocon.flocon.FloconApp.Client import io.github.openflocon.flocon.client.FloconClientImpl -// -//internal class Flocon( -// private val context: FloconContext, -// private val plugins: List -//) { -// -// private val client = FloconClientImpl( -// context = context, -// configuration = FloconConfiguration(), -// plugins = plugins -// ) -// -//} \ No newline at end of file +import io.github.openflocon.flocon.core.FloconMessageSender +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +internal class Flocon( + private val context: FloconContext, + private val plugins: List +) { + + private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + + private val client = FloconClientImpl( + context = context, + configuration = FloconConfiguration(), + plugins = plugins + ) + + init { + scope.launch { + start( + client = client, + context = context, + ) + } + } + + private suspend fun start(client: Client, context: FloconContext) { + // try to connect, it fail : try again in 3s + try { + client.connect( + onClosed = { + println("Client - Closed") + // try again to connect + scope.launch { + start( + client = client, + context = context, + ) + } + } + ) + (client as? FloconMessageSender)?.let { + // if success, just send a bonjour + it.send("bonjour", method = "bonjour", body = "bonjour") + it.sendPendingMessages() + } + } catch (t: Throwable) { + if(t.message?.contains("CLEARTEXT communication to localhost not permitted by network security policy") == true) { + withContext(Dispatchers.Main) { + displayClearTextError(context = context) + } + } else { + //t.printStackTrace() + delay(3_000) + start( + client = client, + context = context, + ) + } + } + } + +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt index 993c9dce3..9f907afae 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -1,8 +1,13 @@ package io.github.openflocon.flocon +import io.github.openflocon.flocon.client.FloconClientImpl +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + class FloconConfiguration internal constructor() { - internal val pluginConfigs = mutableMapOf, Any>() + internal val pluginConfigs = mutableMapOf, Any>() /** * Install a plugin with the given [factory] and optional [configure] block. @@ -13,13 +18,34 @@ class FloconConfiguration internal constructor() { ) { val config = factory.createConfig() config.configure() - pluginConfigs[factory] = config + pluginConfigs[factory as FloconPluginFactory] = config // TODO } } fun startFlocon(context: FloconContext, block: FloconConfiguration.() -> Unit) { val configuration = FloconConfiguration().apply(block) - - + + Flocon( + context = context, + plugins = configuration.pluginConfigs.map { (factory, config) -> + factory.install( + config, + DumpObject( + FloconClientImpl(context, configuration, plugins = emptyList()) + ) + ) as FloconPlugin + } + ) +} + +class DumpObject( + client: Client +) : FloconApp() { + + override val client: Client = client + + private val _initialized = MutableStateFlow(false) + override val isInitialized: StateFlow = _initialized.asStateFlow() + } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt index 3a05b5b0b..b3e8e9177 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt @@ -36,5 +36,5 @@ interface FloconPluginFactory : FloconPlugin /** * Install the plugin into the [io.github.openflocon.flocon.FloconApp] instance with the given [config]. */ - fun install(config: Config, app: FloconApp): PluginInstance + fun install(config: Any, app: FloconApp): PluginInstance // TODO } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt index 91e19704f..2469db2b4 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -15,7 +15,7 @@ object FloconAnalytics : FloconPluginFactory { override val name: String = "Files" override val pluginId: String = Protocol.ToDevice.Files.Plugin override fun createConfig() = FloconFilesConfig() - override fun install(config: FloconFilesConfig, app: FloconApp): FloconFilesPlugin { + override fun install(config: Any, app: FloconApp): FloconFilesPlugin { val client = app.client return FloconFilesPluginImpl( context = app.context, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt index b6d4d9048..25c107c77 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt @@ -35,7 +35,7 @@ object FloconNetwork : FloconPluginFactory { override fun createConfig(): FloconAnalyticsConfig = TODO() - override fun install( - config: FloconAnalyticsConfig, - app: FloconApp - ): FloconAnalyticsPlugin = TODO() + override fun install(config: Any, app: FloconApp): FloconAnalyticsPlugin = TODO() override val name: String = "" } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt index 36a04ae60..95313a4a8 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt @@ -16,10 +16,7 @@ object FloconDatabase : FloconPluginFactory { TODO("Not yet implemented") } - override fun install( - config: FloconFilesConfig, - app: FloconApp - ): FloconFilesPlugin { + override fun install(config: Any, app: FloconApp): FloconFilesPlugin { TODO("Not yet implemented") } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt index f498f2255..7b23222fa 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt @@ -21,10 +21,7 @@ class FloconNetworkConfig { */ object FloconNetwork : FloconPluginFactory { override fun createConfig(): FloconNetworkConfig = TODO() - override fun install( - config: FloconNetworkConfig, - app: FloconApp - ): FloconNetworkPlugin = TODO() + override fun install(config: Any, app: FloconApp): FloconNetworkPlugin = TODO() override val name: String = "" } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt index 111ff7278..91324e681 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt @@ -14,10 +14,7 @@ object FloconPreferences : FloconPluginFactory { TODO("Not yet implemented") } - override fun install( - config: FloconTableConfig, - app: FloconApp - ): FloconTablePlugin { + override fun install(config: Any, app: FloconApp): FloconTablePlugin { TODO("Not yet implemented") } From fd3457fc25750dfb70a13568808cd4b8aed575b9 Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Thu, 12 Mar 2026 10:54:14 +0100 Subject: [PATCH 05/35] feat: Make deeplink works --- .../plugins/deeplinks/FloconDeeplinks.kt | 18 +++- .../io/github/openflocon/flocon/Flocon.kt | 36 ++++--- .../io/github/openflocon/flocon/FloconApp.kt | 25 +---- .../openflocon/flocon/FloconConfiguration.kt | 15 ++- .../io/github/openflocon/flocon/FloconCore.kt | 3 +- .../flocon/client/FloconClientImpl.kt | 100 +++++++++++++++++- 6 files changed, 154 insertions(+), 43 deletions(-) diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt index 3a33d6cae..ca4dab195 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -1,6 +1,10 @@ package io.github.openflocon.flocon.plugins.deeplinks -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel import kotlinx.coroutines.flow.MutableStateFlow @@ -11,6 +15,7 @@ object FloconDeeplinks : FloconPluginFactory) { - this.deeplinks.update { - deeplinks - } + this.deeplinks.update { deeplinks } try { + println("Deeplinks: sending") sender.send( plugin = Protocol.FromDevice.Deeplink.Plugin, method = Protocol.FromDevice.Deeplink.Method.GetDeeplinks, body = toDeeplinksJson(deeplinks) ) + println("Deeplinks: sent") } catch (t: Throwable) { + println("Deeplinks: error: ${t.message}") + t.printStackTrace() FloconLogger.logError("deeplink mapping error", t) } } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt index 97392a96f..bd1df5393 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt @@ -1,29 +1,23 @@ package io.github.openflocon.flocon import io.github.openflocon.flocon.FloconApp.Client -import io.github.openflocon.flocon.client.FloconClientImpl +import io.github.openflocon.flocon.client.FloconClient import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.model.floconMessageFromServerFromJson import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO -import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext internal class Flocon( private val context: FloconContext, + private val scope: CoroutineScope, + private val client: FloconClient, private val plugins: List ) { - private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) - - private val client = FloconClientImpl( - context = context, - configuration = FloconConfiguration(), - plugins = plugins - ) - init { scope.launch { start( @@ -46,20 +40,24 @@ internal class Flocon( context = context, ) } - } + }, + onMessageReceived = ::onMessageReceived ) + + plugins.forEach(FloconPlugin::onConnectedToServer) + (client as? FloconMessageSender)?.let { // if success, just send a bonjour it.send("bonjour", method = "bonjour", body = "bonjour") it.sendPendingMessages() } } catch (t: Throwable) { - if(t.message?.contains("CLEARTEXT communication to localhost not permitted by network security policy") == true) { + if (t.message?.contains("CLEARTEXT communication to localhost not permitted by network security policy") == true) { withContext(Dispatchers.Main) { displayClearTextError(context = context) } } else { - //t.printStackTrace() + t.printStackTrace() delay(3_000) start( client = client, @@ -69,4 +67,16 @@ internal class Flocon( } } + private fun onMessageReceived(message: String) { + scope.launch(Dispatchers.IO) { + floconMessageFromServerFromJson(message)?.let { messageFromServer -> + plugins.find { it.key == messageFromServer.plugin } + ?.onMessageReceived( + method = messageFromServer.method, + body = messageFromServer.body, + ) + } + } + } + } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt index 4319f3dab..176c16416 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt @@ -13,32 +13,17 @@ abstract class FloconApp { interface Client { @Throws(Throwable::class) - suspend fun connect(onClosed: () -> Unit) + suspend fun connect( + onClosed: () -> Unit, + onMessageReceived: (message: String) -> Unit + ) + suspend fun disconnect() -// val databasePlugin: FloconDatabasePlugin? -// val dashboardPlugin: FloconDashboardPlugin? -// val tablePlugin: FloconTablePlugin? - //val deeplinksPlugin: FloconDeeplinksPlugin? -// val analyticsPlugin: FloconAnalyticsPlugin? -// val networkPlugin: FloconNetworkPlugin? -// val devicePlugin: FloconDevicePlugin? -// val preferencesPlugin: FloconPreferencesPlugin? -// val crashReporterPlugin: FloconCrashReporterPlugin? - - /** - * Retrieve a plugin instance by its [key]. - */ - fun getPlugin(key: String): T? } open val client: Client? = null abstract val isInitialized: StateFlow -// protected fun initializeFlocon(context: FloconContext) { -// this.context = context -// instance = this -// } - } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt index 9f907afae..aa2dca357 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -1,6 +1,11 @@ package io.github.openflocon.flocon +import io.github.openflocon.flocon.client.FloconClient import io.github.openflocon.flocon.client.FloconClientImpl +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -25,15 +30,17 @@ class FloconConfiguration internal constructor() { fun startFlocon(context: FloconContext, block: FloconConfiguration.() -> Unit) { val configuration = FloconConfiguration().apply(block) + val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) + val client = FloconClient(context = context, scope = scope) Flocon( context = context, + scope = scope, + client = client, plugins = configuration.pluginConfigs.map { (factory, config) -> factory.install( - config, - DumpObject( - FloconClientImpl(context, configuration, plugins = emptyList()) - ) + config = config, + app = DumpObject(client) // TODO Change ) as FloconPlugin } ) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt index 871f74f61..237f66188 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt @@ -61,7 +61,8 @@ abstract class FloconCore : FloconApp() { context = context, ) } - } + }, + onMessageReceived = {} ) (client as? FloconMessageSender)?.let { // if success, just send a bonjour diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt index 1fe2a7159..d82e71971 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt @@ -35,13 +35,14 @@ internal class FloconClientImpl( private val coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()) - override fun getPlugin(key: String): T? { + fun getPlugin(key: String): T? { return plugins.find { it.key == key } as? T } @Throws(Throwable::class) override suspend fun connect( onClosed: () -> Unit, + onMessageReceived: (message: String) -> Unit ) { webSocketClient.connect( address = address, @@ -116,4 +117,101 @@ internal class FloconClientImpl( webSocketClient.sendPendingMessages() } } +} + +internal class FloconClient( + private val context: FloconContext, + private val scope: CoroutineScope +) : FloconApp.Client, FloconMessageSender, FloconFileSender { + + private val appInstance by lazy { currentTimeMillis() } + private val appInfos by lazy { getAppInfos(context) } + private val versionName by lazy { BuildConfig.APP_VERSION } + private val address by lazy { getServerHost(context) } + + private val webSocketClient: FloconWebSocketClient = buildFloconWebSocketClient() + private val httpClient: FloconHttpClient = buildFloconHttpClient() + + @Throws(Throwable::class) + override suspend fun connect( + onClosed: () -> Unit, + onMessageReceived: (message: String) -> Unit + ) { + webSocketClient.connect( + address = address, + port = FLOCON_WEBSOCKET_PORT, + onMessageReceived = ::onMessageReceived, + onClosed = onClosed, + ) + } + + override suspend fun disconnect() { + webSocketClient.disconnect() + } + + private fun onMessageReceived(message: String) { + scope.launch(Dispatchers.IO) { + floconMessageFromServerFromJson(message)?.let { messageFromServer -> + messageFromServer.plugin +// plugins.find { it.key == messageFromServer.plugin } +// ?.onMessageReceived( +// method = messageFromServer.method, +// body = messageFromServer.body, +// ) + } + } + } + + override fun send( + plugin: String, + method: String, + body: String, + ) { + scope.launch(Dispatchers.IO) { + webSocketClient.sendMessage( + message = FloconMessageToServer( + deviceId = appInfos.deviceId, + plugin = plugin, + body = body, + appName = appInfos.appName, + appPackageName = appInfos.appPackageName, + method = method, + deviceName = appInfos.deviceName, + appInstance = appInstance, + platform = appInfos.platform, + versionName = versionName, + ) + .toFloconMessageToServer(), + ) + } + } + + override fun send( + file: FloconFile, + infos: FloconFileInfo, + ) { + scope.launch(Dispatchers.IO) { + httpClient.send( + address = address, + port = FLOCON_HTTP_PORT, + file = file, + infos = infos, + + deviceId = appInfos.deviceId, + appPackageName = appInfos.appPackageName, + appInstance = appInstance, + ) + } + } + + override fun sendPendingMessages() { + scope.launch(Dispatchers.IO) { + webSocketClient.sendPendingMessages() + } + } + + companion object { + private const val FLOCON_WEBSOCKET_PORT = 9023 + private const val FLOCON_HTTP_PORT = 9024 + } } \ No newline at end of file From 6ab9f26969cbb2c5a717b648539c802a8ecf5b5c Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Thu, 12 Mar 2026 11:52:50 +0100 Subject: [PATCH 06/35] feat: Clean --- .../plugins/deeplinks/FloconDeeplinks.kt | 28 +--- .../deeplinks/FloconDeeplinksPlugin.kt | 1 + .../io/github/openflocon/flocon/Flocon.kt | 2 +- .../openflocon/flocon/FloconConfiguration.kt | 32 ++-- .../io/github/openflocon/flocon/FloconCore.kt | 3 +- .../github/openflocon/flocon/FloconPlugin.kt | 12 +- .../flocon/client/FloconClientImpl.kt | 156 ++++++++---------- .../flocon/core/FloconFileSender.kt | 2 +- .../flocon/core/FloconMessageSender.kt | 4 +- .../analytics/FloconAnalyticsPlugin.kt | 16 +- .../FloconCrashReporterPlugin.kt | 16 +- .../dashboard/FloconDashboardPlugin.kt | 6 +- .../plugins/database/FloconDatabasePlugin.kt | 52 +++--- .../plugins/device/FloconDevicePluginImpl.kt | 26 +-- .../flocon/plugins/files/FloconFilesPlugin.kt | 36 ++-- .../network/FloconNetworkPluginImpl.kt | 26 +-- .../sharedprefs/FloconSharedPrefsPlugin.kt | 6 +- .../plugins/tables/FloconTablesPlugin.kt | 16 +- .../analytics/FloconAnalyticsPlugin.kt | 5 +- .../FloconCrashReporterPlugin.kt | 3 +- .../dashboard/FloconDashboardPlugin.kt | 3 +- .../database/FloconDatabasePlugin.kt | 5 +- .../pluginsold/device/FloconDevicePlugin.kt | 4 +- .../pluginsold/files/FloconFilesPlugin.kt | 9 +- .../pluginsold/network/FloconNetworkPlugin.kt | 5 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 9 +- .../pluginsold/tables/FloconTablesPlugin.kt | 5 +- .../io/github/openflocon/flocon/ktor/Mocks.kt | 9 + 28 files changed, 248 insertions(+), 249 deletions(-) diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt index ca4dab195..2e9e69375 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -14,28 +14,23 @@ object FloconDeeplinks : FloconPluginFactory, private val sender: FloconMessageSender, ) : FloconPlugin, FloconDeeplinksPlugin { override val key: String = "DEEP_LINK" - private val deeplinks = MutableStateFlow?>(null) - - override fun onMessageReceived( + override suspend fun onMessageReceived( method: String, body: String, ) { @@ -43,17 +38,12 @@ internal class FloconDeeplinksPluginImpl( // no op } - override fun onConnectedToServer() { - println("Deeplinks: connected (${deeplinks.value})") - // on connected, send known deeplinks - deeplinks.value?.let { - registerDeeplinks(it) - } + override suspend fun onConnectedToServer() { + println("Deeplinks: connected (${deeplinks})") + registerDeeplinks(deeplinks) } - override fun registerDeeplinks(deeplinks: List) { - this.deeplinks.update { deeplinks } - + override suspend fun registerDeeplinks(deeplinks: List) { try { println("Deeplinks: sending") sender.send( diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt index 1e4f57cbd..337106b29 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.plugins.deeplinks import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel class DeeplinkLinkBuilder internal constructor( diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt index bd1df5393..31eab3f3d 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt @@ -44,7 +44,7 @@ internal class Flocon( onMessageReceived = ::onMessageReceived ) - plugins.forEach(FloconPlugin::onConnectedToServer) + plugins.forEach { it.onConnectedToServer() } (client as? FloconMessageSender)?.let { // if success, just send a bonjour diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt index aa2dca357..e1253bf15 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -1,7 +1,6 @@ package io.github.openflocon.flocon import io.github.openflocon.flocon.client.FloconClient -import io.github.openflocon.flocon.client.FloconClientImpl import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO @@ -10,39 +9,40 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow -class FloconConfiguration internal constructor() { +class FloconConfiguration internal constructor( + private val client: FloconClient +) { - internal val pluginConfigs = mutableMapOf, Any>() + internal val plugins = mutableListOf() /** * Install a plugin with the given [factory] and optional [configure] block. */ - fun install( - factory: FloconPluginFactory, + fun install( + factory: FloconPluginFactory, configure: Config.() -> Unit = {} ) { - val config = factory.createConfig() - config.configure() - pluginConfigs[factory as FloconPluginFactory] = config // TODO + val plugin = factory.install( + config = factory.createConfig() + .apply { configure() }, + app = DumpObject(client = client) + ) + + plugins.add(plugin) } } fun startFlocon(context: FloconContext, block: FloconConfiguration.() -> Unit) { - val configuration = FloconConfiguration().apply(block) val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) - val client = FloconClient(context = context, scope = scope) + val client = FloconClient(context = context) + val configuration = FloconConfiguration(client = client).apply(block) Flocon( context = context, scope = scope, client = client, - plugins = configuration.pluginConfigs.map { (factory, config) -> - factory.install( - config = config, - app = DumpObject(client) // TODO Change - ) as FloconPlugin - } + plugins = configuration.plugins ) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt index 237f66188..be8a0c673 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt @@ -1,6 +1,5 @@ package io.github.openflocon.flocon -import io.github.openflocon.flocon.client.FloconClientImpl import io.github.openflocon.flocon.core.FloconMessageSender import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -30,7 +29,7 @@ abstract class FloconCore : FloconApp() { protected fun initializeFlocon( context: FloconContext, - configuration: FloconConfiguration = FloconConfiguration() + configuration: FloconConfiguration = FloconConfiguration(TODO()) ) { //super.initializeFlocon(context) // val newClient = FloconClientImpl(context, configuration) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt index b3e8e9177..53865e802 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt @@ -7,14 +7,16 @@ package io.github.openflocon.flocon interface FloconPlugin { val key: String - fun onMessageReceived( + suspend fun onMessageReceived( method: String, body: String, ) - fun onConnectedToServer() + suspend fun onConnectedToServer() } +interface FloconPluginConfig + /** * A unique key for identifying a Flocon plugin. */ @@ -27,7 +29,8 @@ interface FloconPluginKey { * A factory for creating and installing Flocon plugins. * This is the entry point for Ktor-style [install] calls. */ -interface FloconPluginFactory : FloconPluginKey { +interface FloconPluginFactory : FloconPluginKey { + /** * Create a default configuration instance for the plugin. */ @@ -36,5 +39,6 @@ interface FloconPluginFactory : FloconPlugin /** * Install the plugin into the [io.github.openflocon.flocon.FloconApp] instance with the given [config]. */ - fun install(config: Any, app: FloconApp): PluginInstance // TODO + fun install(config: Config, app: FloconApp): PluginInstance // TODO + } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt index d82e71971..7c7b58a5b 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/client/FloconClientImpl.kt @@ -1,8 +1,18 @@ package io.github.openflocon.flocon.client -import io.github.openflocon.flocon.* -import io.github.openflocon.flocon.core.* -import io.github.openflocon.flocon.model.* +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconConfiguration +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconFile +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.core.FloconFileSender +import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.core.getAppInfos +import io.github.openflocon.flocon.getServerHost +import io.github.openflocon.flocon.model.FloconFileInfo +import io.github.openflocon.flocon.model.FloconMessageToServer +import io.github.openflocon.flocon.model.floconMessageFromServerFromJson +import io.github.openflocon.flocon.model.toFloconMessageToServer import io.github.openflocon.flocon.utils.currentTimeMillis import io.github.openflocon.flocon.websocket.FloconHttpClient import io.github.openflocon.flocon.websocket.FloconWebSocketClient @@ -50,7 +60,7 @@ internal class FloconClientImpl( onMessageReceived = ::onMessageReceived, onClosed = onClosed, ) - plugins.forEach(FloconPlugin::onConnectedToServer) + plugins.forEach { it.onConnectedToServer() } } override suspend fun disconnect() { @@ -70,58 +80,51 @@ internal class FloconClientImpl( } } - override fun send( + override suspend fun send( plugin: String, method: String, body: String, ) { - coroutineScope.launch(Dispatchers.IO) { - webSocketClient.sendMessage( - message = FloconMessageToServer( - deviceId = appInfos.deviceId, - plugin = plugin, - body = body, - appName = appInfos.appName, - appPackageName = appInfos.appPackageName, - method = method, - deviceName = appInfos.deviceName, - appInstance = appInstance, - platform = appInfos.platform, - versionName = versionName, - ) - .toFloconMessageToServer(), + webSocketClient.sendMessage( + message = FloconMessageToServer( + deviceId = appInfos.deviceId, + plugin = plugin, + body = body, + appName = appInfos.appName, + appPackageName = appInfos.appPackageName, + method = method, + deviceName = appInfos.deviceName, + appInstance = appInstance, + platform = appInfos.platform, + versionName = versionName, ) - } + .toFloconMessageToServer(), + ) } - override fun send( + override suspend fun send( file: FloconFile, infos: FloconFileInfo, ) { - coroutineScope.launch(Dispatchers.IO) { - httpClient.send( - address = address, - port = FLOCON_HTTP_PORT, - file = file, - infos = infos, + httpClient.send( + address = address, + port = FLOCON_HTTP_PORT, + file = file, + infos = infos, - deviceId = appInfos.deviceId, - appPackageName = appInfos.appPackageName, - appInstance = appInstance, - ) - } + deviceId = appInfos.deviceId, + appPackageName = appInfos.appPackageName, + appInstance = appInstance, + ) } - override fun sendPendingMessages() { - coroutineScope.launch(Dispatchers.IO) { - webSocketClient.sendPendingMessages() - } + override suspend fun sendPendingMessages() { + webSocketClient.sendPendingMessages() } } internal class FloconClient( - private val context: FloconContext, - private val scope: CoroutineScope + private val context: FloconContext ) : FloconApp.Client, FloconMessageSender, FloconFileSender { private val appInstance by lazy { currentTimeMillis() } @@ -140,7 +143,7 @@ internal class FloconClient( webSocketClient.connect( address = address, port = FLOCON_WEBSOCKET_PORT, - onMessageReceived = ::onMessageReceived, + onMessageReceived = onMessageReceived, onClosed = onClosed, ) } @@ -149,65 +152,46 @@ internal class FloconClient( webSocketClient.disconnect() } - private fun onMessageReceived(message: String) { - scope.launch(Dispatchers.IO) { - floconMessageFromServerFromJson(message)?.let { messageFromServer -> - messageFromServer.plugin -// plugins.find { it.key == messageFromServer.plugin } -// ?.onMessageReceived( -// method = messageFromServer.method, -// body = messageFromServer.body, -// ) - } - } - } - - override fun send( + override suspend fun send( plugin: String, method: String, body: String, ) { - scope.launch(Dispatchers.IO) { - webSocketClient.sendMessage( - message = FloconMessageToServer( - deviceId = appInfos.deviceId, - plugin = plugin, - body = body, - appName = appInfos.appName, - appPackageName = appInfos.appPackageName, - method = method, - deviceName = appInfos.deviceName, - appInstance = appInstance, - platform = appInfos.platform, - versionName = versionName, - ) - .toFloconMessageToServer(), + webSocketClient.sendMessage( + message = FloconMessageToServer( + deviceId = appInfos.deviceId, + plugin = plugin, + body = body, + appName = appInfos.appName, + appPackageName = appInfos.appPackageName, + method = method, + deviceName = appInfos.deviceName, + appInstance = appInstance, + platform = appInfos.platform, + versionName = versionName, ) - } + .toFloconMessageToServer(), + ) } - override fun send( + override suspend fun send( file: FloconFile, infos: FloconFileInfo, ) { - scope.launch(Dispatchers.IO) { - httpClient.send( - address = address, - port = FLOCON_HTTP_PORT, - file = file, - infos = infos, + httpClient.send( + address = address, + port = FLOCON_HTTP_PORT, + file = file, + infos = infos, - deviceId = appInfos.deviceId, - appPackageName = appInfos.appPackageName, - appInstance = appInstance, - ) - } + deviceId = appInfos.deviceId, + appPackageName = appInfos.appPackageName, + appInstance = appInstance, + ) } - override fun sendPendingMessages() { - scope.launch(Dispatchers.IO) { - webSocketClient.sendPendingMessages() - } + override suspend fun sendPendingMessages() { + webSocketClient.sendPendingMessages() } companion object { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt index 929fe8411..3f5b977ce 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt @@ -4,5 +4,5 @@ import io.github.openflocon.flocon.FloconFile import io.github.openflocon.flocon.model.FloconFileInfo internal interface FloconFileSender { - fun send(file: FloconFile, infos: FloconFileInfo) + suspend fun send(file: FloconFile, infos: FloconFileInfo) } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt index 4e99fbc91..dbff6b15b 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt @@ -1,11 +1,11 @@ package io.github.openflocon.flocon.core interface FloconMessageSender { - fun send( + suspend fun send( plugin: String, method: String, body: String, ) - fun sendPendingMessages() + suspend fun sendPendingMessages() } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt index 2469db2b4..d0b293286 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -15,7 +15,7 @@ object FloconAnalytics : FloconPluginFactory) { analyticsItems.takeIf { it.isNotEmpty() }?.forEach { toSend -> try { - sender.send( - plugin = Protocol.FromDevice.Analytics.Plugin, - method = Protocol.FromDevice.Analytics.Method.AddItems, - body = analyticsItemsToJson(toSend) - ) +// sender.send( +// plugin = Protocol.FromDevice.Analytics.Plugin, +// method = Protocol.FromDevice.Analytics.Method.AddItems, +// body = analyticsItemsToJson(toSend) +// ) } catch (t: Throwable) { FloconLogger.logError("error on sendAnalytics", t) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt index 835814ed5..e230612b1 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt @@ -22,7 +22,7 @@ object FloconCrashReporter : Protocol.ToDevice.Analytics.Plugin // Crash reporter is usually write-only but we can set an ID override fun createConfig() = FloconCrashReporterConfig() - override fun install(config: Any, app: FloconApp): FloconCrashReporterPlugin { + override fun install(config: FloconCrashReporterConfig, app: FloconApp): FloconCrashReporterPlugin { val client = app.client as FloconMessageSender return FloconCrashReporterPluginImpl( context = TODO(), //FloconContext(appContext = null), // Handled by datasource @@ -48,7 +48,7 @@ internal class FloconCrashReporterPluginImpl( } } - override fun onConnectedToServer() { + override suspend fun onConnectedToServer() { // Send all pending crashes coroutineScope.launch { try { @@ -64,7 +64,7 @@ internal class FloconCrashReporterPluginImpl( } } - override fun onMessageReceived( + override suspend fun onMessageReceived( method: String, body: String, ) { @@ -73,11 +73,11 @@ internal class FloconCrashReporterPluginImpl( private fun sendCrashes(crashes: List) { try { - sender.send( - plugin = Protocol.FromDevice.CrashReporter.Plugin, - method = Protocol.FromDevice.CrashReporter.Method.ReportCrash, - body = crashReportsListToJson(crashes), - ) +// sender.send( +// plugin = Protocol.FromDevice.CrashReporter.Plugin, +// method = Protocol.FromDevice.CrashReporter.Method.ReportCrash, +// body = crashReportsListToJson(crashes), +// ) } catch (t: Throwable) { FloconLogger.logError("Crash report sending error", t) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt index 69cd31a9f..018cf0b74 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt @@ -19,7 +19,7 @@ import kotlinx.coroutines.launch override val name: String = "Dashboard" override val pluginId: String = Protocol.ToDevice.Dashboard.Plugin override fun createConfig() = FloconDashboardConfig() - override fun install(config: Any, app: FloconApp): FloconDashboardPlugin { + override fun install(config: FloconDashboardConfig, app: FloconApp): FloconDashboardPlugin { return FloconDashboardPluginImpl( sender = app.client as FloconMessageSender ) @@ -38,7 +38,7 @@ internal class FloconDashboardPluginImpl( private val dashboards = mutableMapOf() private val callbackMap = mutableMapOf() - override fun onMessageReceived( + override suspend fun onMessageReceived( method: String, body: String, ) { @@ -76,7 +76,7 @@ internal class FloconDashboardPluginImpl( } } - override fun onConnectedToServer() { + override suspend fun onConnectedToServer() { // on connected, send known dashboards dashboards.values.takeIf { it.isNotEmpty() }?.forEach { dashboardConfig -> registerDashboardInternal(dashboardConfig) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt index 36ebe85eb..69d662783 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt @@ -38,7 +38,7 @@ object FloconDatabase : FloconPluginFactory) { try { - sender.send( - plugin = Protocol.FromDevice.Database.Plugin, - method = Protocol.FromDevice.Database.Method.LogQuery, - body = DatabaseQueryLogModel( - dbName = dbName, - sqlQuery = sqlQuery, - bindArgs = bindArgs.map { it.toString() }, - timestamp = currentTimeMillis(), - ).toJson(), - ) +// sender.send( +// plugin = Protocol.FromDevice.Database.Plugin, +// method = Protocol.FromDevice.Database.Method.LogQuery, +// body = DatabaseQueryLogModel( +// dbName = dbName, +// sqlQuery = sqlQuery, +// bindArgs = bindArgs.map { it.toString() }, +// timestamp = currentTimeMillis(), +// ).toJson(), +// ) } catch (t: Throwable) { FloconLogger.logError("Database logging error", t) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt index 61fc5317f..ef90efbcc 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt @@ -10,7 +10,7 @@ object FloconDevice : FloconPluginFactory { val icon = getAppIconBase64(context) if (icon != null) { - sender.send( - plugin = Protocol.FromDevice.Device.Plugin, - method = Protocol.FromDevice.Device.Method.AppIcon, - body = icon, - ) +// sender.send( +// plugin = Protocol.FromDevice.Device.Plugin, +// method = Protocol.FromDevice.Device.Method.AppIcon, +// body = icon, +// ) } } @@ -60,7 +60,7 @@ internal class FloconDevicePluginImpl( } } - override fun onConnectedToServer() { + override suspend fun onConnectedToServer() { // no op } } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt index d887edb1e..85b61b199 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt @@ -26,7 +26,7 @@ object FloconFiles : FloconPluginFactory { override val name: String = "Files" override val pluginId: String = Protocol.ToDevice.Files.Plugin override fun createConfig() = FloconFilesConfig() - override fun install(config: Any, app: FloconApp): FloconFilesPlugin { + override fun install(config: FloconFilesConfig, app: FloconApp): FloconFilesPlugin { val client = app.client return FloconFilesPluginImpl( context = app.context, @@ -61,7 +61,7 @@ internal class FloconFilesPluginImpl( private val fileDataSource = fileDataSource(context) private val withFoldersSize = MutableStateFlow(false) - override fun onMessageReceived( + override suspend fun onMessageReceived( method: String, body: String, ) { @@ -83,13 +83,13 @@ internal class FloconFilesPluginImpl( fileDataSource.getFile(path = getFileMessage.path, isConstantPath = false) ?.let { file -> - floconFileSender.send( - file = file, - infos = FloconFileInfo( - requestId = getFileMessage.requestId, - path = getFileMessage.path, - ) - ) +// floconFileSender.send( +// file = file, +// infos = FloconFileInfo( +// requestId = getFileMessage.requestId, +// path = getFileMessage.path, +// ) +// ) } } @@ -158,20 +158,20 @@ internal class FloconFilesPluginImpl( ) try { - sender.send( - plugin = Protocol.FromDevice.Files.Plugin, - method = Protocol.FromDevice.Files.Method.ListFiles, - body = FilesResultDataModel( - requestId = requestId, - files = files, - ).toJson(), - ) +// sender.send( +// plugin = Protocol.FromDevice.Files.Plugin, +// method = Protocol.FromDevice.Files.Method.ListFiles, +// body = FilesResultDataModel( +// requestId = requestId, +// files = files, +// ).toJson(), +// ) } catch (t: Throwable) { FloconLogger.logError("File parsing error", t) } } - override fun onConnectedToServer() { + override suspend fun onConnectedToServer() { // no op } } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt index 25c107c77..6d2a9c0b8 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt @@ -35,7 +35,7 @@ object FloconNetwork : FloconPluginFactory() - override fun onMessageReceived( + override suspend fun onMessageReceived( method: String, body: String, ) { @@ -62,7 +62,7 @@ internal class FloconSharedPrefsPluginImpl( // } } - override fun onConnectedToServer() { + override suspend fun onConnectedToServer() { sendSharedPreferences() } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt index 3c95bc023..2306b0664 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt @@ -11,7 +11,7 @@ import io.github.openflocon.flocon.pluginsold.tables.model.TableItem override val name: String = "Table" override val pluginId: String = Protocol.ToDevice.Table.Plugin override fun createConfig() = FloconTableConfig() - override fun install(config: Any, app: FloconApp): FloconTablePlugin { + override fun install(config: FloconTableConfig, app: FloconApp): FloconTablePlugin { return FloconTablePluginImpl( sender = app.client as FloconMessageSender ) @@ -23,14 +23,14 @@ internal class FloconTablePluginImpl( ) : FloconPlugin, FloconTablePlugin { override val key: String = "TABLE" - override fun onMessageReceived( + override suspend fun onMessageReceived( method: String, body: String, ) { // no op } - override fun onConnectedToServer() { + override suspend fun onConnectedToServer() { // no op } @@ -40,11 +40,11 @@ internal class FloconTablePluginImpl( private fun sendTable(tableItems: List) { try { - sender.send( - plugin = Protocol.FromDevice.Table.Plugin, - method = Protocol.FromDevice.Table.Method.AddItems, - body = tableItemListToJson(tableItems).toString() - ) +// sender.send( +// plugin = Protocol.FromDevice.Table.Plugin, +// method = Protocol.FromDevice.Table.Method.AddItems, +// body = tableItemListToJson(tableItems).toString() +// ) } catch (t: Throwable) { FloconLogger.logError("Table json mapping error", t) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt index b9b3db73d..a64cc3866 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt @@ -2,17 +2,18 @@ package io.github.openflocon.flocon.pluginsold.analytics import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem -class FloconAnalyticsConfig +class FloconAnalyticsConfig : FloconPluginConfig /** * Flocon Analytics Plugin. */ object FloconAnalytics : FloconPluginFactory { override fun createConfig(): FloconAnalyticsConfig = TODO() - override fun install(config: Any, app: FloconApp): FloconAnalyticsPlugin = TODO() + override fun install(config: FloconAnalyticsConfig, app: FloconApp): FloconAnalyticsPlugin = TODO() override val name: String = "" } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt index a4de6eaf9..e30e0037d 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt @@ -1,8 +1,9 @@ package io.github.openflocon.flocon.pluginsold.crashreporter import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig -class FloconCrashReporterConfig { +class FloconCrashReporterConfig : FloconPluginConfig { var catchFatalErrors: Boolean = true } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/FloconDashboardPlugin.kt index f0dde5d6a..48aa3c542 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/FloconDashboardPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/dashboard/FloconDashboardPlugin.kt @@ -1,9 +1,10 @@ package io.github.openflocon.flocon.pluginsold.dashboard import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardConfig -class FloconDashboardConfig +class FloconDashboardConfig : FloconPluginConfig /** * Flocon Dashboard Plugin. diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt index 95313a4a8..1f07a69b8 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt @@ -2,10 +2,11 @@ package io.github.openflocon.flocon.pluginsold.database import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.pluginsold.database.model.FloconDatabaseModel -class FloconDatabaseConfig +class FloconDatabaseConfig : FloconPluginConfig /** * Flocon Database Plugin. @@ -16,7 +17,7 @@ object FloconDatabase : FloconPluginFactory() } @@ -15,7 +18,7 @@ object FloconFiles : FloconPluginFactory { TODO("Not yet implemented") } - override fun install(config: Any, app: FloconApp): FloconFilesPlugin { + override fun install(config: FloconFilesConfig, app: FloconApp): FloconFilesPlugin { TODO("Not yet implemented") } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt index 7b23222fa..2f220e3b2 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocon.pluginsold.network import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest @@ -10,7 +11,7 @@ import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketMockListener import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse -class FloconNetworkConfig { +class FloconNetworkConfig : FloconPluginConfig { var badQualityConfig: BadQualityConfig? = null val mocks = mutableListOf() } @@ -21,7 +22,7 @@ class FloconNetworkConfig { */ object FloconNetwork : FloconPluginFactory { override fun createConfig(): FloconNetworkConfig = TODO() - override fun install(config: Any, app: FloconApp): FloconNetworkPlugin = TODO() + override fun install(config: FloconNetworkConfig, app: FloconApp): FloconNetworkPlugin = TODO() override val name: String = "" } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt index 91324e681..6beb16aa2 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt @@ -1,9 +1,12 @@ package io.github.openflocon.flocon.pluginsold.sharedprefs -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconSharedPreferenceModel -class FloconPreferencesConfig +class FloconPreferencesConfig : FloconPluginConfig /** * Flocon Preferences Plugin. @@ -14,7 +17,7 @@ object FloconPreferences : FloconPluginFactory { TODO("Not yet implemented") } - override fun install(config: Any, app: FloconApp): FloconTablePlugin { + override fun install(config: FloconTableConfig, app: FloconApp): FloconTablePlugin { TODO("Not yet implemented") } diff --git a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt b/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt index 57f0da6a8..d6d99e3b7 100644 --- a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt +++ b/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt @@ -10,6 +10,7 @@ import io.ktor.http.HeadersBuilder import io.ktor.http.HttpProtocolVersion import io.ktor.http.HttpStatusCode import io.ktor.util.date.GMTDate +import io.ktor.util.logging.Logger import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.InternalAPI import kotlinx.coroutines.delay @@ -28,6 +29,14 @@ internal fun findMock( } } +//fun test() { +// HttpClient { +// install() { +// +// } +// } +//} + @OptIn(InternalAPI::class) internal suspend fun executeMock( request: HttpRequestBuilder, From 6c469516de9e1b9600d6df470fec7d830ed15f94 Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Thu, 12 Mar 2026 13:37:17 +0100 Subject: [PATCH 07/35] feat: Create core network modules --- .../network/core-no-op/build.gradle.kts | 118 +++++++++++++++++ .../src/androidMain/AndroidManifest.xml | 3 + .../network/core/noop/NetworkCoreNoOp.kt | 3 + FloconAndroid/network/core/build.gradle.kts | 121 ++++++++++++++++++ .../core/src/androidMain/AndroidManifest.xml | 3 + .../flocon/network/core/NetworkCore.kt | 3 + .../ktor-interceptor-no-op/.gitignore | 0 .../ktor-interceptor-no-op/build.gradle.kts | 2 +- .../ktor-interceptor-no-op/consumer-rules.pro | 0 .../ktor-interceptor-no-op/proguard-rules.pro | 0 .../flocon/ktor/FloconKtorPlugin.kt | 0 .../{ => network}/ktor-interceptor/.gitignore | 0 .../ktor-interceptor/build.gradle.kts | 2 +- .../ktor-interceptor/consumer-rules.pro | 0 .../ktor-interceptor/proguard-rules.pro | 0 .../openflocon/flocon/ktor/DecodeUtils.kt | 0 .../openflocon/flocon/ktor/BadQuality.kt | 0 .../flocon/ktor/FloconKtorPlugin.kt | 0 .../io/github/openflocon/flocon/ktor/Mocks.kt | 0 .../io/github/openflocon/flocon/ktor/Utils.kt | 0 .../openflocon/flocon/ktor/DecodeUtils.kt | 0 .../openflocon/flocon/ktor/DecodeUtils.kt | 0 .../okhttp-interceptor-no-op/.gitignore | 0 .../okhttp-interceptor-no-op/build.gradle.kts | 1 + .../consumer-rules.pro | 0 .../proguard-rules.pro | 0 .../src/main/AndroidManifest.xml | 0 .../flocon/okhttp/OkHttpInterceptor.kt | 0 .../okhttp/websocket/FloconWebSocket.kt | 0 .../okhttp-interceptor/.gitignore | 0 .../okhttp-interceptor/build.gradle.kts | 2 +- .../okhttp-interceptor/consumer-rules.pro | 0 .../okhttp-interceptor/proguard-rules.pro | 0 .../src/main/AndroidManifest.xml | 0 .../openflocon/flocon/okhttp/BadQuality.kt | 0 .../github/openflocon/flocon/okhttp/Mock.kt | 0 .../flocon/okhttp/OkHttpInterceptor.kt | 0 .../github/openflocon/flocon/okhttp/Utils.kt | 0 .../okhttp/websocket/FloconWebSocket.kt | 0 .../openflocon/flocon/okhttp/UtilsTest.kt | 0 .../sample-android-only/build.gradle.kts | 8 +- .../sample-multiplatform/build.gradle.kts | 2 +- FloconAndroid/settings.gradle.kts | 10 +- 43 files changed, 266 insertions(+), 12 deletions(-) create mode 100644 FloconAndroid/network/core-no-op/build.gradle.kts create mode 100644 FloconAndroid/network/core-no-op/src/androidMain/AndroidManifest.xml create mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/NetworkCoreNoOp.kt create mode 100644 FloconAndroid/network/core/build.gradle.kts create mode 100644 FloconAndroid/network/core/src/androidMain/AndroidManifest.xml create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/NetworkCore.kt rename FloconAndroid/{ => network}/ktor-interceptor-no-op/.gitignore (100%) rename FloconAndroid/{ => network}/ktor-interceptor-no-op/build.gradle.kts (98%) rename FloconAndroid/{ => network}/ktor-interceptor-no-op/consumer-rules.pro (100%) rename FloconAndroid/{ => network}/ktor-interceptor-no-op/proguard-rules.pro (100%) rename FloconAndroid/{ => network}/ktor-interceptor-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt (100%) rename FloconAndroid/{ => network}/ktor-interceptor/.gitignore (100%) rename FloconAndroid/{ => network}/ktor-interceptor/build.gradle.kts (98%) rename FloconAndroid/{ => network}/ktor-interceptor/consumer-rules.pro (100%) rename FloconAndroid/{ => network}/ktor-interceptor/proguard-rules.pro (100%) rename FloconAndroid/{ => network}/ktor-interceptor/src/androidMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt (100%) rename FloconAndroid/{ => network}/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt (100%) rename FloconAndroid/{ => network}/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt (100%) rename FloconAndroid/{ => network}/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt (100%) rename FloconAndroid/{ => network}/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Utils.kt (100%) rename FloconAndroid/{ => network}/ktor-interceptor/src/iosMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt (100%) rename FloconAndroid/{ => network}/ktor-interceptor/src/jvmMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt (100%) rename FloconAndroid/{ => network}/okhttp-interceptor-no-op/.gitignore (100%) rename FloconAndroid/{ => network}/okhttp-interceptor-no-op/build.gradle.kts (97%) rename FloconAndroid/{ => network}/okhttp-interceptor-no-op/consumer-rules.pro (100%) rename FloconAndroid/{ => network}/okhttp-interceptor-no-op/proguard-rules.pro (100%) rename FloconAndroid/{ => network}/okhttp-interceptor-no-op/src/main/AndroidManifest.xml (100%) rename FloconAndroid/{ => network}/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt (100%) rename FloconAndroid/{ => network}/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/.gitignore (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/build.gradle.kts (98%) rename FloconAndroid/{ => network}/okhttp-interceptor/consumer-rules.pro (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/proguard-rules.pro (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/src/main/AndroidManifest.xml (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Utils.kt (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt (100%) rename FloconAndroid/{ => network}/okhttp-interceptor/src/test/kotlin/io/github/openflocon/flocon/okhttp/UtilsTest.kt (100%) diff --git a/FloconAndroid/network/core-no-op/build.gradle.kts b/FloconAndroid/network/core-no-op/build.gradle.kts new file mode 100644 index 000000000..7d09e14e2 --- /dev/null +++ b/FloconAndroid/network/core-no-op/build.gradle.kts @@ -0,0 +1,118 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +android { + namespace = "io.github.openflocon.flocon.network.core.noop" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-network-core-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Network Core No-Op" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/network/core-no-op/src/androidMain/AndroidManifest.xml b/FloconAndroid/network/core-no-op/src/androidMain/AndroidManifest.xml new file mode 100644 index 000000000..9a40236b9 --- /dev/null +++ b/FloconAndroid/network/core-no-op/src/androidMain/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/NetworkCoreNoOp.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/NetworkCoreNoOp.kt new file mode 100644 index 000000000..cf487ea7b --- /dev/null +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/NetworkCoreNoOp.kt @@ -0,0 +1,3 @@ +package io.github.openflocon.flocon.network.core.noop + +// Placeholder for Network Core No-Op diff --git a/FloconAndroid/network/core/build.gradle.kts b/FloconAndroid/network/core/build.gradle.kts new file mode 100644 index 000000000..af58159d7 --- /dev/null +++ b/FloconAndroid/network/core/build.gradle.kts @@ -0,0 +1,121 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) + alias(libs.plugins.kotlin.serialization) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + api(project(":flocon")) + + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(libs.kotlinx.serialization.json) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +android { + namespace = "io.github.openflocon.flocon.network.core" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-network-core", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Network Core" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/network/core/src/androidMain/AndroidManifest.xml b/FloconAndroid/network/core/src/androidMain/AndroidManifest.xml new file mode 100644 index 000000000..9a40236b9 --- /dev/null +++ b/FloconAndroid/network/core/src/androidMain/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/NetworkCore.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/NetworkCore.kt new file mode 100644 index 000000000..1ce7f0e47 --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/NetworkCore.kt @@ -0,0 +1,3 @@ +package io.github.openflocon.flocon.network.core + +// Placeholder for Network Core diff --git a/FloconAndroid/ktor-interceptor-no-op/.gitignore b/FloconAndroid/network/ktor-interceptor-no-op/.gitignore similarity index 100% rename from FloconAndroid/ktor-interceptor-no-op/.gitignore rename to FloconAndroid/network/ktor-interceptor-no-op/.gitignore diff --git a/FloconAndroid/ktor-interceptor-no-op/build.gradle.kts b/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts similarity index 98% rename from FloconAndroid/ktor-interceptor-no-op/build.gradle.kts rename to FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts index f645d5790..0f966ba28 100644 --- a/FloconAndroid/ktor-interceptor-no-op/build.gradle.kts +++ b/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) + implementation(project(":network:core-no-op")) implementation(libs.ktor.client.core) } } diff --git a/FloconAndroid/ktor-interceptor-no-op/consumer-rules.pro b/FloconAndroid/network/ktor-interceptor-no-op/consumer-rules.pro similarity index 100% rename from FloconAndroid/ktor-interceptor-no-op/consumer-rules.pro rename to FloconAndroid/network/ktor-interceptor-no-op/consumer-rules.pro diff --git a/FloconAndroid/ktor-interceptor-no-op/proguard-rules.pro b/FloconAndroid/network/ktor-interceptor-no-op/proguard-rules.pro similarity index 100% rename from FloconAndroid/ktor-interceptor-no-op/proguard-rules.pro rename to FloconAndroid/network/ktor-interceptor-no-op/proguard-rules.pro diff --git a/FloconAndroid/ktor-interceptor-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt b/FloconAndroid/network/ktor-interceptor-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt similarity index 100% rename from FloconAndroid/ktor-interceptor-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt rename to FloconAndroid/network/ktor-interceptor-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt diff --git a/FloconAndroid/ktor-interceptor/.gitignore b/FloconAndroid/network/ktor-interceptor/.gitignore similarity index 100% rename from FloconAndroid/ktor-interceptor/.gitignore rename to FloconAndroid/network/ktor-interceptor/.gitignore diff --git a/FloconAndroid/ktor-interceptor/build.gradle.kts b/FloconAndroid/network/ktor-interceptor/build.gradle.kts similarity index 98% rename from FloconAndroid/ktor-interceptor/build.gradle.kts rename to FloconAndroid/network/ktor-interceptor/build.gradle.kts index d18d78819..0bc55cdc3 100644 --- a/FloconAndroid/ktor-interceptor/build.gradle.kts +++ b/FloconAndroid/network/ktor-interceptor/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) + implementation(project(":network:core")) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0") implementation(libs.ktor.client.core) } diff --git a/FloconAndroid/ktor-interceptor/consumer-rules.pro b/FloconAndroid/network/ktor-interceptor/consumer-rules.pro similarity index 100% rename from FloconAndroid/ktor-interceptor/consumer-rules.pro rename to FloconAndroid/network/ktor-interceptor/consumer-rules.pro diff --git a/FloconAndroid/ktor-interceptor/proguard-rules.pro b/FloconAndroid/network/ktor-interceptor/proguard-rules.pro similarity index 100% rename from FloconAndroid/ktor-interceptor/proguard-rules.pro rename to FloconAndroid/network/ktor-interceptor/proguard-rules.pro diff --git a/FloconAndroid/ktor-interceptor/src/androidMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt b/FloconAndroid/network/ktor-interceptor/src/androidMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt similarity index 100% rename from FloconAndroid/ktor-interceptor/src/androidMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt rename to FloconAndroid/network/ktor-interceptor/src/androidMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt diff --git a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt b/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt similarity index 100% rename from FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt rename to FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt diff --git a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt b/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt similarity index 100% rename from FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt rename to FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/FloconKtorPlugin.kt diff --git a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt b/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt similarity index 100% rename from FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt rename to FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt diff --git a/FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Utils.kt b/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Utils.kt similarity index 100% rename from FloconAndroid/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Utils.kt rename to FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Utils.kt diff --git a/FloconAndroid/ktor-interceptor/src/iosMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt b/FloconAndroid/network/ktor-interceptor/src/iosMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt similarity index 100% rename from FloconAndroid/ktor-interceptor/src/iosMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt rename to FloconAndroid/network/ktor-interceptor/src/iosMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt diff --git a/FloconAndroid/ktor-interceptor/src/jvmMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt b/FloconAndroid/network/ktor-interceptor/src/jvmMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt similarity index 100% rename from FloconAndroid/ktor-interceptor/src/jvmMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt rename to FloconAndroid/network/ktor-interceptor/src/jvmMain/kotlin/io/github/openflocon/flocon/ktor/DecodeUtils.kt diff --git a/FloconAndroid/okhttp-interceptor-no-op/.gitignore b/FloconAndroid/network/okhttp-interceptor-no-op/.gitignore similarity index 100% rename from FloconAndroid/okhttp-interceptor-no-op/.gitignore rename to FloconAndroid/network/okhttp-interceptor-no-op/.gitignore diff --git a/FloconAndroid/okhttp-interceptor-no-op/build.gradle.kts b/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts similarity index 97% rename from FloconAndroid/okhttp-interceptor-no-op/build.gradle.kts rename to FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts index 897fd4fc9..739f6b1ee 100644 --- a/FloconAndroid/okhttp-interceptor-no-op/build.gradle.kts +++ b/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts @@ -34,6 +34,7 @@ android { } dependencies { + implementation(project(":network:core-no-op")) implementation(platform(libs.okhttp.bom)) implementation(libs.okhttp3.okhttp) } diff --git a/FloconAndroid/okhttp-interceptor-no-op/consumer-rules.pro b/FloconAndroid/network/okhttp-interceptor-no-op/consumer-rules.pro similarity index 100% rename from FloconAndroid/okhttp-interceptor-no-op/consumer-rules.pro rename to FloconAndroid/network/okhttp-interceptor-no-op/consumer-rules.pro diff --git a/FloconAndroid/okhttp-interceptor-no-op/proguard-rules.pro b/FloconAndroid/network/okhttp-interceptor-no-op/proguard-rules.pro similarity index 100% rename from FloconAndroid/okhttp-interceptor-no-op/proguard-rules.pro rename to FloconAndroid/network/okhttp-interceptor-no-op/proguard-rules.pro diff --git a/FloconAndroid/okhttp-interceptor-no-op/src/main/AndroidManifest.xml b/FloconAndroid/network/okhttp-interceptor-no-op/src/main/AndroidManifest.xml similarity index 100% rename from FloconAndroid/okhttp-interceptor-no-op/src/main/AndroidManifest.xml rename to FloconAndroid/network/okhttp-interceptor-no-op/src/main/AndroidManifest.xml diff --git a/FloconAndroid/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt b/FloconAndroid/network/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt similarity index 100% rename from FloconAndroid/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt rename to FloconAndroid/network/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt diff --git a/FloconAndroid/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt b/FloconAndroid/network/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt similarity index 100% rename from FloconAndroid/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt rename to FloconAndroid/network/okhttp-interceptor-no-op/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt diff --git a/FloconAndroid/okhttp-interceptor/.gitignore b/FloconAndroid/network/okhttp-interceptor/.gitignore similarity index 100% rename from FloconAndroid/okhttp-interceptor/.gitignore rename to FloconAndroid/network/okhttp-interceptor/.gitignore diff --git a/FloconAndroid/okhttp-interceptor/build.gradle.kts b/FloconAndroid/network/okhttp-interceptor/build.gradle.kts similarity index 98% rename from FloconAndroid/okhttp-interceptor/build.gradle.kts rename to FloconAndroid/network/okhttp-interceptor/build.gradle.kts index 5388747f0..2ab89d589 100644 --- a/FloconAndroid/okhttp-interceptor/build.gradle.kts +++ b/FloconAndroid/network/okhttp-interceptor/build.gradle.kts @@ -41,7 +41,7 @@ kotlin { dependencies { - implementation(project(":flocon")) + implementation(project(":network:core")) implementation(platform(libs.kotlinx.coroutines.bom)) implementation(libs.jetbrains.kotlinx.coroutines.core) diff --git a/FloconAndroid/okhttp-interceptor/consumer-rules.pro b/FloconAndroid/network/okhttp-interceptor/consumer-rules.pro similarity index 100% rename from FloconAndroid/okhttp-interceptor/consumer-rules.pro rename to FloconAndroid/network/okhttp-interceptor/consumer-rules.pro diff --git a/FloconAndroid/okhttp-interceptor/proguard-rules.pro b/FloconAndroid/network/okhttp-interceptor/proguard-rules.pro similarity index 100% rename from FloconAndroid/okhttp-interceptor/proguard-rules.pro rename to FloconAndroid/network/okhttp-interceptor/proguard-rules.pro diff --git a/FloconAndroid/okhttp-interceptor/src/main/AndroidManifest.xml b/FloconAndroid/network/okhttp-interceptor/src/main/AndroidManifest.xml similarity index 100% rename from FloconAndroid/okhttp-interceptor/src/main/AndroidManifest.xml rename to FloconAndroid/network/okhttp-interceptor/src/main/AndroidManifest.xml diff --git a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt similarity index 100% rename from FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt rename to FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt diff --git a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt similarity index 100% rename from FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt rename to FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt diff --git a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt similarity index 100% rename from FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt rename to FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt diff --git a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Utils.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Utils.kt similarity index 100% rename from FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Utils.kt rename to FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Utils.kt diff --git a/FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt similarity index 100% rename from FloconAndroid/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt rename to FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt diff --git a/FloconAndroid/okhttp-interceptor/src/test/kotlin/io/github/openflocon/flocon/okhttp/UtilsTest.kt b/FloconAndroid/network/okhttp-interceptor/src/test/kotlin/io/github/openflocon/flocon/okhttp/UtilsTest.kt similarity index 100% rename from FloconAndroid/okhttp-interceptor/src/test/kotlin/io/github/openflocon/flocon/okhttp/UtilsTest.kt rename to FloconAndroid/network/okhttp-interceptor/src/test/kotlin/io/github/openflocon/flocon/okhttp/UtilsTest.kt diff --git a/FloconAndroid/sample-android-only/build.gradle.kts b/FloconAndroid/sample-android-only/build.gradle.kts index c8dc04fa9..64ecd4299 100644 --- a/FloconAndroid/sample-android-only/build.gradle.kts +++ b/FloconAndroid/sample-android-only/build.gradle.kts @@ -87,11 +87,11 @@ dependencies { debugImplementation(project(":deeplinks")) releaseImplementation(project(":deeplinks-no-op")) - debugImplementation(project(":okhttp-interceptor")) - releaseImplementation(project(":okhttp-interceptor-no-op")) + debugImplementation(project(":network:okhttp-interceptor")) + releaseImplementation(project(":network:okhttp-interceptor-no-op")) implementation(project(":grpc:grpc-interceptor-lite")) - debugImplementation(project(":ktor-interceptor")) - releaseImplementation(project(":ktor-interceptor-no-op")) + debugImplementation(project(":network:ktor-interceptor")) + releaseImplementation(project(":network:ktor-interceptor-no-op")) debugImplementation(project(":datastores")) releaseImplementation(project(":datastores-no-op")) } diff --git a/FloconAndroid/sample-multiplatform/build.gradle.kts b/FloconAndroid/sample-multiplatform/build.gradle.kts index 1cad46fc0..51ba4847a 100644 --- a/FloconAndroid/sample-multiplatform/build.gradle.kts +++ b/FloconAndroid/sample-multiplatform/build.gradle.kts @@ -34,7 +34,7 @@ kotlin { val commonMain by getting { dependencies { implementation(project(":flocon")) - implementation(project(":ktor-interceptor")) + implementation(project(":network:ktor-interceptor")) implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index 4b3e4db49..1009160d5 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -20,14 +20,16 @@ include(":sample-android-only") include(":sample-multiplatform") include(":flocon") include(":flocon-no-op") -include(":okhttp-interceptor") -include(":okhttp-interceptor-no-op") +include(":network:okhttp-interceptor") +include(":network:okhttp-interceptor-no-op") include(":grpc:grpc-interceptor") include(":grpc:grpc-interceptor-base") include(":grpc:grpc-interceptor-lite") -include(":ktor-interceptor") -include(":ktor-interceptor-no-op") +include(":network:ktor-interceptor") +include(":network:ktor-interceptor-no-op") include(":datastores") include(":datastores-no-op") include(":deeplinks") include(":deeplinks-no-op") +include(":network:core") +include(":network:core-no-op") From f490aca536d096aaab2a93475c81ee55eb54f91e Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Thu, 12 Mar 2026 14:04:33 +0100 Subject: [PATCH 08/35] feat: Move plugin --- .../FloconNetworkPluginImpl.android.kt | 7 -- .../network/FloconNetworkPluginImpl.jvm.kt | 77 ---------------- .../core}/FloconNetworkPluginImpl.android.kt | 28 +++--- .../network/core}/FloconNetworkPluginImpl.kt | 14 ++- .../network/core}/mapper/BadQualityToJson.kt | 2 +- .../mapper/FloconNetworkRequestToJson.kt | 2 +- .../core}/mapper/MockResponseToJson.kt | 2 +- .../flocon/network/core}/mapper/Websocket.kt | 2 +- .../core}/FloconNetworkPluginImpl.ios.kt | 6 +- .../core/FloconNetworkPluginImpl.jvm.kt | 91 +++++++++++++++++++ 10 files changed, 117 insertions(+), 114 deletions(-) delete mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.android.kt rename FloconAndroid/{flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/network => network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core}/FloconNetworkPluginImpl.android.kt (73%) rename FloconAndroid/{flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network => network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core}/FloconNetworkPluginImpl.kt (90%) rename FloconAndroid/{flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network => network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core}/mapper/BadQualityToJson.kt (98%) rename FloconAndroid/{flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network => network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core}/mapper/FloconNetworkRequestToJson.kt (98%) rename FloconAndroid/{flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network => network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core}/mapper/MockResponseToJson.kt (98%) rename FloconAndroid/{flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network => network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core}/mapper/Websocket.kt (92%) rename FloconAndroid/{flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/network => network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core}/FloconNetworkPluginImpl.ios.kt (75%) create mode 100644 FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.jvm.kt diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.android.kt deleted file mode 100644 index 9c6088f1e..000000000 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.android.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.github.openflocon.flocon.plugins.network - -import io.github.openflocon.flocon.FloconContext - -internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { - TODO("Not yet implemented") -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.jvm.kt b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.jvm.kt index c6729c0f3..f113a8b4f 100644 --- a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.jvm.kt +++ b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.jvm.kt @@ -12,80 +12,3 @@ import java.io.File import java.io.FileInputStream import java.io.FileOutputStream -internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { - return FloconNetworkDataSourceJvm() -} - -internal class FloconNetworkDataSourceJvm( -) : FloconNetworkDataSource { - - private val baseDir: File = File(System.getProperty("user.home"), ".flocon") - - init { - if (!baseDir.exists()) { - baseDir.mkdirs() - } - } - - override fun saveMocksToFile(mocks: List) { - try { - val file = File(baseDir, FLOCON_NETWORK_MOCKS_JSON) - val jsonString = writeMockResponsesToJson(mocks) - FileOutputStream(file).use { - it.write(jsonString.toByteArray(Charsets.UTF_8)) - } - } catch (t: Throwable) { - FloconLogger.logError("issue in saveMocksToFile", t) - } - } - - override fun loadMocksFromFile(): List { - return try { - val file = File(baseDir, FLOCON_NETWORK_MOCKS_JSON) - if (!file.exists()) { - return emptyList() - } - - val jsonString = FileInputStream(file).use { - it.readBytes().toString(Charsets.UTF_8) - } - parseMockResponses(jsonString) - } catch (t: Throwable) { - FloconLogger.logError("issue in loadMocksFromFile", t) - emptyList() - } - } - - override fun loadBadNetworkConfig(): BadQualityConfig? { - return try { - val file = File(baseDir, FLOCON_NETWORK_BAD_CONFIG_JSON) - if (!file.exists()) { - return null - } - - val jsonString = FileInputStream(file).use { - it.readBytes().toString(Charsets.UTF_8) - } - parseBadQualityConfig(jsonString) - } catch (t: Throwable) { - FloconLogger.logError("issue in loadBadNetworkConfig", t) - null - } - } - - override fun saveBadNetworkConfig(config: BadQualityConfig?) { - try { - val file = File(baseDir, FLOCON_NETWORK_BAD_CONFIG_JSON) - if (config == null) { - file.delete() - } else { - val jsonString = config.toJsonString() - FileOutputStream(file).use { - it.write(jsonString.toByteArray(Charsets.UTF_8)) - } - } - } catch (t: Throwable) { - FloconLogger.logError("issue in saveBadNetworkConfig", t) - } - } -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPluginImpl.android.kt b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.android.kt similarity index 73% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPluginImpl.android.kt rename to FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.android.kt index 0b7493ae0..e11512cc2 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPluginImpl.android.kt +++ b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.android.kt @@ -1,29 +1,27 @@ -package io.github.openflocon.flocon.pluginsold.network +package io.github.openflocon.flocon.network.core import android.content.Context import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.plugins.network.FLOCON_NETWORK_BAD_CONFIG_JSON -import io.github.openflocon.flocon.plugins.network.FLOCON_NETWORK_MOCKS_JSON -import io.github.openflocon.flocon.plugins.network.FloconNetworkDataSource -import io.github.openflocon.flocon.plugins.network.mapper.parseBadQualityConfig -import io.github.openflocon.flocon.plugins.network.mapper.parseMockResponses -import io.github.openflocon.flocon.plugins.network.mapper.toJsonString -import io.github.openflocon.flocon.plugins.network.mapper.writeMockResponsesToJson +import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig +import io.github.openflocon.flocon.network.core.mapper.parseMockResponses +import io.github.openflocon.flocon.network.core.mapper.toJsonString +import io.github.openflocon.flocon.network.core.mapper.writeMockResponsesToJson import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse import java.io.File import java.io.FileInputStream import java.io.FileOutputStream -//internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { -// return FloconNetworkDataSourceAndroid( -// context = context.context, -// ) -//} +internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { + return FloconNetworkDataSourceAndroid( + context = context.context, + ) +} -internal class FloconNetworkDataSourceAndroid(private val context: Context) : - FloconNetworkDataSource { +internal class FloconNetworkDataSourceAndroid( + private val context: Context +) : FloconNetworkDataSource { override fun saveMocksToFile(mocks: List) { try { val file = File(context.filesDir, FLOCON_NETWORK_MOCKS_JSON) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt similarity index 90% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt rename to FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt index 6d2a9c0b8..f6d5a0a5d 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network +package io.github.openflocon.flocon.network.core import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconContext @@ -7,13 +7,11 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.network.mapper.floconNetworkCallRequestToJson -import io.github.openflocon.flocon.plugins.network.mapper.floconNetworkCallResponseToJson -import io.github.openflocon.flocon.plugins.network.mapper.floconNetworkWebSocketEventToJson -import io.github.openflocon.flocon.plugins.network.mapper.parseBadQualityConfig -import io.github.openflocon.flocon.plugins.network.mapper.parseMockResponses -import io.github.openflocon.flocon.plugins.network.mapper.parseWebSocketMockMessage -import io.github.openflocon.flocon.plugins.network.mapper.webSocketIdsToJsonArray +import io.github.openflocon.flocon.network.core.mapper.floconNetworkCallResponseToJson +import io.github.openflocon.flocon.network.core.mapper.floconNetworkWebSocketEventToJson +import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig +import io.github.openflocon.flocon.network.core.mapper.parseMockResponses +import io.github.openflocon.flocon.network.core.mapper.parseWebSocketMockMessage import io.github.openflocon.flocon.pluginsold.network.FloconNetworkConfig import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/BadQualityToJson.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/BadQualityToJson.kt similarity index 98% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/BadQualityToJson.kt rename to FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/BadQualityToJson.kt index 97112eb6f..0b4c0950e 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/BadQualityToJson.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/BadQualityToJson.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.mapper +package io.github.openflocon.flocon.network.core.mapper import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/FloconNetworkRequestToJson.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt similarity index 98% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/FloconNetworkRequestToJson.kt rename to FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt index e8b849d6c..45d3977cd 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/FloconNetworkRequestToJson.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt @@ -1,6 +1,6 @@ @file:OptIn(ExperimentalUuidApi::class) -package io.github.openflocon.flocon.plugins.network.mapper +package io.github.openflocon.flocon.network.core.mapper import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/MockResponseToJson.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt similarity index 98% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/MockResponseToJson.kt rename to FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt index fd6efd088..ba7227eed 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/MockResponseToJson.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.mapper +package io.github.openflocon.flocon.network.core.mapper import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/Websocket.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/Websocket.kt similarity index 92% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/Websocket.kt rename to FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/Websocket.kt index 5212883e4..8eeaeb931 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/network/mapper/Websocket.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/Websocket.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.network.mapper +package io.github.openflocon.flocon.network.core.mapper import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.ios.kt b/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.ios.kt similarity index 75% rename from FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.ios.kt rename to FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.ios.kt index bdccd4100..dc587f51f 100644 --- a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.ios.kt +++ b/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.ios.kt @@ -1,8 +1,8 @@ -package io.github.openflocon.flocon.plugins.network +package io.github.openflocon.flocon.network.core import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig -import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { return FloconNetworkDataSourceIOs() diff --git a/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.jvm.kt b/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.jvm.kt new file mode 100644 index 000000000..16342afe8 --- /dev/null +++ b/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.jvm.kt @@ -0,0 +1,91 @@ +package io.github.openflocon.flocon.network.core + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig +import io.github.openflocon.flocon.network.core.mapper.parseMockResponses +import io.github.openflocon.flocon.network.core.mapper.toJsonString +import io.github.openflocon.flocon.network.core.mapper.writeMockResponsesToJson +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream + +internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { + return FloconNetworkDataSourceJvm() +} + +internal class FloconNetworkDataSourceJvm( +) : FloconNetworkDataSource { + + private val baseDir: File = File(System.getProperty("user.home"), ".flocon") + + init { + if (!baseDir.exists()) { + baseDir.mkdirs() + } + } + + override fun saveMocksToFile(mocks: List) { + try { + val file = File(baseDir, FLOCON_NETWORK_MOCKS_JSON) + val jsonString = writeMockResponsesToJson(mocks) + FileOutputStream(file).use { + it.write(jsonString.toByteArray(Charsets.UTF_8)) + } + } catch (t: Throwable) { + FloconLogger.logError("issue in saveMocksToFile", t) + } + } + + override fun loadMocksFromFile(): List { + return try { + val file = File(baseDir, FLOCON_NETWORK_MOCKS_JSON) + if (!file.exists()) { + return emptyList() + } + + val jsonString = FileInputStream(file).use { + it.readBytes().toString(Charsets.UTF_8) + } + parseMockResponses(jsonString) + } catch (t: Throwable) { + FloconLogger.logError("issue in loadMocksFromFile", t) + emptyList() + } + } + + override fun loadBadNetworkConfig(): BadQualityConfig? { + return try { + val file = File(baseDir, FLOCON_NETWORK_BAD_CONFIG_JSON) + if (!file.exists()) { + return null + } + + val jsonString = FileInputStream(file).use { + it.readBytes().toString(Charsets.UTF_8) + } + parseBadQualityConfig(jsonString) + } catch (t: Throwable) { + FloconLogger.logError("issue in loadBadNetworkConfig", t) + null + } + } + + override fun saveBadNetworkConfig(config: BadQualityConfig?) { + try { + val file = File(baseDir, FLOCON_NETWORK_BAD_CONFIG_JSON) + if (config == null) { + file.delete() + } else { + val jsonString = config.toJsonString() + FileOutputStream(file).use { + it.write(jsonString.toByteArray(Charsets.UTF_8)) + } + } + } catch (t: Throwable) { + FloconLogger.logError("issue in saveBadNetworkConfig", t) + } + } +} \ No newline at end of file From 754251f7402bce22107011a7cff2317a3a34159f Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Thu, 12 Mar 2026 15:07:36 +0100 Subject: [PATCH 09/35] feat: OkHttp work --- .../plugins/deeplinks/FloconDeeplinks.kt | 5 - .../io/github/openflocon/flocon/FloconApp.kt | 3 +- .../openflocon/flocon/FloconConfiguration.kt | 38 +++- .../io/github/openflocon/flocon/FloconCore.kt | 2 +- .../github/openflocon/flocon/FloconPlugin.kt | 2 +- .../flocon/core/FloconMessageSender.kt | 2 + .../openflocon/flocon/dsl/FloconMarker.kt | 14 ++ .../flocon/error/PluginNotInitialized.kt | 6 + .../analytics/FloconAnalyticsPlugin.kt | 1 + .../database/FloconDatabasePlugin.kt | 2 + .../pluginsold/device/FloconDevicePlugin.kt | 2 + .../pluginsold/files/FloconFilesPlugin.kt | 2 + .../pluginsold/network/FloconNetworkPlugin.kt | 18 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 2 + .../pluginsold/tables/FloconTablesPlugin.kt | 2 + .../network/FloconNetworkPluginImpl.jvm.kt | 14 -- .../network/core/FloconNetworkPluginImpl.kt | 51 +++-- .../network/ktor-interceptor/build.gradle.kts | 5 +- .../okhttp-interceptor/build.gradle.kts | 2 +- .../flocon/okhttp/OkHttpInterceptor.kt | 210 +++++++++--------- .../flocon/myapplication/MainActivity.kt | 41 ++-- 21 files changed, 239 insertions(+), 185 deletions(-) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/dsl/FloconMarker.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/error/PluginNotInitialized.kt delete mode 100644 FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.jvm.kt diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt index 2e9e69375..c5a3c8aa8 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -34,26 +34,21 @@ internal class FloconDeeplinksPluginImpl( method: String, body: String, ) { - println("Deeplinks: message received $($method) ($body)") // no op } override suspend fun onConnectedToServer() { - println("Deeplinks: connected (${deeplinks})") registerDeeplinks(deeplinks) } override suspend fun registerDeeplinks(deeplinks: List) { try { - println("Deeplinks: sending") sender.send( plugin = Protocol.FromDevice.Deeplink.Plugin, method = Protocol.FromDevice.Deeplink.Method.GetDeeplinks, body = toDeeplinksJson(deeplinks) ) - println("Deeplinks: sent") } catch (t: Throwable) { - println("Deeplinks: error: ${t.message}") t.printStackTrace() FloconLogger.logError("deeplink mapping error", t) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt index 176c16416..7b2eafcf8 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconApp.kt @@ -7,7 +7,8 @@ abstract class FloconApp { companion object { var instance: FloconApp? = null - private set + get() = field ?: error("FloconApp is not initialized") + internal set } interface Client { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt index e1253bf15..11dd42161 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -10,10 +10,11 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow class FloconConfiguration internal constructor( + private val context: FloconContext, private val client: FloconClient ) { - internal val plugins = mutableListOf() + private val plugins: MutableMap FloconPlugin> = mutableMapOf() /** * Install a plugin with the given [factory] and optional [configure] block. @@ -22,13 +23,24 @@ class FloconConfiguration internal constructor( factory: FloconPluginFactory, configure: Config.() -> Unit = {} ) { - val plugin = factory.install( - config = factory.createConfig() - .apply { configure() }, - app = DumpObject(client = client) + plugins[factory.pluginId] = { scope -> + val config = factory.createConfig() + .apply { configure() } + + factory.install( + config = config, + app = scope + ) + } + } + + fun build(): List { + val app = DumpObject( + context = context, + client = client ) - plugins.add(plugin) + return plugins.values.map { it.invoke(app) } } } @@ -36,17 +48,22 @@ class FloconConfiguration internal constructor( fun startFlocon(context: FloconContext, block: FloconConfiguration.() -> Unit) { val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) val client = FloconClient(context = context) - val configuration = FloconConfiguration(client = client).apply(block) + val configuration = FloconConfiguration( + context = context, + client = client + ) + .apply(block) Flocon( context = context, scope = scope, client = client, - plugins = configuration.plugins + plugins = configuration.build() ) } class DumpObject( + context: FloconContext, client: Client ) : FloconApp() { @@ -55,4 +72,9 @@ class DumpObject( private val _initialized = MutableStateFlow(false) override val isInitialized: StateFlow = _initialized.asStateFlow() + init { + this.context = context + instance = this + } + } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt index be8a0c673..996721541 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt @@ -29,7 +29,7 @@ abstract class FloconCore : FloconApp() { protected fun initializeFlocon( context: FloconContext, - configuration: FloconConfiguration = FloconConfiguration(TODO()) + configuration: FloconConfiguration = FloconConfiguration(TODO(), TODO()) ) { //super.initializeFlocon(context) // val newClient = FloconClientImpl(context, configuration) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt index 53865e802..65aa4bbe0 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt @@ -22,7 +22,7 @@ interface FloconPluginConfig */ interface FloconPluginKey { val name: String - val pluginId: String? get() = null + val pluginId: String } /** diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt index dbff6b15b..a61ba4772 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.core interface FloconMessageSender { + suspend fun send( plugin: String, method: String, @@ -8,4 +9,5 @@ interface FloconMessageSender { ) suspend fun sendPendingMessages() + } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/dsl/FloconMarker.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/dsl/FloconMarker.kt new file mode 100644 index 000000000..80868b751 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/dsl/FloconMarker.kt @@ -0,0 +1,14 @@ +package io.github.openflocon.flocon.dsl + +@RequiresOptIn( + message = "Used to mark internal Flocon APIs", + level = RequiresOptIn.Level.ERROR +) +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.FIELD, + AnnotationTarget.PROPERTY +) +annotation class FloconMarker diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/error/PluginNotInitialized.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/error/PluginNotInitialized.kt new file mode 100644 index 000000000..60da21935 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/error/PluginNotInitialized.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon.error + +import io.github.openflocon.flocon.dsl.FloconMarker + +@FloconMarker +fun pluginNotInitialized(pluginName: String): Nothing = error("$pluginName is not initialized") \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt index a64cc3866..44ad622b9 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt @@ -16,6 +16,7 @@ object FloconAnalytics : FloconPluginFactory { override val name: String get() = TODO("Not yet implemented") + override val pluginId: String + get() = TODO("Not yet implemented") } interface FloconFilesPlugin : FloconPlugin \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt index 2f220e3b2..8836baf08 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt @@ -1,9 +1,7 @@ package io.github.openflocon.flocon.pluginsold.network -import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig -import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse @@ -16,18 +14,6 @@ class FloconNetworkConfig : FloconPluginConfig { val mocks = mutableListOf() } -/** - * Flocon Network Plugin. - * Used to inspect HTTP/S and WebSocket calls. - */ -object FloconNetwork : FloconPluginFactory { - override fun createConfig(): FloconNetworkConfig = TODO() - override fun install(config: FloconNetworkConfig, app: FloconApp): FloconNetworkPlugin = TODO() - - override val name: String = "" -} - - interface FloconNetworkPlugin : FloconPlugin { val mocks: Collection val badQualityConfig: BadQualityConfig? @@ -35,9 +21,9 @@ interface FloconNetworkPlugin : FloconPlugin { fun logRequest(request: FloconNetworkCallRequest) fun logResponse(response: FloconNetworkCallResponse) - fun logWebSocket( + suspend fun logWebSocket( event: FloconWebSocketEvent, ) - fun registerWebSocketMockListener(id: String, listener: FloconWebSocketMockListener) + suspend fun registerWebSocketMockListener(id: String, listener: FloconWebSocketMockListener) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt index 6beb16aa2..9af248027 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt @@ -23,6 +23,8 @@ object FloconPreferences : FloconPluginFactory { override val name: String get() = TODO("Not yet implemented") + override val pluginId: String + get() = TODO("Not yet implemented") } //fun floconTable(tableName: String) : TableBuilder { diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.jvm.kt b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.jvm.kt deleted file mode 100644 index f113a8b4f..000000000 --- a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/network/FloconNetworkPluginImpl.jvm.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.openflocon.flocon.plugins.network - -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.plugins.network.mapper.parseBadQualityConfig -import io.github.openflocon.flocon.plugins.network.mapper.parseMockResponses -import io.github.openflocon.flocon.plugins.network.mapper.toJsonString -import io.github.openflocon.flocon.plugins.network.mapper.writeMockResponsesToJson -import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig -import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse -import java.io.File -import java.io.FileInputStream -import java.io.FileOutputStream - diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt index f6d5a0a5d..e0057fc06 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt @@ -7,11 +7,15 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.dsl.FloconMarker +import io.github.openflocon.flocon.error.pluginNotInitialized +import io.github.openflocon.flocon.network.core.mapper.floconNetworkCallRequestToJson import io.github.openflocon.flocon.network.core.mapper.floconNetworkCallResponseToJson import io.github.openflocon.flocon.network.core.mapper.floconNetworkWebSocketEventToJson import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig import io.github.openflocon.flocon.network.core.mapper.parseMockResponses import io.github.openflocon.flocon.network.core.mapper.parseWebSocketMockMessage +import io.github.openflocon.flocon.network.core.mapper.webSocketIdsToJsonArray import io.github.openflocon.flocon.pluginsold.network.FloconNetworkConfig import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig @@ -39,6 +43,7 @@ object FloconNetwork : FloconPluginFactory>(emptyMap()) - private val _mocks = MutableStateFlow>(dataSource.loadMocksFromFile()) + private val _mocks = MutableStateFlow(dataSource.loadMocksFromFile()) override val mocks: List get() = _mocks.value - private val _badQualityConfig = - MutableStateFlow(dataSource.loadBadNetworkConfig()) + private val _badQualityConfig = MutableStateFlow(dataSource.loadBadNetworkConfig()) override val badQualityConfig: BadQualityConfig? get() = _badQualityConfig.value override fun logRequest(request: FloconNetworkCallRequest) { try { -// sender.send( -// plugin = Protocol.FromDevice.Network.Plugin, -// method = Protocol.FromDevice.Network.Method.LogNetworkCallRequest, -// body = request.floconNetworkCallRequestToJson(), -// ) + coroutineScope.launch { + sender.send( + plugin = Protocol.FromDevice.Network.Plugin, + method = Protocol.FromDevice.Network.Method.LogNetworkCallRequest, + body = request.floconNetworkCallRequestToJson(), + ) + } } catch (t: Throwable) { FloconLogger.logError("Network json mapping error", t) } @@ -103,7 +114,7 @@ internal class FloconNetworkPluginImpl( } } - override fun logWebSocket( + override suspend fun logWebSocket( event: FloconWebSocketEvent, ) { coroutineScope.launch { @@ -149,7 +160,7 @@ internal class FloconNetworkPluginImpl( updateWebSocketIds() } - override fun registerWebSocketMockListener( + override suspend fun registerWebSocketMockListener( id: String, listener: FloconWebSocketMockListener ) { @@ -159,11 +170,15 @@ internal class FloconNetworkPluginImpl( updateWebSocketIds() } - private fun updateWebSocketIds() { -// sender.send( -// plugin = Protocol.FromDevice.Network.Plugin, -// method = Protocol.FromDevice.Network.Method.RegisterWebSocketIds, -// body = webSocketIdsToJsonArray(ids = websocketListeners.value.keys), -// ) + private suspend fun updateWebSocketIds() { + sender.send( + plugin = Protocol.FromDevice.Network.Plugin, + method = Protocol.FromDevice.Network.Method.RegisterWebSocketIds, + body = webSocketIdsToJsonArray(ids = websocketListeners.value.keys), + ) + } + + companion object { + var plugin: FloconNetworkPlugin? = null } } \ No newline at end of file diff --git a/FloconAndroid/network/ktor-interceptor/build.gradle.kts b/FloconAndroid/network/ktor-interceptor/build.gradle.kts index 0bc55cdc3..2404e2b0b 100644 --- a/FloconAndroid/network/ktor-interceptor/build.gradle.kts +++ b/FloconAndroid/network/ktor-interceptor/build.gradle.kts @@ -22,7 +22,10 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation(project(":network:core")) + + api(project(":flocon")) + api(project(":network:core")) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0") implementation(libs.ktor.client.core) } diff --git a/FloconAndroid/network/okhttp-interceptor/build.gradle.kts b/FloconAndroid/network/okhttp-interceptor/build.gradle.kts index 2ab89d589..a30d90427 100644 --- a/FloconAndroid/network/okhttp-interceptor/build.gradle.kts +++ b/FloconAndroid/network/okhttp-interceptor/build.gradle.kts @@ -41,7 +41,7 @@ kotlin { dependencies { - implementation(project(":network:core")) + api(project(":network:core")) implementation(platform(libs.kotlinx.coroutines.bom)) implementation(libs.jetbrains.kotlinx.coroutines.core) diff --git a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt index 88e0cf095..1986f8f42 100644 --- a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt +++ b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt @@ -2,8 +2,14 @@ package io.github.openflocon.flocon.okhttp +import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.network.core.networkPlugin +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkResponse import okhttp3.Interceptor +import okhttp3.MediaType import okhttp3.Request import okhttp3.Response import java.io.IOException @@ -23,14 +29,15 @@ class FloconOkhttpInterceptor( @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { - val floconNetworkPlugin = TODO()//FloconApp.instance?.client?.networkPlugin - if (floconNetworkPlugin == null || !shouldLog(chain)) { + val floconNetworkPlugin = FloconApp.instance!!.networkPlugin + + if (!shouldLog(chain)) { // on no op, do not intercept the call, just execute it return chain.proceed(chain.request()) } - Uuid.random().toString() - "http" + val floconCallId = Uuid.random().toString() + val floconNetworkType = "http" val request = chain.request() @@ -60,7 +67,7 @@ class FloconOkhttpInterceptor( ) val isMocked = mockConfig != null - FloconNetworkRequest( + val floconNetworkRequest = FloconNetworkRequest( url = request.url.toString(), method = request.method, startTime = requestedAt, @@ -70,119 +77,118 @@ class FloconOkhttpInterceptor( isMocked = isMocked, ) -// floconNetworkPlugin.logRequest( -// FloconNetworkCallRequest( -// floconCallId = floconCallId, -// floconNetworkType = floconNetworkType, -// isMocked = isMocked, -// request = floconNetworkRequest, -// ) -// ) + floconNetworkPlugin.logRequest( + FloconNetworkCallRequest( + floconCallId = floconCallId, + floconNetworkType = floconNetworkType, + isMocked = isMocked, + request = floconNetworkRequest, + ) + ) try { - val response = TODO() -// if (isMocked) { -// executeMock(request = request, mock = mockConfig, requestHeaders = requestHeadersMap) -// } else { -// floconNetworkPlugin.badQualityConfig?.let { badQualityConfig -> -// executeBadQuality( -// badQualityConfig = badQualityConfig, -// request = request, -// ) -// } ?: run { -// chain.proceed(request) -// } -// } + val response = if (isMocked) { + executeMock( + request = request, + mock = mockConfig, + requestHeaders = requestHeadersMap + ) + } else { + floconNetworkPlugin.badQualityConfig?.let { badQualityConfig -> + executeBadQuality( + badQualityConfig = badQualityConfig, + request = request, + ) + } ?: run { + chain.proceed(request) + } + } val endTime = System.nanoTime() - - (endTime - startTime) / 1e6 + val durationMs: Double = (endTime - startTime) / 1e6 // To get the response body, be careful // because the body can only be read once. // It must be duplicated so that the chain can continue normally. -// val responseBody = response.body -// var responseBodyString: String? = null -// var responseSize: Long? = null -// val responseContentType: MediaType? = responseBody?.contentType() -// -// val responseHeadersMap = -// response.headers.toMultimap().mapValues { it.value.joinToString(",") } -// -// if (responseBody != null) { -// val (bodyString, bodySize) = extractResponseBodyInfo( -// response = response, -// responseHeaders = responseHeadersMap, -// ) -// responseBodyString = bodyString -// responseSize = bodySize -// } - -// val isImage = -// responseContentType?.toString()?.startsWith("image/") == true || (isImage?.invoke( -// FloconNetworkIsImageParams( -// request = request, -// response = response, -// responseContentType = responseContentType?.toString(), -// ) -// ) == true) -// -// val requestHeadersMapUpToDate = -// response.request.headers.toMultimap().mapValues { it.value.joinToString(",") } -// -// val floconCallResponse = FloconNetworkResponse( -// httpCode = response.code, -// contentType = responseContentType?.toString(), -// body = responseBodyString.takeUnless { isImage }, // dont send images responses bytes -// headers = responseHeadersMap, -// size = responseSize, -// grpcStatus = null, -// error = null, -// requestHeaders = requestHeadersMapUpToDate, -// isImage = isImage, -// ) -// -// floconNetworkPlugin.logResponse( -// FloconNetworkCallResponse( -// floconCallId = floconCallId, -// durationMs = durationMs, -// floconNetworkType = floconNetworkType, -// isMocked = isMocked, -// response = floconCallResponse, -// ) -// ) + val responseBody = response.body + var responseBodyString: String? = null + var responseSize: Long? = null + val responseContentType: MediaType? = responseBody?.contentType() + + val responseHeadersMap = + response.headers.toMultimap().mapValues { it.value.joinToString(",") } + + if (responseBody != null) { + val (bodyString, bodySize) = extractResponseBodyInfo( + response = response, + responseHeaders = responseHeadersMap, + ) + responseBodyString = bodyString + responseSize = bodySize + } + + val isImage = + responseContentType?.toString()?.startsWith("image/") == true || (isImage?.invoke( + FloconNetworkIsImageParams( + request = request, + response = response, + responseContentType = responseContentType?.toString(), + ) + ) == true) + + val requestHeadersMapUpToDate = + response.request.headers.toMultimap().mapValues { it.value.joinToString(",") } + + val floconCallResponse = FloconNetworkResponse( + httpCode = response.code, + contentType = responseContentType?.toString(), + body = responseBodyString.takeUnless { isImage }, // dont send images responses bytes + headers = responseHeadersMap, + size = responseSize, + grpcStatus = null, + error = null, + requestHeaders = requestHeadersMapUpToDate, + isImage = isImage, + ) + + floconNetworkPlugin.logResponse( + FloconNetworkCallResponse( + floconCallId = floconCallId, + durationMs = durationMs, + floconNetworkType = floconNetworkType, + isMocked = isMocked, + response = floconCallResponse, + ) + ) // Rebuild the response with a new body so that the chain can continue // The original response body is already consumed by peekBody, so no need to rebuild with it. // Just return the original response if you don't modify the body itself. return response } catch (e: IOException) { - val endTime = System.nanoTime() + val durationMs: Double = (endTime - startTime) / 1e6 + val floconCallResponse = FloconNetworkResponse( + httpCode = null, + contentType = null, + body = null, + headers = emptyMap(), + size = null, + grpcStatus = null, + error = e.message ?: e.javaClass.simpleName, + requestHeaders = null, + isImage = false, + ) - (endTime - startTime) / 1e6 - -// val floconCallResponse = FloconNetworkResponse( -// httpCode = null, -// contentType = null, -// body = null, -// headers = emptyMap(), -// size = null, -// grpcStatus = null, -// error = e.message ?: e.javaClass.simpleName, -// requestHeaders = null, -// isImage = false, -// ) - -// floconNetworkPlugin.logResponse( -// FloconNetworkCallResponse( -// floconCallId = floconCallId, -// durationMs = durationMs, -// floconNetworkType = floconNetworkType, -// isMocked = isMocked, -// response = floconCallResponse, -// ) -// ) + floconNetworkPlugin.logResponse( + FloconNetworkCallResponse( + floconCallId = floconCallId, + durationMs = durationMs, + floconNetworkType = floconNetworkType, + isMocked = isMocked, + response = floconCallResponse, + ) + ) throw e } } diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt index 3adc8f327..99ef90936 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt @@ -27,10 +27,13 @@ import io.github.openflocon.flocon.myapplication.database.model.DogEntity import io.github.openflocon.flocon.myapplication.grpc.GrpcController import io.github.openflocon.flocon.myapplication.ui.ImagesListView import io.github.openflocon.flocon.myapplication.ui.theme.MyApplicationTheme +import io.github.openflocon.flocon.network.core.FloconNetwork +import io.github.openflocon.flocon.okhttp.FloconOkhttpInterceptor import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks import io.github.openflocon.flocon.startFlocon import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch +import okhttp3.OkHttpClient import kotlin.random.Random import kotlin.uuid.ExperimentalUuidApi @@ -46,21 +49,21 @@ class MainActivity : ComponentActivity() { Toast.makeText(this, "opend with : $it", Toast.LENGTH_LONG).show() } -// val okHttpClient = OkHttpClient() -// .newBuilder() -// .addInterceptor( -// FloconOkhttpInterceptor( -// isImage = { -// it.request.url.toString().contains("picsum") -// }, -// /*shouldLog = { -// val url = it.request().url.toString() -// println("url: $url") -// url.contains("1").not() -// }*/ -// ) -// ) -// .build() + val okHttpClient = OkHttpClient() + .newBuilder() + .addInterceptor( + FloconOkhttpInterceptor( + isImage = { + it.request.url.toString().contains("picsum") + }, + /*shouldLog = { + val url = it.request().url.toString() + println("url: $url") + url.contains("1").not() + }*/ + ) + ) + .build() // initializeSharedPreferences(applicationContext) // initializeDatabases(context = applicationContext) @@ -72,7 +75,7 @@ class MainActivity : ComponentActivity() { // initializeSharedPreferencesAfterInit(applicationContext) // initializeDatastores(applicationContext) -// val dummyHttpCaller = DummyHttpCaller(client = okHttpClient) + val dummyHttpCaller = DummyHttpCaller(client = okHttpClient) // val dummyWebsocketCaller = DummyWebsocketCaller(client = okHttpClient) // GlobalScope.launch { dummyWebsocketCaller.connectToWebsocket() } // val graphQlTester = GraphQlTester(client = okHttpClient) @@ -102,7 +105,7 @@ class MainActivity : ComponentActivity() { ) { Button( onClick = { - //dummyHttpCaller.call() + dummyHttpCaller.call() } ) { Text("okhttp test") @@ -228,6 +231,10 @@ class MainActivity : ComponentActivity() { description = "Open a post and send a comment" ) } + + install(FloconNetwork) { + + } } } From a523461ea1048a33c5b8cae7a1e677d79ee9c408 Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Thu, 12 Mar 2026 16:33:02 +0100 Subject: [PATCH 10/35] feat: Clean install --- .../plugins/deeplinks/FloconDeeplinks.kt | 16 ++- .../files/FloconFilesPlugin.android.kt | 5 + .../websocket/FloconHttpClient.android.kt | 7 +- .../websocket/FloconHttpClientAndroid.kt | 2 + .../io/github/openflocon/flocon/Flocon.kt | 27 +++-- .../openflocon/flocon/FloconConfiguration.kt | 36 +++--- .../io/github/openflocon/flocon/FloconCore.kt | 84 ------------- .../io/github/openflocon/flocon/FloconFile.kt | 5 +- .../github/openflocon/flocon/FloconPlugin.kt | 10 +- .../flocon/client/FloconClientImpl.kt | 110 +----------------- .../flocon/core/FloconFileSender.kt | 4 + .../openflocon/flocon/model/FloconFileInfo.kt | 5 +- .../analytics/FloconAnalyticsPlugin.kt | 10 +- .../FloconCrashReporterPlugin.kt | 8 +- .../dashboard/FloconDashboardPlugin.kt | 7 +- .../plugins/database/FloconDatabasePlugin.kt | 13 +-- .../plugins/device/FloconDevicePluginImpl.kt | 10 +- .../flocon/plugins/files/FloconFilesPlugin.kt | 19 ++- .../sharedprefs/FloconSharedPrefsPlugin.kt | 9 +- .../plugins/tables/FloconTablesPlugin.kt | 8 +- .../analytics/FloconAnalyticsPlugin.kt | 6 +- .../database/FloconDatabasePlugin.kt | 6 +- .../pluginsold/device/FloconDevicePlugin.kt | 5 +- .../pluginsold/files/FloconFilesPlugin.kt | 6 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 6 +- .../pluginsold/tables/FloconTablesPlugin.kt | 6 +- .../flocon/websocket/FloconHttpClient.kt | 7 +- .../io/github/openflocon/flocon/Flocon.ios.kt | 8 -- .../io/github/openflocon/flocon/Flocon.jvm.kt | 11 -- .../FloconNetworkDataSource.android.kt | 7 ++ .../FloconNetworkDataSourceAndroid.kt} | 11 +- .../flocon/network/core/FloconNetwork.kt | 41 +++++++ .../flocon/network/core/NetworkCore.kt | 3 - .../datasource/FloconNetworkDataSource.kt | 16 +++ .../{ => plugin}/FloconNetworkPluginImpl.kt | 39 +------ .../datasource/FloconNetworkDataSource.ios.kt | 7 ++ .../FloconNetworkDataSourceImpl.kt} | 9 +- .../datasource/FloconNetworkDataSource.jvm.kt | 7 ++ .../FloconNetworkDataSourceImpl.kt} | 11 +- .../flocon/okhttp/OkHttpInterceptor.kt | 4 +- .../repository/DeeplinkRepositoryImpl.kt | 2 - 41 files changed, 255 insertions(+), 358 deletions(-) delete mode 100644 FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/Flocon.ios.kt delete mode 100644 FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/Flocon.jvm.kt create mode 100644 FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.android.kt rename FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/{FloconNetworkPluginImpl.android.kt => datasource/FloconNetworkDataSourceAndroid.kt} (90%) create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt delete mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/NetworkCore.kt create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.kt rename FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/{ => plugin}/FloconNetworkPluginImpl.kt (78%) create mode 100644 FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.ios.kt rename FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/{FloconNetworkPluginImpl.ios.kt => datasource/FloconNetworkDataSourceImpl.kt} (62%) create mode 100644 FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.jvm.kt rename FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/{FloconNetworkPluginImpl.jvm.kt => datasource/FloconNetworkDataSourceImpl.kt} (91%) diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt index c5a3c8aa8..3bae66feb 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -1,23 +1,27 @@ package io.github.openflocon.flocon.plugins.deeplinks -import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.update object FloconDeeplinks : FloconPluginFactory { override val name: String = "Deeplinks" override val pluginId: String = FloconDeeplinks::class.simpleName!! override fun createConfig() = FloconDeeplinksConfig() - override fun install(config: FloconDeeplinksConfig, app: FloconApp): FloconDeeplinksPlugin { + + @OptIn(FloconMarker::class) + override fun install( + pluginConfig: FloconDeeplinksConfig, + floconConfig: FloconConfig + ): FloconDeeplinksPlugin { val plugin = FloconDeeplinksPluginImpl( - deeplinks = config.deeplinks, - sender = app.client as FloconMessageSender + deeplinks = pluginConfig.deeplinks, + sender = floconConfig.client as FloconMessageSender ) return plugin diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt index 5d8ad7a43..435aa072d 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt @@ -3,6 +3,7 @@ package io.github.openflocon.flocon.pluginsold.files import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconFile import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.plugins.files.FileDataSource import io.github.openflocon.flocon.plugins.files.model.fromdevice.FileDataModel import java.io.File @@ -10,6 +11,8 @@ import java.io.File internal class FileDataSourceAndroid( private val context: FloconContext, ) : FileDataSource { + + @FloconMarker override fun getFile( path: String, isConstantPath: Boolean @@ -26,6 +29,7 @@ internal class FileDataSourceAndroid( return file.takeIf { it.exists() }?.let { FloconFile(it) } } + @FloconMarker override fun getFolderContent( path: String, isConstantPath: Boolean, @@ -86,6 +90,7 @@ internal class FileDataSourceAndroid( } } + @FloconMarker override fun deleteFolderContent(folder: FloconFile) { deleteFolderContent(folder.file) } diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.android.kt index 6fa9bf0f0..92b85cda4 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.android.kt @@ -1,5 +1,6 @@ package io.github.openflocon.flocon.websocket -internal actual fun buildFloconHttpClient(): FloconHttpClient { - return FloconHttpClientAndroid() -} \ No newline at end of file +import io.github.openflocon.flocon.dsl.FloconMarker + +@FloconMarker +internal actual fun buildFloconHttpClient(): FloconHttpClient = FloconHttpClientAndroid() \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClientAndroid.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClientAndroid.kt index be744b5bf..28e5bda02 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClientAndroid.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClientAndroid.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.websocket import io.github.openflocon.flocon.FloconFile +import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.model.FloconFileInfo import okhttp3.MediaType.Companion.toMediaType import okhttp3.MultipartBody @@ -12,6 +13,7 @@ import okhttp3.RequestBody.Companion.asRequestBody * The android client uses okhttp, because for android-only project there's more chance to having okhttp than ktor * it prevent conflicts with ktor versions also */ +@FloconMarker internal class FloconHttpClientAndroid : FloconHttpClient { private val client by lazy { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt index 31eab3f3d..075727480 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt @@ -1,28 +1,27 @@ +@file:OptIn(FloconMarker::class) + package io.github.openflocon.flocon import io.github.openflocon.flocon.FloconApp.Client -import io.github.openflocon.flocon.client.FloconClient import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.model.floconMessageFromServerFromJson -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -internal class Flocon( - private val context: FloconContext, - private val scope: CoroutineScope, - private val client: FloconClient, +class Flocon internal constructor( + private val config: FloconConfig, private val plugins: List ) { init { - scope.launch { + config.scope.launch { start( - client = client, - context = context, + client = config.client, + context = config.context, ) } } @@ -34,7 +33,7 @@ internal class Flocon( onClosed = { println("Client - Closed") // try again to connect - scope.launch { + config.scope.launch { start( client = client, context = context, @@ -68,7 +67,7 @@ internal class Flocon( } private fun onMessageReceived(message: String) { - scope.launch(Dispatchers.IO) { + config.scope.launch(Dispatchers.IO) { floconMessageFromServerFromJson(message)?.let { messageFromServer -> plugins.find { it.key == messageFromServer.plugin } ?.onMessageReceived( @@ -79,4 +78,10 @@ internal class Flocon( } } + companion object { + var instance: Flocon? = null + get() = field ?: error("Flocon is not initialized") + internal set + } + } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt index 11dd42161..fb8f00ce3 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon import io.github.openflocon.flocon.client.FloconClient +import io.github.openflocon.flocon.dsl.FloconMarker import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO @@ -10,11 +11,10 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow class FloconConfiguration internal constructor( - private val context: FloconContext, - private val client: FloconClient + private val config: FloconConfig ) { - private val plugins: MutableMap FloconPlugin> = mutableMapOf() + private val plugins: MutableMap FloconPlugin> = mutableMapOf() /** * Install a plugin with the given [factory] and optional [configure] block. @@ -28,36 +28,36 @@ class FloconConfiguration internal constructor( .apply { configure() } factory.install( - config = config, - app = scope + pluginConfig = config, + floconConfig = scope ) } } fun build(): List { - val app = DumpObject( - context = context, - client = client - ) - - return plugins.values.map { it.invoke(app) } + return plugins.values.map { it.invoke(config) } } } +@ConsistentCopyVisibility +data class FloconConfig internal constructor( + val context: FloconContext, + val scope: CoroutineScope, + val client: FloconClient +) + fun startFlocon(context: FloconContext, block: FloconConfiguration.() -> Unit) { - val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) - val client = FloconClient(context = context) - val configuration = FloconConfiguration( + val config = FloconConfig( context = context, - client = client + scope = CoroutineScope(Dispatchers.IO + SupervisorJob()), + client = FloconClient(context = context) ) + val configuration = FloconConfiguration(config = config) .apply(block) Flocon( - context = context, - scope = scope, - client = client, + config = config, plugins = configuration.build() ) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt index 996721541..a834ef254 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt @@ -1,89 +1,5 @@ package io.github.openflocon.flocon -import io.github.openflocon.flocon.core.FloconMessageSender -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext - expect class FloconContext -abstract class FloconCore : FloconApp() { - - private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) - - private var _client: Client? = null - - override val client: Client? - get() { - return _client - } - - private val _isInitialized = MutableStateFlow(false) - override val isInitialized: StateFlow = _isInitialized - - protected fun initializeFlocon( - context: FloconContext, - configuration: FloconConfiguration = FloconConfiguration(TODO(), TODO()) - ) { - //super.initializeFlocon(context) - // val newClient = FloconClientImpl(context, configuration) - //_client = newClient - - // Setup crash handler early to catch crashes during initialization - //newClient.crashReporterPlugin?.setupCrashHandler() - - _isInitialized.value = true - -// scope.launch { -// start( -// client = newClient, -// context = context -// ) -// } - } - - private suspend fun start(client: Client, context: FloconContext) { - // try to connect, it fail : try again in 3s - try { - client.connect( - onClosed = { - // try again to connect - scope.launch { - start( - client = client, - context = context, - ) - } - }, - onMessageReceived = {} - ) - (client as? FloconMessageSender)?.let { - // if success, just send a bonjour - it.send("bonjour", method = "bonjour", body = "bonjour") - it.sendPendingMessages() - } - } catch (t: Throwable) { - if(t.message?.contains("CLEARTEXT communication to localhost not permitted by network security policy") == true) { - withContext(Dispatchers.Main) { - displayClearTextError(context = context) - } - } else { - //t.printStackTrace() - delay(3_000) - start( - client = client, - context = context, - ) - } - } - } - -} - internal expect fun displayClearTextError(context: FloconContext) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconFile.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconFile.kt index 6fa28d86a..c55899b22 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconFile.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconFile.kt @@ -1,3 +1,6 @@ package io.github.openflocon.flocon -internal expect class FloconFile \ No newline at end of file +import io.github.openflocon.flocon.dsl.FloconMarker + +@FloconMarker +expect class FloconFile \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt index 65aa4bbe0..e91903615 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt @@ -1,5 +1,7 @@ package io.github.openflocon.flocon +import io.github.openflocon.flocon.dsl.FloconMarker + /** * Base interface for all Flocon plugins. * Plugins can receive messages from the server and react to connection events. @@ -29,7 +31,8 @@ interface FloconPluginKey { * A factory for creating and installing Flocon plugins. * This is the entry point for Ktor-style [install] calls. */ -interface FloconPluginFactory : FloconPluginKey { +interface FloconPluginFactory : + FloconPluginKey { /** * Create a default configuration instance for the plugin. @@ -37,8 +40,9 @@ interface FloconPluginFactory -) : FloconApp.Client, FloconMessageSender, FloconFileSender { - - private val FLOCON_WEBSOCKET_PORT = 9023 - private val FLOCON_HTTP_PORT = 9024 - - private val appInstance by lazy { currentTimeMillis() } - private val appInfos by lazy { getAppInfos(context) } - private val versionName by lazy { BuildConfig.APP_VERSION } - private val address by lazy { getServerHost(context) } - - private val webSocketClient: FloconWebSocketClient = buildFloconWebSocketClient() - private val httpClient: FloconHttpClient = buildFloconHttpClient() - - private val coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()) - - - fun getPlugin(key: String): T? { - return plugins.find { it.key == key } as? T - } - - @Throws(Throwable::class) - override suspend fun connect( - onClosed: () -> Unit, - onMessageReceived: (message: String) -> Unit - ) { - webSocketClient.connect( - address = address, - port = FLOCON_WEBSOCKET_PORT, - onMessageReceived = ::onMessageReceived, - onClosed = onClosed, - ) - plugins.forEach { it.onConnectedToServer() } - } - - override suspend fun disconnect() { - webSocketClient.disconnect() - } - - private fun onMessageReceived(message: String) { - coroutineScope.launch(Dispatchers.IO) { - floconMessageFromServerFromJson(message)?.let { messageFromServer -> - messageFromServer.plugin - plugins.find { it.key == messageFromServer.plugin } - ?.onMessageReceived( - method = messageFromServer.method, - body = messageFromServer.body, - ) - } - } - } - - override suspend fun send( - plugin: String, - method: String, - body: String, - ) { - webSocketClient.sendMessage( - message = FloconMessageToServer( - deviceId = appInfos.deviceId, - plugin = plugin, - body = body, - appName = appInfos.appName, - appPackageName = appInfos.appPackageName, - method = method, - deviceName = appInfos.deviceName, - appInstance = appInstance, - platform = appInfos.platform, - versionName = versionName, - ) - .toFloconMessageToServer(), - ) - } - - override suspend fun send( - file: FloconFile, - infos: FloconFileInfo, - ) { - httpClient.send( - address = address, - port = FLOCON_HTTP_PORT, - file = file, - infos = infos, - - deviceId = appInfos.deviceId, - appPackageName = appInfos.appPackageName, - appInstance = appInstance, - ) - } - - override suspend fun sendPendingMessages() { - webSocketClient.sendPendingMessages() - } -} - -internal class FloconClient( +class FloconClient internal constructor( private val context: FloconContext ) : FloconApp.Client, FloconMessageSender, FloconFileSender { @@ -174,6 +69,7 @@ internal class FloconClient( ) } + @FloconMarker override suspend fun send( file: FloconFile, infos: FloconFileInfo, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt index 3f5b977ce..4d835a5a7 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt @@ -1,8 +1,12 @@ package io.github.openflocon.flocon.core import io.github.openflocon.flocon.FloconFile +import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.model.FloconFileInfo internal interface FloconFileSender { + + @FloconMarker suspend fun send(file: FloconFile, infos: FloconFileInfo) + } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconFileInfo.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconFileInfo.kt index 1bd6f4eb8..0aeb75d9d 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconFileInfo.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconFileInfo.kt @@ -1,6 +1,9 @@ package io.github.openflocon.flocon.model -internal data class FloconFileInfo( +import io.github.openflocon.flocon.dsl.FloconMarker + +@FloconMarker +data class FloconFileInfo( val path: String, val requestId: String, ) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt index d0b293286..d57654c3d 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -1,12 +1,11 @@ package io.github.openflocon.flocon.plugins.analytics -import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.analytics.mapper.analyticsItemsToJson import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsConfig import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsPlugin import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem @@ -15,9 +14,12 @@ object FloconAnalytics : FloconPluginFactory { override val name: String = "Files" override val pluginId: String = Protocol.ToDevice.Files.Plugin override fun createConfig() = FloconFilesConfig() - override fun install(config: FloconFilesConfig, app: FloconApp): FloconFilesPlugin { - val client = app.client + override fun install( + pluginConfig: FloconFilesConfig, + floconConfig: FloconConfig + ): FloconFilesPlugin { + val client = floconConfig.client return FloconFilesPluginImpl( - context = app.context, + context = floconConfig.context, floconFileSender = client as FloconFileSender, sender = client as FloconMessageSender ) @@ -37,7 +40,10 @@ object FloconFiles : FloconPluginFactory { } internal interface FileDataSource { + + @FloconMarker fun getFile(path: String, isConstantPath: Boolean): FloconFile? + fun getFolderContent( path: String, isConstantPath: Boolean, @@ -46,6 +52,8 @@ internal interface FileDataSource { fun deleteFile(path: String) fun deleteFiles(path: List) + + @FloconMarker fun deleteFolderContent(folder: FloconFile) } @@ -61,6 +69,7 @@ internal class FloconFilesPluginImpl( private val fileDataSource = fileDataSource(context) private val withFoldersSize = MutableStateFlow(false) + @FloconMarker override suspend fun onMessageReceived( method: String, body: String, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt index 1f5fe1ef5..d64298869 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt @@ -10,10 +10,13 @@ object FloconPreferences : FloconPluginFactory { override fun createConfig(): FloconAnalyticsConfig = TODO() - override fun install(config: FloconAnalyticsConfig, app: FloconApp): FloconAnalyticsPlugin = TODO() + override fun install( + pluginConfig: FloconAnalyticsConfig, + floconConfig: FloconConfig + ): FloconAnalyticsPlugin = TODO() override val name: String = "" override val pluginId: String = "ANALYTICS" diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt index 9e5cbabd5..147783416 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.pluginsold.database import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory @@ -17,7 +18,10 @@ object FloconDatabase : FloconPluginFactory { TODO("Not yet implemented") } - override fun install(config: FloconFilesConfig, app: FloconApp): FloconFilesPlugin { + override fun install( + pluginConfig: FloconFilesConfig, + floconConfig: FloconConfig + ): FloconFilesPlugin { TODO("Not yet implemented") } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt index 9af248027..3ec1427d2 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.pluginsold.sharedprefs import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory @@ -17,7 +18,10 @@ object FloconPreferences : FloconPluginFactory { TODO("Not yet implemented") } - override fun install(config: FloconTableConfig, app: FloconApp): FloconTablePlugin { + override fun install( + pluginConfig: FloconTableConfig, + floconConfig: FloconConfig + ): FloconTablePlugin { TODO("Not yet implemented") } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.kt index 7660cf030..a82cb3177 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.kt @@ -1,11 +1,14 @@ package io.github.openflocon.flocon.websocket import io.github.openflocon.flocon.FloconFile +import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.model.FloconFileInfo -internal expect fun buildFloconHttpClient() : FloconHttpClient +internal expect fun buildFloconHttpClient(): FloconHttpClient internal interface FloconHttpClient { + + @FloconMarker suspend fun send( file: FloconFile, infos: FloconFileInfo, @@ -14,5 +17,5 @@ internal interface FloconHttpClient { deviceId: String, appPackageName: String, appInstance: Long - ) : Boolean + ): Boolean } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/Flocon.ios.kt b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/Flocon.ios.kt deleted file mode 100644 index 14a0608d9..000000000 --- a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/Flocon.ios.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.openflocon.flocon - -object Flocon : FloconCore() { - fun initialize() { - super.initializeFlocon(context = FloconContext()) - } -} - diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/Flocon.jvm.kt b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/Flocon.jvm.kt deleted file mode 100644 index ec43cd8ff..000000000 --- a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/Flocon.jvm.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon - -object Flocon : FloconCore() { - - fun initialize() { - super.initializeFlocon(context = FloconContext( - appName = "Flocon-sample", - packageName = "io.github.openflocon.flocon", - )) - } -} diff --git a/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.android.kt b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.android.kt new file mode 100644 index 000000000..5c424d559 --- /dev/null +++ b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.android.kt @@ -0,0 +1,7 @@ +package io.github.openflocon.flocon.network.core.datasource + +import io.github.openflocon.flocon.FloconContext + +internal actual inline fun buildFloconNetworkDataSource( + context: FloconContext +): FloconNetworkDataSource = FloconNetworkDataSourceAndroid(context = context.context) \ No newline at end of file diff --git a/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.android.kt b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt similarity index 90% rename from FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.android.kt rename to FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt index e11512cc2..3351a639f 100644 --- a/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.android.kt +++ b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt @@ -1,24 +1,19 @@ -package io.github.openflocon.flocon.network.core +package io.github.openflocon.flocon.network.core.datasource import android.content.Context -import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig import io.github.openflocon.flocon.network.core.mapper.parseMockResponses import io.github.openflocon.flocon.network.core.mapper.toJsonString import io.github.openflocon.flocon.network.core.mapper.writeMockResponsesToJson +import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_BAD_CONFIG_JSON +import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_MOCKS_JSON import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse import java.io.File import java.io.FileInputStream import java.io.FileOutputStream -internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { - return FloconNetworkDataSourceAndroid( - context = context.context, - ) -} - internal class FloconNetworkDataSourceAndroid( private val context: Context ) : FloconNetworkDataSource { diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt new file mode 100644 index 000000000..43f00fd3a --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt @@ -0,0 +1,41 @@ +package io.github.openflocon.flocon.network.core + +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.dsl.FloconMarker +import io.github.openflocon.flocon.error.pluginNotInitialized +import io.github.openflocon.flocon.network.core.plugin.FloconNetworkPluginImpl +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkConfig +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import kotlinx.coroutines.SupervisorJob + +object FloconNetwork : FloconPluginFactory { + override val name: String = "Network" + override val pluginId: String = Protocol.ToDevice.Network.Plugin + + override fun createConfig() = FloconNetworkConfig() + + @OptIn(FloconMarker::class) + override fun install( + pluginConfig: FloconNetworkConfig, + floconConfig: FloconConfig + ): FloconNetworkPlugin { + return FloconNetworkPluginImpl( + context = floconConfig.context, + sender = floconConfig.client as FloconMessageSender, + coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()), + ) + .also { FloconNetworkPluginImpl.plugin = it } + } + +} + +@OptIn(FloconMarker::class) +val Flocon.Companion.networkPlugin: FloconNetworkPlugin + get() = FloconNetworkPluginImpl.plugin ?: pluginNotInitialized("Network") \ No newline at end of file diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/NetworkCore.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/NetworkCore.kt deleted file mode 100644 index 1ce7f0e47..000000000 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/NetworkCore.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.github.openflocon.flocon.network.core - -// Placeholder for Network Core diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.kt new file mode 100644 index 000000000..69cf9d441 --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.kt @@ -0,0 +1,16 @@ +package io.github.openflocon.flocon.network.core.datasource + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse + +internal interface FloconNetworkDataSource { + fun saveMocksToFile(mocks: List) + fun loadMocksFromFile(): List + fun saveBadNetworkConfig(config: BadQualityConfig?) + fun loadBadNetworkConfig(): BadQualityConfig? +} + +internal expect inline fun buildFloconNetworkDataSource( + context: FloconContext +): FloconNetworkDataSource \ No newline at end of file diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt similarity index 78% rename from FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt rename to FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt index e0057fc06..cca03df51 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt @@ -1,14 +1,11 @@ -package io.github.openflocon.flocon.network.core +package io.github.openflocon.flocon.network.core.plugin -import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.dsl.FloconMarker -import io.github.openflocon.flocon.error.pluginNotInitialized +import io.github.openflocon.flocon.network.core.datasource.buildFloconNetworkDataSource import io.github.openflocon.flocon.network.core.mapper.floconNetworkCallRequestToJson import io.github.openflocon.flocon.network.core.mapper.floconNetworkCallResponseToJson import io.github.openflocon.flocon.network.core.mapper.floconNetworkWebSocketEventToJson @@ -16,7 +13,6 @@ import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig import io.github.openflocon.flocon.network.core.mapper.parseMockResponses import io.github.openflocon.flocon.network.core.mapper.parseWebSocketMockMessage import io.github.openflocon.flocon.network.core.mapper.webSocketIdsToJsonArray -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkConfig import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest @@ -25,45 +21,14 @@ import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketMockListener import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO -import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -object FloconNetwork : FloconPluginFactory { - override val name: String = "Network" - override val pluginId: String = Protocol.ToDevice.Network.Plugin - override fun createConfig() = FloconNetworkConfig() - override fun install(config: FloconNetworkConfig, app: FloconApp): FloconNetworkPlugin { - return FloconNetworkPluginImpl( - context = app.context, - sender = app.client as FloconMessageSender, - coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()), - ) - .also { FloconNetworkPluginImpl.plugin = it } - } -} - internal const val FLOCON_NETWORK_MOCKS_JSON = "flocon_network_mocks.json" internal const val FLOCON_NETWORK_BAD_CONFIG_JSON = "flocon_network_bad_config.json" -internal interface FloconNetworkDataSource { - fun saveMocksToFile(mocks: List) - fun loadMocksFromFile(): List - fun saveBadNetworkConfig(config: BadQualityConfig?) - fun loadBadNetworkConfig(): BadQualityConfig? -} - -internal expect fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource - -@OptIn(FloconMarker::class) -@Suppress("UnusedReceiverParameter") -val FloconApp.networkPlugin: FloconNetworkPlugin - get() = FloconNetworkPluginImpl.plugin ?: pluginNotInitialized("Network") - internal class FloconNetworkPluginImpl( context: FloconContext, private var sender: FloconMessageSender, diff --git a/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.ios.kt b/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.ios.kt new file mode 100644 index 000000000..580dd4815 --- /dev/null +++ b/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.ios.kt @@ -0,0 +1,7 @@ +package io.github.openflocon.flocon.network.core.datasource + +import io.github.openflocon.flocon.FloconContext + +internal actual inline fun buildFloconNetworkDataSource( + context: FloconContext +): FloconNetworkDataSource = FloconNetworkDataSourceImpl() \ No newline at end of file diff --git a/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.ios.kt b/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt similarity index 62% rename from FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.ios.kt rename to FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt index dc587f51f..fad59bfae 100644 --- a/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.ios.kt +++ b/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt @@ -1,15 +1,10 @@ -package io.github.openflocon.flocon.network.core +package io.github.openflocon.flocon.network.core.datasource -import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse -internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { - return FloconNetworkDataSourceIOs() -} +internal class FloconNetworkDataSourceImpl : FloconNetworkDataSource { -// TODO -internal class FloconNetworkDataSourceIOs : FloconNetworkDataSource { override fun saveMocksToFile(mocks: List) { // TODO } diff --git a/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.jvm.kt b/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.jvm.kt new file mode 100644 index 000000000..580dd4815 --- /dev/null +++ b/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.jvm.kt @@ -0,0 +1,7 @@ +package io.github.openflocon.flocon.network.core.datasource + +import io.github.openflocon.flocon.FloconContext + +internal actual inline fun buildFloconNetworkDataSource( + context: FloconContext +): FloconNetworkDataSource = FloconNetworkDataSourceImpl() \ No newline at end of file diff --git a/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.jvm.kt b/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt similarity index 91% rename from FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.jvm.kt rename to FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt index 16342afe8..a2e304384 100644 --- a/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetworkPluginImpl.jvm.kt +++ b/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt @@ -1,22 +1,19 @@ -package io.github.openflocon.flocon.network.core +package io.github.openflocon.flocon.network.core.datasource -import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig import io.github.openflocon.flocon.network.core.mapper.parseMockResponses import io.github.openflocon.flocon.network.core.mapper.toJsonString import io.github.openflocon.flocon.network.core.mapper.writeMockResponsesToJson +import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_BAD_CONFIG_JSON +import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_MOCKS_JSON import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse import java.io.File import java.io.FileInputStream import java.io.FileOutputStream -internal actual fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource { - return FloconNetworkDataSourceJvm() -} - -internal class FloconNetworkDataSourceJvm( +internal class FloconNetworkDataSourceImpl( ) : FloconNetworkDataSource { private val baseDir: File = File(System.getProperty("user.home"), ".flocon") diff --git a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt index 1986f8f42..d201396fd 100644 --- a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt +++ b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt @@ -2,7 +2,7 @@ package io.github.openflocon.flocon.okhttp -import io.github.openflocon.flocon.FloconApp +import io.github.openflocon.flocon.Flocon import io.github.openflocon.flocon.network.core.networkPlugin import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse @@ -29,7 +29,7 @@ class FloconOkhttpInterceptor( @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { - val floconNetworkPlugin = FloconApp.instance!!.networkPlugin + val floconNetworkPlugin = Flocon.networkPlugin if (!shouldLog(chain)) { // on no op, do not intercept the call, just execute it diff --git a/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/deeplink/repository/DeeplinkRepositoryImpl.kt b/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/deeplink/repository/DeeplinkRepositoryImpl.kt index 8e8bc6d0b..ed63264f7 100644 --- a/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/deeplink/repository/DeeplinkRepositoryImpl.kt +++ b/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/deeplink/repository/DeeplinkRepositoryImpl.kt @@ -31,8 +31,6 @@ class DeeplinkRepositoryImpl( Protocol.FromDevice.Deeplink.Method.GetDeeplinks -> { val deeplinks = remote.getItems(message) ?: return - println(deeplinks.toString()) - localDeeplinkDataSource.update( deviceIdAndPackageNameDomainModel = deviceIdAndPackageName, deeplinks = deeplinks From cad125e08061b877b295e7abecf9f8df0e77bf5b Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Thu, 12 Mar 2026 16:38:03 +0100 Subject: [PATCH 11/35] feat: No op --- .../flocon/network/core/noop/FloconNetwork.kt | 32 +++++ .../network/core/noop/NetworkCoreNoOp.kt | 3 - .../core/noop/mapper/BadQualityToJson.kt | 104 +++++++++++++++ .../noop/mapper/FloconNetworkRequestToJson.kt | 111 ++++++++++++++++ .../core/noop/mapper/MockResponseToJson.kt | 119 ++++++++++++++++++ .../network/core/noop/mapper/Websocket.kt | 25 ++++ .../noop/plugin/FloconNetworkPluginImpl.kt | 32 +++++ FloconAndroid/settings.gradle.kts | 4 +- 8 files changed, 425 insertions(+), 5 deletions(-) create mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt delete mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/NetworkCoreNoOp.kt create mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt create mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt create mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt create mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt create mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/plugin/FloconNetworkPluginImpl.kt diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt new file mode 100644 index 000000000..ab2a5f8c9 --- /dev/null +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt @@ -0,0 +1,32 @@ +package io.github.openflocon.flocon.network.core.noop + +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.dsl.FloconMarker +import io.github.openflocon.flocon.error.pluginNotInitialized +import io.github.openflocon.flocon.network.core.noop.plugin.FloconNetworkPluginImpl +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkConfig +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin + +object FloconNetwork : FloconPluginFactory { + override val name: String = "Network" + override val pluginId: String = Protocol.ToDevice.Network.Plugin + + override fun createConfig() = FloconNetworkConfig() + + @OptIn(FloconMarker::class) + override fun install( + pluginConfig: FloconNetworkConfig, + floconConfig: FloconConfig + ): FloconNetworkPlugin { + return FloconNetworkPluginImpl() + .also { FloconNetworkPluginImpl.plugin = it } + } + +} + +@OptIn(FloconMarker::class) +val Flocon.Companion.networkPlugin: FloconNetworkPlugin + get() = FloconNetworkPluginImpl.plugin ?: pluginNotInitialized("Network") \ No newline at end of file diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/NetworkCoreNoOp.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/NetworkCoreNoOp.kt deleted file mode 100644 index cf487ea7b..000000000 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/NetworkCoreNoOp.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.github.openflocon.flocon.network.core.noop - -// Placeholder for Network Core No-Op diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt new file mode 100644 index 000000000..1e9c85456 --- /dev/null +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt @@ -0,0 +1,104 @@ +package io.github.openflocon.flocon.network.core.noop.mapper + +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString + +internal fun BadQualityConfig.toJsonString(): String { + return FloconEncoder.json.encodeToString( + toSerializable() + ) +} + +internal fun parseBadQualityConfig(jsonString: String): BadQualityConfig? { + return try { + val parsed = FloconEncoder.json.decodeFromString( + jsonString + ) + parsed.toDomain() + } catch (t: Throwable) { + FloconLogger.logError(t.message ?: "bad connection network parsing issue", t) + null + } +} + +@Serializable +internal class BadQualityConfigSerializable( + val latency: LatencySerializable, + val errorProbability: Double, + val errors: List, +) { + @Serializable + class LatencySerializable( + val latencyTriggerProbability: Float, + val minLatencyMs: Long, + val maxLatencyMs: Long, + ) + + @Serializable + class ErrorSerializable( + val weight: Float, + val errorCode: Int? = null, + val errorBody: String? = null, + val errorContentType: String? = null, + val errorException: String? = null, + ) +} + +internal fun BadQualityConfig.toSerializable(): BadQualityConfigSerializable { + return BadQualityConfigSerializable( + latency = BadQualityConfigSerializable.LatencySerializable( + latencyTriggerProbability = latency.latencyTriggerProbability, + minLatencyMs = latency.minLatencyMs, + maxLatencyMs = latency.maxLatencyMs + ), + errorProbability = errorProbability, + errors = errors.map { error -> + when (val t = error.type) { + is BadQualityConfig.Error.Type.Body -> BadQualityConfigSerializable.ErrorSerializable( + weight = error.weight, + errorCode = t.errorCode, + errorBody = t.errorBody, + errorContentType = t.errorContentType + ) + + is BadQualityConfig.Error.Type.ErrorThrow -> BadQualityConfigSerializable.ErrorSerializable( + weight = error.weight, + errorException = t.classPath + ) + } + } + ) +} + +internal fun BadQualityConfigSerializable.toDomain(): BadQualityConfig { + val latencyConfig = BadQualityConfig.LatencyConfig( + latencyTriggerProbability = latency.latencyTriggerProbability, + minLatencyMs = latency.minLatencyMs, + maxLatencyMs = latency.maxLatencyMs + ) + + val errorsList = errors.map { e -> + val type = if (!e.errorException.isNullOrEmpty()) { + BadQualityConfig.Error.Type.ErrorThrow(e.errorException) + } else { + BadQualityConfig.Error.Type.Body( + errorCode = e.errorCode ?: 0, + errorBody = e.errorBody.orEmpty(), + errorContentType = e.errorContentType.orEmpty() + ) + } + BadQualityConfig.Error( + weight = e.weight, + type = type + ) + } + + return BadQualityConfig( + latency = latencyConfig, + errorProbability = errorProbability, + errors = errorsList + ) +} \ No newline at end of file diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt new file mode 100644 index 000000000..03b132903 --- /dev/null +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt @@ -0,0 +1,111 @@ +@file:OptIn(ExperimentalUuidApi::class) + +package io.github.openflocon.flocon.network.core.noop.mapper + +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid + +@Serializable +internal class FloconNetworkCallRequestRemote( + val floconCallId: String, + val floconNetworkType: String, + val isMocked: Boolean, + + val url: String, + val method: String, + val startTime: Long, + val requestBody: String?, + val requestHeaders: Map, + val requestSize: Long?, +) + +internal fun FloconNetworkCallRequest.floconNetworkCallRequestToJson(): String { + val remoteModel = FloconNetworkCallRequestRemote( + floconCallId = floconCallId, + floconNetworkType = floconNetworkType, + isMocked = isMocked, + url = request.url, + method = request.method, + startTime = request.startTime, + requestBody = request.body, + requestHeaders = request.headers, + requestSize = request.size + ) + return FloconEncoder.json.encodeToString(remoteModel) +} + +@Serializable +internal class FloconNetworkCallResponseRemote( + val floconCallId: String, + val durationMs: Double, + val floconNetworkType: String, + val isMocked: Boolean, + val responseHttpCode: Int?, + val responseGrpcStatus: String?, + val responseContentType: String?, + val responseBody: String?, + val responseSize: Long?, + val responseHeaders: Map, + val requestHeaders: Map?, // we might receive the request headers later if the interceptor is at first position in the http interceptor chain + val responseError: String?, + val isImage: Boolean, +) + +internal fun FloconNetworkCallResponse.floconNetworkCallResponseToJson(): String { + val remoteModel = FloconNetworkCallResponseRemote( + floconCallId = floconCallId, + floconNetworkType = floconNetworkType, + isMocked = isMocked, + durationMs = durationMs, + responseHttpCode = response.httpCode, + responseGrpcStatus = response.grpcStatus, + responseContentType = response.contentType, + responseBody = response.body, + responseHeaders = response.headers, + requestHeaders = response.requestHeaders?.takeIf { + it.isNotEmpty() + }, + responseSize = response.size, + isImage = response.isImage, + responseError = response.error, + ) + + return FloconEncoder.json.encodeToString(remoteModel) +} + +@Serializable +internal class FloconWebSocketEventRemote( + val id: String, + val event: String, + val url: String, + val size: Long, + val timestamp: Long, + val message: String?, + val error: String?, +) + +internal fun FloconWebSocketEvent.floconNetworkWebSocketEventToJson(): String { + val remoteModel = FloconWebSocketEventRemote( + id = Uuid.random().toString(), + event = when (event) { + FloconWebSocketEvent.Event.Closed -> "closed" + FloconWebSocketEvent.Event.Closing -> "closing" + FloconWebSocketEvent.Event.Error -> "error" + FloconWebSocketEvent.Event.ReceiveMessage -> "received" + FloconWebSocketEvent.Event.SendMessage -> "sent" + FloconWebSocketEvent.Event.Open -> "open" + }, + url = websocketUrl, + size = size, + timestamp = timeStamp, + message = message, + error = error?.message + ) + return FloconEncoder.json.encodeToString(remoteModel) +} \ No newline at end of file diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt new file mode 100644 index 000000000..9696d7d1f --- /dev/null +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt @@ -0,0 +1,119 @@ +package io.github.openflocon.flocon.network.core.noop.mapper + +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString + +@Serializable +internal class MockNetworkResponseDataModel( + val expectation: Expectation, + val response: Response, +) { + @Serializable + class Expectation( + val urlPattern: String, // a regex + val method: String, // can be get, post, put, ... or a wildcard * + ) + + @Serializable + class Response( + val httpCode: Int?, + val body: String?, + val mediaType: String?, + val delay: Long?, + val headers: Map?, + val errorException: String?, + ) +} + + +internal fun parseMockResponses(jsonString: String): List { + try { + val remote = + FloconEncoder.json.decodeFromString>(jsonString) + return remote.mapNotNull { + it.toDomain() + } + } catch (t: Throwable) { + FloconLogger.logError(t.message ?: "mock network parsing issue", t) + return emptyList() + } +} + +internal fun MockNetworkResponseDataModel.toDomain(): MockNetworkResponse? { + return MockNetworkResponse( + expectation = MockNetworkResponse.Expectation( + urlPattern = expectation.urlPattern, + method = expectation.method, + ), + response = this.mapResponseToDomain() ?: return null + ) +} + +private fun MockNetworkResponseDataModel.mapResponseToDomain(): MockNetworkResponse.Response? { + return response.run { + when { + errorException != null -> MockNetworkResponse.Response.ErrorThrow( + classPath = errorException, + delay = delay ?: 0L, + ) + + httpCode != null -> MockNetworkResponse.Response.Body( + httpCode = httpCode, + body = body ?: "", + delay = delay ?: 0L, + mediaType = mediaType ?: "", + headers = headers ?: emptyMap() + ) + + else -> run { + FloconLogger.logError("error parsing mock response", null) + return@run null + } + } + } +} + + +internal fun writeMockResponsesToJson(mocks: List): String { + return try { + FloconEncoder.json.encodeToString(mocks.map { it.toRemote() }) + } catch (t: Throwable) { + FloconLogger.logError(t.message ?: "mock network writing issue", t) + return "[]" + } +} + +private fun MockNetworkResponse.toRemote(): MockNetworkResponseDataModel { + return MockNetworkResponseDataModel( + expectation = MockNetworkResponseDataModel.Expectation( + urlPattern = expectation.urlPattern, + method = expectation.method, + ), + response = mapResponseToRemote(), + ) +} + +private fun MockNetworkResponse.mapResponseToRemote(): MockNetworkResponseDataModel.Response { + return when (val response = this.response) { + is MockNetworkResponse.Response.ErrorThrow -> MockNetworkResponseDataModel.Response( + errorException = response.classPath, + delay = response.delay, + body = null, + headers = null, + httpCode = null, + mediaType = null, + ) + + is MockNetworkResponse.Response.Body -> MockNetworkResponseDataModel.Response( + errorException = null, + delay = response.delay, + body = response.body, + headers = response.headers, + httpCode = response.httpCode, + mediaType = response.mediaType, + ) + } +} diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt new file mode 100644 index 000000000..8cd994774 --- /dev/null +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt @@ -0,0 +1,25 @@ +package io.github.openflocon.flocon.network.core.noop.mapper + +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.core.FloconEncoder +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString + +@Serializable +internal class WebSocketMockMessage( + val id: String, + val message: String, +) + +internal fun webSocketIdsToJsonArray(ids: Collection): String { + return FloconEncoder.json.encodeToString(ids) +} + +internal fun parseWebSocketMockMessage(jsonString: String): WebSocketMockMessage? { + try { + return FloconEncoder.json.decodeFromString(jsonString) + } catch (t: Throwable) { + FloconLogger.logError(t.message ?: "mock wesocket network parsing issue", t) + } + return null +} \ No newline at end of file diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/plugin/FloconNetworkPluginImpl.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/plugin/FloconNetworkPluginImpl.kt new file mode 100644 index 000000000..6f1a38e8e --- /dev/null +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/plugin/FloconNetworkPluginImpl.kt @@ -0,0 +1,32 @@ +package io.github.openflocon.flocon.network.core.noop.plugin + +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin +import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent +import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketMockListener +import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse + +internal class FloconNetworkPluginImpl : FloconPlugin, FloconNetworkPlugin { + override val key: String = "NETWORK" + override val mocks: Collection = emptyList() + override val badQualityConfig: BadQualityConfig? = null + + override suspend fun onMessageReceived(method: String, body: String) = Unit // No op + override suspend fun onConnectedToServer() = Unit // No op + + override fun logRequest(request: FloconNetworkCallRequest) = Unit // No op + override fun logResponse(response: FloconNetworkCallResponse) = Unit // No op + + override suspend fun logWebSocket(event: FloconWebSocketEvent) = Unit // No op + override suspend fun registerWebSocketMockListener( + id: String, + listener: FloconWebSocketMockListener + ) = Unit // No op + + companion object { + var plugin: FloconNetworkPlugin? = null + } +} \ No newline at end of file diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index 1009160d5..aeee1139f 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -1,3 +1,5 @@ +rootProject.name = "Flocon Sample App" + pluginManagement { repositories { google() @@ -14,8 +16,6 @@ dependencyResolutionManagement { } } -rootProject.name = "Flocon Sample App" - include(":sample-android-only") include(":sample-multiplatform") include(":flocon") From 004c71358c673fdd35ff43feff678ac214441628 Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Thu, 12 Mar 2026 17:30:25 +0100 Subject: [PATCH 12/35] feat: Other plugins --- .../database/FloconDatabasePlugin.android.kt | 6 +- .../analytics/FloconAnalyticsPlugin.kt | 11 ++- .../analytics/builder/AnalyticsBuilder.kt | 32 +++++++++ .../analytics/mapper/AnalyticsItemsMapper.kt | 2 +- .../plugins/analytics/model/AnalyticsEvent.kt | 11 +++ .../plugins/analytics/model/AnalyticsItem.kt | 9 +++ .../model/AnalyticsPropertiesConfig.kt | 11 +++ .../FloconCrashReporterPlugin.kt | 20 ++++-- .../plugins/dashboard/FloconDashboardDSL.kt | 10 +-- .../dashboard/FloconDashboardPlugin.kt | 21 ++++-- .../dashboard/builder/ContainerBuilder.kt | 14 ++++ .../dashboard/builder/DashboardBuilder.kt | 21 ++++++ .../plugins/dashboard/builder/FormBuilder.kt | 20 ++++++ .../dashboard/builder/SectionBuilder.kt | 10 +++ .../flocon/plugins/dashboard/dsl/ButtonDsl.kt | 19 +++++ .../plugins/dashboard/dsl/CheckBoxDsl.kt | 21 ++++++ .../plugins/dashboard/dsl/DashboardDsl.kt | 15 ++++ .../flocon/plugins/dashboard/dsl/FormDsl.kt | 22 ++++++ .../flocon/plugins/dashboard/dsl/HtmlDsl.kt | 9 +++ .../plugins/dashboard/dsl/MarkdownDsl.kt | 9 +++ .../plugins/dashboard/dsl/PlainTextDsl.kt | 26 +++++++ .../plugins/dashboard/dsl/SectionDsl.kt | 13 ++++ .../flocon/plugins/dashboard/dsl/TextDsl.kt | 15 ++++ .../flocon/plugins/dashboard/dsl/TextField.kt | 23 ++++++ .../plugins/dashboard/mapper/JsonMapper.kt | 26 +++---- .../plugins/dashboard/model/ContainerType.kt | 6 ++ .../dashboard/model/DashboardConfig.kt | 8 +++ .../plugins/dashboard/model/DashboardScope.kt | 25 +++++++ .../dashboard/model/config/ButtonConfig.kt | 7 ++ .../dashboard/model/config/CheckBoxConfig.kt | 8 +++ .../dashboard/model/config/ContainerConfig.kt | 9 +++ .../dashboard/model/config/ElementConfig.kt | 3 + .../dashboard/model/config/FormConfig.kt | 13 ++++ .../dashboard/model/config/HtmlConfig.kt | 6 ++ .../dashboard/model/config/LabelConfig.kt | 6 ++ .../dashboard/model/config/MarkdownConfig.kt | 6 ++ .../dashboard/model/config/PlainTextConfig.kt | 7 ++ .../dashboard/model/config/SectionConfig.kt | 10 +++ .../dashboard/model/config/TextConfig.kt | 7 ++ .../dashboard/model/config/TextFieldConfig.kt | 9 +++ .../plugins/database/FloconDatabasePlugin.kt | 20 +++--- .../database/model/FloconDatabaseModel.kt | 10 +++ .../plugins/device/FloconDevicePluginImpl.kt | 16 ++++- .../flocon/plugins/files/FloconFilesPlugin.kt | 10 ++- .../sharedprefs/FloconSharedPrefsPlugin.kt | 18 +++-- .../model/FloconSharedPreferenceModel.kt | 5 ++ .../plugins/tables/FloconTablesPlugin.kt | 20 ++++-- .../flocon/plugins/tables/model/TableItem.kt | 21 +++++- .../FloconSharedPrefsPlugin.jvm.kt | 1 - .../flocon/grpc/model/RequestHolder.kt | 2 +- .../flocon/network/core/noop/FloconNetwork.kt | 4 +- .../core/noop/mapper/BadQualityToJson.kt | 2 +- .../noop/mapper/FloconNetworkRequestToJson.kt | 6 +- .../core/noop/mapper/MockResponseToJson.kt | 2 +- .../noop/plugin/FloconNetworkPluginImpl.kt | 14 ++-- .../FloconNetworkDataSourceAndroid.kt | 4 +- .../flocon/network/core/FloconNetwork.kt | 29 +++++++- .../datasource/FloconNetworkDataSource.kt | 4 +- .../network/core/mapper/BadQualityToJson.kt | 2 +- .../core/mapper/FloconNetworkRequestToJson.kt | 6 +- .../network/core/mapper/MockResponseToJson.kt | 2 +- .../network/core/model/BadQualityConfig.kt | 72 +++++++++++++++++++ .../network/core/model/FloconHttpRequest.kt | 23 ++++++ .../core/model/FloconNetworkCallRequest.kt | 8 +++ .../core/model/FloconNetworkCallResponse.kt | 9 +++ .../core/model/FloconWebSocketEvent.kt | 21 ++++++ .../core/model/FloconWebSocketMockListener.kt | 5 ++ .../network/core/model/MockNetworkResponse.kt | 39 ++++++++++ .../core/plugin/FloconNetworkPluginImpl.kt | 14 ++-- .../datasource/FloconNetworkDataSourceImpl.kt | 4 +- .../datasource/FloconNetworkDataSourceImpl.kt | 4 +- .../openflocon/flocon/ktor/BadQuality.kt | 2 +- .../io/github/openflocon/flocon/ktor/Mocks.kt | 4 +- .../openflocon/flocon/okhttp/BadQuality.kt | 2 +- .../github/openflocon/flocon/okhttp/Mock.kt | 4 +- .../flocon/okhttp/OkHttpInterceptor.kt | 8 +-- .../okhttp/websocket/FloconWebSocket.kt | 2 +- .../dashboard/InitializeDashboard.kt | 16 ++--- .../database/InitializeDatabases.kt | 9 ++- .../sharedpreferences/SharedPreferences.kt | 1 - 80 files changed, 845 insertions(+), 126 deletions(-) create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/ContainerBuilder.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/DashboardBuilder.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/FormBuilder.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/SectionBuilder.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/ButtonDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/CheckBoxDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/DashboardDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/FormDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/HtmlDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/MarkdownDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/PlainTextDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/SectionDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextDsl.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextField.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/ContainerType.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardScope.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ButtonConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/CheckBoxConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ContainerConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ElementConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/FormConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/HtmlConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/LabelConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/MarkdownConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/PlainTextConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/SectionConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextFieldConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/BadQualityConfig.kt create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconHttpRequest.kt create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconNetworkCallRequest.kt create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconNetworkCallResponse.kt create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconWebSocketEvent.kt create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconWebSocketMockListener.kt create mode 100644 FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/MockNetworkResponse.kt diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt index ec7c7ba2f..e8b491b09 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt @@ -24,7 +24,7 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : private val MAX_DEPTH = 7 override fun executeSQL( - registeredDatabases: List, + registeredDatabases: List, databaseName: String, query: String ): DatabaseExecuteSqlResponse { @@ -105,9 +105,7 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : } } - override fun getAllDataBases( - registeredDatabases: List - ): List { + override fun getAllDataBases(registeredDatabases: List): List { val databasesDir = context.getDatabasePath("dummy_db").parentFile ?: return emptyList() val foundDatabases = mutableListOf() diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt index d57654c3d..2c79458ae 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -3,12 +3,17 @@ package io.github.openflocon.flocon.plugins.analytics import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsConfig -import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsPlugin -import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem + +class FloconAnalyticsConfig : FloconPluginConfig + +interface FloconAnalyticsPlugin : FloconPlugin { + fun registerAnalytics(analyticsItems: List) +} object FloconAnalytics : FloconPluginFactory { override val name: String = "Analytics" diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt new file mode 100644 index 000000000..d4aef5b4d --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt @@ -0,0 +1,32 @@ +@file:OptIn(ExperimentalUuidApi::class) + +package io.github.openflocon.flocon.plugins.analytics.builder + +import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsEvent +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem +import io.github.openflocon.flocon.utils.currentTimeMillis +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid + +class AnalyticsBuilder( + val analyticsTableId: String, + private val analyticsPlugin: FloconAnalyticsPlugin?, +) { + fun logEvents(vararg events: AnalyticsEvent) { + this.logEvents(events.toList()) + } + + fun logEvents(events: List) { + val analyticsItems = events.map { + AnalyticsItem( + id = Uuid.random().toString(), + analyticsTableId = analyticsTableId, + eventName = it.eventName, + createdAt = currentTimeMillis(), + properties = it.properties, + ) + } + analyticsPlugin?.registerAnalytics(analyticsItems) + } +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt index 4a4fae0ed..f93b42598 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt @@ -1,7 +1,7 @@ package io.github.openflocon.flocon.plugins.analytics.mapper import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt new file mode 100644 index 000000000..b0de88ffa --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.plugins.analytics.model + +data class AnalyticsEvent( + val eventName: String, + val properties: List, +) { + constructor( + eventName: String, + vararg properties: AnalyticsPropertiesConfig, + ) : this(eventName, properties.toList()) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt new file mode 100644 index 000000000..55c7285cd --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.plugins.analytics.model + +data class AnalyticsItem( + val id: String, + val analyticsTableId: String, + val eventName: String, + val createdAt: Long, + val properties: List, +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt new file mode 100644 index 000000000..f36d72382 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.plugins.analytics.model + +data class AnalyticsPropertiesConfig( + val name: String, + val value: String, +) + +infix fun String.analyticsProperty(value: String) = AnalyticsPropertiesConfig( + name = this, + value = value, +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt index 39fc9912a..4c31686df 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt @@ -1,10 +1,14 @@ package io.github.openflocon.flocon.plugins.crashreporter -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel -import io.github.openflocon.flocon.pluginsold.crashreporter.FloconCrashReporterConfig -import io.github.openflocon.flocon.pluginsold.crashreporter.FloconCrashReporterPlugin import io.github.openflocon.flocon.utils.currentTimeMillis import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -14,6 +18,14 @@ import kotlinx.coroutines.launch import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid +class FloconCrashReporterConfig : FloconPluginConfig { + var catchFatalErrors: Boolean = true +} + +interface FloconCrashReporterPlugin : FloconPlugin { + fun setupCrashHandler() +} + object FloconCrashReporter : FloconPluginFactory { override val name: String = "CrashReporter" @@ -27,7 +39,7 @@ object FloconCrashReporter : ): FloconCrashReporterPlugin { val client = floconConfig.client as FloconMessageSender return FloconCrashReporterPluginImpl( - context = TODO(), //FloconContext(appContext = null), // Handled by datasource + context = floconConfig.context, sender = client, coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()), ) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardDSL.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardDSL.kt index 3c9bc8353..f747dd047 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardDSL.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardDSL.kt @@ -1,10 +1,10 @@ package io.github.openflocon.flocon.plugins.dashboard -import io.github.openflocon.flocon.pluginsold.dashboard.builder.FormBuilder -import io.github.openflocon.flocon.pluginsold.dashboard.builder.SectionBuilder -import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardScope -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ContainerConfig +import io.github.openflocon.flocon.plugins.dashboard.builder.FormBuilder +import io.github.openflocon.flocon.plugins.dashboard.builder.SectionBuilder +import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig +import io.github.openflocon.flocon.plugins.dashboard.model.DashboardScope +import io.github.openflocon.flocon.plugins.dashboard.model.config.ContainerConfig import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt index aa60be205..a556a3880 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt @@ -1,21 +1,30 @@ package io.github.openflocon.flocon.plugins.dashboard -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.plugins.dashboard.mapper.toJson import io.github.openflocon.flocon.plugins.dashboard.model.DashboardCallback +import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig import io.github.openflocon.flocon.plugins.dashboard.model.todevice.ToDeviceCheckBoxValueChangedMessage import io.github.openflocon.flocon.plugins.dashboard.model.todevice.ToDeviceSubmittedFormMessage import io.github.openflocon.flocon.plugins.dashboard.model.todevice.ToDeviceSubmittedTextFieldMessage -import io.github.openflocon.flocon.pluginsold.dashboard.FloconDashboardConfig -import io.github.openflocon.flocon.pluginsold.dashboard.FloconDashboardPlugin -import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardConfig import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch - object FloconDashboard : FloconPluginFactory { +class FloconDashboardConfig : FloconPluginConfig + +interface FloconDashboardPlugin : FloconPlugin { + fun registerDashboard(dashboardConfig: DashboardConfig) +} + +object FloconDashboard : FloconPluginFactory { override val name: String = "Dashboard" override val pluginId: String = Protocol.ToDevice.Dashboard.Plugin override fun createConfig() = FloconDashboardConfig() @@ -41,7 +50,7 @@ internal class FloconDashboardPluginImpl( private val dashboards = mutableMapOf() private val callbackMap = mutableMapOf() - override suspend fun onMessageReceived( + override suspend fun onMessageReceived( method: String, body: String, ) { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/ContainerBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/ContainerBuilder.kt new file mode 100644 index 000000000..e9685eb39 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/ContainerBuilder.kt @@ -0,0 +1,14 @@ +package io.github.openflocon.flocon.plugins.dashboard.builder + +import io.github.openflocon.flocon.plugins.dashboard.model.config.ContainerConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.ElementConfig + +abstract class ContainerBuilder { + open val elements = mutableListOf() + + open fun add(element: ElementConfig) { + elements.add(element) + } + + abstract fun build(): ContainerConfig +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/DashboardBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/DashboardBuilder.kt new file mode 100644 index 000000000..77c7352b9 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/DashboardBuilder.kt @@ -0,0 +1,21 @@ +package io.github.openflocon.flocon.plugins.dashboard.builder + +import io.github.openflocon.flocon.plugins.dashboard.dsl.DashboardDsl +import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.ContainerConfig + +@DashboardDsl +class DashboardBuilder(private val id: String) { + private val containers = mutableListOf() + + fun add(container: ContainerConfig) { + containers.add(container) + } + + fun build(): DashboardConfig { + return DashboardConfig( + id = id, + containers = containers + ) + } +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/FormBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/FormBuilder.kt new file mode 100644 index 000000000..71ecf7b7d --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/FormBuilder.kt @@ -0,0 +1,20 @@ +package io.github.openflocon.flocon.plugins.dashboard.builder + +import io.github.openflocon.flocon.plugins.dashboard.model.config.FormConfig + +class FormBuilder( + val name: String, + val submitText: String, + val onSubmitted: (Map) -> Unit, +) : ContainerBuilder() { + + override fun build(): FormConfig { + return FormConfig( + id = "form_$name", + name = name, + submitText = submitText, + elements = elements, + onSubmitted = onSubmitted + ) + } +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/SectionBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/SectionBuilder.kt new file mode 100644 index 000000000..4d7cde6d6 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/builder/SectionBuilder.kt @@ -0,0 +1,10 @@ +package io.github.openflocon.flocon.plugins.dashboard.builder + +import io.github.openflocon.flocon.plugins.dashboard.model.config.SectionConfig + +class SectionBuilder(val name: String) : ContainerBuilder() { + + override fun build(): SectionConfig { + return SectionConfig(name, elements) + } +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/ButtonDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/ButtonDsl.kt new file mode 100644 index 000000000..60f4fac25 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/ButtonDsl.kt @@ -0,0 +1,19 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.plugins.dashboard.model.config.ButtonConfig + +@DashboardDsl +fun ContainerBuilder.button( + text: String, + id: String, + onClick: () -> Unit, +) { + add( + ButtonConfig( + text = text, + id = id, + onClick = onClick, + ) + ) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/CheckBoxDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/CheckBoxDsl.kt new file mode 100644 index 000000000..6569df699 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/CheckBoxDsl.kt @@ -0,0 +1,21 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.plugins.dashboard.model.config.CheckBoxConfig + +@DashboardDsl +fun ContainerBuilder.checkBox( + id: String, + label: String, + value: Boolean, + onUpdated: (Boolean) -> Unit = {}, +) { + add( + CheckBoxConfig( + id = id, + label = label, + value = value, + onUpdated = onUpdated, + ) + ) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/DashboardDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/DashboardDsl.kt new file mode 100644 index 000000000..097eab050 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/DashboardDsl.kt @@ -0,0 +1,15 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.DashboardBuilder +import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig + +@DslMarker +annotation class DashboardDsl + +fun dashboardConfig(id: String, block: DashboardBuilder.() -> Unit): DashboardConfig { + val builder = DashboardBuilder(id = id) + .apply { + block() + } + return builder.build() +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/FormDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/FormDsl.kt new file mode 100644 index 000000000..9603e49ec --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/FormDsl.kt @@ -0,0 +1,22 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.DashboardBuilder +import io.github.openflocon.flocon.plugins.dashboard.builder.FormBuilder + +@DashboardDsl +fun DashboardBuilder.form( + name: String, + submitText: String, + onSubmitted: (Map) -> Unit, + block: FormBuilder.() -> Unit +) { + val builder = FormBuilder( + name = name, + submitText = submitText, + onSubmitted = onSubmitted + ).apply { + block() + } + + add(builder.build()) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/HtmlDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/HtmlDsl.kt new file mode 100644 index 000000000..5b93e4884 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/HtmlDsl.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.plugins.dashboard.model.config.HtmlConfig + +@DashboardDsl +fun ContainerBuilder.html(label: String, value: String) { + add(HtmlConfig(label = label, value = value)) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/MarkdownDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/MarkdownDsl.kt new file mode 100644 index 000000000..1a9d5f6f3 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/MarkdownDsl.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.plugins.dashboard.model.config.MarkdownConfig + +@DashboardDsl +fun ContainerBuilder.markdown(label: String, value: String) { + add(MarkdownConfig(label = label, value = value)) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/PlainTextDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/PlainTextDsl.kt new file mode 100644 index 000000000..8fa25c287 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/PlainTextDsl.kt @@ -0,0 +1,26 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.plugins.dashboard.model.config.PlainTextConfig + +@DashboardDsl +fun ContainerBuilder.plainText(label: String, value: String) { + add( + PlainTextConfig( + label = label, + value = value, + type = "text", + ) + ) +} + +@DashboardDsl +fun ContainerBuilder.json(label: String, value: String) { + add( + PlainTextConfig( + label = label, + value = value, + type = "json", + ) + ) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/SectionDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/SectionDsl.kt new file mode 100644 index 000000000..0bc1b3956 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/SectionDsl.kt @@ -0,0 +1,13 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.DashboardBuilder +import io.github.openflocon.flocon.plugins.dashboard.builder.SectionBuilder + +@DashboardDsl +fun DashboardBuilder.section(name: String, block: SectionBuilder.() -> Unit) { + val builder = SectionBuilder(name).apply { + block() + } + + add(builder.build()) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextDsl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextDsl.kt new file mode 100644 index 000000000..c56b3f555 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextDsl.kt @@ -0,0 +1,15 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.plugins.dashboard.model.config.LabelConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.TextConfig + +@DashboardDsl +fun ContainerBuilder.text(label: String, value: String, color: Int? = null) { + add(TextConfig(label = label, value = value, color = color)) +} + +@DashboardDsl +fun ContainerBuilder.label(label: String, color: Int? = null) { + add(LabelConfig(label = label, color = color)) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextField.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextField.kt new file mode 100644 index 000000000..42bf0bc4e --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/dsl/TextField.kt @@ -0,0 +1,23 @@ +package io.github.openflocon.flocon.plugins.dashboard.dsl + +import io.github.openflocon.flocon.plugins.dashboard.builder.ContainerBuilder +import io.github.openflocon.flocon.plugins.dashboard.model.config.TextFieldConfig + +@DashboardDsl +fun ContainerBuilder.textField( + id: String, + label: String, + placeHolder: String?, + value: String, + onSubmitted: (String) -> Unit = {}, +) { + add( + TextFieldConfig( + id = id, + label = label, + placeHolder = placeHolder, + value = value, + onSubmitted = onSubmitted, + ) + ) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/mapper/JsonMapper.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/mapper/JsonMapper.kt index c7410bcb3..09626f9cc 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/mapper/JsonMapper.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/mapper/JsonMapper.kt @@ -7,19 +7,19 @@ import io.github.openflocon.flocon.plugins.dashboard.model.DashboardCallback.But import io.github.openflocon.flocon.plugins.dashboard.model.DashboardCallback.CheckBoxCallback import io.github.openflocon.flocon.plugins.dashboard.model.DashboardCallback.FormCallback import io.github.openflocon.flocon.plugins.dashboard.model.DashboardCallback.TextFieldCallback -import io.github.openflocon.flocon.pluginsold.dashboard.model.DashboardConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ButtonConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.CheckBoxConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ContainerConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.ElementConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.FormConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.HtmlConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.LabelConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.MarkdownConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.PlainTextConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.SectionConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.TextConfig -import io.github.openflocon.flocon.pluginsold.dashboard.model.config.TextFieldConfig +import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.ButtonConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.CheckBoxConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.ContainerConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.ElementConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.FormConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.HtmlConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.LabelConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.MarkdownConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.PlainTextConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.SectionConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.TextConfig +import io.github.openflocon.flocon.plugins.dashboard.model.config.TextFieldConfig import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.buildJsonObject diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/ContainerType.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/ContainerType.kt new file mode 100644 index 000000000..8bf2247aa --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/ContainerType.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon.plugins.dashboard.model + +enum class ContainerType { + FORM, + SECTION +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardConfig.kt new file mode 100644 index 000000000..87432e05a --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardConfig.kt @@ -0,0 +1,8 @@ +package io.github.openflocon.flocon.plugins.dashboard.model + +import io.github.openflocon.flocon.plugins.dashboard.model.config.ContainerConfig + +data class DashboardConfig( + val id: String, + val containers: List +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardScope.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardScope.kt new file mode 100644 index 000000000..291222091 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/DashboardScope.kt @@ -0,0 +1,25 @@ +package io.github.openflocon.flocon.plugins.dashboard.model + +import io.github.openflocon.flocon.plugins.dashboard.builder.FormBuilder +import io.github.openflocon.flocon.plugins.dashboard.builder.SectionBuilder +import kotlinx.coroutines.flow.Flow + +interface DashboardScope { + fun section(name: String, flow: Flow, content: SectionBuilder.(T) -> Unit) + fun section(name: String, content: SectionBuilder.() -> Unit) + + fun form( + name: String, + submitText: String = "Submit", + onSubmitted: (Map) -> Unit, + flow: Flow, + content: FormBuilder.(T) -> Unit + ) + + fun form( + name: String, + submitText: String = "Submit", + onSubmitted: (Map) -> Unit, + content: FormBuilder.() -> Unit + ) +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ButtonConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ButtonConfig.kt new file mode 100644 index 000000000..f7703e279 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ButtonConfig.kt @@ -0,0 +1,7 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +data class ButtonConfig( + val text: String, + val id: String, + val onClick: () -> Unit, +) : ElementConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/CheckBoxConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/CheckBoxConfig.kt new file mode 100644 index 000000000..f6f534486 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/CheckBoxConfig.kt @@ -0,0 +1,8 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +data class CheckBoxConfig( + val id: String, + val label: String, + val value: Boolean, + val onUpdated: (Boolean) -> Unit, +) : ElementConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ContainerConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ContainerConfig.kt new file mode 100644 index 000000000..88f77c091 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ContainerConfig.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +import io.github.openflocon.flocon.plugins.dashboard.model.ContainerType + +sealed interface ContainerConfig { + val name: String + val elements: List + val containerType: ContainerType +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ElementConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ElementConfig.kt new file mode 100644 index 000000000..8a3e4e3c0 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/ElementConfig.kt @@ -0,0 +1,3 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +sealed interface ElementConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/FormConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/FormConfig.kt new file mode 100644 index 000000000..37e3bf917 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/FormConfig.kt @@ -0,0 +1,13 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +import io.github.openflocon.flocon.plugins.dashboard.model.ContainerType + +data class FormConfig( + override val name: String, + override val elements: List, + val id: String, + val submitText: String, + val onSubmitted: (Map) -> Unit, +) : ContainerConfig { + override val containerType: ContainerType = ContainerType.FORM +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/HtmlConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/HtmlConfig.kt new file mode 100644 index 000000000..70fce9994 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/HtmlConfig.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +data class HtmlConfig( + val label: String, + val value: String, +) : ElementConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/LabelConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/LabelConfig.kt new file mode 100644 index 000000000..9dcf4e815 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/LabelConfig.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +data class LabelConfig( + val label: String, + val color: Int?, +) : ElementConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/MarkdownConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/MarkdownConfig.kt new file mode 100644 index 000000000..f2e4a3799 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/MarkdownConfig.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +data class MarkdownConfig( + val label: String, + val value: String, +) : ElementConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/PlainTextConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/PlainTextConfig.kt new file mode 100644 index 000000000..12b74553f --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/PlainTextConfig.kt @@ -0,0 +1,7 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +data class PlainTextConfig( + val label: String, + val value: String, + val type: String, // text, json +) : ElementConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/SectionConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/SectionConfig.kt new file mode 100644 index 000000000..a707d5b01 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/SectionConfig.kt @@ -0,0 +1,10 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +import io.github.openflocon.flocon.plugins.dashboard.model.ContainerType + +data class SectionConfig( + override val name: String, + override val elements: List, +) : ContainerConfig { + override val containerType: ContainerType = ContainerType.SECTION +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextConfig.kt new file mode 100644 index 000000000..b33db66ba --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextConfig.kt @@ -0,0 +1,7 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +data class TextConfig( + val label: String, + val value: String, + val color: Int?, +) : ElementConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextFieldConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextFieldConfig.kt new file mode 100644 index 000000000..63de1f656 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/config/TextFieldConfig.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.plugins.dashboard.model.config + +data class TextFieldConfig( + val id: String, + val label: String, + val placeHolder: String?, + val value: String, + val onSubmitted: (String) -> Unit, +) : ElementConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt index 1d9ceac05..0463c2d9f 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt @@ -1,21 +1,26 @@ package io.github.openflocon.flocon.plugins.database -import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseExecuteSqlResponse import io.github.openflocon.flocon.plugins.database.model.fromdevice.DeviceDataBaseDataModel import io.github.openflocon.flocon.plugins.database.model.todevice.DatabaseQueryMessage -import io.github.openflocon.flocon.pluginsold.database.FloconDatabaseConfig -import io.github.openflocon.flocon.pluginsold.database.FloconDatabasePlugin -import io.github.openflocon.flocon.pluginsold.database.model.FloconDatabaseModel +import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel import kotlinx.coroutines.flow.MutableStateFlow +class FloconDatabaseConfig : FloconPluginConfig + +interface FloconDatabasePlugin : FloconPlugin { + fun register(floconDatabaseModel: FloconDatabaseModel) + fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) +} + internal interface FloconDatabaseDataSource { fun executeSQL( registeredDatabases: List, @@ -40,7 +45,7 @@ object FloconDatabase : FloconPluginFactory { override val name: String = "Device" diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt index 152b8e666..a3c708973 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt @@ -1,11 +1,11 @@ package io.github.openflocon.flocon.plugins.files -import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconFile import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconFileSender @@ -17,11 +17,15 @@ import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceDeleteFi import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceDeleteFolderContentMessage import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceGetFileMessage import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceGetFilesMessage -import io.github.openflocon.flocon.pluginsold.files.FloconFilesConfig -import io.github.openflocon.flocon.pluginsold.files.FloconFilesPlugin import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update +class FloconFilesConfig : FloconPluginConfig { + val roots = mutableListOf() +} + +interface FloconFilesPlugin : FloconPlugin + object FloconFiles : FloconPluginFactory { override val name: String = "Files" override val pluginId: String = Protocol.ToDevice.Files.Plugin diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt index d64298869..f2d162865 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt @@ -1,10 +1,20 @@ package io.github.openflocon.flocon.plugins.sharedprefs -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.pluginsold.sharedprefs.FloconPreferencesConfig -import io.github.openflocon.flocon.pluginsold.sharedprefs.FloconPreferencesPlugin -import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconSharedPreferenceModel +import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconSharedPreferenceModel + +class FloconPreferencesConfig : FloconPluginConfig + +interface FloconPreferencesPlugin : FloconPlugin { + fun register(sharedPreference: FloconSharedPreferenceModel) +} object FloconPreferences : FloconPluginFactory { override val name: String = "Preferences" diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt new file mode 100644 index 000000000..47b0e946f --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt @@ -0,0 +1,5 @@ +package io.github.openflocon.flocon.plugins.sharedprefs.model + +// TODO Get model from git +class FloconSharedPreferenceModel { +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt index 338bce055..e22068da7 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt @@ -1,12 +1,22 @@ package io.github.openflocon.flocon.plugins.tables -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.pluginsold.tables.FloconTableConfig -import io.github.openflocon.flocon.pluginsold.tables.FloconTablePlugin -import io.github.openflocon.flocon.pluginsold.tables.model.TableItem +import io.github.openflocon.flocon.plugins.tables.model.TableItem +import io.github.openflocon.flocon.plugins.tables.model.tableItemListToJson - object FloconTable : FloconPluginFactory { +class FloconTableConfig : FloconPluginConfig + +interface FloconTablePlugin : FloconPlugin { + fun registerItems(tableItems: List) +} + +object FloconTable : FloconPluginFactory { override val name: String = "Table" override val pluginId: String = Protocol.ToDevice.Table.Plugin override fun createConfig() = FloconTableConfig() diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt index 2e81530b7..81467899b 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt @@ -1,11 +1,28 @@ package io.github.openflocon.flocon.plugins.tables.model import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.pluginsold.tables.model.TableColumnConfig -import io.github.openflocon.flocon.pluginsold.tables.model.TableItem import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString +data class TableItem( + val id: String, + val name: String, + val createdAt: Long, + val columns: List, +) + +data class TableColumnConfig( + val columnName: String, + val value: String, +) + +infix fun String.toParam(value: String) = TableColumnConfig( + columnName = this, + value = value, +) + +// --- JSON Serialization --- + internal fun tableItemListToJson(items: Collection): String { return FloconEncoder.json.encodeToString(items.map { it.toRemote() }) } diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt index 645d38c33..9d596dd9a 100644 --- a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt +++ b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt @@ -2,7 +2,6 @@ package io.github.openflocon.flocon.plugins.sharedprefs import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference -import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference //internal actual fun buildFloconPreferencesDataSource(context: FloconContext): FloconPreferencesDataSource { // return FloconPreferencesDataSourceJvm() diff --git a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt index 2f9de14b2..00d93ba8b 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt +++ b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt @@ -4,5 +4,5 @@ import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest import kotlinx.coroutines.CompletableDeferred internal data class RequestHolder( - val request: CompletableDeferred = CompletableDeferred() + val request: CompletableDeferred = CompletableDeferred() ) \ No newline at end of file diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt index ab2a5f8c9..4935b04a4 100644 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt @@ -7,8 +7,8 @@ import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.error.pluginNotInitialized import io.github.openflocon.flocon.network.core.noop.plugin.FloconNetworkPluginImpl -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkConfig -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin +import io.github.openflocon.flocon.network.core.FloconNetworkConfig +import io.github.openflocon.flocon.network.core.FloconNetworkPlugin object FloconNetwork : FloconPluginFactory { override val name: String = "Network" diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt index 1e9c85456..90df55c94 100644 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt @@ -2,7 +2,7 @@ package io.github.openflocon.flocon.network.core.noop.mapper import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.BadQualityConfig import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt index 03b132903..4fe64d4db 100644 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt @@ -3,9 +3,9 @@ package io.github.openflocon.flocon.network.core.noop.mapper import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.network.core.model.FloconWebSocketEvent import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlin.uuid.ExperimentalUuidApi diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt index 9696d7d1f..7ab3d09bf 100644 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt @@ -2,7 +2,7 @@ package io.github.openflocon.flocon.network.core.noop.mapper import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/plugin/FloconNetworkPluginImpl.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/plugin/FloconNetworkPluginImpl.kt index 6f1a38e8e..a2b02b316 100644 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/plugin/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/plugin/FloconNetworkPluginImpl.kt @@ -1,13 +1,13 @@ package io.github.openflocon.flocon.network.core.noop.plugin import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent -import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketMockListener -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.FloconNetworkPlugin +import io.github.openflocon.flocon.network.core.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.network.core.model.FloconWebSocketEvent +import io.github.openflocon.flocon.network.core.model.FloconWebSocketMockListener +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse internal class FloconNetworkPluginImpl : FloconPlugin, FloconNetworkPlugin { override val key: String = "NETWORK" diff --git a/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt index 3351a639f..07a3bd15a 100644 --- a/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt +++ b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt @@ -8,8 +8,8 @@ import io.github.openflocon.flocon.network.core.mapper.toJsonString import io.github.openflocon.flocon.network.core.mapper.writeMockResponsesToJson import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_BAD_CONFIG_JSON import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_MOCKS_JSON -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse import java.io.File import java.io.FileInputStream import java.io.FileOutputStream diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt index 43f00fd3a..636aada5e 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt @@ -2,19 +2,44 @@ package io.github.openflocon.flocon.network.core import io.github.openflocon.flocon.Flocon import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.error.pluginNotInitialized +import io.github.openflocon.flocon.network.core.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.network.core.model.FloconWebSocketEvent +import io.github.openflocon.flocon.network.core.model.FloconWebSocketMockListener +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse import io.github.openflocon.flocon.network.core.plugin.FloconNetworkPluginImpl -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkConfig -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.SupervisorJob +class FloconNetworkConfig : FloconPluginConfig { + var badQualityConfig: BadQualityConfig? = null + val mocks = mutableListOf() +} + +interface FloconNetworkPlugin : FloconPlugin { + val mocks: Collection + val badQualityConfig: BadQualityConfig? + + fun logRequest(request: FloconNetworkCallRequest) + fun logResponse(response: FloconNetworkCallResponse) + + suspend fun logWebSocket( + event: FloconWebSocketEvent, + ) + + suspend fun registerWebSocketMockListener(id: String, listener: FloconWebSocketMockListener) +} + object FloconNetwork : FloconPluginFactory { override val name: String = "Network" override val pluginId: String = Protocol.ToDevice.Network.Plugin diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.kt index 69cf9d441..4048ace9c 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.kt @@ -1,8 +1,8 @@ package io.github.openflocon.flocon.network.core.datasource import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse internal interface FloconNetworkDataSource { fun saveMocksToFile(mocks: List) diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/BadQualityToJson.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/BadQualityToJson.kt index 0b4c0950e..88caef4df 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/BadQualityToJson.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/BadQualityToJson.kt @@ -2,7 +2,7 @@ package io.github.openflocon.flocon.network.core.mapper import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.BadQualityConfig import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt index 45d3977cd..329115850 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt @@ -3,9 +3,9 @@ package io.github.openflocon.flocon.network.core.mapper import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.network.core.model.FloconWebSocketEvent import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlin.uuid.ExperimentalUuidApi diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt index ba7227eed..76b00f959 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt @@ -2,7 +2,7 @@ package io.github.openflocon.flocon.network.core.mapper import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/BadQualityConfig.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/BadQualityConfig.kt new file mode 100644 index 000000000..fb1293f90 --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/BadQualityConfig.kt @@ -0,0 +1,72 @@ +package io.github.openflocon.flocon.network.core.model + +import io.github.openflocon.flocon.FloconLogger +import kotlin.random.Random + +data class BadQualityConfig( + val latency: LatencyConfig, + val errorProbability: Double, // chance of triggering an error + val errors: List, // list of errors +) { + class LatencyConfig( + val latencyTriggerProbability: Float, + val minLatencyMs: Long, + val maxLatencyMs: Long, + ) { + fun shouldSimulateLatency(): Boolean { + return latencyTriggerProbability > 0f && (latencyTriggerProbability == 1f || Random.nextDouble() < latencyTriggerProbability) + } + fun getRandomLatency() : Long { + return Random.nextLong( + minLatencyMs, + maxLatencyMs + 1 + ) + } + } + class Error( + val weight: Float, // increase the probability of being triggered vs all others errors + val type: Type, + ) { + sealed interface Type { + data class Body( + val errorCode: Int, + val errorBody: String, + val errorContentType: String, // "application/json" + ) : Type + data class ErrorThrow( + val classPath: String, + ) : Type { + fun generate() : Throwable? { + return try { + io.github.openflocon.flocon.utils.createThrowableFromClassName(classPath) + } catch (t: Throwable) { + FloconLogger.logError("BadQualityConfig error, className not found", t) + null + } + } + } + } + } + + fun shouldFail(): Boolean { + return errorProbability > 0 && Random.nextDouble() < errorProbability + } + + fun selectRandomError(): BadQualityConfig.Error? { + if (errors.isEmpty()) { + return null + } + + val totalWeight = errors.sumOf { it.weight.toDouble() } + var randomNumber = Random.nextDouble(0.0, totalWeight) + + for (error in errors) { + randomNumber -= error.weight.toDouble() + if (randomNumber <= 0) { + return error + } + } + + return errors.first() + } +} diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconHttpRequest.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconHttpRequest.kt new file mode 100644 index 000000000..2b2029b59 --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconHttpRequest.kt @@ -0,0 +1,23 @@ +package io.github.openflocon.flocon.network.core.model + +data class FloconNetworkRequest( + val url: String, + val method: String, + val startTime: Long, + val headers: Map, + val body: String?, + val size: Long?, + val isMocked: Boolean, +) + +data class FloconNetworkResponse( + val httpCode: Int?, + val grpcStatus: String?, + val contentType: String?, + val body: String?, + val size: Long?, + val headers: Map, + val requestHeaders: Map?, // we might receive the request headers later if the interceptor is at first position in the http interceptor chain + val error: String?, + val isImage: Boolean, +) diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconNetworkCallRequest.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconNetworkCallRequest.kt new file mode 100644 index 000000000..bcaf31628 --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconNetworkCallRequest.kt @@ -0,0 +1,8 @@ +package io.github.openflocon.flocon.network.core.model + +data class FloconNetworkCallRequest( + val floconCallId: String, + val request: FloconNetworkRequest, + val floconNetworkType: String, + val isMocked: Boolean, +) diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconNetworkCallResponse.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconNetworkCallResponse.kt new file mode 100644 index 000000000..20cb62bf3 --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconNetworkCallResponse.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.network.core.model + +data class FloconNetworkCallResponse( + val floconCallId: String, + val response: FloconNetworkResponse, + val durationMs: Double, + val floconNetworkType: String, + val isMocked: Boolean, +) diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconWebSocketEvent.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconWebSocketEvent.kt new file mode 100644 index 000000000..df16fbbc4 --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconWebSocketEvent.kt @@ -0,0 +1,21 @@ +package io.github.openflocon.flocon.network.core.model + +import io.github.openflocon.flocon.utils.currentTimeMillis + +class FloconWebSocketEvent( + val websocketUrl: String, + val event: Event, + val size: Long = 0L, + val message: String? = null, + val error: Throwable? = null, + val timeStamp: Long = currentTimeMillis(), +) { + enum class Event { + Closed, + Closing, + Error, + ReceiveMessage, + SendMessage, + Open, + } +} diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconWebSocketMockListener.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconWebSocketMockListener.kt new file mode 100644 index 000000000..3c1928a7f --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/FloconWebSocketMockListener.kt @@ -0,0 +1,5 @@ +package io.github.openflocon.flocon.network.core.model + +interface FloconWebSocketMockListener { + fun onMessage(message: String) +} diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/MockNetworkResponse.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/MockNetworkResponse.kt new file mode 100644 index 000000000..09562fe3c --- /dev/null +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/model/MockNetworkResponse.kt @@ -0,0 +1,39 @@ +package io.github.openflocon.flocon.network.core.model + +data class MockNetworkResponse( + val expectation: Expectation, + val response: Response, +) { + data class Expectation( + val urlPattern: String, // a regex + val method: String, // can be get, post, put, ... or a wildcard * + ) { + + private val regex = Regex(urlPattern) + + fun matches(url: String, method: String): Boolean { + val urlMatches = regex.matches(url) + val methodMatches = this.method == "*" || this.method.equals(method, ignoreCase = true) + return urlMatches && methodMatches + } + } + + sealed interface Response { + val delay: Long + data class Body( + val httpCode: Int, + val body: String, + override val delay: Long, + val mediaType: String, + val headers: Map, + ) : Response + data class ErrorThrow( + val classPath: String, + override val delay: Long, + ) : Response { + fun generate() : Throwable? { + return io.github.openflocon.flocon.utils.createThrowableFromClassName(classPath) + } + } + } +} diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt index cca03df51..c95e76a53 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt @@ -13,13 +13,13 @@ import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig import io.github.openflocon.flocon.network.core.mapper.parseMockResponses import io.github.openflocon.flocon.network.core.mapper.parseWebSocketMockMessage import io.github.openflocon.flocon.network.core.mapper.webSocketIdsToJsonArray -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent -import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketMockListener -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.FloconNetworkPlugin +import io.github.openflocon.flocon.network.core.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.network.core.model.FloconWebSocketEvent +import io.github.openflocon.flocon.network.core.model.FloconWebSocketMockListener +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow diff --git a/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt b/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt index fad59bfae..c062ee677 100644 --- a/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt +++ b/FloconAndroid/network/core/src/iosMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt @@ -1,7 +1,7 @@ package io.github.openflocon.flocon.network.core.datasource -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse internal class FloconNetworkDataSourceImpl : FloconNetworkDataSource { diff --git a/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt b/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt index a2e304384..be864eafa 100644 --- a/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt +++ b/FloconAndroid/network/core/src/jvmMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceImpl.kt @@ -7,8 +7,8 @@ import io.github.openflocon.flocon.network.core.mapper.toJsonString import io.github.openflocon.flocon.network.core.mapper.writeMockResponsesToJson import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_BAD_CONFIG_JSON import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_MOCKS_JSON -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse import java.io.File import java.io.FileInputStream import java.io.FileOutputStream diff --git a/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt b/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt index 0ee37502c..b56f7fd25 100644 --- a/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt +++ b/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/BadQuality.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.ktor -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.BadQualityConfig import io.ktor.client.HttpClient import io.ktor.client.call.HttpClientCall import io.ktor.client.request.HttpRequestBuilder diff --git a/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt b/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt index d6d99e3b7..1f68c28e5 100644 --- a/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt +++ b/FloconAndroid/network/ktor-interceptor/src/commonMain/kotlin/io/github/openflocon/flocon/ktor/Mocks.kt @@ -1,7 +1,7 @@ package io.github.openflocon.flocon.ktor -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.FloconNetworkPlugin +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse import io.ktor.client.HttpClient import io.ktor.client.call.HttpClientCall import io.ktor.client.request.HttpRequestBuilder diff --git a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt index 35c443ef4..b632a7e9e 100644 --- a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt +++ b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/BadQuality.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.okhttp -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.BadQualityConfig import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.Protocol import okhttp3.Request diff --git a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt index b09e3f3ac..a597b6702 100644 --- a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt +++ b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/Mock.kt @@ -1,7 +1,7 @@ package io.github.openflocon.flocon.okhttp -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.FloconNetworkPlugin +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.Protocol import okhttp3.Request diff --git a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt index d201396fd..3d0b712ba 100644 --- a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt +++ b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt @@ -4,10 +4,10 @@ package io.github.openflocon.flocon.okhttp import io.github.openflocon.flocon.Flocon import io.github.openflocon.flocon.network.core.networkPlugin -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkResponse +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkCallResponse +import io.github.openflocon.flocon.network.core.model.FloconNetworkRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkResponse import okhttp3.Interceptor import okhttp3.MediaType import okhttp3.Request diff --git a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt index d7208acbf..09d5593fb 100644 --- a/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt +++ b/FloconAndroid/network/okhttp-interceptor/src/main/kotlin/io/github/openflocon/flocon/okhttp/websocket/FloconWebSocket.kt @@ -1,7 +1,7 @@ package io.github.openflocon.flocon.okhttp.websocket import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent +import io.github.openflocon.flocon.network.core.model.FloconWebSocketEvent import okhttp3.Response import okhttp3.WebSocket import okhttp3.WebSocketListener diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/dashboard/InitializeDashboard.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/dashboard/InitializeDashboard.kt index bc472fa48..e0761a5d8 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/dashboard/InitializeDashboard.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/dashboard/InitializeDashboard.kt @@ -12,14 +12,14 @@ import io.github.openflocon.flocon.myapplication.dashboard.device.initializeDevi import io.github.openflocon.flocon.myapplication.dashboard.tokens.tokensFlow import io.github.openflocon.flocon.myapplication.dashboard.user.userFlow import io.github.openflocon.flocon.plugins.dashboard.floconDashboard -import io.github.openflocon.flocon.pluginsold.dashboard.dsl.button -import io.github.openflocon.flocon.pluginsold.dashboard.dsl.checkBox -import io.github.openflocon.flocon.pluginsold.dashboard.dsl.html -import io.github.openflocon.flocon.pluginsold.dashboard.dsl.json -import io.github.openflocon.flocon.pluginsold.dashboard.dsl.markdown -import io.github.openflocon.flocon.pluginsold.dashboard.dsl.plainText -import io.github.openflocon.flocon.pluginsold.dashboard.dsl.text -import io.github.openflocon.flocon.pluginsold.dashboard.dsl.textField +import io.github.openflocon.flocon.plugins.dashboard.dsl.button +import io.github.openflocon.flocon.plugins.dashboard.dsl.checkBox +import io.github.openflocon.flocon.plugins.dashboard.dsl.html +import io.github.openflocon.flocon.plugins.dashboard.dsl.json +import io.github.openflocon.flocon.plugins.dashboard.dsl.markdown +import io.github.openflocon.flocon.plugins.dashboard.dsl.plainText +import io.github.openflocon.flocon.plugins.dashboard.dsl.text +import io.github.openflocon.flocon.plugins.dashboard.dsl.textField import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt index b14bb0625..c0da1d077 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt @@ -6,7 +6,6 @@ import io.github.openflocon.flocon.myapplication.database.model.DogEntity import io.github.openflocon.flocon.myapplication.database.model.FoodEntity import io.github.openflocon.flocon.myapplication.database.model.HumanEntity import io.github.openflocon.flocon.myapplication.database.model.HumanWithDogEntity -import io.github.openflocon.flocon.pluginsold.database.floconRegisterDatabase import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -15,10 +14,10 @@ fun initializeInMemoryDatabases(context: Context): DogDatabase { context, DogDatabase::class.java, ).build().also { - floconRegisterDatabase( - displayName = "inmemory_dogs", - openHelper = it.openHelper - ) +// floconRegisterDatabase( +// displayName = "inmemory_dogs", +// openHelper = it.openHelper +// ) } } diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/SharedPreferences.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/SharedPreferences.kt index 051be10c0..099d6d9f6 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/SharedPreferences.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/sharedpreferences/SharedPreferences.kt @@ -5,7 +5,6 @@ package io.github.openflocon.flocon.myapplication.sharedpreferences import android.content.Context import android.preference.PreferenceManager import androidx.core.content.edit -import io.github.openflocon.flocon.pluginsold.sharedprefs.FloconSharedPreference import org.json.JSONArray import org.json.JSONObject import kotlin.uuid.Uuid From c4125f5f73aea9dbc2b1a6e09c4bdb98b05451ae Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Thu, 12 Mar 2026 23:40:07 +0100 Subject: [PATCH 13/35] feat: Move database --- .../database/core-no-op/build.gradle.kts | 118 ++++++++++++++ FloconAndroid/database/core/build.gradle.kts | 126 +++++++++++++++ .../core}/FloconDatabasePlugin.android.kt | 57 ++----- .../core/FloconSqliteDatabaseModel.kt | 9 ++ .../database/core/FloconDatabasePlugin.kt | 146 ++++++++++++++++++ .../core/model/FloconDatabaseModel.kt | 16 ++ .../fromdevice/DatabaseExecuteSqlResponse.kt | 59 +++++++ .../model/fromdevice/DatabaseQueryLogModel.kt | 23 +++ .../fromdevice/DeviceDataBaseDataModel.kt | 15 ++ .../QueryResultReceivedDataModel.kt | 15 ++ .../model/todevice/DatabaseQueryMessage.kt | 23 +++ .../database/core/FloconDatabasePlugin.ios.kt | 127 +++++++++++++++ .../database/room-no-op/build.gradle.kts | 82 ++++++++++ .../database/room/floconRegisterDatabase.kt | 9 ++ FloconAndroid/database/room/build.gradle.kts | 91 +++++++++++ .../database/room/FloconRoomDatabaseModel.kt | 28 ++++ FloconAndroid/flocon/build.gradle.kts | 5 - .../database/FloconDatabasePlugin.android.kt | 7 - .../database/FloconSqliteDatabaseModel.kt | 27 ---- .../plugins/database/FloconDatabasePlugin.kt | 136 +--------------- .../database/model/FloconDatabaseModel.kt | 11 +- .../database/FloconDatabasePlugin.kt | 39 +---- .../database/model/FloconDatabaseModel.kt | 11 +- FloconAndroid/settings.gradle.kts | 4 + 24 files changed, 908 insertions(+), 276 deletions(-) create mode 100644 FloconAndroid/database/core-no-op/build.gradle.kts create mode 100644 FloconAndroid/database/core/build.gradle.kts rename FloconAndroid/{flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database => database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core}/FloconDatabasePlugin.android.kt (78%) create mode 100644 FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconSqliteDatabaseModel.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseQueryLogModel.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DeviceDataBaseDataModel.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/QueryResultReceivedDataModel.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/todevice/DatabaseQueryMessage.kt create mode 100644 FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt create mode 100644 FloconAndroid/database/room-no-op/build.gradle.kts create mode 100644 FloconAndroid/database/room-no-op/src/main/java/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt create mode 100644 FloconAndroid/database/room/build.gradle.kts create mode 100644 FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt delete mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.android.kt delete mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconSqliteDatabaseModel.kt diff --git a/FloconAndroid/database/core-no-op/build.gradle.kts b/FloconAndroid/database/core-no-op/build.gradle.kts new file mode 100644 index 000000000..b7390b113 --- /dev/null +++ b/FloconAndroid/database/core-no-op/build.gradle.kts @@ -0,0 +1,118 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +android { + namespace = "io.github.openflocon.flocon.database.core.noop" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-database-core-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Database Core No-Op" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/database/core/build.gradle.kts b/FloconAndroid/database/core/build.gradle.kts new file mode 100644 index 000000000..295d31de3 --- /dev/null +++ b/FloconAndroid/database/core/build.gradle.kts @@ -0,0 +1,126 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) + alias(libs.plugins.kotlin.serialization) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + api(project(":flocon")) + + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(libs.kotlinx.serialization.json) + } + } + + val androidMain by getting { + dependencies { + implementation(libs.androidx.sqlite) + implementation(libs.androidx.sqlite.framework) + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + dependencies { + implementation(libs.androidx.sqlite.bundled) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.database.core" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-database-core", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Database Core" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.android.kt similarity index 78% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt rename to FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.android.kt index e8b491b09..a35064604 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.android.kt +++ b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.android.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.pluginsold.database +package io.github.openflocon.flocon.database.core import android.content.Context import android.database.Cursor @@ -7,16 +7,16 @@ import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteOpenHelper import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.plugins.database.FloconDatabaseDataSource -import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseExecuteSqlResponse -import io.github.openflocon.flocon.plugins.database.model.fromdevice.DeviceDataBaseDataModel -import io.github.openflocon.flocon.pluginsold.database.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.FloconAndroidSqlDatabaseModel +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.DeviceDataBaseDataModel import java.io.File import java.util.Locale -//internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { -// return FloconDatabaseDataSourceAndroid(context.context) -//} +internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { + return FloconDatabaseDataSourceAndroid(context.context) +} internal class FloconDatabaseDataSourceAndroid(private val context: Context) : FloconDatabaseDataSource { @@ -24,18 +24,19 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : private val MAX_DEPTH = 7 override fun executeSQL( - registeredDatabases: List, + registeredDatabases: List, databaseName: String, query: String ): DatabaseExecuteSqlResponse { val databaseModel = registeredDatabases.find { it.displayName == databaseName } - return when(databaseModel) { - is FloconSqliteDatabaseModel -> { + return when (databaseModel) { + is FloconAndroidSqlDatabaseModel -> { executeSQL( database = databaseModel.database, query = query, ) } + else -> openDbAndExecuteQuery( databaseName = databaseName, query = query, @@ -105,7 +106,7 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : } } - override fun getAllDataBases(registeredDatabases: List): List { + override fun getAllDataBases(registeredDatabases: List): List { val databasesDir = context.getDatabasePath("dummy_db").parentFile ?: return emptyList() val foundDatabases = mutableListOf() @@ -116,39 +117,9 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : foundDatabases = foundDatabases ) -// registeredDatabases.forEach { -// when(it) { -// is FloconFileDatabaseModel -> { -// // check if file exists here -// if (File(it.absolutePath).exists()) { -// foundDatabases.add( -// DeviceDataBaseDataModel( -// id = it.absolutePath, -// name = it.displayName, -// ) -// ) -// } -// } -// else -> { -// foundDatabases.add( -// DeviceDataBaseDataModel( -// id = it.displayName, -// name = it.displayName, -// ) -// ) -// } -// } -// } - return foundDatabases } - /** - * Recursively scans a directory for SQLite database files. - * - * @param directory The current directory to scan. - * @param foundDatabases The mutable list to add found databases to. - */ private fun scanDirectoryForDatabases( directory: File, depth: Int, @@ -184,7 +155,6 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : } } - private fun executeSelect( database: SupportSQLiteDatabase, query: String, @@ -259,7 +229,6 @@ private fun getObjectFromColumnIndex(cursor: Cursor, column: Int): String? { } } -// must use the old way to get the version... private fun getDatabaseVersion( path: String, ): Int { diff --git a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconSqliteDatabaseModel.kt b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconSqliteDatabaseModel.kt new file mode 100644 index 000000000..a5001434c --- /dev/null +++ b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconSqliteDatabaseModel.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.database.core + +import androidx.sqlite.db.SupportSQLiteDatabase +import io.github.openflocon.flocon.database.core.model.FloconAndroidSqlDatabaseModel + +internal class FloconSqliteDatabaseModel( + override val displayName: String, + val database: SupportSQLiteDatabase +) : FloconAndroidSqlDatabaseModel diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt new file mode 100644 index 000000000..296894eae --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt @@ -0,0 +1,146 @@ +package io.github.openflocon.flocon.database.core + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.DeviceDataBaseDataModel +import io.github.openflocon.flocon.database.core.model.todevice.DatabaseQueryMessage +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.dsl.FloconMarker +import io.github.openflocon.flocon.error.pluginNotInitialized +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update + +class FloconDatabaseConfig : FloconPluginConfig + +interface FloconDatabasePlugin : FloconPlugin { + fun register(floconDatabaseModel: FloconDatabaseModel) + fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) +} + +internal interface FloconDatabaseDataSource { + fun executeSQL( + registeredDatabases: List, + databaseName: String, + query: String + ): DatabaseExecuteSqlResponse + + fun getAllDataBases( + registeredDatabases: List + ): List +} + +internal expect fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource + +object FloconDatabase : FloconPluginFactory { + override val name: String = "Database" + override val pluginId: String = Protocol.ToDevice.Database.Plugin + override fun createConfig() = FloconDatabaseConfig() + override fun install( + pluginConfig: FloconDatabaseConfig, + floconConfig: FloconConfig + ): FloconDatabasePlugin { + return FloconDatabasePluginImpl( + sender = floconConfig.client as FloconMessageSender, + context = floconConfig.context + ).also { FloconDatabasePluginImpl.plugin = it } + } +} + +internal class FloconDatabasePluginImpl( + private var sender: FloconMessageSender, + private val context: FloconContext, +) : FloconPlugin, FloconDatabasePlugin { + override val key: String = "DATABASE" + + companion object { + var plugin: FloconDatabasePlugin? = null + } + + private val registeredDatabases = MutableStateFlow>(emptyList()) + + private val dataSource = buildFloconDatabaseDataSource(context) + + override suspend fun onMessageReceived( + method: String, + body: String, + ) { + when (method) { + Protocol.ToDevice.Database.Method.GetDatabases -> { + sendAllDatabases(sender) + } + + Protocol.ToDevice.Database.Method.Query -> { + val queryMessage = + DatabaseQueryMessage.fromJson(message = body) ?: return + val result = dataSource.executeSQL( + registeredDatabases = registeredDatabases.value, + databaseName = queryMessage.database, + query = queryMessage.query, + ) + try { +// sender.send( +// plugin = Protocol.FromDevice.Database.Plugin, +// method = Protocol.FromDevice.Database.Method.Query, +// body = QueryResultDataModel( +// requestId = queryMessage.requestId, +// result = result.toJson(), +// ).toJson(), +// ) + } catch (t: Throwable) { + FloconLogger.logError("Database parsing error", t) + } + } + } + } + + override suspend fun onConnectedToServer() { + sendAllDatabases(sender) + } + + private fun sendAllDatabases(sender: FloconMessageSender) { + val databases = dataSource.getAllDataBases( + registeredDatabases = registeredDatabases.value, + ) + try { +// sender.send( +// plugin = Protocol.FromDevice.Database.Plugin, +// method = Protocol.FromDevice.Database.Method.GetDatabases, +// body = listDeviceDataBaseDataModelToJson(databases), +// ) + } catch (t: Throwable) { + FloconLogger.logError("Database parsing error", t) + } + } + + override fun register(floconDatabaseModel: FloconDatabaseModel) { + registeredDatabases.update { it + floconDatabaseModel } + } + + override fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) { + try { +// sender.send( +// plugin = Protocol.FromDevice.Database.Plugin, +// method = Protocol.FromDevice.Database.Method.LogQuery, +// body = DatabaseQueryLogModel( +// dbName = dbName, +// sqlQuery = sqlQuery, +// bindArgs = bindArgs.map { it.toString() }, +// timestamp = currentTimeMillis(), +// ).toJson(), +// ) + } catch (t: Throwable) { + FloconLogger.logError("Database logging error", t) + } + } +} + +@OptIn(FloconMarker::class) +val Flocon.Companion.databasePlugin: FloconDatabasePlugin + get() = FloconDatabasePluginImpl.plugin ?: pluginNotInitialized("Database") diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt new file mode 100644 index 000000000..7b33e8822 --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt @@ -0,0 +1,16 @@ +package io.github.openflocon.flocon.database.core.model + +import androidx.sqlite.db.SupportSQLiteDatabase + +interface FloconDatabaseModel { + val displayName: String +} + +interface FloconAndroidSqlDatabaseModel : FloconDatabaseModel { + val database: SupportSQLiteDatabase +} + +data class FloconFileDatabaseModel( + override val displayName: String, + val absolutePath: String +) : FloconDatabaseModel diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt new file mode 100644 index 000000000..71a71e9d9 --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt @@ -0,0 +1,59 @@ +package io.github.openflocon.flocon.database.core.model.fromdevice + +import io.github.openflocon.flocon.core.FloconEncoder +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.encodeToJsonElement +import kotlinx.serialization.json.put + +@Serializable +sealed interface DatabaseExecuteSqlResponse { + + @Serializable + // Case for successful SELECT queries + class Select( + val columns: List, + val values: List> + ) : DatabaseExecuteSqlResponse + + // Case for successful INSERT queries + @Serializable + class Insert( + val insertedId: Long + ) : DatabaseExecuteSqlResponse + + // Case for successful UPDATE or DELETE queries + @Serializable + class UpdateDelete( + val affectedCount: Int + ) : DatabaseExecuteSqlResponse + + // Case for successful "raw" queries (CREATE TABLE, DROP TABLE, etc.) + @Serializable + object RawSuccess : DatabaseExecuteSqlResponse + + // Case for an SQL execution error + @Serializable + class Error( + val message: String, // Detailed error message + val originalSql: String, // SQL query that caused the error (optional) + ) : DatabaseExecuteSqlResponse +} + +fun DatabaseExecuteSqlResponse.toJson(): String { + val jsonEncoder = FloconEncoder.json + val thisAsJson = jsonEncoder.encodeToJsonElement(this) + + val type = when (this) { + is DatabaseExecuteSqlResponse.Error -> "Error" + is DatabaseExecuteSqlResponse.Insert -> "Insert" + DatabaseExecuteSqlResponse.RawSuccess -> "RawSuccess" + is DatabaseExecuteSqlResponse.Select -> "Select" + is DatabaseExecuteSqlResponse.UpdateDelete -> "UpdateDelete" + } + + return buildJsonObject { + put("type", type) + put("body", thisAsJson.toString()) // warning : the desktop is waiting for a string representation of the json here + }.toString() +} diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseQueryLogModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseQueryLogModel.kt new file mode 100644 index 000000000..74359152f --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseQueryLogModel.kt @@ -0,0 +1,23 @@ +package io.github.openflocon.flocon.database.core.model.fromdevice + +import io.github.openflocon.flocon.core.FloconEncoder +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString + +@Serializable +data class DatabaseQueryLogModel( + val dbName: String, + val sqlQuery: String, + val bindArgs: List?, + val timestamp: Long, +) { + fun toJson(): String { + return FloconEncoder.json.encodeToString(this) + } + + companion object { + fun fromJson(json: String): DatabaseQueryLogModel { + return FloconEncoder.json.decodeFromString(json) + } + } +} diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DeviceDataBaseDataModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DeviceDataBaseDataModel.kt new file mode 100644 index 000000000..42e00113b --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DeviceDataBaseDataModel.kt @@ -0,0 +1,15 @@ +package io.github.openflocon.flocon.database.core.model.fromdevice + +import io.github.openflocon.flocon.core.FloconEncoder +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString + +@Serializable +data class DeviceDataBaseDataModel( + val id: String, + val name: String, +) + +fun listDeviceDataBaseDataModelToJson(items: List) : String { + return FloconEncoder.json.encodeToString(items) +} diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/QueryResultReceivedDataModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/QueryResultReceivedDataModel.kt new file mode 100644 index 000000000..c4e51d071 --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/QueryResultReceivedDataModel.kt @@ -0,0 +1,15 @@ +package io.github.openflocon.flocon.database.core.model.fromdevice + +import io.github.openflocon.flocon.core.FloconEncoder +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString + +@Serializable +internal data class QueryResultDataModel( + val requestId: String, + val result: String, +) { + fun toJson(): String { + return FloconEncoder.json.encodeToString(this) + } +} diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/todevice/DatabaseQueryMessage.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/todevice/DatabaseQueryMessage.kt new file mode 100644 index 000000000..cd81313c8 --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/todevice/DatabaseQueryMessage.kt @@ -0,0 +1,23 @@ +package io.github.openflocon.flocon.database.core.model.todevice + +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.core.FloconEncoder +import kotlinx.serialization.Serializable + +@Serializable +data class DatabaseQueryMessage( + val query: String, + val requestId: String, + val database: String, +) { + companion object { + fun fromJson(message: String): DatabaseQueryMessage? { + return try { + FloconEncoder.json.decodeFromString(message) + } catch (t: Throwable) { + FloconLogger.logError("parsing issue", t) + null + } + } + } +} diff --git a/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt b/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt new file mode 100644 index 000000000..f0645b467 --- /dev/null +++ b/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt @@ -0,0 +1,127 @@ +package io.github.openflocon.flocon.database.core + +import androidx.sqlite.SQLiteConnection +import androidx.sqlite.driver.NativeSQLiteDriver +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.FloconFileDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.DeviceDataBaseDataModel +import platform.Foundation.NSFileManager + +internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { + return FloconDatabaseDataSourceIos(context) +} + +internal class FloconDatabaseDataSourceIos( + private val context: FloconContext +) : FloconDatabaseDataSource { + + override fun executeSQL( + registeredDatabases: List, + databaseName: String, + query: String + ): DatabaseExecuteSqlResponse { + val fileManager = NSFileManager.defaultManager + if (!fileManager.fileExistsAtPath(databaseName)) { + return DatabaseExecuteSqlResponse.Error( + message = "Database file not found: $databaseName", + originalSql = query + ) + } + + val driver = NativeSQLiteDriver() + val connection = driver.open(fileName = databaseName) + + return try { + val firstWord = getFirstWord(query).uppercase() + when (firstWord) { + "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(connection, query) + "INSERT" -> executeInsert(connection, query) + "UPDATE", "DELETE" -> executeUpdateDelete(connection, query) + else -> executeRawQuery(connection, query) + } + } catch (t: Throwable) { + DatabaseExecuteSqlResponse.Error( + message = t.message ?: "Error executing SQL", + originalSql = query + ) + } finally { + connection.close() + } + } + + override fun getAllDataBases( + registeredDatabases: List + ): List { + val fileManager = NSFileManager.defaultManager + return registeredDatabases.mapNotNull { + if(it is FloconFileDatabaseModel) { + if (fileManager.fileExistsAtPath(it.absolutePath)) { + DeviceDataBaseDataModel( + id = it.absolutePath, + name = it.displayName + ) + } else null + } else null + } + } +} + +// --- SQL execution helpers --- + +private fun executeSelect(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { + val cursor = connection.prepare(query).use { statement -> + val columnCount = statement.getColumnCount() + val columns = (0 until columnCount).map { statement.getColumnName(it) } + val rows = mutableListOf>() + + while (statement.step()) { + val row = (0 until columnCount).map { idx -> + statement.getText(idx) + } + rows.add(row) + } + + statement.close() // maybe remove + DatabaseExecuteSqlResponse.Select(columns, rows) + } + return cursor +} + +private fun executeUpdateDelete(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { + connection.prepare(query).use { statement -> + statement.close() + } + // sqlite-kt n'expose pas encore `changes()`, on renvoie 0 + return DatabaseExecuteSqlResponse.UpdateDelete(affectedCount = 0) +} + +private fun executeInsert(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { + connection.prepare(query).use { statement -> + statement.close() + } + + // Récupération du dernier ID inséré + var id = -1L + connection.prepare("SELECT last_insert_rowid()").use { +// id = if (it.step()) it.getLong(0) else -1L +// it.close() // maybe remove + } + + return DatabaseExecuteSqlResponse.Insert(id) +} + +private fun executeRawQuery(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { + connection.prepare(query).use { statement -> + statement.close() // maybe remove + } + return DatabaseExecuteSqlResponse.RawSuccess +} + +// --- Utilities --- +private fun getFirstWord(s: String): String { + val trimmed = s.trim() + val firstSpace = trimmed.indexOf(' ') + return if (firstSpace >= 0) trimmed.substring(0, firstSpace) else trimmed +} diff --git a/FloconAndroid/database/room-no-op/build.gradle.kts b/FloconAndroid/database/room-no-op/build.gradle.kts new file mode 100644 index 000000000..b5a556424 --- /dev/null +++ b/FloconAndroid/database/room-no-op/build.gradle.kts @@ -0,0 +1,82 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + id("com.vanniktech.maven.publish") version "0.34.0" +} + +android { + namespace = "io.github.openflocon.flocon.database.room.noop" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } +} + +dependencies { + implementation(project(":database:core-no-op")) +} + + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-database-room-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Room Implementation No-Op" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/database/room-no-op/src/main/java/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt b/FloconAndroid/database/room-no-op/src/main/java/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt new file mode 100644 index 000000000..1aefa1497 --- /dev/null +++ b/FloconAndroid/database/room-no-op/src/main/java/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.database.room + +fun floconRegisterDatabase(displayName: String, database: Any) { + // no op +} + +fun floconRegisterDatabase(displayName: String, openHelper: Any, dummy: Boolean = true) { + // no op +} diff --git a/FloconAndroid/database/room/build.gradle.kts b/FloconAndroid/database/room/build.gradle.kts new file mode 100644 index 000000000..b60b75333 --- /dev/null +++ b/FloconAndroid/database/room/build.gradle.kts @@ -0,0 +1,91 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + id("com.vanniktech.maven.publish") version "0.34.0" +} + +android { + namespace = "io.github.openflocon.flocon.database.room" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } +} + +dependencies { + + api(project(":database:core")) + + implementation(libs.androidx.room.runtime) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.jetbrains.kotlinx.coroutines.core) + implementation(libs.jetbrains.kotlinx.coroutines.android) + + testImplementation(libs.junit) +} + + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-database-room", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Room implementation" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt new file mode 100644 index 000000000..b826dda27 --- /dev/null +++ b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt @@ -0,0 +1,28 @@ +package io.github.openflocon.flocon.database.room + +import androidx.sqlite.db.SupportSQLiteDatabase +import androidx.sqlite.db.SupportSQLiteOpenHelper +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.database.core.databasePlugin +import io.github.openflocon.flocon.database.core.model.FloconAndroidSqlDatabaseModel + +data class FloconRoomDatabaseModel( + override val displayName: String, + val database: SupportSQLiteDatabase +) : FloconAndroidSqlDatabaseModel + +fun floconRegisterDatabase(displayName: String, database: SupportSQLiteDatabase) { + Flocon.databasePlugin.register( + FloconRoomDatabaseModel( + displayName = displayName, + database = database, + ) + ) +} + +fun floconRegisterDatabase(displayName: String, openHelper: SupportSQLiteOpenHelper) { + floconRegisterDatabase( + displayName = displayName, + database = openHelper.writableDatabase, + ) +} diff --git a/FloconAndroid/flocon/build.gradle.kts b/FloconAndroid/flocon/build.gradle.kts index 457438cef..3c5e9f5ad 100644 --- a/FloconAndroid/flocon/build.gradle.kts +++ b/FloconAndroid/flocon/build.gradle.kts @@ -38,9 +38,6 @@ kotlin { implementation(libs.kotlinx.coroutines.android) implementation(libs.jakewharton.process.phoenix) implementation("com.squareup.okhttp3:okhttp:4.12.0") - - implementation(libs.androidx.sqlite) - implementation(libs.androidx.sqlite.framework) } } @@ -71,8 +68,6 @@ kotlin { implementation(libs.ktor.client.logging) implementation(libs.ktor.serialization.kotlinx.json) - implementation(libs.androidx.sqlite.bundled) - // to store the device id implementation("com.russhwolf:multiplatform-settings:1.3.0") } diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.android.kt deleted file mode 100644 index 8a4ac38fb..000000000 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.android.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.github.openflocon.flocon.plugins.database - -import io.github.openflocon.flocon.FloconContext - -internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { - TODO("Not yet implemented") -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconSqliteDatabaseModel.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconSqliteDatabaseModel.kt deleted file mode 100644 index b5b0087b9..000000000 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconSqliteDatabaseModel.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.database - -import androidx.sqlite.db.SupportSQLiteDatabase -import androidx.sqlite.db.SupportSQLiteOpenHelper -import io.github.openflocon.flocon.pluginsold.database.model.FloconDatabaseModel - -internal class FloconSqliteDatabaseModel( - override val displayName: String, - val database: SupportSQLiteDatabase -) : FloconDatabaseModel - -fun floconRegisterDatabase(displayName: String, database: SupportSQLiteDatabase) { -// floconRegisterDatabase( -// FloconSqliteDatabaseModel( -// displayName = displayName, -// database = database, -// ) -// ) -} - - -fun floconRegisterDatabase(displayName: String, openHelper: SupportSQLiteOpenHelper) { - floconRegisterDatabase( - displayName = displayName, - database = openHelper.writableDatabase, - ) -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt index 0463c2d9f..1d9511610 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt @@ -1,135 +1 @@ -package io.github.openflocon.flocon.plugins.database - -import io.github.openflocon.flocon.FloconConfig -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginConfig -import io.github.openflocon.flocon.FloconPluginFactory -import io.github.openflocon.flocon.Protocol -import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseExecuteSqlResponse -import io.github.openflocon.flocon.plugins.database.model.fromdevice.DeviceDataBaseDataModel -import io.github.openflocon.flocon.plugins.database.model.todevice.DatabaseQueryMessage -import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel -import kotlinx.coroutines.flow.MutableStateFlow - -class FloconDatabaseConfig : FloconPluginConfig - -interface FloconDatabasePlugin : FloconPlugin { - fun register(floconDatabaseModel: FloconDatabaseModel) - fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) -} - -internal interface FloconDatabaseDataSource { - fun executeSQL( - registeredDatabases: List, - databaseName: String, - query: String - ): DatabaseExecuteSqlResponse - - fun getAllDataBases( - registeredDatabases: List - ): List -} - -internal expect fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource - -object FloconDatabase : FloconPluginFactory { - override val name: String = "Database" - override val pluginId: String = Protocol.ToDevice.Database.Plugin - override fun createConfig() = FloconDatabaseConfig() - override fun install( - pluginConfig: FloconDatabaseConfig, - floconConfig: FloconConfig - ): FloconDatabasePlugin { - return FloconDatabasePluginImpl( - sender = floconConfig.client as FloconMessageSender, - context = floconConfig.context - ) - } -} - -internal class FloconDatabasePluginImpl( - private var sender: FloconMessageSender, - private val context: FloconContext, -) : FloconPlugin, FloconDatabasePlugin { - override val key: String = "DATABASE" - - private val registeredDatabases = MutableStateFlow>(emptyList()) - - private val dataSource = buildFloconDatabaseDataSource(context) - - override suspend fun onMessageReceived( - method: String, - body: String, - ) { - when (method) { - Protocol.ToDevice.Database.Method.GetDatabases -> { - sendAllDatabases(sender) - } - - Protocol.ToDevice.Database.Method.Query -> { - val queryMessage = - DatabaseQueryMessage.fromJson(message = body) ?: return - val result = dataSource.executeSQL( - registeredDatabases = registeredDatabases.value, - databaseName = queryMessage.database, - query = queryMessage.query, - ) - try { -// sender.send( -// plugin = Protocol.FromDevice.Database.Plugin, -// method = Protocol.FromDevice.Database.Method.Query, -// body = QueryResultDataModel( -// requestId = queryMessage.requestId, -// result = result.toJson(), -// ).toJson(), -// ) - } catch (t: Throwable) { - FloconLogger.logError("Database parsing error", t) - } - } - } - } - - override suspend fun onConnectedToServer() { - sendAllDatabases(sender) - } - - private fun sendAllDatabases(sender: FloconMessageSender) { - val databases = dataSource.getAllDataBases( - registeredDatabases = registeredDatabases.value, - ) - try { -// sender.send( -// plugin = Protocol.FromDevice.Database.Plugin, -// method = Protocol.FromDevice.Database.Method.GetDatabases, -// body = listDeviceDataBaseDataModelToJson(databases), -// ) - } catch (t: Throwable) { - FloconLogger.logError("Database parsing error", t) - } - } - - override fun register(floconDatabaseModel: FloconDatabaseModel) { - TODO("Not yet implemented") - } - - override fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) { - try { -// sender.send( -// plugin = Protocol.FromDevice.Database.Plugin, -// method = Protocol.FromDevice.Database.Method.LogQuery, -// body = DatabaseQueryLogModel( -// dbName = dbName, -// sqlQuery = sqlQuery, -// bindArgs = bindArgs.map { it.toString() }, -// timestamp = currentTimeMillis(), -// ).toJson(), -// ) - } catch (t: Throwable) { - FloconLogger.logError("Database logging error", t) - } - } -} \ No newline at end of file +// DEPRECATED: Moved to :database:core \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt index 06d08c830..dc137eed6 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt @@ -1,10 +1 @@ -package io.github.openflocon.flocon.plugins.database.model - -interface FloconDatabaseModel { - val displayName: String -} - -data class FloconFileDatabaseModel( - override val displayName: String, - val absolutePath: String -) : FloconDatabaseModel +// DEPRECATED diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt index 147783416..1d9511610 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt @@ -1,38 +1 @@ -package io.github.openflocon.flocon.pluginsold.database - -import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.FloconConfig -import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginConfig -import io.github.openflocon.flocon.FloconPluginFactory -import io.github.openflocon.flocon.pluginsold.database.model.FloconDatabaseModel - -class FloconDatabaseConfig : FloconPluginConfig - -/** - * Flocon Database Plugin. - * Used to inspect Room or other SQL databases. - */ -object FloconDatabase : FloconPluginFactory { - override fun createConfig(): FloconDatabaseConfig { - TODO("Not yet implemented") - } - - override fun install( - pluginConfig: FloconDatabaseConfig, - floconConfig: FloconConfig - ): FloconDatabasePlugin { - TODO("Not yet implemented") - } - - override val name: String - get() = TODO("Not yet implemented") - override val pluginId: String - get() = TODO("Not yet implemented") -} - - -interface FloconDatabasePlugin : FloconPlugin { - fun register(floconDatabaseModel: FloconDatabaseModel) - fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) -} \ No newline at end of file +// DEPRECATED: Moved to :database:core \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt index 4298eb2eb..0447420ba 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt @@ -1,10 +1 @@ -package io.github.openflocon.flocon.pluginsold.database.model - -interface FloconDatabaseModel { - val displayName: String -} - -data class FloconFileDatabaseModel( - override val displayName: String, - val absolutePath: String -) : FloconDatabaseModel \ No newline at end of file +// DEPRECATED \ No newline at end of file diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index aeee1139f..1a9e42680 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -33,3 +33,7 @@ include(":deeplinks") include(":deeplinks-no-op") include(":network:core") include(":network:core-no-op") +include(":database:core") +include(":database:core-no-op") +include(":database:room") +include(":database:room-no-op") From f56cb5ad5a9a2300904112c6e5515ce14fda9abf Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Fri, 13 Mar 2026 00:07:11 +0100 Subject: [PATCH 14/35] fix: Compile --- FloconAndroid/database/core/build.gradle.kts | 3 - .../core/FloconSqliteDatabaseModel.kt | 9 -- .../database/core/FloconDatabasePlugin.kt | 29 +++-- .../core/model/FloconDatabaseModel.kt | 6 +- .../database/core/FloconDatabasePlugin.jvm.kt | 7 ++ .../database/room-no-op/build.gradle.kts | 68 +++++++---- .../database/room/floconRegisterDatabase.kt | 9 ++ FloconAndroid/database/room/build.gradle.kts | 91 +++++++++------ .../database/room/FloconRoomDatabaseModel.kt | 110 ++++++++++++++++++ .../room}/FloconDatabasePlugin.android.kt | 99 +++++++--------- .../room/FloconSqliteDatabaseModel.kt | 8 ++ .../sample-android-only/build.gradle.kts | 7 ++ .../flocon/myapplication/MainActivity.kt | 14 ++- 13 files changed, 316 insertions(+), 144 deletions(-) delete mode 100644 FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconSqliteDatabaseModel.kt create mode 100644 FloconAndroid/database/core/src/jvmMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.jvm.kt create mode 100644 FloconAndroid/database/room-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt create mode 100644 FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt rename FloconAndroid/database/{core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core => room/src/main/java/io/github/openflocon/flocon/database/room}/FloconDatabasePlugin.android.kt (71%) create mode 100644 FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt diff --git a/FloconAndroid/database/core/build.gradle.kts b/FloconAndroid/database/core/build.gradle.kts index 295d31de3..1d07bb50d 100644 --- a/FloconAndroid/database/core/build.gradle.kts +++ b/FloconAndroid/database/core/build.gradle.kts @@ -32,8 +32,6 @@ kotlin { val androidMain by getting { dependencies { - implementation(libs.androidx.sqlite) - implementation(libs.androidx.sqlite.framework) } } @@ -51,7 +49,6 @@ kotlin { iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) dependencies { - implementation(libs.androidx.sqlite.bundled) } } } diff --git a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconSqliteDatabaseModel.kt b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconSqliteDatabaseModel.kt deleted file mode 100644 index a5001434c..000000000 --- a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconSqliteDatabaseModel.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.database.core - -import androidx.sqlite.db.SupportSQLiteDatabase -import io.github.openflocon.flocon.database.core.model.FloconAndroidSqlDatabaseModel - -internal class FloconSqliteDatabaseModel( - override val displayName: String, - val database: SupportSQLiteDatabase -) : FloconAndroidSqlDatabaseModel diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt index 296894eae..b773c74f7 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt @@ -1,5 +1,6 @@ package io.github.openflocon.flocon.database.core +import io.github.openflocon.flocon.Flocon import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger @@ -8,10 +9,10 @@ import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse import io.github.openflocon.flocon.database.core.model.fromdevice.DeviceDataBaseDataModel import io.github.openflocon.flocon.database.core.model.todevice.DatabaseQueryMessage -import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.error.pluginNotInitialized import kotlinx.coroutines.flow.MutableStateFlow @@ -36,8 +37,6 @@ internal interface FloconDatabaseDataSource { ): List } -internal expect fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource - object FloconDatabase : FloconPluginFactory { override val name: String = "Database" override val pluginId: String = Protocol.ToDevice.Database.Plugin @@ -65,7 +64,7 @@ internal class FloconDatabasePluginImpl( private val registeredDatabases = MutableStateFlow>(emptyList()) - private val dataSource = buildFloconDatabaseDataSource(context) + private val dataSource: Nothing = TODO() // buildFloconDatabaseDataSource(context) override suspend fun onMessageReceived( method: String, @@ -79,11 +78,17 @@ internal class FloconDatabasePluginImpl( Protocol.ToDevice.Database.Method.Query -> { val queryMessage = DatabaseQueryMessage.fromJson(message = body) ?: return - val result = dataSource.executeSQL( - registeredDatabases = registeredDatabases.value, - databaseName = queryMessage.database, - query = queryMessage.query, - ) + val databaseModel = + registeredDatabases.value.find { it.displayName == queryMessage.database } + if (databaseModel is io.github.openflocon.flocon.database.core.model.FloconSqlDatabaseModel) { + databaseModel.executeSQL(query = queryMessage.query) + } else { +// dataSource.executeSQL( +// registeredDatabases = registeredDatabases.value, +// databaseName = queryMessage.database, +// query = queryMessage.query, +// ) + } try { // sender.send( // plugin = Protocol.FromDevice.Database.Plugin, @@ -105,9 +110,9 @@ internal class FloconDatabasePluginImpl( } private fun sendAllDatabases(sender: FloconMessageSender) { - val databases = dataSource.getAllDataBases( - registeredDatabases = registeredDatabases.value, - ) +// dataSource.getAllDataBases( +// registeredDatabases = registeredDatabases.value, +// ) try { // sender.send( // plugin = Protocol.FromDevice.Database.Plugin, diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt index 7b33e8822..343c1cf38 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt @@ -1,13 +1,11 @@ package io.github.openflocon.flocon.database.core.model -import androidx.sqlite.db.SupportSQLiteDatabase - interface FloconDatabaseModel { val displayName: String } -interface FloconAndroidSqlDatabaseModel : FloconDatabaseModel { - val database: SupportSQLiteDatabase +interface FloconSqlDatabaseModel : FloconDatabaseModel { + suspend fun executeSQL(query: String): io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse } data class FloconFileDatabaseModel( diff --git a/FloconAndroid/database/core/src/jvmMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.jvm.kt b/FloconAndroid/database/core/src/jvmMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.jvm.kt new file mode 100644 index 000000000..e0c25951c --- /dev/null +++ b/FloconAndroid/database/core/src/jvmMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.jvm.kt @@ -0,0 +1,7 @@ +package io.github.openflocon.flocon.database.core + +import io.github.openflocon.flocon.FloconContext + +internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { + TODO("Not yet implemented") +} \ No newline at end of file diff --git a/FloconAndroid/database/room-no-op/build.gradle.kts b/FloconAndroid/database/room-no-op/build.gradle.kts index b5a556424..ffd49f7e0 100644 --- a/FloconAndroid/database/room-no-op/build.gradle.kts +++ b/FloconAndroid/database/room-no-op/build.gradle.kts @@ -1,7 +1,51 @@ plugins { + alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - id("com.vanniktech.maven.publish") version "0.34.0" + alias(libs.plugins.vanniktech.maven.publish) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":database:core-no-op")) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } } android { @@ -10,32 +54,12 @@ android { defaultConfig { minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } - kotlinOptions { - jvmTarget = "11" - } -} - -dependencies { - implementation(project(":database:core-no-op")) } diff --git a/FloconAndroid/database/room-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt b/FloconAndroid/database/room-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt new file mode 100644 index 000000000..1aefa1497 --- /dev/null +++ b/FloconAndroid/database/room-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.database.room + +fun floconRegisterDatabase(displayName: String, database: Any) { + // no op +} + +fun floconRegisterDatabase(displayName: String, openHelper: Any, dummy: Boolean = true) { + // no op +} diff --git a/FloconAndroid/database/room/build.gradle.kts b/FloconAndroid/database/room/build.gradle.kts index b60b75333..c828ca467 100644 --- a/FloconAndroid/database/room/build.gradle.kts +++ b/FloconAndroid/database/room/build.gradle.kts @@ -1,7 +1,55 @@ plugins { + alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - id("com.vanniktech.maven.publish") version "0.34.0" + alias(libs.plugins.vanniktech.maven.publish) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + api(project(":database:core")) + implementation(libs.androidx.room.runtime) + implementation(libs.androidx.sqlite) + } + } + + val androidMain by getting { + dependencies { + implementation(libs.jetbrains.kotlinx.coroutines.android) + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } } android { @@ -10,41 +58,12 @@ android { defaultConfig { minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } - kotlinOptions { - jvmTarget = "11" - } -} - -dependencies { - - api(project(":database:core")) - - implementation(libs.androidx.room.runtime) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.jetbrains.kotlinx.coroutines.core) - implementation(libs.jetbrains.kotlinx.coroutines.android) - - testImplementation(libs.junit) } @@ -76,10 +95,12 @@ mavenPublishing { } } developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } } } scm { diff --git a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt new file mode 100644 index 000000000..5f7906836 --- /dev/null +++ b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt @@ -0,0 +1,110 @@ +package io.github.openflocon.flocon.database.room + +import androidx.room.RoomDatabase +import androidx.room.Transactor +import androidx.room.exclusiveTransaction +import androidx.room.execSQL +import androidx.room.useReaderConnection +import androidx.sqlite.SQLiteConnection +import androidx.sqlite.execSQL +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.database.core.databasePlugin +import io.github.openflocon.flocon.database.core.model.FloconSqlDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse + +data class FloconRoomDatabaseModel( + override val displayName: String, + val database: RoomDatabase +) : FloconSqlDatabaseModel { + override suspend fun executeSQL(query: String): DatabaseExecuteSqlResponse { + return try { + database.useReaderConnection { connection -> +// val firstWordUpperCase = getFirstWord(query).uppercase() +// when (firstWordUpperCase) { +// "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(connection, query) +// "INSERT" -> executeInsert(connection, query) +// "UPDATE", "DELETE" -> executeUpdateDelete(connection, query) +// else -> executeRawQuery(connection, query) +// } + TODO() + } + } catch (t: Throwable) { + DatabaseExecuteSqlResponse.Error( + message = t.message ?: "error on executeSQL", + originalSql = query, + ) + } + } +} + +private fun executeSelect( + connection: Transactor, + query: String, +): DatabaseExecuteSqlResponse { + return TODO() +// connection.prepare(query).use { statement -> +// val columnNames = mutableListOf() +// val columnCount = statement.getColumnCount() +// for (i in 0 until columnCount) { +// columnNames.add(statement.getColumnName(i)) +// } +// +// val rows = mutableListOf>() +// while (statement.step()) { +// val values = mutableListOf() +// for (i in 0 until columnCount) { +// values.add(if (statement.isNull(i)) null else statement.getText(i)) +// } +// rows.add(values) +// } +// +// DatabaseExecuteSqlResponse.Select( +// columns = columnNames, +// values = rows, +// ) +// } +} + +private fun executeInsert( + connection: SQLiteConnection, + query: String, +): DatabaseExecuteSqlResponse { + connection.execSQL(query) + // SQLite doesn't easily return the last inserted ID via the statement itself without extra queries like last_insert_rowid() + // But for inspection purposes, we might just return 0 or query it. + // For now, let's just return a successful RawSuccess or implement last_insert_rowid + val id = connection.prepare("SELECT last_insert_rowid()").use { it.step(); it.getLong(0) } + return DatabaseExecuteSqlResponse.Insert(id) +} + +private fun executeUpdateDelete( + connection: SQLiteConnection, + query: String, +): DatabaseExecuteSqlResponse { + connection.execSQL(query) + val count = connection.prepare("SELECT changes()").use { it.step(); it.getLong(0).toInt() } + return DatabaseExecuteSqlResponse.UpdateDelete(count) +} + +private fun executeRawQuery( + connection: SQLiteConnection, + query: String, +): DatabaseExecuteSqlResponse { + connection.execSQL(query) + return DatabaseExecuteSqlResponse.RawSuccess +} + +private fun getFirstWord(s: String): String { + val trimmed = s.trim() + val firstSpace = trimmed.indexOf(' ') + return if (firstSpace >= 0) trimmed.substring(0, firstSpace) else trimmed +} + +fun floconRegisterDatabase(displayName: String, database: RoomDatabase) { + Flocon.databasePlugin.register( + FloconRoomDatabaseModel( + displayName = displayName, + database = database, + ) + ) +} diff --git a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.android.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt similarity index 71% rename from FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.android.kt rename to FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt index a35064604..d2a8ee323 100644 --- a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.android.kt +++ b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt @@ -1,21 +1,23 @@ -package io.github.openflocon.flocon.database.core +package io.github.openflocon.flocon.database.room import android.content.Context import android.database.Cursor import android.database.sqlite.SQLiteDatabase -import androidx.sqlite.db.SupportSQLiteDatabase -import androidx.sqlite.db.SupportSQLiteOpenHelper -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.database.core.model.FloconAndroidSqlDatabaseModel +import io.github.openflocon.flocon.database.core.FloconDatabaseDataSource import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.FloconSqlDatabaseModel import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse import io.github.openflocon.flocon.database.core.model.fromdevice.DeviceDataBaseDataModel import java.io.File import java.util.Locale -internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { - return FloconDatabaseDataSourceAndroid(context.context) +interface FloconAndroidSqlDatabaseModel : FloconSqlDatabaseModel { + val database: SQLiteDatabase + + override suspend fun executeSQL(query: String): DatabaseExecuteSqlResponse { + return executeSQLInternal(database, query) + } } internal class FloconDatabaseDataSourceAndroid(private val context: Context) : @@ -31,7 +33,7 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : val databaseModel = registeredDatabases.find { it.displayName == databaseName } return when (databaseModel) { is FloconAndroidSqlDatabaseModel -> { - executeSQL( + executeSQLInternal( database = databaseModel.database, query = query, ) @@ -48,31 +50,16 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : databaseName: String, query: String ): DatabaseExecuteSqlResponse { - var helper: SupportSQLiteOpenHelper? = null + var database: SQLiteDatabase? = null return try { val path = context.getDatabasePath(databaseName) - val version = getDatabaseVersion(path = path.absolutePath) - helper = FrameworkSQLiteOpenHelperFactory().create( - SupportSQLiteOpenHelper.Configuration.builder(context) - .name(path.absolutePath) - .callback(object : SupportSQLiteOpenHelper.Callback(version) { - override fun onCreate(db: SupportSQLiteDatabase) { - // no op - } - - override fun onUpgrade( - db: SupportSQLiteDatabase, - oldVersion: Int, - newVersion: Int - ) { - // no op - } - }) - .build() + database = SQLiteDatabase.openDatabase( + path.absolutePath, + null, + SQLiteDatabase.OPEN_READWRITE ) - val database = helper.writableDatabase - executeSQL( + executeSQLInternal( database = database, query = query, ) @@ -82,27 +69,7 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : originalSql = query, ) } finally { - helper?.close() - } - } - - private fun executeSQL( - database: SupportSQLiteDatabase, - query: String - ): DatabaseExecuteSqlResponse { - return try { - val firstWordUpperCase = getFirstWord(query).uppercase(Locale.getDefault()) - when (firstWordUpperCase) { - "UPDATE", "DELETE" -> executeUpdateDelete(database, query) - "INSERT" -> executeInsert(database, query) - "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(database, query) - else -> executeRawQuery(database, query) - } - } catch (t: Throwable) { - DatabaseExecuteSqlResponse.Error( - message = t.message ?: "error on executeSQL", - originalSql = query, - ) + database?.close() } } @@ -126,7 +93,7 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : foundDatabases: MutableList ) { if (depth >= MAX_DEPTH) { - return; + return } directory.listFiles()?.forEach { file -> if (file.isDirectory) { @@ -155,11 +122,31 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : } } +private fun executeSQLInternal( + database: SQLiteDatabase, + query: String +): DatabaseExecuteSqlResponse { + return try { + val firstWordUpperCase = getFirstWord(query).uppercase(Locale.getDefault()) + when (firstWordUpperCase) { + "UPDATE", "DELETE" -> executeUpdateDelete(database, query) + "INSERT" -> executeInsert(database, query) + "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(database, query) + else -> executeRawQuery(database, query) + } + } catch (t: Throwable) { + DatabaseExecuteSqlResponse.Error( + message = t.message ?: "error on executeSQL", + originalSql = query, + ) + } +} + private fun executeSelect( - database: SupportSQLiteDatabase, + database: SQLiteDatabase, query: String, ): DatabaseExecuteSqlResponse { - val cursor: Cursor = database.query(query) + val cursor: Cursor = database.rawQuery(query, null) try { val columnNames = cursor.columnNames.toList() val rows = cursorToList(cursor) @@ -173,7 +160,7 @@ private fun executeSelect( } private fun executeUpdateDelete( - database: SupportSQLiteDatabase, + database: SQLiteDatabase, query: String, ): DatabaseExecuteSqlResponse { val statement = database.compileStatement(query) @@ -182,7 +169,7 @@ private fun executeUpdateDelete( } private fun executeInsert( - database: SupportSQLiteDatabase, + database: SQLiteDatabase, query: String, ): DatabaseExecuteSqlResponse { val statement = database.compileStatement(query) @@ -191,7 +178,7 @@ private fun executeInsert( } private fun executeRawQuery( - database: SupportSQLiteDatabase, + database: SQLiteDatabase, query: String, ): DatabaseExecuteSqlResponse { database.execSQL(query) diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt new file mode 100644 index 000000000..d9c57cda1 --- /dev/null +++ b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt @@ -0,0 +1,8 @@ +package io.github.openflocon.flocon.database.room + +import androidx.sqlite.db.SupportSQLiteDatabase + +internal class FloconSqliteDatabaseModel( + override val displayName: String, + override val database: SupportSQLiteDatabase +) : FloconAndroidSqlDatabaseModel diff --git a/FloconAndroid/sample-android-only/build.gradle.kts b/FloconAndroid/sample-android-only/build.gradle.kts index 64ecd4299..e136cdea7 100644 --- a/FloconAndroid/sample-android-only/build.gradle.kts +++ b/FloconAndroid/sample-android-only/build.gradle.kts @@ -7,6 +7,7 @@ plugins { alias(libs.plugins.kotlin.compose) alias(libs.plugins.ksp) alias(libs.plugins.apollo) + id("com.google.protobuf") } @@ -87,11 +88,17 @@ dependencies { debugImplementation(project(":deeplinks")) releaseImplementation(project(":deeplinks-no-op")) + debugImplementation(project(":database:room")) + releaseImplementation(project(":database:room-no-op")) + debugImplementation(project(":network:okhttp-interceptor")) releaseImplementation(project(":network:okhttp-interceptor-no-op")) + implementation(project(":grpc:grpc-interceptor-lite")) + debugImplementation(project(":network:ktor-interceptor")) releaseImplementation(project(":network:ktor-interceptor-no-op")) + debugImplementation(project(":datastores")) releaseImplementation(project(":datastores-no-op")) } diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt index 99ef90936..1f8a0a878 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt @@ -21,6 +21,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.FloconDatabase +import io.github.openflocon.flocon.database.room.floconRegisterDatabase import io.github.openflocon.flocon.myapplication.database.DogDatabase import io.github.openflocon.flocon.myapplication.database.initializeInMemoryDatabases import io.github.openflocon.flocon.myapplication.database.model.DogEntity @@ -232,10 +234,16 @@ class MainActivity : ComponentActivity() { ) } - install(FloconNetwork) { - - } + install(FloconNetwork) + install(FloconDatabase) } } + private fun toMigrate() { + floconRegisterDatabase( + displayName = "inmemory_dogs", + openHelper = it.openHelper + ) + } + } \ No newline at end of file From 43f1969db74a3d0476aaeb84e448b031a69098d8 Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Fri, 13 Mar 2026 14:33:28 +0100 Subject: [PATCH 15/35] feat: Database compile --- .../core/FloconDatabasePluginImpl.android.kt | 281 ++++++++++++++++++ .../flocon/database/core/FloconDatabase.kt | 31 ++ .../database/core/FloconDatabaseConfig.kt | 12 + .../database/core/FloconDatabaseEncoding.kt | 27 ++ .../database/core/FloconDatabasePlugin.kt | 140 +-------- .../database/core/FloconDatabasePluginImpl.kt | 111 +++++++ .../datasource/FloconDatabaseDataSource.kt | 20 ++ .../core/datasource/FloconDatabaseProvider.kt | 14 + .../core/model/FloconDatabaseModel.kt | 13 +- .../fromdevice/DatabaseExecuteResponse.kt | 11 + .../fromdevice/DatabaseExecuteSqlResponse.kt | 17 +- .../{ => sql}/DatabaseQueryLogModel.kt | 3 +- .../{ => sql}/DeviceDataBaseDataModel.kt | 2 +- .../{ => sql}/QueryResultReceivedDataModel.kt | 5 +- .../database/core/FloconDatabasePlugin.ios.kt | 2 +- .../database/room/FloconRoomDatabaseConfig.kt | 24 ++ .../database/room/FloconRoomDatabaseModel.kt | 106 ++++--- .../room/FloconRoomDatabaseProviderImpl.kt | 38 +++ .../room/FloconDatabasePlugin.android.kt | 16 +- .../room/FloconRoomDatabaseModel.android.kt | 25 ++ .../database/room/FloconRoomDatabaseModel.kt | 28 -- .../room/FloconSqliteDatabaseModel.kt | 3 +- .../openflocon/flocon/FloconConfiguration.kt | 18 -- .../openflocon/flocon/FloconEncoding.kt | 18 ++ .../github/openflocon/flocon/FloconPlugin.kt | 3 + .../flocon/myapplication/MainActivity.kt | 16 +- 26 files changed, 731 insertions(+), 253 deletions(-) create mode 100644 FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.android.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabaseConfig.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabaseEncoding.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseProvider.kt create mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteResponse.kt rename FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/{ => sql}/DatabaseQueryLogModel.kt (92%) rename FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/{ => sql}/DeviceDataBaseDataModel.kt (98%) rename FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/{ => sql}/QueryResultReceivedDataModel.kt (74%) create mode 100644 FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseConfig.kt create mode 100644 FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt create mode 100644 FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.android.kt delete mode 100644 FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconEncoding.kt diff --git a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.android.kt b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.android.kt new file mode 100644 index 000000000..f467855ea --- /dev/null +++ b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.android.kt @@ -0,0 +1,281 @@ +package io.github.openflocon.flocon.database.core + +import android.content.Context +import android.database.Cursor +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseDataSource +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.FloconFileDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel +import java.io.File + +internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { + return FloconDatabaseDataSourceAndroid(context.context) +} + +internal class FloconDatabaseDataSourceAndroid( + private val context: Context +) : FloconDatabaseDataSource { + + override suspend fun executeQuery( + registeredDatabases: List, + databaseName: String, + query: String + ): DatabaseExecuteResponse? { + val databaseModel = registeredDatabases.find { it.displayName == databaseName } + + return databaseModel?.executeQuery( + query = query + ) +// return when(databaseModel) { +// is FloconSqliteDatabaseModel -> { +// executeQuery( +// database = databaseModel.database, +// query = query, +// ) +// } +// else -> openDbAndExecuteQuery( +// databaseName = databaseName, +// query = query, +// ) +// } + } + +// private fun openDbAndExecuteQuery( +// databaseName: String, +// query: String +// ): DatabaseExecuteSqlResponse { +// var helper: SupportSQLiteOpenHelper? = null +// return try { +// val path = context.getDatabasePath(databaseName) +// val version = getDatabaseVersion(path = path.absolutePath) +// helper = FrameworkSQLiteOpenHelperFactory().create( +// SupportSQLiteOpenHelper.Configuration.builder(context) +// .name(path.absolutePath) +// .callback(object : SupportSQLiteOpenHelper.Callback(version) { +// override fun onCreate(db: SupportSQLiteDatabase) { +// // no op +// } +// +// override fun onUpgrade( +// db: SupportSQLiteDatabase, +// oldVersion: Int, +// newVersion: Int +// ) { +// // no op +// } +// }) +// .build() +// ) +// val database = helper.writableDatabase +// +// executeSQL( +// database = database, +// query = query, +// ) +// } catch (t: Throwable) { +// DatabaseExecuteSqlResponse.Error( +// message = t.message ?: "error on executeSQL", +// originalSql = query, +// ) +// } finally { +// helper?.close() +// } +// } + +// private fun executeSQL( +// database: SupportSQLiteDatabase, +// query: String +// ): DatabaseExecuteSqlResponse { +// return try { +// val firstWordUpperCase = getFirstWord(query).uppercase(Locale.getDefault()) +// when (firstWordUpperCase) { +// "UPDATE", "DELETE" -> executeUpdateDelete(database, query) +// "INSERT" -> executeInsert(database, query) +// "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(database, query) +// else -> executeRawQuery(database, query) +// } +// } catch (t: Throwable) { +// DatabaseExecuteSqlResponse.Error( +// message = t.message ?: "error on executeSQL", +// originalSql = query, +// ) +// } +// } + + override fun getAllDataBases( + registeredDatabases: List + ): List { + val databasesDir = context.getDatabasePath("dummy_db").parentFile ?: return emptyList() + + val foundDatabases = mutableListOf() + // Start the recursive search from the base databases directory + scanDirectoryForDatabases( + directory = databasesDir, + depth = 0, + foundDatabases = foundDatabases + ) + + registeredDatabases.forEach { + when (it) { + is FloconFileDatabaseModel -> { + // check if file exists here + if (File(it.absolutePath).exists()) { + foundDatabases.add( + DeviceDataBaseDataModel( + id = it.absolutePath, + name = it.displayName, + ) + ) + } + } + + else -> { + foundDatabases.add( + DeviceDataBaseDataModel( + id = it.displayName, + name = it.displayName, + ) + ) + } + } + } + + return foundDatabases + } + + /** + * Recursively scans a directory for SQLite database files. + * + * @param directory The current directory to scan. + * @param foundDatabases The mutable list to add found databases to. + */ + private fun scanDirectoryForDatabases( + directory: File, + depth: Int, + foundDatabases: MutableList + ) { + if (depth >= MAX_DEPTH) { + return + } + directory.listFiles()?.forEach { file -> + if (file.isDirectory) { + // If it's a directory, recursively call this function + scanDirectoryForDatabases( + directory = file, + depth = depth + 1, + foundDatabases = foundDatabases, + ) + } else { + // If it's a file, check if it's a database file + if (file.isFile && + !file.name.endsWith("-wal") && // Write-Ahead Log + !file.name.endsWith("-shm") && // Shared-Memory + !file.name.endsWith("-journal") // Older journaling mode + ) { + foundDatabases.add( + DeviceDataBaseDataModel( + id = file.absolutePath, // Use absolute path for unique ID + name = file.name, + ) + ) + } + } + } + } + + companion object { + private const val MAX_DEPTH = 7 + } +} + + +//private fun executeSelect( +// database: SupportSQLiteDatabase, +// query: String, +//): DatabaseExecuteSqlResponse { +// val cursor: Cursor = database.query(query) +// try { +// val columnNames = cursor.columnNames.toList() +// val rows = cursorToList(cursor) +// return DatabaseExecuteSqlResponse.Select( +// columns = columnNames, +// values = rows, +// ) +// } finally { +// cursor.close() +// } +//} + +//private fun executeUpdateDelete( +// database: SupportSQLiteDatabase, +// query: String, +//): DatabaseExecuteSqlResponse { +// val statement = database.compileStatement(query) +// val count: Int = statement.executeUpdateDelete() +// return DatabaseExecuteSqlResponse.UpdateDelete(count) +//} +// +//private fun executeInsert( +// database: SupportSQLiteDatabase, +// query: String, +//): DatabaseExecuteSqlResponse { +// val statement = database.compileStatement(query) +// val insertedId: Long = statement.executeInsert() +// return DatabaseExecuteSqlResponse.Insert(insertedId) +//} +// +//private fun executeRawQuery( +// database: SupportSQLiteDatabase, +// query: String, +//): DatabaseExecuteSqlResponse { +// database.execSQL(query) +// return DatabaseExecuteSqlResponse.RawSuccess +//} + +private fun getFirstWord(s: String): String { + var s = s + s = s.trim { it <= ' ' } + val firstSpace = s.indexOf(' ') + return if (firstSpace >= 0) s.substring(0, firstSpace) else s +} + +private fun cursorToList(cursor: Cursor): List> { + val rows = mutableListOf>() + val numColumns = cursor.columnCount + while (cursor.moveToNext()) { + val values = mutableListOf() + for (column in 0.. null + Cursor.FIELD_TYPE_INTEGER -> cursor.getLong(column).toString() + Cursor.FIELD_TYPE_FLOAT -> cursor.getDouble(column).toString() + Cursor.FIELD_TYPE_BLOB -> cursor.getBlob(column).toString() + Cursor.FIELD_TYPE_STRING -> cursor.getString(column).toString() + else -> cursor.getString(column) + } +} + +// must use the old way to get the version... +private fun getDatabaseVersion( + path: String, +): Int { + return android.database.sqlite.SQLiteDatabase.openDatabase( + path, + null, + android.database.sqlite.SQLiteDatabase.OPEN_READONLY + ).use { db -> + db.rawQuery("PRAGMA user_version", null).use { cursor -> + if (cursor.moveToFirst()) cursor.getInt(0) else 0 + } + } +} \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt new file mode 100644 index 000000000..219abe66d --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt @@ -0,0 +1,31 @@ +package io.github.openflocon.flocon.database.core + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconEncoding +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.dsl.FloconMarker + +object FloconDatabase : FloconPluginFactory { + override val name: String = "Database" + override val pluginId: String = Protocol.ToDevice.Database.Plugin + + @FloconMarker + override fun createEncoding(): FloconEncoding = FloconDatabaseEncoding() + + override fun createConfig() = FloconDatabaseConfig() + + @OptIn(FloconMarker::class) + override fun install( + pluginConfig: FloconDatabaseConfig, + floconConfig: FloconConfig + ): FloconDatabasePlugin { + return FloconDatabasePluginImpl( + sender = floconConfig.client as FloconMessageSender, + context = floconConfig.context, + providers = pluginConfig.providers + ).also { FloconDatabasePluginImpl.plugin = it } + } + +} diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabaseConfig.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabaseConfig.kt new file mode 100644 index 000000000..b3dbc5b75 --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabaseConfig.kt @@ -0,0 +1,12 @@ +package io.github.openflocon.flocon.database.core + +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseProvider +import io.github.openflocon.flocon.dsl.FloconMarker + +class FloconDatabaseConfig : FloconPluginConfig { + + @FloconMarker + val providers: MutableList = mutableListOf() + +} diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabaseEncoding.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabaseEncoding.kt new file mode 100644 index 000000000..2a1b5cf6b --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabaseEncoding.kt @@ -0,0 +1,27 @@ +package io.github.openflocon.flocon.database.core + +import io.github.openflocon.flocon.FloconEncoding +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse +import io.github.openflocon.flocon.dsl.FloconMarker +import kotlinx.serialization.modules.SerializersModule +import kotlinx.serialization.modules.polymorphic +import kotlinx.serialization.modules.subclass + +@FloconMarker +internal class FloconDatabaseEncoding : FloconEncoding { + override val serializersModule: SerializersModule + get() = SerializersModule { + polymorphic(DatabaseExecuteResponse::class) { + polymorphic(DatabaseExecuteSqlResponse::class) { + subclass(DatabaseExecuteSqlResponse.Insert::class) + subclass(DatabaseExecuteSqlResponse.UpdateDelete::class) + subclass(DatabaseExecuteSqlResponse.Select::class) + subclass(DatabaseExecuteSqlResponse.RawSuccess::class) + subclass(DatabaseExecuteSqlResponse.Error::class) + + defaultDeserializer { DatabaseExecuteSqlResponse.Error.serializer() } + } + } + } +} \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt index b773c74f7..704879c5b 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.kt @@ -1,151 +1,23 @@ package io.github.openflocon.flocon.database.core import io.github.openflocon.flocon.Flocon -import io.github.openflocon.flocon.FloconConfig -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginConfig -import io.github.openflocon.flocon.FloconPluginFactory -import io.github.openflocon.flocon.Protocol -import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseProvider import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel -import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse -import io.github.openflocon.flocon.database.core.model.fromdevice.DeviceDataBaseDataModel -import io.github.openflocon.flocon.database.core.model.todevice.DatabaseQueryMessage import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.error.pluginNotInitialized -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.update - -class FloconDatabaseConfig : FloconPluginConfig interface FloconDatabasePlugin : FloconPlugin { - fun register(floconDatabaseModel: FloconDatabaseModel) - fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) -} - -internal interface FloconDatabaseDataSource { - fun executeSQL( - registeredDatabases: List, - databaseName: String, - query: String - ): DatabaseExecuteSqlResponse - - fun getAllDataBases( - registeredDatabases: List - ): List -} - -object FloconDatabase : FloconPluginFactory { - override val name: String = "Database" - override val pluginId: String = Protocol.ToDevice.Database.Plugin - override fun createConfig() = FloconDatabaseConfig() - override fun install( - pluginConfig: FloconDatabaseConfig, - floconConfig: FloconConfig - ): FloconDatabasePlugin { - return FloconDatabasePluginImpl( - sender = floconConfig.client as FloconMessageSender, - context = floconConfig.context - ).also { FloconDatabasePluginImpl.plugin = it } - } -} -internal class FloconDatabasePluginImpl( - private var sender: FloconMessageSender, - private val context: FloconContext, -) : FloconPlugin, FloconDatabasePlugin { - override val key: String = "DATABASE" + @FloconMarker + val providers: List - companion object { - var plugin: FloconDatabasePlugin? = null - } - - private val registeredDatabases = MutableStateFlow>(emptyList()) - - private val dataSource: Nothing = TODO() // buildFloconDatabaseDataSource(context) - - override suspend fun onMessageReceived( - method: String, - body: String, - ) { - when (method) { - Protocol.ToDevice.Database.Method.GetDatabases -> { - sendAllDatabases(sender) - } - - Protocol.ToDevice.Database.Method.Query -> { - val queryMessage = - DatabaseQueryMessage.fromJson(message = body) ?: return - val databaseModel = - registeredDatabases.value.find { it.displayName == queryMessage.database } - if (databaseModel is io.github.openflocon.flocon.database.core.model.FloconSqlDatabaseModel) { - databaseModel.executeSQL(query = queryMessage.query) - } else { -// dataSource.executeSQL( -// registeredDatabases = registeredDatabases.value, -// databaseName = queryMessage.database, -// query = queryMessage.query, -// ) - } - try { -// sender.send( -// plugin = Protocol.FromDevice.Database.Plugin, -// method = Protocol.FromDevice.Database.Method.Query, -// body = QueryResultDataModel( -// requestId = queryMessage.requestId, -// result = result.toJson(), -// ).toJson(), -// ) - } catch (t: Throwable) { - FloconLogger.logError("Database parsing error", t) - } - } - } - } - - override suspend fun onConnectedToServer() { - sendAllDatabases(sender) - } - - private fun sendAllDatabases(sender: FloconMessageSender) { -// dataSource.getAllDataBases( -// registeredDatabases = registeredDatabases.value, -// ) - try { -// sender.send( -// plugin = Protocol.FromDevice.Database.Plugin, -// method = Protocol.FromDevice.Database.Method.GetDatabases, -// body = listDeviceDataBaseDataModelToJson(databases), -// ) - } catch (t: Throwable) { - FloconLogger.logError("Database parsing error", t) - } - } + fun register(floconDatabaseModel: FloconDatabaseModel) - override fun register(floconDatabaseModel: FloconDatabaseModel) { - registeredDatabases.update { it + floconDatabaseModel } - } + fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) - override fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) { - try { -// sender.send( -// plugin = Protocol.FromDevice.Database.Plugin, -// method = Protocol.FromDevice.Database.Method.LogQuery, -// body = DatabaseQueryLogModel( -// dbName = dbName, -// sqlQuery = sqlQuery, -// bindArgs = bindArgs.map { it.toString() }, -// timestamp = currentTimeMillis(), -// ).toJson(), -// ) - } catch (t: Throwable) { - FloconLogger.logError("Database logging error", t) - } - } } @OptIn(FloconMarker::class) val Flocon.Companion.databasePlugin: FloconDatabasePlugin - get() = FloconDatabasePluginImpl.plugin ?: pluginNotInitialized("Database") + get() = FloconDatabasePluginImpl.plugin ?: pluginNotInitialized("Database") \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.kt new file mode 100644 index 000000000..dc07b079b --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.kt @@ -0,0 +1,111 @@ +package io.github.openflocon.flocon.database.core + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseDataSource +import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseProvider +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.QueryResultDataModel +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.listDeviceDataBaseDataModelToJson +import io.github.openflocon.flocon.database.core.model.todevice.DatabaseQueryMessage +import io.github.openflocon.flocon.dsl.FloconMarker +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update + +internal expect fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource + +internal class FloconDatabasePluginImpl( + private var sender: FloconMessageSender, + private val context: FloconContext, + @FloconMarker + override val providers: List +) : FloconPlugin, FloconDatabasePlugin { + + override val key: String = "DATABASE" + + private val registeredDatabases = MutableStateFlow>(emptyList()) + + private val dataSource = buildFloconDatabaseDataSource(context) + + override suspend fun onMessageReceived( + method: String, + body: String + ) { + when (method) { + Protocol.ToDevice.Database.Method.GetDatabases -> sendAllDatabases(sender) + + Protocol.ToDevice.Database.Method.Query -> { + val queryMessage = DatabaseQueryMessage.fromJson(message = body) ?: return + val databaseModel = registeredDatabases.value + .find { it.displayName == queryMessage.database } + val result = databaseModel?.executeQuery(query = queryMessage.query) + ?: DatabaseExecuteSqlResponse.Error( + message = "Database not found", + originalSql = queryMessage.query, + ) + + try { + sender.send( + plugin = Protocol.FromDevice.Database.Plugin, + method = Protocol.FromDevice.Database.Method.Query, + body = QueryResultDataModel( + requestId = queryMessage.requestId, + result = result + ) + .toJson() + ) + } catch (t: Throwable) { + FloconLogger.logError("Database parsing error", t) + } + } + } + } + + override suspend fun onConnectedToServer() { + sendAllDatabases(sender) + } + + private suspend fun sendAllDatabases(sender: FloconMessageSender) { + val databases = dataSource.getAllDataBases( + registeredDatabases = registeredDatabases.value, + ) + try { + sender.send( + plugin = Protocol.FromDevice.Database.Plugin, + method = Protocol.FromDevice.Database.Method.GetDatabases, + body = listDeviceDataBaseDataModelToJson(databases), + ) + } catch (t: Throwable) { + FloconLogger.logError("Database parsing error", t) + } + } + + override fun register(floconDatabaseModel: FloconDatabaseModel) { + registeredDatabases.update { it + floconDatabaseModel } + } + + override fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) { + try { +// sender.send( +// plugin = Protocol.FromDevice.Database.Plugin, +// method = Protocol.FromDevice.Database.Method.LogQuery, +// body = DatabaseQueryLogModel( +// dbName = dbName, +// sqlQuery = sqlQuery, +// bindArgs = bindArgs.map { it.toString() }, +// timestamp = currentTimeMillis(), +// ).toJson(), +// ) + } catch (t: Throwable) { + FloconLogger.logError("Database logging error", t) + } + } + + companion object { + var plugin: FloconDatabasePlugin? = null + } +} \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt new file mode 100644 index 000000000..8415d9e79 --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt @@ -0,0 +1,20 @@ +package io.github.openflocon.flocon.database.core.datasource + +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel + +interface FloconDatabaseDataSource { + + suspend fun executeQuery( + registeredDatabases: List, + databaseName: String, + query: String + ): DatabaseExecuteResponse? + + fun getAllDataBases( + registeredDatabases: List + ): List + +} \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseProvider.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseProvider.kt new file mode 100644 index 000000000..b54fb9d56 --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseProvider.kt @@ -0,0 +1,14 @@ +package io.github.openflocon.flocon.database.core.datasource + +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel +import io.github.openflocon.flocon.dsl.FloconMarker + +interface FloconDatabaseProvider { + + @FloconMarker + fun getAllDataBases( + registeredDatabases: List + ): List + +} \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt index 343c1cf38..8b7899c70 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt @@ -1,14 +1,19 @@ package io.github.openflocon.flocon.database.core.model +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse + interface FloconDatabaseModel { val displayName: String -} -interface FloconSqlDatabaseModel : FloconDatabaseModel { - suspend fun executeSQL(query: String): io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse + suspend fun executeQuery(query: String): DatabaseExecuteResponse + } data class FloconFileDatabaseModel( override val displayName: String, val absolutePath: String -) : FloconDatabaseModel +) : FloconDatabaseModel { + override suspend fun executeQuery(query: String): DatabaseExecuteResponse { + TODO("Not yet implemented") + } +} diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteResponse.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteResponse.kt new file mode 100644 index 000000000..03ffb0d12 --- /dev/null +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteResponse.kt @@ -0,0 +1,11 @@ +@file:OptIn(ExperimentalSerializationApi::class) + +package io.github.openflocon.flocon.database.core.model.fromdevice + +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonClassDiscriminator + +@Serializable +@JsonClassDiscriminator("type") +sealed interface DatabaseExecuteResponse \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt index 71a71e9d9..9539a01a0 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt @@ -1,15 +1,17 @@ package io.github.openflocon.flocon.database.core.model.fromdevice import io.github.openflocon.flocon.core.FloconEncoder +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.encodeToJsonElement import kotlinx.serialization.json.put @Serializable -sealed interface DatabaseExecuteSqlResponse { +sealed interface DatabaseExecuteSqlResponse : DatabaseExecuteResponse { @Serializable + @SerialName("SELECT") // Case for successful SELECT queries class Select( val columns: List, @@ -18,25 +20,29 @@ sealed interface DatabaseExecuteSqlResponse { // Case for successful INSERT queries @Serializable + @SerialName("INSERT") class Insert( val insertedId: Long ) : DatabaseExecuteSqlResponse // Case for successful UPDATE or DELETE queries @Serializable + @SerialName("UPDATE_DELETE") class UpdateDelete( val affectedCount: Int ) : DatabaseExecuteSqlResponse // Case for successful "raw" queries (CREATE TABLE, DROP TABLE, etc.) @Serializable + @SerialName("RAW_SUCCESS") object RawSuccess : DatabaseExecuteSqlResponse // Case for an SQL execution error @Serializable + @SerialName("ERROR") class Error( - val message: String, // Detailed error message - val originalSql: String, // SQL query that caused the error (optional) + val message: String = "", // Detailed error message + val originalSql: String = "", // SQL query that caused the error (optional) ) : DatabaseExecuteSqlResponse } @@ -54,6 +60,9 @@ fun DatabaseExecuteSqlResponse.toJson(): String { return buildJsonObject { put("type", type) - put("body", thisAsJson.toString()) // warning : the desktop is waiting for a string representation of the json here + put( + "body", + thisAsJson.toString() + ) // warning : the desktop is waiting for a string representation of the json here }.toString() } diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseQueryLogModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DatabaseQueryLogModel.kt similarity index 92% rename from FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseQueryLogModel.kt rename to FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DatabaseQueryLogModel.kt index 74359152f..dbb7a4507 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseQueryLogModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DatabaseQueryLogModel.kt @@ -1,7 +1,8 @@ -package io.github.openflocon.flocon.database.core.model.fromdevice +package io.github.openflocon.flocon.database.core.model.fromdevice.sql import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString @Serializable diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DeviceDataBaseDataModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt similarity index 98% rename from FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DeviceDataBaseDataModel.kt rename to FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt index 42e00113b..337bb00f4 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DeviceDataBaseDataModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.database.core.model.fromdevice +package io.github.openflocon.flocon.database.core.model.fromdevice.sql import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/QueryResultReceivedDataModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt similarity index 74% rename from FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/QueryResultReceivedDataModel.kt rename to FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt index c4e51d071..1d1da7d6c 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/QueryResultReceivedDataModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt @@ -1,13 +1,14 @@ -package io.github.openflocon.flocon.database.core.model.fromdevice +package io.github.openflocon.flocon.database.core.model.fromdevice.sql import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString @Serializable internal data class QueryResultDataModel( val requestId: String, - val result: String, + val result: DatabaseExecuteResponse, ) { fun toJson(): String { return FloconEncoder.json.encodeToString(this) diff --git a/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt b/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt index f0645b467..b6b4286b7 100644 --- a/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt +++ b/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt @@ -6,7 +6,7 @@ import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel import io.github.openflocon.flocon.database.core.model.FloconFileDatabaseModel import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse -import io.github.openflocon.flocon.database.core.model.fromdevice.DeviceDataBaseDataModel +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel import platform.Foundation.NSFileManager internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { diff --git a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseConfig.kt b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseConfig.kt new file mode 100644 index 000000000..40d7007f1 --- /dev/null +++ b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseConfig.kt @@ -0,0 +1,24 @@ +package io.github.openflocon.flocon.database.room + +import io.github.openflocon.flocon.database.core.FloconDatabaseConfig +import io.github.openflocon.flocon.dsl.FloconMarker + +class FloconRoomDatabaseConfig internal constructor() { + internal val paths: MutableList = mutableListOf() + + fun path(path: String) { + paths.add(path) + } + +} + +@OptIn(FloconMarker::class) +fun FloconDatabaseConfig.room(block: FloconRoomDatabaseConfig.() -> Unit = {}) { + val config = FloconRoomDatabaseConfig().apply(block) + + providers.add( + FloconRoomDatabaseProviderImpl( + paths = config.paths + ) + ) +} \ No newline at end of file diff --git a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt index 5f7906836..c97d82cd8 100644 --- a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt +++ b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt @@ -2,31 +2,48 @@ package io.github.openflocon.flocon.database.room import androidx.room.RoomDatabase import androidx.room.Transactor -import androidx.room.exclusiveTransaction import androidx.room.execSQL import androidx.room.useReaderConnection -import androidx.sqlite.SQLiteConnection -import androidx.sqlite.execSQL import io.github.openflocon.flocon.Flocon import io.github.openflocon.flocon.database.core.databasePlugin -import io.github.openflocon.flocon.database.core.model.FloconSqlDatabaseModel +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse data class FloconRoomDatabaseModel( override val displayName: String, val database: RoomDatabase -) : FloconSqlDatabaseModel { - override suspend fun executeSQL(query: String): DatabaseExecuteSqlResponse { +) : FloconDatabaseModel { + + override suspend fun executeQuery(query: String): DatabaseExecuteResponse { return try { database.useReaderConnection { connection -> -// val firstWordUpperCase = getFirstWord(query).uppercase() -// when (firstWordUpperCase) { -// "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(connection, query) -// "INSERT" -> executeInsert(connection, query) -// "UPDATE", "DELETE" -> executeUpdateDelete(connection, query) -// else -> executeRawQuery(connection, query) -// } - TODO() + val firstWordUpperCase = getFirstWord(query).uppercase() + + when (firstWordUpperCase) { + "SELECT", + "PRAGMA", + "EXPLAIN" -> executeSelect( + connection = connection, + query = query + ) + + "INSERT" -> executeInsert( + connection = connection, + query = query + ) + + "UPDATE", + "DELETE" -> executeUpdateDelete( + connection = connection, + query = query + ) + + else -> executeRawQuery( + connection = connection, + query = query + ) + } } } catch (t: Throwable) { DatabaseExecuteSqlResponse.Error( @@ -37,57 +54,56 @@ data class FloconRoomDatabaseModel( } } -private fun executeSelect( +private suspend fun executeSelect( connection: Transactor, query: String, ): DatabaseExecuteSqlResponse { - return TODO() -// connection.prepare(query).use { statement -> -// val columnNames = mutableListOf() -// val columnCount = statement.getColumnCount() -// for (i in 0 until columnCount) { -// columnNames.add(statement.getColumnName(i)) -// } -// -// val rows = mutableListOf>() -// while (statement.step()) { -// val values = mutableListOf() -// for (i in 0 until columnCount) { -// values.add(if (statement.isNull(i)) null else statement.getText(i)) -// } -// rows.add(values) -// } -// -// DatabaseExecuteSqlResponse.Select( -// columns = columnNames, -// values = rows, -// ) -// } + return connection.usePrepared(query) { statement -> + val columnNames = mutableListOf() + val columnCount = statement.getColumnCount() + for (i in 0 until columnCount) { + columnNames.add(statement.getColumnName(i)) + } + + val rows = mutableListOf>() + while (statement.step()) { + val values = mutableListOf() + for (i in 0 until columnCount) { + values.add(if (statement.isNull(i)) null else statement.getText(i)) + } + rows.add(values) + } + + DatabaseExecuteSqlResponse.Select( + columns = columnNames, + values = rows + ) + } } -private fun executeInsert( - connection: SQLiteConnection, +private suspend fun executeInsert( + connection: Transactor, query: String, ): DatabaseExecuteSqlResponse { connection.execSQL(query) // SQLite doesn't easily return the last inserted ID via the statement itself without extra queries like last_insert_rowid() // But for inspection purposes, we might just return 0 or query it. // For now, let's just return a successful RawSuccess or implement last_insert_rowid - val id = connection.prepare("SELECT last_insert_rowid()").use { it.step(); it.getLong(0) } + val id = connection.usePrepared("SELECT last_insert_rowid()") { it.step(); it.getLong(0) } return DatabaseExecuteSqlResponse.Insert(id) } -private fun executeUpdateDelete( - connection: SQLiteConnection, +private suspend fun executeUpdateDelete( + connection: Transactor, query: String, ): DatabaseExecuteSqlResponse { connection.execSQL(query) - val count = connection.prepare("SELECT changes()").use { it.step(); it.getLong(0).toInt() } + val count = connection.usePrepared("SELECT changes()") { it.step(); it.getLong(0).toInt() } return DatabaseExecuteSqlResponse.UpdateDelete(count) } -private fun executeRawQuery( - connection: SQLiteConnection, +private suspend fun executeRawQuery( + connection: Transactor, query: String, ): DatabaseExecuteSqlResponse { connection.execSQL(query) diff --git a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt new file mode 100644 index 000000000..db6fc35b3 --- /dev/null +++ b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt @@ -0,0 +1,38 @@ +package io.github.openflocon.flocon.database.room + +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.database.core.databasePlugin +import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseProvider +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel +import io.github.openflocon.flocon.dsl.FloconMarker + +interface FloconRoomDatabaseProvider : FloconDatabaseProvider { + + // TODO + fun register() + +} + +@OptIn(FloconMarker::class) +internal class FloconRoomDatabaseProviderImpl( + paths: List +) : FloconRoomDatabaseProvider { + + override fun getAllDataBases( + registeredDatabases: List + ): List { + TODO("Not yet implemented") + } + + override fun register() { + TODO("Not yet implemented") + } + +} + +@OptIn(FloconMarker::class) +val Flocon.Companion.databaseRoom: FloconRoomDatabaseProvider + get() = databasePlugin.providers + .firstNotNullOfOrNull { it as? FloconRoomDatabaseProvider } + ?: error("Room database provider not initialized") \ No newline at end of file diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt index d2a8ee323..fce42a575 100644 --- a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt +++ b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt @@ -3,19 +3,19 @@ package io.github.openflocon.flocon.database.room import android.content.Context import android.database.Cursor import android.database.sqlite.SQLiteDatabase -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.database.core.FloconDatabaseDataSource +import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseDataSource import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel -import io.github.openflocon.flocon.database.core.model.FloconSqlDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse -import io.github.openflocon.flocon.database.core.model.fromdevice.DeviceDataBaseDataModel +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel import java.io.File import java.util.Locale -interface FloconAndroidSqlDatabaseModel : FloconSqlDatabaseModel { +interface FloconAndroidSqlDatabaseModel : FloconDatabaseModel { val database: SQLiteDatabase - override suspend fun executeSQL(query: String): DatabaseExecuteSqlResponse { + + override suspend fun executeQuery(query: String): DatabaseExecuteResponse { return executeSQLInternal(database, query) } } @@ -25,11 +25,11 @@ internal class FloconDatabaseDataSourceAndroid(private val context: Context) : private val MAX_DEPTH = 7 - override fun executeSQL( + override suspend fun executeQuery( registeredDatabases: List, databaseName: String, query: String - ): DatabaseExecuteSqlResponse { + ): DatabaseExecuteResponse? { val databaseModel = registeredDatabases.find { it.displayName == databaseName } return when (databaseModel) { is FloconAndroidSqlDatabaseModel -> { diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.android.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.android.kt new file mode 100644 index 000000000..8f40c0b14 --- /dev/null +++ b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.android.kt @@ -0,0 +1,25 @@ +package io.github.openflocon.flocon.database.room + +import android.database.sqlite.SQLiteDatabase +import androidx.sqlite.db.SupportSQLiteOpenHelper + +//data class FloconRoomDatabaseModel( +// override val displayName: String, +// override val database: SQLiteDatabase +//) : FloconAndroidSqlDatabaseModel + +fun floconRegisterDatabase(displayName: String, database: SQLiteDatabase) { +// Flocon.databasePlugin.register( +// FloconRoomDatabaseModel( +// displayName = displayName, +// database = database +// ) +// ) +} + +fun floconRegisterDatabase(displayName: String, openHelper: SupportSQLiteOpenHelper) { +// floconRegisterDatabase( +// displayName = displayName, +// database = openHelper.writableDatabase., +// ) +} diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt deleted file mode 100644 index b826dda27..000000000 --- a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.openflocon.flocon.database.room - -import androidx.sqlite.db.SupportSQLiteDatabase -import androidx.sqlite.db.SupportSQLiteOpenHelper -import io.github.openflocon.flocon.Flocon -import io.github.openflocon.flocon.database.core.databasePlugin -import io.github.openflocon.flocon.database.core.model.FloconAndroidSqlDatabaseModel - -data class FloconRoomDatabaseModel( - override val displayName: String, - val database: SupportSQLiteDatabase -) : FloconAndroidSqlDatabaseModel - -fun floconRegisterDatabase(displayName: String, database: SupportSQLiteDatabase) { - Flocon.databasePlugin.register( - FloconRoomDatabaseModel( - displayName = displayName, - database = database, - ) - ) -} - -fun floconRegisterDatabase(displayName: String, openHelper: SupportSQLiteOpenHelper) { - floconRegisterDatabase( - displayName = displayName, - database = openHelper.writableDatabase, - ) -} diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt index d9c57cda1..045b20f29 100644 --- a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt +++ b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt @@ -1,8 +1,9 @@ package io.github.openflocon.flocon.database.room +import android.database.sqlite.SQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase internal class FloconSqliteDatabaseModel( override val displayName: String, - override val database: SupportSQLiteDatabase + override val database: SQLiteDatabase//SupportSQLiteDatabase ) : FloconAndroidSqlDatabaseModel diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt index fb8f00ce3..5d5d0fda1 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -1,7 +1,6 @@ package io.github.openflocon.flocon import io.github.openflocon.flocon.client.FloconClient -import io.github.openflocon.flocon.dsl.FloconMarker import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO @@ -60,21 +59,4 @@ fun startFlocon(context: FloconContext, block: FloconConfiguration.() -> Unit) { config = config, plugins = configuration.build() ) -} - -class DumpObject( - context: FloconContext, - client: Client -) : FloconApp() { - - override val client: Client = client - - private val _initialized = MutableStateFlow(false) - override val isInitialized: StateFlow = _initialized.asStateFlow() - - init { - this.context = context - instance = this - } - } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconEncoding.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconEncoding.kt new file mode 100644 index 000000000..a5f3c0dfe --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconEncoding.kt @@ -0,0 +1,18 @@ +package io.github.openflocon.flocon + +import io.github.openflocon.flocon.dsl.FloconMarker +import kotlinx.serialization.modules.EmptySerializersModule +import kotlinx.serialization.modules.SerializersModule + +@FloconMarker +interface FloconEncoding { + + val serializersModule: SerializersModule + +} + +@FloconMarker +internal class DefaultEncoding() : FloconEncoding { + override val serializersModule: SerializersModule + get() = EmptySerializersModule() +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt index e91903615..377e3f4d9 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt @@ -34,6 +34,9 @@ interface FloconPluginKey { interface FloconPluginFactory : FloconPluginKey { + @FloconMarker + fun createEncoding(): FloconEncoding = DefaultEncoding() + /** * Create a default configuration instance for the plugin. */ diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt index 1f8a0a878..345afea84 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt @@ -23,7 +23,9 @@ import androidx.compose.ui.unit.dp import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.database.core.FloconDatabase import io.github.openflocon.flocon.database.room.floconRegisterDatabase +import io.github.openflocon.flocon.database.room.room import io.github.openflocon.flocon.myapplication.database.DogDatabase +import io.github.openflocon.flocon.myapplication.database.initializeDatabases import io.github.openflocon.flocon.myapplication.database.initializeInMemoryDatabases import io.github.openflocon.flocon.myapplication.database.model.DogEntity import io.github.openflocon.flocon.myapplication.grpc.GrpcController @@ -68,7 +70,7 @@ class MainActivity : ComponentActivity() { .build() // initializeSharedPreferences(applicationContext) -// initializeDatabases(context = applicationContext) + initializeDatabases(context = applicationContext) // FloconLogger.enabled = true // Flocon.initialize(this) @@ -235,15 +237,17 @@ class MainActivity : ComponentActivity() { } install(FloconNetwork) - install(FloconDatabase) + install(FloconDatabase) { + room() + } } } private fun toMigrate() { - floconRegisterDatabase( - displayName = "inmemory_dogs", - openHelper = it.openHelper - ) +// floconRegisterDatabase( +// displayName = "inmemory_dogs", +// openHelper = it.openHelper +// ) } } \ No newline at end of file From 91fb3f862383ed6a0dccb845c39de6e764b92b00 Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Fri, 13 Mar 2026 17:01:36 +0100 Subject: [PATCH 16/35] feat: Clean a bit --- .../core/FloconDatabasePluginImpl.android.kt | 281 ------------------ .../core/model/FloconDatabaseModel.android.kt | 46 +++ .../flocon/database/core/FloconDatabase.kt | 9 +- .../database/core/FloconDatabaseConfig.kt | 5 +- .../database/core/FloconDatabasePluginImpl.kt | 63 ++-- .../core/datasource/FloconDatabaseProvider.kt | 3 +- .../core/model/FloconDatabaseModel.kt | 12 +- .../fromdevice/sql/DeviceDataBaseDataModel.kt | 2 +- .../sql/QueryResultReceivedDataModel.kt | 2 +- FloconAndroid/database/room/build.gradle.kts | 3 +- .../FloconRoomDatabaseProviderImpl.android.kt | 75 +++++ .../database/room/FloconRoomDatabaseConfig.kt | 1 + .../database/room/FloconRoomDatabaseModel.kt | 32 +- .../room/FloconRoomDatabaseProviderImpl.kt | 18 +- .../room/FloconRoomDatabaseModel.android.kt | 25 -- .../room/FloconSqliteDatabaseModel.kt | 9 - .../room/extensions/RoomBuilderExt.kt | 25 ++ .../plugins/deeplinks/FloconDeeplinks.kt | 3 +- .../io/github/openflocon/flocon/Flocon.kt | 1 + .../openflocon/flocon/FloconConfiguration.kt | 5 +- .../github/openflocon/flocon/FloconPlugin.kt | 2 +- .../analytics/FloconAnalyticsPlugin.kt | 5 +- .../FloconCrashReporterPlugin.kt | 3 +- .../dashboard/FloconDashboardPlugin.kt | 3 +- .../plugins/device/FloconDevicePluginImpl.kt | 2 +- .../flocon/plugins/files/FloconFilesPlugin.kt | 2 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 2 +- .../plugins/tables/FloconTablesPlugin.kt | 3 +- .../analytics/FloconAnalyticsPlugin.kt | 3 +- .../pluginsold/device/FloconDevicePlugin.kt | 2 +- .../pluginsold/files/FloconFilesPlugin.kt | 3 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 3 +- .../pluginsold/tables/FloconTablesPlugin.kt | 3 +- FloconAndroid/gradle/libs.versions.toml | 15 +- .../flocon/network/core/FloconNetwork.kt | 3 +- .../flocon/myapplication/MainActivity.kt | 11 +- .../myapplication/database/DogDatabase.kt | 24 +- .../database/InitializeDatabases.kt | 16 +- .../sample-multiplatform/build.gradle.kts | 2 +- .../features/database/DatabaseTabViewModel.kt | 2 +- 40 files changed, 296 insertions(+), 433 deletions(-) delete mode 100644 FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.android.kt create mode 100644 FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.android.kt create mode 100644 FloconAndroid/database/room/src/androidMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.android.kt delete mode 100644 FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.android.kt delete mode 100644 FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt create mode 100644 FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/extensions/RoomBuilderExt.kt diff --git a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.android.kt b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.android.kt deleted file mode 100644 index f467855ea..000000000 --- a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.android.kt +++ /dev/null @@ -1,281 +0,0 @@ -package io.github.openflocon.flocon.database.core - -import android.content.Context -import android.database.Cursor -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseDataSource -import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel -import io.github.openflocon.flocon.database.core.model.FloconFileDatabaseModel -import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse -import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel -import java.io.File - -internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { - return FloconDatabaseDataSourceAndroid(context.context) -} - -internal class FloconDatabaseDataSourceAndroid( - private val context: Context -) : FloconDatabaseDataSource { - - override suspend fun executeQuery( - registeredDatabases: List, - databaseName: String, - query: String - ): DatabaseExecuteResponse? { - val databaseModel = registeredDatabases.find { it.displayName == databaseName } - - return databaseModel?.executeQuery( - query = query - ) -// return when(databaseModel) { -// is FloconSqliteDatabaseModel -> { -// executeQuery( -// database = databaseModel.database, -// query = query, -// ) -// } -// else -> openDbAndExecuteQuery( -// databaseName = databaseName, -// query = query, -// ) -// } - } - -// private fun openDbAndExecuteQuery( -// databaseName: String, -// query: String -// ): DatabaseExecuteSqlResponse { -// var helper: SupportSQLiteOpenHelper? = null -// return try { -// val path = context.getDatabasePath(databaseName) -// val version = getDatabaseVersion(path = path.absolutePath) -// helper = FrameworkSQLiteOpenHelperFactory().create( -// SupportSQLiteOpenHelper.Configuration.builder(context) -// .name(path.absolutePath) -// .callback(object : SupportSQLiteOpenHelper.Callback(version) { -// override fun onCreate(db: SupportSQLiteDatabase) { -// // no op -// } -// -// override fun onUpgrade( -// db: SupportSQLiteDatabase, -// oldVersion: Int, -// newVersion: Int -// ) { -// // no op -// } -// }) -// .build() -// ) -// val database = helper.writableDatabase -// -// executeSQL( -// database = database, -// query = query, -// ) -// } catch (t: Throwable) { -// DatabaseExecuteSqlResponse.Error( -// message = t.message ?: "error on executeSQL", -// originalSql = query, -// ) -// } finally { -// helper?.close() -// } -// } - -// private fun executeSQL( -// database: SupportSQLiteDatabase, -// query: String -// ): DatabaseExecuteSqlResponse { -// return try { -// val firstWordUpperCase = getFirstWord(query).uppercase(Locale.getDefault()) -// when (firstWordUpperCase) { -// "UPDATE", "DELETE" -> executeUpdateDelete(database, query) -// "INSERT" -> executeInsert(database, query) -// "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(database, query) -// else -> executeRawQuery(database, query) -// } -// } catch (t: Throwable) { -// DatabaseExecuteSqlResponse.Error( -// message = t.message ?: "error on executeSQL", -// originalSql = query, -// ) -// } -// } - - override fun getAllDataBases( - registeredDatabases: List - ): List { - val databasesDir = context.getDatabasePath("dummy_db").parentFile ?: return emptyList() - - val foundDatabases = mutableListOf() - // Start the recursive search from the base databases directory - scanDirectoryForDatabases( - directory = databasesDir, - depth = 0, - foundDatabases = foundDatabases - ) - - registeredDatabases.forEach { - when (it) { - is FloconFileDatabaseModel -> { - // check if file exists here - if (File(it.absolutePath).exists()) { - foundDatabases.add( - DeviceDataBaseDataModel( - id = it.absolutePath, - name = it.displayName, - ) - ) - } - } - - else -> { - foundDatabases.add( - DeviceDataBaseDataModel( - id = it.displayName, - name = it.displayName, - ) - ) - } - } - } - - return foundDatabases - } - - /** - * Recursively scans a directory for SQLite database files. - * - * @param directory The current directory to scan. - * @param foundDatabases The mutable list to add found databases to. - */ - private fun scanDirectoryForDatabases( - directory: File, - depth: Int, - foundDatabases: MutableList - ) { - if (depth >= MAX_DEPTH) { - return - } - directory.listFiles()?.forEach { file -> - if (file.isDirectory) { - // If it's a directory, recursively call this function - scanDirectoryForDatabases( - directory = file, - depth = depth + 1, - foundDatabases = foundDatabases, - ) - } else { - // If it's a file, check if it's a database file - if (file.isFile && - !file.name.endsWith("-wal") && // Write-Ahead Log - !file.name.endsWith("-shm") && // Shared-Memory - !file.name.endsWith("-journal") // Older journaling mode - ) { - foundDatabases.add( - DeviceDataBaseDataModel( - id = file.absolutePath, // Use absolute path for unique ID - name = file.name, - ) - ) - } - } - } - } - - companion object { - private const val MAX_DEPTH = 7 - } -} - - -//private fun executeSelect( -// database: SupportSQLiteDatabase, -// query: String, -//): DatabaseExecuteSqlResponse { -// val cursor: Cursor = database.query(query) -// try { -// val columnNames = cursor.columnNames.toList() -// val rows = cursorToList(cursor) -// return DatabaseExecuteSqlResponse.Select( -// columns = columnNames, -// values = rows, -// ) -// } finally { -// cursor.close() -// } -//} - -//private fun executeUpdateDelete( -// database: SupportSQLiteDatabase, -// query: String, -//): DatabaseExecuteSqlResponse { -// val statement = database.compileStatement(query) -// val count: Int = statement.executeUpdateDelete() -// return DatabaseExecuteSqlResponse.UpdateDelete(count) -//} -// -//private fun executeInsert( -// database: SupportSQLiteDatabase, -// query: String, -//): DatabaseExecuteSqlResponse { -// val statement = database.compileStatement(query) -// val insertedId: Long = statement.executeInsert() -// return DatabaseExecuteSqlResponse.Insert(insertedId) -//} -// -//private fun executeRawQuery( -// database: SupportSQLiteDatabase, -// query: String, -//): DatabaseExecuteSqlResponse { -// database.execSQL(query) -// return DatabaseExecuteSqlResponse.RawSuccess -//} - -private fun getFirstWord(s: String): String { - var s = s - s = s.trim { it <= ' ' } - val firstSpace = s.indexOf(' ') - return if (firstSpace >= 0) s.substring(0, firstSpace) else s -} - -private fun cursorToList(cursor: Cursor): List> { - val rows = mutableListOf>() - val numColumns = cursor.columnCount - while (cursor.moveToNext()) { - val values = mutableListOf() - for (column in 0.. null - Cursor.FIELD_TYPE_INTEGER -> cursor.getLong(column).toString() - Cursor.FIELD_TYPE_FLOAT -> cursor.getDouble(column).toString() - Cursor.FIELD_TYPE_BLOB -> cursor.getBlob(column).toString() - Cursor.FIELD_TYPE_STRING -> cursor.getString(column).toString() - else -> cursor.getString(column) - } -} - -// must use the old way to get the version... -private fun getDatabaseVersion( - path: String, -): Int { - return android.database.sqlite.SQLiteDatabase.openDatabase( - path, - null, - android.database.sqlite.SQLiteDatabase.OPEN_READONLY - ).use { db -> - db.rawQuery("PRAGMA user_version", null).use { cursor -> - if (cursor.moveToFirst()) cursor.getInt(0) else 0 - } - } -} \ No newline at end of file diff --git a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.android.kt b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.android.kt new file mode 100644 index 000000000..aae3a3626 --- /dev/null +++ b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.android.kt @@ -0,0 +1,46 @@ +package io.github.openflocon.flocon.database.core.model + +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse + +actual fun openDbAndExecuteQuery( + path: String, + query: String +): DatabaseExecuteSqlResponse { +// var helper: SupportSQLiteOpenHelper? = null +// return try { +// val path = context.getDatabasePath(databaseName) +// val version = getDatabaseVersion(path = path.absolutePath) +// helper = FrameworkSQLiteOpenHelperFactory().create( +// SupportSQLiteOpenHelper.Configuration.builder(context) +// .name(path.absolutePath) +// .callback(object : SupportSQLiteOpenHelper.Callback(version) { +// override fun onCreate(db: SupportSQLiteDatabase) { +// // no op +// } +// +// override fun onUpgrade( +// db: SupportSQLiteDatabase, +// oldVersion: Int, +// newVersion: Int +// ) { +// // no op +// } +// }) +// .build() +// ) +// val database = helper.writableDatabase +// +// executeSQL( +// database = database, +// query = query, +// ) +// } catch (t: Throwable) { +// DatabaseExecuteSqlResponse.Error( +// message = t.message ?: "error on executeSQL", +// originalSql = query, +// ) +// } finally { +// helper?.close() +// } + TODO() +} \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt index 219abe66d..eddb854db 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.database.core import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconEncoding import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol @@ -14,7 +15,8 @@ object FloconDatabase : FloconPluginFactory = mutableListOf() diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.kt index dc07b079b..aff63fe0a 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePluginImpl.kt @@ -1,47 +1,51 @@ package io.github.openflocon.flocon.database.core -import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseDataSource import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseProvider import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DatabaseQueryLogModel +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel import io.github.openflocon.flocon.database.core.model.fromdevice.sql.QueryResultDataModel import io.github.openflocon.flocon.database.core.model.fromdevice.sql.listDeviceDataBaseDataModelToJson import io.github.openflocon.flocon.database.core.model.todevice.DatabaseQueryMessage import io.github.openflocon.flocon.dsl.FloconMarker +import io.github.openflocon.flocon.utils.currentTimeMillis +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update - -internal expect fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource +import kotlinx.coroutines.flow.updateAndGet +import kotlinx.coroutines.launch +import kotlinx.serialization.encodeToString internal class FloconDatabasePluginImpl( private var sender: FloconMessageSender, - private val context: FloconContext, + private val scope: CoroutineScope, @FloconMarker override val providers: List ) : FloconPlugin, FloconDatabasePlugin { - override val key: String = "DATABASE" + override val key: String = Protocol.FromDevice.Database.Plugin private val registeredDatabases = MutableStateFlow>(emptyList()) - private val dataSource = buildFloconDatabaseDataSource(context) - override suspend fun onMessageReceived( method: String, body: String ) { + println("Database: $method & $body") when (method) { Protocol.ToDevice.Database.Method.GetDatabases -> sendAllDatabases(sender) Protocol.ToDevice.Database.Method.Query -> { val queryMessage = DatabaseQueryMessage.fromJson(message = body) ?: return val databaseModel = registeredDatabases.value - .find { it.displayName == queryMessage.database } + .find { it.id == queryMessage.database } + val result = databaseModel?.executeQuery(query = queryMessage.query) ?: DatabaseExecuteSqlResponse.Error( message = "Database not found", @@ -54,7 +58,7 @@ internal class FloconDatabasePluginImpl( method = Protocol.FromDevice.Database.Method.Query, body = QueryResultDataModel( requestId = queryMessage.requestId, - result = result + result = FloconEncoder.json.encodeToString(result) ) .toJson() ) @@ -69,15 +73,17 @@ internal class FloconDatabasePluginImpl( sendAllDatabases(sender) } + @OptIn(FloconMarker::class) private suspend fun sendAllDatabases(sender: FloconMessageSender) { - val databases = dataSource.getAllDataBases( - registeredDatabases = registeredDatabases.value, - ) + val databases = providers.flatMap { it.getAllDataBases(emptyList()) } + val all = registeredDatabases.updateAndGet { it + databases } + .map { DeviceDataBaseDataModel(id = it.id, name = it.displayName) } + try { sender.send( plugin = Protocol.FromDevice.Database.Plugin, method = Protocol.FromDevice.Database.Method.GetDatabases, - body = listDeviceDataBaseDataModelToJson(databases), + body = listDeviceDataBaseDataModelToJson(all), ) } catch (t: Throwable) { FloconLogger.logError("Database parsing error", t) @@ -89,19 +95,22 @@ internal class FloconDatabasePluginImpl( } override fun logQuery(dbName: String, sqlQuery: String, bindArgs: List) { - try { -// sender.send( -// plugin = Protocol.FromDevice.Database.Plugin, -// method = Protocol.FromDevice.Database.Method.LogQuery, -// body = DatabaseQueryLogModel( -// dbName = dbName, -// sqlQuery = sqlQuery, -// bindArgs = bindArgs.map { it.toString() }, -// timestamp = currentTimeMillis(), -// ).toJson(), -// ) - } catch (t: Throwable) { - FloconLogger.logError("Database logging error", t) + scope.launch { + try { + sender.send( + plugin = Protocol.FromDevice.Database.Plugin, + method = Protocol.FromDevice.Database.Method.LogQuery, + body = DatabaseQueryLogModel( + dbName = dbName, + sqlQuery = sqlQuery, + bindArgs = bindArgs.map { it.toString() }, + timestamp = currentTimeMillis() + ) + .toJson() + ) + } catch (t: Throwable) { + FloconLogger.logError("Database logging error", t) + } } } diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseProvider.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseProvider.kt index b54fb9d56..047665840 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseProvider.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseProvider.kt @@ -1,7 +1,6 @@ package io.github.openflocon.flocon.database.core.datasource import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel -import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel import io.github.openflocon.flocon.dsl.FloconMarker interface FloconDatabaseProvider { @@ -9,6 +8,6 @@ interface FloconDatabaseProvider { @FloconMarker fun getAllDataBases( registeredDatabases: List - ): List + ): List } \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt index 8b7899c70..c6978e3f8 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.kt @@ -1,8 +1,10 @@ package io.github.openflocon.flocon.database.core.model import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse interface FloconDatabaseModel { + val id: String val displayName: String suspend fun executeQuery(query: String): DatabaseExecuteResponse @@ -10,10 +12,18 @@ interface FloconDatabaseModel { } data class FloconFileDatabaseModel( + override val id: String, override val displayName: String, val absolutePath: String ) : FloconDatabaseModel { + override suspend fun executeQuery(query: String): DatabaseExecuteResponse { - TODO("Not yet implemented") + return openDbAndExecuteQuery(absolutePath, query) } + } + +expect fun openDbAndExecuteQuery( + path: String, + query: String +): DatabaseExecuteSqlResponse \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt index 337bb00f4..182dcc0e2 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt @@ -7,7 +7,7 @@ import kotlinx.serialization.encodeToString @Serializable data class DeviceDataBaseDataModel( val id: String, - val name: String, + val name: String ) fun listDeviceDataBaseDataModelToJson(items: List) : String { diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt index 1d1da7d6c..a05cfdae1 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt @@ -8,7 +8,7 @@ import kotlinx.serialization.encodeToString @Serializable internal data class QueryResultDataModel( val requestId: String, - val result: DatabaseExecuteResponse, + val result: String ) { fun toJson(): String { return FloconEncoder.json.encodeToString(this) diff --git a/FloconAndroid/database/room/build.gradle.kts b/FloconAndroid/database/room/build.gradle.kts index c828ca467..4b8d7eb40 100644 --- a/FloconAndroid/database/room/build.gradle.kts +++ b/FloconAndroid/database/room/build.gradle.kts @@ -25,7 +25,8 @@ kotlin { implementation(project(":flocon")) api(project(":database:core")) implementation(libs.androidx.room.runtime) - implementation(libs.androidx.sqlite) + implementation(libs.androidx.room.sqlite.wrapper) + implementation(libs.androidx.sqlite.bundled) } } diff --git a/FloconAndroid/database/room/src/androidMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.android.kt b/FloconAndroid/database/room/src/androidMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.android.kt new file mode 100644 index 000000000..68eeae3b9 --- /dev/null +++ b/FloconAndroid/database/room/src/androidMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.android.kt @@ -0,0 +1,75 @@ +package io.github.openflocon.flocon.database.room + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.FloconFileDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel +import io.github.openflocon.flocon.dsl.FloconMarker +import java.io.File + +@OptIn(markerClass = [FloconMarker::class]) +internal actual class FloconRoomDatabaseProviderImpl actual constructor( + private val context: FloconContext, + paths: List +) : FloconRoomDatabaseProvider { + + actual override fun register() { + TODO("Not yet implemented") + } + + @FloconMarker + actual override fun getAllDataBases(registeredDatabases: List): List { + val databasesDir = context.context.getDatabasePath("dummy_db") + .parentFile + ?: return emptyList() + + val foundDatabases = mutableListOf() + // Start the recursive search from the base databases directory + scanDirectoryForDatabases( + directory = databasesDir, + depth = 0, + foundDatabases = foundDatabases + ) + + return foundDatabases + } + + private fun scanDirectoryForDatabases( + directory: File, + depth: Int, + foundDatabases: MutableList + ) { + if (depth >= MAX_DEPTH) { + return + } + directory.listFiles()?.forEach { file -> + if (file.isDirectory) { + // If it's a directory, recursively call this function + scanDirectoryForDatabases( + directory = file, + depth = depth + 1, + foundDatabases = foundDatabases, + ) + } else { + // If it's a file, check if it's a database file + if (file.isFile && + !file.name.endsWith("-wal") && // Write-Ahead Log + !file.name.endsWith("-shm") && // Shared-Memory + !file.name.endsWith("-journal") // Older journaling mode + ) { + foundDatabases.add( + FloconFileDatabaseModel( + id = file.absolutePath, // Use absolute path for unique ID + displayName = file.name, + absolutePath = file.absolutePath + ) + ) + } + } + } + } + + companion object { + private const val MAX_DEPTH = 7 + } +} \ No newline at end of file diff --git a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseConfig.kt b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseConfig.kt index 40d7007f1..f34d1d51d 100644 --- a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseConfig.kt +++ b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseConfig.kt @@ -18,6 +18,7 @@ fun FloconDatabaseConfig.room(block: FloconRoomDatabaseConfig.() -> Unit = {}) { providers.add( FloconRoomDatabaseProviderImpl( + context = context, paths = config.paths ) ) diff --git a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt index c97d82cd8..632ce7a9e 100644 --- a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt +++ b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt @@ -10,7 +10,26 @@ import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse -data class FloconRoomDatabaseModel( +fun floconRegisterDatabase(displayName: String, database: RoomDatabase) { + Flocon.databasePlugin.register( + FloconRoomDatabaseModel( + id = displayName, + displayName = displayName, + database = database + ) + ) +} + +fun floconLogDatabaseQuery(databaseName: String, sqlQuery: String, bindArgs: List) { + Flocon.databasePlugin.logQuery( + dbName = databaseName, + sqlQuery = sqlQuery, + bindArgs = bindArgs, + ) +} + +internal data class FloconRoomDatabaseModel( + override val id: String, override val displayName: String, val database: RoomDatabase ) : FloconDatabaseModel { @@ -114,13 +133,4 @@ private fun getFirstWord(s: String): String { val trimmed = s.trim() val firstSpace = trimmed.indexOf(' ') return if (firstSpace >= 0) trimmed.substring(0, firstSpace) else trimmed -} - -fun floconRegisterDatabase(displayName: String, database: RoomDatabase) { - Flocon.databasePlugin.register( - FloconRoomDatabaseModel( - displayName = displayName, - database = database, - ) - ) -} +} \ No newline at end of file diff --git a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt index db6fc35b3..7982aeeac 100644 --- a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt +++ b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt @@ -1,10 +1,10 @@ package io.github.openflocon.flocon.database.room import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.database.core.databasePlugin import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseProvider import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel -import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel import io.github.openflocon.flocon.dsl.FloconMarker interface FloconRoomDatabaseProvider : FloconDatabaseProvider { @@ -15,20 +15,12 @@ interface FloconRoomDatabaseProvider : FloconDatabaseProvider { } @OptIn(FloconMarker::class) -internal class FloconRoomDatabaseProviderImpl( +internal expect class FloconRoomDatabaseProviderImpl( + context: FloconContext, paths: List ) : FloconRoomDatabaseProvider { - - override fun getAllDataBases( - registeredDatabases: List - ): List { - TODO("Not yet implemented") - } - - override fun register() { - TODO("Not yet implemented") - } - + override fun register() + override fun getAllDataBases(registeredDatabases: List): List } @OptIn(FloconMarker::class) diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.android.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.android.kt deleted file mode 100644 index 8f40c0b14..000000000 --- a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.android.kt +++ /dev/null @@ -1,25 +0,0 @@ -package io.github.openflocon.flocon.database.room - -import android.database.sqlite.SQLiteDatabase -import androidx.sqlite.db.SupportSQLiteOpenHelper - -//data class FloconRoomDatabaseModel( -// override val displayName: String, -// override val database: SQLiteDatabase -//) : FloconAndroidSqlDatabaseModel - -fun floconRegisterDatabase(displayName: String, database: SQLiteDatabase) { -// Flocon.databasePlugin.register( -// FloconRoomDatabaseModel( -// displayName = displayName, -// database = database -// ) -// ) -} - -fun floconRegisterDatabase(displayName: String, openHelper: SupportSQLiteOpenHelper) { -// floconRegisterDatabase( -// displayName = displayName, -// database = openHelper.writableDatabase., -// ) -} diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt deleted file mode 100644 index 045b20f29..000000000 --- a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconSqliteDatabaseModel.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.database.room - -import android.database.sqlite.SQLiteDatabase -import androidx.sqlite.db.SupportSQLiteDatabase - -internal class FloconSqliteDatabaseModel( - override val displayName: String, - override val database: SQLiteDatabase//SupportSQLiteDatabase -) : FloconAndroidSqlDatabaseModel diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/extensions/RoomBuilderExt.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/extensions/RoomBuilderExt.kt new file mode 100644 index 000000000..5c12df0bf --- /dev/null +++ b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/extensions/RoomBuilderExt.kt @@ -0,0 +1,25 @@ +package io.github.openflocon.flocon.database.room.extensions + +import androidx.room.RoomDatabase +import androidx.room.RoomDatabase.QueryCallback +import io.github.openflocon.flocon.database.room.floconLogDatabaseQuery +import java.util.concurrent.Executor +import java.util.concurrent.Executors + +inline fun RoomDatabase.Builder.floconLogs( + name: String? = T::class.simpleName, + executor: Executor = Executors.newSingleThreadExecutor(), + queryCallback: QueryCallback? = null +): RoomDatabase.Builder { + return setQueryCallback( + queryCallback = { sqlQuery, bindArgs -> + floconLogDatabaseQuery( + databaseName = name ?: "database", + sqlQuery = sqlQuery, + bindArgs = bindArgs + ) + queryCallback?.onQuery(sqlQuery, bindArgs) + }, + executor = executor + ) +} \ No newline at end of file diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt index 3bae66feb..6caacd52c 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.plugins.deeplinks import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginFactory @@ -12,7 +13,7 @@ import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel object FloconDeeplinks : FloconPluginFactory { override val name: String = "Deeplinks" override val pluginId: String = FloconDeeplinks::class.simpleName!! - override fun createConfig() = FloconDeeplinksConfig() + override fun createConfig(context: FloconContext) = FloconDeeplinksConfig() @OptIn(FloconMarker::class) override fun install( diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt index 075727480..6386e43ef 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt @@ -67,6 +67,7 @@ class Flocon internal constructor( } private fun onMessageReceived(message: String) { + println("Message received : $message") config.scope.launch(Dispatchers.IO) { floconMessageFromServerFromJson(message)?.let { messageFromServer -> plugins.find { it.key == messageFromServer.plugin } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt index 5d5d0fda1..0d74f842c 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -5,9 +5,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow class FloconConfiguration internal constructor( private val config: FloconConfig @@ -23,7 +20,7 @@ class FloconConfiguration internal constructor( configure: Config.() -> Unit = {} ) { plugins[factory.pluginId] = { scope -> - val config = factory.createConfig() + val config = factory.createConfig(config.context) .apply { configure() } factory.install( diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt index 377e3f4d9..948f13d2b 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt @@ -40,7 +40,7 @@ interface FloconPluginFactory { override val name: String = "Analytics" override val pluginId: String = Protocol.ToDevice.Analytics.Plugin - override fun createConfig() = FloconAnalyticsConfig() + override fun createConfig(context: FloconContext) = FloconAnalyticsConfig() override fun install( pluginConfig: FloconAnalyticsConfig, floconConfig: FloconConfig @@ -33,7 +34,7 @@ internal class FloconAnalyticsPluginImpl( private val sender: FloconMessageSender, ) : FloconPlugin, FloconAnalyticsPlugin { override val key: String - get() = "ANALYTICS" + get() = Protocol.ToDevice.Analytics.Plugin override suspend fun onMessageReceived( method: String, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt index 4c31686df..8a61800e1 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt @@ -32,7 +32,8 @@ object FloconCrashReporter : override val pluginId: String = Protocol.ToDevice.Analytics.Plugin // Crash reporter is usually write-only but we can set an ID - override fun createConfig() = FloconCrashReporterConfig() + override fun createConfig(context: FloconContext) = FloconCrashReporterConfig() + override fun install( pluginConfig: FloconCrashReporterConfig, floconConfig: FloconConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt index a556a3880..ee9d2ff6f 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.plugins.dashboard import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig @@ -27,7 +28,7 @@ interface FloconDashboardPlugin : FloconPlugin { object FloconDashboard : FloconPluginFactory { override val name: String = "Dashboard" override val pluginId: String = Protocol.ToDevice.Dashboard.Plugin - override fun createConfig() = FloconDashboardConfig() + override fun createConfig(context: FloconContext) = FloconDashboardConfig() override fun install( pluginConfig: FloconDashboardConfig, floconConfig: FloconConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt index f1a7f9710..8bea31768 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt @@ -18,7 +18,7 @@ interface FloconDevicePlugin : FloconPlugin { object FloconDevice : FloconPluginFactory { override val name: String = "Device" override val pluginId: String = Protocol.ToDevice.Device.Plugin - override fun createConfig() = FloconDeviceConfig() + override fun createConfig(context: FloconContext) = FloconDeviceConfig() override fun install( pluginConfig: FloconDeviceConfig, floconConfig: FloconConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt index a3c708973..3dd6df539 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt @@ -29,7 +29,7 @@ interface FloconFilesPlugin : FloconPlugin object FloconFiles : FloconPluginFactory { override val name: String = "Files" override val pluginId: String = Protocol.ToDevice.Files.Plugin - override fun createConfig() = FloconFilesConfig() + override fun createConfig(context: FloconContext) = FloconFilesConfig() override fun install( pluginConfig: FloconFilesConfig, floconConfig: FloconConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt index f2d162865..79ba0dd4d 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt @@ -19,7 +19,7 @@ interface FloconPreferencesPlugin : FloconPlugin { object FloconPreferences : FloconPluginFactory { override val name: String = "Preferences" override val pluginId: String = Protocol.ToDevice.SharedPreferences.Plugin - override fun createConfig() = FloconPreferencesConfig() + override fun createConfig(context: FloconContext) = FloconPreferencesConfig() override fun install( pluginConfig: FloconPreferencesConfig, floconConfig: FloconConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt index e22068da7..8c63f218d 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt @@ -1,6 +1,7 @@ package io.github.openflocon.flocon.plugins.tables import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig @@ -19,7 +20,7 @@ interface FloconTablePlugin : FloconPlugin { object FloconTable : FloconPluginFactory { override val name: String = "Table" override val pluginId: String = Protocol.ToDevice.Table.Plugin - override fun createConfig() = FloconTableConfig() + override fun createConfig(context: FloconContext) = FloconTableConfig() override fun install( pluginConfig: FloconTableConfig, floconConfig: FloconConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt index e48831806..63f2a342e 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocon.pluginsold.analytics import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory @@ -13,7 +14,7 @@ class FloconAnalyticsConfig : FloconPluginConfig * Flocon Analytics Plugin. */ object FloconAnalytics : FloconPluginFactory { - override fun createConfig(): FloconAnalyticsConfig = TODO() + override fun createConfig(context: FloconContext) = TODO() override fun install( pluginConfig: FloconAnalyticsConfig, floconConfig: FloconConfig diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt index 71f0e8b94..c0b9cfa2b 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt @@ -8,7 +8,7 @@ class FloconDeviceConfig : FloconPluginConfig * Flocon Device Plugin. */ object FloconDevice : FloconPluginFactory { - override fun createConfig(): FloconDeviceConfig { + override fun createConfig(context: FloconContext): FloconDeviceConfig { TODO("Not yet implemented") } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt index 9472865f7..42eebfe1f 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocon.pluginsold.files import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory @@ -15,7 +16,7 @@ class FloconFilesConfig : FloconPluginConfig { * Used to inspect and download files from the device. */ object FloconFiles : FloconPluginFactory { - override fun createConfig(): FloconFilesConfig { + override fun createConfig(context: FloconContext): FloconFilesConfig { TODO("Not yet implemented") } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt index 3ec1427d2..dec9be9dc 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocon.pluginsold.sharedprefs import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory @@ -14,7 +15,7 @@ class FloconPreferencesConfig : FloconPluginConfig * Used to inspect SharedPreferences or other key-value stores. */ object FloconPreferences : FloconPluginFactory { - override fun createConfig(): FloconPreferencesConfig { + override fun createConfig(context: FloconContext): FloconPreferencesConfig { TODO("Not yet implemented") } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/FloconTablesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/FloconTablesPlugin.kt index d7b2aec3a..63ebbc40b 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/FloconTablesPlugin.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocon.pluginsold.tables import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory @@ -14,7 +15,7 @@ class FloconTableConfig : FloconPluginConfig * Used to display custom data tables. */ object FloconTable : FloconPluginFactory { - override fun createConfig(): FloconTableConfig { + override fun createConfig(context: FloconContext): FloconTableConfig { TODO("Not yet implemented") } diff --git a/FloconAndroid/gradle/libs.versions.toml b/FloconAndroid/gradle/libs.versions.toml index 32ea39e80..f65bafb13 100644 --- a/FloconAndroid/gradle/libs.versions.toml +++ b/FloconAndroid/gradle/libs.versions.toml @@ -19,7 +19,7 @@ composeBom = "2025.06.01" appcompat = "1.7.1" material = "1.12.0" okhttpBom = "4.12.0" -room = "2.7.2" +room = "2.8.4" # for grpc gson = "2.11.0" grpc = "1.70.0" @@ -28,7 +28,7 @@ grpcKotlin = "1.4.3" protobuf = "4.26.1" ksp = "2.1.0-1.0.29" processPhoenix = "3.0.0" -sqlite = "2.5.2" +sqlite = "2.6.2" sqliteJdbc = "3.50.3.0" buildconfig = "5.6.8" brotli = "0.1.2" @@ -36,9 +36,6 @@ brotli = "0.1.2" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" } -androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } -androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } -androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } brotli-dec = { module = "org.brotli:dec", version.ref = "brotli" } apollo-http-okhttprealization = { module = "com.apollographql.apollo:apollo-http-okhttprealization", version.ref = "apollo" } apollo-runtime = { module = "com.apollographql.apollo:apollo-runtime", version.ref = "apollo" } @@ -90,9 +87,11 @@ protobuf-kotlin-lite = { group = "com.google.protobuf", name = "protobuf-kotlin- protobuf-util = { group = "com.google.protobuf", name = "protobuf-java-util", version.ref = "protobuf" } sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" } squareup-okhttp = { module = "com.squareup.okhttp3:okhttp" } -sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } -androidx-sqlite = { group = "androidx.sqlite", name = "sqlite", version.ref = "sqlite" } -androidx-sqlite-framework = { group = "androidx.sqlite", name = "sqlite-framework", version.ref = "sqlite" } + +androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } +androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } +androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } +androidx-room-sqlite-wrapper = { module = "androidx.room:room-sqlite-wrapper", version.ref = "room" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt index 636aada5e..a9eac6957 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocon.network.core import io.github.openflocon.flocon.Flocon import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory @@ -44,7 +45,7 @@ object FloconNetwork : FloconPluginFactory @@ -243,11 +243,4 @@ class MainActivity : ComponentActivity() { } } - private fun toMigrate() { -// floconRegisterDatabase( -// displayName = "inmemory_dogs", -// openHelper = it.openHelper -// ) - } - } \ No newline at end of file diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/DogDatabase.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/DogDatabase.kt index c499b51df..e3c13da9c 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/DogDatabase.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/DogDatabase.kt @@ -4,11 +4,11 @@ import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase +import io.github.openflocon.flocon.database.room.extensions.floconLogs import io.github.openflocon.flocon.myapplication.database.dao.DogDao import io.github.openflocon.flocon.myapplication.database.model.DogEntity import io.github.openflocon.flocon.myapplication.database.model.HumanEntity import io.github.openflocon.flocon.myapplication.database.model.HumanWithDogEntity -import java.util.concurrent.Executors @Database( entities = [ @@ -29,18 +29,16 @@ abstract class DogDatabase : RoomDatabase() { fun getDatabase(context: Context): DogDatabase { val dbName = "dogs_database" return INSTANCE ?: synchronized(this) { - TODO() -// val instance = Room.databaseBuilder( -// context.applicationContext, -// DogDatabase::class.java, -// dbName -// ).setQueryCallback({ sqlQuery, bindArgs -> floconLogDatabaseQuery( -// dbName = dbName, sqlQuery = sqlQuery, bindArgs = bindArgs -// ) }, Executors.newSingleThreadExecutor()) -// .fallbackToDestructiveMigration() -// .build() -// INSTANCE = instance -// instance + val instance = Room.databaseBuilder( + context.applicationContext, + DogDatabase::class.java, + dbName + ) + .floconLogs() + .fallbackToDestructiveMigration(dropAllTables = true) + .build() + INSTANCE = instance + instance } } } diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt index c0da1d077..d380b0602 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/database/InitializeDatabases.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocon.myapplication.database import android.content.Context import androidx.room.Room +import io.github.openflocon.flocon.database.room.floconRegisterDatabase import io.github.openflocon.flocon.myapplication.database.model.DogEntity import io.github.openflocon.flocon.myapplication.database.model.FoodEntity import io.github.openflocon.flocon.myapplication.database.model.HumanEntity @@ -14,10 +15,10 @@ fun initializeInMemoryDatabases(context: Context): DogDatabase { context, DogDatabase::class.java, ).build().also { -// floconRegisterDatabase( -// displayName = "inmemory_dogs", -// openHelper = it.openHelper -// ) + floconRegisterDatabase( + displayName = "inmemory_dogs", + database = it + ) } } @@ -25,6 +26,11 @@ fun initializeDatabases(context: Context) { val dogDatabase = DogDatabase.getDatabase(context) val foodDatabase = FoodDatabase.getDatabase(context) + floconRegisterDatabase( + displayName = "dogs", + database = dogDatabase + ) + GlobalScope.launch { dogDatabase.dogDao().insertDog( DogEntity( @@ -125,7 +131,7 @@ fun initializeDatabases(context: Context) { id = 10L + i, name = "dog$i", breed = randomBreed, - pictureUrl = "https://picsum.photos/500/50${i%10}.jpg", + pictureUrl = "https://picsum.photos/500/50${i % 10}.jpg", age = (1..15).random() ) ) diff --git a/FloconAndroid/sample-multiplatform/build.gradle.kts b/FloconAndroid/sample-multiplatform/build.gradle.kts index 51ba4847a..64301aaa6 100644 --- a/FloconAndroid/sample-multiplatform/build.gradle.kts +++ b/FloconAndroid/sample-multiplatform/build.gradle.kts @@ -75,7 +75,7 @@ kotlin { implementation(libs.ktor.client.cio) implementation(libs.sqlite.jdbc) - implementation(libs.sqlite.bundled) + implementation(libs.androidx.sqlite.bundled) // Compose Desktop implementation(compose.desktop.currentOs) diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/DatabaseTabViewModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/DatabaseTabViewModel.kt index b28f5c9f0..3c63480f9 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/DatabaseTabViewModel.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/DatabaseTabViewModel.kt @@ -59,7 +59,7 @@ class DatabaseTabViewModel( var query = mutableStateOf("") val lastQueries = observeLastSuccessQueriesUseCase(params.databaseId) - .map { it.filterNot { it.isBlank() } } + .map { it.filterNot(String::isBlank) } .flowOn(dispatcherProvider.data) .stateIn( viewModelScope, From 0e8949654aba388c778668c5f9aef3e11e4c563c Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 25 Mar 2026 13:26:31 +0100 Subject: [PATCH 17/35] fix: Database --- FloconAndroid/.vscode/settings.json | 2 +- FloconAndroid/database/core/build.gradle.kts | 2 + .../core/model/FloconDatabaseModel.android.kt | 128 +++++++--- .../datasource/FloconDatabaseDataSource.kt | 1 - .../database/core/FloconDatabasePlugin.ios.kt | 126 +--------- .../core/model/FloconDatabaseModel.ios.kt | 75 ++++++ .../database/core/FloconDatabasePlugin.jvm.kt | 90 ++++++- .../FloconRoomDatabaseProviderImpl.android.kt | 6 +- .../database/room/FloconRoomDatabaseModel.kt | 3 - .../room/FloconRoomDatabaseProviderImpl.kt | 1 - .../room/FloconDatabasePlugin.android.kt | 231 ------------------ 11 files changed, 260 insertions(+), 405 deletions(-) create mode 100644 FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.ios.kt delete mode 100644 FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt diff --git a/FloconAndroid/.vscode/settings.json b/FloconAndroid/.vscode/settings.json index c5f3f6b9c..e0f15db2e 100644 --- a/FloconAndroid/.vscode/settings.json +++ b/FloconAndroid/.vscode/settings.json @@ -1,3 +1,3 @@ { - "java.configuration.updateBuildConfiguration": "interactive" + "java.configuration.updateBuildConfiguration": "automatic" } \ No newline at end of file diff --git a/FloconAndroid/database/core/build.gradle.kts b/FloconAndroid/database/core/build.gradle.kts index 1d07bb50d..f66e064ad 100644 --- a/FloconAndroid/database/core/build.gradle.kts +++ b/FloconAndroid/database/core/build.gradle.kts @@ -37,6 +37,7 @@ kotlin { val jvmMain by getting { dependencies { + implementation(libs.sqlite.jdbc) } } @@ -49,6 +50,7 @@ kotlin { iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) dependencies { + implementation(libs.androidx.sqlite.bundled) } } } diff --git a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.android.kt b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.android.kt index aae3a3626..a0157ddcc 100644 --- a/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.android.kt +++ b/FloconAndroid/database/core/src/androidMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.android.kt @@ -1,46 +1,100 @@ package io.github.openflocon.flocon.database.core.model +import android.database.Cursor +import android.database.sqlite.SQLiteDatabase import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse +import java.util.Locale actual fun openDbAndExecuteQuery( path: String, query: String ): DatabaseExecuteSqlResponse { -// var helper: SupportSQLiteOpenHelper? = null -// return try { -// val path = context.getDatabasePath(databaseName) -// val version = getDatabaseVersion(path = path.absolutePath) -// helper = FrameworkSQLiteOpenHelperFactory().create( -// SupportSQLiteOpenHelper.Configuration.builder(context) -// .name(path.absolutePath) -// .callback(object : SupportSQLiteOpenHelper.Callback(version) { -// override fun onCreate(db: SupportSQLiteDatabase) { -// // no op -// } -// -// override fun onUpgrade( -// db: SupportSQLiteDatabase, -// oldVersion: Int, -// newVersion: Int -// ) { -// // no op -// } -// }) -// .build() -// ) -// val database = helper.writableDatabase -// -// executeSQL( -// database = database, -// query = query, -// ) -// } catch (t: Throwable) { -// DatabaseExecuteSqlResponse.Error( -// message = t.message ?: "error on executeSQL", -// originalSql = query, -// ) -// } finally { -// helper?.close() -// } - TODO() + var database: SQLiteDatabase? = null + return try { + database = SQLiteDatabase.openDatabase( + path, + null, + SQLiteDatabase.OPEN_READWRITE + ) + executeSQLInternal(database, query) + } catch (t: Throwable) { + DatabaseExecuteSqlResponse.Error( + message = t.message ?: "error on executeSQL", + originalSql = query, + ) + } finally { + database?.close() + } +} + +private fun executeSQLInternal( + database: SQLiteDatabase, + query: String +): DatabaseExecuteSqlResponse { + val firstWord = query.trim().let { + val idx = it.indexOf(' ') + if (idx >= 0) it.substring(0, idx) else it + }.uppercase(Locale.getDefault()) + + return when (firstWord) { + "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(database, query) + "INSERT" -> executeInsert(database, query) + "UPDATE", "DELETE" -> executeUpdateDelete(database, query) + else -> executeRawQuery(database, query) + } +} + +private fun executeSelect( + database: SQLiteDatabase, + query: String, +): DatabaseExecuteSqlResponse { + val cursor: Cursor = database.rawQuery(query, null) + return try { + val columnNames = cursor.columnNames.toList() + val rows = mutableListOf>() + while (cursor.moveToNext()) { + val values = mutableListOf() + for (i in 0 until cursor.columnCount) { + values.add( + when (cursor.getType(i)) { + Cursor.FIELD_TYPE_NULL -> null + Cursor.FIELD_TYPE_INTEGER -> cursor.getLong(i).toString() + Cursor.FIELD_TYPE_FLOAT -> cursor.getDouble(i).toString() + Cursor.FIELD_TYPE_BLOB -> cursor.getBlob(i).toString() + else -> cursor.getString(i) + } + ) + } + rows.add(values) + } + DatabaseExecuteSqlResponse.Select(columns = columnNames, values = rows) + } finally { + cursor.close() + } +} + +private fun executeInsert( + database: SQLiteDatabase, + query: String, +): DatabaseExecuteSqlResponse { + val statement = database.compileStatement(query) + val insertedId: Long = statement.executeInsert() + return DatabaseExecuteSqlResponse.Insert(insertedId) +} + +private fun executeUpdateDelete( + database: SQLiteDatabase, + query: String, +): DatabaseExecuteSqlResponse { + val statement = database.compileStatement(query) + val count: Int = statement.executeUpdateDelete() + return DatabaseExecuteSqlResponse.UpdateDelete(count) +} + +private fun executeRawQuery( + database: SQLiteDatabase, + query: String, +): DatabaseExecuteSqlResponse { + database.execSQL(query) + return DatabaseExecuteSqlResponse.RawSuccess } \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt index 8415d9e79..53e00734b 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt @@ -2,7 +2,6 @@ package io.github.openflocon.flocon.database.core.datasource import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse -import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel interface FloconDatabaseDataSource { diff --git a/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt b/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt index b6b4286b7..3ec4ab462 100644 --- a/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt +++ b/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.ios.kt @@ -1,127 +1,3 @@ package io.github.openflocon.flocon.database.core -import androidx.sqlite.SQLiteConnection -import androidx.sqlite.driver.NativeSQLiteDriver -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel -import io.github.openflocon.flocon.database.core.model.FloconFileDatabaseModel -import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse -import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel -import platform.Foundation.NSFileManager - -internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { - return FloconDatabaseDataSourceIos(context) -} - -internal class FloconDatabaseDataSourceIos( - private val context: FloconContext -) : FloconDatabaseDataSource { - - override fun executeSQL( - registeredDatabases: List, - databaseName: String, - query: String - ): DatabaseExecuteSqlResponse { - val fileManager = NSFileManager.defaultManager - if (!fileManager.fileExistsAtPath(databaseName)) { - return DatabaseExecuteSqlResponse.Error( - message = "Database file not found: $databaseName", - originalSql = query - ) - } - - val driver = NativeSQLiteDriver() - val connection = driver.open(fileName = databaseName) - - return try { - val firstWord = getFirstWord(query).uppercase() - when (firstWord) { - "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(connection, query) - "INSERT" -> executeInsert(connection, query) - "UPDATE", "DELETE" -> executeUpdateDelete(connection, query) - else -> executeRawQuery(connection, query) - } - } catch (t: Throwable) { - DatabaseExecuteSqlResponse.Error( - message = t.message ?: "Error executing SQL", - originalSql = query - ) - } finally { - connection.close() - } - } - - override fun getAllDataBases( - registeredDatabases: List - ): List { - val fileManager = NSFileManager.defaultManager - return registeredDatabases.mapNotNull { - if(it is FloconFileDatabaseModel) { - if (fileManager.fileExistsAtPath(it.absolutePath)) { - DeviceDataBaseDataModel( - id = it.absolutePath, - name = it.displayName - ) - } else null - } else null - } - } -} - -// --- SQL execution helpers --- - -private fun executeSelect(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { - val cursor = connection.prepare(query).use { statement -> - val columnCount = statement.getColumnCount() - val columns = (0 until columnCount).map { statement.getColumnName(it) } - val rows = mutableListOf>() - - while (statement.step()) { - val row = (0 until columnCount).map { idx -> - statement.getText(idx) - } - rows.add(row) - } - - statement.close() // maybe remove - DatabaseExecuteSqlResponse.Select(columns, rows) - } - return cursor -} - -private fun executeUpdateDelete(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { - connection.prepare(query).use { statement -> - statement.close() - } - // sqlite-kt n'expose pas encore `changes()`, on renvoie 0 - return DatabaseExecuteSqlResponse.UpdateDelete(affectedCount = 0) -} - -private fun executeInsert(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { - connection.prepare(query).use { statement -> - statement.close() - } - - // Récupération du dernier ID inséré - var id = -1L - connection.prepare("SELECT last_insert_rowid()").use { -// id = if (it.step()) it.getLong(0) else -1L -// it.close() // maybe remove - } - - return DatabaseExecuteSqlResponse.Insert(id) -} - -private fun executeRawQuery(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { - connection.prepare(query).use { statement -> - statement.close() // maybe remove - } - return DatabaseExecuteSqlResponse.RawSuccess -} - -// --- Utilities --- -private fun getFirstWord(s: String): String { - val trimmed = s.trim() - val firstSpace = trimmed.indexOf(' ') - return if (firstSpace >= 0) trimmed.substring(0, firstSpace) else trimmed -} +// iOS implementation is in model/FloconDatabaseModel.ios.kt diff --git a/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.ios.kt b/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.ios.kt new file mode 100644 index 000000000..7b8ddc3d6 --- /dev/null +++ b/FloconAndroid/database/core/src/iosMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.ios.kt @@ -0,0 +1,75 @@ +package io.github.openflocon.flocon.database.core.model + +import androidx.sqlite.SQLiteConnection +import androidx.sqlite.driver.NativeSQLiteDriver +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse + +actual fun openDbAndExecuteQuery( + path: String, + query: String +): DatabaseExecuteSqlResponse { + val driver = NativeSQLiteDriver() + val connection = driver.open(fileName = path) + return try { + val firstWord = query.trim().let { + val idx = it.indexOf(' ') + if (idx >= 0) it.substring(0, idx) else it + }.uppercase() + + when (firstWord) { + "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(connection, query) + "INSERT" -> executeInsert(connection, query) + "UPDATE", "DELETE" -> executeUpdateDelete(connection, query) + else -> executeRawQuery(connection, query) + } + } catch (t: Throwable) { + DatabaseExecuteSqlResponse.Error( + message = t.message ?: "Error executing SQL", + originalSql = query + ) + } finally { + connection.close() + } +} + +// --- SQL execution helpers --- + +private fun executeSelect(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { + return connection.prepare(query).use { statement -> + val columnCount = statement.getColumnCount() + val columns = (0 until columnCount).map { statement.getColumnName(it) } + val rows = mutableListOf>() + + while (statement.step()) { + val row = (0 until columnCount).map { idx -> + if (statement.isNull(idx)) null else statement.getText(idx) + } + rows.add(row) + } + + DatabaseExecuteSqlResponse.Select(columns, rows) + } +} + +private fun executeInsert(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { + connection.prepare(query).use { it.step() } + + val id = connection.prepare("SELECT last_insert_rowid()").use { stmt -> + if (stmt.step()) stmt.getLong(0) else -1L + } + return DatabaseExecuteSqlResponse.Insert(id) +} + +private fun executeUpdateDelete(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { + connection.prepare(query).use { it.step() } + + val count = connection.prepare("SELECT changes()").use { stmt -> + if (stmt.step()) stmt.getLong(0).toInt() else 0 + } + return DatabaseExecuteSqlResponse.UpdateDelete(affectedCount = count) +} + +private fun executeRawQuery(connection: SQLiteConnection, query: String): DatabaseExecuteSqlResponse { + connection.prepare(query).use { it.step() } + return DatabaseExecuteSqlResponse.RawSuccess +} \ No newline at end of file diff --git a/FloconAndroid/database/core/src/jvmMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.jvm.kt b/FloconAndroid/database/core/src/jvmMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.jvm.kt index e0c25951c..fde7260cf 100644 --- a/FloconAndroid/database/core/src/jvmMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.jvm.kt +++ b/FloconAndroid/database/core/src/jvmMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabasePlugin.jvm.kt @@ -1,7 +1,89 @@ -package io.github.openflocon.flocon.database.core +package io.github.openflocon.flocon.database.core.model -import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse +import java.sql.Connection +import java.sql.DriverManager +import java.sql.ResultSet -internal actual fun buildFloconDatabaseDataSource(context: FloconContext): FloconDatabaseDataSource { - TODO("Not yet implemented") +actual fun openDbAndExecuteQuery( + path: String, + query: String +): DatabaseExecuteSqlResponse { + var connection: Connection? = null + return try { + Class.forName("org.sqlite.JDBC") + connection = DriverManager.getConnection("jdbc:sqlite:$path") + executeSQLInternal(connection, query) + } catch (t: Throwable) { + DatabaseExecuteSqlResponse.Error( + message = t.message ?: "error on executeSQL", + originalSql = query, + ) + } finally { + connection?.close() + } +} + +private fun executeSQLInternal( + connection: Connection, + query: String +): DatabaseExecuteSqlResponse { + val firstWord = query.trim().let { + val idx = it.indexOf(' ') + if (idx >= 0) it.substring(0, idx) else it + }.uppercase() + + return when (firstWord) { + "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(connection, query) + "INSERT" -> executeInsert(connection, query) + "UPDATE", "DELETE" -> executeUpdateDelete(connection, query) + else -> executeRawQuery(connection, query) + } +} + +private fun executeSelect( + connection: Connection, + query: String, +): DatabaseExecuteSqlResponse { + val statement = connection.createStatement() + val rs: ResultSet = statement.executeQuery(query) + val meta = rs.metaData + val columnCount = meta.columnCount + val columns = (1..columnCount).map { meta.getColumnName(it) } + val rows = mutableListOf>() + while (rs.next()) { + val row = (1..columnCount).map { i -> + rs.getString(i) + } + rows.add(row) + } + return DatabaseExecuteSqlResponse.Select(columns = columns, values = rows) +} + +private fun executeInsert( + connection: Connection, + query: String, +): DatabaseExecuteSqlResponse { + val statement = connection.createStatement() + statement.executeUpdate(query) + val keys: ResultSet = statement.generatedKeys + val insertedId = if (keys.next()) keys.getLong(1) else -1L + return DatabaseExecuteSqlResponse.Insert(insertedId) +} + +private fun executeUpdateDelete( + connection: Connection, + query: String, +): DatabaseExecuteSqlResponse { + val statement = connection.createStatement() + val count = statement.executeUpdate(query) + return DatabaseExecuteSqlResponse.UpdateDelete(count) +} + +private fun executeRawQuery( + connection: Connection, + query: String, +): DatabaseExecuteSqlResponse { + connection.createStatement().execute(query) + return DatabaseExecuteSqlResponse.RawSuccess } \ No newline at end of file diff --git a/FloconAndroid/database/room/src/androidMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.android.kt b/FloconAndroid/database/room/src/androidMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.android.kt index 68eeae3b9..2626606a4 100644 --- a/FloconAndroid/database/room/src/androidMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.android.kt +++ b/FloconAndroid/database/room/src/androidMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.android.kt @@ -1,9 +1,10 @@ package io.github.openflocon.flocon.database.room +import io.github.openflocon.flocon.Flocon import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.databasePlugin import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel import io.github.openflocon.flocon.database.core.model.FloconFileDatabaseModel -import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel import io.github.openflocon.flocon.dsl.FloconMarker import java.io.File @@ -14,7 +15,8 @@ internal actual class FloconRoomDatabaseProviderImpl actual constructor( ) : FloconRoomDatabaseProvider { actual override fun register() { - TODO("Not yet implemented") + val databases = getAllDataBases(emptyList()) + databases.forEach { Flocon.databasePlugin.register(it) } } @FloconMarker diff --git a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt index 632ce7a9e..ce1ad90c5 100644 --- a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt +++ b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseModel.kt @@ -105,9 +105,6 @@ private suspend fun executeInsert( query: String, ): DatabaseExecuteSqlResponse { connection.execSQL(query) - // SQLite doesn't easily return the last inserted ID via the statement itself without extra queries like last_insert_rowid() - // But for inspection purposes, we might just return 0 or query it. - // For now, let's just return a successful RawSuccess or implement last_insert_rowid val id = connection.usePrepared("SELECT last_insert_rowid()") { it.step(); it.getLong(0) } return DatabaseExecuteSqlResponse.Insert(id) } diff --git a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt index 7982aeeac..112a4ee42 100644 --- a/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt +++ b/FloconAndroid/database/room/src/commonMain/kotlin/io/github/openflocon/flocon/database/room/FloconRoomDatabaseProviderImpl.kt @@ -9,7 +9,6 @@ import io.github.openflocon.flocon.dsl.FloconMarker interface FloconRoomDatabaseProvider : FloconDatabaseProvider { - // TODO fun register() } diff --git a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt b/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt deleted file mode 100644 index fce42a575..000000000 --- a/FloconAndroid/database/room/src/main/java/io/github/openflocon/flocon/database/room/FloconDatabasePlugin.android.kt +++ /dev/null @@ -1,231 +0,0 @@ -package io.github.openflocon.flocon.database.room - -import android.content.Context -import android.database.Cursor -import android.database.sqlite.SQLiteDatabase -import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseDataSource -import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel -import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse -import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse -import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel -import java.io.File -import java.util.Locale - -interface FloconAndroidSqlDatabaseModel : FloconDatabaseModel { - val database: SQLiteDatabase - - - override suspend fun executeQuery(query: String): DatabaseExecuteResponse { - return executeSQLInternal(database, query) - } -} - -internal class FloconDatabaseDataSourceAndroid(private val context: Context) : - FloconDatabaseDataSource { - - private val MAX_DEPTH = 7 - - override suspend fun executeQuery( - registeredDatabases: List, - databaseName: String, - query: String - ): DatabaseExecuteResponse? { - val databaseModel = registeredDatabases.find { it.displayName == databaseName } - return when (databaseModel) { - is FloconAndroidSqlDatabaseModel -> { - executeSQLInternal( - database = databaseModel.database, - query = query, - ) - } - - else -> openDbAndExecuteQuery( - databaseName = databaseName, - query = query, - ) - } - } - - private fun openDbAndExecuteQuery( - databaseName: String, - query: String - ): DatabaseExecuteSqlResponse { - var database: SQLiteDatabase? = null - return try { - val path = context.getDatabasePath(databaseName) - database = SQLiteDatabase.openDatabase( - path.absolutePath, - null, - SQLiteDatabase.OPEN_READWRITE - ) - - executeSQLInternal( - database = database, - query = query, - ) - } catch (t: Throwable) { - DatabaseExecuteSqlResponse.Error( - message = t.message ?: "error on executeSQL", - originalSql = query, - ) - } finally { - database?.close() - } - } - - override fun getAllDataBases(registeredDatabases: List): List { - val databasesDir = context.getDatabasePath("dummy_db").parentFile ?: return emptyList() - - val foundDatabases = mutableListOf() - // Start the recursive search from the base databases directory - scanDirectoryForDatabases( - directory = databasesDir, - depth = 0, - foundDatabases = foundDatabases - ) - - return foundDatabases - } - - private fun scanDirectoryForDatabases( - directory: File, - depth: Int, - foundDatabases: MutableList - ) { - if (depth >= MAX_DEPTH) { - return - } - directory.listFiles()?.forEach { file -> - if (file.isDirectory) { - // If it's a directory, recursively call this function - scanDirectoryForDatabases( - directory = file, - depth = depth + 1, - foundDatabases = foundDatabases, - ) - } else { - // If it's a file, check if it's a database file - if (file.isFile && - !file.name.endsWith("-wal") && // Write-Ahead Log - !file.name.endsWith("-shm") && // Shared-Memory - !file.name.endsWith("-journal") // Older journaling mode - ) { - foundDatabases.add( - DeviceDataBaseDataModel( - id = file.absolutePath, // Use absolute path for unique ID - name = file.name, - ) - ) - } - } - } - } -} - -private fun executeSQLInternal( - database: SQLiteDatabase, - query: String -): DatabaseExecuteSqlResponse { - return try { - val firstWordUpperCase = getFirstWord(query).uppercase(Locale.getDefault()) - when (firstWordUpperCase) { - "UPDATE", "DELETE" -> executeUpdateDelete(database, query) - "INSERT" -> executeInsert(database, query) - "SELECT", "PRAGMA", "EXPLAIN" -> executeSelect(database, query) - else -> executeRawQuery(database, query) - } - } catch (t: Throwable) { - DatabaseExecuteSqlResponse.Error( - message = t.message ?: "error on executeSQL", - originalSql = query, - ) - } -} - -private fun executeSelect( - database: SQLiteDatabase, - query: String, -): DatabaseExecuteSqlResponse { - val cursor: Cursor = database.rawQuery(query, null) - try { - val columnNames = cursor.columnNames.toList() - val rows = cursorToList(cursor) - return DatabaseExecuteSqlResponse.Select( - columns = columnNames, - values = rows, - ) - } finally { - cursor.close() - } -} - -private fun executeUpdateDelete( - database: SQLiteDatabase, - query: String, -): DatabaseExecuteSqlResponse { - val statement = database.compileStatement(query) - val count: Int = statement.executeUpdateDelete() - return DatabaseExecuteSqlResponse.UpdateDelete(count) -} - -private fun executeInsert( - database: SQLiteDatabase, - query: String, -): DatabaseExecuteSqlResponse { - val statement = database.compileStatement(query) - val insertedId: Long = statement.executeInsert() - return DatabaseExecuteSqlResponse.Insert(insertedId) -} - -private fun executeRawQuery( - database: SQLiteDatabase, - query: String, -): DatabaseExecuteSqlResponse { - database.execSQL(query) - return DatabaseExecuteSqlResponse.RawSuccess -} - -private fun getFirstWord(s: String): String { - var s = s - s = s.trim { it <= ' ' } - val firstSpace = s.indexOf(' ') - return if (firstSpace >= 0) s.substring(0, firstSpace) else s -} - -private fun cursorToList(cursor: Cursor): List> { - val rows = mutableListOf>() - val numColumns = cursor.columnCount - while (cursor.moveToNext()) { - val values = mutableListOf() - for (column in 0.. null - Cursor.FIELD_TYPE_INTEGER -> cursor.getLong(column).toString() - Cursor.FIELD_TYPE_FLOAT -> cursor.getDouble(column).toString() - Cursor.FIELD_TYPE_BLOB -> cursor.getBlob(column).toString() - Cursor.FIELD_TYPE_STRING -> cursor.getString(column).toString() - else -> cursor.getString(column) - } -} - -private fun getDatabaseVersion( - path: String, -): Int { - return SQLiteDatabase.openDatabase( - path, - null, - SQLiteDatabase.OPEN_READONLY - ).use { db -> - db.rawQuery("PRAGMA user_version", null).use { cursor -> - if (cursor.moveToFirst()) cursor.getInt(0) else 0 - } - } -} From 62c0bebfe3689d5af7ea195f1d52ec3e184ec9ba Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 25 Mar 2026 13:28:59 +0100 Subject: [PATCH 18/35] fix: Remove useless file --- .../datasource/FloconDatabaseDataSource.kt | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt deleted file mode 100644 index 53e00734b..000000000 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/datasource/FloconDatabaseDataSource.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.github.openflocon.flocon.database.core.datasource - -import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel -import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse -import io.github.openflocon.flocon.database.core.model.fromdevice.sql.DeviceDataBaseDataModel - -interface FloconDatabaseDataSource { - - suspend fun executeQuery( - registeredDatabases: List, - databaseName: String, - query: String - ): DatabaseExecuteResponse? - - fun getAllDataBases( - registeredDatabases: List - ): List - -} \ No newline at end of file From 2688a2430e3f283533f2bb31bcd430c6c6970c96 Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 25 Mar 2026 15:40:44 +0100 Subject: [PATCH 19/35] feat: Add room3 --- .../database/room3-no-op/build.gradle.kts | 106 ++++++++++++++ .../database/room3/floconRegisterDatabase.kt | 9 ++ .../database/room3/floconRegisterDatabase.kt | 9 ++ FloconAndroid/database/room3/build.gradle.kts | 121 ++++++++++++++++ ...FloconRoom3DatabaseProviderImpl.android.kt | 77 ++++++++++ .../room3/FloconRoom3DatabaseConfig.kt | 25 ++++ .../room3/FloconRoom3DatabaseModel.kt | 133 ++++++++++++++++++ .../room3/FloconRoom3DatabaseProviderImpl.kt | 29 ++++ .../FloconRoom3DatabaseProviderImpl.ios.kt | 24 ++++ .../FloconRoom3DatabaseProviderImpl.jvm.kt | 24 ++++ .../room3/extensions/Room3BuilderExt.kt | 15 ++ FloconAndroid/flocon/build.gradle.kts | 1 + .../io/github/openflocon/flocon/FloconCore.kt | 1 - .../plugins/files/FloconFilesPlugin.ios.kt | 2 + .../flocon/websocket/FloconHttpClient.ios.kt | 3 + FloconAndroid/gradle/libs.versions.toml | 3 + .../sample-android-only/build.gradle.kts | 2 + FloconAndroid/settings.gradle.kts | 2 + 18 files changed, 585 insertions(+), 1 deletion(-) create mode 100644 FloconAndroid/database/room3-no-op/build.gradle.kts create mode 100644 FloconAndroid/database/room3-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt create mode 100644 FloconAndroid/database/room3-no-op/src/main/java/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt create mode 100644 FloconAndroid/database/room3/build.gradle.kts create mode 100644 FloconAndroid/database/room3/src/androidMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.android.kt create mode 100644 FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseConfig.kt create mode 100644 FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseModel.kt create mode 100644 FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.kt create mode 100644 FloconAndroid/database/room3/src/iosMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.ios.kt create mode 100644 FloconAndroid/database/room3/src/jvmMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.jvm.kt create mode 100644 FloconAndroid/database/room3/src/main/java/io/github/openflocon/flocon/database/room3/extensions/Room3BuilderExt.kt diff --git a/FloconAndroid/database/room3-no-op/build.gradle.kts b/FloconAndroid/database/room3-no-op/build.gradle.kts new file mode 100644 index 000000000..5c3db1e82 --- /dev/null +++ b/FloconAndroid/database/room3-no-op/build.gradle.kts @@ -0,0 +1,106 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":database:core-no-op")) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +android { + namespace = "io.github.openflocon.flocon.database.room3.noop" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-database-room3-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Room 3 Implementation No-Op" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/database/room3-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt b/FloconAndroid/database/room3-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt new file mode 100644 index 000000000..e5f4b0a89 --- /dev/null +++ b/FloconAndroid/database/room3-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.database.room3 + +fun floconRegisterDatabase(displayName: String, database: Any) { + // no op +} + +fun floconRegisterDatabase(displayName: String, openHelper: Any, dummy: Boolean = true) { + // no op +} diff --git a/FloconAndroid/database/room3-no-op/src/main/java/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt b/FloconAndroid/database/room3-no-op/src/main/java/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt new file mode 100644 index 000000000..e5f4b0a89 --- /dev/null +++ b/FloconAndroid/database/room3-no-op/src/main/java/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.database.room3 + +fun floconRegisterDatabase(displayName: String, database: Any) { + // no op +} + +fun floconRegisterDatabase(displayName: String, openHelper: Any, dummy: Boolean = true) { + // no op +} diff --git a/FloconAndroid/database/room3/build.gradle.kts b/FloconAndroid/database/room3/build.gradle.kts new file mode 100644 index 000000000..99e8d69c1 --- /dev/null +++ b/FloconAndroid/database/room3/build.gradle.kts @@ -0,0 +1,121 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) + alias(libs.plugins.androidx.room) + alias(libs.plugins.ksp) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(project(":database:core")) + implementation(libs.androidx.room3.runtime) + implementation(libs.androidx.sqlite.bundled) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +room { + schemaDirectory("$projectDir/schemas") +} + +dependencies { + // KSP for Room + add("kspCommonMainMetadata", libs.androidx.room3.compiler) + add("kspAndroid", libs.androidx.room3.compiler) + add("kspJvm", libs.androidx.room3.compiler) + add("kspIosArm64", libs.androidx.room3.compiler) + add("kspIosSimulatorArm64", libs.androidx.room3.compiler) +} + +android { + namespace = "io.github.openflocon.flocon.database.room3" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-database-room3", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Room 3 Implementation" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/database/room3/src/androidMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.android.kt b/FloconAndroid/database/room3/src/androidMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.android.kt new file mode 100644 index 000000000..4dcc4d16b --- /dev/null +++ b/FloconAndroid/database/room3/src/androidMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.android.kt @@ -0,0 +1,77 @@ +package io.github.openflocon.flocon.database.room3 + +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.databasePlugin +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.FloconFileDatabaseModel +import io.github.openflocon.flocon.dsl.FloconMarker +import java.io.File + +@OptIn(markerClass = [FloconMarker::class]) +internal actual class FloconRoom3DatabaseProviderImpl actual constructor( + private val context: FloconContext, + paths: List +) : FloconRoom3DatabaseProvider { + + actual override fun register() { + val databases = getAllDataBases(emptyList()) + databases.forEach { Flocon.databasePlugin.register(it) } + } + + @FloconMarker + actual override fun getAllDataBases(registeredDatabases: List): List { + val databasesDir = context.context.getDatabasePath("dummy_db") + .parentFile + ?: return emptyList() + + val foundDatabases = mutableListOf() + // Start the recursive search from the base databases directory + scanDirectoryForDatabases( + directory = databasesDir, + depth = 0, + foundDatabases = foundDatabases + ) + + return foundDatabases + } + + private fun scanDirectoryForDatabases( + directory: File, + depth: Int, + foundDatabases: MutableList + ) { + if (depth >= MAX_DEPTH) { + return + } + directory.listFiles()?.forEach { file -> + if (file.isDirectory) { + // If it's a directory, recursively call this function + scanDirectoryForDatabases( + directory = file, + depth = depth + 1, + foundDatabases = foundDatabases, + ) + } else { + // If it's a file, check if it's a database file + if (file.isFile && + !file.name.endsWith("-wal") && // Write-Ahead Log + !file.name.endsWith("-shm") && // Shared-Memory + !file.name.endsWith("-journal") // Older journaling mode + ) { + foundDatabases.add( + FloconFileDatabaseModel( + id = file.absolutePath, // Use absolute path for unique ID + displayName = file.name, + absolutePath = file.absolutePath + ) + ) + } + } + } + } + + companion object { + private const val MAX_DEPTH = 7 + } +} \ No newline at end of file diff --git a/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseConfig.kt b/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseConfig.kt new file mode 100644 index 000000000..fd361d636 --- /dev/null +++ b/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseConfig.kt @@ -0,0 +1,25 @@ +package io.github.openflocon.flocon.database.room3 + +import io.github.openflocon.flocon.database.core.FloconDatabaseConfig +import io.github.openflocon.flocon.dsl.FloconMarker + +class FloconRoom3DatabaseConfig internal constructor() { + internal val paths: MutableList = mutableListOf() + + fun path(path: String) { + paths.add(path) + } + +} + +@OptIn(FloconMarker::class) +fun FloconDatabaseConfig.room(block: FloconRoom3DatabaseConfig.() -> Unit = {}) { + val config = FloconRoom3DatabaseConfig().apply(block) + + providers.add( + FloconRoom3DatabaseProviderImpl( + context = context, + paths = config.paths + ) + ) +} \ No newline at end of file diff --git a/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseModel.kt b/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseModel.kt new file mode 100644 index 000000000..b811ac716 --- /dev/null +++ b/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseModel.kt @@ -0,0 +1,133 @@ +package io.github.openflocon.flocon.database.room3 + +import androidx.room3.RoomDatabase +import androidx.room3.Transactor +import androidx.room3.executeSQL +import androidx.room3.useReaderConnection +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.database.core.databasePlugin +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse + +fun floconRegisterDatabase(displayName: String, database: RoomDatabase) { + Flocon.databasePlugin.register( + FloconRoom3DatabaseModel( + id = displayName, + displayName = displayName, + database = database + ) + ) +} + +fun floconLogDatabaseQuery(databaseName: String, sqlQuery: String, bindArgs: List) { + Flocon.databasePlugin.logQuery( + dbName = databaseName, + sqlQuery = sqlQuery, + bindArgs = bindArgs, + ) +} + +internal data class FloconRoom3DatabaseModel( + override val id: String, + override val displayName: String, + val database: RoomDatabase +) : FloconDatabaseModel { + + override suspend fun executeQuery(query: String): DatabaseExecuteResponse { + return try { + database.useReaderConnection { connection -> + val firstWordUpperCase = getFirstWord(query).uppercase() + + when (firstWordUpperCase) { + "SELECT", + "PRAGMA", + "EXPLAIN" -> executeSelect( + connection = connection, + query = query + ) + + "INSERT" -> executeInsert( + connection = connection, + query = query + ) + + "UPDATE", + "DELETE" -> executeUpdateDelete( + connection = connection, + query = query + ) + + else -> executeRawQuery( + connection = connection, + query = query + ) + } + } + } catch (t: Throwable) { + DatabaseExecuteSqlResponse.Error( + message = t.message ?: "error on executeSQL", + originalSql = query, + ) + } + } +} + +private suspend fun executeSelect( + connection: Transactor, + query: String, +): DatabaseExecuteSqlResponse { + return connection.usePrepared(query) { statement -> + val columnNames = mutableListOf() + val columnCount = statement.getColumnCount() + for (i in 0 until columnCount) { + columnNames.add(statement.getColumnName(i)) + } + + val rows = mutableListOf>() + while (statement.step()) { + val values = mutableListOf() + for (i in 0 until columnCount) { + values.add(if (statement.isNull(i)) null else statement.getText(i)) + } + rows.add(values) + } + + DatabaseExecuteSqlResponse.Select( + columns = columnNames, + values = rows + ) + } +} + +private suspend fun executeInsert( + connection: Transactor, + query: String, +): DatabaseExecuteSqlResponse { + connection.executeSQL(query) + val id = connection.usePrepared("SELECT last_insert_rowid()") { it.step(); it.getLong(0) } + return DatabaseExecuteSqlResponse.Insert(id) +} + +private suspend fun executeUpdateDelete( + connection: Transactor, + query: String, +): DatabaseExecuteSqlResponse { + connection.executeSQL(query) + val count = connection.usePrepared("SELECT changes()") { it.step(); it.getLong(0).toInt() } + return DatabaseExecuteSqlResponse.UpdateDelete(count) +} + +private suspend fun executeRawQuery( + connection: Transactor, + query: String, +): DatabaseExecuteSqlResponse { + connection.executeSQL(query) + return DatabaseExecuteSqlResponse.RawSuccess +} + +private fun getFirstWord(s: String): String { + val trimmed = s.trim() + val firstSpace = trimmed.indexOf(' ') + return if (firstSpace >= 0) trimmed.substring(0, firstSpace) else trimmed +} \ No newline at end of file diff --git a/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.kt b/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.kt new file mode 100644 index 000000000..0c5fa278b --- /dev/null +++ b/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.kt @@ -0,0 +1,29 @@ +package io.github.openflocon.flocon.database.room3 + +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.databasePlugin +import io.github.openflocon.flocon.database.core.datasource.FloconDatabaseProvider +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.dsl.FloconMarker + +interface FloconRoom3DatabaseProvider : FloconDatabaseProvider { + + fun register() + +} + +@OptIn(FloconMarker::class) +internal expect class FloconRoom3DatabaseProviderImpl( + context: FloconContext, + paths: List +) : FloconRoom3DatabaseProvider { + override fun register() + override fun getAllDataBases(registeredDatabases: List): List +} + +@OptIn(FloconMarker::class) +val Flocon.Companion.databaseRoom3: FloconRoom3DatabaseProvider + get() = databasePlugin.providers + .firstNotNullOfOrNull { it as? FloconRoom3DatabaseProvider } + ?: error("Room3 database provider not initialized") \ No newline at end of file diff --git a/FloconAndroid/database/room3/src/iosMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.ios.kt b/FloconAndroid/database/room3/src/iosMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.ios.kt new file mode 100644 index 000000000..4d0537c54 --- /dev/null +++ b/FloconAndroid/database/room3/src/iosMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.ios.kt @@ -0,0 +1,24 @@ +package io.github.openflocon.flocon.database.room3 + +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.databasePlugin +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.dsl.FloconMarker + +@OptIn(markerClass = [FloconMarker::class]) +internal actual class FloconRoom3DatabaseProviderImpl actual constructor( + private val context: FloconContext, + paths: List +) : FloconRoom3DatabaseProvider { + + actual override fun register() { + val databases = getAllDataBases(emptyList()) + databases.forEach { Flocon.databasePlugin.register(it) } + } + + @FloconMarker + actual override fun getAllDataBases(registeredDatabases: List): List { + return emptyList() + } +} diff --git a/FloconAndroid/database/room3/src/jvmMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.jvm.kt b/FloconAndroid/database/room3/src/jvmMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.jvm.kt new file mode 100644 index 000000000..4d0537c54 --- /dev/null +++ b/FloconAndroid/database/room3/src/jvmMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.jvm.kt @@ -0,0 +1,24 @@ +package io.github.openflocon.flocon.database.room3 + +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.databasePlugin +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.dsl.FloconMarker + +@OptIn(markerClass = [FloconMarker::class]) +internal actual class FloconRoom3DatabaseProviderImpl actual constructor( + private val context: FloconContext, + paths: List +) : FloconRoom3DatabaseProvider { + + actual override fun register() { + val databases = getAllDataBases(emptyList()) + databases.forEach { Flocon.databasePlugin.register(it) } + } + + @FloconMarker + actual override fun getAllDataBases(registeredDatabases: List): List { + return emptyList() + } +} diff --git a/FloconAndroid/database/room3/src/main/java/io/github/openflocon/flocon/database/room3/extensions/Room3BuilderExt.kt b/FloconAndroid/database/room3/src/main/java/io/github/openflocon/flocon/database/room3/extensions/Room3BuilderExt.kt new file mode 100644 index 000000000..2b0f27d8f --- /dev/null +++ b/FloconAndroid/database/room3/src/main/java/io/github/openflocon/flocon/database/room3/extensions/Room3BuilderExt.kt @@ -0,0 +1,15 @@ +package io.github.openflocon.flocon.database.room3.extensions + +import androidx.room3.RoomDatabase +import java.util.concurrent.Executor +import java.util.concurrent.Executors + +inline fun RoomDatabase.Builder.floconLogs( + name: String? = T::class.simpleName, + executor: Executor = Executors.newSingleThreadExecutor(), + // QueryCallback is removed or altered in Room 3. + queryCallback: Any? = null +): RoomDatabase.Builder { + // TODO: Room 3 removed or changed QueryCallback. Logging must be rewritten for Room 3. + return this +} \ No newline at end of file diff --git a/FloconAndroid/flocon/build.gradle.kts b/FloconAndroid/flocon/build.gradle.kts index 3c5e9f5ad..98d34f6df 100644 --- a/FloconAndroid/flocon/build.gradle.kts +++ b/FloconAndroid/flocon/build.gradle.kts @@ -70,6 +70,7 @@ kotlin { // to store the device id implementation("com.russhwolf:multiplatform-settings:1.3.0") + implementation(libs.androidx.sqlite.bundled) } } } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt index a834ef254..946b32851 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconCore.kt @@ -1,5 +1,4 @@ package io.github.openflocon.flocon -expect class FloconContext internal expect fun displayClearTextError(context: FloconContext) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.ios.kt b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.ios.kt index ffa1dbc9a..1c7d1ef58 100644 --- a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.ios.kt +++ b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.ios.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocon.plugins.files import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconFile +import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.plugins.files.model.fromdevice.FileDataModel internal actual fun fileDataSource(context: FloconContext): FileDataSource { @@ -9,6 +10,7 @@ internal actual fun fileDataSource(context: FloconContext): FileDataSource { } // TODO +@io.github.openflocon.flocon.dsl.FloconMarker internal class FileDataSourceIOs : FileDataSource { override fun getFile( path: String, diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.ios.kt b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.ios.kt index cd9fa5333..690d060fa 100644 --- a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.ios.kt +++ b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.ios.kt @@ -13,10 +13,13 @@ import io.ktor.http.HttpHeaders import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json +import io.github.openflocon.flocon.dsl.FloconMarker + internal actual fun buildFloconHttpClient(): FloconHttpClient { return FloconHttpClientIOs() } +@io.github.openflocon.flocon.dsl.FloconMarker internal class FloconHttpClientIOs() : FloconHttpClient { // client configurable selon la plateforme (Android, iOS, JVM, etc.) diff --git a/FloconAndroid/gradle/libs.versions.toml b/FloconAndroid/gradle/libs.versions.toml index f65bafb13..c8aafb267 100644 --- a/FloconAndroid/gradle/libs.versions.toml +++ b/FloconAndroid/gradle/libs.versions.toml @@ -93,6 +93,9 @@ androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = " androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } androidx-room-sqlite-wrapper = { module = "androidx.room:room-sqlite-wrapper", version.ref = "room" } +androidx-room3-runtime = { module = "androidx.room3:room3-runtime", version = "3.0.0-alpha01" } +androidx-room3-compiler = { module = "androidx.room3:room3-compiler", version = "3.0.0-alpha01" } + [plugins] android-application = { id = "com.android.application", version.ref = "agp" } androidx-room = { id = "androidx.room", version.ref = "room" } diff --git a/FloconAndroid/sample-android-only/build.gradle.kts b/FloconAndroid/sample-android-only/build.gradle.kts index e136cdea7..e16ed5784 100644 --- a/FloconAndroid/sample-android-only/build.gradle.kts +++ b/FloconAndroid/sample-android-only/build.gradle.kts @@ -90,6 +90,8 @@ dependencies { debugImplementation(project(":database:room")) releaseImplementation(project(":database:room-no-op")) + debugImplementation(project(":database:room3")) + releaseImplementation(project(":database:room3-no-op")) debugImplementation(project(":network:okhttp-interceptor")) releaseImplementation(project(":network:okhttp-interceptor-no-op")) diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index 1a9e42680..748d46048 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -37,3 +37,5 @@ include(":database:core") include(":database:core-no-op") include(":database:room") include(":database:room-no-op") +include(":database:room3") +include(":database:room3-no-op") From e826685568230b2618c4b4e760899ed7a8fd009a Mon Sep 17 00:00:00 2001 From: doTTTTT Date: Sun, 5 Apr 2026 22:04:31 +0200 Subject: [PATCH 20/35] fix: Build --- .../deeplinks/FloconDeeplinkEncoding.kt | 18 +++++++ .../plugins/deeplinks/FloconDeeplinks.kt | 23 +++++++-- .../deeplinks/FloconDeeplinksConfig.kt | 37 ++++++++++++++ .../deeplinks/FloconDeeplinksPlugin.kt | 49 ++----------------- .../flocon/plugins/deeplinks/Mapping.kt | 39 ++++++++++++--- .../plugins/deeplinks/model/DeeplinkModel.kt | 24 ++++++--- .../deeplinks/model/DeeplinksRemote.kt | 47 +++++++++++++++--- .../openflocon/flocon/core/FloconEncoder.kt | 8 +-- .../flocon/myapplication/MainActivity.kt | 19 ++++--- 9 files changed, 179 insertions(+), 85 deletions(-) create mode 100644 FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinkEncoding.kt create mode 100644 FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksConfig.kt diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinkEncoding.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinkEncoding.kt new file mode 100644 index 000000000..45f898644 --- /dev/null +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinkEncoding.kt @@ -0,0 +1,18 @@ +package io.github.openflocon.flocon.plugins.deeplinks + +import io.github.openflocon.flocon.FloconEncoding +import io.github.openflocon.flocon.dsl.FloconMarker +import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkParameterRemote +import kotlinx.serialization.modules.SerializersModule +import kotlinx.serialization.modules.polymorphic +import kotlinx.serialization.modules.subclass + +@FloconMarker +internal class FloconDeeplinkEncoding : FloconEncoding { + override val serializersModule: SerializersModule = SerializersModule { + polymorphic(DeeplinkParameterRemote::class) { + subclass(DeeplinkParameterRemote.AutoComplete::class) + subclass(DeeplinkParameterRemote.Variable::class) + } + } +} \ No newline at end of file diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt index 6caacd52c..83c8ef103 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocon.plugins.deeplinks import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconEncoding import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginFactory @@ -13,7 +14,11 @@ import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel object FloconDeeplinks : FloconPluginFactory { override val name: String = "Deeplinks" override val pluginId: String = FloconDeeplinks::class.simpleName!! - override fun createConfig(context: FloconContext) = FloconDeeplinksConfig() + override fun createConfig(context: FloconContext): FloconDeeplinksConfig = + FloconDeeplinksConfigImpl() + + @FloconMarker + override fun createEncoding(): FloconEncoding = FloconDeeplinkEncoding() @OptIn(FloconMarker::class) override fun install( @@ -21,7 +26,8 @@ object FloconDeeplinks : FloconPluginFactory, + private val variables: List, private val sender: FloconMessageSender, ) : FloconPlugin, FloconDeeplinksPlugin { override val key: String = "DEEP_LINK" @@ -43,15 +50,21 @@ internal class FloconDeeplinksPluginImpl( } override suspend fun onConnectedToServer() { - registerDeeplinks(deeplinks) + registerDeeplinks( + deeplinks = deeplinks, + variables = variables + ) } - override suspend fun registerDeeplinks(deeplinks: List) { + suspend fun registerDeeplinks( + deeplinks: List, + variables: List + ) { try { sender.send( plugin = Protocol.FromDevice.Deeplink.Plugin, method = Protocol.FromDevice.Deeplink.Method.GetDeeplinks, - body = toDeeplinksJson(deeplinks) + body = createJson(deeplinks = deeplinks, variables = variables) ) } catch (t: Throwable) { t.printStackTrace() diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksConfig.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksConfig.kt new file mode 100644 index 000000000..7dd0e694c --- /dev/null +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksConfig.kt @@ -0,0 +1,37 @@ +package io.github.openflocon.flocon.plugins.deeplinks + +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel + +abstract class FloconDeeplinksConfig : FloconPluginConfig { + abstract fun variable(name: String, block: DeeplinkVariableBuilder.() -> Unit = {}) + + abstract fun deeplink(link: String, block: DeeplinkLinkBuilder.() -> Unit = {}) + + internal abstract fun deeplinks(): List + internal abstract fun variables(): List +} + +internal class FloconDeeplinksConfigImpl internal constructor() : FloconDeeplinksConfig() { + + private val variables = mutableListOf() + private val deeplinks = mutableListOf() + + override fun variable(name: String, block: DeeplinkVariableBuilder.() -> Unit) { + val variable = DeeplinkVariableBuilder(name).apply(block) + .build() + + variables.add(variable) + } + + override fun deeplink(link: String, block: DeeplinkLinkBuilder.() -> Unit) { + val deeplink = DeeplinkLinkBuilder(link).apply(block) + .build() + + deeplinks.add(deeplink) + } + + override fun deeplinks(): List = deeplinks.toList() + override fun variables(): List = variables.toList() + +} \ No newline at end of file diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt index 337106b29..2369b1f7f 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt @@ -1,7 +1,6 @@ package io.github.openflocon.flocon.plugins.deeplinks import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel class DeeplinkLinkBuilder internal constructor( @@ -14,14 +13,14 @@ class DeeplinkLinkBuilder internal constructor( infix fun String.withAutoComplete(suggestions: List) { parameters[this] = DeeplinkModel.Parameter.AutoComplete( - paramName = this, - suggestions.distinct() + name = this, + autoComplete = suggestions.distinct() ) } infix fun String.withVariable(variableName: String) { parameters[this] = DeeplinkModel.Parameter.Variable( - paramName = this, + name = this, variableName = variableName ) } @@ -70,44 +69,4 @@ data class DeeplinkVariable( } -class DeeplinkBuilder { - private val variables = mutableListOf() - private val deeplinks = mutableListOf() - - fun variable(name: String, block: DeeplinkVariableBuilder.() -> Unit = {}) { - val variable = DeeplinkVariableBuilder(name).apply(block) - .build() - - variables.add(variable) - } - - fun deeplink(link: String, block: DeeplinkLinkBuilder.() -> Unit = {}) { - val deeplink = DeeplinkLinkBuilder(link).apply(block) - .build() - - deeplinks.add(deeplink) - } - - internal fun deeplinks(): List = deeplinks.toList() - internal fun variables(): List = variables.toList() -} - -fun FloconApp.deeplinks(deeplinksBlock: DeeplinkBuilder.() -> Unit) { - this.client?.deeplinksPlugin?.let { - val builder = DeeplinkBuilder().apply(deeplinksBlock) - - it.registerDeeplinks( - deeplinks = builder.deeplinks(), - variables = builder.variables() - ) - } -} - -interface FloconDeeplinksPlugin { - - fun registerDeeplinks( - deeplinks: List, - variables: List - ) - -} \ No newline at end of file +interface FloconDeeplinksPlugin : FloconPlugin \ No newline at end of file diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt index dd57bb442..02627c180 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt @@ -4,11 +4,18 @@ import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkParameterRemote import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkRemote +import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkVariableRemote import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinksRemote -import kotlinx.serialization.encodeToString -internal fun toDeeplinksJson(deeplinks: List): String { - val dto = DeeplinksRemote(deeplinks.map { it.toRemote() }) +internal fun createJson( + deeplinks: List, + variables: List +): String { + val dto = DeeplinksRemote( + deeplinks = deeplinks.map(DeeplinkModel::toRemote), + variables = variables.map(DeeplinkVariable::toRemote) + ) + return FloconEncoder.json.encodeToString(dto) } @@ -19,7 +26,27 @@ internal fun DeeplinkModel.toRemote(): DeeplinkRemote = DeeplinkRemote( parameters = parameters.map { it.toRemote() } ) -internal fun DeeplinkModel.Parameter.toRemote(): DeeplinkParameterRemote = DeeplinkParameterRemote( - paramName = paramName, - autoComplete = autoComplete +internal fun DeeplinkModel.Parameter.toRemote(): DeeplinkParameterRemote = when (this) { + is DeeplinkModel.Parameter.AutoComplete -> DeeplinkParameterRemote.AutoComplete( + name = name, + autoComplete = autoComplete + ) + + is DeeplinkModel.Parameter.Variable -> DeeplinkParameterRemote.Variable( + name = name, + variableName = variableName + ) +} + +internal fun DeeplinkVariable.toRemote() = DeeplinkVariableRemote( + name = name, + mode = mode.toRemote() ) + +internal fun DeeplinkVariable.Mode.toRemote() = when (this) { + is DeeplinkVariable.Mode.AutoComplete -> DeeplinkVariableRemote.Mode.AutoComplete( + suggestions = suggestions + ) + + DeeplinkVariable.Mode.Input -> DeeplinkVariableRemote.Mode.Input +} \ No newline at end of file diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt index bf521ba14..1578513e1 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt @@ -1,13 +1,25 @@ package io.github.openflocon.flocon.plugins.deeplinks.model -data class DeeplinkModel( +@ConsistentCopyVisibility +data class DeeplinkModel internal constructor( val link: String, val label: String? = null, val description: String? = null, - val parameters: List, + val parameters: List ) { - data class Parameter( - val paramName: String, - val autoComplete: List, - ) + sealed interface Parameter { + val name: String + + @ConsistentCopyVisibility + data class AutoComplete internal constructor( + override val name: String, + val autoComplete: List + ) : Parameter + + @ConsistentCopyVisibility + data class Variable internal constructor( + override val name: String, + val variableName: String + ) : Parameter + } } diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt index 06cd4cf38..1c9e7a37e 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt @@ -1,12 +1,8 @@ package io.github.openflocon.flocon.plugins.deeplinks.model +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable - -@Serializable -internal class DeeplinkParameterRemote( - val paramName: String, - val autoComplete: List, -) +import kotlinx.serialization.json.JsonClassDiscriminator @Serializable internal class DeeplinkRemote( @@ -19,4 +15,43 @@ internal class DeeplinkRemote( @Serializable internal class DeeplinksRemote( val deeplinks: List, + val variables: List ) + +@Serializable +internal data class DeeplinkVariableRemote( + val name: String, + val mode: Mode = Mode.Input, + val description: String? = null +) { + + @Serializable + @JsonClassDiscriminator("mode") + sealed interface Mode { + @SerialName("input") + object Input : Mode + + @SerialName("auto_complete") + data class AutoComplete(val suggestions: List) : Mode + } + +} + +@JsonClassDiscriminator("type") +internal sealed interface DeeplinkParameterRemote { + val name: String + + @Serializable + @SerialName("auto_complete") + data class AutoComplete( + override val name: String, + val autoComplete: List + ) : DeeplinkParameterRemote + + @Serializable + @SerialName("variable") + data class Variable( + override val name: String, + val variableName: String + ) : DeeplinkParameterRemote +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt index 679355f17..cf5659731 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt @@ -1,10 +1,7 @@ package io.github.openflocon.flocon.core -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkParameterRemote import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModule -import kotlinx.serialization.modules.polymorphic -import kotlinx.serialization.modules.subclass object FloconEncoder { val json = Json { @@ -13,10 +10,7 @@ object FloconEncoder { encodeDefaults = false serializersModule = SerializersModule { - polymorphic(DeeplinkParameterRemote::class) { - subclass(DeeplinkParameterRemote.AutoComplete::class) - subclass(DeeplinkParameterRemote.Variable::class) - } + } } } \ No newline at end of file diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt index 237bbafa5..acc9d0f03 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt @@ -221,19 +221,18 @@ class MainActivity : ComponentActivity() { private fun initFlocon() { startFlocon(FloconContext(this)) { install(FloconDeeplinks) { - register("flocon://home") - register("flocon://test") - register( - "flocon://user/[userId]", - label = "User" + deeplink("flocon://home") + deeplink("flocon://test") + deeplink( + "flocon://user/[userId]" ) { - param("userId", listOf("Florent", "David", "Guillaume")) + label = "User" + "userId" withAutoComplete listOf("Florent", "David", "Guillaume") } - register( - "flocon://post/[postId]?comment=[commentText]", - label = "Post", + deeplink("flocon://post/[postId]?comment=[commentText]") { + label = "Post" description = "Open a post and send a comment" - ) + } } install(FloconNetwork) From 9bda13e518f3dc8ae257721745d8f788945d01e1 Mon Sep 17 00:00:00 2001 From: Raphael Teyssandier Date: Sun, 5 Apr 2026 22:14:34 +0200 Subject: [PATCH 21/35] 2.0.0 - Rework gradle (#510) --- .../build-logic/convention/build.gradle.kts | 28 +++ .../openflocon/buildlogic/AndroidConfig.kt | 22 ++ .../FloconAndroidLibraryConventionPlugin.kt | 26 ++ ...oconKotlinMultiplatformConventionPlugin.kt | 38 +++ .../FloconPublishConventionPlugin.kt | 52 ++++ FloconAndroid/build-logic/gradle.properties | 2 + FloconAndroid/build-logic/settings.gradle.kts | 15 ++ FloconAndroid/build.gradle.kts | 2 +- .../database/core-no-op/build.gradle.kts | 81 +----- FloconAndroid/database/core/build.gradle.kts | 81 +----- .../database/room-no-op/build.gradle.kts | 67 +---- FloconAndroid/database/room/build.gradle.kts | 73 +----- .../database/room3-no-op/build.gradle.kts | 19 +- FloconAndroid/database/room3/build.gradle.kts | 10 +- .../datastores-no-op/build.gradle.kts | 123 +++------ FloconAndroid/datastores/build.gradle.kts | 124 +++------ .../deeplinks-no-op/build.gradle.kts | 84 +------ FloconAndroid/deeplinks/build.gradle.kts | 81 +----- .../flocon/plugins/deeplinks/Mapping.kt | 1 + FloconAndroid/flocon-no-op/build.gradle.kts | 80 +----- FloconAndroid/flocon/build.gradle.kts | 236 ++++++------------ FloconAndroid/gradle/libs.versions.toml | 42 ++-- .../grpc-interceptor-base/build.gradle.kts | 123 +++------ .../grpc-interceptor-lite/build.gradle.kts | 117 ++------- .../grpc/grpc-interceptor/build.gradle.kts | 118 ++------- .../network/core-no-op/build.gradle.kts | 81 +----- FloconAndroid/network/core/build.gradle.kts | 82 +----- .../ktor-interceptor-no-op/build.gradle.kts | 82 +----- .../network/ktor-interceptor/build.gradle.kts | 86 +------ .../okhttp-interceptor-no-op/build.gradle.kts | 113 ++------- .../okhttp-interceptor/build.gradle.kts | 130 +++------- .../sample-android-only/build.gradle.kts | 30 +-- .../sample-multiplatform/build.gradle.kts | 4 +- FloconAndroid/settings.gradle.kts | 8 +- 34 files changed, 604 insertions(+), 1657 deletions(-) create mode 100644 FloconAndroid/build-logic/convention/build.gradle.kts create mode 100644 FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/AndroidConfig.kt create mode 100644 FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconAndroidLibraryConventionPlugin.kt create mode 100644 FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconKotlinMultiplatformConventionPlugin.kt create mode 100644 FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconPublishConventionPlugin.kt create mode 100644 FloconAndroid/build-logic/gradle.properties create mode 100644 FloconAndroid/build-logic/settings.gradle.kts diff --git a/FloconAndroid/build-logic/convention/build.gradle.kts b/FloconAndroid/build-logic/convention/build.gradle.kts new file mode 100644 index 000000000..82674d015 --- /dev/null +++ b/FloconAndroid/build-logic/convention/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + `kotlin-dsl` +} + +group = "io.github.openflocon.buildlogic" + +dependencies { + implementation(libs.android.gradlePlugin) + implementation(libs.kotlin.gradlePlugin) + implementation(libs.vanniktech.mavenPublish.gradlePlugin) +} + +gradlePlugin { + plugins { + register("floconAndroidLibrary") { + id = "flocon.android.library" + implementationClass = "io.github.openflocon.buildlogic.FloconAndroidLibraryConventionPlugin" + } + register("floconKotlinMultiplatform") { + id = "flocon.kotlin.multiplatform" + implementationClass = "io.github.openflocon.buildlogic.FloconKotlinMultiplatformConventionPlugin" + } + register("floconPublish") { + id = "flocon.publish" + implementationClass = "io.github.openflocon.buildlogic.FloconPublishConventionPlugin" + } + } +} diff --git a/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/AndroidConfig.kt b/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/AndroidConfig.kt new file mode 100644 index 000000000..e25d4d737 --- /dev/null +++ b/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/AndroidConfig.kt @@ -0,0 +1,22 @@ +package io.github.openflocon.buildlogic + +import com.android.build.gradle.LibraryExtension +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +internal fun Project.configureAndroidLibrary() { + extensions.configure { + compileSdk = 36 + + defaultConfig { + minSdk = 23 + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + } +} diff --git a/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconAndroidLibraryConventionPlugin.kt b/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconAndroidLibraryConventionPlugin.kt new file mode 100644 index 000000000..af1fb9a27 --- /dev/null +++ b/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconAndroidLibraryConventionPlugin.kt @@ -0,0 +1,26 @@ +package io.github.openflocon.buildlogic + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +class FloconAndroidLibraryConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.library") + apply("org.jetbrains.kotlin.android") + } + + configureAndroidLibrary() + + tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) + } + } + } + } +} diff --git a/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconKotlinMultiplatformConventionPlugin.kt b/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconKotlinMultiplatformConventionPlugin.kt new file mode 100644 index 000000000..f60e19246 --- /dev/null +++ b/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconKotlinMultiplatformConventionPlugin.kt @@ -0,0 +1,38 @@ +package io.github.openflocon.buildlogic + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +class FloconKotlinMultiplatformConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.jetbrains.kotlin.multiplatform") + apply("com.android.library") + } + + configureAndroidLibrary() + + extensions.configure { + androidTarget { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + compilerOptions { + freeCompilerArgs.add("-XXLanguage:+ExpectRefinement") + } + } + } + } +} diff --git a/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconPublishConventionPlugin.kt b/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconPublishConventionPlugin.kt new file mode 100644 index 000000000..df47b1eaf --- /dev/null +++ b/FloconAndroid/build-logic/convention/src/main/kotlin/io/github/openflocon/buildlogic/FloconPublishConventionPlugin.kt @@ -0,0 +1,52 @@ +package io.github.openflocon.buildlogic + +import com.vanniktech.maven.publish.MavenPublishBaseExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +class FloconPublishConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.vanniktech.maven.publish") + } + + extensions.configure { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + pom { + name.set(project.name) + description.set(project.findProperty("floconDescription") as? String) + inceptionYear.set("2025") + url.set("https://github.com/openflocon/Flocon") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + distribution.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("openflocon") + name.set("Open Flocon") + url.set("https://github.com/openflocon") + } + } + scm { + url.set("https://github.com/openflocon/Flocon") + connection.set("scm:git:git://github.com/openflocon/Flocon.git") + developerConnection.set("scm:git:ssh://git@github.com/openflocon/Flocon.git") + } + } + } + } + } +} diff --git a/FloconAndroid/build-logic/gradle.properties b/FloconAndroid/build-logic/gradle.properties new file mode 100644 index 000000000..b29124d09 --- /dev/null +++ b/FloconAndroid/build-logic/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +kotlin.daemon.jvmargs=-Xmx1024m diff --git a/FloconAndroid/build-logic/settings.gradle.kts b/FloconAndroid/build-logic/settings.gradle.kts new file mode 100644 index 000000000..f26e6d9f9 --- /dev/null +++ b/FloconAndroid/build-logic/settings.gradle.kts @@ -0,0 +1,15 @@ +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "build-logic" + +include(":convention") diff --git a/FloconAndroid/build.gradle.kts b/FloconAndroid/build.gradle.kts index 5d6f07e57..8cc104597 100644 --- a/FloconAndroid/build.gradle.kts +++ b/FloconAndroid/build.gradle.kts @@ -7,5 +7,5 @@ plugins { alias(libs.plugins.android.library) apply false alias(libs.plugins.ksp) apply false alias(libs.plugins.vanniktech.maven.publish) apply false - id("com.google.protobuf") version "0.9.5" apply false + alias(libs.plugins.protobuf) apply false } \ No newline at end of file diff --git a/FloconAndroid/database/core-no-op/build.gradle.kts b/FloconAndroid/database/core-no-op/build.gradle.kts index b7390b113..348ce3da1 100644 --- a/FloconAndroid/database/core-no-op/build.gradle.kts +++ b/FloconAndroid/database/core-no-op/build.gradle.kts @@ -1,29 +1,14 @@ plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(projects.flocon) + implementation(libs.kotlinx.coroutines.core) } } @@ -51,68 +36,14 @@ kotlin { android { namespace = "io.github.openflocon.flocon.database.core.noop" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-database-core-no-op", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon Database Core No-Op" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } } + diff --git a/FloconAndroid/database/core/build.gradle.kts b/FloconAndroid/database/core/build.gradle.kts index f66e064ad..346a4e2b9 100644 --- a/FloconAndroid/database/core/build.gradle.kts +++ b/FloconAndroid/database/core/build.gradle.kts @@ -1,31 +1,16 @@ plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") alias(libs.plugins.kotlin.serialization) } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - api(project(":flocon")) + api(projects.flocon) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) } } @@ -58,68 +43,14 @@ kotlin { android { namespace = "io.github.openflocon.flocon.database.core" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-database-core", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon Database Core" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } } + diff --git a/FloconAndroid/database/room-no-op/build.gradle.kts b/FloconAndroid/database/room-no-op/build.gradle.kts index ffd49f7e0..22b4f41d1 100644 --- a/FloconAndroid/database/room-no-op/build.gradle.kts +++ b/FloconAndroid/database/room-no-op/build.gradle.kts @@ -1,28 +1,13 @@ plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - implementation(project(":database:core-no-op")) + implementation(projects.database.coreNoOp) } } @@ -50,57 +35,15 @@ kotlin { android { namespace = "io.github.openflocon.flocon.database.room.noop" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-database-room-no-op", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon Room Implementation No-Op" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } } + diff --git a/FloconAndroid/database/room/build.gradle.kts b/FloconAndroid/database/room/build.gradle.kts index 4b8d7eb40..eb82a4a12 100644 --- a/FloconAndroid/database/room/build.gradle.kts +++ b/FloconAndroid/database/room/build.gradle.kts @@ -1,29 +1,14 @@ plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) - api(project(":database:core")) + implementation(projects.flocon) + api(projects.database.core) implementation(libs.androidx.room.runtime) implementation(libs.androidx.room.sqlite.wrapper) implementation(libs.androidx.sqlite.bundled) @@ -32,7 +17,7 @@ kotlin { val androidMain by getting { dependencies { - implementation(libs.jetbrains.kotlinx.coroutines.android) + implementation(libs.kotlinx.coroutines.android) } } @@ -55,59 +40,15 @@ kotlin { android { namespace = "io.github.openflocon.flocon.database.room" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-database-room", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon Room implementation" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } } + diff --git a/FloconAndroid/database/room3-no-op/build.gradle.kts b/FloconAndroid/database/room3-no-op/build.gradle.kts index 5c3db1e82..470e7406c 100644 --- a/FloconAndroid/database/room3-no-op/build.gradle.kts +++ b/FloconAndroid/database/room3-no-op/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.android.library) @@ -6,10 +8,8 @@ plugins { kotlin { androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) } } @@ -56,6 +56,16 @@ android { minSdk = 23 } + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 @@ -78,6 +88,7 @@ mavenPublishing { version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) + pom { name = "Flocon Room 3 Implementation No-Op" description = project.property("floconDescription") as String diff --git a/FloconAndroid/database/room3/build.gradle.kts b/FloconAndroid/database/room3/build.gradle.kts index 99e8d69c1..cf12f31f2 100644 --- a/FloconAndroid/database/room3/build.gradle.kts +++ b/FloconAndroid/database/room3/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.android.library) @@ -8,10 +10,8 @@ plugins { kotlin { androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) } } @@ -32,11 +32,13 @@ kotlin { val androidMain by getting { dependencies { + implementation(libs.brotli.dec) } } val jvmMain by getting { dependencies { + implementation(libs.brotli.dec) } } diff --git a/FloconAndroid/datastores-no-op/build.gradle.kts b/FloconAndroid/datastores-no-op/build.gradle.kts index c3f4b30d0..d89542b0c 100644 --- a/FloconAndroid/datastores-no-op/build.gradle.kts +++ b/FloconAndroid/datastores-no-op/build.gradle.kts @@ -1,93 +1,30 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - id("com.vanniktech.maven.publish") version "0.34.0" -} - -android { - namespace = "io.github.openflocon.flocon.datastores" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} - -kotlin { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } -} - -dependencies { - - implementation(project(":flocon")) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.jetbrains.kotlinx.coroutines.core) - - implementation(libs.androidx.datastore.preferences) -} - - -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-datastores-no-op", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) - - pom { - name = "Flocon Datastores Integration No Op" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.android.library") + id("flocon.publish") +} + +android { + namespace = "io.github.openflocon.flocon.datastores" +} + + +dependencies { + + implementation(projects.flocon) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.androidx.datastore.preferences) +} + + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-datastores-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} \ No newline at end of file diff --git a/FloconAndroid/datastores/build.gradle.kts b/FloconAndroid/datastores/build.gradle.kts index e30b81eca..6974dfad8 100644 --- a/FloconAndroid/datastores/build.gradle.kts +++ b/FloconAndroid/datastores/build.gradle.kts @@ -1,94 +1,30 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - id("com.vanniktech.maven.publish") version "0.34.0" -} - -android { - namespace = "io.github.openflocon.flocon.datastores" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} - -kotlin { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } -} - -dependencies { - - implementation(project(":flocon")) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.jetbrains.kotlinx.coroutines.core) - implementation(libs.jetbrains.kotlinx.coroutines.android) - - implementation(libs.androidx.datastore.preferences) -} - - -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-datastores", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) - - pom { - name = "Flocon Datastores Integration" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.android.library") + id("flocon.publish") +} + +android { + namespace = "io.github.openflocon.flocon.datastores" +} + +dependencies { + + implementation(projects.flocon) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.coroutines.android) + + implementation(libs.androidx.datastore.preferences) +} + + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-datastores", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} \ No newline at end of file diff --git a/FloconAndroid/deeplinks-no-op/build.gradle.kts b/FloconAndroid/deeplinks-no-op/build.gradle.kts index b183bb71e..438e43cdb 100644 --- a/FloconAndroid/deeplinks-no-op/build.gradle.kts +++ b/FloconAndroid/deeplinks-no-op/build.gradle.kts @@ -1,37 +1,22 @@ plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(projects.flocon) + implementation(libs.kotlinx.coroutines.core) } } - + val androidMain by getting { dependencies { } } - + val jvmMain by getting { dependencies { } @@ -51,68 +36,13 @@ kotlin { android { namespace = "io.github.openflocon.flocon.deeplinks.noop" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-deeplinks-no-op", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon Deeplinks No-Op" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } } diff --git a/FloconAndroid/deeplinks/build.gradle.kts b/FloconAndroid/deeplinks/build.gradle.kts index 25714f431..0049a7aef 100644 --- a/FloconAndroid/deeplinks/build.gradle.kts +++ b/FloconAndroid/deeplinks/build.gradle.kts @@ -1,30 +1,15 @@ plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") alias(libs.plugins.kotlin.serialization) } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(projects.flocon) + implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) } } @@ -53,68 +38,14 @@ kotlin { android { namespace = "io.github.openflocon.flocon.deeplinks" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-deeplinks", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon Deeplinks" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } } + diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt index 02627c180..89caedf6c 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt @@ -6,6 +6,7 @@ import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkParameterRemo import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkRemote import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkVariableRemote import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinksRemote +import kotlinx.serialization.encodeToString internal fun createJson( deeplinks: List, diff --git a/FloconAndroid/flocon-no-op/build.gradle.kts b/FloconAndroid/flocon-no-op/build.gradle.kts index 895bd36bf..99ab4b8c7 100644 --- a/FloconAndroid/flocon-no-op/build.gradle.kts +++ b/FloconAndroid/flocon-no-op/build.gradle.kts @@ -1,29 +1,16 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") } kotlin { - androidTarget { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) - api(project(":flocon")) + api(projects.flocon) + implementation(libs.kotlinx.coroutines.core) } } @@ -51,68 +38,13 @@ kotlin { android { namespace = "io.github.openflocon.flocon" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-no-op", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon No Op" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +} diff --git a/FloconAndroid/flocon/build.gradle.kts b/FloconAndroid/flocon/build.gradle.kts index 98d34f6df..ab063ba78 100644 --- a/FloconAndroid/flocon/build.gradle.kts +++ b/FloconAndroid/flocon/build.gradle.kts @@ -1,154 +1,82 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.vanniktech.maven.publish) - alias(libs.plugins.buildconfig) -} - -kotlin { - androidTarget { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - - compilerOptions { - freeCompilerArgs.add("-XXLanguage:+ExpectRefinement") - } - - sourceSets { - val commonMain by getting { - dependencies { - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) - implementation(libs.kotlinx.serialization.json) - } - } - - val androidMain by getting { - dependencies { - implementation(libs.kotlinx.coroutines.android) - implementation(libs.jakewharton.process.phoenix) - implementation("com.squareup.okhttp3:okhttp:4.12.0") - } - } - - val jvmMain by getting { - dependencies { - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.cio) - - implementation(libs.ktor.client.content.negotiation) - implementation(libs.ktor.client.logging) - implementation(libs.ktor.serialization.kotlinx.json) - } - } - - val iosX64Main by getting - val iosArm64Main by getting - val iosSimulatorArm64Main by getting - val iosMain by creating { - dependsOn(commonMain) - iosX64Main.dependsOn(this) - iosArm64Main.dependsOn(this) - iosSimulatorArm64Main.dependsOn(this) - dependencies { - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.darwin) - - implementation(libs.ktor.client.content.negotiation) - implementation(libs.ktor.client.logging) - implementation(libs.ktor.serialization.kotlinx.json) - - // to store the device id - implementation("com.russhwolf:multiplatform-settings:1.3.0") - implementation(libs.androidx.sqlite.bundled) - } - } - } -} - -buildConfig { - packageName("io.github.openflocon.flocondesktop") - - buildConfigField("APP_VERSION", System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String) -} - -android { - namespace = "io.github.openflocon.flocon" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - sourceSets["main"].res.srcDirs("src/androidMain/res") -} - -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) - - pom { - name = "Flocon" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.kotlin.multiplatform") + alias(libs.plugins.kotlin.serialization) + id("flocon.publish") + alias(libs.plugins.buildconfig) +} + + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.serialization.json) + } + } + + val androidMain by getting { + dependencies { + implementation(libs.kotlinx.coroutines.android) + implementation(libs.jakewharton.process.phoenix) + implementation("com.squareup.okhttp3:okhttp:4.12.0") + } + } + + val jvmMain by getting { + dependencies { + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.cio) + + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.client.logging) + implementation(libs.ktor.serialization.kotlinx.json) + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + dependencies { + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.darwin) + + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.client.logging) + implementation(libs.ktor.serialization.kotlinx.json) + + // to store the device id + implementation("com.russhwolf:multiplatform-settings:1.3.0") + implementation(libs.androidx.sqlite.bundled) + } + } + } +} + +buildConfig { + packageName("io.github.openflocon.flocondesktop") + + buildConfigField("APP_VERSION", System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String) +} + +android { + namespace = "io.github.openflocon.flocon" + + sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + sourceSets["main"].res.srcDirs("src/androidMain/res") +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} \ No newline at end of file diff --git a/FloconAndroid/gradle/libs.versions.toml b/FloconAndroid/gradle/libs.versions.toml index c8aafb267..e0c4d0368 100644 --- a/FloconAndroid/gradle/libs.versions.toml +++ b/FloconAndroid/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.11.0-rc02" +agp = "8.13.2" apollo = "4.0.0" coilCompose = "3.2.0" compose = "1.9.0" @@ -10,19 +10,19 @@ coreKtx = "1.16.0" junit = "4.13.2" junitVersion = "1.2.1" espressoCore = "3.6.1" -kotlinxCoroutinesBom = "1.10.2" -kotlinxSerialization = "1.8.0" +kotlinxCoroutines = "1.10.2" +kotlinxSerialization = "1.7.1" ktor = "3.2.3" lifecycleRuntimeKtx = "2.9.1" activityCompose = "1.10.1" composeBom = "2025.06.01" appcompat = "1.7.1" material = "1.12.0" -okhttpBom = "4.12.0" +okhttp = "4.12.0" room = "2.8.4" # for grpc gson = "2.11.0" -grpc = "1.70.0" +grpc = "1.73.0" protobufPlugin = "0.9.5" grpcKotlin = "1.4.3" protobuf = "4.26.1" @@ -34,6 +34,9 @@ buildconfig = "5.6.8" brotli = "0.1.2" [libraries] +android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" } +kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } +vanniktech-mavenPublish-gradlePlugin = { group = "com.vanniktech", name = "gradle-maven-publish-plugin", version.ref = "mavenPublish" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" } brotli-dec = { module = "org.brotli:dec", version.ref = "brotli" } @@ -43,9 +46,6 @@ coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coilCo coil-network-ktor = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coilCompose" } coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coilCompose" } jakewharton-process-phoenix = { group = "com.jakewharton", name = "process-phoenix", version.ref = "processPhoenix" } -jetbrains-kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android" } -jetbrains-kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core" } -jetbrains-kotlinx-coroutines-core-fixed = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutinesBom" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } @@ -59,17 +59,22 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-material3 = { group = "androidx.compose.material3", name = "material3" } + # for grpc gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } grpc-android = { group = "io.grpc", name = "grpc-android", version.ref = "grpc" } grpc-okhttp = { group = "io.grpc", name = "grpc-okhttp", version.ref = "grpc" } grpc-kotlin-stub = { group = "io.grpc", name = "grpc-kotlin-stub", version.ref = "grpcKotlin" } grpc-protobuf-lite = { group = "io.grpc", name = "grpc-protobuf-lite", version.ref = "grpc" } -kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android" } -kotlinx-coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version.ref = "kotlinxCoroutinesBom" } -kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core" } -kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinxCoroutinesBom" } +grpc-gen-java = { group = "io.grpc", name = "protoc-gen-grpc-java", version.ref = "grpc" } +grpc-gen-kotlin = { group = "io.grpc", name = "protoc-gen-grpc-kotlin", version.ref = "grpcKotlin" } + +kotlinx-coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version.ref = "kotlinxCoroutines" } +kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" } +kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" } +kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinxCoroutines" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" } + ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" } ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } @@ -78,15 +83,15 @@ ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "kto ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } ktor-clientJava = { module = "io.ktor:ktor-client-java", version.ref = "ktor" } ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } -okhttp = { module = "com.squareup.okhttp3:okhttp" } -okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttpBom" } -okhttp3-okhttp = { module = "com.squareup.okhttp3:okhttp" } -org-jetbrains-kotlinx-kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android" } -org-jetbrains-kotlinx-kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core" } + +okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttp" } +okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } + +protobuf-protoc = { group = "com.google.protobuf", name = "protoc", version = "3.25.1" } protobuf-kotlin-lite = { group = "com.google.protobuf", name = "protobuf-kotlin-lite", version.ref = "protobuf"} protobuf-util = { group = "com.google.protobuf", name = "protobuf-java-util", version.ref = "protobuf" } + sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" } -squareup-okhttp = { module = "com.squareup.okhttp3:okhttp" } androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } @@ -109,3 +114,4 @@ android-library = { id = "com.android.library", version.ref = "agp" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "mavenPublish" } buildconfig = { id = "com.github.gmazzo.buildconfig", version.ref = "buildconfig" } +protobuf = { id = "com.google.protobuf", version.ref = "protobufPlugin" } diff --git a/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts b/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts index 4e00098c9..fb3e112e3 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts +++ b/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts @@ -1,93 +1,30 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - id("com.vanniktech.maven.publish") version "0.34.0" -} - -android { - namespace = "io.github.openflocon.flocon.grpc.base" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} - -kotlin { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } -} - -dependencies { - implementation(project(":flocon")) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.kotlinx.coroutines.core) - - implementation(libs.grpc.android) -} - - -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-grpc-interceptor-base", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) - - - pom { - name = "Flocon Grpc Interceptor" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.android.library") + id("flocon.publish") +} + + +android { + namespace = "io.github.openflocon.flocon.grpc.base" +} + + +dependencies { + implementation(projects.flocon) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.grpc.android) +} + + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-grpc-interceptor-base", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} \ No newline at end of file diff --git a/FloconAndroid/grpc/grpc-interceptor-lite/build.gradle.kts b/FloconAndroid/grpc/grpc-interceptor-lite/build.gradle.kts index cc99dcd78..9f49224d7 100644 --- a/FloconAndroid/grpc/grpc-interceptor-lite/build.gradle.kts +++ b/FloconAndroid/grpc/grpc-interceptor-lite/build.gradle.kts @@ -1,90 +1,27 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - id("com.vanniktech.maven.publish") version "0.34.0" -} - -android { - namespace = "io.github.openflocon.flocon.grpc.lite" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} - -kotlin { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } -} - -dependencies { - api(project(":grpc:grpc-interceptor-base")) - - implementation(libs.grpc.android) - implementation(libs.gson) -} - -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-grpc-interceptor-lite", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) - - - pom { - name = "Flocon Grpc Interceptor Lite" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.android.library") + id("flocon.publish") +} + + +android { + namespace = "io.github.openflocon.flocon.grpc.lite" +} + + +dependencies { + api(projects.grpc.grpcInterceptorBase) + + implementation(libs.grpc.android) + implementation(libs.gson) +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-grpc-interceptor-lite", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} \ No newline at end of file diff --git a/FloconAndroid/grpc/grpc-interceptor/build.gradle.kts b/FloconAndroid/grpc/grpc-interceptor/build.gradle.kts index c39e77e0f..ef4b916ff 100644 --- a/FloconAndroid/grpc/grpc-interceptor/build.gradle.kts +++ b/FloconAndroid/grpc/grpc-interceptor/build.gradle.kts @@ -1,91 +1,27 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - id("com.vanniktech.maven.publish") version "0.34.0" -} - -android { - namespace = "io.github.openflocon.flocon.grpc" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} - -kotlin { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } -} - -dependencies { - api(project(":grpc:grpc-interceptor-base")) - - implementation(libs.grpc.android) - implementation(libs.protobuf.util) -} - - -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-grpc-interceptor", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) - - - pom { - name = "Flocon Grpc Interceptor" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.android.library") + id("flocon.publish") +} + +android { + namespace = "io.github.openflocon.flocon.grpc" +} + + +dependencies { + api(projects.grpc.grpcInterceptorBase) + + implementation(libs.grpc.android) + implementation(libs.protobuf.util) +} + + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-grpc-interceptor", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} \ No newline at end of file diff --git a/FloconAndroid/network/core-no-op/build.gradle.kts b/FloconAndroid/network/core-no-op/build.gradle.kts index 7d09e14e2..27fa6b6cf 100644 --- a/FloconAndroid/network/core-no-op/build.gradle.kts +++ b/FloconAndroid/network/core-no-op/build.gradle.kts @@ -1,29 +1,14 @@ plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(projects.flocon) + implementation(libs.kotlinx.coroutines.core) } } @@ -51,68 +36,14 @@ kotlin { android { namespace = "io.github.openflocon.flocon.network.core.noop" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-network-core-no-op", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon Network Core No-Op" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } } + diff --git a/FloconAndroid/network/core/build.gradle.kts b/FloconAndroid/network/core/build.gradle.kts index af58159d7..a677713ae 100644 --- a/FloconAndroid/network/core/build.gradle.kts +++ b/FloconAndroid/network/core/build.gradle.kts @@ -1,31 +1,15 @@ plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") alias(libs.plugins.kotlin.serialization) } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - api(project(":flocon")) - - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + api(projects.flocon) + implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) } } @@ -54,68 +38,14 @@ kotlin { android { namespace = "io.github.openflocon.flocon.network.core" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-network-core", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon Network Core" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } } + diff --git a/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts b/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts index 0f966ba28..821e8a0a5 100644 --- a/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts +++ b/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts @@ -1,28 +1,13 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") } kotlin { - androidTarget { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - implementation(project(":network:core-no-op")) + implementation(projects.network.coreNoOp) implementation(libs.ktor.client.core) } } @@ -51,71 +36,14 @@ kotlin { android { namespace = "io.github.openflocon.flocon.ktor" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-ktor-interceptor-no-op", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - - pom { - name = "Flocon Ktor Interceptor No Op" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +} diff --git a/FloconAndroid/network/ktor-interceptor/build.gradle.kts b/FloconAndroid/network/ktor-interceptor/build.gradle.kts index 2404e2b0b..57fd88634 100644 --- a/FloconAndroid/network/ktor-interceptor/build.gradle.kts +++ b/FloconAndroid/network/ktor-interceptor/build.gradle.kts @@ -1,32 +1,17 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) + id("flocon.kotlin.multiplatform") + id("flocon.publish") } kotlin { - androidTarget { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { - api(project(":flocon")) - api(project(":network:core")) + api(projects.flocon) + api(projects.network.core) - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0") + implementation(libs.kotlinx.coroutines.core) implementation(libs.ktor.client.core) } } @@ -57,71 +42,14 @@ kotlin { android { namespace = "io.github.openflocon.flocon.ktor" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } +mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-ktor-interceptor", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - - pom { - name = "Flocon Ktor Interceptor" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +} diff --git a/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts b/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts index 739f6b1ee..aa77a7815 100644 --- a/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts +++ b/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts @@ -1,88 +1,25 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - id("com.vanniktech.maven.publish") version "0.34.0" -} - -android { - namespace = "io.github.openflocon.flocon.okhttp" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} - -dependencies { - implementation(project(":network:core-no-op")) - implementation(platform(libs.okhttp.bom)) - implementation(libs.okhttp3.okhttp) -} - -kotlin { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } -} - -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-okhttp-interceptor-no-op", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) - - pom { - name = "Flocon OkHttp Interceptor" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +plugins { + id("flocon.android.library") + id("flocon.publish") +} + + +android { + namespace = "io.github.openflocon.flocon.okhttp" +} + + +dependencies { + implementation(projects.network.coreNoOp) + implementation(platform(libs.okhttp.bom)) + implementation(libs.okhttp) +} + + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-okhttp-interceptor-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} \ No newline at end of file diff --git a/FloconAndroid/network/okhttp-interceptor/build.gradle.kts b/FloconAndroid/network/okhttp-interceptor/build.gradle.kts index a30d90427..7816ec3d0 100644 --- a/FloconAndroid/network/okhttp-interceptor/build.gradle.kts +++ b/FloconAndroid/network/okhttp-interceptor/build.gradle.kts @@ -1,98 +1,32 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - id("com.vanniktech.maven.publish") version "0.34.0" -} - -android { - namespace = "io.github.openflocon.flocon.okhttp" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} - -kotlin { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - } -} - -dependencies { - - api(project(":network:core")) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.jetbrains.kotlinx.coroutines.core) - implementation(libs.jetbrains.kotlinx.coroutines.android) - - implementation(platform(libs.okhttp.bom)) - implementation(libs.okhttp3.okhttp) - implementation(libs.brotli.dec) - - testImplementation(libs.junit) -} - - -mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-okhttp-interceptor", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) - - pom { - name = "Flocon OkHttp Interceptor" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } -} \ No newline at end of file +plugins { + id("flocon.android.library") + id("flocon.publish") +} + +android { + namespace = "io.github.openflocon.flocon.okhttp" +} + +dependencies { + + api(projects.network.core) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.coroutines.android) + + implementation(platform(libs.okhttp.bom)) + implementation(libs.okhttp) + implementation(libs.brotli.dec) + + testImplementation(libs.junit) +} + + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-okhttp-interceptor", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} \ No newline at end of file diff --git a/FloconAndroid/sample-android-only/build.gradle.kts b/FloconAndroid/sample-android-only/build.gradle.kts index e16ed5784..9d077af4c 100644 --- a/FloconAndroid/sample-android-only/build.gradle.kts +++ b/FloconAndroid/sample-android-only/build.gradle.kts @@ -8,7 +8,7 @@ plugins { alias(libs.plugins.ksp) alias(libs.plugins.apollo) - id("com.google.protobuf") + alias(libs.plugins.protobuf) } android { @@ -82,27 +82,27 @@ dependencies { //implementation("io.github.openflocon:flocon-okhttp-interceptor-no-op:$floconVersion") implementation("io.github.openflocon:flocon-ktor-interceptor:$floconVersion") } else { - debugImplementation(project(":flocon")) - releaseImplementation(project(":flocon-no-op")) + debugImplementation(projects.flocon) + releaseImplementation(projects.floconNoOp) - debugImplementation(project(":deeplinks")) - releaseImplementation(project(":deeplinks-no-op")) + debugImplementation(projects.deeplinks) + releaseImplementation(projects.deeplinksNoOp) debugImplementation(project(":database:room")) releaseImplementation(project(":database:room-no-op")) debugImplementation(project(":database:room3")) releaseImplementation(project(":database:room3-no-op")) - debugImplementation(project(":network:okhttp-interceptor")) - releaseImplementation(project(":network:okhttp-interceptor-no-op")) + debugImplementation(projects.network.okhttpInterceptor) + releaseImplementation(projects.network.okhttpInterceptorNoOp) - implementation(project(":grpc:grpc-interceptor-lite")) + implementation(projects.grpc.grpcInterceptorLite) - debugImplementation(project(":network:ktor-interceptor")) - releaseImplementation(project(":network:ktor-interceptor-no-op")) + debugImplementation(projects.network.ktorInterceptor) + releaseImplementation(projects.network.ktorInterceptorNoOp) - debugImplementation(project(":datastores")) - releaseImplementation(project(":datastores-no-op")) + debugImplementation(projects.datastores) + releaseImplementation(projects.datastoresNoOp) } @@ -168,12 +168,12 @@ apollo { protobuf { protoc { - artifact = "com.google.protobuf:protoc:3.25.1" + artifact = libs.protobuf.protoc.get().toString() } generateProtoTasks { - val protocGenJava = "io.grpc:protoc-gen-grpc-java:1.73.0" - val protocGenKotlin = "io.grpc:protoc-gen-grpc-kotlin:1.4.3" + ":jdk8@jar" + val protocGenJava = libs.grpc.gen.java.get().toString() + val protocGenKotlin = libs.grpc.gen.kotlin.get().toString() + ":jdk8@jar" plugins { id("java") { diff --git a/FloconAndroid/sample-multiplatform/build.gradle.kts b/FloconAndroid/sample-multiplatform/build.gradle.kts index 64301aaa6..605e80924 100644 --- a/FloconAndroid/sample-multiplatform/build.gradle.kts +++ b/FloconAndroid/sample-multiplatform/build.gradle.kts @@ -33,8 +33,8 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) - implementation(project(":network:ktor-interceptor")) + implementation(projects.flocon) + implementation(projects.network.ktorInterceptor) implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index 748d46048..2521b305b 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -1,4 +1,6 @@ -rootProject.name = "Flocon Sample App" +rootProject.name = "Flocon-Sample-App" + +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { repositories { @@ -7,6 +9,7 @@ pluginManagement { gradlePluginPortal() } } + dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { @@ -39,3 +42,6 @@ include(":database:room") include(":database:room-no-op") include(":database:room3") include(":database:room3-no-op") + +includeBuild("build-logic") + From dc836f788889ed4c0512046a5b8889a4a3ff481f Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Thu, 7 May 2026 15:43:45 +0200 Subject: [PATCH 22/35] fix: Build --- .../sample-multiplatform/build.gradle.kts | 1 + .../flocon/myapplication/multi/Databases.kt | 16 +++--- .../myapplication/multi/MainActivity.kt | 8 +-- .../flocon/myapplication/multi/ui/App.kt | 51 ++++++++----------- 4 files changed, 34 insertions(+), 42 deletions(-) diff --git a/FloconAndroid/sample-multiplatform/build.gradle.kts b/FloconAndroid/sample-multiplatform/build.gradle.kts index 605e80924..89d400280 100644 --- a/FloconAndroid/sample-multiplatform/build.gradle.kts +++ b/FloconAndroid/sample-multiplatform/build.gradle.kts @@ -34,6 +34,7 @@ kotlin { val commonMain by getting { dependencies { implementation(projects.flocon) + implementation(projects.deeplinks) implementation(projects.network.ktorInterceptor) implementation(libs.kotlinx.coroutines.core) diff --git a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/Databases.kt b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/Databases.kt index 6a6199926..2fb927254 100644 --- a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/Databases.kt +++ b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/Databases.kt @@ -2,11 +2,8 @@ package io.github.openflocon.flocon.myapplication.multi import android.content.Context import androidx.room.Room -import androidx.room.RoomDatabase import io.github.openflocon.flocon.myapplication.multi.database.DogDatabase import io.github.openflocon.flocon.myapplication.multi.database.FoodDatabase -import io.github.openflocon.flocon.plugins.database.floconLogDatabaseQuery -import java.util.concurrent.Executor import java.util.concurrent.Executors object Databases { @@ -14,17 +11,20 @@ object Databases { private var dogDatabase: DogDatabase? = null fun getDogDatabase(context: Context): DogDatabase { - val dbName = "dogs_database" + "dogs_database" return dogDatabase ?: synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, DogDatabase::class.java, "dogs_database" ) - .setQueryCallback({ sqlQuery, bindArgs -> floconLogDatabaseQuery( - dbName = dbName, sqlQuery = sqlQuery, bindArgs = bindArgs - ) }, Executors.newSingleThreadExecutor()) - .fallbackToDestructiveMigration().build() +// .setQueryCallback({ sqlQuery, bindArgs -> +// floconLogDatabaseQuery( +// dbName = dbName, sqlQuery = sqlQuery, bindArgs = bindArgs +// ) +// }, Executors.newSingleThreadExecutor()) + .fallbackToDestructiveMigration(dropAllTables = true) + .build() dogDatabase = instance instance } diff --git a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt index 3ad3d762a..89253a000 100644 --- a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt +++ b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt @@ -5,7 +5,7 @@ import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge -import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.ktor.FloconKtorPlugin import io.github.openflocon.flocon.myapplication.multi.Databases.getDogDatabase @@ -14,6 +14,7 @@ import io.github.openflocon.flocon.myapplication.multi.database.initializeDataba import io.github.openflocon.flocon.myapplication.multi.sharedpreferences.initializeSharedPreferences import io.github.openflocon.flocon.myapplication.multi.ui.App import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks +import io.github.openflocon.flocon.startFlocon import io.ktor.client.HttpClient import io.ktor.client.engine.okhttp.OkHttp @@ -52,10 +53,9 @@ class MainActivity : ComponentActivity() { ) FloconLogger.enabled = true - Flocon.initialize(this) { - install(FloconDeeplinks) { - } + startFlocon(FloconContext(this)) { + install(FloconDeeplinks) } setContent { diff --git a/FloconAndroid/sample-multiplatform/src/commonMain/kotlin/io/github/openflocon/flocon/myapplication/multi/ui/App.kt b/FloconAndroid/sample-multiplatform/src/commonMain/kotlin/io/github/openflocon/flocon/myapplication/multi/ui/App.kt index 140e68bf3..02afbfb09 100644 --- a/FloconAndroid/sample-multiplatform/src/commonMain/kotlin/io/github/openflocon/flocon/myapplication/multi/ui/App.kt +++ b/FloconAndroid/sample-multiplatform/src/commonMain/kotlin/io/github/openflocon/flocon/myapplication/multi/ui/App.kt @@ -2,7 +2,6 @@ package io.github.openflocon.flocon.myapplication.multi.ui import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -16,14 +15,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import io.github.openflocon.flocon.myapplication.multi.DummyHttpKtorCaller import io.github.openflocon.flocon.myapplication.multi.dashboard.initializeDashboard -import io.github.openflocon.flocon.myapplication.multi.database.model.DogEntity -import io.github.openflocon.flocon.plugins.analytics.floconAnalytics -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsEvent -import io.github.openflocon.flocon.plugins.analytics.model.analyticsProperty -import io.github.openflocon.flocon.plugins.tables.floconTable -import io.github.openflocon.flocon.plugins.tables.model.toParam -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch import kotlin.random.Random @Composable @@ -44,7 +35,7 @@ fun App() { text = "Flocon Multi App", style = MaterialTheme.typography.headlineMedium ) - + Column( modifier = Modifier.fillMaxWidth(), ) { @@ -64,32 +55,32 @@ fun App() { } Button( onClick = { - val value = Random.nextInt(from = 0, until = 1000).toString() - floconTable("analytics").log( - "name" toParam "new name $value", - "value1" toParam "value1 $value", - "value2" toParam "value2 $value", - ) + Random.nextInt(from = 0, until = 1000).toString() +// floconTable("analytics").log( +// "name" toParam "new name $value", +// "value1" toParam "value1 $value", +// "value2" toParam "value2 $value", +// ) } ) { Text("send table event") } Button( onClick = { - floconAnalytics("firebase").logEvents( - AnalyticsEvent( - eventName = "clicked user", - "userId" analyticsProperty "1024", - "username" analyticsProperty "florent", - "index" analyticsProperty "3", - ), - AnalyticsEvent( - eventName = "opened profile", - "userId" analyticsProperty "2048", - "username" analyticsProperty "kevin", - "age" analyticsProperty "34", - ), - ) +// floconAnalytics("firebase").logEvents( +// AnalyticsEvent( +// eventName = "clicked user", +// "userId" analyticsProperty "1024", +// "username" analyticsProperty "florent", +// "index" analyticsProperty "3", +// ), +// AnalyticsEvent( +// eventName = "opened profile", +// "userId" analyticsProperty "2048", +// "username" analyticsProperty "kevin", +// "age" analyticsProperty "34", +// ), +// ) } ) { Text("send analytics event") From 38d160e0e1a91e24a8877b922dff1463060710b1 Mon Sep 17 00:00:00 2001 From: Raphael Teyssandier Date: Wed, 13 May 2026 14:09:40 +0200 Subject: [PATCH 23/35] 2.0.0 - Table (#512) --- .../flocon/database/core/FloconDatabase.kt | 7 +- .../database/core/FloconDatabasePluginImpl.kt | 35 ++-- .../fromdevice/DatabaseExecuteSqlResponse.kt | 25 --- .../fromdevice/sql/DatabaseQueryLogModel.kt | 15 +- .../fromdevice/sql/DeviceDataBaseDataModel.kt | 6 - .../sql/QueryResultReceivedDataModel.kt | 9 +- .../model/todevice/DatabaseQueryMessage.kt | 15 +- FloconAndroid/database/room/build.gradle.kts | 7 - .../database/room3-no-op/build.gradle.kts | 2 + FloconAndroid/database/room3/build.gradle.kts | 4 - .../datastores-no-op/build.gradle.kts | 58 +++---- FloconAndroid/datastores/build.gradle.kts | 58 +++---- .../plugins/deeplinks/FloconDeeplinks.kt | 13 +- .../flocon/plugins/deeplinks/Mapping.kt | 16 +- FloconAndroid/flocon/build.gradle.kts | 163 +++++++++--------- .../FloconCrashReporterDataSource.android.kt | 13 +- .../io/github/openflocon/flocon/Flocon.kt | 23 ++- .../openflocon/flocon/FloconConfiguration.kt | 44 +++-- .../openflocon/flocon/FloconEncoding.kt | 5 +- .../github/openflocon/flocon/FloconPlugin.kt | 8 +- .../flocon/client/FloconClientImpl.kt | 78 +++++---- .../openflocon/flocon/core/FloconEncoder.kt | 36 +++- .../flocon/core/FloconFileSender.kt | 2 +- .../flocon/core/FloconMessageSender.kt | 4 +- .../flocon/error/PluginNotInitialized.kt | 1 + .../flocon/model/FloconMessageFromServer.kt | 13 -- .../flocon/model/FloconMessageToServer.kt | 6 - .../analytics/FloconAnalyticsPlugin.kt | 20 ++- .../analytics/mapper/AnalyticsItemsMapper.kt | 12 +- .../FloconCrashReporterPlugin.kt | 7 +- .../crashreporter/model/CrashReportMapper.kt | 22 --- .../dashboard/FloconDashboardPlugin.kt | 19 +- .../ToDeviceCheckBoxValueChangedMessage.kt | 17 +- .../todevice/ToDeviceSubmittedFormMessage.kt | 15 +- .../ToDeviceSubmittedTextFieldMessage.kt | 15 +- .../fromdevice/DatabaseExecuteSqlResponse.kt | 60 ------- .../model/fromdevice/DatabaseQueryLogModel.kt | 14 +- .../fromdevice/DeviceDataBaseDataModel.kt | 8 +- .../QueryResultReceivedDataModel.kt | 8 +- .../model/todevice/DatabaseQueryMessage.kt | 15 +- .../plugins/device/FloconDevicePluginImpl.kt | 4 +- .../fromdevice/RegisterDeviceDataModel.kt | 10 +- .../flocon/plugins/files/FloconFilesPlugin.kt | 25 +-- .../model/fromdevice/FilesResultDataModel.kt | 8 +- .../todevice/ToDeviceDeleteFileMessage.kt | 15 +- .../todevice/ToDeviceDeleteFilesMessage.kt | 15 +- .../ToDeviceDeleteFolderContentMessage.kt | 15 +- .../model/todevice/ToDeviceGetFileMessage.kt | 15 +- .../model/todevice/ToDeviceGetFilesMessage.kt | 16 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 6 +- .../model/FloconPreferenceWrapper.kt | 10 +- .../SharedPreferenceValueResultDataModel.kt | 8 +- ...oDeviceEditSharedPreferenceValueMessage.kt | 15 +- ...ToDeviceGetSharedPreferenceValueMessage.kt | 15 +- .../todevice/ToDeviceGetSharedPrefsMessage.kt | 15 +- .../analytics/FloconAnalyticsPlugin.kt | 43 ----- .../analytics/builder/AnalyticsBuilder.kt | 32 ---- .../analytics/model/AnalyticsEvent.kt | 11 -- .../model/AnalyticsPropertiesConfig.kt | 11 -- .../pluginsold/analytics/model/TableItem.kt | 9 - .../pluginsold/device/FloconDevicePlugin.kt | 10 +- .../pluginsold/files/FloconFilesPlugin.kt | 5 +- .../sharedprefs/FloconSharedPrefsPlugin.kt | 5 +- .../pluginsold/tables/FloconTablesPlugin.kt | 51 ------ .../pluginsold/tables/builder/TableBuilder.kt | 20 --- .../tables/model/TableColumnConfig.kt | 11 -- .../pluginsold/tables/model/TableItem.kt | 8 - .../database/FloconDatabasePlugin.ios.kt | 1 - .../database/FloconDatabasePlugin.jvm.kt | 1 - .../gradle/gradle-daemon-jvm.properties | 13 ++ FloconAndroid/gradle/libs.versions.toml | 4 +- .../grpc-interceptor-base/build.gradle.kts | 58 +++---- .../FloconNetworkDataSource.android.kt | 9 +- .../FloconNetworkDataSourceAndroid.kt | 25 +-- .../flocon/network/core/FloconNetwork.kt | 5 +- .../datasource/FloconNetworkDataSource.kt | 4 +- .../network/core/mapper/BadQualityToJson.kt | 21 --- .../core/mapper/FloconNetworkRequestToJson.kt | 100 +++++------ .../network/core/mapper/MockResponseToJson.kt | 24 --- .../flocon/network/core/mapper/Websocket.kt | 18 +- .../core/plugin/FloconNetworkPluginImpl.kt | 32 ++-- .../okhttp-interceptor-no-op/build.gradle.kts | 47 +++-- .../okhttp-interceptor/build.gradle.kts | 62 ++++--- .../sample-android-only/build.gradle.kts | 3 + .../flocon/myapplication/MainActivity.kt | 12 +- .../table/InitializeDashboard.kt | 11 -- .../myapplication/table/InitializeTable.kt | 13 ++ FloconAndroid/settings.gradle.kts | 5 + FloconAndroid/tables-no-op/build.gradle.kts | 117 +++++++++++++ .../flocon/plugins/tables/FloconTablesNoOp.kt | 43 +++++ .../flocon/plugins/tables/model/TableItem.kt | 4 + FloconAndroid/tables/build.gradle.kts | 119 +++++++++++++ .../plugins/tables/FloconTablesPlugin.kt | 35 +++- .../flocon/plugins/tables/dsl/TableItemDsl.kt | 35 ++++ .../plugins/tables/model/TableColumnConfig.kt | 6 + .../flocon/plugins/tables/model/TableItem.kt | 20 +-- 96 files changed, 976 insertions(+), 1177 deletions(-) delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportMapper.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseExecuteSqlResponse.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/FloconTablesPlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableColumnConfig.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableItem.kt create mode 100644 FloconAndroid/gradle/gradle-daemon-jvm.properties delete mode 100644 FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeDashboard.kt create mode 100644 FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeTable.kt create mode 100644 FloconAndroid/tables-no-op/build.gradle.kts create mode 100644 FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesNoOp.kt create mode 100644 FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt create mode 100644 FloconAndroid/tables/build.gradle.kts rename FloconAndroid/{flocon => tables}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt (62%) create mode 100644 FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt create mode 100644 FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt rename FloconAndroid/{flocon => tables}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt (63%) diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt index eddb854db..7e5e49832 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/FloconDatabase.kt @@ -5,6 +5,7 @@ import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconEncoding import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.dsl.FloconMarker @@ -21,12 +22,14 @@ object FloconDatabase : FloconPluginFactory + override val providers: List, + private val encoder: FloconEncoder ) : FloconPlugin, FloconDatabasePlugin { override val key: String = Protocol.FromDevice.Database.Plugin @@ -42,7 +43,7 @@ internal class FloconDatabasePluginImpl( Protocol.ToDevice.Database.Method.GetDatabases -> sendAllDatabases(sender) Protocol.ToDevice.Database.Method.Query -> { - val queryMessage = DatabaseQueryMessage.fromJson(message = body) ?: return + val queryMessage = encoder.decode(body) ?: return val databaseModel = registeredDatabases.value .find { it.id == queryMessage.database } @@ -56,11 +57,12 @@ internal class FloconDatabasePluginImpl( sender.send( plugin = Protocol.FromDevice.Database.Plugin, method = Protocol.FromDevice.Database.Method.Query, - body = QueryResultDataModel( - requestId = queryMessage.requestId, - result = FloconEncoder.json.encodeToString(result) + body = encoder.encode( + QueryResultDataModel( + requestId = queryMessage.requestId, + result = encoder.encode(result) + ) ) - .toJson() ) } catch (t: Throwable) { FloconLogger.logError("Database parsing error", t) @@ -74,7 +76,7 @@ internal class FloconDatabasePluginImpl( } @OptIn(FloconMarker::class) - private suspend fun sendAllDatabases(sender: FloconMessageSender) { + private fun sendAllDatabases(sender: FloconMessageSender) { val databases = providers.flatMap { it.getAllDataBases(emptyList()) } val all = registeredDatabases.updateAndGet { it + databases } .map { DeviceDataBaseDataModel(id = it.id, name = it.displayName) } @@ -83,7 +85,7 @@ internal class FloconDatabasePluginImpl( sender.send( plugin = Protocol.FromDevice.Database.Plugin, method = Protocol.FromDevice.Database.Method.GetDatabases, - body = listDeviceDataBaseDataModelToJson(all), + body = encoder.encode(all), ) } catch (t: Throwable) { FloconLogger.logError("Database parsing error", t) @@ -100,13 +102,14 @@ internal class FloconDatabasePluginImpl( sender.send( plugin = Protocol.FromDevice.Database.Plugin, method = Protocol.FromDevice.Database.Method.LogQuery, - body = DatabaseQueryLogModel( - dbName = dbName, - sqlQuery = sqlQuery, - bindArgs = bindArgs.map { it.toString() }, - timestamp = currentTimeMillis() + body = encoder.encode( + DatabaseQueryLogModel( + dbName = dbName, + sqlQuery = sqlQuery, + bindArgs = bindArgs.map { it.toString() }, + timestamp = currentTimeMillis() + ) ) - .toJson() ) } catch (t: Throwable) { FloconLogger.logError("Database logging error", t) diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt index 9539a01a0..2987b5aed 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/DatabaseExecuteSqlResponse.kt @@ -1,11 +1,7 @@ package io.github.openflocon.flocon.database.core.model.fromdevice -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.json.buildJsonObject -import kotlinx.serialization.json.encodeToJsonElement -import kotlinx.serialization.json.put @Serializable sealed interface DatabaseExecuteSqlResponse : DatabaseExecuteResponse { @@ -45,24 +41,3 @@ sealed interface DatabaseExecuteSqlResponse : DatabaseExecuteResponse { val originalSql: String = "", // SQL query that caused the error (optional) ) : DatabaseExecuteSqlResponse } - -fun DatabaseExecuteSqlResponse.toJson(): String { - val jsonEncoder = FloconEncoder.json - val thisAsJson = jsonEncoder.encodeToJsonElement(this) - - val type = when (this) { - is DatabaseExecuteSqlResponse.Error -> "Error" - is DatabaseExecuteSqlResponse.Insert -> "Insert" - DatabaseExecuteSqlResponse.RawSuccess -> "RawSuccess" - is DatabaseExecuteSqlResponse.Select -> "Select" - is DatabaseExecuteSqlResponse.UpdateDelete -> "UpdateDelete" - } - - return buildJsonObject { - put("type", type) - put( - "body", - thisAsJson.toString() - ) // warning : the desktop is waiting for a string representation of the json here - }.toString() -} diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DatabaseQueryLogModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DatabaseQueryLogModel.kt index dbb7a4507..456b10fe4 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DatabaseQueryLogModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DatabaseQueryLogModel.kt @@ -1,9 +1,6 @@ package io.github.openflocon.flocon.database.core.model.fromdevice.sql -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString @Serializable data class DatabaseQueryLogModel( @@ -11,14 +8,4 @@ data class DatabaseQueryLogModel( val sqlQuery: String, val bindArgs: List?, val timestamp: Long, -) { - fun toJson(): String { - return FloconEncoder.json.encodeToString(this) - } - - companion object { - fun fromJson(json: String): DatabaseQueryLogModel { - return FloconEncoder.json.decodeFromString(json) - } - } -} +) diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt index 182dcc0e2..74891fb6c 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/DeviceDataBaseDataModel.kt @@ -1,15 +1,9 @@ package io.github.openflocon.flocon.database.core.model.fromdevice.sql -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString @Serializable data class DeviceDataBaseDataModel( val id: String, val name: String ) - -fun listDeviceDataBaseDataModelToJson(items: List) : String { - return FloconEncoder.json.encodeToString(items) -} diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt index a05cfdae1..e916b787c 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/fromdevice/sql/QueryResultReceivedDataModel.kt @@ -1,16 +1,9 @@ package io.github.openflocon.flocon.database.core.model.fromdevice.sql -import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteResponse import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString @Serializable internal data class QueryResultDataModel( val requestId: String, val result: String -) { - fun toJson(): String { - return FloconEncoder.json.encodeToString(this) - } -} +) \ No newline at end of file diff --git a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/todevice/DatabaseQueryMessage.kt b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/todevice/DatabaseQueryMessage.kt index cd81313c8..c0451d778 100644 --- a/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/todevice/DatabaseQueryMessage.kt +++ b/FloconAndroid/database/core/src/commonMain/kotlin/io/github/openflocon/flocon/database/core/model/todevice/DatabaseQueryMessage.kt @@ -1,7 +1,5 @@ package io.github.openflocon.flocon.database.core.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable @@ -9,15 +7,4 @@ data class DatabaseQueryMessage( val query: String, val requestId: String, val database: String, -) { - companion object { - fun fromJson(message: String): DatabaseQueryMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} +) diff --git a/FloconAndroid/database/room/build.gradle.kts b/FloconAndroid/database/room/build.gradle.kts index eb82a4a12..86da03840 100644 --- a/FloconAndroid/database/room/build.gradle.kts +++ b/FloconAndroid/database/room/build.gradle.kts @@ -20,11 +20,6 @@ kotlin { implementation(libs.kotlinx.coroutines.android) } } - - val jvmMain by getting { - dependencies { - } - } val iosX64Main by getting val iosArm64Main by getting @@ -42,8 +37,6 @@ android { namespace = "io.github.openflocon.flocon.database.room" } - - mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, diff --git a/FloconAndroid/database/room3-no-op/build.gradle.kts b/FloconAndroid/database/room3-no-op/build.gradle.kts index 470e7406c..60cdfa68a 100644 --- a/FloconAndroid/database/room3-no-op/build.gradle.kts +++ b/FloconAndroid/database/room3-no-op/build.gradle.kts @@ -22,6 +22,8 @@ kotlin { sourceSets { val commonMain by getting { dependencies { + implementation(project(":network:core-no-op")) + implementation(libs.ktor.client.core) implementation(project(":database:core-no-op")) } } diff --git a/FloconAndroid/database/room3/build.gradle.kts b/FloconAndroid/database/room3/build.gradle.kts index cf12f31f2..3e7385b5f 100644 --- a/FloconAndroid/database/room3/build.gradle.kts +++ b/FloconAndroid/database/room3/build.gradle.kts @@ -32,13 +32,11 @@ kotlin { val androidMain by getting { dependencies { - implementation(libs.brotli.dec) } } val jvmMain by getting { dependencies { - implementation(libs.brotli.dec) } } @@ -72,14 +70,12 @@ android { defaultConfig { minSdk = 23 } - compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } } - mavenPublishing { publishToMavenCentral(automaticRelease = true) diff --git a/FloconAndroid/datastores-no-op/build.gradle.kts b/FloconAndroid/datastores-no-op/build.gradle.kts index d89542b0c..5f4154d85 100644 --- a/FloconAndroid/datastores-no-op/build.gradle.kts +++ b/FloconAndroid/datastores-no-op/build.gradle.kts @@ -1,30 +1,30 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - id("flocon.android.library") - id("flocon.publish") -} - -android { - namespace = "io.github.openflocon.flocon.datastores" -} - - -dependencies { - - implementation(projects.flocon) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.kotlinx.coroutines.core) - - implementation(libs.androidx.datastore.preferences) -} - - -mavenPublishing { - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-datastores-no-op", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.android.library") + id("flocon.publish") +} + +android { + namespace = "io.github.openflocon.flocon.datastores" +} + + +dependencies { + + implementation(projects.flocon) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.androidx.datastore.preferences) +} + + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-datastores-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) } \ No newline at end of file diff --git a/FloconAndroid/datastores/build.gradle.kts b/FloconAndroid/datastores/build.gradle.kts index 6974dfad8..19c695d5f 100644 --- a/FloconAndroid/datastores/build.gradle.kts +++ b/FloconAndroid/datastores/build.gradle.kts @@ -1,30 +1,30 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - id("flocon.android.library") - id("flocon.publish") -} - -android { - namespace = "io.github.openflocon.flocon.datastores" -} - -dependencies { - - implementation(projects.flocon) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.kotlinx.coroutines.core) - implementation(libs.kotlinx.coroutines.android) - - implementation(libs.androidx.datastore.preferences) -} - - -mavenPublishing { - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-datastores", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.android.library") + id("flocon.publish") +} + +android { + namespace = "io.github.openflocon.flocon.datastores" +} + +dependencies { + + implementation(projects.flocon) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.coroutines.android) + + implementation(libs.androidx.datastore.preferences) +} + + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-datastores", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) } \ No newline at end of file diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt index 83c8ef103..856d79497 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt @@ -7,7 +7,9 @@ import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.core.encode import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel @@ -23,12 +25,14 @@ object FloconDeeplinks : FloconPluginFactory, private val variables: List, private val sender: FloconMessageSender, + private val encoder: FloconEncoder ) : FloconPlugin, FloconDeeplinksPlugin { override val key: String = "DEEP_LINK" @@ -56,7 +61,7 @@ internal class FloconDeeplinksPluginImpl( ) } - suspend fun registerDeeplinks( + fun registerDeeplinks( deeplinks: List, variables: List ) { @@ -64,7 +69,7 @@ internal class FloconDeeplinksPluginImpl( sender.send( plugin = Protocol.FromDevice.Deeplink.Plugin, method = Protocol.FromDevice.Deeplink.Method.GetDeeplinks, - body = createJson(deeplinks = deeplinks, variables = variables) + body = encoder.encode(createRemote(deeplinks = deeplinks, variables = variables)) ) } catch (t: Throwable) { t.printStackTrace() diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt index 89caedf6c..8e0194e42 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt @@ -1,24 +1,18 @@ package io.github.openflocon.flocon.plugins.deeplinks -import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkParameterRemote import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkRemote import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkVariableRemote import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinksRemote -import kotlinx.serialization.encodeToString -internal fun createJson( +internal fun createRemote( deeplinks: List, variables: List -): String { - val dto = DeeplinksRemote( - deeplinks = deeplinks.map(DeeplinkModel::toRemote), - variables = variables.map(DeeplinkVariable::toRemote) - ) - - return FloconEncoder.json.encodeToString(dto) -} +) = DeeplinksRemote( + deeplinks = deeplinks.map(DeeplinkModel::toRemote), + variables = variables.map(DeeplinkVariable::toRemote) +) internal fun DeeplinkModel.toRemote(): DeeplinkRemote = DeeplinkRemote( label = label, diff --git a/FloconAndroid/flocon/build.gradle.kts b/FloconAndroid/flocon/build.gradle.kts index ab063ba78..a60a1be31 100644 --- a/FloconAndroid/flocon/build.gradle.kts +++ b/FloconAndroid/flocon/build.gradle.kts @@ -1,82 +1,81 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - id("flocon.kotlin.multiplatform") - alias(libs.plugins.kotlin.serialization) - id("flocon.publish") - alias(libs.plugins.buildconfig) -} - - -kotlin { - sourceSets { - val commonMain by getting { - dependencies { - implementation(libs.kotlinx.coroutines.core) - implementation(libs.kotlinx.serialization.json) - } - } - - val androidMain by getting { - dependencies { - implementation(libs.kotlinx.coroutines.android) - implementation(libs.jakewharton.process.phoenix) - implementation("com.squareup.okhttp3:okhttp:4.12.0") - } - } - - val jvmMain by getting { - dependencies { - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.cio) - - implementation(libs.ktor.client.content.negotiation) - implementation(libs.ktor.client.logging) - implementation(libs.ktor.serialization.kotlinx.json) - } - } - - val iosX64Main by getting - val iosArm64Main by getting - val iosSimulatorArm64Main by getting - val iosMain by creating { - dependsOn(commonMain) - iosX64Main.dependsOn(this) - iosArm64Main.dependsOn(this) - iosSimulatorArm64Main.dependsOn(this) - dependencies { - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.darwin) - - implementation(libs.ktor.client.content.negotiation) - implementation(libs.ktor.client.logging) - implementation(libs.ktor.serialization.kotlinx.json) - - // to store the device id - implementation("com.russhwolf:multiplatform-settings:1.3.0") - implementation(libs.androidx.sqlite.bundled) - } - } - } -} - -buildConfig { - packageName("io.github.openflocon.flocondesktop") - - buildConfigField("APP_VERSION", System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String) -} - -android { - namespace = "io.github.openflocon.flocon" - - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - sourceSets["main"].res.srcDirs("src/androidMain/res") -} - -mavenPublishing { - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) -} \ No newline at end of file +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.kotlin.multiplatform") + alias(libs.plugins.kotlin.serialization) + id("flocon.publish") + alias(libs.plugins.buildconfig) +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.serialization.json) + } + } + + val androidMain by getting { + dependencies { + implementation(libs.kotlinx.coroutines.android) + implementation(libs.jakewharton.process.phoenix) + implementation("com.squareup.okhttp3:okhttp:4.12.0") + } + } + + val jvmMain by getting { + dependencies { + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.cio) + + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.client.logging) + implementation(libs.ktor.serialization.kotlinx.json) + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + dependencies { + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.darwin) + + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.client.logging) + implementation(libs.ktor.serialization.kotlinx.json) + + // to store the device id + implementation("com.russhwolf:multiplatform-settings:1.3.0") + implementation(libs.androidx.sqlite.bundled) + } + } + } +} + +buildConfig { + packageName("io.github.openflocon.flocondesktop") + + buildConfigField("APP_VERSION", System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String) +} + +android { + namespace = "io.github.openflocon.flocon" + + sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + sourceSets["main"].res.srcDirs("src/androidMain/res") +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt index f7e9a720a..927c2a107 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt @@ -1,16 +1,17 @@ package io.github.openflocon.flocon.pluginsold.crashreporter import android.content.Context -import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.core.decode +import io.github.openflocon.flocon.core.encode import io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporterDataSource import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel -import io.github.openflocon.flocon.plugins.crashreporter.model.crashReportFromJson -import io.github.openflocon.flocon.plugins.crashreporter.model.toJson import java.io.File internal class FloconCrashReporterDataSourceAndroid( - private val context: Context + private val context: Context, + private val encoder: FloconEncoder ) : FloconCrashReporterDataSource { private val crashesDir = File(context.filesDir, "flocon_crashes") @@ -22,7 +23,7 @@ internal class FloconCrashReporterDataSourceAndroid( override fun saveCrash(crash: CrashReportDataModel) { try { val file = File(crashesDir, "${crash.crashId}.json") - val jsonString = crash.toJson() + val jsonString = encoder.encode(crash) file.writeText(jsonString) } catch (t: Throwable) { FloconLogger.logError("Error saving crash", t) @@ -34,7 +35,7 @@ internal class FloconCrashReporterDataSourceAndroid( crashesDir.listFiles() ?.mapNotNull { file -> try { - crashReportFromJson(file.readText()) + encoder.decode(file.readText()) } catch (t: Throwable) { t.printStackTrace() null diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt index 6386e43ef..7a7c434df 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/Flocon.kt @@ -3,18 +3,20 @@ package io.github.openflocon.flocon import io.github.openflocon.flocon.FloconApp.Client +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.core.decode import io.github.openflocon.flocon.dsl.FloconMarker -import io.github.openflocon.flocon.model.floconMessageFromServerFromJson +import io.github.openflocon.flocon.model.FloconMessageFromServer import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class Flocon internal constructor( private val config: FloconConfig, - private val plugins: List + private val plugins: List, + private val encoder: FloconEncoder ) { init { @@ -68,13 +70,18 @@ class Flocon internal constructor( private fun onMessageReceived(message: String) { println("Message received : $message") - config.scope.launch(Dispatchers.IO) { - floconMessageFromServerFromJson(message)?.let { messageFromServer -> - plugins.find { it.key == messageFromServer.plugin } + config.scope.launch { + try { + val serialized = encoder.decode(message) + ?: return@launch + + plugins.find { it.key == serialized.plugin } ?.onMessageReceived( - method = messageFromServer.method, - body = messageFromServer.body, + method = serialized.method, + body = serialized.body ) + } catch (throwable: Throwable) { + throwable.printStackTrace() } } } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt index 0d74f842c..68c39be0e 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconConfiguration.kt @@ -1,16 +1,21 @@ package io.github.openflocon.flocon import io.github.openflocon.flocon.client.FloconClient +import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.SupervisorJob +import kotlinx.serialization.modules.SerializersModule +import kotlinx.serialization.modules.plus class FloconConfiguration internal constructor( private val config: FloconConfig ) { - private val plugins: MutableMap FloconPlugin> = mutableMapOf() + private val plugins: MutableMap FloconPlugin> = mutableMapOf() + + private var serializerModule = SerializersModule {} /** * Install a plugin with the given [factory] and optional [configure] block. @@ -19,21 +24,26 @@ class FloconConfiguration internal constructor( factory: FloconPluginFactory, configure: Config.() -> Unit = {} ) { - plugins[factory.pluginId] = { scope -> + plugins[factory.pluginId] = { scope, encoder -> val config = factory.createConfig(config.context) .apply { configure() } factory.install( pluginConfig = config, - floconConfig = scope + floconConfig = scope, + encoder = encoder ) } + + serializerModule += factory.createEncoding().serializersModule } - fun build(): List { - return plugins.values.map { it.invoke(config) } + fun build(encoder: FloconEncoder): List { + return plugins.values.map { it.invoke(config, encoder) } } + fun encoding() = serializerModule + } @ConsistentCopyVisibility @@ -43,17 +53,31 @@ data class FloconConfig internal constructor( val client: FloconClient ) -fun startFlocon(context: FloconContext, block: FloconConfiguration.() -> Unit) { +fun startFlocon( + context: FloconContext, + block: FloconConfiguration.() -> Unit +) { + val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) + val client = FloconClient( + context = context, + scope = scope + ) val config = FloconConfig( context = context, - scope = CoroutineScope(Dispatchers.IO + SupervisorJob()), - client = FloconClient(context = context) + scope = scope, + client = client + ) + val configuration = FloconConfiguration( + config = config, ) - val configuration = FloconConfiguration(config = config) .apply(block) + val encoder = FloconEncoder(module = configuration.encoding()) + + client.setupEncoder(encoder) Flocon( config = config, - plugins = configuration.build() + plugins = configuration.build(encoder), + encoder = encoder ) } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconEncoding.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconEncoding.kt index a5f3c0dfe..a830472c6 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconEncoding.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconEncoding.kt @@ -1,18 +1,15 @@ package io.github.openflocon.flocon -import io.github.openflocon.flocon.dsl.FloconMarker import kotlinx.serialization.modules.EmptySerializersModule import kotlinx.serialization.modules.SerializersModule -@FloconMarker interface FloconEncoding { val serializersModule: SerializersModule } -@FloconMarker -internal class DefaultEncoding() : FloconEncoding { +internal class DefaultEncoding : FloconEncoding { override val serializersModule: SerializersModule get() = EmptySerializersModule() } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt index 948f13d2b..b8f76d15e 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/FloconPlugin.kt @@ -1,5 +1,6 @@ package io.github.openflocon.flocon +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.dsl.FloconMarker /** @@ -34,7 +35,6 @@ interface FloconPluginKey { interface FloconPluginFactory : FloconPluginKey { - @FloconMarker fun createEncoding(): FloconEncoding = DefaultEncoding() /** @@ -46,6 +46,10 @@ interface FloconPluginFactory Unit, @@ -47,47 +59,53 @@ class FloconClient internal constructor( webSocketClient.disconnect() } - override suspend fun send( + override fun send( plugin: String, method: String, body: String, ) { - webSocketClient.sendMessage( - message = FloconMessageToServer( - deviceId = appInfos.deviceId, - plugin = plugin, - body = body, - appName = appInfos.appName, - appPackageName = appInfos.appPackageName, - method = method, - deviceName = appInfos.deviceName, - appInstance = appInstance, - platform = appInfos.platform, - versionName = versionName, + scope.launch { + webSocketClient.sendMessage( + encoder.encode( + FloconMessageToServer( + deviceId = appInfos.deviceId, + plugin = plugin, + body = body, + appName = appInfos.appName, + appPackageName = appInfos.appPackageName, + method = method, + deviceName = appInfos.deviceName, + appInstance = appInstance, + platform = appInfos.platform, + versionName = versionName, + ) + ) ) - .toFloconMessageToServer(), - ) + } } @FloconMarker - override suspend fun send( + override fun send( file: FloconFile, infos: FloconFileInfo, ) { - httpClient.send( - address = address, - port = FLOCON_HTTP_PORT, - file = file, - infos = infos, - - deviceId = appInfos.deviceId, - appPackageName = appInfos.appPackageName, - appInstance = appInstance, - ) + scope.launch { + httpClient.send( + address = address, + port = FLOCON_HTTP_PORT, + file = file, + infos = infos, + deviceId = appInfos.deviceId, + appPackageName = appInfos.appPackageName, + appInstance = appInstance, + ) + } } - override suspend fun sendPendingMessages() { - webSocketClient.sendPendingMessages() + override fun sendPendingMessages() { + scope.launch { + webSocketClient.sendPendingMessages() + } } companion object { diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt index cf5659731..51e738415 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconEncoder.kt @@ -1,16 +1,42 @@ package io.github.openflocon.flocon.core +import kotlinx.serialization.KSerializer import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModule +import kotlinx.serialization.serializer -object FloconEncoder { - val json = Json { +class FloconEncoder internal constructor( + val module: SerializersModule +) { + private val json = Json { ignoreUnknownKeys = true isLenient = true encodeDefaults = false + serializersModule = module + } - serializersModule = SerializersModule { + fun encode(serializer: KSerializer, body: T): String = json.encodeToString( + serializer = serializer, + value = body + ) - } - } + fun decode(serializer: KSerializer, body: String): T = json.decodeFromString( + deserializer = serializer, + string = body + ) + +} + +inline fun FloconEncoder.encode(body: T) = encode( + serializer = module.serializer(), + body = body +) + +inline fun FloconEncoder.decode(body: String): T? = try { + decode( + serializer = module.serializer(), + body = body + ) +} catch (_: Throwable) { + null } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt index 4d835a5a7..43924d572 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt @@ -7,6 +7,6 @@ import io.github.openflocon.flocon.model.FloconFileInfo internal interface FloconFileSender { @FloconMarker - suspend fun send(file: FloconFile, infos: FloconFileInfo) + fun send(file: FloconFile, infos: FloconFileInfo) } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt index a61ba4772..e2daa82cb 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconMessageSender.kt @@ -2,12 +2,12 @@ package io.github.openflocon.flocon.core interface FloconMessageSender { - suspend fun send( + fun send( plugin: String, method: String, body: String, ) - suspend fun sendPendingMessages() + fun sendPendingMessages() } \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/error/PluginNotInitialized.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/error/PluginNotInitialized.kt index 60da21935..99bbac42c 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/error/PluginNotInitialized.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/error/PluginNotInitialized.kt @@ -2,5 +2,6 @@ package io.github.openflocon.flocon.error import io.github.openflocon.flocon.dsl.FloconMarker +// Maybe remove it, and make plugins nullable to avoid app crashing @FloconMarker fun pluginNotInitialized(pluginName: String): Nothing = error("$pluginName is not initialized") \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconMessageFromServer.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconMessageFromServer.kt index 68c813b3c..393ae404d 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconMessageFromServer.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconMessageFromServer.kt @@ -1,20 +1,7 @@ package io.github.openflocon.flocon.model -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -internal fun floconMessageFromServerFromJson( - message: String, -): FloconMessageFromServer? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } -} - @Serializable internal data class FloconMessageFromServer( val plugin: String, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconMessageToServer.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconMessageToServer.kt index 8f8b081eb..50fe8f0f4 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconMessageToServer.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/model/FloconMessageToServer.kt @@ -1,8 +1,6 @@ package io.github.openflocon.flocon.model -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString @Serializable internal class FloconMessageToServer( @@ -17,7 +15,3 @@ internal class FloconMessageToServer( val platform: String, // android, ios, desktop val versionName: String, // ex: 1.3.0 ) - -internal fun FloconMessageToServer.toFloconMessageToServer(): String { - return FloconEncoder.json.encodeToString(this) -} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt index d805cbfd0..0705dc523 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -7,7 +7,10 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.core.encode +import io.github.openflocon.flocon.plugins.analytics.mapper.toRemote import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem class FloconAnalyticsConfig : FloconPluginConfig @@ -22,16 +25,19 @@ object FloconAnalytics : FloconPluginFactory) { analyticsItems.takeIf { it.isNotEmpty() }?.forEach { toSend -> try { -// sender.send( -// plugin = Protocol.FromDevice.Analytics.Plugin, -// method = Protocol.FromDevice.Analytics.Method.AddItems, -// body = analyticsItemsToJson(toSend) -// ) + sender.send( + plugin = Protocol.FromDevice.Analytics.Plugin, + method = Protocol.FromDevice.Analytics.Method.AddItems, + body = encoder.encode(listOf(toSend.toRemote())) + ) } catch (t: Throwable) { FloconLogger.logError("error on sendAnalytics", t) } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt index f93b42598..4bab74e3c 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt @@ -1,17 +1,7 @@ package io.github.openflocon.flocon.plugins.analytics.mapper -import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString - -internal fun analyticsItemsToJson(item: AnalyticsItem): String { - return FloconEncoder.json.encodeToString( - listOf( - item.toSerializable() - ) - ) -} @Serializable internal class AnalyticsItemSerializable( @@ -28,7 +18,7 @@ internal class AnalyticsPropertySerializable( val value: String, ) -internal fun AnalyticsItem.toSerializable(): AnalyticsItemSerializable { +internal fun AnalyticsItem.toRemote(): AnalyticsItemSerializable { return AnalyticsItemSerializable( id = id, analyticsTableId = analyticsTableId, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt index 8a61800e1..8fb7032d3 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt @@ -7,6 +7,7 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel import io.github.openflocon.flocon.utils.currentTimeMillis @@ -26,8 +27,7 @@ interface FloconCrashReporterPlugin : FloconPlugin { fun setupCrashHandler() } -object FloconCrashReporter : - FloconPluginFactory { +object FloconCrashReporter : FloconPluginFactory { override val name: String = "CrashReporter" override val pluginId: String = Protocol.ToDevice.Analytics.Plugin // Crash reporter is usually write-only but we can set an ID @@ -36,7 +36,8 @@ object FloconCrashReporter : override fun install( pluginConfig: FloconCrashReporterConfig, - floconConfig: FloconConfig + floconConfig: FloconConfig, + encoder: FloconEncoder ): FloconCrashReporterPlugin { val client = floconConfig.client as FloconMessageSender return FloconCrashReporterPluginImpl( diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportMapper.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportMapper.kt deleted file mode 100644 index dec1f3fb1..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportMapper.kt +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.openflocon.flocon.plugins.crashreporter.model - -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder -import kotlinx.serialization.encodeToString - -internal fun CrashReportDataModel.toJson(): String { - return FloconEncoder.json.encodeToString(this) -} - -internal fun crashReportFromJson(jsonString: String): CrashReportDataModel? { - return try { - FloconEncoder.json.decodeFromString(jsonString) - } catch (t: Throwable) { - FloconLogger.logError("Crash report parsing error", t) - null - } -} - -internal fun crashReportsListToJson(crashes: List): String { - return FloconEncoder.json.encodeToString(crashes) -} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt index ee9d2ff6f..e2b14a159 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/FloconDashboardPlugin.kt @@ -7,7 +7,9 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.core.decode import io.github.openflocon.flocon.plugins.dashboard.mapper.toJson import io.github.openflocon.flocon.plugins.dashboard.model.DashboardCallback import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig @@ -29,18 +31,17 @@ object FloconDashboard : FloconPluginFactory { - ToDeviceSubmittedFormMessage.fromJson(body)?.let { + encoder.decode(body)?.let { callbackMap[it.id]?.let { it as? DashboardCallback.FormCallback }?.actions?.invoke( it.values ) @@ -71,7 +72,7 @@ internal class FloconDashboardPluginImpl( } Protocol.ToDevice.Dashboard.Method.OnTextFieldSubmitted -> { - ToDeviceSubmittedTextFieldMessage.fromJson(body)?.let { + encoder.decode(body)?.let { callbackMap[it.id]?.let { it as? DashboardCallback.TextFieldCallback }?.action?.invoke( it.value ) @@ -79,7 +80,7 @@ internal class FloconDashboardPluginImpl( } Protocol.ToDevice.Dashboard.Method.OnCheckBoxValueChanged -> { - ToDeviceCheckBoxValueChangedMessage.fromJson(body)?.let { + encoder.decode(body)?.let { callbackMap[it.id]?.let { it as? DashboardCallback.CheckBoxCallback }?.action?.invoke( it.value ) @@ -108,7 +109,7 @@ internal class FloconDashboardPluginImpl( }, ) - dashboards.put(dashboardConfig.id, dashboardConfig) + dashboards[dashboardConfig.id] = dashboardConfig try { sender.send( diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceCheckBoxValueChangedMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceCheckBoxValueChangedMessage.kt index 0af4c78d4..59dfeb855 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceCheckBoxValueChangedMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceCheckBoxValueChangedMessage.kt @@ -1,22 +1,9 @@ package io.github.openflocon.flocon.plugins.dashboard.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable internal data class ToDeviceCheckBoxValueChangedMessage( val id: String, - val value: Boolean, -) { - companion object { - fun fromJson(message: String): ToDeviceCheckBoxValueChangedMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} \ No newline at end of file + val value: Boolean +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceSubmittedFormMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceSubmittedFormMessage.kt index ef406d702..9660934b9 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceSubmittedFormMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceSubmittedFormMessage.kt @@ -1,22 +1,9 @@ package io.github.openflocon.flocon.plugins.dashboard.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable internal data class ToDeviceSubmittedFormMessage( val id: String, val values: Map -) { - companion object { - fun fromJson(message: String): ToDeviceSubmittedFormMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceSubmittedTextFieldMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceSubmittedTextFieldMessage.kt index c789795aa..cc70676e5 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceSubmittedTextFieldMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/dashboard/model/todevice/ToDeviceSubmittedTextFieldMessage.kt @@ -1,22 +1,9 @@ package io.github.openflocon.flocon.plugins.dashboard.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable internal data class ToDeviceSubmittedTextFieldMessage( val id: String, val value: String, -) { - companion object { - fun fromJson(message: String): ToDeviceSubmittedTextFieldMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseExecuteSqlResponse.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseExecuteSqlResponse.kt deleted file mode 100644 index 5ca940607..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseExecuteSqlResponse.kt +++ /dev/null @@ -1,60 +0,0 @@ -package io.github.openflocon.flocon.plugins.database.model.fromdevice - -import io.github.openflocon.flocon.core.FloconEncoder -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.buildJsonObject -import kotlinx.serialization.json.encodeToJsonElement -import kotlinx.serialization.json.put - -@Serializable -internal sealed interface DatabaseExecuteSqlResponse { - - @Serializable - // Case for successful SELECT queries - class Select( - val columns: List, - val values: List> - ) : DatabaseExecuteSqlResponse - - // Case for successful INSERT queries - @Serializable - class Insert( - val insertedId: Long - ) : DatabaseExecuteSqlResponse - - // Case for successful UPDATE or DELETE queries - @Serializable - class UpdateDelete( - val affectedCount: Int - ) : DatabaseExecuteSqlResponse - - // Case for successful "raw" queries (CREATE TABLE, DROP TABLE, etc.) - @Serializable - object RawSuccess : DatabaseExecuteSqlResponse - - // Case for an SQL execution error - @Serializable - class Error( - val message: String, // Detailed error message - val originalSql: String, // SQL query that caused the error (optional) - ) : DatabaseExecuteSqlResponse -} - -internal fun DatabaseExecuteSqlResponse.toJson(): String { - val jsonEncoder = FloconEncoder.json - val thisAsJson = jsonEncoder.encodeToJsonElement(this) - - val type = when (this) { - is DatabaseExecuteSqlResponse.Error -> "Error" - is DatabaseExecuteSqlResponse.Insert -> "Insert" - DatabaseExecuteSqlResponse.RawSuccess -> "RawSuccess" - is DatabaseExecuteSqlResponse.Select -> "Select" - is DatabaseExecuteSqlResponse.UpdateDelete -> "UpdateDelete" - } - - return buildJsonObject { - put("type", type) - put("body", thisAsJson.toString()) // warning : the desktop is waiting for a string representation of the json here - }.toString() -} - diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseQueryLogModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseQueryLogModel.kt index e8644e329..d75c31fb5 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseQueryLogModel.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseQueryLogModel.kt @@ -1,8 +1,6 @@ package io.github.openflocon.flocon.plugins.database.model.fromdevice -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString @Serializable internal data class DatabaseQueryLogModel( @@ -10,14 +8,4 @@ internal data class DatabaseQueryLogModel( val sqlQuery: String, val bindArgs: List?, val timestamp: Long, -) { - fun toJson(): String { - return FloconEncoder.json.encodeToString(this) - } - - companion object { - fun fromJson(json: String): DatabaseQueryLogModel { - return FloconEncoder.json.decodeFromString(json) - } - } -} +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DeviceDataBaseDataModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DeviceDataBaseDataModel.kt index 6842ced6f..6a24b7ea9 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DeviceDataBaseDataModel.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DeviceDataBaseDataModel.kt @@ -1,15 +1,9 @@ package io.github.openflocon.flocon.plugins.database.model.fromdevice -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString @Serializable internal data class DeviceDataBaseDataModel( val id: String, val name: String, -) - -internal fun listDeviceDataBaseDataModelToJson(items: List) : String { - return FloconEncoder.json.encodeToString(items) -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/QueryResultReceivedDataModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/QueryResultReceivedDataModel.kt index 8ef4f899a..66f176021 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/QueryResultReceivedDataModel.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/QueryResultReceivedDataModel.kt @@ -1,15 +1,9 @@ package io.github.openflocon.flocon.plugins.database.model.fromdevice -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString @Serializable internal data class QueryResultDataModel( val requestId: String, val result: String, -) { - fun toJson(): String { - return FloconEncoder.json.encodeToString(this) - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/todevice/DatabaseQueryMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/todevice/DatabaseQueryMessage.kt index c6b353d51..27508e328 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/todevice/DatabaseQueryMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/todevice/DatabaseQueryMessage.kt @@ -1,7 +1,5 @@ package io.github.openflocon.flocon.plugins.database.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable @@ -9,15 +7,4 @@ internal data class DatabaseQueryMessage( val query: String, val requestId: String, val database: String, -) { - companion object { - fun fromJson(message: String): DatabaseQueryMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt index 8bea31768..1d7ef5463 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt @@ -7,6 +7,7 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender class FloconDeviceConfig : FloconPluginConfig @@ -21,7 +22,8 @@ object FloconDevice : FloconPluginFactory(this) - } -} \ No newline at end of file + val serial: String +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt index 3dd6df539..9910d3dfd 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt @@ -8,8 +8,10 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconFileSender import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.core.decode import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.plugins.files.model.fromdevice.FileDataModel import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceDeleteFileMessage @@ -32,13 +34,15 @@ object FloconFiles : FloconPluginFactory { override fun createConfig(context: FloconContext) = FloconFilesConfig() override fun install( pluginConfig: FloconFilesConfig, - floconConfig: FloconConfig + floconConfig: FloconConfig, + encoder: FloconEncoder ): FloconFilesPlugin { val client = floconConfig.client return FloconFilesPluginImpl( context = floconConfig.context, floconFileSender = client as FloconFileSender, - sender = client as FloconMessageSender + sender = client as FloconMessageSender, + encoder = encoder ) } } @@ -67,6 +71,7 @@ internal class FloconFilesPluginImpl( private val context: FloconContext, private val floconFileSender: FloconFileSender, private val sender: FloconMessageSender, + private val encoder: FloconEncoder ) : FloconPlugin, FloconFilesPlugin { override val key: String = "FILES" @@ -80,7 +85,7 @@ internal class FloconFilesPluginImpl( ) { when (method) { Protocol.ToDevice.Files.Method.ListFiles -> { - val listFilesMessage = ToDeviceGetFilesMessage.fromJson(message = body) ?: return + val listFilesMessage = encoder.decode(body) ?: return withFoldersSize.update { listFilesMessage.withFoldersSize } @@ -92,7 +97,7 @@ internal class FloconFilesPluginImpl( } Protocol.ToDevice.Files.Method.GetFile -> { - val getFileMessage = ToDeviceGetFileMessage.fromJson(message = body) ?: return + val getFileMessage = encoder.decode(body) ?: return fileDataSource.getFile(path = getFileMessage.path, isConstantPath = false) ?.let { file -> @@ -107,8 +112,7 @@ internal class FloconFilesPluginImpl( } Protocol.ToDevice.Files.Method.DeleteFile -> { - val deleteFilesMessage = - ToDeviceDeleteFileMessage.fromJson(message = body) ?: return + val deleteFilesMessage = encoder.decode(body) ?: return fileDataSource.deleteFile( path = deleteFilesMessage.filePath, @@ -122,8 +126,7 @@ internal class FloconFilesPluginImpl( } Protocol.ToDevice.Files.Method.DeleteFiles -> { - val deleteFilesMessage = - ToDeviceDeleteFilesMessage.fromJson(message = body) ?: return + val deleteFilesMessage = encoder.decode(body) ?: return fileDataSource.deleteFiles( path = deleteFilesMessage.filePaths, @@ -137,9 +140,7 @@ internal class FloconFilesPluginImpl( } Protocol.ToDevice.Files.Method.DeleteFolderContent -> { - val deleteFolderContentMessage = - ToDeviceDeleteFolderContentMessage.fromJson(message = body) - ?: return + val deleteFolderContentMessage = encoder.decode(body) ?: return fileDataSource.getFile( path = deleteFolderContentMessage.path, @@ -164,7 +165,7 @@ internal class FloconFilesPluginImpl( isConstantPath: Boolean, requestId: String, ) { - val files = fileDataSource.getFolderContent( + fileDataSource.getFolderContent( path = path, isConstantPath = isConstantPath, withFoldersSize = withFoldersSize.value, diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FilesResultDataModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FilesResultDataModel.kt index 1d4400323..768ac68de 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FilesResultDataModel.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FilesResultDataModel.kt @@ -1,15 +1,9 @@ package io.github.openflocon.flocon.plugins.files.model.fromdevice -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString @Serializable internal data class FilesResultDataModel( val requestId: String, val files: List, -) { - fun toJson(): String { - return FloconEncoder.json.encodeToString(this) - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFileMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFileMessage.kt index d8e161301..9332cca48 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFileMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFileMessage.kt @@ -1,7 +1,5 @@ package io.github.openflocon.flocon.plugins.files.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable @@ -10,16 +8,5 @@ internal data class ToDeviceDeleteFileMessage( val parentPath: String, val filePath: String, val isConstantParentPath: Boolean, // ex: context.files / context.caches -) { - companion object { - fun fromJson(message: String): ToDeviceDeleteFileMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFilesMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFilesMessage.kt index 465d374d5..757dddda7 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFilesMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFilesMessage.kt @@ -1,7 +1,5 @@ package io.github.openflocon.flocon.plugins.files.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable @@ -10,15 +8,4 @@ internal data class ToDeviceDeleteFilesMessage( val parentPath: String, val filePaths: List, val isConstantParentPath: Boolean, // ex: context.files / context.caches -) { - companion object { - fun fromJson(message: String): ToDeviceDeleteFilesMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFolderContentMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFolderContentMessage.kt index a2eebd4d2..677eab215 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFolderContentMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFolderContentMessage.kt @@ -1,7 +1,5 @@ package io.github.openflocon.flocon.plugins.files.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable @@ -9,16 +7,5 @@ internal data class ToDeviceDeleteFolderContentMessage( val requestId: String, val path: String, val isConstantPath: Boolean, // ex: context.files / context.caches -) { - companion object { - fun fromJson(message: String): ToDeviceDeleteFolderContentMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFileMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFileMessage.kt index 7e95a9c28..6c4ae0260 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFileMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFileMessage.kt @@ -1,22 +1,9 @@ package io.github.openflocon.flocon.plugins.files.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable internal data class ToDeviceGetFileMessage( val requestId: String, val path: String, -) { - companion object { - fun fromJson(message: String): ToDeviceGetFileMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFilesMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFilesMessage.kt index d8ba615d7..97774eb4a 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFilesMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFilesMessage.kt @@ -1,7 +1,5 @@ package io.github.openflocon.flocon.plugins.files.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable @@ -10,18 +8,6 @@ internal data class ToDeviceGetFilesMessage( val path: String, val isConstantPath: Boolean, // ex: context.files / context.caches val withFoldersSize: Boolean = false, -) { - companion object { - fun fromJson(message: String): ToDeviceGetFilesMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt index 79ba0dd4d..60a90ebe8 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt @@ -7,6 +7,7 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconSharedPreferenceModel @@ -22,7 +23,8 @@ object FloconPreferences : FloconPluginFactory): String { - val value = items.map { PreferencesDescriptor(it.name) } - return FloconEncoder.json.encodeToString(value) -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/SharedPreferenceValueResultDataModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/SharedPreferenceValueResultDataModel.kt index a7f90e476..76ece2ed6 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/SharedPreferenceValueResultDataModel.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/SharedPreferenceValueResultDataModel.kt @@ -1,16 +1,10 @@ package io.github.openflocon.flocon.plugins.sharedprefs.model.fromdevice -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString @Serializable internal data class SharedPreferenceValueResultDataModel( val requestId: String, val sharedPreferenceName: String, val rows: List, -) { - fun toJson(): String { - return FloconEncoder.json.encodeToString(this) - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceEditSharedPreferenceValueMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceEditSharedPreferenceValueMessage.kt index 30023f510..14c33a941 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceEditSharedPreferenceValueMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceEditSharedPreferenceValueMessage.kt @@ -1,7 +1,5 @@ package io.github.openflocon.flocon.plugins.sharedprefs.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable @@ -15,15 +13,4 @@ internal data class ToDeviceEditSharedPreferenceValueMessage( val booleanValue: Boolean? = null, val longValue: Long? = null, val setStringValue: Set? = null, -) { - companion object { - fun fromJson(jsonString: String): ToDeviceEditSharedPreferenceValueMessage? { - return try { - FloconEncoder.json.decodeFromString(jsonString) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPreferenceValueMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPreferenceValueMessage.kt index b30a6a43c..daaa128fa 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPreferenceValueMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPreferenceValueMessage.kt @@ -1,22 +1,9 @@ package io.github.openflocon.flocon.plugins.sharedprefs.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable internal data class ToDeviceGetSharedPreferenceValueMessage( val requestId: String, val sharedPreferenceName: String, -) { - companion object { - fun fromJson(message: String): ToDeviceGetSharedPreferenceValueMessage? { - return try { - return FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPrefsMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPrefsMessage.kt index d549c1ced..00d03f9a2 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPrefsMessage.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPrefsMessage.kt @@ -1,21 +1,8 @@ package io.github.openflocon.flocon.plugins.sharedprefs.model.todevice -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable @Serializable internal data class ToDeviceGetSharedPrefsMessage( val requestId: String, -) { - companion object { - fun fromJson(message: String): ToDeviceGetSharedPrefsMessage? { - return try { - FloconEncoder.json.decodeFromString(message) - } catch (t: Throwable) { - FloconLogger.logError("parsing issue", t) - null - } - } - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt deleted file mode 100644 index 63f2a342e..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt +++ /dev/null @@ -1,43 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.analytics - -import io.github.openflocon.flocon.FloconApp -import io.github.openflocon.flocon.FloconConfig -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginConfig -import io.github.openflocon.flocon.FloconPluginFactory -import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem - -class FloconAnalyticsConfig : FloconPluginConfig - -/** - * Flocon Analytics Plugin. - */ -object FloconAnalytics : FloconPluginFactory { - override fun createConfig(context: FloconContext) = TODO() - override fun install( - pluginConfig: FloconAnalyticsConfig, - floconConfig: FloconConfig - ): FloconAnalyticsPlugin = TODO() - - override val name: String = "" - override val pluginId: String = "ANALYTICS" -} -// -//fun floconAnalytics(analyticsName: String) : AnalyticsBuilder { -// return AnalyticsBuilder( -// analyticsTableId = analyticsName, -// analyticsPlugin = FloconApp.instance?.client?.analyticsPlugin, -// ) -//} - -//fun FloconApp.analytics(analyticsName: String): AnalyticsBuilder { -// return AnalyticsBuilder( -// analyticsTableId = analyticsName, -// analyticsPlugin = this.client?.analyticsPlugin, -// ) -//} - -interface FloconAnalyticsPlugin : FloconPlugin { - fun registerAnalytics(analyticsItems: List) -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt deleted file mode 100644 index f59c51620..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt +++ /dev/null @@ -1,32 +0,0 @@ -@file:OptIn(ExperimentalUuidApi::class) - -package io.github.openflocon.flocon.pluginsold.analytics.builder - -import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsPlugin -import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsEvent -import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem -import io.github.openflocon.flocon.utils.currentTimeMillis -import kotlin.uuid.ExperimentalUuidApi -import kotlin.uuid.Uuid - -class AnalyticsBuilder( - val analyticsTableId: String, - private val analyticsPlugin: FloconAnalyticsPlugin?, -) { - fun logEvents(vararg events: AnalyticsEvent) { - this.logEvents(events.toList()) - } - - fun logEvents(events: List) { - val analyticsItems = events.map { - AnalyticsItem( - id = Uuid.random().toString(), - analyticsTableId = analyticsTableId, - eventName = it.eventName, - createdAt = currentTimeMillis(), - properties = it.properties, - ) - } - analyticsPlugin?.registerAnalytics(analyticsItems) - } -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt deleted file mode 100644 index 10a608249..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.analytics.model - -data class AnalyticsEvent( - val eventName: String, - val properties: List, -) { - constructor( - eventName: String, - vararg properties: AnalyticsPropertiesConfig, - ) : this(eventName, properties.toList()) -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt deleted file mode 100644 index de6d93092..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.analytics.model - -data class AnalyticsPropertiesConfig( - val name: String, - val value: String, -) - -infix fun String.analyticsProperty(value: String) = AnalyticsPropertiesConfig( - name = this, - value = value, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt deleted file mode 100644 index c23f13409..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.analytics.model - -data class AnalyticsItem( - val id: String, - val analyticsTableId: String, - val eventName: String, - val createdAt: Long, - val properties: List, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt index c0b9cfa2b..47aecce92 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/device/FloconDevicePlugin.kt @@ -1,6 +1,11 @@ package io.github.openflocon.flocon.pluginsold.device -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.core.FloconEncoder class FloconDeviceConfig : FloconPluginConfig @@ -14,7 +19,8 @@ object FloconDevice : FloconPluginFactory() @@ -22,7 +22,8 @@ object FloconFiles : FloconPluginFactory { override fun install( pluginConfig: FloconFilesConfig, - floconConfig: FloconConfig + floconConfig: FloconConfig, + encoder: FloconEncoder ): FloconFilesPlugin { TODO("Not yet implemented") } diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt index dec9be9dc..f9d06c388 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt @@ -1,11 +1,11 @@ package io.github.openflocon.flocon.pluginsold.sharedprefs -import io.github.openflocon.flocon.FloconApp import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconSharedPreferenceModel class FloconPreferencesConfig : FloconPluginConfig @@ -21,7 +21,8 @@ object FloconPreferences : FloconPluginFactory { - override fun createConfig(context: FloconContext): FloconTableConfig { - TODO("Not yet implemented") - } - - override fun install( - pluginConfig: FloconTableConfig, - floconConfig: FloconConfig - ): FloconTablePlugin { - TODO("Not yet implemented") - } - - override val name: String - get() = TODO("Not yet implemented") - override val pluginId: String - get() = TODO("Not yet implemented") -} - -//fun floconTable(tableName: String) : TableBuilder { -// return TableBuilder( -// tableId = tableName, -// tablePlugin = FloconApp.instance?.client?.tablePlugin, -// ) -//} -// -//fun FloconApp.table(tableName: String): TableBuilder { -// return TableBuilder( -// tableId = tableName, -// tablePlugin = this.client?.tablePlugin, -// ) -//} - -interface FloconTablePlugin : FloconPlugin { - fun registerItems(tableItems: List) -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt deleted file mode 100644 index 484c85387..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:OptIn(ExperimentalUuidApi::class) - -package io.github.openflocon.flocon.pluginsold.tables.builder - -import kotlin.uuid.ExperimentalUuidApi - -//class TableBuilder( -// val tableName: String, -// private val tablePlugin: FloconTablePlugin?, -//) { -// fun log(vararg columns: TableColumnConfig) { -// val dashboardConfig = TableItem( -// id = Uuid.random().toString(), -// name = tableName, -// columns = columns.toList(), -// createdAt = currentTimeMillis(), -// ) -// tablePlugin?.registerTable(dashboardConfig) -// } -//} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableColumnConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableColumnConfig.kt deleted file mode 100644 index 857f2d8a8..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableColumnConfig.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.tables.model - -data class TableColumnConfig( - val columnName: String, - val value: String, -) - -infix fun String.toParam(value: String) = TableColumnConfig( - columnName = this, - value = value, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableItem.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableItem.kt deleted file mode 100644 index ba4485e34..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/model/TableItem.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.tables.model - -data class TableItem( - val id: String, - val name: String, - val createdAt: Long, - val columns: List, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.ios.kt b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.ios.kt index 73cb6ac63..bdf02ebb7 100644 --- a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.ios.kt +++ b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.ios.kt @@ -5,7 +5,6 @@ import androidx.sqlite.driver.NativeSQLiteDriver import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel import io.github.openflocon.flocon.plugins.database.model.FloconFileDatabaseModel -import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseExecuteSqlResponse import io.github.openflocon.flocon.plugins.database.model.fromdevice.DeviceDataBaseDataModel import platform.Foundation.NSFileManager import platform.posix.close diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.jvm.kt b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.jvm.kt index 01708953c..dc49389d3 100644 --- a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.jvm.kt +++ b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.jvm.kt @@ -3,7 +3,6 @@ package io.github.openflocon.flocon.plugins.database import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.plugins.database.model.FloconDatabaseModel import io.github.openflocon.flocon.plugins.database.model.FloconFileDatabaseModel -import io.github.openflocon.flocon.plugins.database.model.fromdevice.DatabaseExecuteSqlResponse import io.github.openflocon.flocon.plugins.database.model.fromdevice.DeviceDataBaseDataModel import java.io.File import java.sql.Connection diff --git a/FloconAndroid/gradle/gradle-daemon-jvm.properties b/FloconAndroid/gradle/gradle-daemon-jvm.properties new file mode 100644 index 000000000..cfd299ab0 --- /dev/null +++ b/FloconAndroid/gradle/gradle-daemon-jvm.properties @@ -0,0 +1,13 @@ +#This file is generated by updateDaemonJvm +toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/584d2f01a3c6e59ebb9478a182f5f714/redirect +toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/7352c4c0c11b2db21fdd7541204de287/redirect +toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/584d2f01a3c6e59ebb9478a182f5f714/redirect +toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/7352c4c0c11b2db21fdd7541204de287/redirect +toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/12ed6bcbab330f7afa37d16220b272a3/redirect +toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/a7e1d8e6e800a81047d4aec26156ef5c/redirect +toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/584d2f01a3c6e59ebb9478a182f5f714/redirect +toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/7352c4c0c11b2db21fdd7541204de287/redirect +toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/3676ee7aa5095d7f22645eb0f22ca159/redirect +toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/fc98f2d434c5796fe6ec02f0f22957b3/redirect +toolchainVendor=AZUL +toolchainVersion=17 diff --git a/FloconAndroid/gradle/libs.versions.toml b/FloconAndroid/gradle/libs.versions.toml index e0c4d0368..2fba6fb4b 100644 --- a/FloconAndroid/gradle/libs.versions.toml +++ b/FloconAndroid/gradle/libs.versions.toml @@ -4,7 +4,7 @@ apollo = "4.0.0" coilCompose = "3.2.0" compose = "1.9.0" datastorePreferences = "1.1.7" -kotlin = "2.1.0" +kotlin = "2.1.21" mavenPublish = "0.34.0" coreKtx = "1.16.0" junit = "4.13.2" @@ -26,7 +26,7 @@ grpc = "1.73.0" protobufPlugin = "0.9.5" grpcKotlin = "1.4.3" protobuf = "4.26.1" -ksp = "2.1.0-1.0.29" +ksp = "2.1.21-2.0.2" processPhoenix = "3.0.0" sqlite = "2.6.2" sqliteJdbc = "3.50.3.0" diff --git a/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts b/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts index fb3e112e3..e6a51bc83 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts +++ b/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts @@ -1,30 +1,30 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - id("flocon.android.library") - id("flocon.publish") -} - - -android { - namespace = "io.github.openflocon.flocon.grpc.base" -} - - -dependencies { - implementation(projects.flocon) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.kotlinx.coroutines.core) - - implementation(libs.grpc.android) -} - - -mavenPublishing { - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-grpc-interceptor-base", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + id("flocon.android.library") + id("flocon.publish") +} + + +android { + namespace = "io.github.openflocon.flocon.grpc.base" +} + + +dependencies { + implementation(projects.flocon) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.grpc.android) +} + + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-grpc-interceptor-base", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) } \ No newline at end of file diff --git a/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.android.kt b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.android.kt index 5c424d559..844d10f8a 100644 --- a/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.android.kt +++ b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.android.kt @@ -1,7 +1,12 @@ package io.github.openflocon.flocon.network.core.datasource import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.core.FloconEncoder internal actual inline fun buildFloconNetworkDataSource( - context: FloconContext -): FloconNetworkDataSource = FloconNetworkDataSourceAndroid(context = context.context) \ No newline at end of file + context: FloconContext, + encoder: FloconEncoder +): FloconNetworkDataSource = FloconNetworkDataSourceAndroid( + context = context.context, + encoder = encoder +) \ No newline at end of file diff --git a/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt index 07a3bd15a..7c763823d 100644 --- a/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt +++ b/FloconAndroid/network/core/src/androidMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSourceAndroid.kt @@ -2,25 +2,25 @@ package io.github.openflocon.flocon.network.core.datasource import android.content.Context import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig -import io.github.openflocon.flocon.network.core.mapper.parseMockResponses -import io.github.openflocon.flocon.network.core.mapper.toJsonString -import io.github.openflocon.flocon.network.core.mapper.writeMockResponsesToJson -import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_BAD_CONFIG_JSON -import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_MOCKS_JSON +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.core.decode +import io.github.openflocon.flocon.core.encode import io.github.openflocon.flocon.network.core.model.BadQualityConfig import io.github.openflocon.flocon.network.core.model.MockNetworkResponse +import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_BAD_CONFIG_JSON +import io.github.openflocon.flocon.network.core.plugin.FLOCON_NETWORK_MOCKS_JSON import java.io.File import java.io.FileInputStream import java.io.FileOutputStream internal class FloconNetworkDataSourceAndroid( - private val context: Context + private val context: Context, + private val encoder: FloconEncoder ) : FloconNetworkDataSource { override fun saveMocksToFile(mocks: List) { try { val file = File(context.filesDir, FLOCON_NETWORK_MOCKS_JSON) - val jsonString = writeMockResponsesToJson(mocks = mocks) + val jsonString = encoder.encode(mocks) FileOutputStream(file).use { it.write(jsonString.toByteArray()) } @@ -39,7 +39,9 @@ internal class FloconNetworkDataSourceAndroid( val jsonString = FileInputStream(file).use { it.readBytes().toString(Charsets.UTF_8) } - parseMockResponses(jsonString = jsonString) + + encoder.decode>(jsonString) + .orEmpty() } catch (t: Throwable) { FloconLogger.logError("issue in loadMocksFromFile", t) emptyList() @@ -56,7 +58,8 @@ internal class FloconNetworkDataSourceAndroid( val jsonString = FileInputStream(file).use { it.readBytes().toString(Charsets.UTF_8) } - parseBadQualityConfig(jsonString = jsonString) + + encoder.decode(jsonString) } catch (t: Throwable) { FloconLogger.logError("issue in loadBadNetworkConfig", t) null @@ -69,7 +72,7 @@ internal class FloconNetworkDataSourceAndroid( if (config == null) { file.delete() } else { - val jsonString = config.toJsonString() + val jsonString = encoder.encode(config) FileOutputStream(file).use { it.write(jsonString.toByteArray()) } diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt index a9eac6957..0484e2975 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/FloconNetwork.kt @@ -7,6 +7,7 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.error.pluginNotInitialized @@ -50,12 +51,14 @@ object FloconNetwork : FloconPluginFactory( - toSerializable() - ) -} - -internal fun parseBadQualityConfig(jsonString: String): BadQualityConfig? { - return try { - val parsed = FloconEncoder.json.decodeFromString( - jsonString - ) - parsed.toDomain() - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "bad connection network parsing issue", t) - null - } -} @Serializable internal class BadQualityConfigSerializable( diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt index 329115850..666a358f2 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/FloconNetworkRequestToJson.kt @@ -2,12 +2,10 @@ package io.github.openflocon.flocon.network.core.mapper -import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.network.core.model.FloconNetworkCallRequest import io.github.openflocon.flocon.network.core.model.FloconNetworkCallResponse import io.github.openflocon.flocon.network.core.model.FloconWebSocketEvent import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid @@ -25,20 +23,17 @@ internal class FloconNetworkCallRequestRemote( val requestSize: Long?, ) -internal fun FloconNetworkCallRequest.floconNetworkCallRequestToJson(): String { - val remoteModel = FloconNetworkCallRequestRemote( - floconCallId = floconCallId, - floconNetworkType = floconNetworkType, - isMocked = isMocked, - url = request.url, - method = request.method, - startTime = request.startTime, - requestBody = request.body, - requestHeaders = request.headers, - requestSize = request.size - ) - return FloconEncoder.json.encodeToString(remoteModel) -} +internal fun FloconNetworkCallRequest.floconNetworkCallRequestToJson() = FloconNetworkCallRequestRemote( + floconCallId = floconCallId, + floconNetworkType = floconNetworkType, + isMocked = isMocked, + url = request.url, + method = request.method, + startTime = request.startTime, + requestBody = request.body, + requestHeaders = request.headers, + requestSize = request.size +) @Serializable internal class FloconNetworkCallResponseRemote( @@ -57,27 +52,23 @@ internal class FloconNetworkCallResponseRemote( val isImage: Boolean, ) -internal fun FloconNetworkCallResponse.floconNetworkCallResponseToJson(): String { - val remoteModel = FloconNetworkCallResponseRemote( - floconCallId = floconCallId, - floconNetworkType = floconNetworkType, - isMocked = isMocked, - durationMs = durationMs, - responseHttpCode = response.httpCode, - responseGrpcStatus = response.grpcStatus, - responseContentType = response.contentType, - responseBody = response.body, - responseHeaders = response.headers, - requestHeaders = response.requestHeaders?.takeIf { - it.isNotEmpty() - }, - responseSize = response.size, - isImage = response.isImage, - responseError = response.error, - ) - - return FloconEncoder.json.encodeToString(remoteModel) -} +internal fun FloconNetworkCallResponse.floconNetworkCallResponseToJson() = FloconNetworkCallResponseRemote( + floconCallId = floconCallId, + floconNetworkType = floconNetworkType, + isMocked = isMocked, + durationMs = durationMs, + responseHttpCode = response.httpCode, + responseGrpcStatus = response.grpcStatus, + responseContentType = response.contentType, + responseBody = response.body, + responseHeaders = response.headers, + requestHeaders = response.requestHeaders?.takeIf { + it.isNotEmpty() + }, + responseSize = response.size, + isImage = response.isImage, + responseError = response.error, +) @Serializable internal class FloconWebSocketEventRemote( @@ -90,22 +81,19 @@ internal class FloconWebSocketEventRemote( val error: String?, ) -internal fun FloconWebSocketEvent.floconNetworkWebSocketEventToJson(): String { - val remoteModel = FloconWebSocketEventRemote( - id = Uuid.random().toString(), - event = when (event) { - FloconWebSocketEvent.Event.Closed -> "closed" - FloconWebSocketEvent.Event.Closing -> "closing" - FloconWebSocketEvent.Event.Error -> "error" - FloconWebSocketEvent.Event.ReceiveMessage -> "received" - FloconWebSocketEvent.Event.SendMessage -> "sent" - FloconWebSocketEvent.Event.Open -> "open" - }, - url = websocketUrl, - size = size, - timestamp = timeStamp, - message = message, - error = error?.message - ) - return FloconEncoder.json.encodeToString(remoteModel) -} \ No newline at end of file +internal fun FloconWebSocketEvent.floconNetworkWebSocketEventToJson() = FloconWebSocketEventRemote( + id = Uuid.random().toString(), + event = when (event) { + FloconWebSocketEvent.Event.Closed -> "closed" + FloconWebSocketEvent.Event.Closing -> "closing" + FloconWebSocketEvent.Event.Error -> "error" + FloconWebSocketEvent.Event.ReceiveMessage -> "received" + FloconWebSocketEvent.Event.SendMessage -> "sent" + FloconWebSocketEvent.Event.Open -> "open" + }, + url = websocketUrl, + size = size, + timestamp = timeStamp, + message = message, + error = error?.message +) \ No newline at end of file diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt index 76b00f959..dc3cf7079 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt @@ -28,20 +28,6 @@ internal class MockNetworkResponseDataModel( ) } - -internal fun parseMockResponses(jsonString: String): List { - try { - val remote = - FloconEncoder.json.decodeFromString>(jsonString) - return remote.mapNotNull { - it.toDomain() - } - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "mock network parsing issue", t) - return emptyList() - } -} - internal fun MockNetworkResponseDataModel.toDomain(): MockNetworkResponse? { return MockNetworkResponse( expectation = MockNetworkResponse.Expectation( @@ -76,16 +62,6 @@ private fun MockNetworkResponseDataModel.mapResponseToDomain(): MockNetworkRespo } } - -internal fun writeMockResponsesToJson(mocks: List): String { - return try { - FloconEncoder.json.encodeToString(mocks.map { it.toRemote() }) - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "mock network writing issue", t) - return "[]" - } -} - private fun MockNetworkResponse.toRemote(): MockNetworkResponseDataModel { return MockNetworkResponseDataModel( expectation = MockNetworkResponseDataModel.Expectation( diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/Websocket.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/Websocket.kt index 8eeaeb931..967ed6ff1 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/Websocket.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/Websocket.kt @@ -1,25 +1,9 @@ package io.github.openflocon.flocon.network.core.mapper -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString @Serializable internal class WebSocketMockMessage( val id: String, val message: String, -) - -internal fun webSocketIdsToJsonArray(ids: Collection): String { - return FloconEncoder.json.encodeToString(ids) -} - -internal fun parseWebSocketMockMessage(jsonString: String): WebSocketMockMessage? { - try { - return FloconEncoder.json.decodeFromString(jsonString) - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "mock wesocket network parsing issue", t) - } - return null -} \ No newline at end of file +) \ No newline at end of file diff --git a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt index c95e76a53..15b43004d 100644 --- a/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt +++ b/FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/plugin/FloconNetworkPluginImpl.kt @@ -4,16 +4,16 @@ import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.core.decode +import io.github.openflocon.flocon.core.encode +import io.github.openflocon.flocon.network.core.FloconNetworkPlugin import io.github.openflocon.flocon.network.core.datasource.buildFloconNetworkDataSource +import io.github.openflocon.flocon.network.core.mapper.WebSocketMockMessage import io.github.openflocon.flocon.network.core.mapper.floconNetworkCallRequestToJson import io.github.openflocon.flocon.network.core.mapper.floconNetworkCallResponseToJson import io.github.openflocon.flocon.network.core.mapper.floconNetworkWebSocketEventToJson -import io.github.openflocon.flocon.network.core.mapper.parseBadQualityConfig -import io.github.openflocon.flocon.network.core.mapper.parseMockResponses -import io.github.openflocon.flocon.network.core.mapper.parseWebSocketMockMessage -import io.github.openflocon.flocon.network.core.mapper.webSocketIdsToJsonArray -import io.github.openflocon.flocon.network.core.FloconNetworkPlugin import io.github.openflocon.flocon.network.core.model.BadQualityConfig import io.github.openflocon.flocon.network.core.model.FloconNetworkCallRequest import io.github.openflocon.flocon.network.core.model.FloconNetworkCallResponse @@ -32,11 +32,12 @@ internal const val FLOCON_NETWORK_BAD_CONFIG_JSON = "flocon_network_bad_config.j internal class FloconNetworkPluginImpl( context: FloconContext, private var sender: FloconMessageSender, - private val coroutineScope: CoroutineScope + private val coroutineScope: CoroutineScope, + private val encoder: FloconEncoder ) : FloconPlugin, FloconNetworkPlugin { override val key: String = "NETWORK" - private val dataSource = buildFloconNetworkDataSource(context) + private val dataSource = buildFloconNetworkDataSource(context = context, encoder = encoder) private val websocketListeners = MutableStateFlow>(emptyMap()) @@ -56,7 +57,7 @@ internal class FloconNetworkPluginImpl( sender.send( plugin = Protocol.FromDevice.Network.Plugin, method = Protocol.FromDevice.Network.Method.LogNetworkCallRequest, - body = request.floconNetworkCallRequestToJson(), + body = encoder.encode(request.floconNetworkCallRequestToJson()) ) } } catch (t: Throwable) { @@ -71,7 +72,7 @@ internal class FloconNetworkPluginImpl( sender.send( plugin = Protocol.FromDevice.Network.Plugin, method = Protocol.FromDevice.Network.Method.LogNetworkCallResponse, - body = response.floconNetworkCallResponseToJson(), + body = encoder.encode(response.floconNetworkCallResponseToJson()) ) } catch (t: Throwable) { FloconLogger.logError("Network json mapping error", t) @@ -87,7 +88,7 @@ internal class FloconNetworkPluginImpl( sender.send( plugin = Protocol.FromDevice.Network.Plugin, method = Protocol.FromDevice.Network.Method.LogWebSocketEvent, - body = event.floconNetworkWebSocketEventToJson(), + body = encoder.encode(event.floconNetworkWebSocketEventToJson()) ) } catch (t: Throwable) { FloconLogger.logError("Network json mapping error", t) @@ -101,19 +102,20 @@ internal class FloconNetworkPluginImpl( ) { when (method) { Protocol.ToDevice.Network.Method.SetupMocks -> { - val setup = parseMockResponses(jsonString = body) + val setup = encoder.decode>(body) + .orEmpty() _mocks.update { setup } dataSource.saveMocksToFile(mocks) } Protocol.ToDevice.Network.Method.SetupBadNetworkConfig -> { - val config = parseBadQualityConfig(jsonString = body) + val config = encoder.decode(body) _badQualityConfig.update { config } dataSource.saveBadNetworkConfig(config) } Protocol.ToDevice.Network.Method.WebsocketMockMessage -> { - val message = parseWebSocketMockMessage(jsonString = body) + val message = encoder.decode(body) if (message != null) { websocketListeners.value[message.id]?.onMessage(message.message) } @@ -135,11 +137,11 @@ internal class FloconNetworkPluginImpl( updateWebSocketIds() } - private suspend fun updateWebSocketIds() { + private fun updateWebSocketIds() { sender.send( plugin = Protocol.FromDevice.Network.Plugin, method = Protocol.FromDevice.Network.Method.RegisterWebSocketIds, - body = webSocketIdsToJsonArray(ids = websocketListeners.value.keys), + body = encoder.encode(websocketListeners.value.keys) ) } diff --git a/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts b/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts index aa77a7815..094f66831 100644 --- a/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts +++ b/FloconAndroid/network/okhttp-interceptor-no-op/build.gradle.kts @@ -1,25 +1,22 @@ -plugins { - id("flocon.android.library") - id("flocon.publish") -} - - -android { - namespace = "io.github.openflocon.flocon.okhttp" -} - - -dependencies { - implementation(projects.network.coreNoOp) - implementation(platform(libs.okhttp.bom)) - implementation(libs.okhttp) -} - - -mavenPublishing { - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-okhttp-interceptor-no-op", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) -} \ No newline at end of file +plugins { + id("flocon.android.library") + id("flocon.publish") +} + +android { + namespace = "io.github.openflocon.flocon.okhttp" +} + +dependencies { + implementation(projects.network.coreNoOp) + implementation(platform(libs.okhttp.bom)) + implementation(libs.okhttp) +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-okhttp-interceptor-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} diff --git a/FloconAndroid/network/okhttp-interceptor/build.gradle.kts b/FloconAndroid/network/okhttp-interceptor/build.gradle.kts index 7816ec3d0..ca055d13d 100644 --- a/FloconAndroid/network/okhttp-interceptor/build.gradle.kts +++ b/FloconAndroid/network/okhttp-interceptor/build.gradle.kts @@ -1,32 +1,30 @@ -plugins { - id("flocon.android.library") - id("flocon.publish") -} - -android { - namespace = "io.github.openflocon.flocon.okhttp" -} - -dependencies { - - api(projects.network.core) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.kotlinx.coroutines.core) - implementation(libs.kotlinx.coroutines.android) - - implementation(platform(libs.okhttp.bom)) - implementation(libs.okhttp) - implementation(libs.brotli.dec) - - testImplementation(libs.junit) -} - - -mavenPublishing { - coordinates( - groupId = project.property("floconGroupId") as String, - artifactId = "flocon-okhttp-interceptor", - version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String - ) -} \ No newline at end of file +plugins { + id("flocon.android.library") + id("flocon.publish") +} + +android { + namespace = "io.github.openflocon.flocon.okhttp" +} + +dependencies { + api(projects.network.core) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.coroutines.android) + + implementation(platform(libs.okhttp.bom)) + implementation(libs.okhttp) + implementation(libs.brotli.dec) + + testImplementation(libs.junit) +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-okhttp-interceptor", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} diff --git a/FloconAndroid/sample-android-only/build.gradle.kts b/FloconAndroid/sample-android-only/build.gradle.kts index 9d077af4c..05691da2a 100644 --- a/FloconAndroid/sample-android-only/build.gradle.kts +++ b/FloconAndroid/sample-android-only/build.gradle.kts @@ -88,6 +88,9 @@ dependencies { debugImplementation(projects.deeplinks) releaseImplementation(projects.deeplinksNoOp) + debugImplementation(projects.tables) + releaseImplementation(projects.tablesNoOp) + debugImplementation(project(":database:room")) releaseImplementation(project(":database:room-no-op")) debugImplementation(project(":database:room3")) diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt index acc9d0f03..4c26b2858 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt @@ -22,18 +22,20 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.database.core.FloconDatabase -import io.github.openflocon.flocon.database.room.floconRegisterDatabase import io.github.openflocon.flocon.database.room.room import io.github.openflocon.flocon.myapplication.database.DogDatabase import io.github.openflocon.flocon.myapplication.database.initializeDatabases import io.github.openflocon.flocon.myapplication.database.initializeInMemoryDatabases import io.github.openflocon.flocon.myapplication.database.model.DogEntity import io.github.openflocon.flocon.myapplication.grpc.GrpcController +import io.github.openflocon.flocon.myapplication.table.initializeTable import io.github.openflocon.flocon.myapplication.ui.ImagesListView import io.github.openflocon.flocon.myapplication.ui.theme.MyApplicationTheme import io.github.openflocon.flocon.network.core.FloconNetwork import io.github.openflocon.flocon.okhttp.FloconOkhttpInterceptor +import io.github.openflocon.flocon.plugins.analytics.FloconAnalytics import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks +import io.github.openflocon.flocon.plugins.tables.FloconTable import io.github.openflocon.flocon.startFlocon import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -87,7 +89,7 @@ class MainActivity : ComponentActivity() { // val graphQlTester = GraphQlTester(client = okHttpClient) // initializeImages(context = this, okHttpClient = okHttpClient) // initializeDashboard(this) -// initializeTable(this) + initializeTable() setContent { MyApplicationTheme { @@ -223,9 +225,7 @@ class MainActivity : ComponentActivity() { install(FloconDeeplinks) { deeplink("flocon://home") deeplink("flocon://test") - deeplink( - "flocon://user/[userId]" - ) { + deeplink("flocon://user/[userId]") { label = "User" "userId" withAutoComplete listOf("Florent", "David", "Guillaume") } @@ -236,6 +236,8 @@ class MainActivity : ComponentActivity() { } install(FloconNetwork) + install(FloconTable) + install(FloconAnalytics) install(FloconDatabase) { room() } diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeDashboard.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeDashboard.kt deleted file mode 100644 index 7a5050f0c..000000000 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeDashboard.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon.myapplication.table - -import android.content.Context - -fun initializeTable(context: Context) { -// Flocon.table("analytics").log( -// "name" toParam "nameValue", -// "value1" toParam "value1Value", -// "value2" toParam "value2Value", -// ) -} \ No newline at end of file diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeTable.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeTable.kt new file mode 100644 index 000000000..067f69081 --- /dev/null +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeTable.kt @@ -0,0 +1,13 @@ +package io.github.openflocon.flocon.myapplication.table + +import io.github.openflocon.flocon.Flocon +import io.github.openflocon.flocon.plugins.tables.dsl.table +import io.github.openflocon.flocon.plugins.tables.tablePlugin + +fun initializeTable() { + Flocon.tablePlugin.table("analytics") { + column("name", "nameValue") + column("value1", "value1Value") + column("value2", "value2Value") + } +} \ No newline at end of file diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index 2521b305b..3f81b8483 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -9,6 +9,9 @@ pluginManagement { gradlePluginPortal() } } +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.10.0" +} dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) @@ -34,6 +37,8 @@ include(":datastores") include(":datastores-no-op") include(":deeplinks") include(":deeplinks-no-op") +include(":tables") +include(":tables-no-op") include(":network:core") include(":network:core-no-op") include(":database:core") diff --git a/FloconAndroid/tables-no-op/build.gradle.kts b/FloconAndroid/tables-no-op/build.gradle.kts new file mode 100644 index 000000000..60335b38d --- /dev/null +++ b/FloconAndroid/tables-no-op/build.gradle.kts @@ -0,0 +1,117 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +android { + namespace = "io.github.openflocon.flocon.tables.noop" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-tables-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Tables No-Op" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesNoOp.kt b/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesNoOp.kt new file mode 100644 index 000000000..49946f2fc --- /dev/null +++ b/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesNoOp.kt @@ -0,0 +1,43 @@ +package io.github.openflocon.flocon.plugins.tables + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.plugins.tables.model.TableItem + +interface FloconTablePlugin : FloconPlugin { + fun registerItems(tableItems: List) +} + +class FloconTableConfig internal constructor() : FloconPluginConfig + +object FloconTable : FloconPluginFactory { + override val name: String = "Table" + override val pluginId: String = Protocol.ToDevice.Table.Plugin + override fun createConfig(context: FloconContext) = FloconTableConfig() + override fun install( + pluginConfig: FloconTableConfig, + floconConfig: FloconConfig + ): FloconTablePlugin { + return FloconTablePluginNoOp + } +} + +private object FloconTablePluginNoOp : FloconTablePlugin { + override val key: String = "TABLE" + + override suspend fun onMessageReceived(method: String, body: String) { + // no-op + } + + override suspend fun onConnectedToServer() { + // no-op + } + + override fun registerItems(tableItems: List) { + // no-op + } +} diff --git a/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt b/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt new file mode 100644 index 000000000..bbe3ca64c --- /dev/null +++ b/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt @@ -0,0 +1,4 @@ +package io.github.openflocon.flocon.plugins.tables.model + +class TableItem { +} \ No newline at end of file diff --git a/FloconAndroid/tables/build.gradle.kts b/FloconAndroid/tables/build.gradle.kts new file mode 100644 index 000000000..4b6551370 --- /dev/null +++ b/FloconAndroid/tables/build.gradle.kts @@ -0,0 +1,119 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) + alias(libs.plugins.kotlin.serialization) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.kotlinx.serialization.json) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +android { + namespace = "io.github.openflocon.flocon.tables" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-tables", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Tables" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt similarity index 62% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt rename to FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt index 8c63f218d..251372092 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt @@ -1,5 +1,6 @@ package io.github.openflocon.flocon.plugins.tables +import io.github.openflocon.flocon.Flocon import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger @@ -7,9 +8,13 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.core.encode +import io.github.openflocon.flocon.dsl.FloconMarker +import io.github.openflocon.flocon.error.pluginNotInitialized import io.github.openflocon.flocon.plugins.tables.model.TableItem -import io.github.openflocon.flocon.plugins.tables.model.tableItemListToJson +import io.github.openflocon.flocon.plugins.tables.model.toRemote class FloconTableConfig : FloconPluginConfig @@ -23,16 +28,24 @@ object FloconTable : FloconPluginFactory { override fun createConfig(context: FloconContext) = FloconTableConfig() override fun install( pluginConfig: FloconTableConfig, - floconConfig: FloconConfig + floconConfig: FloconConfig, + encoder: FloconEncoder ): FloconTablePlugin { return FloconTablePluginImpl( - sender = floconConfig.client as FloconMessageSender + sender = floconConfig.client as FloconMessageSender, + encoder = encoder ) + .also { FloconTablePluginImpl.plugin = it } } } +@OptIn(FloconMarker::class) +val Flocon.Companion.tablePlugin: FloconTablePlugin + get() = FloconTablePluginImpl.plugin ?: pluginNotInitialized("table") + internal class FloconTablePluginImpl( private val sender: FloconMessageSender, + private val encoder: FloconEncoder ) : FloconPlugin, FloconTablePlugin { override val key: String = "TABLE" @@ -53,13 +66,17 @@ internal class FloconTablePluginImpl( private fun sendTable(tableItems: List) { try { -// sender.send( -// plugin = Protocol.FromDevice.Table.Plugin, -// method = Protocol.FromDevice.Table.Method.AddItems, -// body = tableItemListToJson(tableItems).toString() -// ) + sender.send( + plugin = Protocol.FromDevice.Table.Plugin, + method = Protocol.FromDevice.Table.Method.AddItems, + body = encoder.encode(tableItems.map(TableItem::toRemote)) + ) } catch (t: Throwable) { FloconLogger.logError("Table json mapping error", t) } } -} \ No newline at end of file + + companion object { + var plugin: FloconTablePlugin? = null + } +} diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt new file mode 100644 index 000000000..caf8fb1a5 --- /dev/null +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt @@ -0,0 +1,35 @@ +@file:OptIn(ExperimentalUuidApi::class, ExperimentalTime::class) + +package io.github.openflocon.flocon.plugins.tables.dsl + +import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin +import io.github.openflocon.flocon.plugins.tables.model.TableColumnConfig +import io.github.openflocon.flocon.plugins.tables.model.TableItem +import kotlin.time.Clock +import kotlin.time.ExperimentalTime +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid + +fun FloconTablePlugin.table(tableName: String, block: TableItemDefinition.() -> Unit = {}) { + val item = TableItemDefinition(tableName).apply(block) + .build() + + registerItems(tableItems = listOf(item)) +} + +class TableItemDefinition internal constructor(private val name: String) { + + private val columns: MutableList = mutableListOf() + + fun column(name: String, value: String) { + columns.add(TableColumnConfig(columnName = name, value = value)) + } + + internal fun build() = TableItem( + id = Uuid.random().toHexString(), + name = name, + createdAt = Clock.System.now().toEpochMilliseconds(), + columns = emptyList() + ) + +} \ No newline at end of file diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt new file mode 100644 index 000000000..5d784687a --- /dev/null +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon.plugins.tables.model + +data class TableColumnConfig( + val columnName: String, + val value: String, +) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt similarity index 63% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt rename to FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt index 81467899b..187a65732 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt @@ -1,8 +1,6 @@ package io.github.openflocon.flocon.plugins.tables.model -import io.github.openflocon.flocon.core.FloconEncoder import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString data class TableItem( val id: String, @@ -11,22 +9,6 @@ data class TableItem( val columns: List, ) -data class TableColumnConfig( - val columnName: String, - val value: String, -) - -infix fun String.toParam(value: String) = TableColumnConfig( - columnName = this, - value = value, -) - -// --- JSON Serialization --- - -internal fun tableItemListToJson(items: Collection): String { - return FloconEncoder.json.encodeToString(items.map { it.toRemote() }) -} - @Serializable internal class TableItemRemote( val id: String, @@ -53,4 +35,4 @@ internal fun TableItem.toRemote(): TableItemRemote = TableItemRemote( internal fun TableColumnConfig.toRemote(): TableColumnRemote = TableColumnRemote( column = columnName, value = value -) \ No newline at end of file +) From 3ab7cd8f316293fcde0bc8f3a43e89783adeb23a Mon Sep 17 00:00:00 2001 From: Raphael Teyssandier Date: Wed, 13 May 2026 14:17:42 +0200 Subject: [PATCH 24/35] 2.0.0 - Analytics (#511) --- .../analytics-no-op/build.gradle.kts | 98 +++++++++++++++++ .../plugins/analytics/FloconAnalyticsNoOp.kt | 47 ++++++++ .../analytics/builder/AnalyticsBuilder.kt | 17 +++ .../plugins/analytics/model/AnalyticsEvent.kt | 11 ++ .../plugins/analytics/model/AnalyticsItem.kt | 9 ++ .../model/AnalyticsPropertiesConfig.kt | 11 ++ FloconAndroid/analytics/build.gradle.kts | 100 ++++++++++++++++++ .../analytics/FloconAnalyticsPlugin.kt | 67 ++++++++++++ .../analytics/builder/AnalyticsBuilder.kt | 32 ++++++ .../analytics/mapper/AnalyticsItemsMapper.kt | 44 ++++++++ .../plugins/analytics/model/AnalyticsEvent.kt | 11 ++ .../plugins/analytics/model/AnalyticsItem.kt | 9 ++ .../model/AnalyticsPropertiesConfig.kt | 11 ++ .../database/room3-no-op/build.gradle.kts | 3 - .../analytics/FloconAnalyticsPlugin.kt | 44 ++++++++ .../analytics/builder/AnalyticsBuilder.kt | 32 ++++++ .../analytics/model/AnalyticsEvent.kt | 11 ++ .../model/AnalyticsPropertiesConfig.kt | 11 ++ .../pluginsold/analytics/model/TableItem.kt | 9 ++ .../pluginsold/tables/builder/TableBuilder.kt | 20 ++++ .../core/noop/mapper/MockResponseToJson.kt | 4 + .../network/core/noop/mapper/Websocket.kt | 4 + FloconAndroid/tables-no-op/build.gradle.kts | 3 + FloconAndroid/tables/build.gradle.kts | 2 + .../plugins/tables/FloconTablesPlugin.kt | 1 + .../flocon/plugins/tables/dsl/TableItemDsl.kt | 4 +- .../plugins/tables/model/TableColumnConfig.kt | 2 +- .../flocon/plugins/tables/model/TableItem.kt | 3 +- 28 files changed, 613 insertions(+), 7 deletions(-) create mode 100644 FloconAndroid/analytics-no-op/build.gradle.kts create mode 100644 FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsNoOp.kt create mode 100644 FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt create mode 100644 FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt create mode 100644 FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt create mode 100644 FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt create mode 100644 FloconAndroid/analytics/build.gradle.kts create mode 100644 FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt create mode 100644 FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt create mode 100644 FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt create mode 100644 FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt create mode 100644 FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt create mode 100644 FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt diff --git a/FloconAndroid/analytics-no-op/build.gradle.kts b/FloconAndroid/analytics-no-op/build.gradle.kts new file mode 100644 index 000000000..a7e3f4f02 --- /dev/null +++ b/FloconAndroid/analytics-no-op/build.gradle.kts @@ -0,0 +1,98 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.analytics.noop" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-analytics-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Analytics No-Op" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsNoOp.kt b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsNoOp.kt new file mode 100644 index 000000000..3e4204f84 --- /dev/null +++ b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsNoOp.kt @@ -0,0 +1,47 @@ +package io.github.openflocon.flocon.plugins.analytics + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem + +class FloconAnalyticsConfig : FloconPluginConfig + +interface FloconAnalyticsPlugin : FloconPlugin { + fun registerAnalytics(analyticsItems: List) +} + +object FloconAnalytics : FloconPluginFactory { + override val name: String = "Analytics" + override val pluginId: String = Protocol.ToDevice.Analytics.Plugin + override fun createConfig(context: FloconContext) = FloconAnalyticsConfig() + override fun install( + pluginConfig: FloconAnalyticsConfig, + floconConfig: FloconConfig + ): FloconAnalyticsPlugin { + return FloconAnalyticsNoOpImpl() + } +} + +internal class FloconAnalyticsNoOpImpl : FloconPlugin, FloconAnalyticsPlugin { + override val key: String + get() = Protocol.ToDevice.Analytics.Plugin + + override suspend fun onMessageReceived( + method: String, + body: String, + ) { + // no op + } + + override suspend fun onConnectedToServer() { + // no op + } + + override fun registerAnalytics(analyticsItems: List) { + // no op + } +} diff --git a/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt new file mode 100644 index 000000000..2ae74f610 --- /dev/null +++ b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt @@ -0,0 +1,17 @@ +package io.github.openflocon.flocon.plugins.analytics.builder + +import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsEvent + +class AnalyticsBuilder( + val analyticsTableId: String, + private val analyticsPlugin: FloconAnalyticsPlugin?, +) { + fun logEvents(vararg events: AnalyticsEvent) { + // no-op + } + + fun logEvents(events: List) { + // no-op + } +} diff --git a/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt new file mode 100644 index 000000000..b0de88ffa --- /dev/null +++ b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.plugins.analytics.model + +data class AnalyticsEvent( + val eventName: String, + val properties: List, +) { + constructor( + eventName: String, + vararg properties: AnalyticsPropertiesConfig, + ) : this(eventName, properties.toList()) +} diff --git a/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt new file mode 100644 index 000000000..55c7285cd --- /dev/null +++ b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.plugins.analytics.model + +data class AnalyticsItem( + val id: String, + val analyticsTableId: String, + val eventName: String, + val createdAt: Long, + val properties: List, +) diff --git a/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt new file mode 100644 index 000000000..f36d72382 --- /dev/null +++ b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.plugins.analytics.model + +data class AnalyticsPropertiesConfig( + val name: String, + val value: String, +) + +infix fun String.analyticsProperty(value: String) = AnalyticsPropertiesConfig( + name = this, + value = value, +) diff --git a/FloconAndroid/analytics/build.gradle.kts b/FloconAndroid/analytics/build.gradle.kts new file mode 100644 index 000000000..870ee0a77 --- /dev/null +++ b/FloconAndroid/analytics/build.gradle.kts @@ -0,0 +1,100 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) + alias(libs.plugins.kotlin.serialization) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(libs.kotlinx.serialization.json) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.analytics" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-analytics", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon Analytics" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt new file mode 100644 index 000000000..9e2fe0f5c --- /dev/null +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -0,0 +1,67 @@ +package io.github.openflocon.flocon.plugins.analytics + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconLogger +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem + +class FloconAnalyticsConfig : FloconPluginConfig + +interface FloconAnalyticsPlugin : FloconPlugin { + fun registerAnalytics(analyticsItems: List) +} + +object FloconAnalytics : FloconPluginFactory { + override val name: String = "Analytics" + override val pluginId: String = Protocol.ToDevice.Analytics.Plugin + override fun createConfig(context: FloconContext) = FloconAnalyticsConfig() + override fun install( + pluginConfig: FloconAnalyticsConfig, + floconConfig: FloconConfig + ): FloconAnalyticsPlugin { + return FloconAnalyticsPluginImpl( + sender = floconConfig.client as FloconMessageSender + ) + } +} + +internal class FloconAnalyticsPluginImpl( + private val sender: FloconMessageSender, +) : FloconPlugin, FloconAnalyticsPlugin { + override val key: String + get() = Protocol.ToDevice.Analytics.Plugin + + override suspend fun onMessageReceived( + method: String, + body: String, + ) { + // no op + } + + override suspend fun onConnectedToServer() { + // no op + } + + override fun registerAnalytics(analyticsItems: List) { + sendAnalytics(analyticsItems) + } + + private fun sendAnalytics(analyticsItems: List) { + analyticsItems.takeIf { it.isNotEmpty() }?.forEach { toSend -> + try { +// sender.send( +// plugin = Protocol.FromDevice.Analytics.Plugin, +// method = Protocol.FromDevice.Analytics.Method.AddItems, +// body = analyticsItemsToJson(toSend) +// ) + } catch (t: Throwable) { + FloconLogger.logError("error on sendAnalytics", t) + } + } + } +} diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt new file mode 100644 index 000000000..d4aef5b4d --- /dev/null +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt @@ -0,0 +1,32 @@ +@file:OptIn(ExperimentalUuidApi::class) + +package io.github.openflocon.flocon.plugins.analytics.builder + +import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsEvent +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem +import io.github.openflocon.flocon.utils.currentTimeMillis +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid + +class AnalyticsBuilder( + val analyticsTableId: String, + private val analyticsPlugin: FloconAnalyticsPlugin?, +) { + fun logEvents(vararg events: AnalyticsEvent) { + this.logEvents(events.toList()) + } + + fun logEvents(events: List) { + val analyticsItems = events.map { + AnalyticsItem( + id = Uuid.random().toString(), + analyticsTableId = analyticsTableId, + eventName = it.eventName, + createdAt = currentTimeMillis(), + properties = it.properties, + ) + } + analyticsPlugin?.registerAnalytics(analyticsItems) + } +} diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt new file mode 100644 index 000000000..e8ec738ee --- /dev/null +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt @@ -0,0 +1,44 @@ +package io.github.openflocon.flocon.plugins.analytics.mapper + +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString + +internal fun analyticsItemsToJson(item: AnalyticsItem): String { + return FloconEncoder.json.encodeToString( + listOf( + item.toSerializable() + ) + ) +} + +@Serializable +internal class AnalyticsItemSerializable( + val id: String, + val analyticsTableId: String, + val eventName: String, + val createdAt: Long, + val properties: List, +) + +@Serializable +internal class AnalyticsPropertySerializable( + val name: String, + val value: String, +) + +internal fun AnalyticsItem.toSerializable(): AnalyticsItemSerializable { + return AnalyticsItemSerializable( + id = id, + analyticsTableId = analyticsTableId, + eventName = eventName, + createdAt = createdAt, + properties = properties.map { + AnalyticsPropertySerializable( + name = it.name, + value = it.value + ) + } + ) +} diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt new file mode 100644 index 000000000..b0de88ffa --- /dev/null +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.plugins.analytics.model + +data class AnalyticsEvent( + val eventName: String, + val properties: List, +) { + constructor( + eventName: String, + vararg properties: AnalyticsPropertiesConfig, + ) : this(eventName, properties.toList()) +} diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt new file mode 100644 index 000000000..55c7285cd --- /dev/null +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.plugins.analytics.model + +data class AnalyticsItem( + val id: String, + val analyticsTableId: String, + val eventName: String, + val createdAt: Long, + val properties: List, +) diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt new file mode 100644 index 000000000..f36d72382 --- /dev/null +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.plugins.analytics.model + +data class AnalyticsPropertiesConfig( + val name: String, + val value: String, +) + +infix fun String.analyticsProperty(value: String) = AnalyticsPropertiesConfig( + name = this, + value = value, +) diff --git a/FloconAndroid/database/room3-no-op/build.gradle.kts b/FloconAndroid/database/room3-no-op/build.gradle.kts index 60cdfa68a..6507ac962 100644 --- a/FloconAndroid/database/room3-no-op/build.gradle.kts +++ b/FloconAndroid/database/room3-no-op/build.gradle.kts @@ -67,14 +67,12 @@ android { ) } } - compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } } - mavenPublishing { publishToMavenCentral(automaticRelease = true) @@ -90,7 +88,6 @@ mavenPublishing { version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - pom { name = "Flocon Room 3 Implementation No-Op" description = project.property("floconDescription") as String diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt new file mode 100644 index 000000000..e8bd6f068 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt @@ -0,0 +1,44 @@ +package io.github.openflocon.flocon.pluginsold.analytics + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem + +class FloconAnalyticsConfig : FloconPluginConfig + +/** + * Flocon Analytics Plugin. + */ +object FloconAnalytics : FloconPluginFactory { + override fun createConfig(context: FloconContext) = TODO() + override fun install( + pluginConfig: FloconAnalyticsConfig, + floconConfig: FloconConfig, + encoder: FloconEncoder + ): FloconAnalyticsPlugin = TODO() + + override val name: String = "" + override val pluginId: String = "ANALYTICS" +} +// +//fun floconAnalytics(analyticsName: String) : AnalyticsBuilder { +// return AnalyticsBuilder( +// analyticsTableId = analyticsName, +// analyticsPlugin = FloconApp.instance?.client?.analyticsPlugin, +// ) +//} + +//fun FloconApp.analytics(analyticsName: String): AnalyticsBuilder { +// return AnalyticsBuilder( +// analyticsTableId = analyticsName, +// analyticsPlugin = this.client?.analyticsPlugin, +// ) +//} + +interface FloconAnalyticsPlugin : FloconPlugin { + fun registerAnalytics(analyticsItems: List) +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt new file mode 100644 index 000000000..f59c51620 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt @@ -0,0 +1,32 @@ +@file:OptIn(ExperimentalUuidApi::class) + +package io.github.openflocon.flocon.pluginsold.analytics.builder + +import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsPlugin +import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsEvent +import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem +import io.github.openflocon.flocon.utils.currentTimeMillis +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid + +class AnalyticsBuilder( + val analyticsTableId: String, + private val analyticsPlugin: FloconAnalyticsPlugin?, +) { + fun logEvents(vararg events: AnalyticsEvent) { + this.logEvents(events.toList()) + } + + fun logEvents(events: List) { + val analyticsItems = events.map { + AnalyticsItem( + id = Uuid.random().toString(), + analyticsTableId = analyticsTableId, + eventName = it.eventName, + createdAt = currentTimeMillis(), + properties = it.properties, + ) + } + analyticsPlugin?.registerAnalytics(analyticsItems) + } +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt new file mode 100644 index 000000000..10a608249 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.pluginsold.analytics.model + +data class AnalyticsEvent( + val eventName: String, + val properties: List, +) { + constructor( + eventName: String, + vararg properties: AnalyticsPropertiesConfig, + ) : this(eventName, properties.toList()) +} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt new file mode 100644 index 000000000..de6d93092 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.pluginsold.analytics.model + +data class AnalyticsPropertiesConfig( + val name: String, + val value: String, +) + +infix fun String.analyticsProperty(value: String) = AnalyticsPropertiesConfig( + name = this, + value = value, +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt new file mode 100644 index 000000000..c23f13409 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocon.pluginsold.analytics.model + +data class AnalyticsItem( + val id: String, + val analyticsTableId: String, + val eventName: String, + val createdAt: Long, + val properties: List, +) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt new file mode 100644 index 000000000..484c85387 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/tables/builder/TableBuilder.kt @@ -0,0 +1,20 @@ +@file:OptIn(ExperimentalUuidApi::class) + +package io.github.openflocon.flocon.pluginsold.tables.builder + +import kotlin.uuid.ExperimentalUuidApi + +//class TableBuilder( +// val tableName: String, +// private val tablePlugin: FloconTablePlugin?, +//) { +// fun log(vararg columns: TableColumnConfig) { +// val dashboardConfig = TableItem( +// id = Uuid.random().toString(), +// name = tableName, +// columns = columns.toList(), +// createdAt = currentTimeMillis(), +// ) +// tablePlugin?.registerTable(dashboardConfig) +// } +//} \ No newline at end of file diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt index 7ab3d09bf..2f96ac6ab 100644 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt @@ -1,4 +1,8 @@ +<<<<<<<< HEAD:FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt +package io.github.openflocon.flocon.network.core.mapper +======== package io.github.openflocon.flocon.network.core.noop.mapper +>>>>>>>> 2.0.0:FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt index 8cd994774..567a072cf 100644 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt @@ -1,4 +1,8 @@ +<<<<<<<< HEAD:FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/Websocket.kt +package io.github.openflocon.flocon.network.core.mapper +======== package io.github.openflocon.flocon.network.core.noop.mapper +>>>>>>>> 2.0.0:FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder diff --git a/FloconAndroid/tables-no-op/build.gradle.kts b/FloconAndroid/tables-no-op/build.gradle.kts index 60335b38d..58c5af864 100644 --- a/FloconAndroid/tables-no-op/build.gradle.kts +++ b/FloconAndroid/tables-no-op/build.gradle.kts @@ -68,12 +68,14 @@ android { ) } } + compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } } + mavenPublishing { publishToMavenCentral(automaticRelease = true) @@ -89,6 +91,7 @@ mavenPublishing { version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) + pom { name = "Flocon Tables No-Op" description = project.property("floconDescription") as String diff --git a/FloconAndroid/tables/build.gradle.kts b/FloconAndroid/tables/build.gradle.kts index 4b6551370..f6cb5e71d 100644 --- a/FloconAndroid/tables/build.gradle.kts +++ b/FloconAndroid/tables/build.gradle.kts @@ -30,11 +30,13 @@ kotlin { val androidMain by getting { dependencies { + implementation(libs.brotli.dec) } } val jvmMain by getting { dependencies { + implementation(libs.brotli.dec) } } diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt index 251372092..e71bf2ee7 100644 --- a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt @@ -15,6 +15,7 @@ import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.error.pluginNotInitialized import io.github.openflocon.flocon.plugins.tables.model.TableItem import io.github.openflocon.flocon.plugins.tables.model.toRemote +import kotlin.collections.map class FloconTableConfig : FloconPluginConfig diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt index caf8fb1a5..98802bc8a 100644 --- a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt @@ -3,8 +3,8 @@ package io.github.openflocon.flocon.plugins.tables.dsl import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin -import io.github.openflocon.flocon.plugins.tables.model.TableColumnConfig import io.github.openflocon.flocon.plugins.tables.model.TableItem +import io.github.openflocon.flocon.pluginsold.tables.model.TableColumnConfig import kotlin.time.Clock import kotlin.time.ExperimentalTime import kotlin.uuid.ExperimentalUuidApi @@ -28,7 +28,7 @@ class TableItemDefinition internal constructor(private val name: String) { internal fun build() = TableItem( id = Uuid.random().toHexString(), name = name, - createdAt = Clock.System.now().toEpochMilliseconds(), + createdAt = Clock.System.now().toEpochMilliseconds(), columns = emptyList() ) diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt index 5d784687a..aa1c2f5a7 100644 --- a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.tables.model +package io.github.openflocon.flocon.pluginsold.tables.model data class TableColumnConfig( val columnName: String, diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt index 187a65732..9eaff3359 100644 --- a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt @@ -1,5 +1,6 @@ package io.github.openflocon.flocon.plugins.tables.model +import io.github.openflocon.flocon.pluginsold.tables.model.TableColumnConfig import kotlinx.serialization.Serializable data class TableItem( @@ -29,7 +30,7 @@ internal fun TableItem.toRemote(): TableItemRemote = TableItemRemote( id = id, name = name, createdAt = createdAt, - columns = columns.map { it.toRemote() } + columns = columns.map(TableColumnConfig::toRemote) ) internal fun TableColumnConfig.toRemote(): TableColumnRemote = TableColumnRemote( From 0ad3ca9f161dd06137558273259adbd4f409ef85 Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 25 Mar 2026 23:15:16 +0100 Subject: [PATCH 25/35] feat/2.0.0/wasm --- FloconAndroid/AGENT.md | 52 +++++++++++++++++ .../database/core-no-op/build.gradle.kts | 6 ++ FloconAndroid/database/core/build.gradle.kts | 6 ++ .../core/model/FloconDatabaseModel.wasmJs.kt | 13 +++++ .../database/room3-no-op/build.gradle.kts | 7 +++ FloconAndroid/database/room3/build.gradle.kts | 36 ++++++++---- .../room3/FloconRoom3DatabaseConfig.kt | 0 .../room3/FloconRoom3DatabaseModel.kt | 0 .../FloconRoom3DatabaseProviderImpl.wasmJs.kt | 20 +++++++ .../datastores-no-op/build.gradle.kts | 52 +++++++++++++++++ .../{main => androidMain}/AndroidManifest.xml | 0 .../model/FloconDatastorePreference.kt | 8 +-- FloconAndroid/datastores/build.gradle.kts | 58 ++++++++++++++++++- .../{main => androidMain}/AndroidManifest.xml | 0 .../model/FloconDatastorePreference.kt | 18 +++--- .../deeplinks-no-op/build.gradle.kts | 1 + FloconAndroid/deeplinks/build.gradle.kts | 6 ++ FloconAndroid/flocon-no-op/build.gradle.kts | 1 + .../github/openflocon/flocon/Flocon.wasmJs.kt | 8 +++ FloconAndroid/flocon/build.gradle.kts | 1 + .../flocon/utils/DispatcherUtils.android.kt | 8 +++ .../flocon/utils/DispatcherUtils.kt | 8 +++ .../flocon/utils/DispatcherUtils.ios.kt | 8 +++ .../flocon/utils/DispatcherUtils.jvm.kt | 8 +++ .../openflocon/flocon/FloconContext.wasmJs.kt | 3 + .../openflocon/flocon/FloconCore.wasmJs.kt | 4 ++ .../openflocon/flocon/FloconFile.wasmJs.kt | 6 ++ .../openflocon/flocon/FloconLogger.wasmJs.kt | 18 ++++++ .../openflocon/flocon/ServerHost.wasmJs.kt | 3 + .../openflocon/flocon/core/AppInfos.wasmJs.kt | 11 ++++ .../FloconCrashReporterDataSource.wasmJs.kt | 16 +++++ .../device/FloconDevicePluginImpl.wasmJs.kt | 6 ++ .../plugins/device/GetAppIconUtils.wasmJs.kt | 5 ++ .../plugins/files/FloconFilesPlugin.wasmJs.kt | 22 +++++++ .../FloconSharedPrefsPlugin.wasmJs.kt | 10 ++++ .../flocon/utils/DispatcherUtils.wasmJs.kt | 8 +++ .../flocon/utils/PlatformUtils.wasmJs.kt | 11 ++++ .../websocket/FloconHttpClient.wasmJs.kt | 18 ++++++ .../websocket/FloconWebSocketClient.wasmJs.kt | 19 ++++++ .../network/core-no-op/build.gradle.kts | 6 ++ FloconAndroid/network/core/build.gradle.kts | 6 ++ .../FloconNetworkDataSource.wasmJs.kt | 14 +++++ .../ktor-interceptor-no-op/build.gradle.kts | 6 ++ .../network/ktor-interceptor/build.gradle.kts | 6 ++ .../openflocon/flocon/ktor/Utils.wasmJs.kt | 6 ++ 45 files changed, 504 insertions(+), 25 deletions(-) create mode 100644 FloconAndroid/AGENT.md create mode 100644 FloconAndroid/database/core/src/wasmJsMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.wasmJs.kt rename FloconAndroid/database/room3/src/{commonMain => roomMain}/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseConfig.kt (100%) rename FloconAndroid/database/room3/src/{commonMain => roomMain}/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseModel.kt (100%) create mode 100644 FloconAndroid/database/room3/src/wasmJsMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.wasmJs.kt rename FloconAndroid/datastores-no-op/src/{main => androidMain}/AndroidManifest.xml (100%) rename FloconAndroid/datastores-no-op/src/{main => commonMain}/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt (72%) rename FloconAndroid/datastores/src/{main => androidMain}/AndroidManifest.xml (100%) rename FloconAndroid/datastores/src/{main => commonMain}/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt (86%) create mode 100644 FloconAndroid/flocon-no-op/src/wasmJsMain/kotlin/io/github/openflocon/flocon/Flocon.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.android.kt create mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.kt create mode 100644 FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.ios.kt create mode 100644 FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.jvm.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconContext.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconCore.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconFile.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconLogger.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/ServerHost.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/core/AppInfos.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.wasmJs.kt create mode 100644 FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/websocket/FloconWebSocketClient.wasmJs.kt create mode 100644 FloconAndroid/network/core/src/wasmJsMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.wasmJs.kt create mode 100644 FloconAndroid/network/ktor-interceptor/src/wasmJsMain/kotlin/io/github/openflocon/flocon/ktor/Utils.wasmJs.kt diff --git a/FloconAndroid/AGENT.md b/FloconAndroid/AGENT.md new file mode 100644 index 000000000..de224d978 --- /dev/null +++ b/FloconAndroid/AGENT.md @@ -0,0 +1,52 @@ +# Flocon Project Overview + +Flocon is a modular, plugin-based framework built with **Kotlin Multiplatform (KMP)**. It provides a standardized way to integrate common cross-cutting concerns like networking, database access, datastores, and deep linking into applications. + +## 🚀 Key Features + +- **Modular Architecture**: Separate modules for different functionalities (network, database, etc.). +- **Plugin System**: Easily extensible with "no-op" variants for testing and modularity. +- **KMP Support**: Targets Android, iOS, JVM, and WasmJs. +- **Modern Tech Stack**: Uses Room 3, Ktor, OkHttp, gRPC, and Compose Multiplatform. + +## 🛠 Technical Stack + +- **Kotlin**: 2.1.0 +- **Build System**: Gradle with Version Catalog (`libs.versions.toml`). +- **Dependency Injection**: Manual / Constructor injection (based on current exploration). +- **Asynchronous Programming**: Kotlin Coroutines & Flow. +- **Networking**: Ktor 3.x, OkHttp 4.x, gRPC 1.70.x. +- **Database**: Room 2.x & Room 3.0.0-alpha01. +- **UI**: Compose Multiplatform 1.9.0. + +## 📂 Module Structure + +- `:flocon`: Core library providing the plugin registration and context management. +- `:database`: + - `:database:core`: Abstractions for database providers. + - `:database:room` / `:database:room3`: Room-based implementations. +- `:network`: + - `:network:core`: Core networking abstractions. + - `:network:okhttp-interceptor` / `:network:ktor-interceptor`: Client-specific interceptors. +- `:grpc`: + - `:grpc-interceptor`: Interceptors for gRPC calls. +- `:datastores`: Modules for Typed DataStore integration. +- `:deeplinks`: Abstractions and implementations for handling deep links. + +## 🧩 Core Concepts + +### Plugins +Flocon operates on a plugin-based architecture. Modules typically provide a "Core" or implementation module and a "No-Op" module. The No-Op modules allow the app to compile and run without the actual implementation, which is useful for specialized builds or testing. + +### Interceptors +For networking and gRPC, Flocon uses an interceptor-based approach to hook into the communication pipeline of standard libraries (OkHttp, Ktor, gRPC). + +## 📖 Development Guidelines + +- **Multiplatform First**: Always consider KMP compatibility when adding new features or modules. +- **Modularity**: Keep modules focused and avoid circular dependencies. +- **Naming Conventions**: Follow the `io.github.openflocon.flocon` package naming structure. +- **Version Catalog**: All dependency versions must be managed in `gradle/libs.versions.toml`. + +--- +*Created by Antigravity AI to assist in project understanding.* diff --git a/FloconAndroid/database/core-no-op/build.gradle.kts b/FloconAndroid/database/core-no-op/build.gradle.kts index 348ce3da1..ce8b7acb7 100644 --- a/FloconAndroid/database/core-no-op/build.gradle.kts +++ b/FloconAndroid/database/core-no-op/build.gradle.kts @@ -4,6 +4,11 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon_database_core_no_op" + browser() + binaries.executable() + } sourceSets { val commonMain by getting { dependencies { @@ -25,6 +30,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/database/core/build.gradle.kts b/FloconAndroid/database/core/build.gradle.kts index 346a4e2b9..5dffc225e 100644 --- a/FloconAndroid/database/core/build.gradle.kts +++ b/FloconAndroid/database/core/build.gradle.kts @@ -5,6 +5,11 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon_database_core" + browser() + binaries.executable() + } sourceSets { val commonMain by getting { dependencies { @@ -29,6 +34,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/database/core/src/wasmJsMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.wasmJs.kt b/FloconAndroid/database/core/src/wasmJsMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.wasmJs.kt new file mode 100644 index 000000000..4888f7e96 --- /dev/null +++ b/FloconAndroid/database/core/src/wasmJsMain/kotlin/io/github/openflocon/flocon/database/core/model/FloconDatabaseModel.wasmJs.kt @@ -0,0 +1,13 @@ +package io.github.openflocon.flocon.database.core.model + +import io.github.openflocon.flocon.database.core.model.fromdevice.DatabaseExecuteSqlResponse + +actual fun openDbAndExecuteQuery( + path: String, + query: String +): DatabaseExecuteSqlResponse { + return DatabaseExecuteSqlResponse.Error( + message = "SQLite is not supported on WasmJS yet", + originalSql = query + ) +} diff --git a/FloconAndroid/database/room3-no-op/build.gradle.kts b/FloconAndroid/database/room3-no-op/build.gradle.kts index 6507ac962..a251c1dcf 100644 --- a/FloconAndroid/database/room3-no-op/build.gradle.kts +++ b/FloconAndroid/database/room3-no-op/build.gradle.kts @@ -19,6 +19,12 @@ kotlin { iosArm64() iosSimulatorArm64() + wasmJs { + moduleName = "flocon_database_room3_no_op" + browser() + binaries.executable() + } + sourceSets { val commonMain by getting { dependencies { @@ -41,6 +47,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/database/room3/build.gradle.kts b/FloconAndroid/database/room3/build.gradle.kts index 3e7385b5f..3f94213c4 100644 --- a/FloconAndroid/database/room3/build.gradle.kts +++ b/FloconAndroid/database/room3/build.gradle.kts @@ -17,35 +17,50 @@ kotlin { jvm() + iosX64() iosArm64() iosSimulatorArm64() + wasmJs { + moduleName = "flocon_database_room3" + browser() + binaries.executable() + } + sourceSets { val commonMain by getting { dependencies { implementation(project(":flocon")) + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) implementation(project(":database:core")) + } + } + + val roomMain by creating { + dependsOn(commonMain) + dependencies { implementation(libs.androidx.room3.runtime) implementation(libs.androidx.sqlite.bundled) } } - + val androidMain by getting { - dependencies { - } + dependsOn(roomMain) } - + val jvmMain by getting { - dependencies { - } + dependsOn(roomMain) } - val iosArm64Main by getting - val iosSimulatorArm64Main by getting val iosMain by creating { + dependsOn(roomMain) + } + val iosX64Main by getting { dependsOn(iosMain) } + val iosArm64Main by getting { dependsOn(iosMain) } + val iosSimulatorArm64Main by getting { dependsOn(iosMain) } + + val wasmJsMain by getting { dependsOn(commonMain) - iosArm64Main.dependsOn(this) - iosSimulatorArm64Main.dependsOn(this) } } } @@ -59,6 +74,7 @@ dependencies { add("kspCommonMainMetadata", libs.androidx.room3.compiler) add("kspAndroid", libs.androidx.room3.compiler) add("kspJvm", libs.androidx.room3.compiler) + add("kspIosX64", libs.androidx.room3.compiler) add("kspIosArm64", libs.androidx.room3.compiler) add("kspIosSimulatorArm64", libs.androidx.room3.compiler) } diff --git a/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseConfig.kt b/FloconAndroid/database/room3/src/roomMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseConfig.kt similarity index 100% rename from FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseConfig.kt rename to FloconAndroid/database/room3/src/roomMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseConfig.kt diff --git a/FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseModel.kt b/FloconAndroid/database/room3/src/roomMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseModel.kt similarity index 100% rename from FloconAndroid/database/room3/src/commonMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseModel.kt rename to FloconAndroid/database/room3/src/roomMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseModel.kt diff --git a/FloconAndroid/database/room3/src/wasmJsMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.wasmJs.kt b/FloconAndroid/database/room3/src/wasmJsMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.wasmJs.kt new file mode 100644 index 000000000..ffadd900b --- /dev/null +++ b/FloconAndroid/database/room3/src/wasmJsMain/kotlin/io/github/openflocon/flocon/database/room3/FloconRoom3DatabaseProviderImpl.wasmJs.kt @@ -0,0 +1,20 @@ +package io.github.openflocon.flocon.database.room3 + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.database.core.model.FloconDatabaseModel +import io.github.openflocon.flocon.dsl.FloconMarker + +@OptIn(markerClass = [FloconMarker::class]) +internal actual class FloconRoom3DatabaseProviderImpl actual constructor( + private val context: FloconContext, + paths: List +) : FloconRoom3DatabaseProvider { + + actual override fun register() { + } + + @FloconMarker + actual override fun getAllDataBases(registeredDatabases: List): List { + return emptyList() + } +} diff --git a/FloconAndroid/datastores-no-op/build.gradle.kts b/FloconAndroid/datastores-no-op/build.gradle.kts index 5f4154d85..282d69731 100644 --- a/FloconAndroid/datastores-no-op/build.gradle.kts +++ b/FloconAndroid/datastores-no-op/build.gradle.kts @@ -5,6 +5,58 @@ plugins { id("flocon.publish") } +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + wasmJs { + moduleName = "flocon_datastores_no_op" + browser() + binaries.executable() + } + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + } + } + + val androidMain by getting { + dependencies { + } + } + + val jvmMain by getting { + dependencies { + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val wasmJsMain by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + android { namespace = "io.github.openflocon.flocon.datastores" } diff --git a/FloconAndroid/datastores-no-op/src/main/AndroidManifest.xml b/FloconAndroid/datastores-no-op/src/androidMain/AndroidManifest.xml similarity index 100% rename from FloconAndroid/datastores-no-op/src/main/AndroidManifest.xml rename to FloconAndroid/datastores-no-op/src/androidMain/AndroidManifest.xml diff --git a/FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt b/FloconAndroid/datastores-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt similarity index 72% rename from FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt rename to FloconAndroid/datastores-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt index cfe707327..52d23e6b7 100644 --- a/FloconAndroid/datastores-no-op/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt +++ b/FloconAndroid/datastores-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt @@ -1,9 +1,7 @@ package io.github.openflocon.flocon.preferences.datastores.model -import androidx.datastore.core.DataStore -import androidx.datastore.preferences.core.Preferences -import io.github.openflocon.flocon.`plugins-old`.sharedprefs.model.FloconPreference -import io.github.openflocon.flocon.`plugins-old`.sharedprefs.model.FloconPreferenceValue +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreferenceValue interface FloconDatastoreMapper { fun fromDatastore(datastoreValue: String) : String @@ -12,7 +10,7 @@ interface FloconDatastoreMapper { class FloconDatastorePreference( override val name: String, - val dataStore: DataStore, + @Suppress("UNUSED_PARAMETER") dataStore: Any? = null, ) : io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference { override suspend fun set( diff --git a/FloconAndroid/datastores/build.gradle.kts b/FloconAndroid/datastores/build.gradle.kts index 19c695d5f..3e2a6e0b3 100644 --- a/FloconAndroid/datastores/build.gradle.kts +++ b/FloconAndroid/datastores/build.gradle.kts @@ -5,11 +5,67 @@ plugins { id("flocon.publish") } +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + wasmJs { + moduleName = "flocon_datastores" + browser() + binaries.executable() + } + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + } + } + + val androidMain by getting { + dependencies { + implementation(libs.androidx.datastore.preferences) + } + } + + val jvmMain by getting { + dependencies { + implementation(libs.androidx.datastore.preferences) + } + } + + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val wasmJsMain by getting + val iosMain by creating { + dependsOn(commonMain) + dependencies { + implementation(libs.androidx.datastore.preferences) + } + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + android { namespace = "io.github.openflocon.flocon.datastores" } -dependencies { implementation(projects.flocon) diff --git a/FloconAndroid/datastores/src/main/AndroidManifest.xml b/FloconAndroid/datastores/src/androidMain/AndroidManifest.xml similarity index 100% rename from FloconAndroid/datastores/src/main/AndroidManifest.xml rename to FloconAndroid/datastores/src/androidMain/AndroidManifest.xml diff --git a/FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt b/FloconAndroid/datastores/src/commonMain/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt similarity index 86% rename from FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt rename to FloconAndroid/datastores/src/commonMain/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt index 4e71bce4c..12f2ce12e 100644 --- a/FloconAndroid/datastores/src/main/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt +++ b/FloconAndroid/datastores/src/commonMain/kotlin/io/github/openflocon/flocon/preferences/datastores/model/FloconDatastorePreference.kt @@ -1,14 +1,14 @@ package io.github.openflocon.flocon.preferences.datastores.model -import androidx.datastore.core.DataStore -import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.core.booleanPreferencesKey -import androidx.datastore.preferences.core.doublePreferencesKey -import androidx.datastore.preferences.core.edit -import androidx.datastore.preferences.core.floatPreferencesKey -import androidx.datastore.preferences.core.intPreferencesKey -import androidx.datastore.preferences.core.longPreferencesKey -import androidx.datastore.preferences.core.stringPreferencesKey +//import androidx.datastore.core.DataStore +//import androidx.datastore.preferences.core.Preferences +//import androidx.datastore.preferences.core.booleanPreferencesKey +//import androidx.datastore.preferences.core.doublePreferencesKey +//import androidx.datastore.preferences.core.edit +//import androidx.datastore.preferences.core.floatPreferencesKey +//import androidx.datastore.preferences.core.intPreferencesKey +//import androidx.datastore.preferences.core.longPreferencesKey +//import androidx.datastore.preferences.core.stringPreferencesKey import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreference import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconPreferenceValue diff --git a/FloconAndroid/deeplinks-no-op/build.gradle.kts b/FloconAndroid/deeplinks-no-op/build.gradle.kts index 438e43cdb..f51058fa5 100644 --- a/FloconAndroid/deeplinks-no-op/build.gradle.kts +++ b/FloconAndroid/deeplinks-no-op/build.gradle.kts @@ -25,6 +25,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/deeplinks/build.gradle.kts b/FloconAndroid/deeplinks/build.gradle.kts index 0049a7aef..352c80faf 100644 --- a/FloconAndroid/deeplinks/build.gradle.kts +++ b/FloconAndroid/deeplinks/build.gradle.kts @@ -5,6 +5,11 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon_deeplinks" + binaries.executable() + browser() + } sourceSets { val commonMain by getting { dependencies { @@ -27,6 +32,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/flocon-no-op/build.gradle.kts b/FloconAndroid/flocon-no-op/build.gradle.kts index 99ab4b8c7..03b4aac00 100644 --- a/FloconAndroid/flocon-no-op/build.gradle.kts +++ b/FloconAndroid/flocon-no-op/build.gradle.kts @@ -27,6 +27,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/flocon-no-op/src/wasmJsMain/kotlin/io/github/openflocon/flocon/Flocon.wasmJs.kt b/FloconAndroid/flocon-no-op/src/wasmJsMain/kotlin/io/github/openflocon/flocon/Flocon.wasmJs.kt new file mode 100644 index 000000000..88207316f --- /dev/null +++ b/FloconAndroid/flocon-no-op/src/wasmJsMain/kotlin/io/github/openflocon/flocon/Flocon.wasmJs.kt @@ -0,0 +1,8 @@ +package io.github.openflocon.flocon + +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow + +actual object Flocon : FloconApp { + override val isInitialized: StateFlow = MutableStateFlow(false) +} diff --git a/FloconAndroid/flocon/build.gradle.kts b/FloconAndroid/flocon/build.gradle.kts index a60a1be31..a89f9dbd0 100644 --- a/FloconAndroid/flocon/build.gradle.kts +++ b/FloconAndroid/flocon/build.gradle.kts @@ -38,6 +38,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.android.kt new file mode 100644 index 000000000..382fa2232 --- /dev/null +++ b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.android.kt @@ -0,0 +1,8 @@ +package kotlinx.coroutines + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +public actual val Dispatchers.IO: CoroutineDispatcher get() = Dispatchers.IO + +public actual val IO: CoroutineDispatcher get() = Dispatchers.IO diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.kt new file mode 100644 index 000000000..be94d1ed8 --- /dev/null +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.kt @@ -0,0 +1,8 @@ +package kotlinx.coroutines + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +public expect val Dispatchers.IO: CoroutineDispatcher + +public expect val IO: CoroutineDispatcher diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.ios.kt b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.ios.kt new file mode 100644 index 000000000..7c711bc0a --- /dev/null +++ b/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.ios.kt @@ -0,0 +1,8 @@ +package kotlinx.coroutines + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +public actual val Dispatchers.IO: CoroutineDispatcher get() = Dispatchers.Default + +public actual val IO: CoroutineDispatcher get() = Dispatchers.Default diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.jvm.kt b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.jvm.kt new file mode 100644 index 000000000..382fa2232 --- /dev/null +++ b/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.jvm.kt @@ -0,0 +1,8 @@ +package kotlinx.coroutines + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +public actual val Dispatchers.IO: CoroutineDispatcher get() = Dispatchers.IO + +public actual val IO: CoroutineDispatcher get() = Dispatchers.IO diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconContext.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconContext.wasmJs.kt new file mode 100644 index 000000000..c6158c9c2 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconContext.wasmJs.kt @@ -0,0 +1,3 @@ +package io.github.openflocon.flocon + +actual class FloconContext diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconCore.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconCore.wasmJs.kt new file mode 100644 index 000000000..22cbf2293 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconCore.wasmJs.kt @@ -0,0 +1,4 @@ +package io.github.openflocon.flocon + +internal actual fun displayClearTextError(context: FloconContext) { +} diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconFile.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconFile.wasmJs.kt new file mode 100644 index 000000000..5b4a91e15 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconFile.wasmJs.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon + +import io.github.openflocon.flocon.dsl.FloconMarker + +@FloconMarker +actual class FloconFile diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconLogger.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconLogger.wasmJs.kt new file mode 100644 index 000000000..637d7a7c9 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/FloconLogger.wasmJs.kt @@ -0,0 +1,18 @@ +package io.github.openflocon.flocon + +actual object FloconLogger { + actual var enabled = false + + actual fun logError(text: String, throwable: Throwable?) { + if(enabled) { + println("ERROR: $text") + throwable?.printStackTrace() + } + } + + actual fun log(text: String) { + if(enabled) { + println("DEBUG: $text") + } + } +} diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/ServerHost.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/ServerHost.wasmJs.kt new file mode 100644 index 000000000..489dcbce0 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/ServerHost.wasmJs.kt @@ -0,0 +1,3 @@ +package io.github.openflocon.flocon + +internal actual fun getServerHost(floconContext: FloconContext): String = "localhost" diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/core/AppInfos.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/core/AppInfos.wasmJs.kt new file mode 100644 index 000000000..e971bc432 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/core/AppInfos.wasmJs.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.core + +import io.github.openflocon.flocon.FloconContext + +internal actual fun getAppInfos(floconContext: FloconContext): AppInfos = AppInfos( + deviceId = "wasm-device", + deviceName = "Browser", + appName = "Flocon Wasm", + appPackageName = "io.github.openflocon.wasm", + platform = "wasm" +) diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.wasmJs.kt new file mode 100644 index 000000000..c35073b68 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.wasmJs.kt @@ -0,0 +1,16 @@ +package io.github.openflocon.flocon.plugins.crashreporter + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel + +internal actual fun buildFloconCrashReporterDataSource(context: FloconContext): FloconCrashReporterDataSource = object : FloconCrashReporterDataSource { + override fun saveCrash(crash: CrashReportDataModel) {} + override fun loadPendingCrashes(): List = emptyList() + override fun deleteCrash(crashId: String) {} +} + +internal actual fun setupUncaughtExceptionHandler( + context: FloconContext, + onCrash: (Throwable) -> Unit +) { +} diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.wasmJs.kt new file mode 100644 index 000000000..93191f721 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.wasmJs.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon.plugins.device + +import io.github.openflocon.flocon.FloconContext + +internal actual fun restartApp(context: FloconContext) { +} diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.wasmJs.kt new file mode 100644 index 000000000..cb477e7a2 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.wasmJs.kt @@ -0,0 +1,5 @@ +package io.github.openflocon.flocon.plugins.device + +import io.github.openflocon.flocon.FloconContext + +actual fun getAppIconBase64(context: FloconContext): String? = null diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.wasmJs.kt new file mode 100644 index 000000000..41a60203b --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.wasmJs.kt @@ -0,0 +1,22 @@ +package io.github.openflocon.flocon.plugins.files + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconFile +import io.github.openflocon.flocon.dsl.FloconMarker +import io.github.openflocon.flocon.plugins.files.model.fromdevice.FileDataModel + +internal actual fun fileDataSource(context: FloconContext): FileDataSource = FloconFilesDataSourceWasmJs() + +private class FloconFilesDataSourceWasmJs : FileDataSource { + @FloconMarker + override fun getFolderContent(path: String, isConstantPath: Boolean, withFoldersSize: Boolean): List = emptyList() + + @FloconMarker + override fun getFile(path: String, isConstantPath: Boolean): FloconFile? = null + + override fun deleteFile(path: String) {} + override fun deleteFiles(path: List) {} + + @FloconMarker + override fun deleteFolderContent(folder: FloconFile) {} +} diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.wasmJs.kt new file mode 100644 index 000000000..3dc844cfd --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.wasmJs.kt @@ -0,0 +1,10 @@ +package io.github.openflocon.flocon.plugins.sharedprefs + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconSharedPreferenceModel + +internal actual fun buildFloconSharedPreferenceDataSource(context: FloconContext): FloconSharedPreferenceDataSource = object : FloconSharedPreferenceDataSource { + override fun getSharedPreferences(): List = emptyList() + override fun getSharedPreferenceValue(fileName: String, key: String): String? = null + override fun setSharedPreferenceValue(fileName: String, key: String, value: String) {} +} diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.wasmJs.kt new file mode 100644 index 000000000..7c711bc0a --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/utils/DispatcherUtils.wasmJs.kt @@ -0,0 +1,8 @@ +package kotlinx.coroutines + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +public actual val Dispatchers.IO: CoroutineDispatcher get() = Dispatchers.Default + +public actual val IO: CoroutineDispatcher get() = Dispatchers.Default diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.wasmJs.kt new file mode 100644 index 000000000..ec9cb0ebe --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/utils/PlatformUtils.wasmJs.kt @@ -0,0 +1,11 @@ +package io.github.openflocon.flocon.utils + +// Using a simple polyfill/wrapper for time in wasmJs if needed, +// but for now we'll try to use what's available or stubs to make it compile. +// Note: In a real app, you'd use a library like kotlinx-datetime. + +actual fun currentTimeMillis(): Long = 0L // Stub for now to ensure compilation + +actual fun currentTimeNanos(): Long = 0L // Stub for now to ensure compilation + +actual fun createThrowableFromClassName(className: String): Throwable? = null diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.wasmJs.kt new file mode 100644 index 000000000..c5bb72acf --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/websocket/FloconHttpClient.wasmJs.kt @@ -0,0 +1,18 @@ +package io.github.openflocon.flocon.websocket + +import io.github.openflocon.flocon.FloconFile +import io.github.openflocon.flocon.dsl.FloconMarker +import io.github.openflocon.flocon.model.FloconFileInfo + +internal actual fun buildFloconHttpClient(): FloconHttpClient = object : FloconHttpClient { + @FloconMarker + override suspend fun send( + file: FloconFile, + infos: FloconFileInfo, + address: String, + port: Int, + deviceId: String, + appPackageName: String, + appInstance: Long + ): Boolean = false +} diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/websocket/FloconWebSocketClient.wasmJs.kt b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/websocket/FloconWebSocketClient.wasmJs.kt new file mode 100644 index 000000000..ca5e53a22 --- /dev/null +++ b/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/websocket/FloconWebSocketClient.wasmJs.kt @@ -0,0 +1,19 @@ +package io.github.openflocon.flocon.websocket + +internal actual fun buildFloconWebSocketClient(): FloconWebSocketClient = object : FloconWebSocketClient { + override suspend fun connect( + address: String, + port: Int, + onMessageReceived: (String) -> Unit, + onClosed: () -> Unit + ) { + } + + override suspend fun sendPendingMessages() { + } + + override suspend fun sendMessage(message: String): Boolean = false + + override suspend fun disconnect() { + } +} diff --git a/FloconAndroid/network/core-no-op/build.gradle.kts b/FloconAndroid/network/core-no-op/build.gradle.kts index 27fa6b6cf..7247ac2a8 100644 --- a/FloconAndroid/network/core-no-op/build.gradle.kts +++ b/FloconAndroid/network/core-no-op/build.gradle.kts @@ -4,6 +4,11 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon_network_core_no_op" + browser() + binaries.executable() + } sourceSets { val commonMain by getting { dependencies { @@ -25,6 +30,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/network/core/build.gradle.kts b/FloconAndroid/network/core/build.gradle.kts index a677713ae..22cfe5c78 100644 --- a/FloconAndroid/network/core/build.gradle.kts +++ b/FloconAndroid/network/core/build.gradle.kts @@ -5,6 +5,11 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon_network_core" + browser() + binaries.executable() + } sourceSets { val commonMain by getting { dependencies { @@ -27,6 +32,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/network/core/src/wasmJsMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.wasmJs.kt b/FloconAndroid/network/core/src/wasmJsMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.wasmJs.kt new file mode 100644 index 000000000..271cc6a48 --- /dev/null +++ b/FloconAndroid/network/core/src/wasmJsMain/kotlin/io/github/openflocon/flocon/network/core/datasource/FloconNetworkDataSource.wasmJs.kt @@ -0,0 +1,14 @@ +package io.github.openflocon.flocon.network.core.datasource + +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.network.core.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.MockNetworkResponse + +internal actual inline fun buildFloconNetworkDataSource(context: FloconContext): FloconNetworkDataSource = FloconNetworkDataSourceWasmJs() + +internal class FloconNetworkDataSourceWasmJs : FloconNetworkDataSource { + override fun saveMocksToFile(mocks: List) {} + override fun loadMocksFromFile(): List = emptyList() + override fun saveBadNetworkConfig(config: BadQualityConfig?) {} + override fun loadBadNetworkConfig(): BadQualityConfig? = null +} diff --git a/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts b/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts index 821e8a0a5..ba1789fd4 100644 --- a/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts +++ b/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts @@ -4,6 +4,11 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon_ktor_interceptor_no_op" + browser() + binaries.executable() + } sourceSets { val commonMain by getting { dependencies { @@ -25,6 +30,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/network/ktor-interceptor/build.gradle.kts b/FloconAndroid/network/ktor-interceptor/build.gradle.kts index 57fd88634..4bca9d162 100644 --- a/FloconAndroid/network/ktor-interceptor/build.gradle.kts +++ b/FloconAndroid/network/ktor-interceptor/build.gradle.kts @@ -4,6 +4,11 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon_ktor_interceptor" + browser() + } + binaries.executable() sourceSets { val commonMain by getting { dependencies { @@ -31,6 +36,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting + val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/network/ktor-interceptor/src/wasmJsMain/kotlin/io/github/openflocon/flocon/ktor/Utils.wasmJs.kt b/FloconAndroid/network/ktor-interceptor/src/wasmJsMain/kotlin/io/github/openflocon/flocon/ktor/Utils.wasmJs.kt new file mode 100644 index 000000000..d4511a451 --- /dev/null +++ b/FloconAndroid/network/ktor-interceptor/src/wasmJsMain/kotlin/io/github/openflocon/flocon/ktor/Utils.wasmJs.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.flocon.ktor + +internal actual fun decodeNetworkBody( + bytes: ByteArray, + headers: Map +): String = bytes.decodeToString() From 3f82b4e95bbcb1b59d78f6fab36b85e3e78d6332 Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 8 Apr 2026 14:33:24 +0200 Subject: [PATCH 26/35] feat: Gradle --- FloconAndroid/database/room3/build.gradle.kts | 29 ++----------------- FloconAndroid/gradle/libs.versions.toml | 2 ++ 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/FloconAndroid/database/room3/build.gradle.kts b/FloconAndroid/database/room3/build.gradle.kts index 3f94213c4..5e26920c7 100644 --- a/FloconAndroid/database/room3/build.gradle.kts +++ b/FloconAndroid/database/room3/build.gradle.kts @@ -17,7 +17,6 @@ kotlin { jvm() - iosX64() iosArm64() iosSimulatorArm64() @@ -31,34 +30,13 @@ kotlin { val commonMain by getting { dependencies { implementation(project(":flocon")) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) - implementation(project(":database:core")) - } - } - - val roomMain by creating { - dependsOn(commonMain) - dependencies { + implementation(libs.kotlinx.coroutines.core) implementation(libs.androidx.room3.runtime) - implementation(libs.androidx.sqlite.bundled) + implementation(libs.androidx.sqlite) + implementation(project(":database:core")) } } - val androidMain by getting { - dependsOn(roomMain) - } - - val jvmMain by getting { - dependsOn(roomMain) - } - - val iosMain by creating { - dependsOn(roomMain) - } - val iosX64Main by getting { dependsOn(iosMain) } - val iosArm64Main by getting { dependsOn(iosMain) } - val iosSimulatorArm64Main by getting { dependsOn(iosMain) } - val wasmJsMain by getting { dependsOn(commonMain) } @@ -74,7 +52,6 @@ dependencies { add("kspCommonMainMetadata", libs.androidx.room3.compiler) add("kspAndroid", libs.androidx.room3.compiler) add("kspJvm", libs.androidx.room3.compiler) - add("kspIosX64", libs.androidx.room3.compiler) add("kspIosArm64", libs.androidx.room3.compiler) add("kspIosSimulatorArm64", libs.androidx.room3.compiler) } diff --git a/FloconAndroid/gradle/libs.versions.toml b/FloconAndroid/gradle/libs.versions.toml index 2fba6fb4b..c3a757f69 100644 --- a/FloconAndroid/gradle/libs.versions.toml +++ b/FloconAndroid/gradle/libs.versions.toml @@ -29,6 +29,7 @@ protobuf = "4.26.1" ksp = "2.1.21-2.0.2" processPhoenix = "3.0.0" sqlite = "2.6.2" +sqlite-alpha = "2.7.0-alpha02" sqliteJdbc = "3.50.3.0" buildconfig = "5.6.8" brotli = "0.1.2" @@ -93,6 +94,7 @@ protobuf-util = { group = "com.google.protobuf", name = "protobuf-java-util", ve sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" } +androidx-sqlite = { module = "androidx.sqlite:sqlite", version.ref = "sqlite-alpha" } androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } From 3078a2a5f04d9cce8975e30fbd8aeb4a1182ba99 Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 13 May 2026 14:26:55 +0200 Subject: [PATCH 27/35] fix: Gradle --- .../datastores-no-op/build.gradle.kts | 48 +++++++------- FloconAndroid/datastores/build.gradle.kts | 65 ++++++++----------- .../deeplinks-no-op/build.gradle.kts | 2 +- FloconAndroid/flocon-no-op/build.gradle.kts | 2 +- FloconAndroid/flocon/build.gradle.kts | 2 +- .../network/ktor-interceptor/build.gradle.kts | 5 +- 6 files changed, 56 insertions(+), 68 deletions(-) diff --git a/FloconAndroid/datastores-no-op/build.gradle.kts b/FloconAndroid/datastores-no-op/build.gradle.kts index 282d69731..16019d4ef 100644 --- a/FloconAndroid/datastores-no-op/build.gradle.kts +++ b/FloconAndroid/datastores-no-op/build.gradle.kts @@ -1,36 +1,36 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { - id("flocon.android.library") + id("flocon.kotlin.multiplatform") id("flocon.publish") } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - - wasmJs { - moduleName = "flocon_datastores_no_op" - browser() - binaries.executable() - } +// androidTarget { +// compilations.all { +// kotlinOptions { +// jvmTarget = "11" +// } +// } +// } +// +// jvm() +// +// iosX64() +// iosArm64() +// iosSimulatorArm64() +// +// wasmJs { +// moduleName = "flocon_datastores_no_op" +// browser() +// binaries.executable() +// } sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(projects.flocon) + implementation(libs.kotlinx.coroutines.core) } } @@ -47,7 +47,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting - val wasmJsMain by getting +// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) @@ -79,4 +79,4 @@ mavenPublishing { artifactId = "flocon-datastores-no-op", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) -} \ No newline at end of file +} diff --git a/FloconAndroid/datastores/build.gradle.kts b/FloconAndroid/datastores/build.gradle.kts index 3e2a6e0b3..145e55c53 100644 --- a/FloconAndroid/datastores/build.gradle.kts +++ b/FloconAndroid/datastores/build.gradle.kts @@ -1,45 +1,45 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.internal.platform.wasm.WasmPlatforms.wasmJs plugins { - id("flocon.android.library") + id("flocon.kotlin.multiplatform") id("flocon.publish") } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - - wasmJs { - moduleName = "flocon_datastores" - browser() - binaries.executable() - } +// androidTarget { +// compilations.all { +// kotlinOptions { +// jvmTarget = "11" +// } +// } +// } +// +// jvm() +// +// iosX64() +// iosArm64() +// iosSimulatorArm64() +// +// wasmJs { +// moduleName = "flocon_datastores" +// browser() +// binaries.executable() +// } sourceSets { val commonMain by getting { dependencies { - implementation(project(":flocon")) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(projects.flocon) + implementation(libs.kotlinx.coroutines.core) } } - + val androidMain by getting { dependencies { implementation(libs.androidx.datastore.preferences) } } - + val jvmMain by getting { dependencies { implementation(libs.androidx.datastore.preferences) @@ -49,7 +49,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting - val wasmJsMain by getting +// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) dependencies { @@ -66,21 +66,10 @@ android { namespace = "io.github.openflocon.flocon.datastores" } - - implementation(projects.flocon) - - implementation(platform(libs.kotlinx.coroutines.bom)) - implementation(libs.kotlinx.coroutines.core) - implementation(libs.kotlinx.coroutines.android) - - implementation(libs.androidx.datastore.preferences) -} - - mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-datastores", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) -} \ No newline at end of file +} diff --git a/FloconAndroid/deeplinks-no-op/build.gradle.kts b/FloconAndroid/deeplinks-no-op/build.gradle.kts index f51058fa5..b87ee9109 100644 --- a/FloconAndroid/deeplinks-no-op/build.gradle.kts +++ b/FloconAndroid/deeplinks-no-op/build.gradle.kts @@ -25,7 +25,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting - val wasmJsMain by getting +// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/flocon-no-op/build.gradle.kts b/FloconAndroid/flocon-no-op/build.gradle.kts index 03b4aac00..8ea9ff130 100644 --- a/FloconAndroid/flocon-no-op/build.gradle.kts +++ b/FloconAndroid/flocon-no-op/build.gradle.kts @@ -27,7 +27,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting - val wasmJsMain by getting +// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/flocon/build.gradle.kts b/FloconAndroid/flocon/build.gradle.kts index a89f9dbd0..907726d84 100644 --- a/FloconAndroid/flocon/build.gradle.kts +++ b/FloconAndroid/flocon/build.gradle.kts @@ -38,7 +38,7 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting - val wasmJsMain by getting +// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/network/ktor-interceptor/build.gradle.kts b/FloconAndroid/network/ktor-interceptor/build.gradle.kts index 4bca9d162..2c44a9a8c 100644 --- a/FloconAndroid/network/ktor-interceptor/build.gradle.kts +++ b/FloconAndroid/network/ktor-interceptor/build.gradle.kts @@ -7,8 +7,9 @@ kotlin { wasmJs { moduleName = "flocon_ktor_interceptor" browser() - } binaries.executable() + } + sourceSets { val commonMain by getting { dependencies { @@ -50,8 +51,6 @@ android { namespace = "io.github.openflocon.flocon.ktor" } - - mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, From 85f9cbedcdde32c2a116ac97573bd7a1b0863bcf Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 13 May 2026 14:29:51 +0200 Subject: [PATCH 28/35] feat: Wasm --- .../database/core-no-op/build.gradle.kts | 12 +----- FloconAndroid/database/core/build.gradle.kts | 13 +------ .../datastores-no-op/build.gradle.kts | 37 +++--------------- FloconAndroid/datastores/build.gradle.kts | 39 +++---------------- .../deeplinks-no-op/build.gradle.kts | 17 +++----- FloconAndroid/deeplinks/build.gradle.kts | 12 +----- FloconAndroid/flocon-no-op/build.gradle.kts | 17 +++----- FloconAndroid/flocon/build.gradle.kts | 9 +++-- 8 files changed, 31 insertions(+), 125 deletions(-) diff --git a/FloconAndroid/database/core-no-op/build.gradle.kts b/FloconAndroid/database/core-no-op/build.gradle.kts index ce8b7acb7..69d424509 100644 --- a/FloconAndroid/database/core-no-op/build.gradle.kts +++ b/FloconAndroid/database/core-no-op/build.gradle.kts @@ -9,6 +9,7 @@ kotlin { browser() binaries.executable() } + sourceSets { val commonMain by getting { dependencies { @@ -16,21 +17,10 @@ kotlin { implementation(libs.kotlinx.coroutines.core) } } - - val androidMain by getting { - dependencies { - } - } - - val jvmMain by getting { - dependencies { - } - } val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting - val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/database/core/build.gradle.kts b/FloconAndroid/database/core/build.gradle.kts index 5dffc225e..37da966f6 100644 --- a/FloconAndroid/database/core/build.gradle.kts +++ b/FloconAndroid/database/core/build.gradle.kts @@ -10,6 +10,7 @@ kotlin { browser() binaries.executable() } + sourceSets { val commonMain by getting { dependencies { @@ -19,22 +20,10 @@ kotlin { implementation(libs.kotlinx.serialization.json) } } - - val androidMain by getting { - dependencies { - } - } - - val jvmMain by getting { - dependencies { - implementation(libs.sqlite.jdbc) - } - } val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting - val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/datastores-no-op/build.gradle.kts b/FloconAndroid/datastores-no-op/build.gradle.kts index 16019d4ef..b27fdd579 100644 --- a/FloconAndroid/datastores-no-op/build.gradle.kts +++ b/FloconAndroid/datastores-no-op/build.gradle.kts @@ -1,30 +1,14 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - plugins { id("flocon.kotlin.multiplatform") id("flocon.publish") } kotlin { -// androidTarget { -// compilations.all { -// kotlinOptions { -// jvmTarget = "11" -// } -// } -// } -// -// jvm() -// -// iosX64() -// iosArm64() -// iosSimulatorArm64() -// -// wasmJs { -// moduleName = "flocon_datastores_no_op" -// browser() -// binaries.executable() -// } + wasmJs { + moduleName = "flocon_datastores_no_op" + browser() + binaries.executable() + } sourceSets { val commonMain by getting { @@ -33,21 +17,10 @@ kotlin { implementation(libs.kotlinx.coroutines.core) } } - - val androidMain by getting { - dependencies { - } - } - - val jvmMain by getting { - dependencies { - } - } val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting -// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/datastores/build.gradle.kts b/FloconAndroid/datastores/build.gradle.kts index 145e55c53..3fa34912b 100644 --- a/FloconAndroid/datastores/build.gradle.kts +++ b/FloconAndroid/datastores/build.gradle.kts @@ -1,30 +1,14 @@ -import org.jetbrains.kotlin.gradle.internal.platform.wasm.WasmPlatforms.wasmJs - plugins { id("flocon.kotlin.multiplatform") id("flocon.publish") } kotlin { -// androidTarget { -// compilations.all { -// kotlinOptions { -// jvmTarget = "11" -// } -// } -// } -// -// jvm() -// -// iosX64() -// iosArm64() -// iosSimulatorArm64() -// -// wasmJs { -// moduleName = "flocon_datastores" -// browser() -// binaries.executable() -// } + wasmJs { + moduleName = "flocon_datastores" + browser() + binaries.executable() + } sourceSets { val commonMain by getting { @@ -34,22 +18,9 @@ kotlin { } } - val androidMain by getting { - dependencies { - implementation(libs.androidx.datastore.preferences) - } - } - - val jvmMain by getting { - dependencies { - implementation(libs.androidx.datastore.preferences) - } - } - val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting -// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) dependencies { diff --git a/FloconAndroid/deeplinks-no-op/build.gradle.kts b/FloconAndroid/deeplinks-no-op/build.gradle.kts index b87ee9109..4ab3d4ec4 100644 --- a/FloconAndroid/deeplinks-no-op/build.gradle.kts +++ b/FloconAndroid/deeplinks-no-op/build.gradle.kts @@ -4,6 +4,12 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon_deeplinks_no_op" + binaries.executable() + browser() + } + sourceSets { val commonMain by getting { dependencies { @@ -12,20 +18,9 @@ kotlin { } } - val androidMain by getting { - dependencies { - } - } - - val jvmMain by getting { - dependencies { - } - } - val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting -// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/deeplinks/build.gradle.kts b/FloconAndroid/deeplinks/build.gradle.kts index 352c80faf..b29a68d10 100644 --- a/FloconAndroid/deeplinks/build.gradle.kts +++ b/FloconAndroid/deeplinks/build.gradle.kts @@ -10,6 +10,7 @@ kotlin { binaries.executable() browser() } + sourceSets { val commonMain by getting { dependencies { @@ -18,21 +19,10 @@ kotlin { implementation(libs.kotlinx.serialization.json) } } - - val androidMain by getting { - dependencies { - } - } - - val jvmMain by getting { - dependencies { - } - } val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting - val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/flocon-no-op/build.gradle.kts b/FloconAndroid/flocon-no-op/build.gradle.kts index 8ea9ff130..adbf62120 100644 --- a/FloconAndroid/flocon-no-op/build.gradle.kts +++ b/FloconAndroid/flocon-no-op/build.gradle.kts @@ -6,6 +6,12 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon_no_op" + binaries.executable() + browser() + } + sourceSets { val commonMain by getting { dependencies { @@ -13,21 +19,10 @@ kotlin { implementation(libs.kotlinx.coroutines.core) } } - - val androidMain by getting { - dependencies { - } - } - - val jvmMain by getting { - dependencies { - } - } val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting -// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) diff --git a/FloconAndroid/flocon/build.gradle.kts b/FloconAndroid/flocon/build.gradle.kts index 907726d84..960db4acb 100644 --- a/FloconAndroid/flocon/build.gradle.kts +++ b/FloconAndroid/flocon/build.gradle.kts @@ -1,5 +1,3 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - plugins { id("flocon.kotlin.multiplatform") alias(libs.plugins.kotlin.serialization) @@ -8,6 +6,12 @@ plugins { } kotlin { + wasmJs { + moduleName = "flocon" + binaries.executable() + browser() + } + sourceSets { val commonMain by getting { dependencies { @@ -38,7 +42,6 @@ kotlin { val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting -// val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) From 9dd4c30a16ea20f7b0cad73a5308fe7c96a8183a Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 13 May 2026 14:32:42 +0200 Subject: [PATCH 29/35] fix: Clean --- FloconAndroid/flocon-no-op/build.gradle.kts | 2 - .../analytics/FloconAnalyticsPlugin.kt | 44 ------------------- .../analytics/builder/AnalyticsBuilder.kt | 32 -------------- .../analytics/model/AnalyticsEvent.kt | 11 ----- .../model/AnalyticsPropertiesConfig.kt | 11 ----- .../pluginsold/analytics/model/TableItem.kt | 9 ---- .../database/FloconDatabasePlugin.kt | 1 - .../database/model/FloconDatabaseModel.kt | 1 - .../ktor-interceptor-no-op/build.gradle.kts | 14 +----- 9 files changed, 1 insertion(+), 124 deletions(-) delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt diff --git a/FloconAndroid/flocon-no-op/build.gradle.kts b/FloconAndroid/flocon-no-op/build.gradle.kts index adbf62120..445d245c4 100644 --- a/FloconAndroid/flocon-no-op/build.gradle.kts +++ b/FloconAndroid/flocon-no-op/build.gradle.kts @@ -1,5 +1,3 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - plugins { id("flocon.kotlin.multiplatform") id("flocon.publish") diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt deleted file mode 100644 index e8bd6f068..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/FloconAnalyticsPlugin.kt +++ /dev/null @@ -1,44 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.analytics - -import io.github.openflocon.flocon.FloconConfig -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginConfig -import io.github.openflocon.flocon.FloconPluginFactory -import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem - -class FloconAnalyticsConfig : FloconPluginConfig - -/** - * Flocon Analytics Plugin. - */ -object FloconAnalytics : FloconPluginFactory { - override fun createConfig(context: FloconContext) = TODO() - override fun install( - pluginConfig: FloconAnalyticsConfig, - floconConfig: FloconConfig, - encoder: FloconEncoder - ): FloconAnalyticsPlugin = TODO() - - override val name: String = "" - override val pluginId: String = "ANALYTICS" -} -// -//fun floconAnalytics(analyticsName: String) : AnalyticsBuilder { -// return AnalyticsBuilder( -// analyticsTableId = analyticsName, -// analyticsPlugin = FloconApp.instance?.client?.analyticsPlugin, -// ) -//} - -//fun FloconApp.analytics(analyticsName: String): AnalyticsBuilder { -// return AnalyticsBuilder( -// analyticsTableId = analyticsName, -// analyticsPlugin = this.client?.analyticsPlugin, -// ) -//} - -interface FloconAnalyticsPlugin : FloconPlugin { - fun registerAnalytics(analyticsItems: List) -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt deleted file mode 100644 index f59c51620..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/builder/AnalyticsBuilder.kt +++ /dev/null @@ -1,32 +0,0 @@ -@file:OptIn(ExperimentalUuidApi::class) - -package io.github.openflocon.flocon.pluginsold.analytics.builder - -import io.github.openflocon.flocon.pluginsold.analytics.FloconAnalyticsPlugin -import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsEvent -import io.github.openflocon.flocon.pluginsold.analytics.model.AnalyticsItem -import io.github.openflocon.flocon.utils.currentTimeMillis -import kotlin.uuid.ExperimentalUuidApi -import kotlin.uuid.Uuid - -class AnalyticsBuilder( - val analyticsTableId: String, - private val analyticsPlugin: FloconAnalyticsPlugin?, -) { - fun logEvents(vararg events: AnalyticsEvent) { - this.logEvents(events.toList()) - } - - fun logEvents(events: List) { - val analyticsItems = events.map { - AnalyticsItem( - id = Uuid.random().toString(), - analyticsTableId = analyticsTableId, - eventName = it.eventName, - createdAt = currentTimeMillis(), - properties = it.properties, - ) - } - analyticsPlugin?.registerAnalytics(analyticsItems) - } -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt deleted file mode 100644 index 10a608249..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsEvent.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.analytics.model - -data class AnalyticsEvent( - val eventName: String, - val properties: List, -) { - constructor( - eventName: String, - vararg properties: AnalyticsPropertiesConfig, - ) : this(eventName, properties.toList()) -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt deleted file mode 100644 index de6d93092..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/AnalyticsPropertiesConfig.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.analytics.model - -data class AnalyticsPropertiesConfig( - val name: String, - val value: String, -) - -infix fun String.analyticsProperty(value: String) = AnalyticsPropertiesConfig( - name = this, - value = value, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt deleted file mode 100644 index c23f13409..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/analytics/model/TableItem.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.analytics.model - -data class AnalyticsItem( - val id: String, - val analyticsTableId: String, - val eventName: String, - val createdAt: Long, - val properties: List, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt deleted file mode 100644 index 1d9511610..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/FloconDatabasePlugin.kt +++ /dev/null @@ -1 +0,0 @@ -// DEPRECATED: Moved to :database:core \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt deleted file mode 100644 index 0447420ba..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/database/model/FloconDatabaseModel.kt +++ /dev/null @@ -1 +0,0 @@ -// DEPRECATED \ No newline at end of file diff --git a/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts b/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts index ba1789fd4..852463ec0 100644 --- a/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts +++ b/FloconAndroid/network/ktor-interceptor-no-op/build.gradle.kts @@ -9,6 +9,7 @@ kotlin { browser() binaries.executable() } + sourceSets { val commonMain by getting { dependencies { @@ -16,21 +17,10 @@ kotlin { implementation(libs.ktor.client.core) } } - - val androidMain by getting { - dependencies { - } - } - - val jvmMain by getting { - dependencies { - } - } val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting - val wasmJsMain by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) @@ -44,8 +34,6 @@ android { namespace = "io.github.openflocon.flocon.ktor" } - - mavenPublishing { coordinates( groupId = project.property("floconGroupId") as String, From dd736566d483624af2dd82fae8abbcc78b223d7d Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 13 May 2026 14:48:39 +0200 Subject: [PATCH 30/35] feat: Cleaning --- .../analytics-no-op/build.gradle.kts | 2 +- FloconAndroid/analytics/build.gradle.kts | 78 +------------------ .../analytics/FloconAnalyticsPlugin.kt | 19 +++-- .../analytics/mapper/AnalyticsItemsMapper.kt | 12 +-- .../openflocon/buildlogic/AndroidConfig.kt | 22 ++++++ .../FloconAndroidLibraryConventionPlugin.kt | 26 +++++++ ...oconKotlinMultiplatformConventionPlugin.kt | 38 +++++++++ .../FloconPublishConventionPlugin.kt | 52 +++++++++++++ .../analytics/FloconAnalyticsPlugin.kt | 73 ----------------- .../analytics/builder/AnalyticsBuilder.kt | 32 -------- .../analytics/mapper/AnalyticsItemsMapper.kt | 34 -------- .../plugins/analytics/model/AnalyticsEvent.kt | 11 --- .../plugins/analytics/model/AnalyticsItem.kt | 9 --- .../model/AnalyticsPropertiesConfig.kt | 11 --- .../pluginsold/network/FloconNetworkPlugin.kt | 29 ------- .../network/model/BadQualityConfig.kt | 77 ------------------ .../network/model/FloconHttpRequest.kt | 23 ------ .../network/model/FloconNetworkCallRequest.kt | 8 -- .../model/FloconNetworkCallResponse.kt | 9 --- .../network/model/FloconWebSocketEvent.kt | 21 ----- .../model/FloconWebSocketMockListener.kt | 5 -- .../network/model/MockNetworkResponse.kt | 39 ---------- .../grpc-interceptor-base/build.gradle.kts | 2 +- .../openflocon/flocon/grpc/BadQuality.kt | 2 +- .../flocon/grpc/FloconGrpcBaseInterceptor.kt | 6 +- .../flocon/grpc/FloconGrpcPlugin.kt | 4 +- .../flocon/grpc/model/RequestHolder.kt | 2 +- .../sample-android-only/build.gradle.kts | 3 + FloconAndroid/settings.gradle.kts | 2 + 29 files changed, 168 insertions(+), 483 deletions(-) create mode 100644 FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/AndroidConfig.kt create mode 100644 FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconAndroidLibraryConventionPlugin.kt create mode 100644 FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconKotlinMultiplatformConventionPlugin.kt create mode 100644 FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconPublishConventionPlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/BadQualityConfig.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconHttpRequest.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallRequest.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallResponse.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketEvent.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketMockListener.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/MockNetworkResponse.kt diff --git a/FloconAndroid/analytics-no-op/build.gradle.kts b/FloconAndroid/analytics-no-op/build.gradle.kts index a7e3f4f02..1d040d352 100644 --- a/FloconAndroid/analytics-no-op/build.gradle.kts +++ b/FloconAndroid/analytics-no-op/build.gradle.kts @@ -23,7 +23,7 @@ kotlin { val commonMain by getting { dependencies { implementation(project(":flocon")) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(libs.kotlinx.coroutines.core) } } } diff --git a/FloconAndroid/analytics/build.gradle.kts b/FloconAndroid/analytics/build.gradle.kts index 870ee0a77..dbdb7375e 100644 --- a/FloconAndroid/analytics/build.gradle.kts +++ b/FloconAndroid/analytics/build.gradle.kts @@ -1,30 +1,14 @@ plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.vanniktech.maven.publish) - alias(libs.plugins.kotlin.serialization) + id("flocon.kotlin.multiplatform") + id("flocon.publish") } kotlin { - androidTarget { - compilations.all { - kotlinOptions { - jvmTarget = "11" - } - } - } - - jvm() - - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { val commonMain by getting { dependencies { implementation(project(":flocon")) - implementation(libs.jetbrains.kotlinx.coroutines.core.fixed) + implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) } } @@ -33,68 +17,12 @@ kotlin { android { namespace = "io.github.openflocon.flocon.analytics" - compileSdk = 36 - - defaultConfig { - minSdk = 23 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } } mavenPublishing { - publishToMavenCentral(automaticRelease = true) - - if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { - // Skip signing - } else { - signAllPublications() - } - coordinates( groupId = project.property("floconGroupId") as String, artifactId = "flocon-analytics", version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String ) - - pom { - name = "Flocon Analytics" - description = project.property("floconDescription") as String - inceptionYear = "2025" - url = "https://github.com/openflocon/Flocon" - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - developers { - developer { - id = "openflocon" - name = "Open Flocon" - url = "https://github.com/openflocon" - } - } - scm { - url = "https://github.com/openflocon/Flocon" - connection = "scm:git:git://github.com/openflocon/Flocon.git" - developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" - } - } } diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt index 9e2fe0f5c..9af8d73c8 100644 --- a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt @@ -7,7 +7,9 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender +import io.github.openflocon.flocon.core.encode import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem class FloconAnalyticsConfig : FloconPluginConfig @@ -22,16 +24,19 @@ object FloconAnalytics : FloconPluginFactory) { analyticsItems.takeIf { it.isNotEmpty() }?.forEach { toSend -> try { -// sender.send( -// plugin = Protocol.FromDevice.Analytics.Plugin, -// method = Protocol.FromDevice.Analytics.Method.AddItems, -// body = analyticsItemsToJson(toSend) -// ) + sender.send( + plugin = Protocol.FromDevice.Analytics.Plugin, + method = Protocol.FromDevice.Analytics.Method.AddItems, + body = encoder.encode(toSend) + ) } catch (t: Throwable) { FloconLogger.logError("error on sendAnalytics", t) } diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt index e8ec738ee..fc835947f 100644 --- a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt @@ -1,17 +1,7 @@ package io.github.openflocon.flocon.plugins.analytics.mapper -import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString - -internal fun analyticsItemsToJson(item: AnalyticsItem): String { - return FloconEncoder.json.encodeToString( - listOf( - item.toSerializable() - ) - ) -} @Serializable internal class AnalyticsItemSerializable( @@ -28,7 +18,7 @@ internal class AnalyticsPropertySerializable( val value: String, ) -internal fun AnalyticsItem.toSerializable(): AnalyticsItemSerializable { +internal fun AnalyticsItem.toRemote(): AnalyticsItemSerializable { return AnalyticsItemSerializable( id = id, analyticsTableId = analyticsTableId, diff --git a/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/AndroidConfig.kt b/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/AndroidConfig.kt new file mode 100644 index 000000000..e25d4d737 --- /dev/null +++ b/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/AndroidConfig.kt @@ -0,0 +1,22 @@ +package io.github.openflocon.buildlogic + +import com.android.build.gradle.LibraryExtension +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +internal fun Project.configureAndroidLibrary() { + extensions.configure { + compileSdk = 36 + + defaultConfig { + minSdk = 23 + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + } +} diff --git a/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconAndroidLibraryConventionPlugin.kt b/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconAndroidLibraryConventionPlugin.kt new file mode 100644 index 000000000..af1fb9a27 --- /dev/null +++ b/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconAndroidLibraryConventionPlugin.kt @@ -0,0 +1,26 @@ +package io.github.openflocon.buildlogic + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +class FloconAndroidLibraryConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.library") + apply("org.jetbrains.kotlin.android") + } + + configureAndroidLibrary() + + tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) + } + } + } + } +} diff --git a/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconKotlinMultiplatformConventionPlugin.kt b/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconKotlinMultiplatformConventionPlugin.kt new file mode 100644 index 000000000..f60e19246 --- /dev/null +++ b/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconKotlinMultiplatformConventionPlugin.kt @@ -0,0 +1,38 @@ +package io.github.openflocon.buildlogic + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +class FloconKotlinMultiplatformConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.jetbrains.kotlin.multiplatform") + apply("com.android.library") + } + + configureAndroidLibrary() + + extensions.configure { + androidTarget { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + compilerOptions { + freeCompilerArgs.add("-XXLanguage:+ExpectRefinement") + } + } + } + } +} diff --git a/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconPublishConventionPlugin.kt b/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconPublishConventionPlugin.kt new file mode 100644 index 000000000..df47b1eaf --- /dev/null +++ b/FloconAndroid/build-logic/convention/bin/main/io/github/openflocon/buildlogic/FloconPublishConventionPlugin.kt @@ -0,0 +1,52 @@ +package io.github.openflocon.buildlogic + +import com.vanniktech.maven.publish.MavenPublishBaseExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +class FloconPublishConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.vanniktech.maven.publish") + } + + extensions.configure { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + pom { + name.set(project.name) + description.set(project.findProperty("floconDescription") as? String) + inceptionYear.set("2025") + url.set("https://github.com/openflocon/Flocon") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + distribution.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("openflocon") + name.set("Open Flocon") + url.set("https://github.com/openflocon") + } + } + scm { + url.set("https://github.com/openflocon/Flocon") + connection.set("scm:git:git://github.com/openflocon/Flocon.git") + developerConnection.set("scm:git:ssh://git@github.com/openflocon/Flocon.git") + } + } + } + } + } +} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt deleted file mode 100644 index 0705dc523..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ /dev/null @@ -1,73 +0,0 @@ -package io.github.openflocon.flocon.plugins.analytics - -import io.github.openflocon.flocon.FloconConfig -import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginConfig -import io.github.openflocon.flocon.FloconPluginFactory -import io.github.openflocon.flocon.Protocol -import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.core.encode -import io.github.openflocon.flocon.plugins.analytics.mapper.toRemote -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem - -class FloconAnalyticsConfig : FloconPluginConfig - -interface FloconAnalyticsPlugin : FloconPlugin { - fun registerAnalytics(analyticsItems: List) -} - -object FloconAnalytics : FloconPluginFactory { - override val name: String = "Analytics" - override val pluginId: String = Protocol.ToDevice.Analytics.Plugin - override fun createConfig(context: FloconContext) = FloconAnalyticsConfig() - override fun install( - pluginConfig: FloconAnalyticsConfig, - floconConfig: FloconConfig, - encoder: FloconEncoder - ): FloconAnalyticsPlugin { - return FloconAnalyticsPluginImpl( - sender = floconConfig.client as FloconMessageSender, - encoder = encoder - ) - } -} - -internal class FloconAnalyticsPluginImpl( - private val sender: FloconMessageSender, - private val encoder: FloconEncoder -) : FloconPlugin, FloconAnalyticsPlugin { - override val key: String - get() = Protocol.ToDevice.Analytics.Plugin - - override suspend fun onMessageReceived( - method: String, - body: String, - ) { - // no op - } - - override suspend fun onConnectedToServer() { - // no op - } - - override fun registerAnalytics(analyticsItems: List) { - sendAnalytics(analyticsItems) - } - - private fun sendAnalytics(analyticsItems: List) { - analyticsItems.takeIf { it.isNotEmpty() }?.forEach { toSend -> - try { - sender.send( - plugin = Protocol.FromDevice.Analytics.Plugin, - method = Protocol.FromDevice.Analytics.Method.AddItems, - body = encoder.encode(listOf(toSend.toRemote())) - ) - } catch (t: Throwable) { - FloconLogger.logError("error on sendAnalytics", t) - } - } - } -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt deleted file mode 100644 index d4aef5b4d..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt +++ /dev/null @@ -1,32 +0,0 @@ -@file:OptIn(ExperimentalUuidApi::class) - -package io.github.openflocon.flocon.plugins.analytics.builder - -import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsEvent -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem -import io.github.openflocon.flocon.utils.currentTimeMillis -import kotlin.uuid.ExperimentalUuidApi -import kotlin.uuid.Uuid - -class AnalyticsBuilder( - val analyticsTableId: String, - private val analyticsPlugin: FloconAnalyticsPlugin?, -) { - fun logEvents(vararg events: AnalyticsEvent) { - this.logEvents(events.toList()) - } - - fun logEvents(events: List) { - val analyticsItems = events.map { - AnalyticsItem( - id = Uuid.random().toString(), - analyticsTableId = analyticsTableId, - eventName = it.eventName, - createdAt = currentTimeMillis(), - properties = it.properties, - ) - } - analyticsPlugin?.registerAnalytics(analyticsItems) - } -} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt deleted file mode 100644 index 4bab74e3c..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt +++ /dev/null @@ -1,34 +0,0 @@ -package io.github.openflocon.flocon.plugins.analytics.mapper - -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem -import kotlinx.serialization.Serializable - -@Serializable -internal class AnalyticsItemSerializable( - val id: String, - val analyticsTableId: String, - val eventName: String, - val createdAt: Long, - val properties: List, -) - -@Serializable -internal class AnalyticsPropertySerializable( - val name: String, - val value: String, -) - -internal fun AnalyticsItem.toRemote(): AnalyticsItemSerializable { - return AnalyticsItemSerializable( - id = id, - analyticsTableId = analyticsTableId, - eventName = eventName, - createdAt = createdAt, - properties = properties.map { - AnalyticsPropertySerializable( - name = it.name, - value = it.value - ) - } - ) -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt deleted file mode 100644 index b0de88ffa..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon.plugins.analytics.model - -data class AnalyticsEvent( - val eventName: String, - val properties: List, -) { - constructor( - eventName: String, - vararg properties: AnalyticsPropertiesConfig, - ) : this(eventName, properties.toList()) -} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt deleted file mode 100644 index 55c7285cd..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.plugins.analytics.model - -data class AnalyticsItem( - val id: String, - val analyticsTableId: String, - val eventName: String, - val createdAt: Long, - val properties: List, -) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt deleted file mode 100644 index f36d72382..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon.plugins.analytics.model - -data class AnalyticsPropertiesConfig( - val name: String, - val value: String, -) - -infix fun String.analyticsProperty(value: String) = AnalyticsPropertiesConfig( - name = this, - value = value, -) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt deleted file mode 100644 index 8836baf08..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/FloconNetworkPlugin.kt +++ /dev/null @@ -1,29 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.network - -import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginConfig -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketEvent -import io.github.openflocon.flocon.pluginsold.network.model.FloconWebSocketMockListener -import io.github.openflocon.flocon.pluginsold.network.model.MockNetworkResponse - -class FloconNetworkConfig : FloconPluginConfig { - var badQualityConfig: BadQualityConfig? = null - val mocks = mutableListOf() -} - -interface FloconNetworkPlugin : FloconPlugin { - val mocks: Collection - val badQualityConfig: BadQualityConfig? - - fun logRequest(request: FloconNetworkCallRequest) - fun logResponse(response: FloconNetworkCallResponse) - - suspend fun logWebSocket( - event: FloconWebSocketEvent, - ) - - suspend fun registerWebSocketMockListener(id: String, listener: FloconWebSocketMockListener) -} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/BadQualityConfig.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/BadQualityConfig.kt deleted file mode 100644 index 7fe952d6f..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/BadQualityConfig.kt +++ /dev/null @@ -1,77 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.network.model - -import io.github.openflocon.flocon.FloconLogger -import kotlin.random.Random - -data class BadQualityConfig( - val latency: LatencyConfig, - val errorProbability: Double, // chance of triggering an error - val errors: List, // list of errors -) { - class LatencyConfig( - val latencyTriggerProbability: Float, - val minLatencyMs: Long, - val maxLatencyMs: Long, - ) { - fun shouldSimulateLatency(): Boolean { - return latencyTriggerProbability > 0f && (latencyTriggerProbability == 1f || Random.nextDouble() < latencyTriggerProbability) - } - fun getRandomLatency() : Long { - return Random.nextLong( - minLatencyMs, - maxLatencyMs + 1 - ) - } - } - class Error( - val weight: Float, // increase the probability of being triggered vs all others errors - val type: Type, - ) { - sealed interface Type { - data class Body( - val errorCode: Int, - val errorBody: String, - val errorContentType: String, // "application/json" - ) : Type - data class ErrorThrow( - val classPath: String, - ) : Type { - fun generate() : Throwable? { - return try { - io.github.openflocon.flocon.utils.createThrowableFromClassName(classPath) - } catch (t: Throwable) { - FloconLogger.logError("BadQualityConfig error, className not found", t) - null - } - } - } - } - } - - fun shouldFail(): Boolean { - return errorProbability > 0 && Random.nextDouble() < errorProbability - } - - fun selectRandomError(): BadQualityConfig.Error? { - if (errors.isEmpty()) { - return null - } - - // Calculer la somme totale des poids - val totalWeight = errors.sumOf { it.weight.toDouble() } - - // Générer un nombre aléatoire entre 0 et la somme totale des poids - var randomNumber = Random.nextDouble(0.0, totalWeight) - - // Parcourir la liste pour trouver l'erreur sélectionnée - for (error in errors) { - randomNumber -= error.weight.toDouble() - if (randomNumber <= 0) { - return error - } - } - - // Cas de secours (ne devrait pas arriver si les poids sont positifs) - return errors.first() - } -} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconHttpRequest.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconHttpRequest.kt deleted file mode 100644 index 5d4af5515..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconHttpRequest.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.network.model - -data class FloconNetworkRequest( - val url: String, - val method: String, - val startTime: Long, - val headers: Map, - val body: String?, - val size: Long?, - val isMocked: Boolean, -) - -data class FloconNetworkResponse( - val httpCode: Int?, - val grpcStatus: String?, - val contentType: String?, - val body: String?, - val size: Long?, - val headers: Map, - val requestHeaders: Map?, // we might receive the request headers later if the interceptor is at first position in the http interceptor chain - val error: String?, - val isImage: Boolean, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallRequest.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallRequest.kt deleted file mode 100644 index 8638105a6..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallRequest.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.network.model - -data class FloconNetworkCallRequest( - val floconCallId: String, - val request: FloconNetworkRequest, - val floconNetworkType: String, - val isMocked: Boolean, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallResponse.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallResponse.kt deleted file mode 100644 index 6a8fe9e28..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconNetworkCallResponse.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.network.model - -data class FloconNetworkCallResponse( - val floconCallId: String, - val response: FloconNetworkResponse, - val durationMs: Double, - val floconNetworkType: String, - val isMocked: Boolean, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketEvent.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketEvent.kt deleted file mode 100644 index 29903e336..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketEvent.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.network.model - -import io.github.openflocon.flocon.utils.currentTimeMillis - -class FloconWebSocketEvent( - val websocketUrl: String, - val event: Event, - val size: Long = 0L, - val message: String? = null, - val error: Throwable? = null, - val timeStamp: Long = currentTimeMillis(), -) { - enum class Event { - Closed, - Closing, - Error, - ReceiveMessage, - SendMessage, - Open, - } -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketMockListener.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketMockListener.kt deleted file mode 100644 index 3cd6b177e..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/FloconWebSocketMockListener.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.network.model - -interface FloconWebSocketMockListener { - fun onMessage(message: String) -} diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/MockNetworkResponse.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/MockNetworkResponse.kt deleted file mode 100644 index a1a51226d..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/network/model/MockNetworkResponse.kt +++ /dev/null @@ -1,39 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.network.model - -data class MockNetworkResponse( - val expectation: Expectation, - val response: Response, -) { - data class Expectation( - val urlPattern: String, // a regex - val method: String, // can be get, post, put, ... or a wildcard * - ) { - - private val regex = Regex(urlPattern) - - fun matches(url: String, method: String): Boolean { - val urlMatches = regex.matches(url) - val methodMatches = this.method == "*" || this.method.equals(method, ignoreCase = true) - return urlMatches && methodMatches - } - } - - sealed interface Response { - val delay: Long - data class Body( - val httpCode: Int, - val body: String, - override val delay: Long, - val mediaType: String, - val headers: Map, - ) : Response - data class ErrorThrow( - val classPath: String, - override val delay: Long, - ) : Response { - fun generate() : Throwable? { - return io.github.openflocon.flocon.utils.createThrowableFromClassName(classPath) - } - } - } -} \ No newline at end of file diff --git a/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts b/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts index e6a51bc83..a6d942dc0 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts +++ b/FloconAndroid/grpc/grpc-interceptor-base/build.gradle.kts @@ -12,7 +12,7 @@ android { dependencies { - implementation(projects.flocon) + implementation(projects.network.core) implementation(platform(libs.kotlinx.coroutines.bom)) implementation(libs.kotlinx.coroutines.core) diff --git a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/BadQuality.kt b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/BadQuality.kt index d69d425ae..d410a2a2d 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/BadQuality.kt +++ b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/BadQuality.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.grpc -import io.github.openflocon.flocon.pluginsold.network.model.BadQualityConfig +import io.github.openflocon.flocon.network.core.model.BadQualityConfig import java.io.IOException @Throws(IOException::class) diff --git a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcBaseInterceptor.kt b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcBaseInterceptor.kt index ee83bd28f..4f321f3f1 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcBaseInterceptor.kt +++ b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcBaseInterceptor.kt @@ -5,9 +5,9 @@ package io.github.openflocon.flocon.grpc import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.grpc.model.RequestHolder import io.github.openflocon.flocon.grpc.model.toHeaders -import io.github.openflocon.flocon.pluginsold.network.FloconNetworkPlugin -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkResponse +import io.github.openflocon.flocon.network.core.FloconNetworkPlugin +import io.github.openflocon.flocon.network.core.model.FloconNetworkRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkResponse import io.grpc.CallOptions import io.grpc.Channel import io.grpc.ClientCall diff --git a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt index f9cc4f8ad..732a4a925 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt +++ b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt @@ -1,7 +1,7 @@ package io.github.openflocon.flocon.grpc -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkResponse +import io.github.openflocon.flocon.network.core.model.FloconNetworkRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkResponse internal class FloconGrpcPlugin() { diff --git a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt index 00d93ba8b..5ad926c13 100644 --- a/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt +++ b/FloconAndroid/grpc/grpc-interceptor-base/src/main/kotlin/io/github/openflocon/flocon/grpc/model/RequestHolder.kt @@ -1,6 +1,6 @@ package io.github.openflocon.flocon.grpc.model -import io.github.openflocon.flocon.pluginsold.network.model.FloconNetworkRequest +import io.github.openflocon.flocon.network.core.model.FloconNetworkRequest import kotlinx.coroutines.CompletableDeferred internal data class RequestHolder( diff --git a/FloconAndroid/sample-android-only/build.gradle.kts b/FloconAndroid/sample-android-only/build.gradle.kts index 05691da2a..91a7f5647 100644 --- a/FloconAndroid/sample-android-only/build.gradle.kts +++ b/FloconAndroid/sample-android-only/build.gradle.kts @@ -91,6 +91,9 @@ dependencies { debugImplementation(projects.tables) releaseImplementation(projects.tablesNoOp) + debugImplementation(projects.analytics) + releaseImplementation(projects.analyticsNoOp) + debugImplementation(project(":database:room")) releaseImplementation(project(":database:room-no-op")) debugImplementation(project(":database:room3")) diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index 3f81b8483..c481c4321 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -39,6 +39,8 @@ include(":deeplinks") include(":deeplinks-no-op") include(":tables") include(":tables-no-op") +include(":analytics") +include(":analytics-no-op") include(":network:core") include(":network:core-no-op") include(":database:core") From b8136e48fe096343dcd290db1f2e680451746576 Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 13 May 2026 14:51:09 +0200 Subject: [PATCH 31/35] fix: Clean --- .../{plugins => }/analytics/FloconAnalyticsPlugin.kt | 4 ++-- .../analytics/builder/AnalyticsBuilder.kt | 8 ++++---- .../analytics/mapper/AnalyticsItemsMapper.kt | 4 ++-- .../{plugins => }/analytics/model/AnalyticsEvent.kt | 2 +- .../{plugins => }/analytics/model/AnalyticsItem.kt | 2 +- .../analytics/model/AnalyticsPropertiesConfig.kt | 2 +- .../deeplinks/FloconDeeplinkEncoding.kt | 4 ++-- .../{plugins => }/deeplinks/FloconDeeplinks.kt | 4 ++-- .../{plugins => }/deeplinks/FloconDeeplinksConfig.kt | 4 ++-- .../{plugins => }/deeplinks/FloconDeeplinksPlugin.kt | 4 ++-- .../flocon/{plugins => }/deeplinks/Mapping.kt | 12 ++++++------ .../{plugins => }/deeplinks/model/DeeplinkModel.kt | 2 +- .../{plugins => }/deeplinks/model/DeeplinksRemote.kt | 2 +- .../openflocon/flocon/myapplication/MainActivity.kt | 6 +++--- .../flocon/myapplication/table/InitializeTable.kt | 4 ++-- .../flocon/myapplication/multi/MainActivity.kt | 2 +- .../{plugins => }/tables/FloconTablesPlugin.kt | 6 +++--- .../flocon/{plugins => }/tables/dsl/TableItemDsl.kt | 6 +++--- .../{plugins => }/tables/model/TableColumnConfig.kt | 0 .../flocon/{plugins => }/tables/model/TableItem.kt | 2 +- 20 files changed, 40 insertions(+), 40 deletions(-) rename FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/analytics/FloconAnalyticsPlugin.kt (94%) rename FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/analytics/builder/AnalyticsBuilder.kt (74%) rename FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/analytics/mapper/AnalyticsItemsMapper.kt (85%) rename FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/analytics/model/AnalyticsEvent.kt (81%) rename FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/analytics/model/AnalyticsItem.kt (75%) rename FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/analytics/model/AnalyticsPropertiesConfig.kt (77%) rename FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/deeplinks/FloconDeeplinkEncoding.kt (81%) rename FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/deeplinks/FloconDeeplinks.kt (95%) rename FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/deeplinks/FloconDeeplinksConfig.kt (90%) rename FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/deeplinks/FloconDeeplinksPlugin.kt (93%) rename FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/deeplinks/Mapping.kt (72%) rename FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/deeplinks/model/DeeplinkModel.kt (91%) rename FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/deeplinks/model/DeeplinksRemote.kt (95%) rename FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/tables/FloconTablesPlugin.kt (93%) rename FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/tables/dsl/TableItemDsl.kt (83%) rename FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/tables/model/TableColumnConfig.kt (100%) rename FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/{plugins => }/tables/model/TableItem.kt (93%) diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/FloconAnalyticsPlugin.kt similarity index 94% rename from FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt rename to FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/FloconAnalyticsPlugin.kt index 9af8d73c8..dd06edf60 100644 --- a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsPlugin.kt +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/FloconAnalyticsPlugin.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.analytics +package io.github.openflocon.flocon.analytics import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconContext @@ -10,7 +10,7 @@ import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.core.encode -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem +import io.github.openflocon.flocon.analytics.model.AnalyticsItem class FloconAnalyticsConfig : FloconPluginConfig diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/builder/AnalyticsBuilder.kt similarity index 74% rename from FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt rename to FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/builder/AnalyticsBuilder.kt index d4aef5b4d..4b2387e1d 100644 --- a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/builder/AnalyticsBuilder.kt +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/builder/AnalyticsBuilder.kt @@ -1,10 +1,10 @@ @file:OptIn(ExperimentalUuidApi::class) -package io.github.openflocon.flocon.plugins.analytics.builder +package io.github.openflocon.flocon.analytics.builder -import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPlugin -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsEvent -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem +import io.github.openflocon.flocon.analytics.FloconAnalyticsPlugin +import io.github.openflocon.flocon.analytics.model.AnalyticsEvent +import io.github.openflocon.flocon.analytics.model.AnalyticsItem import io.github.openflocon.flocon.utils.currentTimeMillis import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/mapper/AnalyticsItemsMapper.kt similarity index 85% rename from FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt rename to FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/mapper/AnalyticsItemsMapper.kt index fc835947f..cb312861a 100644 --- a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/mapper/AnalyticsItemsMapper.kt +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/mapper/AnalyticsItemsMapper.kt @@ -1,6 +1,6 @@ -package io.github.openflocon.flocon.plugins.analytics.mapper +package io.github.openflocon.flocon.analytics.mapper -import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem +import io.github.openflocon.flocon.analytics.model.AnalyticsItem import kotlinx.serialization.Serializable @Serializable diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/model/AnalyticsEvent.kt similarity index 81% rename from FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt rename to FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/model/AnalyticsEvent.kt index b0de88ffa..0de6c0798 100644 --- a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsEvent.kt +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/model/AnalyticsEvent.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.analytics.model +package io.github.openflocon.flocon.analytics.model data class AnalyticsEvent( val eventName: String, diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/model/AnalyticsItem.kt similarity index 75% rename from FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt rename to FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/model/AnalyticsItem.kt index 55c7285cd..ba8c85753 100644 --- a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsItem.kt +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/model/AnalyticsItem.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.analytics.model +package io.github.openflocon.flocon.analytics.model data class AnalyticsItem( val id: String, diff --git a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/model/AnalyticsPropertiesConfig.kt similarity index 77% rename from FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt rename to FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/model/AnalyticsPropertiesConfig.kt index f36d72382..e73421fbb 100644 --- a/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/model/AnalyticsPropertiesConfig.kt +++ b/FloconAndroid/analytics/src/commonMain/kotlin/io/github/openflocon/flocon/analytics/model/AnalyticsPropertiesConfig.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.analytics.model +package io.github.openflocon.flocon.analytics.model data class AnalyticsPropertiesConfig( val name: String, diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinkEncoding.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinkEncoding.kt similarity index 81% rename from FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinkEncoding.kt rename to FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinkEncoding.kt index 45f898644..47c95538c 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinkEncoding.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinkEncoding.kt @@ -1,8 +1,8 @@ -package io.github.openflocon.flocon.plugins.deeplinks +package io.github.openflocon.flocon.deeplinks import io.github.openflocon.flocon.FloconEncoding import io.github.openflocon.flocon.dsl.FloconMarker -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkParameterRemote +import io.github.openflocon.flocon.deeplinks.model.DeeplinkParameterRemote import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.polymorphic import kotlinx.serialization.modules.subclass diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinks.kt similarity index 95% rename from FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt rename to FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinks.kt index 856d79497..16ba46096 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinks.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinks.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.deeplinks +package io.github.openflocon.flocon.deeplinks import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconContext @@ -11,7 +11,7 @@ import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.core.encode import io.github.openflocon.flocon.dsl.FloconMarker -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel +import io.github.openflocon.flocon.deeplinks.model.DeeplinkModel object FloconDeeplinks : FloconPluginFactory { override val name: String = "Deeplinks" diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksConfig.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinksConfig.kt similarity index 90% rename from FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksConfig.kt rename to FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinksConfig.kt index 7dd0e694c..2188911d6 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksConfig.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinksConfig.kt @@ -1,7 +1,7 @@ -package io.github.openflocon.flocon.plugins.deeplinks +package io.github.openflocon.flocon.deeplinks import io.github.openflocon.flocon.FloconPluginConfig -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel +import io.github.openflocon.flocon.deeplinks.model.DeeplinkModel abstract class FloconDeeplinksConfig : FloconPluginConfig { abstract fun variable(name: String, block: DeeplinkVariableBuilder.() -> Unit = {}) diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinksPlugin.kt similarity index 93% rename from FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt rename to FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinksPlugin.kt index 2369b1f7f..935b1a319 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksPlugin.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/FloconDeeplinksPlugin.kt @@ -1,7 +1,7 @@ -package io.github.openflocon.flocon.plugins.deeplinks +package io.github.openflocon.flocon.deeplinks import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel +import io.github.openflocon.flocon.deeplinks.model.DeeplinkModel class DeeplinkLinkBuilder internal constructor( private val link: String diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/Mapping.kt similarity index 72% rename from FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt rename to FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/Mapping.kt index 8e0194e42..4fbe5c66d 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/Mapping.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/Mapping.kt @@ -1,10 +1,10 @@ -package io.github.openflocon.flocon.plugins.deeplinks +package io.github.openflocon.flocon.deeplinks -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkModel -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkParameterRemote -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkRemote -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinkVariableRemote -import io.github.openflocon.flocon.plugins.deeplinks.model.DeeplinksRemote +import io.github.openflocon.flocon.deeplinks.model.DeeplinkModel +import io.github.openflocon.flocon.deeplinks.model.DeeplinkParameterRemote +import io.github.openflocon.flocon.deeplinks.model.DeeplinkRemote +import io.github.openflocon.flocon.deeplinks.model.DeeplinkVariableRemote +import io.github.openflocon.flocon.deeplinks.model.DeeplinksRemote internal fun createRemote( deeplinks: List, diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/model/DeeplinkModel.kt similarity index 91% rename from FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt rename to FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/model/DeeplinkModel.kt index 1578513e1..aa3d60d59 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinkModel.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/model/DeeplinkModel.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.deeplinks.model +package io.github.openflocon.flocon.deeplinks.model @ConsistentCopyVisibility data class DeeplinkModel internal constructor( diff --git a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/model/DeeplinksRemote.kt similarity index 95% rename from FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt rename to FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/model/DeeplinksRemote.kt index 1c9e7a37e..9e5be525e 100644 --- a/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/model/DeeplinksRemote.kt +++ b/FloconAndroid/deeplinks/src/commonMain/kotlin/io/github/openflocon/flocon/deeplinks/model/DeeplinksRemote.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.deeplinks.model +package io.github.openflocon.flocon.deeplinks.model import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt index 4c26b2858..f808131a7 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/MainActivity.kt @@ -33,9 +33,9 @@ import io.github.openflocon.flocon.myapplication.ui.ImagesListView import io.github.openflocon.flocon.myapplication.ui.theme.MyApplicationTheme import io.github.openflocon.flocon.network.core.FloconNetwork import io.github.openflocon.flocon.okhttp.FloconOkhttpInterceptor -import io.github.openflocon.flocon.plugins.analytics.FloconAnalytics -import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks -import io.github.openflocon.flocon.plugins.tables.FloconTable +import io.github.openflocon.flocon.analytics.FloconAnalytics +import io.github.openflocon.flocon.deeplinks.FloconDeeplinks +import io.github.openflocon.flocon.tables.FloconTable import io.github.openflocon.flocon.startFlocon import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch diff --git a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeTable.kt b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeTable.kt index 067f69081..a054832b2 100644 --- a/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeTable.kt +++ b/FloconAndroid/sample-android-only/src/main/java/io/github/openflocon/flocon/myapplication/table/InitializeTable.kt @@ -1,8 +1,8 @@ package io.github.openflocon.flocon.myapplication.table import io.github.openflocon.flocon.Flocon -import io.github.openflocon.flocon.plugins.tables.dsl.table -import io.github.openflocon.flocon.plugins.tables.tablePlugin +import io.github.openflocon.flocon.tables.dsl.table +import io.github.openflocon.flocon.tables.tablePlugin fun initializeTable() { Flocon.tablePlugin.table("analytics") { diff --git a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt index 89253a000..d2c637325 100644 --- a/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt +++ b/FloconAndroid/sample-multiplatform/src/androidMain/kotlin/io/github/openflocon/flocon/myapplication/multi/MainActivity.kt @@ -13,7 +13,7 @@ import io.github.openflocon.flocon.myapplication.multi.Databases.getFoodDatabase import io.github.openflocon.flocon.myapplication.multi.database.initializeDatabases import io.github.openflocon.flocon.myapplication.multi.sharedpreferences.initializeSharedPreferences import io.github.openflocon.flocon.myapplication.multi.ui.App -import io.github.openflocon.flocon.plugins.deeplinks.FloconDeeplinks +import io.github.openflocon.flocon.deeplinks.FloconDeeplinks import io.github.openflocon.flocon.startFlocon import io.ktor.client.HttpClient import io.ktor.client.engine.okhttp.OkHttp diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/FloconTablesPlugin.kt similarity index 93% rename from FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt rename to FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/FloconTablesPlugin.kt index e71bf2ee7..05f41b7cd 100644 --- a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesPlugin.kt +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/FloconTablesPlugin.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.tables +package io.github.openflocon.flocon.tables import io.github.openflocon.flocon.Flocon import io.github.openflocon.flocon.FloconConfig @@ -13,8 +13,8 @@ import io.github.openflocon.flocon.core.FloconMessageSender import io.github.openflocon.flocon.core.encode import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.error.pluginNotInitialized -import io.github.openflocon.flocon.plugins.tables.model.TableItem -import io.github.openflocon.flocon.plugins.tables.model.toRemote +import io.github.openflocon.flocon.tables.model.TableItem +import io.github.openflocon.flocon.tables.model.toRemote import kotlin.collections.map class FloconTableConfig : FloconPluginConfig diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/dsl/TableItemDsl.kt similarity index 83% rename from FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt rename to FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/dsl/TableItemDsl.kt index 98802bc8a..09fb74fc6 100644 --- a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/dsl/TableItemDsl.kt +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/dsl/TableItemDsl.kt @@ -1,9 +1,9 @@ @file:OptIn(ExperimentalUuidApi::class, ExperimentalTime::class) -package io.github.openflocon.flocon.plugins.tables.dsl +package io.github.openflocon.flocon.tables.dsl -import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin -import io.github.openflocon.flocon.plugins.tables.model.TableItem +import io.github.openflocon.flocon.tables.FloconTablePlugin +import io.github.openflocon.flocon.tables.model.TableItem import io.github.openflocon.flocon.pluginsold.tables.model.TableColumnConfig import kotlin.time.Clock import kotlin.time.ExperimentalTime diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/model/TableColumnConfig.kt similarity index 100% rename from FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableColumnConfig.kt rename to FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/model/TableColumnConfig.kt diff --git a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/model/TableItem.kt similarity index 93% rename from FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt rename to FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/model/TableItem.kt index 9eaff3359..11245d37e 100644 --- a/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/model/TableItem.kt +++ b/FloconAndroid/tables/src/commonMain/kotlin/io/github/openflocon/flocon/tables/model/TableItem.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.tables.model +package io.github.openflocon.flocon.tables.model import io.github.openflocon.flocon.pluginsold.tables.model.TableColumnConfig import kotlinx.serialization.Serializable From 1d2399b4036a3182e6ebd9fb5fe9457cc0383899 Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 13 May 2026 14:51:54 +0200 Subject: [PATCH 32/35] fix: Delete duplicate --- .../flocon/plugins/database/FloconDatabasePlugin.kt | 1 - .../plugins/database/model/FloconDatabaseModel.kt | 1 - .../model/fromdevice/DatabaseQueryLogModel.kt | 11 ----------- .../model/fromdevice/DeviceDataBaseDataModel.kt | 9 --------- .../model/fromdevice/QueryResultReceivedDataModel.kt | 9 --------- .../database/model/todevice/DatabaseQueryMessage.kt | 10 ---------- 6 files changed, 41 deletions(-) delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseQueryLogModel.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DeviceDataBaseDataModel.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/QueryResultReceivedDataModel.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/todevice/DatabaseQueryMessage.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt deleted file mode 100644 index 1d9511610..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/FloconDatabasePlugin.kt +++ /dev/null @@ -1 +0,0 @@ -// DEPRECATED: Moved to :database:core \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt deleted file mode 100644 index dc137eed6..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/FloconDatabaseModel.kt +++ /dev/null @@ -1 +0,0 @@ -// DEPRECATED diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseQueryLogModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseQueryLogModel.kt deleted file mode 100644 index d75c31fb5..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DatabaseQueryLogModel.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.openflocon.flocon.plugins.database.model.fromdevice - -import kotlinx.serialization.Serializable - -@Serializable -internal data class DatabaseQueryLogModel( - val dbName: String, - val sqlQuery: String, - val bindArgs: List?, - val timestamp: Long, -) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DeviceDataBaseDataModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DeviceDataBaseDataModel.kt deleted file mode 100644 index 6a24b7ea9..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/DeviceDataBaseDataModel.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.plugins.database.model.fromdevice - -import kotlinx.serialization.Serializable - -@Serializable -internal data class DeviceDataBaseDataModel( - val id: String, - val name: String, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/QueryResultReceivedDataModel.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/QueryResultReceivedDataModel.kt deleted file mode 100644 index 66f176021..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/fromdevice/QueryResultReceivedDataModel.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.plugins.database.model.fromdevice - -import kotlinx.serialization.Serializable - -@Serializable -internal data class QueryResultDataModel( - val requestId: String, - val result: String, -) \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/todevice/DatabaseQueryMessage.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/todevice/DatabaseQueryMessage.kt deleted file mode 100644 index 27508e328..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/database/model/todevice/DatabaseQueryMessage.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.github.openflocon.flocon.plugins.database.model.todevice - -import kotlinx.serialization.Serializable - -@Serializable -internal data class DatabaseQueryMessage( - val query: String, - val requestId: String, - val database: String, -) \ No newline at end of file From a25e0686924ab91eb50dca8df005a678d3455560 Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Wed, 13 May 2026 16:03:59 +0200 Subject: [PATCH 33/35] feat: Move crashreporter --- .../crashreporter-no-op/build.gradle.kts | 98 +++++++++++++++++++ .../crashreporter/FloconCrashReporterNoOp.kt | 50 ++++++++++ FloconAndroid/crashreporter/build.gradle.kts | 28 ++++++ .../FloconCrashReporterDataSource.android.kt | 5 +- .../UncaughtExceptionHandler.kt} | 2 +- .../FloconCrashReporterDataSource.kt | 4 +- .../FloconCrashReporterPlugin.kt | 4 +- .../model/CrashReportDataModel.kt | 2 +- .../crashreporter/CrashReporterDataSource.kt | 6 +- .../FloconCrashReporterDataSource.jvm.kt | 8 +- .../FloconCrashReporterDataSource.wasmJs.kt | 4 +- .../FloconCrashReporterDataSource.android.kt | 13 --- .../FloconCrashReporterPlugin.kt | 17 ---- FloconAndroid/settings.gradle.kts | 2 + 14 files changed, 195 insertions(+), 48 deletions(-) create mode 100644 FloconAndroid/crashreporter-no-op/build.gradle.kts create mode 100644 FloconAndroid/crashreporter-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterNoOp.kt create mode 100644 FloconAndroid/crashreporter/build.gradle.kts rename FloconAndroid/{flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold => crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon}/crashreporter/FloconCrashReporterDataSource.android.kt (88%) rename FloconAndroid/{flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/UncaughtExceptionHandler.android.kt => crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/UncaughtExceptionHandler.kt} (91%) rename FloconAndroid/{flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon}/crashreporter/FloconCrashReporterDataSource.kt (76%) rename FloconAndroid/{flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon}/crashreporter/FloconCrashReporterPlugin.kt (96%) rename FloconAndroid/{flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins => crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon}/crashreporter/model/CrashReportDataModel.kt (78%) rename FloconAndroid/{flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins => crashreporter/src/iosMain/kotlin/io/github/openflocon/flocon}/crashreporter/CrashReporterDataSource.kt (75%) rename FloconAndroid/{flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins => crashreporter/src/jvmMain/kotlin/io/github/openflocon/flocon}/crashreporter/FloconCrashReporterDataSource.jvm.kt (89%) rename FloconAndroid/{flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins => crashreporter/src/wasmJsMain/kotlin/io/github/openflocon/flocon}/crashreporter/FloconCrashReporterDataSource.wasmJs.kt (78%) delete mode 100644 FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.android.kt delete mode 100644 FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt diff --git a/FloconAndroid/crashreporter-no-op/build.gradle.kts b/FloconAndroid/crashreporter-no-op/build.gradle.kts new file mode 100644 index 000000000..3fefefb36 --- /dev/null +++ b/FloconAndroid/crashreporter-no-op/build.gradle.kts @@ -0,0 +1,98 @@ +plugins { + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.android.library) + alias(libs.plugins.vanniktech.maven.publish) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm() + + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.kotlinx.coroutines.core) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.crashreporter.noop" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +mavenPublishing { + publishToMavenCentral(automaticRelease = true) + + if (project.hasProperty("signing.required") && project.property("signing.required") == "false") { + // Skip signing + } else { + signAllPublications() + } + + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-crashreporter-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) + + pom { + name = "Flocon CrashReporter No-Op" + description = project.property("floconDescription") as String + inceptionYear = "2025" + url = "https://github.com/openflocon/Flocon" + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + developers { + developer { + id = "openflocon" + name = "Open Flocon" + url = "https://github.com/openflocon" + } + } + scm { + url = "https://github.com/openflocon/Flocon" + connection = "scm:git:git://github.com/openflocon/Flocon.git" + developerConnection = "scm:git:ssh://git@github.com/openflocon/Flocon.git" + } + } +} diff --git a/FloconAndroid/crashreporter-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterNoOp.kt b/FloconAndroid/crashreporter-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterNoOp.kt new file mode 100644 index 000000000..b3ce8e05e --- /dev/null +++ b/FloconAndroid/crashreporter-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterNoOp.kt @@ -0,0 +1,50 @@ +package io.github.openflocon.flocon.crashreporter + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol + +class FloconCrashReporterConfig : FloconPluginConfig { + var catchFatalErrors: Boolean = true +} + +interface FloconCrashReporterPlugin : FloconPlugin { + fun setupCrashHandler() +} + +object FloconCrashReporter : FloconPluginFactory { + override val name: String = "CrashReporter" + override val pluginId: String = Protocol.ToDevice.Analytics.Plugin // Same as real impl + + override fun createConfig(context: FloconContext) = FloconCrashReporterConfig() + + override fun install( + pluginConfig: FloconCrashReporterConfig, + floconConfig: FloconConfig, + encoder: io.github.openflocon.flocon.core.FloconEncoder + ): FloconCrashReporterPlugin { + return FloconCrashReporterNoOpImpl() + } +} + +internal class FloconCrashReporterNoOpImpl : FloconPlugin, FloconCrashReporterPlugin { + override val key: String = "CRASH_REPORTER" + + override fun setupCrashHandler() { + // no op + } + + override suspend fun onConnectedToServer() { + // no op + } + + override suspend fun onMessageReceived( + method: String, + body: String, + ) { + // no op + } +} diff --git a/FloconAndroid/crashreporter/build.gradle.kts b/FloconAndroid/crashreporter/build.gradle.kts new file mode 100644 index 000000000..c8921cc6b --- /dev/null +++ b/FloconAndroid/crashreporter/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + id("flocon.kotlin.multiplatform") + id("flocon.publish") +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.serialization.json) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.crashreporter" +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-crashreporter", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt b/FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.android.kt similarity index 88% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt rename to FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.android.kt index 927c2a107..c76eac1f6 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterDataSource.android.kt +++ b/FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.android.kt @@ -1,12 +1,11 @@ -package io.github.openflocon.flocon.pluginsold.crashreporter +package io.github.openflocon.flocon.crashreporter import android.content.Context import io.github.openflocon.flocon.FloconLogger import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.decode import io.github.openflocon.flocon.core.encode -import io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporterDataSource -import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel +import io.github.openflocon.flocon.crashreporter.model.CrashReportDataModel import java.io.File internal class FloconCrashReporterDataSourceAndroid( diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/UncaughtExceptionHandler.android.kt b/FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/UncaughtExceptionHandler.kt similarity index 91% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/UncaughtExceptionHandler.android.kt rename to FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/UncaughtExceptionHandler.kt index 1608a2c24..9ceea95c8 100644 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/UncaughtExceptionHandler.android.kt +++ b/FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/UncaughtExceptionHandler.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.pluginsold.crashreporter +package io.github.openflocon.flocon.crashreporter import android.os.Build import io.github.openflocon.flocon.FloconContext diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.kt b/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.kt similarity index 76% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.kt rename to FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.kt index 1134b5554..09594503a 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.kt +++ b/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.kt @@ -1,7 +1,7 @@ -package io.github.openflocon.flocon.plugins.crashreporter +package io.github.openflocon.flocon.crashreporter import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel +import io.github.openflocon.flocon.crashreporter.model.CrashReportDataModel internal interface FloconCrashReporterDataSource { fun saveCrash(crash: CrashReportDataModel) diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterPlugin.kt similarity index 96% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt rename to FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterPlugin.kt index 8fb7032d3..c3d33a938 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterPlugin.kt +++ b/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterPlugin.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.crashreporter +package io.github.openflocon.flocon.crashreporter import io.github.openflocon.flocon.FloconConfig import io.github.openflocon.flocon.FloconContext @@ -9,7 +9,7 @@ import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.core.FloconMessageSender -import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel +import io.github.openflocon.flocon.crashreporter.model.CrashReportDataModel import io.github.openflocon.flocon.utils.currentTimeMillis import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportDataModel.kt b/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/model/CrashReportDataModel.kt similarity index 78% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportDataModel.kt rename to FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/model/CrashReportDataModel.kt index 1d10cae2f..edbd8cc4d 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/model/CrashReportDataModel.kt +++ b/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/model/CrashReportDataModel.kt @@ -1,4 +1,4 @@ -package io.github.openflocon.flocon.plugins.crashreporter.model +package io.github.openflocon.flocon.crashreporter.model import kotlinx.serialization.Serializable diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/CrashReporterDataSource.kt b/FloconAndroid/crashreporter/src/iosMain/kotlin/io/github/openflocon/flocon/crashreporter/CrashReporterDataSource.kt similarity index 75% rename from FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/CrashReporterDataSource.kt rename to FloconAndroid/crashreporter/src/iosMain/kotlin/io/github/openflocon/flocon/crashreporter/CrashReporterDataSource.kt index 4d80478b4..f2350c2f1 100644 --- a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/CrashReporterDataSource.kt +++ b/FloconAndroid/crashreporter/src/iosMain/kotlin/io/github/openflocon/flocon/crashreporter/CrashReporterDataSource.kt @@ -1,8 +1,8 @@ -package io.github.openflocon.flocon.plugins.crashreporter +package io.github.openflocon.flocon.crashreporter -import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel +import io.github.openflocon.flocon.crashreporter.model.CrashReportDataModel -internal actual fun buildFloconCrashReporterDataSource(context: io.github.openflocon.flocon.FloconContext): io.github.openflocon.flocon.plugins.crashreporter.FloconCrashReporterDataSource { +internal actual fun buildFloconCrashReporterDataSource(context: io.github.openflocon.flocon.FloconContext): io.github.openflocon.flocon.crashreporter.FloconCrashReporterDataSource { return object : FloconCrashReporterDataSource { override fun saveCrash(crash: CrashReportDataModel) { // no op diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.jvm.kt b/FloconAndroid/crashreporter/src/jvmMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.jvm.kt similarity index 89% rename from FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.jvm.kt rename to FloconAndroid/crashreporter/src/jvmMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.jvm.kt index 7b62ac334..b81678f37 100644 --- a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.jvm.kt +++ b/FloconAndroid/crashreporter/src/jvmMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.jvm.kt @@ -1,10 +1,10 @@ -package io.github.openflocon.flocon.plugins.crashreporter +package io.github.openflocon.flocon.crashreporter import io.github.openflocon.flocon.FloconContext import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel -import io.github.openflocon.flocon.plugins.crashreporter.model.crashReportFromJson -import io.github.openflocon.flocon.plugins.crashreporter.model.toJson +import io.github.openflocon.flocon.crashreporter.model.CrashReportDataModel +import io.github.openflocon.flocon.crashreporter.model.crashReportFromJson +import io.github.openflocon.flocon.crashreporter.model.toJson import java.io.File internal class FloconCrashReporterDataSourceJvm : FloconCrashReporterDataSource { diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.wasmJs.kt b/FloconAndroid/crashreporter/src/wasmJsMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.wasmJs.kt similarity index 78% rename from FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.wasmJs.kt rename to FloconAndroid/crashreporter/src/wasmJsMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.wasmJs.kt index c35073b68..199337f59 100644 --- a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.wasmJs.kt +++ b/FloconAndroid/crashreporter/src/wasmJsMain/kotlin/io/github/openflocon/flocon/crashreporter/FloconCrashReporterDataSource.wasmJs.kt @@ -1,7 +1,7 @@ -package io.github.openflocon.flocon.plugins.crashreporter +package io.github.openflocon.flocon.crashreporter import io.github.openflocon.flocon.FloconContext -import io.github.openflocon.flocon.plugins.crashreporter.model.CrashReportDataModel +import io.github.openflocon.flocon.crashreporter.model.CrashReportDataModel internal actual fun buildFloconCrashReporterDataSource(context: FloconContext): FloconCrashReporterDataSource = object : FloconCrashReporterDataSource { override fun saveCrash(crash: CrashReportDataModel) {} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.android.kt b/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.android.kt deleted file mode 100644 index e736d8c8b..000000000 --- a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/crashreporter/FloconCrashReporterDataSource.android.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.github.openflocon.flocon.plugins.crashreporter - -import io.github.openflocon.flocon.FloconContext - -internal actual fun buildFloconCrashReporterDataSource(context: FloconContext): FloconCrashReporterDataSource { - TODO("Not yet implemented") -} - -internal actual fun setupUncaughtExceptionHandler( - context: FloconContext, - onCrash: (Throwable) -> Unit -) { -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt deleted file mode 100644 index e30e0037d..000000000 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/crashreporter/FloconCrashReporterPlugin.kt +++ /dev/null @@ -1,17 +0,0 @@ -package io.github.openflocon.flocon.pluginsold.crashreporter - -import io.github.openflocon.flocon.FloconPlugin -import io.github.openflocon.flocon.FloconPluginConfig - -class FloconCrashReporterConfig : FloconPluginConfig { - var catchFatalErrors: Boolean = true -} - -/** - * Flocon Crash Reporter Plugin. - */ -//expect object FloconCrashReporter : FloconPluginFactory -// -interface FloconCrashReporterPlugin : FloconPlugin { - fun setupCrashHandler() -} \ No newline at end of file diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index c481c4321..e9b0f8524 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -41,6 +41,8 @@ include(":tables") include(":tables-no-op") include(":analytics") include(":analytics-no-op") +include(":crashreporter") +include(":crashreporter-no-op") include(":network:core") include(":network:core-no-op") include(":database:core") From 0f225557f75c4272e557997f2614dd525b94459e Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Thu, 21 May 2026 14:14:13 +0200 Subject: [PATCH 34/35] fix: Build --- .../plugins/analytics/FloconAnalyticsNoOp.kt | 4 +- .../build-logic/convention/build.gradle.kts | 6 + .../crashreporter-no-op/build.gradle.kts | 75 +---------- .../FloconCrashReporterDataSource.android.kt | 19 ++- .../crashreporter/UncaughtExceptionHandler.kt | 37 +++--- .../model/CrashReportDataModel.kt | 12 +- .../database/room/floconRegisterDatabase.kt | 9 -- .../database/room3/floconRegisterDatabase.kt | 9 -- .../datastores-no-op/build.gradle.kts | 1 + FloconAndroid/datastores/build.gradle.kts | 1 + .../plugins/deeplinks/FloconDeeplinksNoOp.kt | 74 +++++++---- FloconAndroid/device-no-op/build.gradle.kts | 27 ++++ .../plugins/device/FloconDevicePlugin.kt | 47 +++++++ FloconAndroid/device/build.gradle.kts | 28 ++++ .../device/FloconDevicePluginImpl.android.kt | 0 .../plugins/device/GetAppIconUtils.android.kt | 0 .../plugins/device/FloconDevicePluginImpl.kt | 0 .../flocon/plugins/device/GetAppIconUtils.kt | 0 .../fromdevice/RegisterDeviceDataModel.kt | 0 .../device/FloconDevicePluginImpl.ios.kt | 0 .../plugins/device/GetAppIconUtils.ios.kt | 0 .../device/FloconDevicePluginImpl.jvm.kt | 0 .../plugins/device/GetAppIconUtils.jvm.kt | 0 .../device/FloconDevicePluginImpl.wasmJs.kt | 0 .../plugins/device/GetAppIconUtils.wasmJs.kt | 0 FloconAndroid/files-no-op/build.gradle.kts | 27 ++++ .../flocon/plugins/files/FloconFilesPlugin.kt | 43 ++++++ FloconAndroid/files/build.gradle.kts | 28 ++++ .../files/FloconFilesPlugin.android.kt | 0 .../files/FloconFilesPlugin.android.kt | 0 .../flocon/plugins/files/FloconFilesPlugin.kt | 0 .../files/model/fromdevice/FileDataModel.kt | 0 .../model/fromdevice/FilesResultDataModel.kt | 0 .../todevice/ToDeviceDeleteFileMessage.kt | 0 .../todevice/ToDeviceDeleteFilesMessage.kt | 0 .../ToDeviceDeleteFolderContentMessage.kt | 0 .../model/todevice/ToDeviceGetFileMessage.kt | 0 .../model/todevice/ToDeviceGetFilesMessage.kt | 0 .../pluginsold/files/FloconFilesPlugin.kt | 0 .../plugins/files/FloconFilesPlugin.ios.kt | 0 .../plugins/files/FloconFilesPlugin.jvm.kt | 0 .../plugins/files/FloconFilesPlugin.wasmJs.kt | 0 .../openflocon/flocon/Flocon.android.kt | 2 +- .../sharedprefs/FloconSharedPreference.kt | 26 ---- .../flocon/core/FloconFileSender.kt | 2 +- .../network/core-no-op/build.gradle.kts | 3 + .../flocon/network/core/noop/FloconNetwork.kt | 8 +- .../core/noop/mapper/BadQualityToJson.kt | 104 --------------- .../noop/mapper/FloconNetworkRequestToJson.kt | 111 ---------------- .../core/noop/mapper/MockResponseToJson.kt | 123 ------------------ .../network/core/noop/mapper/Websocket.kt | 29 ----- .../sample-android-only/build.gradle.kts | 3 + FloconAndroid/settings.gradle.kts | 6 + .../sharedprefs-no-op/build.gradle.kts | 27 ++++ .../sharedprefs/FloconSharedPrefsPlugin.kt | 48 +++++++ .../model/FloconSharedPreferenceModel.kt | 4 + .../sharedprefs/FloconSharedPrefsPlugin.kt | 50 +++++++ .../model/FloconSharedPreferenceModel.kt | 4 + FloconAndroid/sharedprefs/build.gradle.kts | 28 ++++ .../FloconSharedPrefsPlugin.android.kt | 0 .../sharedprefs/FloconSharedPreference.kt | 0 .../FloconSharedPrefsPlugin.android.kt | 0 .../sharedprefs/SharedPreferencesFinder.kt | 0 .../sharedprefs/FloconSharedPrefsPlugin.kt | 0 .../model/FloconPreferenceWrapper.kt | 0 .../model/FloconSharedPreferenceModel.kt | 0 .../fromdevice/PreferenceRowDataModel.kt | 0 .../SharedPreferenceValueResultDataModel.kt | 0 ...oDeviceEditSharedPreferenceValueMessage.kt | 0 ...ToDeviceGetSharedPreferenceValueMessage.kt | 0 .../todevice/ToDeviceGetSharedPrefsMessage.kt | 0 .../sharedprefs/FloconSharedPrefsPlugin.kt | 0 .../buildFloconPreferencesDataSource.kt | 0 .../sharedprefs/model/FloconPreference.kt | 0 .../model/FloconSharedPreferenceModel.kt | 0 .../FloconSharedPrefsPlugin.ios.kt | 0 .../FloconSharedPrefsPlugin.jvm.kt | 0 .../FloconSharedPrefsPlugin.wasmJs.kt | 0 .../flocon/plugins/tables/FloconTablesNoOp.kt | 4 +- 79 files changed, 486 insertions(+), 543 deletions(-) delete mode 100644 FloconAndroid/database/room-no-op/src/main/java/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt delete mode 100644 FloconAndroid/database/room3-no-op/src/main/java/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt create mode 100644 FloconAndroid/device-no-op/build.gradle.kts create mode 100644 FloconAndroid/device-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt create mode 100644 FloconAndroid/device/build.gradle.kts rename FloconAndroid/{flocon => device}/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.android.kt (100%) rename FloconAndroid/{flocon => device}/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.android.kt (100%) rename FloconAndroid/{flocon => device}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt (100%) rename FloconAndroid/{flocon => device}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.kt (100%) rename FloconAndroid/{flocon => device}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/model/fromdevice/RegisterDeviceDataModel.kt (100%) rename FloconAndroid/{flocon => device}/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.ios.kt (100%) rename FloconAndroid/{flocon => device}/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.ios.kt (100%) rename FloconAndroid/{flocon => device}/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.jvm.kt (100%) rename FloconAndroid/{flocon => device}/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.jvm.kt (100%) rename FloconAndroid/{flocon => device}/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.wasmJs.kt (100%) rename FloconAndroid/{flocon => device}/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.wasmJs.kt (100%) create mode 100644 FloconAndroid/files-no-op/build.gradle.kts create mode 100644 FloconAndroid/files-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt create mode 100644 FloconAndroid/files/build.gradle.kts rename FloconAndroid/{flocon => files}/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.android.kt (100%) rename FloconAndroid/{flocon => files}/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt (100%) rename FloconAndroid/{flocon => files}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt (100%) rename FloconAndroid/{flocon => files}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FileDataModel.kt (100%) rename FloconAndroid/{flocon => files}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FilesResultDataModel.kt (100%) rename FloconAndroid/{flocon => files}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFileMessage.kt (100%) rename FloconAndroid/{flocon => files}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFilesMessage.kt (100%) rename FloconAndroid/{flocon => files}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFolderContentMessage.kt (100%) rename FloconAndroid/{flocon => files}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFileMessage.kt (100%) rename FloconAndroid/{flocon => files}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFilesMessage.kt (100%) rename FloconAndroid/{flocon => files}/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt (100%) rename FloconAndroid/{flocon => files}/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.ios.kt (100%) rename FloconAndroid/{flocon => files}/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.jvm.kt (100%) rename FloconAndroid/{flocon => files}/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.wasmJs.kt (100%) delete mode 100644 FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt delete mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt delete mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt delete mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt delete mode 100644 FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt create mode 100644 FloconAndroid/sharedprefs-no-op/build.gradle.kts create mode 100644 FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt create mode 100644 FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt create mode 100644 FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt create mode 100644 FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt create mode 100644 FloconAndroid/sharedprefs/build.gradle.kts rename FloconAndroid/{flocon => sharedprefs}/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.android.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPreference.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.android.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/SharedPreferencesFinder.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreferenceWrapper.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/PreferenceRowDataModel.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/SharedPreferenceValueResultDataModel.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceEditSharedPreferenceValueMessage.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPreferenceValueMessage.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPrefsMessage.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/buildFloconPreferencesDataSource.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconPreference.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.ios.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt (100%) rename FloconAndroid/{flocon => sharedprefs}/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.wasmJs.kt (100%) diff --git a/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsNoOp.kt b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsNoOp.kt index 3e4204f84..bd8ff2d81 100644 --- a/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsNoOp.kt +++ b/FloconAndroid/analytics-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/analytics/FloconAnalyticsNoOp.kt @@ -6,6 +6,7 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem class FloconAnalyticsConfig : FloconPluginConfig @@ -20,7 +21,8 @@ object FloconAnalytics : FloconPluginFactory try { - encoder.decode(file.readText()) + crashReportFromJson(file.readText()) } catch (t: Throwable) { t.printStackTrace() null @@ -55,6 +54,6 @@ internal class FloconCrashReporterDataSourceAndroid( } } -//internal actual fun buildFloconCrashReporterDataSource(context: FloconContext): FloconCrashReporterDataSource { -// return FloconCrashReporterDataSourceAndroid(context.context) -//} +internal actual fun buildFloconCrashReporterDataSource(context: FloconContext): FloconCrashReporterDataSource { + return FloconCrashReporterDataSourceAndroid(context.context) +} diff --git a/FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/UncaughtExceptionHandler.kt b/FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/UncaughtExceptionHandler.kt index 9ceea95c8..7b15f98c5 100644 --- a/FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/UncaughtExceptionHandler.kt +++ b/FloconAndroid/crashreporter/src/androidMain/kotlin/io/github/openflocon/flocon/crashreporter/UncaughtExceptionHandler.kt @@ -1,23 +1,22 @@ package io.github.openflocon.flocon.crashreporter -import android.os.Build import io.github.openflocon.flocon.FloconContext -//internal actual fun setupUncaughtExceptionHandler( -// context: FloconContext, -// onCrash: (Throwable) -> Unit -//) { -// val defaultHandler = Thread.getDefaultUncaughtExceptionHandler() -// -// Thread.setDefaultUncaughtExceptionHandler { thread, throwable -> -// try { -// // Save crash -// onCrash(throwable) -// } catch (t: Throwable) { -// t.printStackTrace() -// } finally { -// // Call original handler to let the app crash normally -// defaultHandler?.uncaughtException(thread, throwable) -// } -// } -//} +internal actual fun setupUncaughtExceptionHandler( + context: FloconContext, + onCrash: (Throwable) -> Unit +) { + val defaultHandler = Thread.getDefaultUncaughtExceptionHandler() + + Thread.setDefaultUncaughtExceptionHandler { thread, throwable -> + try { + // Save crash + onCrash(throwable) + } catch (t: Throwable) { + t.printStackTrace() + } finally { + // Call original handler to let the app crash normally + defaultHandler?.uncaughtException(thread, throwable) + } + } +} diff --git a/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/model/CrashReportDataModel.kt b/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/model/CrashReportDataModel.kt index edbd8cc4d..be0d36ac1 100644 --- a/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/model/CrashReportDataModel.kt +++ b/FloconAndroid/crashreporter/src/commonMain/kotlin/io/github/openflocon/flocon/crashreporter/model/CrashReportDataModel.kt @@ -1,6 +1,8 @@ package io.github.openflocon.flocon.crashreporter.model import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import kotlinx.serialization.encodeToString @Serializable data class CrashReportDataModel( @@ -9,4 +11,12 @@ data class CrashReportDataModel( val exceptionType: String, val exceptionMessage: String, val stackTrace: String, -) \ No newline at end of file +) + +fun CrashReportDataModel.toJson(): String { + return Json.encodeToString(this) +} + +fun crashReportFromJson(json: String): CrashReportDataModel { + return Json.decodeFromString(json) +} \ No newline at end of file diff --git a/FloconAndroid/database/room-no-op/src/main/java/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt b/FloconAndroid/database/room-no-op/src/main/java/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt deleted file mode 100644 index 1aefa1497..000000000 --- a/FloconAndroid/database/room-no-op/src/main/java/io/github/openflocon/flocon/database/room/floconRegisterDatabase.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.database.room - -fun floconRegisterDatabase(displayName: String, database: Any) { - // no op -} - -fun floconRegisterDatabase(displayName: String, openHelper: Any, dummy: Boolean = true) { - // no op -} diff --git a/FloconAndroid/database/room3-no-op/src/main/java/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt b/FloconAndroid/database/room3-no-op/src/main/java/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt deleted file mode 100644 index e5f4b0a89..000000000 --- a/FloconAndroid/database/room3-no-op/src/main/java/io/github/openflocon/flocon/database/room3/floconRegisterDatabase.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.openflocon.flocon.database.room3 - -fun floconRegisterDatabase(displayName: String, database: Any) { - // no op -} - -fun floconRegisterDatabase(displayName: String, openHelper: Any, dummy: Boolean = true) { - // no op -} diff --git a/FloconAndroid/datastores-no-op/build.gradle.kts b/FloconAndroid/datastores-no-op/build.gradle.kts index b27fdd579..e65ef303d 100644 --- a/FloconAndroid/datastores-no-op/build.gradle.kts +++ b/FloconAndroid/datastores-no-op/build.gradle.kts @@ -14,6 +14,7 @@ kotlin { val commonMain by getting { dependencies { implementation(projects.flocon) + implementation(projects.sharedprefs) implementation(libs.kotlinx.coroutines.core) } } diff --git a/FloconAndroid/datastores/build.gradle.kts b/FloconAndroid/datastores/build.gradle.kts index 3fa34912b..afcdc2b4c 100644 --- a/FloconAndroid/datastores/build.gradle.kts +++ b/FloconAndroid/datastores/build.gradle.kts @@ -14,6 +14,7 @@ kotlin { val commonMain by getting { dependencies { implementation(projects.flocon) + implementation(projects.sharedprefs) implementation(libs.kotlinx.coroutines.core) } } diff --git a/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt b/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt index 83c349e12..daf00d0ed 100644 --- a/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt +++ b/FloconAndroid/deeplinks-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/deeplinks/FloconDeeplinksNoOp.kt @@ -1,34 +1,62 @@ -package io.github.openflocon.flocon.plugins.deeplinks +package io.github.openflocon.flocon.deeplinks -import io.github.openflocon.flocon.* +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.core.FloconEncoder -actual object FloconDeeplinks : FloconPluginFactory { - override val name: String = "Deeplinks" - override val pluginId: String = null - override fun createConfig() = FloconDeeplinksConfig() - override fun install(config: FloconDeeplinksConfig, app: FloconApp): FloconDeeplinksPlugin { - return FloconDeeplinksPluginNoOp - } +class DeeplinkModel + +class DeeplinkVariable + +class DeeplinkLinkBuilder internal constructor(private val link: String) { + var label: String? = null + var description: String? = null + + infix fun String.withAutoComplete(suggestions: List) {} + infix fun String.withVariable(variableName: String) {} } -private object FloconDeeplinksPluginNoOp : FloconDeeplinksPlugin { - override fun registerDeeplinks(deeplinks: List) { - // no-op - } +class DeeplinkVariableBuilder internal constructor(private val name: String) { + var description: String? = null + fun autoComplete(suggestions: List) {} +} - override fun onMessageReceived(method: String, body: String) { - // no-op - } +abstract class FloconDeeplinksConfig : FloconPluginConfig { + abstract fun variable(name: String, block: DeeplinkVariableBuilder.() -> Unit = {}) + abstract fun deeplink(link: String, block: DeeplinkLinkBuilder.() -> Unit = {}) + internal abstract fun deeplinks(): List + internal abstract fun variables(): List +} - override fun onConnectedToServer() { - // no-op - } +internal class FloconDeeplinksConfigImpl : FloconDeeplinksConfig() { + override fun variable(name: String, block: DeeplinkVariableBuilder.() -> Unit) {} + override fun deeplink(link: String, block: DeeplinkLinkBuilder.() -> Unit) {} + override fun deeplinks(): List = emptyList() + override fun variables(): List = emptyList() } -fun floconRegisterDeeplink(vararg deeplinks: String) { - // no-op +interface FloconDeeplinksPlugin : FloconPlugin + +object FloconDeeplinks : FloconPluginFactory { + override val name: String = "Deeplinks" + override val pluginId: String = "FloconDeeplinks" + + override fun createConfig(context: FloconContext): FloconDeeplinksConfig = FloconDeeplinksConfigImpl() + + override fun install( + pluginConfig: FloconDeeplinksConfig, + floconConfig: FloconConfig, + encoder: FloconEncoder + ): FloconDeeplinksPlugin { + return FloconDeeplinksPluginNoOp + } } -fun floconRegisterDeeplinks(deeplinks: List) { - // no-op +private object FloconDeeplinksPluginNoOp : FloconDeeplinksPlugin { + override val key: String = "DEEP_LINK" + override suspend fun onMessageReceived(method: String, body: String) {} + override suspend fun onConnectedToServer() {} } diff --git a/FloconAndroid/device-no-op/build.gradle.kts b/FloconAndroid/device-no-op/build.gradle.kts new file mode 100644 index 000000000..44390215f --- /dev/null +++ b/FloconAndroid/device-no-op/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + id("flocon.kotlin.multiplatform") + id("flocon.publish") +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.kotlinx.coroutines.core) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.device.noop" +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-device-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} diff --git a/FloconAndroid/device-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt b/FloconAndroid/device-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt new file mode 100644 index 000000000..6e7bcd408 --- /dev/null +++ b/FloconAndroid/device-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePlugin.kt @@ -0,0 +1,47 @@ +package io.github.openflocon.flocon.plugins.device + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder + +class FloconDeviceConfig : FloconPluginConfig + +interface FloconDevicePlugin : FloconPlugin { + fun registerWithSerial(serial: String) +} + +object FloconDevice : FloconPluginFactory { + override val name: String = "Device" + override val pluginId: String = Protocol.ToDevice.Device.Plugin + override fun createConfig(context: FloconContext) = FloconDeviceConfig() + override fun install( + pluginConfig: FloconDeviceConfig, + floconConfig: FloconConfig, + encoder: FloconEncoder + ): FloconDevicePlugin { + return FloconDevicePluginNoOpImpl() + } +} + +internal class FloconDevicePluginNoOpImpl : FloconPlugin, FloconDevicePlugin { + override val key: String = "DEVICE" + + override fun registerWithSerial(serial: String) { + // no op + } + + override suspend fun onMessageReceived( + method: String, + body: String, + ) { + // no op + } + + override suspend fun onConnectedToServer() { + // no op + } +} diff --git a/FloconAndroid/device/build.gradle.kts b/FloconAndroid/device/build.gradle.kts new file mode 100644 index 000000000..1bbf9f756 --- /dev/null +++ b/FloconAndroid/device/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + id("flocon.kotlin.multiplatform") + id("flocon.publish") +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.serialization.json) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.device" +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-device", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.android.kt b/FloconAndroid/device/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.android.kt similarity index 100% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.android.kt rename to FloconAndroid/device/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.android.kt diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.android.kt b/FloconAndroid/device/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.android.kt similarity index 100% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.android.kt rename to FloconAndroid/device/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.android.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt b/FloconAndroid/device/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt rename to FloconAndroid/device/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.kt b/FloconAndroid/device/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.kt rename to FloconAndroid/device/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/model/fromdevice/RegisterDeviceDataModel.kt b/FloconAndroid/device/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/model/fromdevice/RegisterDeviceDataModel.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/model/fromdevice/RegisterDeviceDataModel.kt rename to FloconAndroid/device/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/device/model/fromdevice/RegisterDeviceDataModel.kt diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.ios.kt b/FloconAndroid/device/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.ios.kt similarity index 100% rename from FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.ios.kt rename to FloconAndroid/device/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.ios.kt diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.ios.kt b/FloconAndroid/device/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.ios.kt similarity index 100% rename from FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.ios.kt rename to FloconAndroid/device/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.ios.kt diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.jvm.kt b/FloconAndroid/device/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.jvm.kt similarity index 100% rename from FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.jvm.kt rename to FloconAndroid/device/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.jvm.kt diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.jvm.kt b/FloconAndroid/device/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.jvm.kt similarity index 100% rename from FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.jvm.kt rename to FloconAndroid/device/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.jvm.kt diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.wasmJs.kt b/FloconAndroid/device/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.wasmJs.kt similarity index 100% rename from FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.wasmJs.kt rename to FloconAndroid/device/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/FloconDevicePluginImpl.wasmJs.kt diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.wasmJs.kt b/FloconAndroid/device/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.wasmJs.kt similarity index 100% rename from FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.wasmJs.kt rename to FloconAndroid/device/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/device/GetAppIconUtils.wasmJs.kt diff --git a/FloconAndroid/files-no-op/build.gradle.kts b/FloconAndroid/files-no-op/build.gradle.kts new file mode 100644 index 000000000..558379a24 --- /dev/null +++ b/FloconAndroid/files-no-op/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + id("flocon.kotlin.multiplatform") + id("flocon.publish") +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.kotlinx.coroutines.core) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.files.noop" +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-files-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} diff --git a/FloconAndroid/files-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/files-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt new file mode 100644 index 000000000..7fb37ec01 --- /dev/null +++ b/FloconAndroid/files-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt @@ -0,0 +1,43 @@ +package io.github.openflocon.flocon.plugins.files + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder + +class FloconFilesConfig : FloconPluginConfig { + val roots = mutableListOf() +} + +interface FloconFilesPlugin : FloconPlugin + +object FloconFiles : FloconPluginFactory { + override val name: String = "Files" + override val pluginId: String = Protocol.ToDevice.Files.Plugin + override fun createConfig(context: FloconContext) = FloconFilesConfig() + override fun install( + pluginConfig: FloconFilesConfig, + floconConfig: FloconConfig, + encoder: FloconEncoder + ): FloconFilesPlugin { + return FloconFilesPluginNoOpImpl() + } +} + +internal class FloconFilesPluginNoOpImpl : FloconPlugin, FloconFilesPlugin { + override val key: String = "FILES" + + override suspend fun onMessageReceived( + method: String, + body: String, + ) { + // no op + } + + override suspend fun onConnectedToServer() { + // no op + } +} diff --git a/FloconAndroid/files/build.gradle.kts b/FloconAndroid/files/build.gradle.kts new file mode 100644 index 000000000..1686a517e --- /dev/null +++ b/FloconAndroid/files/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + id("flocon.kotlin.multiplatform") + id("flocon.publish") +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.serialization.json) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.files" +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-files", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.android.kt b/FloconAndroid/files/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.android.kt similarity index 100% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.android.kt rename to FloconAndroid/files/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.android.kt diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt b/FloconAndroid/files/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt similarity index 100% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt rename to FloconAndroid/files/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.android.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt b/FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt rename to FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FileDataModel.kt b/FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FileDataModel.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FileDataModel.kt rename to FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FileDataModel.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FilesResultDataModel.kt b/FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FilesResultDataModel.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FilesResultDataModel.kt rename to FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/fromdevice/FilesResultDataModel.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFileMessage.kt b/FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFileMessage.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFileMessage.kt rename to FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFileMessage.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFilesMessage.kt b/FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFilesMessage.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFilesMessage.kt rename to FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFilesMessage.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFolderContentMessage.kt b/FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFolderContentMessage.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFolderContentMessage.kt rename to FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceDeleteFolderContentMessage.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFileMessage.kt b/FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFileMessage.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFileMessage.kt rename to FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFileMessage.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFilesMessage.kt b/FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFilesMessage.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFilesMessage.kt rename to FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/files/model/todevice/ToDeviceGetFilesMessage.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt b/FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt rename to FloconAndroid/files/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/files/FloconFilesPlugin.kt diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.ios.kt b/FloconAndroid/files/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.ios.kt similarity index 100% rename from FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.ios.kt rename to FloconAndroid/files/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.ios.kt diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.jvm.kt b/FloconAndroid/files/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.jvm.kt similarity index 100% rename from FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.jvm.kt rename to FloconAndroid/files/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.jvm.kt diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.wasmJs.kt b/FloconAndroid/files/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.wasmJs.kt similarity index 100% rename from FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.wasmJs.kt rename to FloconAndroid/files/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/files/FloconFilesPlugin.wasmJs.kt diff --git a/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.android.kt b/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.android.kt index 7e6344375..9961ece8d 100644 --- a/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.android.kt +++ b/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/Flocon.android.kt @@ -12,7 +12,7 @@ actual object Flocon : FloconApp() { // This is a no-op implementation @Suppress("UNUSED_PARAMETER") fun initialize(context: Context) { - initializeFlocon() + // no-op } } diff --git a/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt b/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt deleted file mode 100644 index d5be3322c..000000000 --- a/FloconAndroid/flocon-no-op/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPreference.kt +++ /dev/null @@ -1,26 +0,0 @@ -package io.github.openflocon.flocon.plugins.sharedprefs - -import android.content.SharedPreferences -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreference -import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconPreferenceValue - -data class FloconSharedPreference( - override val name: String, - val sharedPreferences: SharedPreferences, -) : FloconPreference { - - override suspend fun set( - columnName: String, - value: FloconPreferenceValue - ) { - // no op - } - - override suspend fun columns(): List { - return emptyList() // no op - } - - override suspend fun get(columnName: String): FloconPreferenceValue? { - return null // no op - } -} \ No newline at end of file diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt index 43924d572..0dbac9617 100644 --- a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt +++ b/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/core/FloconFileSender.kt @@ -4,7 +4,7 @@ import io.github.openflocon.flocon.FloconFile import io.github.openflocon.flocon.dsl.FloconMarker import io.github.openflocon.flocon.model.FloconFileInfo -internal interface FloconFileSender { +interface FloconFileSender { @FloconMarker fun send(file: FloconFile, infos: FloconFileInfo) diff --git a/FloconAndroid/network/core-no-op/build.gradle.kts b/FloconAndroid/network/core-no-op/build.gradle.kts index 7247ac2a8..5438ed867 100644 --- a/FloconAndroid/network/core-no-op/build.gradle.kts +++ b/FloconAndroid/network/core-no-op/build.gradle.kts @@ -1,6 +1,7 @@ plugins { id("flocon.kotlin.multiplatform") id("flocon.publish") + alias(libs.plugins.kotlin.serialization) } kotlin { @@ -13,7 +14,9 @@ kotlin { val commonMain by getting { dependencies { implementation(projects.flocon) + implementation(projects.network.core) implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.serialization.json) } } diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt index 4935b04a4..cdf9cebd7 100644 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt +++ b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/FloconNetwork.kt @@ -10,16 +10,20 @@ import io.github.openflocon.flocon.network.core.noop.plugin.FloconNetworkPluginI import io.github.openflocon.flocon.network.core.FloconNetworkConfig import io.github.openflocon.flocon.network.core.FloconNetworkPlugin +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.core.FloconEncoder + object FloconNetwork : FloconPluginFactory { override val name: String = "Network" override val pluginId: String = Protocol.ToDevice.Network.Plugin - override fun createConfig() = FloconNetworkConfig() + override fun createConfig(context: FloconContext) = FloconNetworkConfig() @OptIn(FloconMarker::class) override fun install( pluginConfig: FloconNetworkConfig, - floconConfig: FloconConfig + floconConfig: FloconConfig, + encoder: FloconEncoder ): FloconNetworkPlugin { return FloconNetworkPluginImpl() .also { FloconNetworkPluginImpl.plugin = it } diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt deleted file mode 100644 index 90df55c94..000000000 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/BadQualityToJson.kt +++ /dev/null @@ -1,104 +0,0 @@ -package io.github.openflocon.flocon.network.core.noop.mapper - -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.network.core.model.BadQualityConfig -import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString - -internal fun BadQualityConfig.toJsonString(): String { - return FloconEncoder.json.encodeToString( - toSerializable() - ) -} - -internal fun parseBadQualityConfig(jsonString: String): BadQualityConfig? { - return try { - val parsed = FloconEncoder.json.decodeFromString( - jsonString - ) - parsed.toDomain() - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "bad connection network parsing issue", t) - null - } -} - -@Serializable -internal class BadQualityConfigSerializable( - val latency: LatencySerializable, - val errorProbability: Double, - val errors: List, -) { - @Serializable - class LatencySerializable( - val latencyTriggerProbability: Float, - val minLatencyMs: Long, - val maxLatencyMs: Long, - ) - - @Serializable - class ErrorSerializable( - val weight: Float, - val errorCode: Int? = null, - val errorBody: String? = null, - val errorContentType: String? = null, - val errorException: String? = null, - ) -} - -internal fun BadQualityConfig.toSerializable(): BadQualityConfigSerializable { - return BadQualityConfigSerializable( - latency = BadQualityConfigSerializable.LatencySerializable( - latencyTriggerProbability = latency.latencyTriggerProbability, - minLatencyMs = latency.minLatencyMs, - maxLatencyMs = latency.maxLatencyMs - ), - errorProbability = errorProbability, - errors = errors.map { error -> - when (val t = error.type) { - is BadQualityConfig.Error.Type.Body -> BadQualityConfigSerializable.ErrorSerializable( - weight = error.weight, - errorCode = t.errorCode, - errorBody = t.errorBody, - errorContentType = t.errorContentType - ) - - is BadQualityConfig.Error.Type.ErrorThrow -> BadQualityConfigSerializable.ErrorSerializable( - weight = error.weight, - errorException = t.classPath - ) - } - } - ) -} - -internal fun BadQualityConfigSerializable.toDomain(): BadQualityConfig { - val latencyConfig = BadQualityConfig.LatencyConfig( - latencyTriggerProbability = latency.latencyTriggerProbability, - minLatencyMs = latency.minLatencyMs, - maxLatencyMs = latency.maxLatencyMs - ) - - val errorsList = errors.map { e -> - val type = if (!e.errorException.isNullOrEmpty()) { - BadQualityConfig.Error.Type.ErrorThrow(e.errorException) - } else { - BadQualityConfig.Error.Type.Body( - errorCode = e.errorCode ?: 0, - errorBody = e.errorBody.orEmpty(), - errorContentType = e.errorContentType.orEmpty() - ) - } - BadQualityConfig.Error( - weight = e.weight, - type = type - ) - } - - return BadQualityConfig( - latency = latencyConfig, - errorProbability = errorProbability, - errors = errorsList - ) -} \ No newline at end of file diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt deleted file mode 100644 index 4fe64d4db..000000000 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/FloconNetworkRequestToJson.kt +++ /dev/null @@ -1,111 +0,0 @@ -@file:OptIn(ExperimentalUuidApi::class) - -package io.github.openflocon.flocon.network.core.noop.mapper - -import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.network.core.model.FloconNetworkCallRequest -import io.github.openflocon.flocon.network.core.model.FloconNetworkCallResponse -import io.github.openflocon.flocon.network.core.model.FloconWebSocketEvent -import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString -import kotlin.uuid.ExperimentalUuidApi -import kotlin.uuid.Uuid - -@Serializable -internal class FloconNetworkCallRequestRemote( - val floconCallId: String, - val floconNetworkType: String, - val isMocked: Boolean, - - val url: String, - val method: String, - val startTime: Long, - val requestBody: String?, - val requestHeaders: Map, - val requestSize: Long?, -) - -internal fun FloconNetworkCallRequest.floconNetworkCallRequestToJson(): String { - val remoteModel = FloconNetworkCallRequestRemote( - floconCallId = floconCallId, - floconNetworkType = floconNetworkType, - isMocked = isMocked, - url = request.url, - method = request.method, - startTime = request.startTime, - requestBody = request.body, - requestHeaders = request.headers, - requestSize = request.size - ) - return FloconEncoder.json.encodeToString(remoteModel) -} - -@Serializable -internal class FloconNetworkCallResponseRemote( - val floconCallId: String, - val durationMs: Double, - val floconNetworkType: String, - val isMocked: Boolean, - val responseHttpCode: Int?, - val responseGrpcStatus: String?, - val responseContentType: String?, - val responseBody: String?, - val responseSize: Long?, - val responseHeaders: Map, - val requestHeaders: Map?, // we might receive the request headers later if the interceptor is at first position in the http interceptor chain - val responseError: String?, - val isImage: Boolean, -) - -internal fun FloconNetworkCallResponse.floconNetworkCallResponseToJson(): String { - val remoteModel = FloconNetworkCallResponseRemote( - floconCallId = floconCallId, - floconNetworkType = floconNetworkType, - isMocked = isMocked, - durationMs = durationMs, - responseHttpCode = response.httpCode, - responseGrpcStatus = response.grpcStatus, - responseContentType = response.contentType, - responseBody = response.body, - responseHeaders = response.headers, - requestHeaders = response.requestHeaders?.takeIf { - it.isNotEmpty() - }, - responseSize = response.size, - isImage = response.isImage, - responseError = response.error, - ) - - return FloconEncoder.json.encodeToString(remoteModel) -} - -@Serializable -internal class FloconWebSocketEventRemote( - val id: String, - val event: String, - val url: String, - val size: Long, - val timestamp: Long, - val message: String?, - val error: String?, -) - -internal fun FloconWebSocketEvent.floconNetworkWebSocketEventToJson(): String { - val remoteModel = FloconWebSocketEventRemote( - id = Uuid.random().toString(), - event = when (event) { - FloconWebSocketEvent.Event.Closed -> "closed" - FloconWebSocketEvent.Event.Closing -> "closing" - FloconWebSocketEvent.Event.Error -> "error" - FloconWebSocketEvent.Event.ReceiveMessage -> "received" - FloconWebSocketEvent.Event.SendMessage -> "sent" - FloconWebSocketEvent.Event.Open -> "open" - }, - url = websocketUrl, - size = size, - timestamp = timeStamp, - message = message, - error = error?.message - ) - return FloconEncoder.json.encodeToString(remoteModel) -} \ No newline at end of file diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt deleted file mode 100644 index 2f96ac6ab..000000000 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt +++ /dev/null @@ -1,123 +0,0 @@ -<<<<<<<< HEAD:FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/MockResponseToJson.kt -package io.github.openflocon.flocon.network.core.mapper -======== -package io.github.openflocon.flocon.network.core.noop.mapper ->>>>>>>> 2.0.0:FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/MockResponseToJson.kt - -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder -import io.github.openflocon.flocon.network.core.model.MockNetworkResponse -import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString - -@Serializable -internal class MockNetworkResponseDataModel( - val expectation: Expectation, - val response: Response, -) { - @Serializable - class Expectation( - val urlPattern: String, // a regex - val method: String, // can be get, post, put, ... or a wildcard * - ) - - @Serializable - class Response( - val httpCode: Int?, - val body: String?, - val mediaType: String?, - val delay: Long?, - val headers: Map?, - val errorException: String?, - ) -} - - -internal fun parseMockResponses(jsonString: String): List { - try { - val remote = - FloconEncoder.json.decodeFromString>(jsonString) - return remote.mapNotNull { - it.toDomain() - } - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "mock network parsing issue", t) - return emptyList() - } -} - -internal fun MockNetworkResponseDataModel.toDomain(): MockNetworkResponse? { - return MockNetworkResponse( - expectation = MockNetworkResponse.Expectation( - urlPattern = expectation.urlPattern, - method = expectation.method, - ), - response = this.mapResponseToDomain() ?: return null - ) -} - -private fun MockNetworkResponseDataModel.mapResponseToDomain(): MockNetworkResponse.Response? { - return response.run { - when { - errorException != null -> MockNetworkResponse.Response.ErrorThrow( - classPath = errorException, - delay = delay ?: 0L, - ) - - httpCode != null -> MockNetworkResponse.Response.Body( - httpCode = httpCode, - body = body ?: "", - delay = delay ?: 0L, - mediaType = mediaType ?: "", - headers = headers ?: emptyMap() - ) - - else -> run { - FloconLogger.logError("error parsing mock response", null) - return@run null - } - } - } -} - - -internal fun writeMockResponsesToJson(mocks: List): String { - return try { - FloconEncoder.json.encodeToString(mocks.map { it.toRemote() }) - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "mock network writing issue", t) - return "[]" - } -} - -private fun MockNetworkResponse.toRemote(): MockNetworkResponseDataModel { - return MockNetworkResponseDataModel( - expectation = MockNetworkResponseDataModel.Expectation( - urlPattern = expectation.urlPattern, - method = expectation.method, - ), - response = mapResponseToRemote(), - ) -} - -private fun MockNetworkResponse.mapResponseToRemote(): MockNetworkResponseDataModel.Response { - return when (val response = this.response) { - is MockNetworkResponse.Response.ErrorThrow -> MockNetworkResponseDataModel.Response( - errorException = response.classPath, - delay = response.delay, - body = null, - headers = null, - httpCode = null, - mediaType = null, - ) - - is MockNetworkResponse.Response.Body -> MockNetworkResponseDataModel.Response( - errorException = null, - delay = response.delay, - body = response.body, - headers = response.headers, - httpCode = response.httpCode, - mediaType = response.mediaType, - ) - } -} diff --git a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt b/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt deleted file mode 100644 index 567a072cf..000000000 --- a/FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt +++ /dev/null @@ -1,29 +0,0 @@ -<<<<<<<< HEAD:FloconAndroid/network/core/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/mapper/Websocket.kt -package io.github.openflocon.flocon.network.core.mapper -======== -package io.github.openflocon.flocon.network.core.noop.mapper ->>>>>>>> 2.0.0:FloconAndroid/network/core-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/network/core/noop/mapper/Websocket.kt - -import io.github.openflocon.flocon.FloconLogger -import io.github.openflocon.flocon.core.FloconEncoder -import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString - -@Serializable -internal class WebSocketMockMessage( - val id: String, - val message: String, -) - -internal fun webSocketIdsToJsonArray(ids: Collection): String { - return FloconEncoder.json.encodeToString(ids) -} - -internal fun parseWebSocketMockMessage(jsonString: String): WebSocketMockMessage? { - try { - return FloconEncoder.json.decodeFromString(jsonString) - } catch (t: Throwable) { - FloconLogger.logError(t.message ?: "mock wesocket network parsing issue", t) - } - return null -} \ No newline at end of file diff --git a/FloconAndroid/sample-android-only/build.gradle.kts b/FloconAndroid/sample-android-only/build.gradle.kts index 91a7f5647..545be5263 100644 --- a/FloconAndroid/sample-android-only/build.gradle.kts +++ b/FloconAndroid/sample-android-only/build.gradle.kts @@ -94,6 +94,9 @@ dependencies { debugImplementation(projects.analytics) releaseImplementation(projects.analyticsNoOp) + debugImplementation(projects.crashreporter) + releaseImplementation(projects.crashreporterNoOp) + debugImplementation(project(":database:room")) releaseImplementation(project(":database:room-no-op")) debugImplementation(project(":database:room3")) diff --git a/FloconAndroid/settings.gradle.kts b/FloconAndroid/settings.gradle.kts index e9b0f8524..c4781ac24 100644 --- a/FloconAndroid/settings.gradle.kts +++ b/FloconAndroid/settings.gradle.kts @@ -43,6 +43,12 @@ include(":analytics") include(":analytics-no-op") include(":crashreporter") include(":crashreporter-no-op") +include(":device") +include(":device-no-op") +include(":files") +include(":files-no-op") +include(":sharedprefs") +include(":sharedprefs-no-op") include(":network:core") include(":network:core-no-op") include(":database:core") diff --git a/FloconAndroid/sharedprefs-no-op/build.gradle.kts b/FloconAndroid/sharedprefs-no-op/build.gradle.kts new file mode 100644 index 000000000..9de465592 --- /dev/null +++ b/FloconAndroid/sharedprefs-no-op/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + id("flocon.kotlin.multiplatform") + id("flocon.publish") +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.kotlinx.coroutines.core) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.sharedprefs.noop" +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-sharedprefs-no-op", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} diff --git a/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt new file mode 100644 index 000000000..05e27c6c0 --- /dev/null +++ b/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt @@ -0,0 +1,48 @@ +package io.github.openflocon.flocon.plugins.sharedprefs + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.plugins.sharedprefs.model.FloconSharedPreferenceModel + +class FloconPreferencesConfig : FloconPluginConfig + +interface FloconPreferencesPlugin : FloconPlugin { + fun register(sharedPreference: FloconSharedPreferenceModel) +} + +object FloconPreferences : FloconPluginFactory { + override val name: String = "Preferences" + override val pluginId: String = Protocol.ToDevice.SharedPreferences.Plugin + override fun createConfig(context: FloconContext) = FloconPreferencesConfig() + override fun install( + pluginConfig: FloconPreferencesConfig, + floconConfig: FloconConfig, + encoder: FloconEncoder + ): FloconPreferencesPlugin { + return FloconSharedPrefsPluginNoOpImpl() + } +} + +internal class FloconSharedPrefsPluginNoOpImpl : FloconPlugin, FloconPreferencesPlugin { + override val key: String = "SHARED_PREF" + + override suspend fun onMessageReceived( + method: String, + body: String, + ) { + // no op + } + + override suspend fun onConnectedToServer() { + // no op + } + + override fun register(sharedPreference: FloconSharedPreferenceModel) { + // no op + } +} diff --git a/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt b/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt new file mode 100644 index 000000000..a0b612b92 --- /dev/null +++ b/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt @@ -0,0 +1,4 @@ +package io.github.openflocon.flocon.plugins.sharedprefs.model + +class FloconSharedPreferenceModel { +} diff --git a/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt new file mode 100644 index 000000000..4ff1e05f8 --- /dev/null +++ b/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt @@ -0,0 +1,50 @@ +package io.github.openflocon.flocon.pluginsold.sharedprefs + +import io.github.openflocon.flocon.FloconConfig +import io.github.openflocon.flocon.FloconContext +import io.github.openflocon.flocon.FloconPlugin +import io.github.openflocon.flocon.FloconPluginConfig +import io.github.openflocon.flocon.FloconPluginFactory +import io.github.openflocon.flocon.core.FloconEncoder +import io.github.openflocon.flocon.pluginsold.sharedprefs.model.FloconSharedPreferenceModel + +class FloconPreferencesConfig : FloconPluginConfig + +object FloconPreferences : FloconPluginFactory { + override val name: String = "Preferences" + override val pluginId: String = "preferences" + override fun createConfig(context: FloconContext): FloconPreferencesConfig { + return FloconPreferencesConfig() + } + + override fun install( + pluginConfig: FloconPreferencesConfig, + floconConfig: FloconConfig, + encoder: FloconEncoder + ): FloconPreferencesPlugin { + return FloconSharedPrefsPluginNoOpImpl() + } +} + +interface FloconPreferencesPlugin : FloconPlugin { + fun register(sharedPreference: FloconSharedPreferenceModel) +} + +internal class FloconSharedPrefsPluginNoOpImpl : FloconPlugin, FloconPreferencesPlugin { + override val key: String = "SHARED_PREF" + + override suspend fun onMessageReceived( + method: String, + body: String, + ) { + // no op + } + + override suspend fun onConnectedToServer() { + // no op + } + + override fun register(sharedPreference: FloconSharedPreferenceModel) { + // no op + } +} diff --git a/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt b/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt new file mode 100644 index 000000000..86fb0e0b6 --- /dev/null +++ b/FloconAndroid/sharedprefs-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt @@ -0,0 +1,4 @@ +package io.github.openflocon.flocon.pluginsold.sharedprefs.model + +class FloconSharedPreferenceModel { +} diff --git a/FloconAndroid/sharedprefs/build.gradle.kts b/FloconAndroid/sharedprefs/build.gradle.kts new file mode 100644 index 000000000..9cee3f151 --- /dev/null +++ b/FloconAndroid/sharedprefs/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + id("flocon.kotlin.multiplatform") + id("flocon.publish") +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":flocon")) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.serialization.json) + } + } + } +} + +android { + namespace = "io.github.openflocon.flocon.sharedprefs" +} + +mavenPublishing { + coordinates( + groupId = project.property("floconGroupId") as String, + artifactId = "flocon-sharedprefs", + version = System.getenv("PROJECT_VERSION_NAME") ?: project.property("floconVersion") as String + ) +} diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.android.kt b/FloconAndroid/sharedprefs/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.android.kt similarity index 100% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.android.kt rename to FloconAndroid/sharedprefs/src/androidMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.android.kt diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPreference.kt b/FloconAndroid/sharedprefs/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPreference.kt similarity index 100% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPreference.kt rename to FloconAndroid/sharedprefs/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPreference.kt diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.android.kt b/FloconAndroid/sharedprefs/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.android.kt similarity index 100% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.android.kt rename to FloconAndroid/sharedprefs/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.android.kt diff --git a/FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/SharedPreferencesFinder.kt b/FloconAndroid/sharedprefs/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/SharedPreferencesFinder.kt similarity index 100% rename from FloconAndroid/flocon/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/SharedPreferencesFinder.kt rename to FloconAndroid/sharedprefs/src/androidMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/SharedPreferencesFinder.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreferenceWrapper.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreferenceWrapper.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreferenceWrapper.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconPreferenceWrapper.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/FloconSharedPreferenceModel.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/PreferenceRowDataModel.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/PreferenceRowDataModel.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/PreferenceRowDataModel.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/PreferenceRowDataModel.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/SharedPreferenceValueResultDataModel.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/SharedPreferenceValueResultDataModel.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/SharedPreferenceValueResultDataModel.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/fromdevice/SharedPreferenceValueResultDataModel.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceEditSharedPreferenceValueMessage.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceEditSharedPreferenceValueMessage.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceEditSharedPreferenceValueMessage.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceEditSharedPreferenceValueMessage.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPreferenceValueMessage.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPreferenceValueMessage.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPreferenceValueMessage.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPreferenceValueMessage.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPrefsMessage.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPrefsMessage.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPrefsMessage.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/model/todevice/ToDeviceGetSharedPrefsMessage.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/FloconSharedPrefsPlugin.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/buildFloconPreferencesDataSource.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/buildFloconPreferencesDataSource.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/buildFloconPreferencesDataSource.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/buildFloconPreferencesDataSource.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconPreference.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconPreference.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconPreference.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconPreference.kt diff --git a/FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt b/FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt similarity index 100% rename from FloconAndroid/flocon/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt rename to FloconAndroid/sharedprefs/src/commonMain/kotlin/io/github/openflocon/flocon/pluginsold/sharedprefs/model/FloconSharedPreferenceModel.kt diff --git a/FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.ios.kt b/FloconAndroid/sharedprefs/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.ios.kt similarity index 100% rename from FloconAndroid/flocon/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.ios.kt rename to FloconAndroid/sharedprefs/src/iosMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.ios.kt diff --git a/FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt b/FloconAndroid/sharedprefs/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt similarity index 100% rename from FloconAndroid/flocon/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt rename to FloconAndroid/sharedprefs/src/jvmMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.jvm.kt diff --git a/FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.wasmJs.kt b/FloconAndroid/sharedprefs/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.wasmJs.kt similarity index 100% rename from FloconAndroid/flocon/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.wasmJs.kt rename to FloconAndroid/sharedprefs/src/wasmJsMain/kotlin/io/github/openflocon/flocon/plugins/sharedprefs/FloconSharedPrefsPlugin.wasmJs.kt diff --git a/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesNoOp.kt b/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesNoOp.kt index 49946f2fc..53f21521d 100644 --- a/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesNoOp.kt +++ b/FloconAndroid/tables-no-op/src/commonMain/kotlin/io/github/openflocon/flocon/plugins/tables/FloconTablesNoOp.kt @@ -6,6 +6,7 @@ import io.github.openflocon.flocon.FloconPlugin import io.github.openflocon.flocon.FloconPluginConfig import io.github.openflocon.flocon.FloconPluginFactory import io.github.openflocon.flocon.Protocol +import io.github.openflocon.flocon.core.FloconEncoder import io.github.openflocon.flocon.plugins.tables.model.TableItem interface FloconTablePlugin : FloconPlugin { @@ -20,7 +21,8 @@ object FloconTable : FloconPluginFactory { override fun createConfig(context: FloconContext) = FloconTableConfig() override fun install( pluginConfig: FloconTableConfig, - floconConfig: FloconConfig + floconConfig: FloconConfig, + encoder: FloconEncoder ): FloconTablePlugin { return FloconTablePluginNoOp } From 2149379b8289049bdbbbaaeb314ec7c78dd52763 Mon Sep 17 00:00:00 2001 From: Raphael TEYSSANDIER Date: Fri, 29 May 2026 10:56:38 +0200 Subject: [PATCH 35/35] feat: FloconSpacing --- .../app/ui/settings/SettingsScreen.kt | 16 ++++++------ .../ui/view/leftpannel/LeftPannelDivider.kt | 4 ++- .../app/ui/view/leftpannel/LeftPannelView.kt | 6 ++--- .../app/ui/view/leftpannel/PannelLabel.kt | 2 +- .../app/ui/view/leftpannel/PannelView.kt | 8 +++--- .../app/ui/view/topbar/MainScreenTopBar.kt | 4 +-- .../ui/view/topbar/TopBarDeviceAndAppView.kt | 3 ++- .../ui/view/topbar/actions/TopBarActions.kt | 3 ++- .../app/ui/view/topbar/app/TopBarAppView.kt | 4 +-- .../ui/view/topbar/device/TopBarDeviceView.kt | 4 +-- .../features/database/view/DatabaseScreen.kt | 5 ++-- .../view/databases_tables/DatabaseItemView.kt | 4 +-- .../DatabasesAndTablesView.kt | 12 ++++----- .../view/databases_tables/TableItemView.kt | 6 ++--- .../mock/edition/view/MockNetworkLabelView.kt | 2 +- .../edition/view/MockNetworkMethodDropdown.kt | 5 ++-- .../mock/edition/view/NetworkEditionWindow.kt | 26 +++++++++---------- .../network/mock/list/view/MockLineView.kt | 8 +++--- .../library/designsystem/FloconTheme.kt | 7 +++++ .../designsystem/theme/FloconSpacing.kt | 21 +++++++++++++++ 20 files changed, 92 insertions(+), 58 deletions(-) create mode 100644 FloconDesktop/library/designsystem/src/commonMain/kotlin/io/github/openflocon/library/designsystem/theme/FloconSpacing.kt diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/settings/SettingsScreen.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/settings/SettingsScreen.kt index 115d0c254..ed54cbc7e 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/settings/SettingsScreen.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/settings/SettingsScreen.kt @@ -87,12 +87,12 @@ private fun SettingsScreen( initialValue = true ) { Column( - verticalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), modifier = Modifier - .padding(8.dp) + .padding(FloconTheme.spacing.small) .clip(FloconTheme.shapes.medium) .background(FloconTheme.colorPalette.primary) - .padding(all = 8.dp) + .padding(all = FloconTheme.spacing.small) ) { if (needsAdbSetup) { Text( @@ -103,7 +103,7 @@ private fun SettingsScreen( } else { Row( verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp) + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.extraSmall) ) { FloconIcon( imageVector = Icons.Outlined.Check, @@ -125,7 +125,7 @@ private fun SettingsScreen( modifier = Modifier.fillMaxWidth() ) Row( - horizontalArrangement = Arrangement.spacedBy(8.dp) + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small) ) { SettingsButton( text = stringResource(Res.string.general_save), @@ -144,10 +144,10 @@ private fun SettingsScreen( ) { Column( modifier = Modifier - .padding(8.dp) + .padding(FloconTheme.spacing.small) .clip(FloconTheme.shapes.medium) .background(FloconTheme.colorPalette.primary) - .padding(all = 8.dp) + .padding(all = FloconTheme.spacing.small) ) { FloconSlider( value = uiState.fontSizeMultiplier, @@ -164,7 +164,7 @@ private fun SettingsScreen( SettingsButton( onClick = { showLicenses = true }, text = stringResource(Res.string.settings_licenses), - modifier = Modifier.padding(8.dp) + modifier = Modifier.padding(FloconTheme.spacing.small) ) } } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/LeftPannelDivider.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/LeftPannelDivider.kt index 94aa59acc..deacee2f8 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/LeftPannelDivider.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/LeftPannelDivider.kt @@ -7,10 +7,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp +import io.github.openflocon.library.designsystem.FloconTheme + @Composable fun LeftPannelDivider(modifier: Modifier = Modifier) { HorizontalDivider( - modifier = modifier.padding(horizontal = 4.dp), + modifier = modifier.padding(horizontal = FloconTheme.spacing.extraSmall), thickness = 1.dp, color = Color.Gray, // TODO Change ) diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/LeftPannelView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/LeftPannelView.kt index e798846bc..cae56e29a 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/LeftPannelView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/LeftPannelView.kt @@ -45,7 +45,7 @@ fun LeftPanelView( modifier = modifier .clip(FloconTheme.shapes.medium) .background(FloconTheme.colorPalette.primary) - .padding(8.dp) + .padding(FloconTheme.spacing.small) ) { MenuSection( current = current, @@ -53,7 +53,7 @@ fun LeftPanelView( expanded = expanded, onClickItem = onClickItem, ) - Spacer(modifier = Modifier.height(12.dp)) + Spacer(modifier = Modifier.height(FloconTheme.spacing.medium)) Spacer(Modifier.weight(1f)) MenuItems( current = current, @@ -105,7 +105,7 @@ private fun ColumnScope.MenuItems( onClick = { onClickItem(item) }, ) if (index != items.lastIndex) - Spacer(Modifier.height(4.dp)) + Spacer(Modifier.height(FloconTheme.spacing.extraSmall)) } } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/PannelLabel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/PannelLabel.kt index 0575fbb49..c3434236d 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/PannelLabel.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/PannelLabel.kt @@ -35,7 +35,7 @@ fun PannelLabel( Text( modifier = Modifier .fillMaxWidth() - .padding(start = 12.dp, bottom = 4.dp), + .padding(start = FloconTheme.spacing.medium, bottom = FloconTheme.spacing.extraSmall), text = text, style = FloconTheme.typography.bodyLarge.copy( fontWeight = FontWeight.Thin, diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/PannelView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/PannelView.kt index 5130743f0..3e31fb1f4 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/PannelView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/leftpannel/PannelView.kt @@ -72,7 +72,7 @@ fun PanelView( 0.3f } else 1f ) - val horizontalPadding = 12.dp + val horizontalPadding = FloconTheme.spacing.medium Row( modifier = modifier @@ -83,13 +83,13 @@ fun PanelView( alpha = lineAlpha } .clickable(onClick = onClick, interactionSource = interactionSource, indication = null) - .padding(horizontal = horizontalPadding, vertical = 4.dp), + .padding(horizontal = horizontalPadding, vertical = FloconTheme.spacing.extraSmall), verticalAlignment = Alignment.CenterVertically, ) { Icon( modifier = Modifier .size(PanelContentMinSize - horizontalPadding.times(2)) - .padding(4.dp), + .padding(FloconTheme.spacing.extraSmall), imageVector = icon, contentDescription = "Description de mon image", tint = iconColor, @@ -104,7 +104,7 @@ fun PanelView( color = FloconTheme.colorPalette.onSurface, style = FloconTheme.typography.bodyMedium, maxLines = 1, - modifier = Modifier.padding(start = 12.dp), + modifier = Modifier.padding(start = FloconTheme.spacing.medium), ) } } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/MainScreenTopBar.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/MainScreenTopBar.kt index 4a5d43c46..fb938ae9b 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/MainScreenTopBar.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/MainScreenTopBar.kt @@ -45,7 +45,7 @@ fun MainScreenTopBar( Row( modifier = modifier .background(FloconTheme.colorPalette.surface) - .padding(vertical = 8.dp, horizontal = 12.dp), + .padding(vertical = FloconTheme.spacing.small, horizontal = FloconTheme.spacing.medium), verticalAlignment = Alignment.CenterVertically, ) { Title() @@ -75,7 +75,7 @@ private fun Title( ) { Row( modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(8.dp), + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), verticalAlignment = Alignment.CenterVertically, ) { Image( diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/TopBarDeviceAndAppView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/TopBarDeviceAndAppView.kt index 5bcaa0bf0..c4dfc316a 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/TopBarDeviceAndAppView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/TopBarDeviceAndAppView.kt @@ -17,6 +17,7 @@ import io.github.openflocon.flocondesktop.app.ui.model.DeviceItemUiModel import io.github.openflocon.flocondesktop.app.ui.model.DevicesStateUiModel import io.github.openflocon.flocondesktop.app.ui.view.topbar.app.TopBarAppDropdown import io.github.openflocon.flocondesktop.app.ui.view.topbar.device.TopBarDeviceDropdown +import io.github.openflocon.library.designsystem.FloconTheme @Composable internal fun TopBarDeviceAndAppView( @@ -30,7 +31,7 @@ internal fun TopBarDeviceAndAppView( ) { Row( modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(8.dp), + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), verticalAlignment = Alignment.CenterVertically, ) { TopBarDeviceDropdown( diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/actions/TopBarActions.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/actions/TopBarActions.kt index aff056108..50a4430fb 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/actions/TopBarActions.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/actions/TopBarActions.kt @@ -13,6 +13,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import io.github.openflocon.flocondesktop.app.ui.model.DevicesStateUiModel import io.github.openflocon.flocondesktop.app.ui.model.RecordVideoStateUiModel +import io.github.openflocon.library.designsystem.FloconTheme @Composable internal fun TopBarActions( @@ -26,7 +27,7 @@ internal fun TopBarActions( Row( modifier = modifier, verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp) + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.extraSmall) ) { TopBarButton( active = false, diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/app/TopBarAppView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/app/TopBarAppView.kt index 6c9f5eb22..0dc599573 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/app/TopBarAppView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/app/TopBarAppView.kt @@ -46,8 +46,8 @@ internal fun TopBarAppView( deleteClick: (() -> Unit)? = null, ) { Row( - modifier = modifier.padding(horizontal = 8.dp, vertical = 4.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), + modifier = modifier.padding(horizontal = FloconTheme.spacing.small, vertical = FloconTheme.spacing.extraSmall), + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), verticalAlignment = Alignment.CenterVertically, ) { AppImage( diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/device/TopBarDeviceView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/device/TopBarDeviceView.kt index 0af13fe71..c1aff68c6 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/device/TopBarDeviceView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/ui/view/topbar/device/TopBarDeviceView.kt @@ -51,8 +51,8 @@ internal fun TopBarDeviceView( deleteClick: (() -> Unit)? = null, ) { Row( - modifier = modifier.padding(horizontal = 8.dp, vertical = 4.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), + modifier = modifier.padding(horizontal = FloconTheme.spacing.small, vertical = FloconTheme.spacing.extraSmall), + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), verticalAlignment = Alignment.CenterVertically, ) { Box( diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/DatabaseScreen.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/DatabaseScreen.kt index 4fb5cadc1..a502d248f 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/DatabaseScreen.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/DatabaseScreen.kt @@ -21,6 +21,7 @@ import io.github.openflocon.flocondesktop.features.database.model.DatabaseScreen import io.github.openflocon.flocondesktop.features.database.model.DatabaseTabState import io.github.openflocon.flocondesktop.features.database.model.DatabasesStateUiModel import io.github.openflocon.flocondesktop.features.database.view.databases_tables.DatabasesAndTablesView +import io.github.openflocon.library.designsystem.FloconTheme import io.github.openflocon.library.designsystem.components.FloconFeature import org.koin.compose.viewmodel.koinViewModel @@ -70,11 +71,11 @@ fun DatabaseScreen( favorites = favorites, onAction = onAction ) - Spacer(modifier = Modifier.width(12.dp)) + Spacer(modifier = Modifier.width(FloconTheme.spacing.medium)) Column(modifier = Modifier.fillMaxWidth()) { DatabaseTabsView( - modifier = Modifier.fillMaxWidth().padding(horizontal = 12.dp), + modifier = Modifier.fillMaxWidth().padding(horizontal = FloconTheme.spacing.medium), tabs = tabs, selected = selectedTab, onAction = { diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/DatabaseItemView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/DatabaseItemView.kt index e835b9b0b..270602c02 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/DatabaseItemView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/DatabaseItemView.kt @@ -113,7 +113,7 @@ private fun DatabaseView( }, onDoubleClick = { onDatabaseDoubleClicked(state) } - ).padding(horizontal = 12.dp, vertical = 8.dp), + ).padding(horizontal = FloconTheme.spacing.medium, vertical = FloconTheme.spacing.small), verticalAlignment = Alignment.CenterVertically, ) { Image( @@ -122,7 +122,7 @@ private fun DatabaseView( contentDescription = null, colorFilter = ColorFilter.tint(textColor), ) - Spacer(modifier = Modifier.width(4.dp)) + Spacer(modifier = Modifier.width(FloconTheme.spacing.extraSmall)) Text( state.name, color = textColor, diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/DatabasesAndTablesView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/DatabasesAndTablesView.kt index dbbda17a4..13d9a7a6b 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/DatabasesAndTablesView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/DatabasesAndTablesView.kt @@ -51,8 +51,8 @@ fun DatabasesAndTablesView( Modifier.fillMaxWidth() .weight(1f) .verticalScroll(rememberScrollState()) - .padding(all = 4.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) + .padding(all = FloconTheme.spacing.extraSmall), + verticalArrangement = Arrangement.spacedBy(FloconTheme.spacing.extraSmall) ) { Text( "Databases", @@ -62,7 +62,7 @@ fun DatabasesAndTablesView( ), maxLines = 1, overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp) + modifier = Modifier.padding(horizontal = FloconTheme.spacing.medium, vertical = FloconTheme.spacing.small) ) when (state) { DatabasesStateUiModel.Empty -> Unit @@ -104,8 +104,8 @@ fun DatabasesAndTablesView( Modifier.fillMaxWidth() .weight(0.4f) .verticalScroll(rememberScrollState()) - .padding(all = 4.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) + .padding(all = FloconTheme.spacing.extraSmall), + verticalArrangement = Arrangement.spacedBy(FloconTheme.spacing.extraSmall) ) { Text( stringResource(Res.string.databases_favorites), @@ -115,7 +115,7 @@ fun DatabasesAndTablesView( ), maxLines = 1, overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp) + modifier = Modifier.padding(horizontal = FloconTheme.spacing.medium, vertical = FloconTheme.spacing.small) ) favorites.forEach { diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/TableItemView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/TableItemView.kt index f4fa41006..b7f65b910 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/TableItemView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/database/view/databases_tables/TableItemView.kt @@ -99,10 +99,10 @@ private fun TableView( onTableDoubleClicked(item) } ) - .padding(horizontal = 12.dp) - .padding(vertical = 4.dp), + .padding(horizontal = FloconTheme.spacing.medium) + .padding(vertical = FloconTheme.spacing.extraSmall), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp), + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.extraSmall), ) { val color = FloconTheme.colorPalette.onSurface Image( diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/MockNetworkLabelView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/MockNetworkLabelView.kt index 90aafc693..5ec8bbc32 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/MockNetworkLabelView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/MockNetworkLabelView.kt @@ -12,7 +12,7 @@ import io.github.openflocon.library.designsystem.FloconTheme internal fun MockNetworkLabelView(label: String) { Text( label, - modifier = Modifier.padding(start = 4.dp), + modifier = Modifier.padding(start = FloconTheme.spacing.extraSmall), color = FloconTheme.colorPalette.onSurface, style = FloconTheme.typography.bodyMedium.copy( fontWeight = FontWeight.Thin, diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/MockNetworkMethodDropdown.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/MockNetworkMethodDropdown.kt index c51909a30..4b9b1cea5 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/MockNetworkMethodDropdown.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/MockNetworkMethodDropdown.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import io.github.openflocon.flocondesktop.features.network.mock.edition.model.MockNetworkMethodUi +import io.github.openflocon.library.designsystem.FloconTheme import io.github.openflocon.library.designsystem.components.FloconDropdownMenu @Composable @@ -23,7 +24,7 @@ fun MockNetworkMethodDropdown( ) { var expanded by remember { mutableStateOf(false) } - Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(4.dp)) { + Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(FloconTheme.spacing.extraSmall)) { MockNetworkLabelView(label) Box { @@ -39,7 +40,7 @@ fun MockNetworkMethodDropdown( ) { MockNetworkMethodUi.entries.forEach { method -> MockNetworkMethodView( - modifier = Modifier.padding(all = 4.dp), + modifier = Modifier.padding(all = FloconTheme.spacing.extraSmall), method = method, onClick = { onValueChange(method) diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/NetworkEditionWindow.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/NetworkEditionWindow.kt index ef01e24f6..887c5413f 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/NetworkEditionWindow.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/edition/view/NetworkEditionWindow.kt @@ -117,7 +117,7 @@ fun MockEditorScreen( Column( modifier = Modifier.fillMaxSize(), - verticalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), ) { FloconDialogHeader( modifier = Modifier @@ -127,7 +127,7 @@ fun MockEditorScreen( error?.let { Text( - modifier = Modifier.padding(horizontal = 16.dp), + modifier = Modifier.padding(horizontal = FloconTheme.spacing.large), text = it, color = MaterialTheme.colorScheme.error, ) } @@ -140,8 +140,8 @@ fun MockEditorScreen( Column( modifier = Modifier .weight(2f) - .padding(horizontal = 16.dp, vertical = 8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), + .padding(horizontal = FloconTheme.spacing.large, vertical = FloconTheme.spacing.small), + verticalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), ) { // Section Expectation Text( @@ -182,8 +182,8 @@ fun MockEditorScreen( Column( modifier = Modifier .weight(3f) - .padding(horizontal = 16.dp, vertical = 8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), + .padding(horizontal = FloconTheme.spacing.large, vertical = FloconTheme.spacing.small), + verticalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), ) { // Section Response Text( @@ -287,7 +287,7 @@ fun MockEditorScreen( FlowRow( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(8.dp), + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), ) { NetworkMockMediaType( text = "application/json", @@ -424,7 +424,7 @@ fun MockEditorScreen( color = FloconTheme.colorPalette.primary, shape = FloconTheme.shapes.medium, ) - .padding(vertical = 4.dp, horizontal = 8.dp), + .padding(vertical = FloconTheme.spacing.extraSmall, horizontal = FloconTheme.spacing.small), ) { val throwable = jsonError if(throwable == null) { @@ -447,8 +447,8 @@ fun MockEditorScreen( } } Row( - modifier = Modifier.fillMaxWidth().padding(all = 8.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.fillMaxWidth().padding(all = FloconTheme.spacing.small), + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), verticalAlignment = Alignment.CenterVertically ) { FloconCheckbox( @@ -489,7 +489,7 @@ fun NetworkMockMediaType(text: String, onClicked: (text: String) -> Unit) { .clickable { onClicked(text) } - .padding(horizontal = 12.dp, vertical = 2.dp), + .padding(horizontal = FloconTheme.spacing.medium, vertical = 2.dp), ) } @@ -504,7 +504,7 @@ private fun HeaderInputField( Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp), + horizontalArrangement = Arrangement.spacedBy(FloconTheme.spacing.small), ) { FloconTextField( value = key, @@ -527,7 +527,7 @@ private fun HeaderInputField( .clip(RoundedCornerShape(2.dp)) .clickable { onRemove() - }.padding(all = 4.dp), + }.padding(all = FloconTheme.spacing.extraSmall), contentAlignment = Alignment.Center, ) { Image( diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/list/view/MockLineView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/list/view/MockLineView.kt index da97c77c5..137c53ba3 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/list/view/MockLineView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/mock/list/view/MockLineView.kt @@ -40,12 +40,12 @@ fun MockLineView( Row( modifier = modifier .clickable { onClicked(item.id) } - .padding(vertical = 8.dp), + .padding(vertical = FloconTheme.spacing.small), verticalAlignment = Alignment.CenterVertically, ) { Box( modifier = Modifier - .padding(horizontal = 8.dp) + .padding(horizontal = FloconTheme.spacing.small) .width(50.dp) .height(12.dp), contentAlignment = Alignment.Center, @@ -83,7 +83,7 @@ fun MockLineView( style = FloconTheme.typography.titleSmall, color = FloconTheme.colorPalette.onSurface, ) - Spacer(Modifier.height(8.dp)) + Spacer(Modifier.height(FloconTheme.spacing.small)) Text( text = item.urlPattern, maxLines = 1, @@ -96,7 +96,7 @@ fun MockLineView( Row( modifier = Modifier - .padding(horizontal = 8.dp) + .padding(horizontal = FloconTheme.spacing.small) .height(12.dp) ) { FloconCheckbox( diff --git a/FloconDesktop/library/designsystem/src/commonMain/kotlin/io/github/openflocon/library/designsystem/FloconTheme.kt b/FloconDesktop/library/designsystem/src/commonMain/kotlin/io/github/openflocon/library/designsystem/FloconTheme.kt index c61554029..0ce18208b 100644 --- a/FloconDesktop/library/designsystem/src/commonMain/kotlin/io/github/openflocon/library/designsystem/FloconTheme.kt +++ b/FloconDesktop/library/designsystem/src/commonMain/kotlin/io/github/openflocon/library/designsystem/FloconTheme.kt @@ -23,8 +23,10 @@ import androidx.compose.ui.unit.sp import io.github.openflocon.library.designsystem.components.FloconMenuRepresentation import io.github.openflocon.library.designsystem.theme.FloconColorPaletteNew import io.github.openflocon.library.designsystem.theme.FloconShape +import io.github.openflocon.library.designsystem.theme.FloconSpacing import io.github.openflocon.library.designsystem.theme.LocalFloconColorPalette import io.github.openflocon.library.designsystem.theme.LocalFloconShape +import io.github.openflocon.library.designsystem.theme.LocalFloconSpacing import io.github.openflocon.library.designsystem.theme.darkPalette import io.github.openflocon.library.designsystem.theme.lightPalette import io.github.openflocon.library.designsystem.theme.materialDarkScheme @@ -44,6 +46,10 @@ object FloconTheme { val shapes: FloconShape @Composable @ReadOnlyComposable get() = LocalFloconShape.current + + val spacing: FloconSpacing + @Composable @ReadOnlyComposable + get() = LocalFloconSpacing.current } @Composable @@ -92,6 +98,7 @@ fun FloconTheme( CompositionLocalProvider( LocalIndication provides ripple, LocalFloconColorPalette provides colorPalette, + LocalFloconSpacing provides FloconSpacing(), LocalTextSelectionColors provides selectionTextColor, LocalScrollbarStyle provides scrollbarStyle, LocalMinimumInteractiveComponentSize provides Dp.Unspecified, diff --git a/FloconDesktop/library/designsystem/src/commonMain/kotlin/io/github/openflocon/library/designsystem/theme/FloconSpacing.kt b/FloconDesktop/library/designsystem/src/commonMain/kotlin/io/github/openflocon/library/designsystem/theme/FloconSpacing.kt new file mode 100644 index 000000000..12cc58455 --- /dev/null +++ b/FloconDesktop/library/designsystem/src/commonMain/kotlin/io/github/openflocon/library/designsystem/theme/FloconSpacing.kt @@ -0,0 +1,21 @@ +package io.github.openflocon.library.designsystem.theme + +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +@Immutable +data class FloconSpacing( + val none: Dp = 0.dp, + val extraSmall: Dp = 4.dp, + val small: Dp = 8.dp, + val medium: Dp = 12.dp, + val large: Dp = 16.dp, + val extraLarge: Dp = 24.dp, + val doubleExtraLarge: Dp = 32.dp, + val tripleExtraLarge: Dp = 48.dp, + val huge: Dp = 64.dp +) + +val LocalFloconSpacing = staticCompositionLocalOf { FloconSpacing() }