diff --git a/FloconAndroid/.idea/gradle.xml b/FloconAndroid/.idea/gradle.xml
index ac540f22..4140775b 100644
--- a/FloconAndroid/.idea/gradle.xml
+++ b/FloconAndroid/.idea/gradle.xml
@@ -12,7 +12,6 @@
-
diff --git a/FloconAndroid/core/src/main/java/io/github/openflocon/flocon/plugins/network/model/FloconHttpRequest.kt b/FloconAndroid/core/src/main/java/io/github/openflocon/flocon/plugins/network/model/FloconHttpRequest.kt
new file mode 100644
index 00000000..6c8d1bd9
--- /dev/null
+++ b/FloconAndroid/core/src/main/java/io/github/openflocon/flocon/plugins/network/model/FloconHttpRequest.kt
@@ -0,0 +1,52 @@
+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,
+ 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,
+ )
+
+ fun toJson(): JSONObject {
+ val json = JSONObject()
+
+ json.put("floconNetworkType", floconNetworkType)
+
+ json.put("url", request.url)
+ json.put("method", request.method)
+ json.put("startTime", request.startTime)
+ json.put("durationMs", durationMs)
+
+ request.body?.let { json.put("requestBody", it) }
+ json.put("requestHeaders", JSONObject(request.headers))
+ json.put("requestSize", request.size)
+
+ response.httpCode?.let { json.put("responseHttpCode", it) }
+ response.grpcStatus?.let { json.put("responseGrpcStatus", 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
+ }
+}
\ No newline at end of file
diff --git a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/FloconGrpcInterceptor.kt b/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/FloconGrpcInterceptor.kt
index 479bb58c..ff3a9d6c 100644
--- a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/FloconGrpcInterceptor.kt
+++ b/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/FloconGrpcInterceptor.kt
@@ -1,12 +1,11 @@
package io.github.openflocon.flocon.grpc
-import io.github.openflocon.flocon.grpc.model.GrpcRequest
-import io.github.openflocon.flocon.grpc.model.GrpcResponse
import io.github.openflocon.flocon.grpc.model.toHeaders
import com.google.gson.ExclusionStrategy
import com.google.gson.FieldAttributes
import com.google.gson.Gson
import com.google.gson.GsonBuilder
+import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest
import io.grpc.CallOptions
import io.grpc.Channel
import io.grpc.ClientCall
@@ -93,14 +92,15 @@ private class LoggingForwardingClientCall(
override fun sendMessage(message: ReqT) {
super.sendMessage(message)
floconGrpcPlugin.reportRequest(
- GrpcRequest(
- id = requestId,
- authority = next.authority(),
+ callId = requestId,
+ request = FloconNetworkRequest.Request(
+ url = next.authority(),
method = method.fullMethodName,
- data = message?.toJson(gson = gson) ?: "",
- unixTimestampMs = System.currentTimeMillis(),
+ body = message?.toJson(gson = gson) ?: "",
+ startTime = System.currentTimeMillis(),
headers = headers?.toHeaders().orEmpty(),
- ),
+ size = 0, // TODO
+ )
)
}
}
@@ -120,13 +120,14 @@ private class LoggingClientCallListener(
override fun onClose(status: Status, trailers: Metadata) {
super.onClose(status, trailers)
floconGrpcPlugin.reportResponse(
- GrpcResponse(
- id = requestId,
- unixTimestampMs = System.currentTimeMillis(),
- status = status.code.toString(),
- cause = status.description,
+ callId = requestId,
+ response = FloconNetworkRequest.Response(
+ body = message?.toJson(gson),
headers = (this.headers ?: trailers).toHeaders(),
- data = message?.toJson(gson),
+ httpCode = null,
+ contentType = "grpc",
+ size = 0L,
+ grpcStatus = status.code.toString(),
),
)
}
diff --git a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt b/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt
index 156ca82f..8c35f636 100644
--- a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt
+++ b/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/FloconGrpcPlugin.kt
@@ -2,26 +2,34 @@ package io.github.openflocon.flocon.grpc
import io.github.openflocon.flocon.Flocon
import io.github.openflocon.flocon.Protocol
-import io.github.openflocon.flocon.grpc.model.GrpcRequest
-import io.github.openflocon.flocon.grpc.model.GrpcResponse
+import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest
+import java.util.concurrent.ConcurrentHashMap
internal class FloconGrpcPlugin(
private val floconClient: Flocon.Client? = null,
) {
- fun reportRequest(request: GrpcRequest) {
- (floconClient ?: Flocon.client)?.send(
- plugin = Protocol.FromDevice.GRPC.Plugin,
- method = Protocol.FromDevice.GRPC.Method.LogNetworkRequest,
- body = request.toJson().toString(),
- )
+ private val requests = ConcurrentHashMap()
+
+ fun reportRequest(callId: String, request: FloconNetworkRequest.Request) {
+ requests[callId] = request
}
- fun reportResponse(response: GrpcResponse) {
- (floconClient ?: Flocon.client)?.send(
- plugin = Protocol.FromDevice.GRPC.Plugin,
- method = Protocol.FromDevice.GRPC.Method.LogNetworkResponse,
- body = response.toJson().toString(),
+ fun reportResponse(callId: String, response: FloconNetworkRequest.Response) {
+ val request = requests[callId] ?: return
+ val responseTime = System.currentTimeMillis()
+ val durationMs = (responseTime - request.startTime).toDouble()
+ val call = FloconNetworkRequest(
+ durationMs = durationMs,
+ request = request,
+ response = response,
+ floconNetworkType = "grpc",
)
+ (floconClient ?: Flocon.client)?.send(
+ plugin = Protocol.FromDevice.Network.Plugin,
+ method = Protocol.FromDevice.Network.Method.LogNetworkCall,
+ body = call.toJson().toString(),
+ )
+ requests.remove(callId)
}
}
diff --git a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcHeader.kt b/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcHeader.kt
index 9a123a8e..6ed4950b 100644
--- a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcHeader.kt
+++ b/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcHeader.kt
@@ -4,37 +4,16 @@ import io.grpc.Metadata
import org.json.JSONArray
import org.json.JSONObject
-internal data class GrpcHeader(
- val key: String,
- val value: String,
-) {
- fun toJson() : JSONObject {
- return JSONObject().apply {
- put("key", key)
- put("value", value)
- }
- }
- companion object Companion {
- fun listOfHeaderToJson(headers: List) : JSONArray {
- return JSONArray().apply {
- headers.forEach {
- put(it.toJson())
- }
- }
- }
- }
-}
-
-internal fun Metadata.toHeaders(): List {
+internal fun Metadata.toHeaders(): Map {
return keys().mapNotNull {
try {
- GrpcHeader(
+ Pair(
it,
get(Metadata.Key.of(it, Metadata.ASCII_STRING_MARSHALLER)).toString(),
)
} catch (e: Exception) {
null
}
- }
+ }.toMap()
}
diff --git a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcRequest.kt b/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcRequest.kt
deleted file mode 100644
index 9e842f6c..00000000
--- a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcRequest.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package io.github.openflocon.flocon.grpc.model
-
-import org.json.JSONObject
-
-internal data class GrpcRequest(
- val id: String,
- val unixTimestampMs: Long,
- val authority: String,
- val method: String,
- val headers: List,
- val data: String,
-) {
- fun toJson(): JSONObject {
- return JSONObject().apply {
- put("id", id)
- put("timestamp", unixTimestampMs)
- put("authority", authority)
- put("method", method)
- put("headers", GrpcHeader.Companion.listOfHeaderToJson(headers))
- put("data", data)
- }
- }
-}
\ No newline at end of file
diff --git a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcResponse.kt b/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcResponse.kt
deleted file mode 100644
index abdde2b8..00000000
--- a/FloconAndroid/grpc-interceptor/src/main/java/io/github/openflocon/flocon/grpc/model/GrpcResponse.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package io.github.openflocon.flocon.grpc.model
-
-import org.json.JSONObject
-
-internal data class GrpcResponse(
- val id: String,
- val unixTimestampMs: Long,
- val status: String,
- val cause: String?,
- val headers: List,
- val data: String?,
-) {
- fun toJson() : JSONObject {
- return JSONObject().apply {
- put("id", id)
- put("timestamp", unixTimestampMs)
- put("status", status)
- put("headers", GrpcHeader.Companion.listOfHeaderToJson(headers))
- put("data", data)
- put("cause", cause)
- }
- }
-}
\ No newline at end of file
diff --git a/FloconAndroid/okhttp-interceptor/src/main/java/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt b/FloconAndroid/okhttp-interceptor/src/main/java/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt
index aa9c754f..f5f5967e 100644
--- a/FloconAndroid/okhttp-interceptor/src/main/java/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt
+++ b/FloconAndroid/okhttp-interceptor/src/main/java/io/github/openflocon/flocon/okhttp/OkHttpInterceptor.kt
@@ -2,7 +2,7 @@ package io.github.openflocon.flocon.okhttp
import io.github.openflocon.flocon.Flocon
import io.github.openflocon.flocon.Protocol
-import io.github.openflocon.flocon.okhttp.model.FloconHttpRequest
+import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest
import okhttp3.Interceptor
import okhttp3.MediaType
import okhttp3.Response
@@ -41,7 +41,7 @@ class FloconOkhttpInterceptor(
val response = chain.proceed(request)
val endTime = System.nanoTime()
- val durationMs = (endTime - startTime) / 1e6
+ val durationMs: Double = (endTime - startTime) / 1e6
// To get the response body, be careful
// because the body can only be read once.
@@ -64,21 +64,25 @@ class FloconOkhttpInterceptor(
val isImage = responseContentType?.toString()?.startsWith("image/") == true
- val floconRequest = FloconHttpRequest(
- url = request.url.toString(),
- method = request.method,
- startTime = requestedAt,
+ val floconRequest = FloconNetworkRequest(
durationMs = durationMs,
-
- requestHeaders = requestHeadersMap,
- requestBody = requestBodyString,
- requestSize = requestSize,
-
- responseHttpCode = response.code,
- responseContentType = responseContentType?.toString(),
- responseBody = responseBodyString.takeUnless { isImage }, // dont send images responses bytes
- responseHeaders = responseHeadersMap,
- responseSize = responseSize,
+ floconNetworkType = "http",
+ request = FloconNetworkRequest.Request(
+ url = request.url.toString(),
+ method = request.method,
+ startTime = requestedAt,
+ headers = requestHeadersMap,
+ body = requestBodyString,
+ size = requestSize,
+ ),
+ response = FloconNetworkRequest.Response(
+ httpCode = response.code,
+ contentType = responseContentType?.toString(),
+ body = responseBodyString.takeUnless { isImage }, // dont send images responses bytes
+ headers = responseHeadersMap,
+ size = responseSize,
+ grpcStatus = null,
+ )
)
val json = floconRequest.toJson()
diff --git a/FloconAndroid/okhttp-interceptor/src/main/java/io/github/openflocon/flocon/okhttp/model/FloconHttpRequest.kt b/FloconAndroid/okhttp-interceptor/src/main/java/io/github/openflocon/flocon/okhttp/model/FloconHttpRequest.kt
deleted file mode 100644
index b3da6e3e..00000000
--- a/FloconAndroid/okhttp-interceptor/src/main/java/io/github/openflocon/flocon/okhttp/model/FloconHttpRequest.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package io.github.openflocon.flocon.okhttp.model
-
-import org.json.JSONObject
-
-data class FloconHttpRequest(
- val url: String,
- val method: String,
- val startTime: Long,
- val durationMs: Double,
- // request
- val requestHeaders: Map,
- val requestBody: String?,
- val requestSize: Long?,
- // response
- val responseHttpCode: Int,
- val responseContentType: String?,
- val responseBody: String?,
- val responseSize: Long?,
- val responseHeaders: Map,
-) {
- fun toJson(): JSONObject {
- val json = JSONObject()
-
- json.put("url", url)
- json.put("method", method)
- json.put("startTime", startTime)
- json.put("durationMs", durationMs)
-
- requestBody?.let { json.put("requestBody", it) }
- json.put("requestHeaders", JSONObject(requestHeaders))
- json.put("requestSize", requestSize)
-
- json.put("responseHttpCode", responseHttpCode)
- responseContentType?.let { json.put("responseContentType", it) }
- responseBody?.let { json.put("responseBody", it) }
- json.put("responseHeaders", JSONObject(responseHeaders))
- json.put("responseSize", responseSize)
-
- return json
- }
-}
\ No newline at end of file
diff --git a/FloconDesktop/composeApp/build.gradle.kts b/FloconDesktop/composeApp/build.gradle.kts
index bda45e39..257803f2 100644
--- a/FloconDesktop/composeApp/build.gradle.kts
+++ b/FloconDesktop/composeApp/build.gradle.kts
@@ -1,4 +1,3 @@
-import com.android.build.gradle.ProguardFiles.getDefaultProguardFile
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/AppDatabase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/AppDatabase.kt
index 1f1e6dea..c6112131 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/AppDatabase.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/AppDatabase.kt
@@ -18,9 +18,6 @@ import io.github.openflocon.flocondesktop.features.deeplinks.data.datasource.roo
import io.github.openflocon.flocondesktop.features.deeplinks.data.datasource.room.model.DeeplinkEntity
import io.github.openflocon.flocondesktop.features.files.data.datasources.FloconFileDao
import io.github.openflocon.flocondesktop.features.files.data.datasources.model.FileEntity
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.GrpcDao
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model.GrpcCallEntity
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model.GrpcResponseEntity
import io.github.openflocon.flocondesktop.features.images.data.datasources.local.FloconImageDao
import io.github.openflocon.flocondesktop.features.images.data.datasources.local.model.DeviceImageEntity
import io.github.openflocon.flocondesktop.features.network.data.datasource.local.FloconHttpRequestDao
@@ -31,7 +28,7 @@ import io.github.openflocon.flocondesktop.features.table.data.datasource.local.m
import kotlinx.coroutines.Dispatchers
@Database(
- version = 24,
+ version = 27,
entities = [
FloconHttpRequestEntity::class,
FileEntity::class,
@@ -43,8 +40,6 @@ import kotlinx.coroutines.Dispatchers
DeviceImageEntity::class,
SuccessQueryEntity::class,
DeeplinkEntity::class,
- GrpcCallEntity::class,
- GrpcResponseEntity::class,
AnalyticsItemEntity::class,
],
)
@@ -60,7 +55,6 @@ abstract class AppDatabase : RoomDatabase() {
abstract val imageDao: FloconImageDao
abstract val queryDao: QueryDao
abstract val deeplinkDao: FloconDeeplinkDao
- abstract val grpcDao: GrpcDao
abstract val analyticsDao: FloconAnalyticsDao
}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/RoomModule.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/RoomModule.kt
index d2ee6d77..c1bf0bc9 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/RoomModule.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/RoomModule.kt
@@ -28,9 +28,6 @@ val roomModule =
single {
get().deeplinkDao
}
- single {
- get().grpcDao
- }
single {
get().analyticsDao
}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/FeaturesModule.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/FeaturesModule.kt
index 0c83e0e7..01fdd231 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/FeaturesModule.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/FeaturesModule.kt
@@ -5,7 +5,6 @@ import io.github.openflocon.flocondesktop.features.dashboard.di.dashboardModule
import io.github.openflocon.flocondesktop.features.database.di.databaseModule
import io.github.openflocon.flocondesktop.features.deeplinks.di.deeplinkModule
import io.github.openflocon.flocondesktop.features.files.di.filesModule
-import io.github.openflocon.flocondesktop.features.grpc.di.grpcModule
import io.github.openflocon.flocondesktop.features.images.di.imagesModule
import io.github.openflocon.flocondesktop.features.network.di.networkModule
import io.github.openflocon.flocondesktop.features.sharedpreferences.di.sharedPreferencesModule
@@ -19,7 +18,6 @@ val featuresModule =
analyticsModule,
databaseModule,
filesModule,
- grpcModule,
imagesModule,
messagesModule,
networkModule,
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/GRPCRepositoryImpl.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/GRPCRepositoryImpl.kt
deleted file mode 100644
index 9a5f18f4..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/GRPCRepositoryImpl.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data
-
-import io.github.openflocon.flocondesktop.DeviceId
-import io.github.openflocon.flocondesktop.FloconIncomingMessageDataModel
-import io.github.openflocon.flocondesktop.Protocol
-import io.github.openflocon.flocondesktop.common.coroutines.dispatcherprovider.DispatcherProvider
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.LocalGrpcDataSource
-import io.github.openflocon.flocondesktop.features.grpc.data.model.fromdevice.GrpcRequestDataModel
-import io.github.openflocon.flocondesktop.features.grpc.data.model.fromdevice.GrpcResponseDataModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallId
-import io.github.openflocon.flocondesktop.features.grpc.domain.repository.GRPCRepository
-import io.github.openflocon.flocondesktop.messages.domain.repository.sub.MessagesReceiverRepository
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.withContext
-import kotlinx.serialization.json.Json
-
-class GRPCRepositoryImpl(
- private val dispatcherProvider: DispatcherProvider,
- private val localGrpcDataSource: LocalGrpcDataSource,
-) : GRPCRepository,
- MessagesReceiverRepository {
-
- private val grpcParser =
- Json {
- ignoreUnknownKeys = true
- }
-
- override val pluginName = listOf(Protocol.FromDevice.GRPC.Plugin)
-
- override suspend fun onMessageReceived(
- deviceId: String,
- message: FloconIncomingMessageDataModel,
- ) {
- withContext(dispatcherProvider.data) {
- when (message.method) {
- Protocol.FromDevice.GRPC.Method.LogNetworkRequest -> decodeGrpcRequest(message)?.let {
- toDomain(it)
- }?.let {
- localGrpcDataSource.saveRequest(
- deviceId = deviceId,
- callId = it.callId,
- request = it.request,
- )
- }
-
- Protocol.FromDevice.GRPC.Method.LogNetworkResponse -> decodeGrpcResponse(message)?.let {
- toDomain(
- it,
- )
- }?.let {
- localGrpcDataSource.saveResponse(
- deviceId = deviceId,
- callId = it.callId,
- response = it.response,
- )
- }
- }
- }
- }
-
- private fun decodeGrpcRequest(message: FloconIncomingMessageDataModel): GrpcRequestDataModel? = try {
- grpcParser.decodeFromString(message.body)
- } catch (t: Throwable) {
- t.printStackTrace()
- null
- }
-
- private fun decodeGrpcResponse(message: FloconIncomingMessageDataModel): GrpcResponseDataModel? = try {
- grpcParser.decodeFromString(message.body)
- } catch (t: Throwable) {
- t.printStackTrace()
- null
- }
-
- override fun observeCalls(deviceId: DeviceId): Flow> = localGrpcDataSource.observeCalls(
- deviceId = deviceId,
- ).flowOn(dispatcherProvider.data)
-
- override fun observeCall(
- currentDeviceId: DeviceId,
- callId: GrpcCallId,
- ): Flow = localGrpcDataSource.observeCall(
- deviceId = currentDeviceId,
- callId = callId,
- ).flowOn(dispatcherProvider.data)
-
- override suspend fun deleteCall(deviceId: DeviceId, callId: GrpcCallId) = withContext(dispatcherProvider.data) {
- localGrpcDataSource.deleteCall(deviceId = deviceId, callId = callId)
- }
- override suspend fun deleteCallsBefore(deviceId: DeviceId, callId: GrpcCallId) = withContext(dispatcherProvider.data) {
- localGrpcDataSource.deleteCallsBefore(deviceId = deviceId, callId = callId)
- }
-
- override suspend fun deleteCallsForDevice(deviceId: DeviceId) = withContext(dispatcherProvider.data) {
- localGrpcDataSource.clearDeviceCalls(deviceId = deviceId)
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/LocalGrpcDataSource.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/LocalGrpcDataSource.kt
deleted file mode 100644
index e2ecb4bb..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/LocalGrpcDataSource.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.datasource
-
-import io.github.openflocon.flocondesktop.DeviceId
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallId
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcRequestDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcResponseDomainModel
-import kotlinx.coroutines.flow.Flow
-
-interface LocalGrpcDataSource {
- suspend fun saveRequest(deviceId: DeviceId, callId: GrpcCallId, request: GrpcRequestDomainModel)
- suspend fun saveResponse(deviceId: DeviceId, callId: GrpcCallId, response: GrpcResponseDomainModel)
- fun observeCalls(deviceId: DeviceId): Flow>
- fun observeCall(deviceId: DeviceId, callId: GrpcCallId): Flow
- suspend fun clearDeviceCalls(deviceId: DeviceId)
-
- suspend fun deleteCall(deviceId: DeviceId, callId: GrpcCallId)
- suspend fun deleteCallsBefore(deviceId: DeviceId, callId: GrpcCallId)
-
- suspend fun clear()
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/GrpcDao.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/GrpcDao.kt
deleted file mode 100644
index e44c93c3..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/GrpcDao.kt
+++ /dev/null
@@ -1,110 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.datasource.room
-
-import androidx.room.Dao
-import androidx.room.Insert
-import androidx.room.Query
-import androidx.room.Transaction
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model.GrpcCallEntity
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model.GrpcCallWithDetails
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model.GrpcResponseEntity
-import kotlinx.coroutines.flow.Flow
-
-@Dao
-interface GrpcDao {
- @Insert
- suspend fun insertGrpcCall(call: GrpcCallEntity)
-
- @Insert
- suspend fun insertGrpcResponse(response: GrpcResponseEntity)
-
- @Transaction
- @Query(
- """
- SELECT * FROM GrpcCallEntity
- WHERE deviceId = :deviceId
- ORDER BY timestamp ASC
- """,
- )
- fun observeCallsWithDetails(deviceId: String): Flow>
-
- @Transaction
- @Query(
- """
- SELECT * FROM GrpcCallEntity
- WHERE deviceId = :deviceId
- AND callId = :callId
- LIMIT 1
- """,
- )
- fun observeCallWithDetails(deviceId: String, callId: String): Flow
-
- @Query("DELETE FROM GrpcCallEntity WHERE deviceId = :deviceId")
- suspend fun clearDeviceRequests(deviceId: String)
-
- @Query(
- """
- DELETE FROM GrpcResponseEntity
- WHERE response_call_id IN (
- SELECT callId
- FROM GrpcCallEntity
- WHERE deviceId = :deviceId
- )
- """,
- )
- suspend fun clearDeviceResponses(deviceId: String)
-
- @Transaction
- suspend fun clearDeviceData(deviceId: String) {
- clearDeviceResponses(deviceId)
- clearDeviceRequests(deviceId)
- }
-
- @Query("DELETE FROM GrpcCallEntity WHERE callId = :requestId")
- suspend fun deleteRequestById(requestId: String)
-
- @Query("DELETE FROM GrpcResponseEntity WHERE response_call_id = :requestId")
- suspend fun deleteResponseById(requestId: String)
-
- @Transaction
- suspend fun deleteCallById(requestId: String) {
- deleteResponseById(requestId)
- deleteRequestById(requestId)
- }
-
- @Transaction
- suspend fun deleteCallsBeforeTimestamp(deviceId: String, timestamp: Long) {
- // First, get call IDs of requests to be deleted
- val callIdsToDelete = getCallIdsBeforeTimestamp(deviceId, timestamp)
-
- // Delete associated headers and responses
- for (callId in callIdsToDelete) {
- deleteCallById(callId)
- }
- }
-
- @Query("SELECT callId FROM GrpcCallEntity WHERE deviceId = :deviceId AND timestamp < :timestamp")
- suspend fun getCallIdsBeforeTimestamp(deviceId: String, timestamp: Long): List
-
- @Query("DELETE FROM GrpcCallEntity")
- suspend fun deleteAllRequests()
-
- @Query("DELETE FROM GrpcResponseEntity")
- suspend fun deleteAllResponses()
-
- @Transaction
- suspend fun clearAllData() {
- deleteAllResponses()
- deleteAllRequests()
- }
-
- @Query(
- """
- SELECT timestamp
- FROM GrpcCallEntity
- WHERE deviceId = :deviceId
- AND callId = :callId
- LIMIT 1
- """,
- )
- suspend fun getCallTimestamp(deviceId: String, callId: String): Long?
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/LocalGrpcDataSourceImpl.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/LocalGrpcDataSourceImpl.kt
deleted file mode 100644
index 894b4a6d..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/LocalGrpcDataSourceImpl.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.datasource.room
-
-import io.github.openflocon.flocondesktop.DeviceId
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.LocalGrpcDataSource
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model.GrpcCallEntity
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model.GrpcResponseEntity
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallId
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcRequestDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcResponseDomainModel
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
-
-class LocalGrpcDataSourceImpl(
- private val grpcDao: GrpcDao,
-) : LocalGrpcDataSource {
-
- override suspend fun saveRequest(
- deviceId: String,
- callId: String,
- request: GrpcRequestDomainModel,
- ) {
- val headersMap = request.headers.associate { it.key to it.value }
- val requestEntity = GrpcCallEntity(
- callId = callId,
- deviceId = deviceId,
- request = GrpcCallEntity.Request(
- timestamp = request.timestamp,
- authority = request.authority,
- method = request.method,
- data = request.data,
- headers = headersMap,
- ),
- )
- grpcDao.insertGrpcCall(requestEntity)
- }
-
- override suspend fun saveResponse(
- deviceId: String,
- callId: String,
- response: GrpcResponseDomainModel,
- ) {
- val headersMap = response.headers.associate { it.key to it.value }
- val responseEntity = GrpcResponseEntity(
- callId = callId,
- responseTimestamp = response.timestamp,
- status = response.status,
- resultType = when (response.result) {
- is GrpcResponseDomainModel.CallResult.Success -> "success"
- is GrpcResponseDomainModel.CallResult.Error -> "error"
- },
- resultData = when (response.result) {
- is GrpcResponseDomainModel.CallResult.Success -> response.result.data
- is GrpcResponseDomainModel.CallResult.Error -> response.result.cause
- },
- headers = headersMap,
- )
- grpcDao.insertGrpcResponse(responseEntity)
- }
-
- override fun observeCalls(deviceId: String): Flow> = grpcDao.observeCallsWithDetails(deviceId).map { entities ->
- entities.map { it.toDomainModel() }
- }
-
- override fun observeCall(deviceId: DeviceId, callId: GrpcCallId) = grpcDao.observeCallWithDetails(deviceId, callId = callId).map {
- it?.toDomainModel()
- }
-
- override suspend fun clearDeviceCalls(deviceId: String) {
- grpcDao.clearDeviceData(deviceId)
- }
-
- override suspend fun deleteCall(deviceId: String, callId: GrpcCallId) {
- grpcDao.deleteCallById(callId)
- }
-
- override suspend fun deleteCallsBefore(deviceId: String, callId: GrpcCallId) {
- val timestamp = grpcDao.getCallTimestamp(deviceId = deviceId, callId = callId) ?: return
- grpcDao.deleteCallsBeforeTimestamp(
- deviceId = deviceId,
- timestamp = timestamp,
- )
- }
-
- override suspend fun clear() {
- grpcDao.clearAllData()
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/mapper/Mapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/mapper/Mapper.kt
deleted file mode 100644
index a957fe94..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/mapper/Mapper.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.datasource.room
-
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model.GrpcCallWithDetails
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcHeaderDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcRequestDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcResponseDomainModel
-
-fun GrpcCallWithDetails.toDomainModel(): GrpcCallDomainModel {
- val requestDomain = with(call.request) {
- GrpcRequestDomainModel(
- timestamp = timestamp,
- authority = authority,
- method = method,
- headers = headers
- .map { GrpcHeaderDomainModel(key = it.key, value = it.value) },
- data = data,
- )
- }
-
- val responseDomain = response?.let {
- val callResult = when (it.resultType) {
- "success" -> GrpcResponseDomainModel.CallResult.Success(it.resultData ?: "")
- "error" -> GrpcResponseDomainModel.CallResult.Error(
- it.resultData ?: "Unknown error",
- )
-
- else -> error("Unknown result type")
- }
- GrpcResponseDomainModel(
- timestamp = it.responseTimestamp,
- status = it.status,
- headers = response.headers
- .map { header ->
- GrpcHeaderDomainModel(
- key = header.key,
- value = header.value,
- )
- },
- result = callResult,
- )
- }
-
- return GrpcCallDomainModel(
- id = call.callId,
- request = requestDomain,
- response = responseDomain,
- )
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/model/GrpcCallEntity.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/model/GrpcCallEntity.kt
deleted file mode 100644
index 7af54d87..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/model/GrpcCallEntity.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model
-
-import androidx.room.Embedded
-import androidx.room.Entity
-import androidx.room.Index
-import androidx.room.PrimaryKey
-
-@Entity(
- indices = [
- Index(value = ["deviceId"]),
- Index(value = ["callId"], unique = true),
- ],
-)
-data class GrpcCallEntity(
- @PrimaryKey val callId: String, // GrpcCallId will be the primary key here
- val deviceId: String,
- @Embedded val request: GrpcCallEntity.Request,
-) {
- data class Request(
- val timestamp: Long,
- val authority: String,
- val method: String,
- val data: String?,
- val headers: Map,
- )
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/model/GrpcCallWithDetails.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/model/GrpcCallWithDetails.kt
deleted file mode 100644
index 2df4a76d..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/model/GrpcCallWithDetails.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model
-
-import androidx.room.Embedded
-import androidx.room.Relation
-
-data class GrpcCallWithDetails(
- @Embedded val call: GrpcCallEntity,
- @Relation(
- parentColumn = "callId",
- entityColumn = "response_call_id",
- )
- val response: GrpcResponseEntity?, // Response can be null if not yet received
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/model/GrpcResponseEntity.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/model/GrpcResponseEntity.kt
deleted file mode 100644
index b1d6b58d..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/datasource/room/model/GrpcResponseEntity.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.model
-
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-
-@Entity
-data class GrpcResponseEntity(
- @PrimaryKey @ColumnInfo(name = "response_call_id") val callId: String, // Linked to GrpcCallEntity's callId
- val responseTimestamp: Long,
- val status: String,
- val resultType: String, // "success" or "error"
- val resultData: String?, // Data for success, cause for error
- val headers: Map,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/di/GRPCDataModule.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/di/GRPCDataModule.kt
deleted file mode 100644
index fe8e8492..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/di/GRPCDataModule.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.di
-
-import io.github.openflocon.flocondesktop.features.grpc.data.GRPCRepositoryImpl
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.LocalGrpcDataSource
-import io.github.openflocon.flocondesktop.features.grpc.data.datasource.room.LocalGrpcDataSourceImpl
-import io.github.openflocon.flocondesktop.features.grpc.domain.repository.GRPCRepository
-import io.github.openflocon.flocondesktop.messages.domain.repository.sub.MessagesReceiverRepository
-import org.koin.core.module.dsl.bind
-import org.koin.core.module.dsl.factoryOf
-import org.koin.core.module.dsl.singleOf
-import org.koin.dsl.module
-
-val grpcDataModule =
- module {
- factoryOf(::GRPCRepositoryImpl) {
- bind()
- bind()
- }
- singleOf(::LocalGrpcDataSourceImpl) {
- bind()
- }
- }
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/mapper/RemoteToDomainMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/mapper/RemoteToDomainMapper.kt
deleted file mode 100644
index 9e4895be..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/mapper/RemoteToDomainMapper.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data
-
-import io.github.openflocon.flocondesktop.features.grpc.data.model.GrpcRequestDomainModelWrapper
-import io.github.openflocon.flocondesktop.features.grpc.data.model.GrpcResponseDomainModelWrapper
-import io.github.openflocon.flocondesktop.features.grpc.data.model.fromdevice.GrpcHeaderDataModel
-import io.github.openflocon.flocondesktop.features.grpc.data.model.fromdevice.GrpcRequestDataModel
-import io.github.openflocon.flocondesktop.features.grpc.data.model.fromdevice.GrpcResponseDataModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcHeaderDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcRequestDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcResponseDomainModel
-
-fun toDomain(dataModel: GrpcRequestDataModel): GrpcRequestDomainModelWrapper? = GrpcRequestDomainModelWrapper(
- callId = dataModel.id,
- request = GrpcRequestDomainModel(
- timestamp = dataModel.timestamp,
- authority = dataModel.authority,
- method = dataModel.method,
- headers = dataModel.headers.map {
- toDomain(it)
- },
- data = dataModel.data,
- ),
-)
-
-fun toDomain(dataModel: GrpcResponseDataModel): GrpcResponseDomainModelWrapper? {
- return GrpcResponseDomainModelWrapper(
- callId = dataModel.id,
- response = GrpcResponseDomainModel(
- timestamp = dataModel.timestamp,
- status = dataModel.status,
- headers = dataModel.headers.map {
- toDomain(it)
- },
- result = when {
- dataModel.data != null -> GrpcResponseDomainModel.CallResult.Success(
- data = dataModel.data,
- )
- dataModel.cause != null -> GrpcResponseDomainModel.CallResult.Error(
- cause = dataModel.cause,
- )
- else -> return null
- },
- ),
- )
-}
-
-private fun toDomain(model: GrpcHeaderDataModel): GrpcHeaderDomainModel = GrpcHeaderDomainModel(
- key = model.key,
- value = model.value,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/GrpcRequestDomainModelWrapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/GrpcRequestDomainModelWrapper.kt
deleted file mode 100644
index c72a8d37..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/GrpcRequestDomainModelWrapper.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.model
-
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallId
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcRequestDomainModel
-
-data class GrpcRequestDomainModelWrapper(
- val callId: GrpcCallId,
- val request: GrpcRequestDomainModel,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/GrpcResponseDomainModelWrapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/GrpcResponseDomainModelWrapper.kt
deleted file mode 100644
index 37f88bbd..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/GrpcResponseDomainModelWrapper.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.model
-
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallId
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcResponseDomainModel
-
-data class GrpcResponseDomainModelWrapper(
- val callId: GrpcCallId,
- val response: GrpcResponseDomainModel,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/fromdevice/GrpcHeaderDataModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/fromdevice/GrpcHeaderDataModel.kt
deleted file mode 100644
index 8264c049..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/fromdevice/GrpcHeaderDataModel.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.model.fromdevice
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class GrpcHeaderDataModel(
- val key: String,
- val value: String,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/fromdevice/GrpcRequestDataModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/fromdevice/GrpcRequestDataModel.kt
deleted file mode 100644
index c545408b..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/fromdevice/GrpcRequestDataModel.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.model.fromdevice
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class GrpcRequestDataModel(
- val id: String,
- val timestamp: Long,
- val authority: String,
- val method: String,
- val headers: List,
- val data: String? = null,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/fromdevice/GrpcResponseDataModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/fromdevice/GrpcResponseDataModel.kt
deleted file mode 100644
index 35574f29..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/data/model/fromdevice/GrpcResponseDataModel.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.data.model.fromdevice
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class GrpcResponseDataModel(
- val id: String,
- val timestamp: Long,
- val status: String,
- val cause: String? = null,
- val headers: List,
- val data: String? = null,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/di/GRPCModule.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/di/GRPCModule.kt
deleted file mode 100644
index a6ae0d65..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/di/GRPCModule.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.di
-
-import io.github.openflocon.flocondesktop.features.grpc.data.di.grpcDataModule
-import io.github.openflocon.flocondesktop.features.grpc.domain.di.grpcDomainModule
-import io.github.openflocon.flocondesktop.features.grpc.ui.di.grpcUiModule
-import org.koin.dsl.module
-
-val grpcModule =
- module {
- includes(
- grpcDataModule,
- grpcDomainModule,
- grpcUiModule,
- )
- }
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/DeleteGrpcCallBeforeUseCase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/DeleteGrpcCallBeforeUseCase.kt
deleted file mode 100644
index 99bb15ac..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/DeleteGrpcCallBeforeUseCase.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain
-
-import io.github.openflocon.flocondesktop.core.domain.device.GetCurrentDeviceIdUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallId
-import io.github.openflocon.flocondesktop.features.grpc.domain.repository.GRPCRepository
-
-class DeleteGrpcCallBeforeUseCase(
- private val grpcRepository: GRPCRepository,
- private val getCurrentDeviceIdUseCase: GetCurrentDeviceIdUseCase,
-) {
- suspend operator fun invoke(callId: GrpcCallId) {
- val deviceId = getCurrentDeviceIdUseCase() ?: return
- grpcRepository.deleteCallsBefore(deviceId = deviceId, callId = callId)
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/DeleteGrpcCallUseCase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/DeleteGrpcCallUseCase.kt
deleted file mode 100644
index 5b1e8717..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/DeleteGrpcCallUseCase.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain
-
-import io.github.openflocon.flocondesktop.core.domain.device.GetCurrentDeviceIdUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallId
-import io.github.openflocon.flocondesktop.features.grpc.domain.repository.GRPCRepository
-
-class DeleteGrpcCallUseCase(
- private val grpcRepository: GRPCRepository,
- private val getCurrentDeviceIdUseCase: GetCurrentDeviceIdUseCase,
-) {
- suspend operator fun invoke(callId: GrpcCallId) {
- val deviceId = getCurrentDeviceIdUseCase() ?: return
- grpcRepository.deleteCall(deviceId, callId)
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/ObserveGrpcCallByIdUseCase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/ObserveGrpcCallByIdUseCase.kt
deleted file mode 100644
index c1cd06e7..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/ObserveGrpcCallByIdUseCase.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain
-
-import io.github.openflocon.flocondesktop.core.domain.device.ObserveCurrentDeviceIdUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallId
-import io.github.openflocon.flocondesktop.features.grpc.domain.repository.GRPCRepository
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-
-class ObserveGrpcCallByIdUseCase(
- private val grpcRepository: GRPCRepository,
- private val observeCurrentDeviceIdUseCase: ObserveCurrentDeviceIdUseCase,
-) {
- operator fun invoke(callId: GrpcCallId): Flow = observeCurrentDeviceIdUseCase().flatMapLatest { currentDeviceId ->
- if (currentDeviceId == null) {
- flowOf(null)
- } else {
- grpcRepository.observeCall(currentDeviceId, callId = callId)
- }
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/ObserveGrpcCallsUseCase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/ObserveGrpcCallsUseCase.kt
deleted file mode 100644
index b87180f8..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/ObserveGrpcCallsUseCase.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain
-
-import io.github.openflocon.flocondesktop.core.domain.device.ObserveCurrentDeviceIdUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.repository.GRPCRepository
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-
-class ObserveGrpcCallsUseCase(
- private val grpcRepository: GRPCRepository,
- private val observeCurrentDeviceIdUseCase: ObserveCurrentDeviceIdUseCase,
-) {
- operator fun invoke(): Flow> = observeCurrentDeviceIdUseCase().flatMapLatest { currentDeviceId ->
- if (currentDeviceId == null) {
- flowOf(emptyList())
- } else {
- grpcRepository.observeCalls(currentDeviceId)
- }
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/ResetCurrentDeviceGrpcCallsUseCase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/ResetCurrentDeviceGrpcCallsUseCase.kt
deleted file mode 100644
index a8a14e12..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/ResetCurrentDeviceGrpcCallsUseCase.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain
-
-import io.github.openflocon.flocondesktop.core.domain.device.GetCurrentDeviceIdUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.repository.GRPCRepository
-
-class ResetCurrentDeviceGrpcCallsUseCase(
- private val grpcRepository: GRPCRepository,
- private val getCurrentDeviceIdUseCase: GetCurrentDeviceIdUseCase,
-) {
- suspend operator fun invoke() {
- val deviceId = getCurrentDeviceIdUseCase() ?: return
- grpcRepository.deleteCallsForDevice(deviceId = deviceId)
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/di/GRPCDomainModule.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/di/GRPCDomainModule.kt
deleted file mode 100644
index 5c1292b2..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/di/GRPCDomainModule.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain.di
-
-import io.github.openflocon.flocondesktop.features.grpc.domain.DeleteGrpcCallBeforeUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.DeleteGrpcCallUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.ObserveGrpcCallByIdUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.ObserveGrpcCallsUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.ResetCurrentDeviceGrpcCallsUseCase
-import org.koin.core.module.dsl.factoryOf
-import org.koin.dsl.module
-
-val grpcDomainModule =
- module {
- factoryOf(::ObserveGrpcCallsUseCase)
- factoryOf(::ObserveGrpcCallByIdUseCase)
- factoryOf(::DeleteGrpcCallUseCase)
- factoryOf(::DeleteGrpcCallBeforeUseCase)
- factoryOf(::ResetCurrentDeviceGrpcCallsUseCase)
- }
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcCallDomainModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcCallDomainModel.kt
deleted file mode 100644
index 74082a7b..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcCallDomainModel.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain.model
-
-data class GrpcCallDomainModel(
- val id: String,
- val request: GrpcRequestDomainModel,
- val response: GrpcResponseDomainModel?,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcCallId.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcCallId.kt
deleted file mode 100644
index 93f7db45..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcCallId.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain.model
-
-typealias GrpcCallId = String
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcHeaderDomainModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcHeaderDomainModel.kt
deleted file mode 100644
index 7e1f1f5f..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcHeaderDomainModel.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain.model
-
-data class GrpcHeaderDomainModel(
- val key: String,
- val value: String,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcRequestDomainModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcRequestDomainModel.kt
deleted file mode 100644
index 77a8dbda..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcRequestDomainModel.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain.model
-
-data class GrpcRequestDomainModel(
- val timestamp: Long,
- val authority: String,
- val method: String,
- val headers: List,
- val data: String?,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcResponseDomainModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcResponseDomainModel.kt
deleted file mode 100644
index dc0cf06b..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/model/GrpcResponseDomainModel.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain.model
-
-data class GrpcResponseDomainModel(
- val timestamp: Long,
- val status: String,
- val headers: List,
- val result: CallResult,
-) {
- sealed interface CallResult {
- data class Success(
- val data: String,
- ) : CallResult
-
- data class Error(
- val cause: String,
- ) : CallResult
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/repository/GRPCRepository.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/repository/GRPCRepository.kt
deleted file mode 100644
index f037cf7c..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/domain/repository/GRPCRepository.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.domain.repository
-
-import io.github.openflocon.flocondesktop.DeviceId
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallId
-import kotlinx.coroutines.flow.Flow
-
-interface GRPCRepository {
- fun observeCalls(deviceId: DeviceId): Flow>
- fun observeCall(currentDeviceId: DeviceId, callId: GrpcCallId): Flow
-
- suspend fun deleteCall(deviceId: DeviceId, callId: GrpcCallId)
- suspend fun deleteCallsBefore(deviceId: DeviceId, callId: GrpcCallId)
- suspend fun deleteCallsForDevice(deviceId: DeviceId)
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/GRPCViewModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/GRPCViewModel.kt
deleted file mode 100644
index 0ff48d65..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/GRPCViewModel.kt
+++ /dev/null
@@ -1,119 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui
-
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import io.github.openflocon.flocondesktop.common.coroutines.dispatcherprovider.DispatcherProvider
-import io.github.openflocon.flocondesktop.common.ui.feedback.FeedbackDisplayer
-import io.github.openflocon.flocondesktop.copyToClipboard
-import io.github.openflocon.flocondesktop.features.grpc.domain.DeleteGrpcCallBeforeUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.DeleteGrpcCallUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.ObserveGrpcCallByIdUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.ObserveGrpcCallsUseCase
-import io.github.openflocon.flocondesktop.features.grpc.domain.ResetCurrentDeviceGrpcCallsUseCase
-import io.github.openflocon.flocondesktop.features.grpc.ui.mapper.toDetailUi
-import io.github.openflocon.flocondesktop.features.grpc.ui.mapper.toUi
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcDetailViewState
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcItemViewState
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.OnGrpcItemUserAction
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.firstOrNull
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.flow.update
-import kotlinx.coroutines.launch
-
-class GRPCViewModel(
- private val dispatcherProvider: DispatcherProvider,
- private val feedbackDisplayer: FeedbackDisplayer,
- observeGrpcCallsUseCase: ObserveGrpcCallsUseCase,
- private val observeGrpcCallByIdUseCase: ObserveGrpcCallByIdUseCase,
- private val deleteGrpcCallBeforeUseCase: DeleteGrpcCallBeforeUseCase,
- private val deleteGrpcCallUseCase: DeleteGrpcCallUseCase,
- private val resetCurrentDeviceGrpcCallsUseCase: ResetCurrentDeviceGrpcCallsUseCase,
-) : ViewModel() {
-
- val state: StateFlow> =
- observeGrpcCallsUseCase()
- .map { list -> list.map { toUi(it) } }
- .flowOn(dispatcherProvider.viewModel)
- .stateIn(viewModelScope, started = SharingStarted.WhileSubscribed(5_000), emptyList())
-
- private val clickedCallId = MutableStateFlow(null)
-
- val detailState: StateFlow =
- clickedCallId
- .flatMapLatest { id ->
- if (id == null) {
- flowOf(null)
- } else {
- observeGrpcCallByIdUseCase(id)
- .distinctUntilChanged()
- .map {
- it?.let {
- toDetailUi(it)
- }
- }
- }
- }
- .flowOn(dispatcherProvider.viewModel)
- .stateIn(viewModelScope, started = SharingStarted.WhileSubscribed(5_000), null)
-
- fun onGrpcItemUserAction(action: OnGrpcItemUserAction) {
- viewModelScope.launch {
- when (action) {
- is OnGrpcItemUserAction.OnClicked -> {
- clickedCallId.update {
- if (it == action.item.callId) {
- null
- } else {
- action.item.callId
- }
- }
- }
-
- is OnGrpcItemUserAction.Remove -> {
- deleteGrpcCallUseCase(callId = action.item.callId)
- }
-
- is OnGrpcItemUserAction.RemoveLinesAbove -> {
- deleteGrpcCallBeforeUseCase(callId = action.item.callId)
- }
-
- is OnGrpcItemUserAction.CopyMethod -> {
- val domainModel = observeGrpcCallByIdUseCase(action.item.callId).firstOrNull()
- ?: return@launch
- copyToClipboard(domainModel.request.method)
- }
-
- is OnGrpcItemUserAction.CopyUrl -> {
- val domainModel = observeGrpcCallByIdUseCase(action.item.callId).firstOrNull()
- ?: return@launch
- copyToClipboard(domainModel.request.authority)
- }
- }
- }
- }
-
- fun onCopyText(text: String) {
- copyToClipboard(text)
- feedbackDisplayer.displayMessage("copied")
- }
-
- fun closeDetailPanel() {
- viewModelScope.launch {
- clickedCallId.update { null }
- }
- }
-
- fun onReset() {
- viewModelScope.launch(dispatcherProvider.viewModel) {
- resetCurrentDeviceGrpcCallsUseCase()
- }
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/di/GRPCUiModule.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/di/GRPCUiModule.kt
deleted file mode 100644
index 64feec83..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/di/GRPCUiModule.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.di
-
-import io.github.openflocon.flocondesktop.features.grpc.ui.GRPCViewModel
-import org.koin.core.module.dsl.viewModelOf
-import org.koin.dsl.module
-
-val grpcUiModule =
- module {
- viewModelOf(::GRPCViewModel)
- }
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/mapper/UiMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/mapper/UiMapper.kt
deleted file mode 100644
index 86e888d1..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/mapper/UiMapper.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.mapper
-
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcCallDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcHeaderDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.domain.model.GrpcResponseDomainModel
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcDetailViewState
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcItemViewState
-import io.github.openflocon.flocondesktop.features.network.ui.mapper.formatDuration
-import io.github.openflocon.flocondesktop.features.network.ui.mapper.formatTimestamp
-import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkDetailHeaderUi
-
-fun toUi(domainModel: GrpcCallDomainModel): GrpcItemViewState = GrpcItemViewState(
- callId = domainModel.id,
- method = domainModel.request.method,
- url = domainModel.request.authority,
- status = if (domainModel.response == null) {
- GrpcItemViewState.StatusViewState.Waiting(text = "Waiting")
- } else {
- when (domainModel.response.result) {
- is GrpcResponseDomainModel.CallResult.Error ->
- GrpcItemViewState.StatusViewState.Failure(domainModel.response.result.cause)
-
- is GrpcResponseDomainModel.CallResult.Success ->
- GrpcItemViewState.StatusViewState.Success(text = "Success")
- }
- },
- requestTimeFormatted = formatTimestamp(domainModel.request.timestamp),
- durationFormatted = domainModel.response?.let {
- val duration = it.timestamp - domainModel.request.timestamp
- formatDuration(duration.toDouble())
- },
-)
-
-fun toDetailUi(domainModel: GrpcCallDomainModel): GrpcDetailViewState = GrpcDetailViewState(
- method = domainModel.request.method,
- url = domainModel.request.authority,
- status = if (domainModel.response == null) {
- GrpcItemViewState.StatusViewState.Waiting(text = "Waiting")
- } else {
- when (domainModel.response.result) {
- is GrpcResponseDomainModel.CallResult.Error ->
- GrpcItemViewState.StatusViewState.Failure(domainModel.response.result.cause)
-
- is GrpcResponseDomainModel.CallResult.Success ->
- GrpcItemViewState.StatusViewState.Success(text = "Success")
- }
- },
- requestTimeFormatted = formatTimestamp(domainModel.request.timestamp),
- durationFormatted = domainModel.response?.let {
- val duration = it.timestamp - domainModel.request.timestamp
- formatDuration(duration.toDouble())
- },
- requestBody = domainModel.request.data,
- requestHeaders = domainModel.request.headers.map {
- toUi(it)
- },
- response = domainModel.response?.let {
- GrpcDetailViewState.ResponseViewState(
- headers = it.headers.map {
- toUi(it)
- },
- result = when (it.result) {
- is GrpcResponseDomainModel.CallResult.Error -> GrpcDetailViewState.DetailPayload.Failure(it.result.cause)
- is GrpcResponseDomainModel.CallResult.Success -> GrpcDetailViewState.DetailPayload.Success(it.result.data)
- },
- )
- },
-)
-
-fun toUi(header: GrpcHeaderDomainModel) = NetworkDetailHeaderUi(
- name = header.key,
- value = header.value,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/GrpcDetailViewState.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/GrpcDetailViewState.kt
deleted file mode 100644
index 2244c0ae..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/GrpcDetailViewState.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.model
-
-import androidx.compose.runtime.Immutable
-import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkDetailHeaderUi
-import io.github.openflocon.flocondesktop.features.network.ui.model.previewNetworkDetailHeaderUi
-
-@Immutable
-data class GrpcDetailViewState(
- val url: String, // authority
-
- val requestTimeFormatted: String,
- val durationFormatted: String?,
-
- val method: String,
- val status: GrpcItemViewState.StatusViewState,
-
- // request
- val requestBody: String?,
- val requestHeaders: List,
-
- val response: ResponseViewState?,
-) {
- data class ResponseViewState(
- val headers: List,
- val result: DetailPayload,
- )
-
- sealed interface DetailPayload {
- data class Success(val body: String) : DetailPayload
- data class Failure(val cause: String) : DetailPayload
- }
-}
-
-fun previewGrpcDetailViewState() = GrpcDetailViewState(
- url = "google.com.test",
- requestTimeFormatted = "00:00:00.0000",
- durationFormatted = "333ms",
- method = "public.get.methodName",
- status = GrpcItemViewState.StatusViewState.Success("OK"),
- requestBody = "request body",
- requestHeaders = listOf(
- previewNetworkDetailHeaderUi(),
- previewNetworkDetailHeaderUi(),
- previewNetworkDetailHeaderUi(),
- previewNetworkDetailHeaderUi(),
- previewNetworkDetailHeaderUi(),
- ),
- response = GrpcDetailViewState.ResponseViewState(
- headers = listOf(
- previewNetworkDetailHeaderUi(),
- previewNetworkDetailHeaderUi(),
- previewNetworkDetailHeaderUi(),
- previewNetworkDetailHeaderUi(),
- previewNetworkDetailHeaderUi(),
- ),
- result = GrpcDetailViewState.DetailPayload.Success("response body"),
- ),
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/GrpcItemColumnWidths.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/GrpcItemColumnWidths.kt
deleted file mode 100644
index 312a4eca..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/GrpcItemColumnWidths.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.model
-
-import androidx.compose.runtime.Immutable
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-
-@Immutable
-data class GrpcItemColumnWidths(
- val requestTimeFormatted: Dp = 90.dp,
- val url: Float = 1f, // weight
- val method: Float = 2f, // weight
- val status: Dp = 80.dp,
- val durationFormatted: Dp = 65.dp,
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/GrpcItemViewState.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/GrpcItemViewState.kt
deleted file mode 100644
index 37ea851a..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/GrpcItemViewState.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.model
-
-import androidx.compose.runtime.Immutable
-
-@Immutable
-data class GrpcItemViewState(
- val callId: String,
-
- val requestTimeFormatted: String,
- val url: String, // authority
- val method: String,
- val status: StatusViewState,
- val durationFormatted: String?,
-) {
- @Immutable
- sealed interface StatusViewState {
- val text: String
-
- @Immutable
- data class Success(override val text: String) : StatusViewState
-
- @Immutable
- data class Waiting(override val text: String) : StatusViewState
-
- @Immutable
- data class Failure(override val text: String) : StatusViewState
- }
-
- fun contains(text: String): Boolean = listOf(callId, requestTimeFormatted, url, method, status.text, durationFormatted).any {
- it?.contains(text, ignoreCase = true) == true
- }
-}
-
-fun previewGrpcItemViewState(): GrpcItemViewState = GrpcItemViewState(
- callId = "0",
- requestTimeFormatted = "00:00:00.0000",
- url = "google.com.test",
- method = "public.get.methodName",
- status = GrpcItemViewState.StatusViewState.Success("OK"),
- durationFormatted = "333ms",
-)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/OnGrpcItemUserAction.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/OnGrpcItemUserAction.kt
deleted file mode 100644
index c55623cf..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/model/OnGrpcItemUserAction.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.model
-
-sealed interface OnGrpcItemUserAction {
- data class OnClicked(
- val item: GrpcItemViewState,
- ) : OnGrpcItemUserAction
-
- data class CopyUrl(
- val item: GrpcItemViewState,
- ) : OnGrpcItemUserAction
-
- data class CopyMethod(
- val item: GrpcItemViewState,
- ) : OnGrpcItemUserAction
-
- data class Remove(
- val item: GrpcItemViewState,
- ) : OnGrpcItemUserAction
-
- data class RemoveLinesAbove(
- val item: GrpcItemViewState,
- ) : OnGrpcItemUserAction
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GRPCScreen.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GRPCScreen.kt
deleted file mode 100644
index ba4e9201..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GRPCScreen.kt
+++ /dev/null
@@ -1,151 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.view
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import io.github.openflocon.flocondesktop.common.ui.FloconColors
-import io.github.openflocon.flocondesktop.common.ui.FloconTheme
-import io.github.openflocon.flocondesktop.features.grpc.ui.GRPCViewModel
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcDetailViewState
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcItemColumnWidths
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcItemViewState
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.OnGrpcItemUserAction
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.previewGrpcItemViewState
-import io.github.openflocon.flocondesktop.features.grpc.ui.view.header.GrpcFilterBar
-import io.github.openflocon.flocondesktop.features.grpc.ui.view.header.GrpcItemHeaderView
-import org.jetbrains.compose.ui.tooling.preview.Preview
-import org.koin.compose.viewmodel.koinViewModel
-
-@Composable
-fun GRPCScreen(modifier: Modifier = Modifier) {
- val viewModel: GRPCViewModel = koinViewModel()
- val state: List by viewModel.state.collectAsStateWithLifecycle()
- val detailState: GrpcDetailViewState? by viewModel.detailState.collectAsStateWithLifecycle()
-
- GRPCScreen(
- grpcItems = state,
- modifier = modifier,
- detailState = detailState,
- onReset = viewModel::onReset,
- closeDetailPanel = viewModel::closeDetailPanel,
- onCopyText = viewModel::onCopyText,
- onGrpcItemUserAction = viewModel::onGrpcItemUserAction,
- )
-}
-
-@Composable
-private fun GRPCScreen(
- grpcItems: List,
- onGrpcItemUserAction: (OnGrpcItemUserAction) -> Unit,
- onReset: () -> Unit,
- detailState: GrpcDetailViewState?,
- closeDetailPanel: () -> Unit,
- onCopyText: (text: String) -> Unit,
- modifier: Modifier = Modifier,
-) {
- val columnWidths: GrpcItemColumnWidths =
- remember { GrpcItemColumnWidths() } // Default widths provided
-
- var filteredItems by remember { mutableStateOf>(emptyList()) }
-
- Surface(modifier = modifier) {
- Box(modifier = Modifier.fillMaxSize()) {
- Column(modifier = Modifier.fillMaxSize()) {
- Text(
- text = "Grpc",
- modifier = Modifier
- .fillMaxWidth()
- .background(FloconColors.pannel)
- .padding(all = 12.dp),
- style = MaterialTheme.typography.titleLarge,
- color = MaterialTheme.colorScheme.onSurface,
- )
- GrpcFilterBar(
- modifier =
- Modifier
- .fillMaxWidth()
- .background(FloconColors.pannel)
- .padding(horizontal = 12.dp),
- grpcItems = grpcItems,
- onResetClicked = onReset,
- onItemsChange = {
- filteredItems = it
- },
- )
- GrpcItemHeaderView(
- columnWidths = columnWidths,
- modifier = Modifier.fillMaxWidth(),
- )
- LazyColumn(
- modifier =
- Modifier
- .fillMaxSize()
- .clickable(
- interactionSource = null,
- indication = null,
- enabled = detailState != null,
- ) {
- closeDetailPanel()
- },
- ) {
- items(filteredItems) {
- GrpcItemView(
- state = it,
- columnWidths = columnWidths,
- modifier = Modifier.fillMaxWidth(),
- onUserAction = onGrpcItemUserAction,
- )
- }
- }
- }
- detailState?.let {
- GrpcDetailView(
- modifier =
- Modifier
- .align(Alignment.TopEnd)
- .fillMaxHeight()
- .width(500.dp),
- state = it,
- onCopy = onCopyText,
- )
- }
- }
- }
-}
-
-@Composable
-@Preview
-private fun GRPCScreenPreview() {
- FloconTheme {
- GRPCScreen(
- grpcItems = List(10) {
- previewGrpcItemViewState()
- },
- onReset = {},
- detailState = null,
- closeDetailPanel = {},
- onCopyText = {},
- onGrpcItemUserAction = {},
- )
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GrpcDetailView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GrpcDetailView.kt
deleted file mode 100644
index b9431d1d..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GrpcDetailView.kt
+++ /dev/null
@@ -1,258 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.view
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.HorizontalDivider
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import io.github.openflocon.flocondesktop.common.ui.FloconColors
-import io.github.openflocon.flocondesktop.common.ui.FloconTheme
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcDetailViewState
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.previewGrpcDetailViewState
-import io.github.openflocon.flocondesktop.features.network.ui.view.detail.CodeBlockView
-import io.github.openflocon.flocondesktop.features.network.ui.view.detail.DetailHeadersView
-import io.github.openflocon.flocondesktop.features.network.ui.view.detail.DetailLineTextView
-import io.github.openflocon.flocondesktop.features.network.ui.view.detail.DetailLineView
-import io.github.openflocon.flocondesktop.features.network.ui.view.detail.DetailSectionTitleView
-import io.github.openflocon.flocondesktop.features.network.ui.view.detail.ExpandedSectionView
-import org.jetbrains.compose.ui.tooling.preview.Preview
-
-@Composable
-fun GrpcDetailView(
- state: GrpcDetailViewState,
- onCopy: (String) -> Unit, // Le lambda onCopy remplace ClipboardManager
- modifier: Modifier = Modifier,
-) {
- val scrollState = rememberScrollState()
-
- var isRequestExpanded by remember { mutableStateOf(true) }
- var isRequestBodyExpanded by remember { mutableStateOf(true) }
- var isRequestHeadersExpanded by remember { mutableStateOf(true) }
-
- var isResponseExpanded by remember { mutableStateOf(true) }
- var isResponseHeadersExpanded by remember { mutableStateOf(true) }
- var isResponseBodyExpanded by remember { mutableStateOf(true) }
-
- val linesLabelWidth: Dp = 130.dp
- val headersLabelWidth: Dp = 150.dp
-
- Column(
- modifier =
- modifier
- .background(FloconColors.background)
- .verticalScroll(scrollState) // Rendre le contenu défilable
- .padding(all = 12.dp),
- ) {
- DetailSectionTitleView(
- isExpanded = isRequestExpanded,
- title = "Request",
- onCopy = null,
- onToggle = {
- isRequestExpanded = it
- },
- )
- ExpandedSectionView(
- modifier = Modifier.fillMaxWidth(),
- isExpanded = isRequestExpanded,
- ) {
- Column(
- modifier =
- Modifier
- .background(
- color = MaterialTheme.colorScheme.surfaceVariant,
- shape = RoundedCornerShape(12.dp),
- ).padding(horizontal = 8.dp, vertical = 4.dp),
- ) {
- DetailLineTextView(
- modifier = Modifier.fillMaxWidth(),
- label = "Url",
- value = state.url,
- labelWidth = linesLabelWidth,
- )
- DetailLineTextView(
- modifier = Modifier.fillMaxWidth(),
- label = "Method",
- labelWidth = linesLabelWidth,
- value = state.method,
- )
- DetailLineView(
- modifier = Modifier.fillMaxWidth(),
- label = "Status",
- labelWidth = linesLabelWidth,
- ) {
- GrpcStatusView(status = state.status)
- }
- DetailLineTextView(
- modifier = Modifier.fillMaxWidth(),
- label = "Request Time",
- value = state.requestTimeFormatted,
- labelWidth = linesLabelWidth,
- )
- state.durationFormatted?.let {
- DetailLineTextView(
- modifier = Modifier.fillMaxWidth(),
- label = "Duration",
- value = it,
- labelWidth = linesLabelWidth,
- )
- }
- }
-
- // headers
- DetailSectionTitleView(
- isExpanded = isRequestHeadersExpanded,
- title = "Request Headers",
- onCopy = null,
- onToggle = {
- isRequestHeadersExpanded = it
- },
- )
- ExpandedSectionView(
- modifier = Modifier.fillMaxWidth(),
- isExpanded = isRequestHeadersExpanded,
- ) {
- DetailHeadersView(
- headers = state.requestHeaders,
- modifier = Modifier.fillMaxWidth(),
- labelWidth = headersLabelWidth,
- )
- }
-
- // body
- DetailSectionTitleView(
- isExpanded = isRequestBodyExpanded,
- title = "Request Body",
- onCopy = {
- onCopy(state.requestBody ?: "")
- },
- onToggle = {
- isRequestBodyExpanded = it
- },
- )
- ExpandedSectionView(
- modifier = Modifier.fillMaxWidth(),
- isExpanded = isRequestBodyExpanded,
- ) {
- CodeBlockView(
- code = state.requestBody ?: "",
- modifier = Modifier.fillMaxWidth(),
- )
- }
- }
-
- HorizontalDivider(
- modifier =
- Modifier
- .fillMaxWidth()
- .padding(start = 12.dp)
- .padding(vertical = 12.dp),
- )
-
- state.response?.let { response ->
- DetailSectionTitleView(
- isExpanded = isResponseExpanded,
- title = "Response",
- onCopy = null,
- onToggle = {
- isResponseExpanded = it
- },
- )
-
- ExpandedSectionView(
- modifier = Modifier.fillMaxWidth(),
- isExpanded = isResponseExpanded,
- ) {
- // headers
- DetailSectionTitleView(
- isExpanded = isResponseHeadersExpanded,
- title = "Response Headers",
- onCopy = null,
- onToggle = {
- isResponseHeadersExpanded = it
- },
- )
- ExpandedSectionView(
- modifier = Modifier.fillMaxWidth(),
- isExpanded = isResponseHeadersExpanded,
- ) {
- DetailHeadersView(
- headers = response.headers,
- modifier = Modifier.fillMaxWidth(),
- labelWidth = headersLabelWidth,
- )
- }
-
- when (val r = response.result) {
- is GrpcDetailViewState.DetailPayload.Failure -> {
- // body
- DetailSectionTitleView(
- isExpanded = isResponseBodyExpanded,
- title = "Response Error",
- onCopy = {
- onCopy(r.cause)
- },
- onToggle = {
- isResponseBodyExpanded = it
- },
- )
- ExpandedSectionView(
- modifier = Modifier.fillMaxWidth(),
- isExpanded = isResponseBodyExpanded,
- ) {
- CodeBlockView(
- code = r.cause,
- modifier = Modifier.fillMaxWidth(),
- )
- }
- }
- is GrpcDetailViewState.DetailPayload.Success -> {
- // body
- DetailSectionTitleView(
- isExpanded = isResponseBodyExpanded,
- title = "Response Body",
- onCopy = {
- onCopy(r.body)
- },
- onToggle = {
- isResponseBodyExpanded = it
- },
- )
- ExpandedSectionView(
- modifier = Modifier.fillMaxWidth(),
- isExpanded = isResponseBodyExpanded,
- ) {
- CodeBlockView(
- code = r.body,
- modifier = Modifier.fillMaxWidth(),
- )
- }
- }
- }
- }
- }
- }
-}
-
-@Preview
-@Composable
-private fun GrpcDetailViewPreview() {
- FloconTheme {
- GrpcDetailView(
- state = previewGrpcDetailViewState(),
- modifier = Modifier.padding(16.dp), // Padding pour la preview
- onCopy = { },
- )
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GrpcItemView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GrpcItemView.kt
deleted file mode 100644
index 6a844625..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GrpcItemView.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.view
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.unit.dp
-import io.github.openflocon.flocondesktop.common.ui.ContextualItem
-import io.github.openflocon.flocondesktop.common.ui.ContextualView
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcItemColumnWidths
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcItemViewState
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.OnGrpcItemUserAction
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.previewGrpcItemViewState
-import org.jetbrains.compose.ui.tooling.preview.Preview
-
-@Composable
-fun GrpcItemView(
- state: GrpcItemViewState,
- columnWidths: GrpcItemColumnWidths = GrpcItemColumnWidths(), // Default widths provided
- onUserAction: (OnGrpcItemUserAction) -> Unit,
- modifier: Modifier = Modifier,
-) {
- // Use MaterialTheme.typography for consistent text sizes
- val bodySmall = MaterialTheme.typography.bodySmall // Typically 12.sp or similar
- val labelSmall = MaterialTheme.typography.labelSmall // Even smaller, good for labels/tags
-
- ContextualView(
- listOf(
- ContextualItem(
- id = "copy_url",
- text = "Copy url",
- ),
- ContextualItem(
- id = "copy_method",
- text = "Copy Method",
- ),
- ContextualItem(
- id = "remove",
- text = "Remove",
- ),
- ContextualItem(
- id = "remove_lines_above",
- text = "Remove lines above ",
- ),
- ),
- onSelect = {
- when (it.id) {
- "copy_url" -> onUserAction(OnGrpcItemUserAction.CopyUrl(state))
- "copy_method" -> onUserAction(OnGrpcItemUserAction.CopyMethod(state))
- "remove" -> onUserAction(OnGrpcItemUserAction.Remove(state))
- "remove_lines_above" -> onUserAction(OnGrpcItemUserAction.RemoveLinesAbove(state))
- }
- },
- ) {
- Row(
- modifier = modifier
- .padding(horizontal = 8.dp, vertical = 4.dp) // Padding for the entire item
- .clip(shape = RoundedCornerShape(8.dp))
- .clickable(onClick = {
- onUserAction(OnGrpcItemUserAction.OnClicked(state))
- })
- .background(
- color = MaterialTheme.colorScheme.surface, // Use surface color for the item background
- )
- .padding(horizontal = 8.dp, vertical = 6.dp),
- // Inner padding for content
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.spacedBy(8.dp),
- ) {
- // Date - Fixed width from data class
- Box(
- modifier = Modifier.width(columnWidths.requestTimeFormatted),
- contentAlignment = Alignment.Center,
- ) {
- Text(
- state.requestTimeFormatted,
- style = bodySmall,
- color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f),
- )
- }
-
- // Request Url - Fixed width from data class
- Box(
- modifier = Modifier.weight(columnWidths.url),
- contentAlignment = Alignment.Center,
- ) {
- Text(
- state.url,
- style = bodySmall,
- color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f),
- )
- }
-
- // Method - Takes remaining space (weight)
- Box(
- modifier = Modifier.weight(columnWidths.method),
- ) {
- Text(
- state.method,
- style = bodySmall,
- color = MaterialTheme.colorScheme.onSurface,
- )
- }
-
- // Status - Fixed width from data class
-
- // TODO add a badge here
- Box(
- modifier = Modifier.width(columnWidths.status),
- contentAlignment = Alignment.Center,
- ) {
- GrpcStatusView(
- state.status,
- )
- }
-
- // Duration - Fixed width from data class
- Box(
- modifier = Modifier.width(columnWidths.durationFormatted),
- contentAlignment = Alignment.Center,
- ) {
- Text(
- state.durationFormatted ?: "", // reserve this space
- style = bodySmall,
- color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f),
- )
- }
- }
- }
-}
-
-@Composable
-@Preview
-private fun ItemViewPreview() {
- MaterialTheme {
- GrpcItemView(
- modifier = Modifier.fillMaxWidth(),
- state = previewGrpcItemViewState(),
- onUserAction = {},
- )
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GrpcStatusView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GrpcStatusView.kt
deleted file mode 100644
index 4d3baad5..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/GrpcStatusView.kt
+++ /dev/null
@@ -1,97 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.view
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.unit.TextUnit
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import io.github.openflocon.flocondesktop.common.ui.FloconTheme
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcItemViewState
-import org.jetbrains.compose.ui.tooling.preview.Preview
-
-// Custom colors for networkStatusUi/method views to integrate better with the theme
-val successBackground = Color(0xFF28A745).copy(alpha = 0.3f) // Muted green for success
-val successText = Color(0xFF28A745) // Brighter green for text
-
-val errorBackground = Color(0xFFDC3545).copy(alpha = 0.3f) // Muted red for error
-val errorText = Color(0xFFDC3545) // Brighter red for text
-
-private val waitingBackground = Color(0xFF6C757D).copy(alpha = 0.3f) // Muted gray for OTHER
-private val waitingText = Color(0xFF6C757D)
-
-@Composable
-fun GrpcStatusView(
- status: GrpcItemViewState.StatusViewState,
- textSize: TextUnit = 12.sp,
- modifier: Modifier = Modifier,
-) {
- Box(
- modifier =
- modifier
- .background(
- color = when (status) {
- is GrpcItemViewState.StatusViewState.Failure -> errorBackground
- is GrpcItemViewState.StatusViewState.Success -> successBackground
- is GrpcItemViewState.StatusViewState.Waiting -> waitingBackground
- },
- shape = RoundedCornerShape(20.dp), // Pill shape
- ).padding(horizontal = 8.dp, vertical = 4.dp),
- // Padding inside the tag
- contentAlignment = Alignment.Center, // Center content if Box is larger than text
- ) {
- Text(
- modifier = modifier,
- text = status.text,
- textAlign = TextAlign.Center,
- fontSize = textSize,
- color = when (status) {
- is GrpcItemViewState.StatusViewState.Failure -> errorText
- is GrpcItemViewState.StatusViewState.Success -> successText
- is GrpcItemViewState.StatusViewState.Waiting -> waitingText
- },
- style = MaterialTheme.typography.labelSmall, // Use typography for consistency
- )
- }
-}
-
-@Composable
-@Preview
-private fun StatusView_Preview() {
- FloconTheme {
- GrpcStatusView(
- status =
- GrpcItemViewState.StatusViewState.Success("OK"),
- )
- }
-}
-
-@Composable
-@Preview
-private fun StatusView_Failure_Preview() {
- FloconTheme {
- GrpcStatusView(
- status =
- GrpcItemViewState.StatusViewState.Failure("Error"),
- )
- }
-}
-
-@Composable
-@Preview
-private fun StatusView_Waiting_Preview() {
- FloconTheme {
- GrpcStatusView(
- status =
- GrpcItemViewState.StatusViewState.Waiting("Waiting"),
- )
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/header/NetworkFilterBar.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/header/NetworkFilterBar.kt
deleted file mode 100644
index bc40be9f..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/header/NetworkFilterBar.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.view.header
-
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberUpdatedState
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.unit.dp
-import flocondesktop.composeapp.generated.resources.Res
-import flocondesktop.composeapp.generated.resources.bin
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcItemViewState
-import io.github.openflocon.flocondesktop.features.network.ui.view.components.FilterBar
-import org.jetbrains.compose.resources.painterResource
-
-@Composable
-fun GrpcFilterBar(
- grpcItems: List,
- onItemsChange: (List) -> Unit,
- onResetClicked: () -> Unit,
- modifier: Modifier = Modifier,
-) {
- var filterText by remember {
- mutableStateOf("")
- }
- val onItemsChangeCallback by rememberUpdatedState(onItemsChange)
- val filteredGrpcItems: List =
- remember(grpcItems, filterText) {
- if (filterText.isBlank()) {
- grpcItems
- } else {
- grpcItems.filter {
- it.contains(filterText)
- }
- }
- }
-
- LaunchedEffect(filteredGrpcItems) {
- onItemsChangeCallback(filteredGrpcItems)
- }
-
- Row(
- modifier = modifier,
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.spacedBy(8.dp),
- ) {
- FilterBar(
- placeholderText = "Filter",
- modifier = Modifier.weight(1f),
- onTextChange = {
- filterText = it
- },
- )
- Box(
- modifier = Modifier
- .clip(RoundedCornerShape(4.dp))
- .clickable(onClick = onResetClicked)
- .padding(all = 8.dp),
- ) {
- Image(
- painter = painterResource(Res.drawable.bin),
- contentDescription = null,
- modifier = Modifier.size(20.dp),
- )
- }
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/header/NetworkItemHeaderView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/header/NetworkItemHeaderView.kt
deleted file mode 100644
index 9068e323..00000000
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/grpc/ui/view/header/NetworkItemHeaderView.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package io.github.openflocon.flocondesktop.features.grpc.ui.view.header
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
-import io.github.openflocon.flocondesktop.common.ui.FloconColors
-import io.github.openflocon.flocondesktop.features.grpc.ui.model.GrpcItemColumnWidths
-import io.github.openflocon.flocondesktop.features.network.ui.view.components.HeaderLabelItem
-
-@Composable
-fun GrpcItemHeaderView(
- modifier: Modifier = Modifier,
- columnWidths: GrpcItemColumnWidths = GrpcItemColumnWidths(), // Default widths provided
-) {
- Row(
- modifier =
- modifier
- .background(FloconColors.pannel)
- .padding(horizontal = 8.dp, vertical = 4.dp) // Padding for the entire item
- .padding(horizontal = 8.dp, vertical = 6.dp),
- horizontalArrangement = Arrangement.spacedBy(8.dp),
- verticalAlignment = Alignment.Bottom,
- ) {
- // Date - Fixed width from data class
- HeaderLabelItem(
- modifier = Modifier.width(columnWidths.requestTimeFormatted),
- text = "Request Time",
- )
- HeaderLabelItem(
- modifier = Modifier.weight(columnWidths.url),
- text = "Url",
- )
- HeaderLabelItem(
- modifier = Modifier.weight(columnWidths.method),
- contentAlignment = Alignment.TopStart,
- text = "Method",
- )
- HeaderLabelItem(
- modifier = Modifier.width(columnWidths.status),
- text = "Status",
- )
- HeaderLabelItem(
- modifier = Modifier.width(columnWidths.durationFormatted),
- text = "Duration",
- )
- }
-}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/FloconHttpRequestGenerator.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/FloconHttpRequestGenerator.kt
index aa90ff5f..83f38c91 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/FloconHttpRequestGenerator.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/FloconHttpRequestGenerator.kt
@@ -84,7 +84,6 @@ object FloconHttpRequestGenerator {
),
response = FloconHttpRequestDomainModel.Response(
body = responseBodyContent,
- httpCode = 200,
byteSize = 1500,
headers =
mapOf(
@@ -93,7 +92,9 @@ object FloconHttpRequestGenerator {
"X-Response-ID" to "res-$index",
),
),
- type = FloconHttpRequestDomainModel.Type.Http,
+ type = FloconHttpRequestDomainModel.Type.Http(
+ httpCode = 200,
+ ),
)
}
}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/NetworkRepositoryImpl.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/NetworkRepositoryImpl.kt
index bf95a01a..67bcbb1f 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/NetworkRepositoryImpl.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/NetworkRepositoryImpl.kt
@@ -8,7 +8,6 @@ import io.github.openflocon.flocondesktop.features.network.data.datasource.local
import io.github.openflocon.flocondesktop.features.network.data.model.FloconHttpRequestDataModel
import io.github.openflocon.flocondesktop.features.network.data.parser.graphql.computeIsGraphQlSuccess
import io.github.openflocon.flocondesktop.features.network.data.parser.graphql.extractGraphQl
-import io.github.openflocon.flocondesktop.features.network.data.parser.graphql.model.GraphQlResponseBody
import io.github.openflocon.flocondesktop.features.network.domain.model.FloconHttpRequestDomainModel
import io.github.openflocon.flocondesktop.features.network.domain.repository.NetworkImageRepository
import io.github.openflocon.flocondesktop.features.network.domain.repository.NetworkRepository
@@ -112,22 +111,30 @@ class NetworkRepositoryImpl(
byteSize = decoded.requestSize ?: 0L,
),
response = FloconHttpRequestDomainModel.Response(
- httpCode = decoded.responseHttpCode!!,
contentType = decoded.responseContentType,
body = decoded.responseBody,
headers = decoded.responseHeaders!!,
byteSize = decoded.responseSize ?: 0L,
),
type = when {
- graphQl != null -> FloconHttpRequestDomainModel.Type.GraphQl(
- query = graphQl.request.queryName ?: "anonymous",
- operationType = graphQl.request.operationType,
- isSuccess = computeIsGraphQlSuccess(
- responseHttpCode = decoded.responseHttpCode,
- response = graphQl.response,
- )
+ decoded.floconNetworkType == "grpc" -> FloconHttpRequestDomainModel.Type.Grpc(
+ responseStatus = decoded.responseGrpcStatus!!,
+ )
+ graphQl != null -> {
+ val httpCode = decoded.responseHttpCode!! // mandatory for graphQl
+ FloconHttpRequestDomainModel.Type.GraphQl(
+ query = graphQl.request.queryName ?: "anonymous",
+ operationType = graphQl.request.operationType,
+ isSuccess = computeIsGraphQlSuccess(
+ responseHttpCode = httpCode,
+ response = graphQl.response,
+ ),
+ httpCode = httpCode,
+ )
+ }
+ else -> FloconHttpRequestDomainModel.Type.Http(
+ httpCode = decoded.responseHttpCode!!, // mandatory for http
)
- else -> FloconHttpRequestDomainModel.Type.Http
},
)
} catch (t: Throwable) {
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkLocalDataSourceRoom.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkLocalDataSourceRoom.kt
index f5a6eb3b..6f50782f 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkLocalDataSourceRoom.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkLocalDataSourceRoom.kt
@@ -33,7 +33,7 @@ class NetworkLocalDataSourceRoom(
override fun observeRequests(deviceId: DeviceId): Flow> = floconHttpRequestDao
.observeRequests(deviceId)
.map { entities ->
- entities.map { it.toDomainModel() }
+ entities.mapNotNull { it.toDomainModel() }
}.flowOn(dispatcherProvider.data)
override suspend fun save(
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/mapper/Mapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/mapper/Mapper.kt
index 720d08fb..64e46141 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/mapper/Mapper.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/mapper/Mapper.kt
@@ -8,13 +8,32 @@ fun FloconHttpRequestDomainModel.toEntity(deviceId: String): FloconHttpRequestEn
uuid = this.uuid,
infos = this.toInfosEntity(),
deviceId = deviceId,
+ http = when (val t = this.type) {
+ is FloconHttpRequestDomainModel.Type.Http -> FloconHttpRequestEntity.HttpEmbedded(
+ responseHttpCode = t.httpCode,
+ )
+ is FloconHttpRequestDomainModel.Type.GraphQl,
+ is FloconHttpRequestDomainModel.Type.Grpc,
+ -> null
+ },
graphql = when (val t = this.type) {
- is FloconHttpRequestDomainModel.Type.GraphQl -> FloconHttpRequestEntity.FloconHttpRequestGraphQlEntity(
+ is FloconHttpRequestDomainModel.Type.GraphQl -> FloconHttpRequestEntity.GraphQlEmbedded(
query = t.query,
operationType = t.operationType,
isSuccess = t.isSuccess,
+ responseHttpCode = t.httpCode,
)
- else -> null
+ is FloconHttpRequestDomainModel.Type.Http,
+ is FloconHttpRequestDomainModel.Type.Grpc,
+ -> null
+ },
+ grpc = when (val t = this.type) {
+ is FloconHttpRequestDomainModel.Type.Grpc -> FloconHttpRequestEntity.GrpcEmbedded(
+ responseStatus = t.responseStatus,
+ )
+ is FloconHttpRequestDomainModel.Type.Http,
+ is FloconHttpRequestDomainModel.Type.GraphQl,
+ -> null
},
)
@@ -26,37 +45,47 @@ private fun FloconHttpRequestDomainModel.toInfosEntity(): FloconHttpRequestInfos
requestHeaders = this.request.headers,
requestBody = this.request.body,
requestByteSize = this.request.byteSize,
- responseHttpCode = this.response.httpCode,
responseContentType = this.response.contentType,
responseBody = this.response.body,
responseHeaders = this.response.headers,
responseByteSize = this.response.byteSize,
)
-fun FloconHttpRequestEntity.toDomainModel(): FloconHttpRequestDomainModel = FloconHttpRequestDomainModel(
- uuid = this.uuid,
- url = this.infos.url,
- durationMs = this.infos.durationMs,
- request = FloconHttpRequestDomainModel.Request(
- method = this.infos.method,
- startTime = this.infos.startTime,
- headers = this.infos.requestHeaders,
- body = this.infos.requestBody,
- byteSize = this.infos.requestByteSize,
- ),
- response = FloconHttpRequestDomainModel.Response(
- httpCode = this.infos.responseHttpCode,
- contentType = this.infos.responseContentType,
- body = this.infos.responseBody,
- headers = this.infos.responseHeaders,
- byteSize = this.infos.responseByteSize,
- ),
- type = when {
- this.graphql != null -> FloconHttpRequestDomainModel.Type.GraphQl(
- query = this.graphql.query,
- operationType = this.graphql.operationType,
- isSuccess = this.graphql.isSuccess,
- )
- else -> FloconHttpRequestDomainModel.Type.Http
- },
-)
+fun FloconHttpRequestEntity.toDomainModel(): FloconHttpRequestDomainModel? {
+ return FloconHttpRequestDomainModel(
+ uuid = this.uuid,
+ url = this.infos.url,
+ durationMs = this.infos.durationMs,
+ request = FloconHttpRequestDomainModel.Request(
+ method = this.infos.method,
+ startTime = this.infos.startTime,
+ headers = this.infos.requestHeaders,
+ body = this.infos.requestBody,
+ byteSize = this.infos.requestByteSize,
+ ),
+ response = FloconHttpRequestDomainModel.Response(
+ contentType = this.infos.responseContentType,
+ body = this.infos.responseBody,
+ headers = this.infos.responseHeaders,
+ byteSize = this.infos.responseByteSize,
+ ),
+ type = when {
+ this.graphql != null -> FloconHttpRequestDomainModel.Type.GraphQl(
+ query = this.graphql.query,
+ operationType = this.graphql.operationType,
+ isSuccess = this.graphql.isSuccess,
+ httpCode = this.graphql.responseHttpCode,
+ )
+
+ this.http != null -> FloconHttpRequestDomainModel.Type.Http(
+ httpCode = this.http.responseHttpCode,
+ )
+
+ this.grpc != null -> FloconHttpRequestDomainModel.Type.Grpc(
+ responseStatus = this.grpc.responseStatus,
+ )
+
+ else -> return null
+ },
+ )
+}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/FloconHttpRequestEntity.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/FloconHttpRequestEntity.kt
index 544f0e2e..aa857cd9 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/FloconHttpRequestEntity.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/FloconHttpRequestEntity.kt
@@ -13,12 +13,27 @@ data class FloconHttpRequestEntity(
val infos: FloconHttpRequestInfosEntity,
// if it's a graphql method, this item is not null
@Embedded(prefix = "graphql_")
- val graphql: FloconHttpRequestGraphQlEntity?,
+ val graphql: GraphQlEmbedded?,
+
+ @Embedded(prefix = "http_")
+ val http: HttpEmbedded?,
+
+ @Embedded(prefix = "grpc_")
+ val grpc: GrpcEmbedded?,
) {
- data class FloconHttpRequestGraphQlEntity(
+ data class GraphQlEmbedded(
val query: String,
val operationType: String,
val isSuccess: Boolean,
+ val responseHttpCode: Int,
+ )
+
+ data class HttpEmbedded(
+ val responseHttpCode: Int,
+ )
+
+ data class GrpcEmbedded(
+ val responseStatus: String,
)
}
@@ -30,7 +45,6 @@ data class FloconHttpRequestInfosEntity(
val requestHeaders: Map,
val requestBody: String?,
val requestByteSize: Long,
- val responseHttpCode: Int,
val responseContentType: String?,
val responseBody: String?,
val responseHeaders: Map,
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/model/FloconHttpRequestDataModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/model/FloconHttpRequestDataModel.kt
index 1ede1c10..63ae9148 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/model/FloconHttpRequestDataModel.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/model/FloconHttpRequestDataModel.kt
@@ -4,6 +4,8 @@ import kotlinx.serialization.Serializable
@Serializable
data class FloconHttpRequestDataModel(
+ val floconNetworkType: String? = null,
+
val url: String? = null,
val method: String? = null,
val startTime: Long? = null,
@@ -18,4 +20,5 @@ data class FloconHttpRequestDataModel(
val responseBody: String? = null,
val responseHeaders: Map? = null,
val responseSize: Long? = null,
+ val responseGrpcStatus: String? = null,
)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/parser/graphql/GraphQlParser.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/parser/graphql/GraphQlParser.kt
index fad767cd..e403c113 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/parser/graphql/GraphQlParser.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/parser/graphql/GraphQlParser.kt
@@ -59,8 +59,8 @@ private fun extractOperationName(query: String): String? {
fun computeIsGraphQlSuccess(
responseHttpCode: Int,
- response: GraphQlResponseBody?
+ response: GraphQlResponseBody?,
): Boolean {
- if(responseHttpCode !in 200..299) return false
+ if (responseHttpCode !in 200..299) return false
return response?.errors?.takeUnless { it.isEmpty() } == null
}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/FloconHttpRequestDomainModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/FloconHttpRequestDomainModel.kt
index f2359add..d2394f36 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/FloconHttpRequestDomainModel.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/FloconHttpRequestDomainModel.kt
@@ -17,7 +17,6 @@ data class FloconHttpRequestDomainModel(
)
data class Response(
- val httpCode: Int, // ex: 200
val contentType: String? = null,
val body: String? = null,
val headers: Map,
@@ -26,10 +25,16 @@ data class FloconHttpRequestDomainModel(
sealed interface Type {
data class GraphQl(
+ val httpCode: Int, // ex: 200
val query: String,
val operationType: String,
val isSuccess: Boolean,
) : Type
- data object Http : Type
+ data class Http(
+ val httpCode: Int, // ex: 200
+ ) : Type
+ data class Grpc(
+ val responseStatus: String,
+ ) : Type
}
}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/MethodUiMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/MethodUiMapper.kt
new file mode 100644
index 00000000..5931fe95
--- /dev/null
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/MethodUiMapper.kt
@@ -0,0 +1,23 @@
+package io.github.openflocon.flocondesktop.features.network.ui.mapper
+
+import io.github.openflocon.flocondesktop.features.network.domain.model.FloconHttpRequestDomainModel
+import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkMethodUi
+import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkMethodUi.OTHER
+
+fun getMethodUi(httpRequest: FloconHttpRequestDomainModel): NetworkMethodUi = when (val t = httpRequest.type) {
+ is FloconHttpRequestDomainModel.Type.GraphQl -> when (t.operationType.lowercase()) {
+ "query" -> NetworkMethodUi.GraphQl.QUERY
+ "mutation" -> NetworkMethodUi.GraphQl.MUTATION
+ else -> OTHER(t.operationType, icon = null)
+ }
+ is FloconHttpRequestDomainModel.Type.Http -> toHttpMethodUi(httpRequest.request.method)
+ is FloconHttpRequestDomainModel.Type.Grpc -> NetworkMethodUi.Grpc
+}
+
+fun toHttpMethodUi(httpMethod: String): NetworkMethodUi = when (httpMethod.lowercase()) {
+ "get" -> NetworkMethodUi.Http.GET
+ "put" -> NetworkMethodUi.Http.PUT
+ "post" -> NetworkMethodUi.Http.POST
+ "delete" -> NetworkMethodUi.Http.DELETE
+ else -> NetworkMethodUi.OTHER(httpMethod, icon = null)
+}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/NetworkDetailUiMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/NetworkDetailUiMapper.kt
index 613fb9e4..f2c8b25f 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/NetworkDetailUiMapper.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/NetworkDetailUiMapper.kt
@@ -5,11 +5,12 @@ import io.github.openflocon.flocondesktop.common.ui.JsonPrettyPrinter
import io.github.openflocon.flocondesktop.features.network.domain.model.FloconHttpRequestDomainModel
import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkDetailHeaderUi
import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkDetailViewState
+import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkStatusUi
fun toDetailUi(request: FloconHttpRequestDomainModel): NetworkDetailViewState = NetworkDetailViewState(
fullUrl = request.url,
- method = toMethodUi(request.request.method),
- status = toNetworkStatusUi(request.response.httpCode),
+ method = toDetailMethodUi(request),
+ status = toDetailNetworkStatusUi(request.type),
requestTimeFormatted = request.request.startTime.let { formatTimestamp(it) },
durationFormatted = formatDuration(request.durationMs),
// request
@@ -24,6 +25,13 @@ fun toDetailUi(request: FloconHttpRequestDomainModel): NetworkDetailViewState =
graphQlSection = graphQlSection(request),
)
+private fun toDetailNetworkStatusUi(type: FloconHttpRequestDomainModel.Type): NetworkStatusUi = when (type) {
+ is FloconHttpRequestDomainModel.Type.Grpc -> toGrpcNetworkStatusUi(type)
+ // here for grphql we want the http code, the graphql status will be displayed on the specific graphql section
+ is FloconHttpRequestDomainModel.Type.GraphQl -> toNetworkStatusUi(code = type.httpCode)
+ is FloconHttpRequestDomainModel.Type.Http -> toNetworkStatusUi(code = type.httpCode)
+}
+
fun graphQlSection(request: FloconHttpRequestDomainModel): NetworkDetailViewState.GraphQlSection? = (request.type as? FloconHttpRequestDomainModel.Type.GraphQl)?.let {
NetworkDetailViewState.GraphQlSection(
queryName = request.type.query,
@@ -43,3 +51,12 @@ fun toNetworkHeadersUi(headers: Map?): List NetworkDetailViewState.Method.MethodName(
+ name = request.request.method,
+ )
+ is FloconHttpRequestDomainModel.Type.GraphQl,
+ is FloconHttpRequestDomainModel.Type.Http,
+ -> NetworkDetailViewState.Method.Http(toHttpMethodUi(request.request.method))
+}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/NetworkUiMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/NetworkUiMapper.kt
index a0f9e585..55fb0a64 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/NetworkUiMapper.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/NetworkUiMapper.kt
@@ -3,8 +3,6 @@ package io.github.openflocon.flocondesktop.features.network.ui.mapper
import io.github.openflocon.flocondesktop.common.ui.ByteFormatter
import io.github.openflocon.flocondesktop.features.network.domain.model.FloconHttpRequestDomainModel
import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkItemViewState
-import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkMethodUi
-import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkStatusUi
import io.ktor.http.Url
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
@@ -55,56 +53,10 @@ fun toUi(httpRequest: FloconHttpRequestDomainModel): NetworkItemViewState = Netw
status = getStatusUi(httpRequest),
)
-fun toTypeUi(httpRequest: FloconHttpRequestDomainModel): NetworkItemViewState.NetworkTypeUi = when (val t = httpRequest.type) {
- is FloconHttpRequestDomainModel.Type.GraphQl -> NetworkItemViewState.NetworkTypeUi.GraphQl(
- queryName = t.query,
- )
-
- FloconHttpRequestDomainModel.Type.Http -> {
- val query = extractPath(httpRequest.url)
- NetworkItemViewState.NetworkTypeUi.Url(
- query = query,
- )
- }
-}
-
-fun getMethodUi(httpRequest: FloconHttpRequestDomainModel): NetworkMethodUi = when (val t = httpRequest.type) {
- is FloconHttpRequestDomainModel.Type.GraphQl -> when (t.operationType.lowercase()) {
- "query" -> NetworkMethodUi.GraphQl.QUERY
- "mutation" -> NetworkMethodUi.GraphQl.MUTATION
- else -> NetworkMethodUi.OTHER(t.operationType, icon = null)
- }
- is FloconHttpRequestDomainModel.Type.Http -> toMethodUi(httpRequest.request.method)
-}
-
-fun getStatusUi(httpRequest: FloconHttpRequestDomainModel): NetworkStatusUi = when (val t = httpRequest.type) {
- is FloconHttpRequestDomainModel.Type.GraphQl -> toGraphQlNetworkStatusUi(isSuccess = t.isSuccess)
- is FloconHttpRequestDomainModel.Type.Http -> toNetworkStatusUi(httpRequest.response.httpCode)
-}
-
fun getDomainUi(httpRequest: FloconHttpRequestDomainModel): String = when (val t = httpRequest.type) {
is FloconHttpRequestDomainModel.Type.GraphQl -> extractDomainAndPath(httpRequest.url)
is FloconHttpRequestDomainModel.Type.Http -> extractDomain(httpRequest.url)
-}
-
-fun toNetworkStatusUi(code: Int): NetworkStatusUi = NetworkStatusUi(
- text = code.toString(),
- isSuccess = code >= 200 && code < 300,
-)
-
-fun toGraphQlNetworkStatusUi(isSuccess: Boolean): NetworkStatusUi {
- return NetworkStatusUi(
- text = if (isSuccess) "Success" else "Error",
- isSuccess = isSuccess,
- )
-}
-
-fun toMethodUi(httpMethod: String): NetworkMethodUi = when (httpMethod.lowercase()) {
- "get" -> NetworkMethodUi.Http.GET
- "put" -> NetworkMethodUi.Http.PUT
- "post" -> NetworkMethodUi.Http.POST
- "delete" -> NetworkMethodUi.Http.DELETE
- else -> NetworkMethodUi.OTHER(httpMethod, icon = null)
+ is FloconHttpRequestDomainModel.Type.Grpc -> extractDomain(httpRequest.url)
}
fun formatDuration(duration: Double): String = duration.milliseconds.toString(unit = DurationUnit.MILLISECONDS)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/StatusUiMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/StatusUiMapper.kt
new file mode 100644
index 00000000..a3e3028e
--- /dev/null
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/StatusUiMapper.kt
@@ -0,0 +1,28 @@
+package io.github.openflocon.flocondesktop.features.network.ui.mapper
+
+import io.github.openflocon.flocondesktop.features.network.domain.model.FloconHttpRequestDomainModel
+import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkStatusUi
+
+fun getStatusUi(httpRequest: FloconHttpRequestDomainModel): NetworkStatusUi = when (val t = httpRequest.type) {
+ is FloconHttpRequestDomainModel.Type.GraphQl -> toGraphQlNetworkStatusUi(isSuccess = t.isSuccess)
+ is FloconHttpRequestDomainModel.Type.Http -> toNetworkStatusUi(t.httpCode)
+ is FloconHttpRequestDomainModel.Type.Grpc -> toGrpcNetworkStatusUi(t)
+}
+
+fun toNetworkStatusUi(code: Int): NetworkStatusUi = NetworkStatusUi(
+ text = code.toString(),
+ isSuccess = code >= 200 && code < 300,
+)
+
+fun toGraphQlNetworkStatusUi(isSuccess: Boolean): NetworkStatusUi = NetworkStatusUi(
+ text = if (isSuccess) "Success" else "Error",
+ isSuccess = isSuccess,
+)
+
+fun toGrpcNetworkStatusUi(type: FloconHttpRequestDomainModel.Type.Grpc): NetworkStatusUi {
+ val isSuccess = type.responseStatus == "OK"
+ return NetworkStatusUi(
+ text = type.responseStatus,
+ isSuccess = isSuccess,
+ )
+}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/TypeUiMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/TypeUiMapper.kt
new file mode 100644
index 00000000..1271e54f
--- /dev/null
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/TypeUiMapper.kt
@@ -0,0 +1,23 @@
+package io.github.openflocon.flocondesktop.features.network.ui.mapper
+
+import io.github.openflocon.flocondesktop.features.network.domain.model.FloconHttpRequestDomainModel
+import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkItemViewState
+
+fun toTypeUi(networkRequest: FloconHttpRequestDomainModel): NetworkItemViewState.NetworkTypeUi = when (val t = networkRequest.type) {
+ is FloconHttpRequestDomainModel.Type.GraphQl -> NetworkItemViewState.NetworkTypeUi.GraphQl(
+ queryName = t.query,
+ )
+
+ is FloconHttpRequestDomainModel.Type.Http -> {
+ val query = extractPath(networkRequest.url)
+ NetworkItemViewState.NetworkTypeUi.Url(
+ query = query,
+ )
+ }
+
+ is FloconHttpRequestDomainModel.Type.Grpc -> {
+ NetworkItemViewState.NetworkTypeUi.Grpc(
+ method = networkRequest.request.method,
+ )
+ }
+}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkDetailViewState.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkDetailViewState.kt
index e61699ac..858f92ee 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkDetailViewState.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkDetailViewState.kt
@@ -7,7 +7,8 @@ data class NetworkDetailViewState(
val fullUrl: String,
val requestTimeFormatted: String,
val durationFormatted: String,
- val method: NetworkMethodUi,
+
+ val method: Method,
val status: NetworkStatusUi,
val graphQlSection: GraphQlSection?,
@@ -21,9 +22,19 @@ data class NetworkDetailViewState(
val responseSize: String,
val responseHeaders: List,
) {
+ @Immutable
data class GraphQlSection(
val queryName: String,
val method: NetworkMethodUi,
val status: NetworkStatusUi,
)
+
+ @Immutable
+ sealed interface Method {
+ @Immutable
+ data class Http(val method: NetworkMethodUi) : Method
+
+ @Immutable
+ data class MethodName(val name: String) : Method
+ }
}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkItemViewState.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkItemViewState.kt
index 66424a95..a888ba89 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkItemViewState.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkItemViewState.kt
@@ -38,6 +38,13 @@ data class NetworkItemViewState(
) : NetworkTypeUi {
override fun contains(text: String): Boolean = queryName.contains(text, ignoreCase = true)
}
+
+ @Immutable
+ data class Grpc(
+ val method: String,
+ ) : NetworkTypeUi {
+ override fun contains(text: String): Boolean = method.contains(text, ignoreCase = true)
+ }
}
}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkMethodUi.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkMethodUi.kt
index a90230b0..35ea1dee 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkMethodUi.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/NetworkMethodUi.kt
@@ -44,6 +44,11 @@ sealed interface NetworkMethodUi {
}
}
+ data object Grpc : NetworkMethodUi {
+ override val text = "gRPC"
+ override val icon = null
+ }
+
data class OTHER(
override val text: String,
override val icon: DrawableResource?,
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/NetworkDetailView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/NetworkDetailView.kt
index ab919675..eff954c8 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/NetworkDetailView.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/NetworkDetailView.kt
@@ -11,6 +11,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -93,7 +94,19 @@ fun NetworkDetailView(
label = "Method",
labelWidth = linesLabelWidth,
) {
- MethodView(method = state.method)
+ when (val m = state.method) {
+ is NetworkDetailViewState.Method.Http -> MethodView(method = m.method)
+ is NetworkDetailViewState.Method.MethodName -> {
+ Text(
+ text = m.name,
+ style = MaterialTheme.typography.bodySmall,
+ color = MaterialTheme.colorScheme.onSurface,
+ modifier = Modifier.weight(2f)
+ .background(color = FloconColors.pannel.copy(alpha = 0.8f), shape = RoundedCornerShape(4.dp))
+ .padding(horizontal = 8.dp, vertical = 6.dp),
+ )
+ }
+ }
}
DetailLineView(
modifier = Modifier.fillMaxWidth(),
@@ -269,7 +282,7 @@ private fun NetworkDetailViewPreview() {
state =
NetworkDetailViewState(
fullUrl = "http://www.google.com",
- method = NetworkMethodUi.Http.GET,
+ method = NetworkDetailViewState.Method.Http(NetworkMethodUi.Http.GET),
status =
NetworkStatusUi(
text = "200",
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/NetworkItemView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/NetworkItemView.kt
index e977afbb..c03544f9 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/NetworkItemView.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/NetworkItemView.kt
@@ -36,7 +36,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
data class NetworkItemColumnWidths(
val dateWidth: Dp = 90.dp,
val methodWidth: Dp = 70.dp,
- val statusCodeWidth: Dp = 60.dp,
+ val statusCodeWidth: Dp = 65.dp,
val requestSizeWidth: Dp = 65.dp,
val responseSizeWidth: Dp = 65.dp,
val timeWidth: Dp = 60.dp,
@@ -151,6 +151,19 @@ fun NetworkItemView(
.padding(horizontal = 8.dp, vertical = 6.dp),
)
}
+
+ is NetworkItemViewState.NetworkTypeUi.Grpc -> {
+ Text(
+ text = type.method,
+ maxLines = 2,
+ overflow = TextOverflow.Ellipsis,
+ style = bodySmall,
+ color = MaterialTheme.colorScheme.onSurface,
+ modifier = Modifier.weight(2f)
+ .background(color = FloconColors.pannel.copy(alpha = 0.8f), shape = RoundedCornerShape(4.dp))
+ .padding(horizontal = 8.dp, vertical = 6.dp),
+ )
+ }
}
}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/components/MethodView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/components/MethodView.kt
index 448574ff..8058927f 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/components/MethodView.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/components/MethodView.kt
@@ -40,8 +40,11 @@ private val deleteMethodText = Color(0xFFDC3545)
private val otherMethodBackground = Color(0xFF6C757D).copy(alpha = 0.3f) // Muted gray for OTHER
private val otherMethodText = Color(0xFF6C757D)
-private val grpcQueryMethodBackground = Color(0XAAE235A9).copy(alpha = 0.8f) // Muted gray for OTHER
-private val grpcQueryMethodText = Color(0XAAFFFFFF)
+private val graphQlQueryMethodBackground = Color(0XAAE235A9).copy(alpha = 0.8f) // Muted gray for OTHER
+private val graphQlQueryMethodText = Color(0XAAFFFFFF)
+
+private val grpcMethodBackground = Color(0xff71CCCB)
+private val grpcMethodText = Color(0xff244B5A)
@Composable
fun MethodView(
@@ -56,8 +59,9 @@ fun MethodView(
is NetworkMethodUi.OTHER -> otherMethodBackground to otherMethodText
is NetworkMethodUi.Http.POST -> postMethodBackground to postMethodText
is NetworkMethodUi.Http.PUT -> putMethodBackground to putMethodText
- is NetworkMethodUi.GraphQl.QUERY -> grpcQueryMethodBackground to grpcQueryMethodText
- is NetworkMethodUi.GraphQl.MUTATION -> grpcQueryMethodBackground to grpcQueryMethodText
+ is NetworkMethodUi.GraphQl.QUERY -> graphQlQueryMethodBackground to graphQlQueryMethodText
+ is NetworkMethodUi.GraphQl.MUTATION -> graphQlQueryMethodBackground to graphQlQueryMethodText
+ is NetworkMethodUi.Grpc -> grpcMethodBackground to grpcMethodText
}
NetworkTag(
@@ -123,3 +127,11 @@ private fun MethodView_GraphQlQuery_Preview() {
MethodView(method = NetworkMethodUi.GraphQl.QUERY)
}
}
+
+@Composable
+@Preview
+private fun MethodView_Ggrpc_Preview() {
+ FloconTheme {
+ MethodView(method = NetworkMethodUi.Grpc)
+ }
+}
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/components/StatusView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/components/StatusView.kt
index 0a3f398d..1d462f48 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/components/StatusView.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/components/StatusView.kt
@@ -1,11 +1,13 @@
package io.github.openflocon.flocondesktop.features.network.ui.view.components
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.text.BasicText
+import androidx.compose.foundation.text.TextAutoSize
import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
import io.github.openflocon.flocondesktop.common.ui.FloconTheme
@@ -25,18 +27,22 @@ fun StatusView(
textSize: TextUnit = 12.sp,
modifier: Modifier = Modifier,
) {
- Text(
- modifier = modifier,
- text = status.text.toString(),
- textAlign = TextAlign.Center,
- fontSize = textSize,
- color =
- when (status.isSuccess) {
- true -> successTagText
- false -> errorTagText
- },
- style = MaterialTheme.typography.labelSmall, // Use typography for consistency
- )
+ Box(modifier = modifier, contentAlignment = Alignment.Center) {
+ BasicText(
+ text = status.text.toString(),
+ autoSize = TextAutoSize.StepBased(
+ maxFontSize = textSize,
+ minFontSize = 8.sp,
+ ),
+ maxLines = 1,
+ style = MaterialTheme.typography.labelSmall.copy(
+ color = when (status.isSuccess) {
+ true -> successTagText
+ false -> errorTagText
+ },
+ ),
+ )
+ }
}
@Composable
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/MainScreen.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/MainScreen.kt
index f2b4882c..12e7a9e7 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/MainScreen.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/MainScreen.kt
@@ -17,7 +17,6 @@ import io.github.openflocon.flocondesktop.features.dashboard.ui.view.DashboardSc
import io.github.openflocon.flocondesktop.features.database.ui.view.DatabaseScreen
import io.github.openflocon.flocondesktop.features.deeplinks.ui.view.DeeplinkScreen
import io.github.openflocon.flocondesktop.features.files.ui.view.FilesScreen
-import io.github.openflocon.flocondesktop.features.grpc.ui.view.GRPCScreen
import io.github.openflocon.flocondesktop.features.images.ui.view.ImagesScreen
import io.github.openflocon.flocondesktop.features.network.ui.view.NetworkScreen
import io.github.openflocon.flocondesktop.features.sharedpreferences.ui.view.SharedPreferencesScreen
@@ -93,12 +92,6 @@ private fun MainScreen(
.fillMaxSize(),
)
- SubScreen.GRPC ->
- GRPCScreen(
- modifier = Modifier
- .fillMaxSize(),
- )
-
SubScreen.Files ->
FilesScreen(
modifier = Modifier
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/MainViewModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/MainViewModel.kt
index 0e2c9b89..4e65849a 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/MainViewModel.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/MainViewModel.kt
@@ -75,7 +75,6 @@ fun buildLeftPanelState(selectedId: String?) = LeftPanelState(
items = listOf(
item(subScreen = SubScreen.Network, selectedId = selectedId),
item(subScreen = SubScreen.Images, selectedId = selectedId),
- item(subScreen = SubScreen.GRPC, selectedId = selectedId),
),
),
LeftPannelSection(
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/model/SubScreen.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/model/SubScreen.kt
index 05dc9328..d0fb1dfa 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/model/SubScreen.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/model/SubScreen.kt
@@ -7,8 +7,6 @@ enum class SubScreen {
Network,
Images, // network images
- GRPC,
-
// storage
Database,
Files, // device files (context.cache, context.files)
diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/view/SubScreenSelectorItem.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/view/SubScreenSelectorItem.kt
index c3f3ef9b..26129527 100644
--- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/view/SubScreenSelectorItem.kt
+++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/main/ui/view/SubScreenSelectorItem.kt
@@ -6,7 +6,6 @@ import flocondesktop.composeapp.generated.resources.dashboard
import flocondesktop.composeapp.generated.resources.database
import flocondesktop.composeapp.generated.resources.deeplinks
import flocondesktop.composeapp.generated.resources.files
-import flocondesktop.composeapp.generated.resources.grpc
import flocondesktop.composeapp.generated.resources.images
import flocondesktop.composeapp.generated.resources.network
import flocondesktop.composeapp.generated.resources.settings
@@ -23,7 +22,6 @@ fun SubScreen.displayName(): String = when (this) {
SubScreen.Files -> "Files"
SubScreen.Tables -> "Tables"
SubScreen.Images -> "Images"
- SubScreen.GRPC -> "gRPC"
SubScreen.SharedPreferences -> "SharedPreferences"
SubScreen.Dashboard -> "Dashboard"
SubScreen.Settings -> "Settings"
@@ -37,7 +35,6 @@ fun SubScreen.icon(): DrawableResource = when (this) {
SubScreen.Database -> Res.drawable.database
SubScreen.Files -> Res.drawable.files
SubScreen.Tables -> Res.drawable.tables
- SubScreen.GRPC -> Res.drawable.grpc
SubScreen.Images -> Res.drawable.images
SubScreen.SharedPreferences -> Res.drawable.sharedpreference
SubScreen.Settings -> Res.drawable.settings