diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts
index 418d346b..5f454b44 100644
--- a/composeApp/build.gradle.kts
+++ b/composeApp/build.gradle.kts
@@ -157,9 +157,121 @@ ktlint {
additionalEditorconfig.put("ktlint_function_naming_ignore_when_annotated_with", "Composable")
}
+tasks.register("copyCommonResourcesToFlavor") {
+ doLast {
+ val projectDir = project.projectDir.absolutePath
+
+ val sourceFile = File(projectDir, "src/commonMain/composeResources")
+
+ val destinationFile = File(projectDir, config.resRoot)
+
+ copyRecursive(sourceFile, destinationFile)
+ }
+}
+
+tasks.register("cleanCopiedCommonResourcesToFlavor") {
+ doLast {
+ val projectDir = project.projectDir.absolutePath
+
+ val destinationFile = File(projectDir, config.resRoot)
+ destinationFile.listFiles()?.forEach { folder ->
+ folder.listFiles()?.forEach { file ->
+ if (file.name == ".gitignore") {
+ file.readText().lines().forEach { line ->
+ if (line.isNotEmpty()) {
+ println("Removing $line")
+ File(folder, line).deleteRecursively()
+ }
+ }.also {
+ file.delete()
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Configure the prepareComposeResourcesTaskForCommonMain task to depend on the copyCommonResourcesToFlavor task.
+ * This will ensure that the common resources are copied to the correct location before the task is executed.
+ *
+ * NOTE: Current limitation is that multiple resources directories are not supported.
+ */
+tasks.named("prepareComposeResourcesTaskForCommonMain").configure {
+ dependsOn("copyCommonResourcesToFlavor")
+}
+
+tasks.named("clean").configure {
+ dependsOn("cleanCopiedCommonResourcesToFlavor")
+}
+
data class AppConfig(
val appId: String,
val appName: String,
val srcRoot: String,
val resRoot: String,
)
+
+/**
+ * Ignore the copied file if it is not already ignored.
+ *
+ * @param filePath The path to the file to ignore.
+ * @param lineToAdd The line to add to the file.
+ */
+fun ignoreCopiedFileIfNotIgnored(
+ filePath: String,
+ lineToAdd: String,
+) {
+ val file = File(filePath)
+
+ if (!file.exists()) {
+ file.createNewFile()
+ }
+
+ val fileContents = file.readText()
+
+ if (!fileContents.contains(lineToAdd)) {
+ file.appendText("\n$lineToAdd")
+ }
+}
+
+/**
+ * Copy files from one directory to another.
+ *
+ * @param from The source directory.
+ * @param to The destination directory.
+ */
+fun copyRecursive(
+ from: File,
+ to: File,
+) {
+ if (!from.exists()) {
+ println("Source directory does not exist: $from")
+ return
+ }
+ from.listFiles()?.forEach { file ->
+ if (file.name != ".DS_Store") {
+ if (file.isDirectory) {
+ val newDir = File(to, file.name)
+ newDir.mkdir()
+ copyRecursive(file, newDir)
+ } else {
+ val destinationFile = File(to, file.name)
+ if (destinationFile.exists()) {
+ println("Overwriting $destinationFile")
+ destinationFile.delete()
+ }
+ if (!destinationFile.parentFile.exists()) {
+ destinationFile.parentFile.mkdirs()
+ }
+ file.copyTo(destinationFile).also {
+ println("Ignoring ${it.name}")
+ ignoreCopiedFileIfNotIgnored(
+ to.absolutePath + "/.gitignore",
+ it.name,
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/composeApp/src/commonMain/composeResources/values/common.xml b/composeApp/src/commonMain/composeResources/values/common.xml
new file mode 100644
index 00000000..4392043c
--- /dev/null
+++ b/composeApp/src/commonMain/composeResources/values/common.xml
@@ -0,0 +1,3 @@
+
+ Run Test
+
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
deleted file mode 100644
index 85420055..00000000
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/shared/ThemeConfigBase.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/shared/ThemeConfigBase.kt
new file mode 100644
index 00000000..82007a63
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/shared/ThemeConfigBase.kt
@@ -0,0 +1,7 @@
+package org.ooni.probe.shared
+
+import androidx.compose.material3.ColorScheme
+
+interface ThemeConfigBase {
+ fun colorScheme(isDarkTheme: Boolean): ColorScheme
+}
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 a0fdfa6f..796e85ff 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/Theme.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/Theme.kt
@@ -4,58 +4,15 @@ import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Shapes
-import androidx.compose.material3.darkColorScheme
-import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
-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
fun AppTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit,
) {
- val colorScheme = if (useDarkTheme) DarkColors else LightColors
+ val colorScheme = ThemeConfig.colorScheme(useDarkTheme)
val shapes =
Shapes(
small = RoundedCornerShape(4.dp),
diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/DashboardScreen.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/DashboardScreen.kt
index 4f7ec016..c19d58a6 100644
--- a/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/DashboardScreen.kt
+++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/DashboardScreen.kt
@@ -18,6 +18,7 @@ import androidx.compose.ui.Modifier
import ooniprobe.composeapp.generated.resources.Res
import ooniprobe.composeapp.generated.resources.app_name
import ooniprobe.composeapp.generated.resources.logo
+import ooniprobe.composeapp.generated.resources.run_tests
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.ui.tooling.preview.Preview
@@ -47,7 +48,7 @@ fun DashboardScreen(
onClick = { onEvent(DashboardViewModel.Event.StartClick) },
enabled = !state.isRunning,
) {
- Text("Run Test")
+ Text(stringResource(Res.string.run_tests))
}
Image(
diff --git a/composeApp/src/dwMain/kotlin/Config.kt b/composeApp/src/dwMain/kotlin/Config.kt
index 83a3e3eb..a6e0da90 100644
--- a/composeApp/src/dwMain/kotlin/Config.kt
+++ b/composeApp/src/dwMain/kotlin/Config.kt
@@ -1,3 +1,7 @@
object Config {
- const val ENVIRONMENT: String = "News Media Scan"
+ object Config {
+ const val OONI_API_BASE_URL: String = "https://api.prod.ooni.io"
+ const val OONI_RUN_DASHBOARD_URL: String = "https://run-v2.ooni.org"
+ const val BASE_SOFTWARE_NAME: String = "news-media-scan"
+ }
}
diff --git a/composeApp/src/dwMain/kotlin/org/ooni/probe/ui/Colors.kt b/composeApp/src/dwMain/kotlin/org/ooni/probe/ui/Colors.kt
index 19903501..217ad4dd 100644
--- a/composeApp/src/dwMain/kotlin/org/ooni/probe/ui/Colors.kt
+++ b/composeApp/src/dwMain/kotlin/org/ooni/probe/ui/Colors.kt
@@ -1,16 +1,64 @@
package org.ooni.probe.ui
+import androidx.compose.material3.ColorScheme
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.lightColorScheme
import androidx.compose.ui.graphics.Color
-val primaryColor = Color(0xffD32625)
-val primaryLightColor = primaryColor.copy(alpha = 0.75f)
-val secondaryColor = Color(0xff5db8fe)
-val secondaryLightColor = secondaryColor.copy(alpha = 0.75f)
-val primaryTextColor = Color(0xffffffff)
-val secondaryTextColor = Color(0xff000000)
-val surfaceDark = Color(0xFF161616)
-val surfaceLight = Color(0xFFFFFFFF)
-val backgroundLightColor = Color(0xffF1F0F5)
-val backgroundDarkColor = Color(0xff010100)
-val errorColor = Color(0xFFFF8989)
-val onErrorColor = Color(0xFF000000)
+class ThemeConfig {
+ companion object {
+ fun colorScheme(isDarkTheme: Boolean) = if (isDarkTheme) darkColors else lightColors
+ }
+}
+
+private val primaryColor = Color(0xffD32625)
+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)
+
+val darkColors: ColorScheme =
+ 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,
+ )
+val lightColors: ColorScheme =
+ 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,
+ )
diff --git a/composeApp/src/dwMain/resources/drawable/.gitignore b/composeApp/src/dwMain/resources/drawable/.gitignore
new file mode 100644
index 00000000..35f3f1a5
--- /dev/null
+++ b/composeApp/src/dwMain/resources/drawable/.gitignore
@@ -0,0 +1,2 @@
+
+compose-multiplatform.xml
\ No newline at end of file
diff --git a/composeApp/src/dwMain/resources/values/.gitignore b/composeApp/src/dwMain/resources/values/.gitignore
new file mode 100644
index 00000000..5bdcc5ad
--- /dev/null
+++ b/composeApp/src/dwMain/resources/values/.gitignore
@@ -0,0 +1,2 @@
+
+common.xml
\ No newline at end of file
diff --git a/composeApp/src/dwMain/resources/values/strings.xml b/composeApp/src/dwMain/resources/values/strings.xml
index ce499141..3cbb405a 100644
--- a/composeApp/src/dwMain/resources/values/strings.xml
+++ b/composeApp/src/dwMain/resources/values/strings.xml
@@ -1,4 +1,3 @@
News Media Scan
- News x
diff --git a/composeApp/src/ooniMain/kotlin/Config.kt b/composeApp/src/ooniMain/kotlin/Config.kt
index 43050c91..e511cc05 100644
--- a/composeApp/src/ooniMain/kotlin/Config.kt
+++ b/composeApp/src/ooniMain/kotlin/Config.kt
@@ -1,3 +1,7 @@
+package org.ooni.probe.config
+
object Config {
- const val ENVIRONMENT: String = "OONI Probe"
+ const val OONI_API_BASE_URL: String = "https://api.prod.ooni.io"
+ const val OONI_RUN_DASHBOARD_URL: String = "https://run-v2.ooni.org"
+ const val BASE_SOFTWARE_NAME: String = "ooniprobe"
}
diff --git a/composeApp/src/ooniMain/kotlin/org/ooni/probe/ui/Colors.kt b/composeApp/src/ooniMain/kotlin/org/ooni/probe/ui/Colors.kt
index 545b7307..b74eb8b6 100644
--- a/composeApp/src/ooniMain/kotlin/org/ooni/probe/ui/Colors.kt
+++ b/composeApp/src/ooniMain/kotlin/org/ooni/probe/ui/Colors.kt
@@ -1,6 +1,16 @@
package org.ooni.probe.ui
+import androidx.compose.material3.ColorScheme
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.lightColorScheme
import androidx.compose.ui.graphics.Color
+import org.ooni.probe.shared.ThemeConfigBase
+
+class ThemeConfig {
+ companion object : ThemeConfigBase {
+ override fun colorScheme(isDarkTheme: Boolean) = if (isDarkTheme) darkColors else lightColors
+ }
+}
val primaryColor = Color(0xff0588cb)
val primaryLightColor = primaryColor.copy(alpha = 0.75f)
@@ -14,3 +24,42 @@ val backgroundLightColor = Color(0xffF1F0F5)
val backgroundDarkColor = Color(0xff010100)
val errorColor = Color(0xFFFF8989)
val onErrorColor = Color(0xFF000000)
+
+val darkColors: ColorScheme =
+ 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,
+ )
+val lightColors: ColorScheme =
+ 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,
+ )
diff --git a/composeApp/src/ooniMain/resources/drawable/.gitignore b/composeApp/src/ooniMain/resources/drawable/.gitignore
new file mode 100644
index 00000000..35f3f1a5
--- /dev/null
+++ b/composeApp/src/ooniMain/resources/drawable/.gitignore
@@ -0,0 +1,2 @@
+
+compose-multiplatform.xml
\ No newline at end of file
diff --git a/composeApp/src/ooniMain/resources/values/.gitignore b/composeApp/src/ooniMain/resources/values/.gitignore
new file mode 100644
index 00000000..5bdcc5ad
--- /dev/null
+++ b/composeApp/src/ooniMain/resources/values/.gitignore
@@ -0,0 +1,2 @@
+
+common.xml
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 59e98477..4029470f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -11,3 +11,4 @@ android.useAndroidX=true
kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.mpp.enableCInteropCommonization=true
+organization=dw