diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..0503f08f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,14 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+[*]
+
+indent_style = space
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
\ No newline at end of file
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
new file mode 100644
index 00000000..664c03dc
--- /dev/null
+++ b/.github/actions/setup/action.yml
@@ -0,0 +1,13 @@
+name: 'Setup'
+description: 'Setup Java, checkout and setup gradle'
+runs:
+ using: "composite"
+ steps:
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+
+ - name: Gradle cache
+ uses: gradle/actions/setup-gradle@v3
diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
new file mode 100644
index 00000000..066aa74e
--- /dev/null
+++ b/.github/workflows/validate.yml
@@ -0,0 +1,69 @@
+name: Validate
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+
+jobs:
+ build:
+ name: Build
+ runs-on: macos-latest
+
+ strategy:
+ matrix:
+ type: [Debug, Release]
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup
+ uses: ./.github/actions/setup
+
+ - name: Build Android
+ run: ./gradlew assemble${{ matrix.type }}
+
+ - name: Build iOS
+ run: ./gradlew link${{ matrix.type }}FrameworkIosSimulatorArm64
+
+ android-lint:
+ name: Android Lint
+ runs-on: macos-latest
+ needs: [ build ]
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup
+ uses: ./.github/actions/setup
+
+ - name: Run lint
+ run: ./gradlew lint
+
+ - name: Uploads test reports
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: android-lint-report
+ path: composeApp/build/reports/
+
+ kotlin-lint:
+ name: Kotlin Lint
+ runs-on: macos-latest
+ needs: [ build ]
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup
+ uses: ./.github/actions/setup
+
+ - name: Run lint
+ run: ./gradlew ktlintCheck
+
+ - name: Uploads test reports
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: android-lint-report
+ path: composeApp/build/reports/ktlint/
diff --git a/build.gradle.kts b/build.gradle.kts
index f49eedf2..ee4a7838 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -7,4 +7,5 @@ plugins {
alias(libs.plugins.jetbrainsComposeCompiler) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.cocoapods) apply false
+ alias(libs.plugins.ktlint) apply false
}
\ No newline at end of file
diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts
index 7df336d5..cb16a249 100644
--- a/composeApp/build.gradle.kts
+++ b/composeApp/build.gradle.kts
@@ -8,6 +8,7 @@ plugins {
alias(libs.plugins.jetbrainsComposeCompiler)
alias(libs.plugins.cocoapods)
alias(libs.plugins.kotlinSerialization)
+ alias(libs.plugins.ktlint)
}
kotlin {
@@ -32,11 +33,12 @@ kotlin {
framework {
baseName = "composeApp"
isStatic = true
+ binaryOption("bundleId", "composeApp")
}
podfile = project.file("../iosApp/Podfile")
}
-
+
sourceSets {
androidMain.dependencies {
implementation(libs.compose.ui.tooling.preview)
@@ -53,6 +55,10 @@ kotlin {
implementation(compose.components.uiToolingPreview)
implementation(libs.kotlin.serialization)
}
+
+ all {
+ languageSettings.optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
+ }
}
@OptIn(ExperimentalKotlinGradlePluginApi::class)
@@ -96,4 +102,18 @@ android {
dependencies {
debugImplementation(libs.compose.ui.tooling)
}
+ android {
+ lint {
+ warningsAsErrors = true
+ disable += "AndroidGradlePluginVersion"
+ }
+ }
+}
+
+ktlint {
+ filter {
+ exclude("**/generated/**")
+ include("**/kotlin/**")
+ }
+ additionalEditorconfig.put("ktlint_function_naming_ignore_when_annotated_with", "Composable")
}
diff --git a/composeApp/src/androidMain/kotlin/org/ooni/engine/AndroidOonimkallBridge.kt b/composeApp/src/androidMain/kotlin/org/ooni/engine/AndroidOonimkallBridge.kt
index 1d3f9d41..0729a380 100644
--- a/composeApp/src/androidMain/kotlin/org/ooni/engine/AndroidOonimkallBridge.kt
+++ b/composeApp/src/androidMain/kotlin/org/ooni/engine/AndroidOonimkallBridge.kt
@@ -13,4 +13,4 @@ class AndroidOonimkallBridge : OonimkallBridge {
override fun waitForNextEvent() = task.waitForNextEvent()
}
}
-}
\ No newline at end of file
+}
diff --git a/composeApp/src/androidMain/kotlin/org/ooni/probe/AndroidApplication.kt b/composeApp/src/androidMain/kotlin/org/ooni/probe/AndroidApplication.kt
index e1a28d8b..0802c08b 100644
--- a/composeApp/src/androidMain/kotlin/org/ooni/probe/AndroidApplication.kt
+++ b/composeApp/src/androidMain/kotlin/org/ooni/probe/AndroidApplication.kt
@@ -2,4 +2,4 @@ package org.ooni.probe
import android.app.Application
-class AndroidApplication : Application()
\ No newline at end of file
+class AndroidApplication : Application()
diff --git a/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml b/composeApp/src/androidMain/res/drawable/ic_launcher_foreground.xml
similarity index 100%
rename from composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml
rename to composeApp/src/androidMain/res/drawable/ic_launcher_foreground.xml
diff --git a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml
index eca70cfe..6f3b755b 100644
--- a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -2,4 +2,5 @@
+
\ No newline at end of file
diff --git a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml
index eca70cfe..6f3b755b 100644
--- a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -2,4 +2,5 @@
+
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/engine/Engine.kt b/composeApp/src/commonMain/kotlin/org/ooni/engine/Engine.kt
index e3acc575..76c2f90d 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/engine/Engine.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/engine/Engine.kt
@@ -10,31 +10,32 @@ import kotlin.math.roundToInt
class Engine(
private val bridge: OonimkallBridge,
private val json: Json,
- private val baseFilePath: String
+ private val baseFilePath: String,
) {
+ fun startTask(taskSettings: TaskSettings): Flow =
+ channelFlow {
+ val finalSettings =
+ taskSettings.copy(
+ stateDir = baseFilePath,
+ tunnelDir = baseFilePath,
+ tempDir = baseFilePath,
+ assetsDir = baseFilePath,
+ )
- fun startTask(taskSettings: TaskSettings): Flow = channelFlow {
- val finalSettings = taskSettings.copy(
- stateDir = baseFilePath,
- tunnelDir = baseFilePath,
- tempDir = baseFilePath,
- assetsDir = baseFilePath,
- )
-
- val task = bridge.startTask(json.encodeToString(finalSettings))
+ val task = bridge.startTask(json.encodeToString(finalSettings))
- while (!task.isDone()) {
- val eventJson = task.waitForNextEvent()
- val eventResult = json.decodeFromString(eventJson)
- eventResult.toTaskEvent()?.let { send(it) }
- }
+ while (!task.isDone()) {
+ val eventJson = task.waitForNextEvent()
+ val eventResult = json.decodeFromString(eventJson)
+ eventResult.toTaskEvent()?.let { send(it) }
+ }
- invokeOnClose {
- if (it is CancellationException) {
- task.interrupt()
+ invokeOnClose {
+ if (it is CancellationException) {
+ task.interrupt()
+ }
}
}
- }
private fun EventResult.toTaskEvent(): TaskEvent? =
when (key) {
@@ -46,20 +47,22 @@ class Engine(
value?.percentage?.let { percentageValue ->
TaskEvent.Progress(
percentage = (percentageValue * 100.0).roundToInt(),
- message = value?.message
+ message = value?.message,
)
}
- "log" -> value?.message?.let { message ->
- TaskEvent.Log(
- level = value?.log_level,
- message = message
- )
- }
+ "log" ->
+ value?.message?.let { message ->
+ TaskEvent.Log(
+ level = value?.logLevel,
+ message = message,
+ )
+ }
- "status.report_create" -> value?.report_id?.let {
- TaskEvent.ReportCreate(reportId = it)
- }
+ "status.report_create" ->
+ value?.reportId?.let {
+ TaskEvent.ReportCreate(reportId = it)
+ }
"task_terminated" -> TaskEvent.TaskTerminated
@@ -67,4 +70,4 @@ class Engine(
else -> null
}
-}
\ No newline at end of file
+}
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/engine/EventResult.kt b/composeApp/src/commonMain/kotlin/org/ooni/engine/EventResult.kt
index e48ca6a6..d81e235f 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/engine/EventResult.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/engine/EventResult.kt
@@ -1,29 +1,64 @@
package org.ooni.engine
+import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
class EventResult {
+ @SerialName("key")
var key: String? = null
+
+ @SerialName("value")
var value: Value? = null
@Serializable
class Value {
+ @SerialName("key")
var key: Double = 0.0
- var log_level: String? = null
+
+ @SerialName("log_level")
+ var logLevel: String? = null
+
+ @SerialName("message")
var message: String? = null
+
+ @SerialName("percentage")
var percentage: Double = 0.0
- var json_str: String? = null
+
+ @SerialName("json_str")
+ var jsonStr: String? = null
+
+ @SerialName("idx")
var idx: Int = 0
- var report_id: String? = null
- var probe_ip: String? = null
- var probe_asn: String? = null
- var probe_cc: String? = null
- var probe_network_name: String? = null
- var downloaded_kb: Double = 0.0
- var uploaded_kb: Double = 0.0
+
+ @SerialName("report_id")
+ var reportId: String? = null
+
+ @SerialName("probe_ip")
+ var probeIp: String? = null
+
+ @SerialName("probe_asn")
+ var probeAsn: String? = null
+
+ @SerialName("probe_cc")
+ var probeCc: String? = null
+
+ @SerialName("probe_network_name")
+ var probeNetworkName: String? = null
+
+ @SerialName("downloaded_kb")
+ var downloadedKb: Double = 0.0
+
+ @SerialName("uploaded_kb")
+ var uploadedKb: Double = 0.0
+
+ @SerialName("input")
var input: String? = null
+
+ @SerialName("failure")
var failure: String? = null
- var orig_key: String? = null
+
+ @SerialName("orig_key")
+ var origKey: String? = null
}
}
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/engine/OonimkallBridge.kt b/composeApp/src/commonMain/kotlin/org/ooni/engine/OonimkallBridge.kt
index c498c54f..fb401cf6 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/engine/OonimkallBridge.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/engine/OonimkallBridge.kt
@@ -5,7 +5,9 @@ interface OonimkallBridge {
interface Task {
fun interrupt()
+
fun isDone(): Boolean
+
fun waitForNextEvent(): String
}
-}
\ No newline at end of file
+}
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskEvent.kt b/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskEvent.kt
index b4a8c210..5a75a01f 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskEvent.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskEvent.kt
@@ -3,25 +3,25 @@ package org.ooni.engine
sealed interface TaskEvent {
data class Log(
val level: String?,
- val message: String
- ): TaskEvent
+ val message: String,
+ ) : TaskEvent
data object Started : TaskEvent
data class ReportCreate(
- val reportId: String
+ val reportId: String,
) : TaskEvent
data class Progress(
val percentage: Int,
- val message: String?
- ): TaskEvent
+ val message: String?,
+ ) : TaskEvent
data object StatusEnd : TaskEvent
data object TaskTerminated : TaskEvent
data class FailureStartup(
- val message: String?
- ): TaskEvent
-}
\ No newline at end of file
+ val message: String?,
+ ) : TaskEvent
+}
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskSettings.kt b/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskSettings.kt
index 5b250811..4bb25915 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskSettings.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskSettings.kt
@@ -13,12 +13,12 @@ data class TaskSettings(
@SerialName("temp_dir") val tempDir: String? = null,
@SerialName("tunnel_dir") val tunnelDir: String? = null,
@SerialName("assets_dir") val assetsDir: String? = null,
- @SerialName("options") val options: Options = Options()
+ @SerialName("options") val options: Options = Options(),
) {
@Serializable
data class Options(
@SerialName("no_collector") val noCollector: Boolean = true,
@SerialName("software_name") val softwareName: String = "Probe Multiplatform",
- @SerialName("software_version") val softwareVersion: String = "1.0"
+ @SerialName("software_version") val softwareVersion: String = "1.0",
)
-}
\ No newline at end of file
+}
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt
index d28fc18c..86cd973c 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt
@@ -3,26 +3,24 @@ package org.ooni.probe
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import org.ooni.probe.di.Dependencies
import org.jetbrains.compose.ui.tooling.preview.Preview
+import org.ooni.probe.di.Dependencies
import org.ooni.probe.ui.Theme
import org.ooni.probe.ui.main.MainScreen
@Composable
@Preview
-fun App(
- dependencies: Dependencies
-) {
+fun App(dependencies: Dependencies) {
Theme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background,
) {
MainScreen(
- dependencies.mainViewModel
+ dependencies.mainViewModel,
)
}
}
-}
\ No newline at end of file
+}
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/di/Dependencies.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/di/Dependencies.kt
index 65759bca..8309f950 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/probe/di/Dependencies.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/di/Dependencies.kt
@@ -9,7 +9,6 @@ class Dependencies(
private val oonimkallBridge: OonimkallBridge,
private val baseFileDir: String,
) {
-
private val json by lazy {
Json {
encodeDefaults = true
@@ -20,5 +19,4 @@ class Dependencies(
private val engine by lazy { Engine(oonimkallBridge, json, baseFileDir) }
val mainViewModel by lazy { MainViewModel(engine) }
-
-}
\ No newline at end of file
+}
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/Theme.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/Theme.kt
index aabcb76d..ca9a42a8 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/Theme.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/Theme.kt
@@ -10,84 +10,58 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
-val PrimaryColor = Color(0xff0588cb)
-val PrimaryLightColor = PrimaryColor.copy(alpha = 0.75f)
-
-val SecondaryColor = Color(0xff5db8fe)
-val SecondaryLightColor = SecondaryColor.copy(alpha = 0.75f)
-
-// TODO: fix the color theme
-
-val PrimaryTextColor = Color(0xffffffff)
-val SecondaryTextColor = Color(0xff000000)
-
-// val SurfaceDark = Color(0xFF1f1f1f)
-// val SurfaceDark = Color(0xFF121212)
-val SurfaceDark = Color(0xFF161616)
-
-val SurfaceLight = Color(0xFFFFFFFF)
-
-val BackgroundLightColor = Color(0xffF1F0F5)
-
-val BackgroundDarkColor = Color(0xff010100)
-
-val ErrorColor = Color(0xFFFF8989)
-val OnErrorColor = Color(0xFF000000)
-
-val SuccessColor = Color(0xFF34b233)
-
-const val SessionColor = 0xFfBA4949
-const val ShortBreakColor = 0xFf38858A
-const val LongBreakColor = 0xFf397097
-
-const val Red = 0xFFFF0000
-const val Orange = 0xFFFFA500
-const val Blue = 0xFF0000FF
-const val Green = 0xFF00FF00
-
-const val LightGreen = 0xFF90EE90
-const val Yellow = 0xFFFFFF00
-const val LightBlue = 0xFFADD8E6
-const val Pink = 0xFFFFC0CB
-
-private val LightColors = lightColorScheme(
- primary = PrimaryColor,
- onPrimary = PrimaryTextColor,
- secondary = SecondaryColor,
- onSecondary = SecondaryTextColor,
- tertiary = PrimaryLightColor,
- onTertiary = PrimaryTextColor,
- background = BackgroundLightColor,
- onBackground = Color.Black,
- surface = SurfaceLight,
- onSurface = Color.Black,
- surfaceVariant = SurfaceLight,
- onSurfaceVariant = Color.Black,
- secondaryContainer = PrimaryColor,
- onSecondaryContainer = Color.White,
- error = ErrorColor,
- onError = OnErrorColor,
-)
-
-private val DarkColors = darkColorScheme(
- primary = PrimaryColor,
- onPrimary = PrimaryTextColor,
- secondary = SecondaryLightColor,
- onSecondary = SecondaryTextColor,
- tertiary = PrimaryLightColor,
- onTertiary = PrimaryTextColor,
- background = BackgroundDarkColor,
- onBackground = Color.White,
- surface = SurfaceDark,
- onSurface = Color.White,
- surfaceVariant = SurfaceDark,
- onSurfaceVariant = Color.White,
- secondaryContainer = PrimaryColor,
- onSecondaryContainer = Color.White,
- error = ErrorColor,
- onError = OnErrorColor,
-)
+private val primaryColor = Color(0xff0588cb)
+private val primaryLightColor = primaryColor.copy(alpha = 0.75f)
+private val secondaryColor = Color(0xff5db8fe)
+private val secondaryLightColor = secondaryColor.copy(alpha = 0.75f)
+private val primaryTextColor = Color(0xffffffff)
+private val secondaryTextColor = Color(0xff000000)
+private val surfaceDark = Color(0xFF161616)
+private val surfaceLight = Color(0xFFFFFFFF)
+private val backgroundLightColor = Color(0xffF1F0F5)
+private val backgroundDarkColor = Color(0xff010100)
+private val errorColor = Color(0xFFFF8989)
+private val onErrorColor = Color(0xFF000000)
+
+private val LightColors =
+ lightColorScheme(
+ primary = primaryColor,
+ onPrimary = primaryTextColor,
+ secondary = secondaryColor,
+ onSecondary = secondaryTextColor,
+ tertiary = primaryLightColor,
+ onTertiary = primaryTextColor,
+ background = backgroundLightColor,
+ onBackground = Color.Black,
+ surface = surfaceLight,
+ onSurface = Color.Black,
+ surfaceVariant = surfaceLight,
+ onSurfaceVariant = Color.Black,
+ secondaryContainer = primaryColor,
+ onSecondaryContainer = Color.White,
+ error = errorColor,
+ onError = onErrorColor,
+ )
+private val DarkColors =
+ darkColorScheme(
+ primary = primaryColor,
+ onPrimary = primaryTextColor,
+ secondary = secondaryLightColor,
+ onSecondary = secondaryTextColor,
+ tertiary = primaryLightColor,
+ onTertiary = primaryTextColor,
+ background = backgroundDarkColor,
+ onBackground = Color.White,
+ surface = surfaceDark,
+ onSurface = Color.White,
+ surfaceVariant = surfaceDark,
+ onSurfaceVariant = Color.White,
+ secondaryContainer = primaryColor,
+ onSecondaryContainer = Color.White,
+ error = errorColor,
+ onError = onErrorColor,
+ )
@Composable
internal fun Theme(
@@ -95,11 +69,12 @@ internal fun Theme(
content: @Composable () -> Unit,
) {
val colorScheme = if (useDarkTheme) DarkColors else LightColors
- val shapes = Shapes(
- small = RoundedCornerShape(4.dp),
- medium = RoundedCornerShape(8.dp),
- large = RoundedCornerShape(12.dp),
- )
+ val shapes =
+ Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(8.dp),
+ large = RoundedCornerShape(12.dp),
+ )
val typography = MaterialTheme.typography
MaterialTheme(
@@ -108,4 +83,4 @@ internal fun Theme(
typography,
content,
)
-}
\ No newline at end of file
+}
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/main/MainScreen.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/main/MainScreen.kt
index 753f7a87..548804d7 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/main/MainScreen.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/main/MainScreen.kt
@@ -12,24 +12,23 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
@Composable
-fun MainScreen(
- viewModel: MainViewModel
-) {
+fun MainScreen(viewModel: MainViewModel) {
val state by viewModel.state.collectAsState()
Column {
Button(
onClick = { viewModel.onEvent(MainViewModel.Event.StartClick) },
- enabled = !state.isRunning
+ enabled = !state.isRunning,
) {
Text("Run Test")
}
Text(
text = state.log,
- modifier = Modifier
- .fillMaxSize()
- .verticalScroll(rememberScrollState())
+ modifier =
+ Modifier
+ .fillMaxSize()
+ .verticalScroll(rememberScrollState()),
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/main/MainViewModel.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/main/MainViewModel.kt
index 643dfb32..c19eeef1 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/main/MainViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/main/MainViewModel.kt
@@ -16,7 +16,7 @@ import org.ooni.engine.Engine
import org.ooni.engine.TaskSettings
class MainViewModel(
- private val engine: Engine
+ private val engine: Engine,
) {
private val events = MutableSharedFlow(extraBufferCapacity = 1)
@@ -53,7 +53,7 @@ class MainViewModel(
data class State(
val isRunning: Boolean = false,
- val log: String = ""
+ val log: String = "",
)
sealed interface Event {
@@ -61,10 +61,11 @@ class MainViewModel(
}
companion object {
- val TASK_SETTINGS = TaskSettings(
- name = "web_connectivity",
- inputs = listOf("https://ooni.org"),
- logLevel = "DEBUG2"
- )
+ val TASK_SETTINGS =
+ TaskSettings(
+ name = "web_connectivity",
+ inputs = listOf("https://ooni.org"),
+ logLevel = "DEBUG2",
+ )
}
}
diff --git a/composeApp/src/iosMain/kotlin/org/ooni/probe/MainViewController.kt b/composeApp/src/iosMain/kotlin/org/ooni/probe/MainViewController.kt
index f9477233..c41e982a 100644
--- a/composeApp/src/iosMain/kotlin/org/ooni/probe/MainViewController.kt
+++ b/composeApp/src/iosMain/kotlin/org/ooni/probe/MainViewController.kt
@@ -5,5 +5,7 @@ import org.ooni.engine.OonimkallBridge
import org.ooni.probe.di.Dependencies
import platform.Foundation.NSTemporaryDirectory
-fun MainViewController(bridge: OonimkallBridge) =
- ComposeUIViewController { App(Dependencies(bridge, NSTemporaryDirectory())) }
\ No newline at end of file
+fun mainViewController(bridge: OonimkallBridge) =
+ ComposeUIViewController {
+ App(Dependencies(bridge, NSTemporaryDirectory()))
+ }
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index f3a3514b..34f548b2 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -5,7 +5,7 @@ android-compileSdk = "34"
android-minSdk = "24"
android-targetSdk = "34"
-androidx-activityCompose = "1.9.0"
+androidx-activityCompose = "1.9.1"
compose = "1.6.8"
compose-plugin = "1.6.11"
kotlin = "2.0.0"
@@ -24,4 +24,5 @@ jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin
jetbrainsComposeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
-cocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" }
\ No newline at end of file
+cocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" }
+ktlint = { id = "org.jlleitschuh.gradle.ktlint", version = "12.1.1" }
\ No newline at end of file
diff --git a/iosApp/Podfile b/iosApp/Podfile
index f3cd2a5a..c38ddd2b 100644
--- a/iosApp/Podfile
+++ b/iosApp/Podfile
@@ -1,4 +1,4 @@
-platform :ios, '9.0'
+platform :ios, '12.0'
use_frameworks!
target 'iosApp' do
diff --git a/iosApp/Podfile.lock b/iosApp/Podfile.lock
index 2c88a8c9..b16758ea 100644
--- a/iosApp/Podfile.lock
+++ b/iosApp/Podfile.lock
@@ -41,6 +41,6 @@ SPEC CHECKSUMS:
libz: 83658eb2a0db785623ffdf9ce13407e6b8b5c8f9
oonimkall: 9768ce9dad18265d45d2ea972c84fb0bd5237cc3
-PODFILE CHECKSUM: 9f3463701e9fb15f3dded022f7afabede102208e
+PODFILE CHECKSUM: 04b498ba1984c25e9816234b0551222184c25492
COCOAPODS: 1.15.2
diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj
index 2562ec72..123f806b 100644
--- a/iosApp/iosApp.xcodeproj/project.pbxproj
+++ b/iosApp/iosApp.xcodeproj/project.pbxproj
@@ -127,7 +127,6 @@
B92378962B6B1156000C7307 /* Frameworks */,
7555FF79242A565900829871 /* Resources */,
93E977732C4FE022009CCABC /* ShellScript */,
- 3793390471A4D6FCCF24C27E /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -206,23 +205,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 3793390471A4D6FCCF24C27E /* [CP] Copy Pods Resources */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-input-files.xcfilelist",
- );
- name = "[CP] Copy Pods Resources";
- outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-output-files.xcfilelist",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources.sh\"\n";
- showEnvVarsInLog = 0;
- };
93E977732C4FE022009CCABC /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
diff --git a/iosApp/iosApp/ContentView.swift b/iosApp/iosApp/ContentView.swift
index 52eb65b6..daa9a9a7 100644
--- a/iosApp/iosApp/ContentView.swift
+++ b/iosApp/iosApp/ContentView.swift
@@ -4,7 +4,7 @@ import composeApp
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
- MainViewControllerKt.MainViewController(bridge: IosOonimkallBridge())
+ MainViewControllerKt.mainViewController(bridge: IosOonimkallBridge())
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}