mirror of
https://github.com/openflocon/Flocon.git
synced 2026-06-24 00:49:11 +00:00
Feat no op (#81)
* feat: [ANDROID] no op lib * feat: [ANDROID] no op lib * renamed modules * renamed modules * renamed modules * renamed modules * updated publish yml --------- Co-authored-by: Florent Champigny <florent@bere.al>
This commit is contained in:
parent
92fc478b12
commit
ed07d7e674
106 changed files with 558 additions and 218 deletions
2
.github/workflows/publish_android.yml
vendored
2
.github/workflows/publish_android.yml
vendored
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
- name: Publish to MavenCentral
|
||||
run: ./gradlew :core:publishToMavenCentral :okhttp-interceptor:publishToMavenCentral :grpc-interceptor:publishToMavenCentral --no-configuration-cache
|
||||
run: ./gradlew :flocon-base:publishToMavenCentral :flocon:publishToMavenCentral :flocon-no-op:publishToMavenCentral :okhttp-interceptor:publishToMavenCentral :grpc-interceptor:publishToMavenCentral --no-configuration-cache
|
||||
working-directory: FloconAndroid
|
||||
env:
|
||||
PROJECT_VERSION_NAME: ${{ github.ref_name }}
|
||||
|
|
|
|||
4
FloconAndroid/.idea/gradle.xml
generated
4
FloconAndroid/.idea/gradle.xml
generated
|
|
@ -11,7 +11,9 @@
|
|||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/core" />
|
||||
<option value="$PROJECT_DIR$/flocon" />
|
||||
<option value="$PROJECT_DIR$/flocon-base" />
|
||||
<option value="$PROJECT_DIR$/flocon-no-op" />
|
||||
<option value="$PROJECT_DIR$/grpc-interceptor" />
|
||||
<option value="$PROJECT_DIR$/okhttp-interceptor" />
|
||||
</set>
|
||||
|
|
|
|||
|
|
@ -46,12 +46,14 @@ android {
|
|||
val useMaven = false
|
||||
dependencies {
|
||||
if(useMaven) {
|
||||
val floconVersion = "1.0.3"
|
||||
val floconVersion = "1.0.5"
|
||||
implementation("io.github.openflocon:flocon:$floconVersion")
|
||||
//implementation("io.github.openflocon:flocon-no-op:$floconVersion")
|
||||
implementation("io.github.openflocon:flocon-grpc-interceptor:$floconVersion")
|
||||
implementation("io.github.openflocon:flocon-okhttp-interceptor:$floconVersion")
|
||||
} else {
|
||||
implementation(project(":core"))
|
||||
//implementation(project(":flocon"))
|
||||
implementation(project(":flocon-no-op"))
|
||||
implementation(project(":okhttp-interceptor"))
|
||||
implementation(project(":grpc-interceptor"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@ 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.deeplinks.deeplinks
|
||||
import io.github.openflocon.flocon.plugins.deeplinks.model.Deeplink
|
||||
import io.github.openflocon.flocon.plugins.tables.model.toParam
|
||||
import io.github.openflocon.flocon.plugins.tables.table
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
package io.github.openflocon.flocon.model
|
||||
|
||||
import io.github.openflocon.flocon.FloconLogger
|
||||
import org.json.JSONObject
|
||||
|
||||
data class FloconMessageFromServer(
|
||||
val plugin: String,
|
||||
val method: String,
|
||||
val body: String,
|
||||
) {
|
||||
companion object {
|
||||
fun fromJson(
|
||||
message: String,
|
||||
): FloconMessageFromServer? {
|
||||
return try {
|
||||
val jsonObject = JSONObject(message)
|
||||
|
||||
FloconMessageFromServer(
|
||||
plugin = jsonObject.getString("plugin"),
|
||||
method = jsonObject.getString("method"),
|
||||
body = jsonObject.getString("body"),
|
||||
)
|
||||
} catch (t: Throwable) {
|
||||
FloconLogger.logError("parsing issue", t)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
82
FloconAndroid/flocon-base/build.gradle.kts
Normal file
82
FloconAndroid/flocon-base/build.gradle.kts
Normal file
|
|
@ -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.base"
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 24
|
||||
|
||||
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(platform(libs.kotlinx.coroutines.bom))
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.kotlinx.coroutines.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-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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package io.github.openflocon.flocon
|
||||
|
||||
import android.content.Context
|
||||
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.network.FloconNetworkPlugin
|
||||
import io.github.openflocon.flocon.plugins.tables.FloconTablePlugin
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
abstract class FloconApp {
|
||||
|
||||
companion object {
|
||||
var instance: FloconApp? = null
|
||||
private set
|
||||
}
|
||||
|
||||
interface Client : FloconMessageSender {
|
||||
|
||||
@Throws(Throwable::class)
|
||||
suspend fun connect(onClosed: () -> Unit)
|
||||
fun disconnect()
|
||||
|
||||
val dashboardPlugin: FloconDashboardPlugin
|
||||
val tablePlugin: FloconTablePlugin
|
||||
val deeplinksPlugin: FloconDeeplinksPlugin
|
||||
val analyticsPlugin: FloconAnalyticsPlugin
|
||||
val networkPlugin: FloconNetworkPlugin
|
||||
}
|
||||
|
||||
open val client: FloconApp.Client? = null
|
||||
|
||||
abstract val isInitialized : StateFlow<Boolean>
|
||||
|
||||
open fun initialize(context: Context) {
|
||||
instance = this
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package io.github.openflocon.flocon.model
|
||||
|
||||
data class FloconMessageFromServer(
|
||||
val plugin: String,
|
||||
val method: String,
|
||||
val body: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package io.github.openflocon.flocon.plugins.analytics
|
||||
|
||||
import io.github.openflocon.flocon.FloconApp
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
import io.github.openflocon.flocon.plugins.analytics.builder.AnalyticsBuilder
|
||||
import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem
|
||||
|
||||
fun FloconApp.analytics(analyticsName: String): AnalyticsBuilder {
|
||||
return AnalyticsBuilder(
|
||||
analyticsTableId = analyticsName,
|
||||
analyticsPlugin = this.client?.analyticsPlugin,
|
||||
)
|
||||
}
|
||||
|
||||
interface FloconAnalyticsPlugin : FloconPlugin {
|
||||
fun registerAnalytics(analyticsItems: List<AnalyticsItem>)
|
||||
}
|
||||
|
|
@ -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<AnalyticsPropertiesConfig>,
|
||||
)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package io.github.openflocon.flocon.plugins.dashboard
|
||||
|
||||
import io.github.openflocon.flocon.FloconApp
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
import io.github.openflocon.flocon.plugins.dashboard.dsl.DashboardBuilder
|
||||
import io.github.openflocon.flocon.plugins.dashboard.dsl.dashboardConfig
|
||||
import io.github.openflocon.flocon.plugins.dashboard.model.DashboardConfig
|
||||
|
||||
|
||||
fun FloconApp.dashboard(id: String, block: DashboardBuilder.() -> Unit) {
|
||||
this.client?.dashboardPlugin?.let {
|
||||
// on no op, this callback is never called
|
||||
val dashboardConfig = dashboardConfig(id = id, block)
|
||||
it.registerDashboard(dashboardConfig)
|
||||
}
|
||||
}
|
||||
|
||||
interface FloconDashboardPlugin : FloconPlugin {
|
||||
fun registerDashboard(dashboardConfig: DashboardConfig)
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package io.github.openflocon.flocon.plugins.database
|
||||
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
|
||||
|
||||
interface FloconDatabasePlugin : FloconPlugin
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package io.github.openflocon.flocon.plugins.deeplinks
|
||||
|
||||
import io.github.openflocon.flocon.FloconApp
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
import io.github.openflocon.flocon.plugins.deeplinks.model.Deeplink
|
||||
|
||||
fun FloconApp.deeplinks(deeplinks: List<Deeplink>) {
|
||||
this.client?.deeplinksPlugin?.registerDeeplinks(deeplinks)
|
||||
}
|
||||
|
||||
interface FloconDeeplinksPlugin : FloconPlugin {
|
||||
fun registerDeeplinks(deeplinks: List<Deeplink>)
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package io.github.openflocon.flocon.plugins.files
|
||||
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
|
||||
interface FloconFilesPlugin : FloconPlugin
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package io.github.openflocon.flocon.plugins.network
|
||||
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest
|
||||
|
||||
interface FloconNetworkPlugin : FloconPlugin {
|
||||
fun log(call: FloconNetworkRequest)
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package io.github.openflocon.flocon.plugins.network.model
|
||||
|
||||
data class FloconNetworkRequest(
|
||||
val request: Request,
|
||||
val response: Response,
|
||||
val durationMs: Double,
|
||||
val floconNetworkType: String,
|
||||
) {
|
||||
data class Request(
|
||||
val url: String,
|
||||
val method: String,
|
||||
val startTime: Long,
|
||||
val headers: Map<String, String>,
|
||||
val body: String?,
|
||||
val size: Long?,
|
||||
)
|
||||
|
||||
data class Response(
|
||||
val httpCode: Int?,
|
||||
val grpcStatus: String?,
|
||||
val contentType: String?,
|
||||
val body: String?,
|
||||
val size: Long?,
|
||||
val headers: Map<String, String>,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package io.github.openflocon.flocon.plugins.SharedPreferences
|
||||
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
|
||||
interface FloconSharedPreferencesPlugin : FloconPlugin
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package io.github.openflocon.flocon.plugins.tables
|
||||
|
||||
import io.github.openflocon.flocon.FloconApp
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
import io.github.openflocon.flocon.plugins.tables.builder.TableBuilder
|
||||
import io.github.openflocon.flocon.plugins.tables.model.TableItem
|
||||
|
||||
fun FloconApp.table(tableName: String): TableBuilder {
|
||||
return TableBuilder(
|
||||
tableName = tableName,
|
||||
tablePlugin = this.client?.tablePlugin,
|
||||
)
|
||||
}
|
||||
|
||||
interface FloconTablePlugin : FloconPlugin {
|
||||
fun registerTable(tableItem: TableItem)
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package io.github.openflocon.flocon.plugins.tables.model
|
||||
|
||||
data class TableItem(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val createdAt: Long,
|
||||
val columns: List<TableColumnConfig>,
|
||||
)
|
||||
1
FloconAndroid/flocon-no-op/.gitignore
vendored
Normal file
1
FloconAndroid/flocon-no-op/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
84
FloconAndroid/flocon-no-op/build.gradle.kts
Normal file
84
FloconAndroid/flocon-no-op/build.gradle.kts
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
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"
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 24
|
||||
|
||||
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(platform(libs.kotlinx.coroutines.bom))
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.kotlinx.coroutines.android)
|
||||
|
||||
api(project(":flocon-base"))
|
||||
}
|
||||
|
||||
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-no-op",
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
0
FloconAndroid/flocon-no-op/consumer-rules.pro
Normal file
0
FloconAndroid/flocon-no-op/consumer-rules.pro
Normal file
21
FloconAndroid/flocon-no-op/proguard-rules.pro
vendored
Normal file
21
FloconAndroid/flocon-no-op/proguard-rules.pro
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# 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
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package io.github.openflocon.flocon
|
||||
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
object Flocon : FloconApp() {
|
||||
override val isInitialized = MutableStateFlow(false)
|
||||
}
|
||||
1
FloconAndroid/flocon/.gitignore
vendored
Normal file
1
FloconAndroid/flocon/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
|
|
@ -40,6 +40,7 @@ dependencies {
|
|||
|
||||
implementation(platform(libs.okhttp.bom))
|
||||
implementation(libs.okhttp)
|
||||
api(project(":flocon-base"))
|
||||
}
|
||||
|
||||
mavenPublishing {
|
||||
0
FloconAndroid/flocon/consumer-rules.pro
Normal file
0
FloconAndroid/flocon/consumer-rules.pro
Normal file
21
FloconAndroid/flocon/proguard-rules.pro
vendored
Normal file
21
FloconAndroid/flocon/proguard-rules.pro
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# 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
|
||||
|
|
@ -11,35 +11,34 @@ 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
|
||||
|
||||
object Flocon {
|
||||
object Flocon : FloconApp() {
|
||||
|
||||
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
|
||||
interface Client : FloconMessageSender {
|
||||
private var _client: FloconApp.Client? = null
|
||||
|
||||
@Throws(Throwable::class)
|
||||
suspend fun connect(onClosed: () -> Unit)
|
||||
fun disconnect()
|
||||
override val client: FloconApp.Client?
|
||||
get() {
|
||||
return _client
|
||||
}
|
||||
|
||||
val dashboardPlugin: FloconDashboardPlugin
|
||||
val tablePlugin: FloconTablePlugin
|
||||
val deeplinksPlugin: FloconDeeplinksPlugin
|
||||
val analyticsPlugin: FloconAnalyticsPlugin
|
||||
}
|
||||
override val isInitialized = MutableStateFlow(false)
|
||||
|
||||
var client: Flocon.Client? = null
|
||||
private set
|
||||
|
||||
fun initialize(context: Context) {
|
||||
override fun initialize(context: Context) {
|
||||
val app = context.applicationContext
|
||||
val newClient = FloconClientImpl(app)
|
||||
client = newClient
|
||||
_client = newClient
|
||||
isInitialized.value = true
|
||||
|
||||
scope.launch {
|
||||
start(newClient)
|
||||
}
|
||||
|
||||
super.initialize(context)
|
||||
}
|
||||
|
||||
private suspend fun start(client: FloconClientImpl) {
|
||||
|
|
@ -3,10 +3,11 @@ package io.github.openflocon.flocon.client
|
|||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import io.github.openflocon.flocon.Flocon
|
||||
import io.github.openflocon.flocon.FloconApp
|
||||
import io.github.openflocon.flocon.Protocol
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
import io.github.openflocon.flocon.model.FloconMessageFromServer
|
||||
import io.github.openflocon.flocon.model.floconMessageFromServerFromJson
|
||||
import io.github.openflocon.flocon.model.toFloconMessageToServer
|
||||
import io.github.openflocon.flocon.plugins.SharedPreferences.FloconSharedPreferencesPluginImpl
|
||||
import io.github.openflocon.flocon.plugins.analytics.FloconAnalyticsPluginImpl
|
||||
|
|
@ -14,6 +15,7 @@ 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.files.FloconFilesPluginImpl
|
||||
import io.github.openflocon.flocon.plugins.network.FloconNetworkPluginImpl
|
||||
import io.github.openflocon.flocon.plugins.tables.FloconTablePluginImpl
|
||||
import io.github.openflocon.flocon.utils.AppUtils
|
||||
import io.github.openflocon.flocon.utils.NetUtils
|
||||
|
|
@ -26,7 +28,7 @@ import kotlinx.coroutines.launch
|
|||
|
||||
internal class FloconClientImpl(
|
||||
appContext: Context,
|
||||
) : Flocon.Client {
|
||||
) : FloconApp.Client {
|
||||
|
||||
private val FLOCON_PORT = 9023
|
||||
|
||||
|
|
@ -47,6 +49,7 @@ internal class FloconClientImpl(
|
|||
override val tablePlugin = FloconTablePluginImpl(sender = this)
|
||||
override val deeplinksPlugin = FloconDeeplinksPluginImpl(sender = this)
|
||||
override val analyticsPlugin = FloconAnalyticsPluginImpl(sender = this)
|
||||
override val networkPlugin = FloconNetworkPluginImpl(sender = this)
|
||||
|
||||
private val allPlugins = listOf<FloconPlugin>(
|
||||
databasePlugin,
|
||||
|
|
@ -56,6 +59,7 @@ internal class FloconClientImpl(
|
|||
tablePlugin,
|
||||
deeplinksPlugin,
|
||||
analyticsPlugin,
|
||||
networkPlugin,
|
||||
)
|
||||
|
||||
@Throws(Throwable::class)
|
||||
|
|
@ -79,7 +83,7 @@ internal class FloconClientImpl(
|
|||
|
||||
private fun onMessageReceived(message: String) {
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
FloconMessageFromServer.fromJson(message)?.let { messageFromServer ->
|
||||
floconMessageFromServerFromJson(message)?.let { messageFromServer ->
|
||||
when (messageFromServer.plugin) {
|
||||
Protocol.ToDevice.Database.Plugin -> {
|
||||
databasePlugin.onMessageReceived(
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package io.github.openflocon.flocon.model
|
||||
|
||||
import io.github.openflocon.flocon.FloconLogger
|
||||
import org.json.JSONObject
|
||||
|
||||
fun floconMessageFromServerFromJson(
|
||||
message: String,
|
||||
): FloconMessageFromServer? {
|
||||
return try {
|
||||
val jsonObject = JSONObject(message)
|
||||
|
||||
FloconMessageFromServer(
|
||||
plugin = jsonObject.getString("plugin"),
|
||||
method = jsonObject.getString("method"),
|
||||
body = jsonObject.getString("body"),
|
||||
)
|
||||
} catch (t: Throwable) {
|
||||
FloconLogger.logError("parsing issue", t)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +1,13 @@
|
|||
package io.github.openflocon.flocon.plugins.analytics
|
||||
|
||||
import io.github.openflocon.flocon.Flocon
|
||||
import io.github.openflocon.flocon.Protocol
|
||||
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.builder.AnalyticsBuilder
|
||||
import io.github.openflocon.flocon.plugins.analytics.model.AnalyticsItem
|
||||
import io.github.openflocon.flocon.plugins.analytics.model.analyticsItemsToJson
|
||||
import org.json.JSONArray
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
|
||||
fun Flocon.analytics(analyticsName: String): AnalyticsBuilder {
|
||||
return AnalyticsBuilder(
|
||||
analyticsTableId = analyticsName,
|
||||
analyticsPlugin = this.client?.analyticsPlugin,
|
||||
)
|
||||
}
|
||||
|
||||
interface FloconAnalyticsPlugin : FloconPlugin {
|
||||
fun registerAnalytics(analyticsItems: List<AnalyticsItem>)
|
||||
}
|
||||
|
||||
class FloconAnalyticsPluginImpl(
|
||||
private val sender: FloconMessageSender,
|
||||
) : FloconAnalyticsPlugin {
|
||||
|
|
@ -31,17 +18,17 @@ class FloconAnalyticsPluginImpl(
|
|||
messageFromServer: FloconMessageFromServer,
|
||||
sender: FloconMessageSender,
|
||||
) {
|
||||
when(messageFromServer.method) {
|
||||
Protocol.ToDevice.Analytics.Method.ClearItems-> {
|
||||
when (messageFromServer.method) {
|
||||
Protocol.ToDevice.Analytics.Method.ClearItems -> {
|
||||
val items = readIds(messageFromServer.body)
|
||||
if(items.isNotEmpty()) {
|
||||
if (items.isNotEmpty()) {
|
||||
clearItems(items.toSet())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun readIds(body: String) : List<String> {
|
||||
private fun readIds(body: String): List<String> {
|
||||
return try {
|
||||
val array = JSONArray(body)
|
||||
val items = mutableListOf<String>()
|
||||
|
|
@ -69,7 +56,7 @@ class FloconAnalyticsPluginImpl(
|
|||
sender.send(
|
||||
plugin = Protocol.FromDevice.Analytics.Plugin,
|
||||
method = Protocol.FromDevice.Analytics.Method.AddItems,
|
||||
body = AnalyticsItem.listToJson(toSend).toString()
|
||||
body = analyticsItemsToJson(toSend).toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,24 +3,14 @@ package io.github.openflocon.flocon.plugins.analytics.model
|
|||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
data class AnalyticsItem(
|
||||
val id: String,
|
||||
val analyticsTableId: String,
|
||||
val eventName: String,
|
||||
val createdAt: Long,
|
||||
val properties: List<AnalyticsPropertiesConfig>,
|
||||
) {
|
||||
companion object {
|
||||
fun listToJson(items: Collection<AnalyticsItem>) : JSONArray {
|
||||
val array = JSONArray()
|
||||
fun analyticsItemsToJson(items: Collection<AnalyticsItem>) : JSONArray {
|
||||
val array = JSONArray()
|
||||
|
||||
items.forEach {
|
||||
array.put(it.toJson())
|
||||
}
|
||||
|
||||
return array
|
||||
}
|
||||
items.forEach {
|
||||
array.put(it.toJson())
|
||||
}
|
||||
|
||||
return array
|
||||
}
|
||||
|
||||
private fun AnalyticsItem.toJson() : JSONObject {
|
||||
|
|
@ -1,12 +1,8 @@
|
|||
package io.github.openflocon.flocon.plugins.dashboard
|
||||
|
||||
import io.github.openflocon.flocon.Flocon
|
||||
import io.github.openflocon.flocon.Protocol
|
||||
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.dsl.DashboardBuilder
|
||||
import io.github.openflocon.flocon.plugins.dashboard.dsl.dashboardConfig
|
||||
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
|
||||
|
|
@ -14,16 +10,6 @@ import io.github.openflocon.flocon.plugins.dashboard.model.todevice.ToDeviceChec
|
|||
import io.github.openflocon.flocon.plugins.dashboard.model.todevice.ToDeviceSubmittedTextFieldMessage
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
|
||||
fun Flocon.dashboard(id: String, block: DashboardBuilder.() -> Unit) {
|
||||
val dashboardConfig = dashboardConfig(id = id, block)
|
||||
this.client?.dashboardPlugin?.registerDashboard(dashboardConfig)
|
||||
}
|
||||
|
||||
interface FloconDashboardPlugin : FloconPlugin {
|
||||
fun registerDashboard(dashboardConfig: DashboardConfig)
|
||||
}
|
||||
|
||||
class FloconDashboardPluginImpl(
|
||||
private val sender: FloconMessageSender,
|
||||
) : FloconDashboardPlugin {
|
||||
|
|
@ -41,14 +27,20 @@ class FloconDashboardPluginImpl(
|
|||
|
||||
callbackMap[id]?.let { it as? DashboardCallback.ButtonCallback }?.action?.invoke()
|
||||
}
|
||||
|
||||
Protocol.ToDevice.Dashboard.Method.OnTextFieldSubmitted -> {
|
||||
ToDeviceSubmittedTextFieldMessage.fromJson(messageFromServer.body)?.let {
|
||||
callbackMap[it.id]?.let { it as? DashboardCallback.TextFieldCallback }?.action?.invoke(it.value)
|
||||
callbackMap[it.id]?.let { it as? DashboardCallback.TextFieldCallback }?.action?.invoke(
|
||||
it.value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Protocol.ToDevice.Dashboard.Method.OnCheckBoxValueChanged -> {
|
||||
ToDeviceCheckBoxValueChangedMessage.fromJson(messageFromServer.body)?.let {
|
||||
callbackMap[it.id]?.let { it as? DashboardCallback.CheckBoxCallback }?.action?.invoke(it.value)
|
||||
callbackMap[it.id]?.let { it as? DashboardCallback.CheckBoxCallback }?.action?.invoke(
|
||||
it.value
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,9 +16,6 @@ import io.github.openflocon.flocon.plugins.database.model.todevice.DatabaseQuery
|
|||
import java.io.File
|
||||
import java.util.Locale
|
||||
|
||||
|
||||
interface FloconDatabasePlugin : FloconPlugin
|
||||
|
||||
class FloconDatabasePluginImpl(
|
||||
private val context: Context,
|
||||
) : FloconDatabasePlugin {
|
||||
|
|
@ -1,23 +1,12 @@
|
|||
package io.github.openflocon.flocon.plugins.deeplinks
|
||||
|
||||
import io.github.openflocon.flocon.Flocon
|
||||
import io.github.openflocon.flocon.Protocol
|
||||
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.Deeplink
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
|
||||
fun Flocon.deeplinks(deeplinks: List<Deeplink>) {
|
||||
this.client?.deeplinksPlugin?.registerDeeplinks(deeplinks)
|
||||
}
|
||||
|
||||
interface FloconDeeplinksPlugin : FloconPlugin {
|
||||
fun registerDeeplinks(deeplinks: List<Deeplink>)
|
||||
}
|
||||
|
||||
class FloconDeeplinksPluginImpl(
|
||||
private val sender: FloconMessageSender,
|
||||
) : FloconDeeplinksPlugin {
|
||||
|
|
@ -13,10 +13,6 @@ import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceDeleteFo
|
|||
import io.github.openflocon.flocon.plugins.files.model.todevice.ToDeviceGetFilesMessage
|
||||
import java.io.File
|
||||
|
||||
|
||||
interface FloconFilesPlugin : FloconPlugin {
|
||||
}
|
||||
|
||||
class FloconFilesPluginImpl(
|
||||
private val context: Context,
|
||||
) : FloconFilesPlugin {
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package io.github.openflocon.flocon.plugins.network
|
||||
|
||||
import io.github.openflocon.flocon.Protocol
|
||||
import io.github.openflocon.flocon.core.FloconMessageSender
|
||||
import io.github.openflocon.flocon.model.FloconMessageFromServer
|
||||
import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest
|
||||
import io.github.openflocon.flocon.plugins.network.model.floconNetworkRequestToJson
|
||||
|
||||
class FloconNetworkPluginImpl(
|
||||
private var sender: FloconMessageSender,
|
||||
) : FloconNetworkPlugin {
|
||||
|
||||
override fun log(call: FloconNetworkRequest) {
|
||||
sender.send(
|
||||
plugin = Protocol.FromDevice.Network.Plugin,
|
||||
method = Protocol.FromDevice.Network.Method.LogNetworkCall,
|
||||
body = floconNetworkRequestToJson(call).toString(),
|
||||
)
|
||||
}
|
||||
|
||||
override fun onMessageReceived(
|
||||
messageFromServer: FloconMessageFromServer,
|
||||
sender: FloconMessageSender
|
||||
) {
|
||||
// no op
|
||||
}
|
||||
|
||||
override fun onConnectedToServer(sender: FloconMessageSender) {
|
||||
// no op
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,33 +2,11 @@ package io.github.openflocon.flocon.plugins.network.model
|
|||
|
||||
import org.json.JSONObject
|
||||
|
||||
data class FloconNetworkRequest(
|
||||
val request: Request,
|
||||
val response: Response,
|
||||
val durationMs: Double,
|
||||
val floconNetworkType: String,
|
||||
) {
|
||||
data class Request(
|
||||
val url: String,
|
||||
val method: String,
|
||||
val startTime: Long,
|
||||
val headers: Map<String, String>,
|
||||
val body: String?,
|
||||
val size: Long?,
|
||||
)
|
||||
|
||||
data class Response(
|
||||
val httpCode: Int?,
|
||||
val grpcStatus: String?,
|
||||
val contentType: String?,
|
||||
val body: String?,
|
||||
val size: Long?,
|
||||
val headers: Map<String, String>,
|
||||
)
|
||||
|
||||
fun toJson(): JSONObject {
|
||||
val json = JSONObject()
|
||||
fun floconNetworkRequestToJson(network: FloconNetworkRequest): JSONObject {
|
||||
val json = JSONObject()
|
||||
|
||||
with(network) {
|
||||
json.put("floconNetworkType", floconNetworkType)
|
||||
|
||||
json.put("url", request.url)
|
||||
|
|
@ -42,11 +20,11 @@ data class FloconNetworkRequest(
|
|||
|
||||
response.httpCode?.let { json.put("responseHttpCode", it) }
|
||||
response.grpcStatus?.let { json.put("responseGrpcStatus", it) }
|
||||
response.contentType?.let { json.put("responseContentType", it) }
|
||||
response.contentType?.let { json.put("responseContentType", it) }
|
||||
response.body?.let { json.put("responseBody", it) }
|
||||
json.put("responseHeaders", JSONObject(response.headers))
|
||||
json.put("responseSize", response.size)
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
return json
|
||||
}
|
||||
|
|
@ -19,9 +19,6 @@ import io.github.openflocon.flocon.plugins.sharedprefs.model.todevice.ToDeviceGe
|
|||
// Got some code from Flipper client
|
||||
// https://github.com/facebook/flipper/blob/main/android/src/main/java/com/facebook/flipper/plugins/sharedpreferences/SharedPreferencesFlipperPlugin.java
|
||||
|
||||
interface FloconSharedPreferencesPlugin : FloconPlugin {
|
||||
}
|
||||
|
||||
class FloconSharedPreferencesPluginImpl(
|
||||
private val context: Context,
|
||||
) : FloconSharedPreferencesPlugin {
|
||||
|
|
@ -1,27 +1,13 @@
|
|||
package io.github.openflocon.flocon.plugins.tables
|
||||
|
||||
import io.github.openflocon.flocon.Flocon
|
||||
import io.github.openflocon.flocon.Protocol
|
||||
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.builder.TableBuilder
|
||||
import io.github.openflocon.flocon.plugins.tables.model.TableItem
|
||||
import io.github.openflocon.flocon.plugins.tables.model.tableItemListToJson
|
||||
import org.json.JSONArray
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
|
||||
|
||||
fun Flocon.table(tableName: String): TableBuilder {
|
||||
return TableBuilder(
|
||||
tableName = tableName,
|
||||
tablePlugin = this.client?.tablePlugin,
|
||||
)
|
||||
}
|
||||
|
||||
interface FloconTablePlugin : FloconPlugin {
|
||||
fun registerTable(tableItem: TableItem)
|
||||
}
|
||||
|
||||
class FloconTablePluginImpl(
|
||||
private val sender: FloconMessageSender,
|
||||
) : FloconTablePlugin {
|
||||
|
|
@ -32,17 +18,17 @@ class FloconTablePluginImpl(
|
|||
messageFromServer: FloconMessageFromServer,
|
||||
sender: FloconMessageSender,
|
||||
) {
|
||||
when(messageFromServer.method) {
|
||||
Protocol.ToDevice.Table.Method.ClearItems-> {
|
||||
when (messageFromServer.method) {
|
||||
Protocol.ToDevice.Table.Method.ClearItems -> {
|
||||
val items = readIds(messageFromServer.body)
|
||||
if(items.isNotEmpty()) {
|
||||
if (items.isNotEmpty()) {
|
||||
clearItems(items.toSet())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun readIds(body: String) : List<String> {
|
||||
private fun readIds(body: String): List<String> {
|
||||
return try {
|
||||
val array = JSONArray(body)
|
||||
val items = mutableListOf<String>()
|
||||
|
|
@ -70,7 +56,7 @@ class FloconTablePluginImpl(
|
|||
sender.send(
|
||||
plugin = Protocol.FromDevice.Table.Plugin,
|
||||
method = Protocol.FromDevice.Table.Method.AddItems,
|
||||
body = TableItem.listToJson(tableMessages).toString()
|
||||
body = tableItemListToJson(tableMessages).toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,26 +3,17 @@ package io.github.openflocon.flocon.plugins.tables.model
|
|||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
data class TableItem(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val createdAt: Long,
|
||||
val columns: List<TableColumnConfig>,
|
||||
) {
|
||||
companion object {
|
||||
fun listToJson(items: Collection<TableItem>) : JSONArray {
|
||||
val array = JSONArray()
|
||||
fun tableItemListToJson(items: Collection<TableItem>): JSONArray {
|
||||
val array = JSONArray()
|
||||
|
||||
items.forEach {
|
||||
array.put(it.toJson())
|
||||
}
|
||||
|
||||
return array
|
||||
}
|
||||
items.forEach {
|
||||
array.put(it.toJson())
|
||||
}
|
||||
|
||||
return array
|
||||
}
|
||||
|
||||
private fun TableItem.toJson() : JSONObject {
|
||||
private fun TableItem.toJson(): JSONObject {
|
||||
val tableItemJson = JSONObject()
|
||||
|
||||
tableItemJson.put("id", this.id)
|
||||
|
|
@ -35,7 +35,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":core"))
|
||||
implementation(project(":flocon-base"))
|
||||
|
||||
implementation(libs.gson)
|
||||
implementation(libs.grpc.android)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue