From d69b2d158d15844170af426516c349dcde7197c1 Mon Sep 17 00:00:00 2001 From: Ash Davies <1892070+ashdavies@users.noreply.github.com> Date: Fri, 3 Nov 2023 10:40:11 +0100 Subject: [PATCH] Remove system and environment lookup properties --- app-launcher/android/build.gradle.kts | 1 + .../ashdavies/playground/LauncherActivity.kt | 22 +++++++++---- .../io/ashdavies/playground/LauncherScreen.kt | 2 +- .../ashdavies/playground/LauncherUiFactory.kt | 2 +- app-launcher/desktop/build.gradle.kts | 1 + .../io/ashdavies/playground/LauncherMain.kt | 23 ++++++++----- .../ashdavies/playground/events/EventPager.kt | 11 +++++-- .../io/ashdavies/compose/FirebaseApp.kt | 9 +++--- .../kotlin/io/ashdavies/http/Software.kt | 9 ------ .../kotlin/io/ashdavies/http/System.kt | 32 ------------------- .../kotlin/io/ashdavies/http/ApiBuilder.kt | 7 ---- .../kotlin/io/ashdavies/http/Environment.kt | 11 ------- .../kotlin/io/ashdavies/http/HttpClient.kt | 13 +++++--- .../io/ashdavies/http/HttpCredentials.kt | 12 +++++++ .../kotlin/io/ashdavies/http/Software.kt | 7 ---- .../kotlin/io/ashdavies/http/System.kt | 3 -- .../kotlin/io/ashdavies/http/Software.kt | 7 ---- .../kotlin/io/ashdavies/http/System.kt | 8 ----- 18 files changed, 67 insertions(+), 113 deletions(-) delete mode 100644 http-client/src/androidMain/kotlin/io/ashdavies/http/Software.kt delete mode 100644 http-client/src/androidMain/kotlin/io/ashdavies/http/System.kt delete mode 100644 http-client/src/commonMain/kotlin/io/ashdavies/http/ApiBuilder.kt delete mode 100644 http-client/src/commonMain/kotlin/io/ashdavies/http/Environment.kt create mode 100644 http-client/src/commonMain/kotlin/io/ashdavies/http/HttpCredentials.kt delete mode 100644 http-client/src/commonMain/kotlin/io/ashdavies/http/Software.kt delete mode 100644 http-client/src/commonMain/kotlin/io/ashdavies/http/System.kt delete mode 100644 http-client/src/jvmMain/kotlin/io/ashdavies/http/Software.kt delete mode 100644 http-client/src/jvmMain/kotlin/io/ashdavies/http/System.kt diff --git a/app-launcher/android/build.gradle.kts b/app-launcher/android/build.gradle.kts index e6d9cc96c..7c3ffa53a 100644 --- a/app-launcher/android/build.gradle.kts +++ b/app-launcher/android/build.gradle.kts @@ -26,6 +26,7 @@ android { dependencies { implementation(projects.appLauncher.common) implementation(projects.firebaseCompose) + implementation(projects.httpClient) with(libs.androidx) { implementation(libs.androidx.core.splashscreen) diff --git a/app-launcher/android/src/main/kotlin/io/ashdavies/playground/LauncherActivity.kt b/app-launcher/android/src/main/kotlin/io/ashdavies/playground/LauncherActivity.kt index fcca28089..bc55fbfba 100644 --- a/app-launcher/android/src/main/kotlin/io/ashdavies/playground/LauncherActivity.kt +++ b/app-launcher/android/src/main/kotlin/io/ashdavies/playground/LauncherActivity.kt @@ -1,26 +1,34 @@ package io.ashdavies.playground +import android.os.Build import androidx.activity.compose.setContent import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.CompositionLocalProvider import com.slack.circuit.backstack.rememberSaveableBackStack import com.slack.circuit.foundation.CircuitCompositionLocals import com.slack.circuit.foundation.NavigableCircuitContent import com.slack.circuit.foundation.rememberCircuitNavigator import com.slack.circuit.overlay.ContentWithOverlays -import io.ashdavies.compose.ProvideFirebaseApp +import io.ashdavies.http.HttpCredentials +import io.ashdavies.http.LocalHttpCredentials internal class LauncherActivity : KotlinActivity(action = { + val credentials = HttpCredentials(getString(R.string.playground_api_key), Build.PRODUCT) val initialBackStack = buildInitialBackStack(intent.getStringExtra("route")) - val circuitConfig = CircuitConfig(applicationContext) + val circuit = CircuitConfig(applicationContext) setContent { val backStack = rememberSaveableBackStack { initialBackStack.forEach(::push) } - val navigator = rememberCircuitNavigator(backStack) - ProvideFirebaseApp { - MaterialTheme(colorScheme = dynamicColorScheme()) { - CircuitCompositionLocals(circuitConfig) { - ContentWithOverlays { NavigableCircuitContent(navigator, backStack) } + CompositionLocalProvider(LocalHttpCredentials provides credentials) { + CircuitCompositionLocals(circuit) { + ContentWithOverlays { + MaterialTheme(dynamicColorScheme()) { + NavigableCircuitContent( + navigator = rememberCircuitNavigator(backStack), + backstack = backStack, + ) + } } } } diff --git a/app-launcher/common/src/commonMain/kotlin/io/ashdavies/playground/LauncherScreen.kt b/app-launcher/common/src/commonMain/kotlin/io/ashdavies/playground/LauncherScreen.kt index a7ec83744..e81b44db3 100644 --- a/app-launcher/common/src/commonMain/kotlin/io/ashdavies/playground/LauncherScreen.kt +++ b/app-launcher/common/src/commonMain/kotlin/io/ashdavies/playground/LauncherScreen.kt @@ -40,7 +40,7 @@ import io.ashdavies.graphics.rememberAsyncImagePainter ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class, ) -public fun LauncherScreen( +internal fun LauncherScreen( state: LauncherScreen.State, modifier: Modifier = Modifier, ) { diff --git a/app-launcher/common/src/commonMain/kotlin/io/ashdavies/playground/LauncherUiFactory.kt b/app-launcher/common/src/commonMain/kotlin/io/ashdavies/playground/LauncherUiFactory.kt index 36b9eea20..13cdabae8 100644 --- a/app-launcher/common/src/commonMain/kotlin/io/ashdavies/playground/LauncherUiFactory.kt +++ b/app-launcher/common/src/commonMain/kotlin/io/ashdavies/playground/LauncherUiFactory.kt @@ -3,7 +3,7 @@ package io.ashdavies.playground import com.slack.circuit.runtime.ui.Ui import com.slack.circuit.runtime.ui.ui -public fun LauncherUiFactory(): Ui.Factory = Ui.Factory { screen, _ -> +internal fun LauncherUiFactory(): Ui.Factory = Ui.Factory { screen, _ -> when (screen is LauncherScreen) { true -> ui { state, modifier -> LauncherScreen(state, modifier) } false -> null diff --git a/app-launcher/desktop/build.gradle.kts b/app-launcher/desktop/build.gradle.kts index e667edfa5..fbaad9d7f 100644 --- a/app-launcher/desktop/build.gradle.kts +++ b/app-launcher/desktop/build.gradle.kts @@ -11,6 +11,7 @@ kotlin { } jvmMain.dependencies { + implementation(projects.httpClient) implementation(libs.jetbrains.kotlinx.cli) implementation(libs.slack.circuit.foundation) implementation(projects.appLauncher.common) diff --git a/app-launcher/desktop/src/jvmMain/kotlin/io/ashdavies/playground/LauncherMain.kt b/app-launcher/desktop/src/jvmMain/kotlin/io/ashdavies/playground/LauncherMain.kt index 69ad22c47..459c9b175 100644 --- a/app-launcher/desktop/src/jvmMain/kotlin/io/ashdavies/playground/LauncherMain.kt +++ b/app-launcher/desktop/src/jvmMain/kotlin/io/ashdavies/playground/LauncherMain.kt @@ -1,6 +1,7 @@ package io.ashdavies.playground import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Window @@ -11,6 +12,8 @@ import com.slack.circuit.foundation.CircuitCompositionLocals import com.slack.circuit.foundation.NavigableCircuitContent import com.slack.circuit.foundation.rememberCircuitNavigator import io.ashdavies.content.PlatformContext +import io.ashdavies.http.HttpCredentials +import io.ashdavies.http.LocalHttpCredentials import kotlinx.cli.ArgParser import kotlinx.cli.ArgType @@ -20,23 +23,27 @@ public fun main(args: Array) { val argResult = argParser.parse(args) val initialBackStack = buildInitialBackStack(routerArgOption) - val circuitConfig = CircuitConfig(PlatformContext.Default) + val circuit = CircuitConfig(PlatformContext.Default) - application { - val windowState = rememberWindowState(size = DpSize(450.dp, 975.dp)) + val credentials = HttpCredentials( + apiKey = System.getProperty("PLAYGROUND_API_KEY"), + userAgent = System.getProperty("os.name"), + ) + application { Window( onCloseRequest = ::exitApplication, + state = rememberWindowState(size = DpSize(450.dp, 975.dp)), title = argResult.commandName, - state = windowState, ) { val backStack = rememberSaveableBackStack { initialBackStack.forEach(::push) } val navigator = rememberCircuitNavigator(backStack, ::exitApplication) - val colorScheme = dynamicColorScheme() - MaterialTheme(colorScheme = colorScheme) { - CircuitCompositionLocals(circuitConfig) { - NavigableCircuitContent(navigator, backStack) + MaterialTheme(dynamicColorScheme()) { + CircuitCompositionLocals(circuit) { + CompositionLocalProvider(LocalHttpCredentials provides credentials) { + NavigableCircuitContent(navigator, backStack) + } } } } diff --git a/events-app/src/commonMain/kotlin/io/ashdavies/playground/events/EventPager.kt b/events-app/src/commonMain/kotlin/io/ashdavies/playground/events/EventPager.kt index 0654687cc..67897ac51 100644 --- a/events-app/src/commonMain/kotlin/io/ashdavies/playground/events/EventPager.kt +++ b/events-app/src/commonMain/kotlin/io/ashdavies/playground/events/EventPager.kt @@ -6,7 +6,7 @@ import app.cash.paging.ExperimentalPagingApi import app.cash.paging.Pager import app.cash.paging.PagingConfig import io.ashdavies.generated.apis.EventsApi -import io.ashdavies.http.buildApi +import io.ashdavies.http.LocalHttpCredentials import io.ashdavies.playground.Event import io.ashdavies.playground.EventsQueries import io.ashdavies.playground.MultipleReferenceWarning @@ -20,7 +20,7 @@ private const val DEFAULT_PAGE_SIZE = 10 @MultipleReferenceWarning internal fun rememberEventPager( eventsQueries: EventsQueries = rememberPlaygroundDatabase().eventsQueries, - eventsApi: EventsApi = remember { buildApi(::EventsApi) }, + eventsApi: EventsApi = rememberEventsApi(), initialKey: String = todayAsString(), pageSize: Int = DEFAULT_PAGE_SIZE, ): Pager = remember(eventsQueries, eventsApi) { @@ -31,3 +31,10 @@ internal fun rememberEventPager( pagingSourceFactory = { EventsPagingSource(eventsQueries) }, ) } + +@Composable +private fun rememberEventsApi( + apiKey: String = LocalHttpCredentials.current.apiKey, +): EventsApi = remember(apiKey) { + EventsApi().apply { setApiKey(apiKey) } +} diff --git a/firebase-compose/src/androidMain/kotlin/io/ashdavies/compose/FirebaseApp.kt b/firebase-compose/src/androidMain/kotlin/io/ashdavies/compose/FirebaseApp.kt index 693a51480..1c48152da 100644 --- a/firebase-compose/src/androidMain/kotlin/io/ashdavies/compose/FirebaseApp.kt +++ b/firebase-compose/src/androidMain/kotlin/io/ashdavies/compose/FirebaseApp.kt @@ -14,7 +14,7 @@ public val LocalFirebaseAndroidApp: ProvidableCompositionLocal = st } @Composable -public fun ProvideFirebaseApp(context: Context = LocalContext.current, content: @Composable () -> Unit) { +public fun FirebaseApp(context: Context = LocalContext.current, content: @Composable () -> Unit) { CompositionLocalProvider( LocalFirebaseAndroidApp provides requireFirebaseApp(context), content = content, @@ -22,10 +22,9 @@ public fun ProvideFirebaseApp(context: Context = LocalContext.current, content: } private fun requireFirebaseApp(context: Context): FirebaseApp { - val firebaseApp = if (FirebaseApp.getApps(context).size > 0) { - FirebaseApp.getInstance() - } else { - FirebaseApp.initializeApp(context) + val firebaseApp = when (FirebaseApp.getApps(context).isEmpty()) { + true -> FirebaseApp.initializeApp(context) + else -> FirebaseApp.getInstance() } return requireNotNull(firebaseApp) { diff --git a/http-client/src/androidMain/kotlin/io/ashdavies/http/Software.kt b/http-client/src/androidMain/kotlin/io/ashdavies/http/Software.kt deleted file mode 100644 index 98de393e9..000000000 --- a/http-client/src/androidMain/kotlin/io/ashdavies/http/Software.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.ashdavies.http - -import android.os.Build - -public actual object Software { - public actual val buildVersion: String = Build.FINGERPRINT - public actual val productName: String = Build.PRODUCT - public actual val clientName: String = "Ktor/2.0.0" -} diff --git a/http-client/src/androidMain/kotlin/io/ashdavies/http/System.kt b/http-client/src/androidMain/kotlin/io/ashdavies/http/System.kt deleted file mode 100644 index 91b97471c..000000000 --- a/http-client/src/androidMain/kotlin/io/ashdavies/http/System.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.ashdavies.http - -import java.lang.System -import java.lang.reflect.Field -import java.lang.reflect.Modifier - -private const val APPLICATION_ID = "io.ashdavies.playground" - -private val Field.isStatic: Boolean get() = Modifier.isStatic(modifiers) - -private val Field.isString: Boolean get() = type.isAssignableFrom(String::class.java) - -private val buildConfigCache = mutableMapOf>() - -public actual object System : Environment { - - override val properties: Map = System.getProperties() - - @Suppress("MemberVisibilityCanBePrivate") - public var buildConfig: String = "$APPLICATION_ID.BuildConfig" - - override val env: Map - get() = buildConfigCache.getOrPut(buildConfig) { - loadBuildConfig(buildConfig) - } -} - -private fun loadBuildConfig(className: String): Map = buildMap { - Class.forName(className).declaredFields.forEach { - if (it.isStatic && it.isString) put(it.name, it.get(null) as String) - } -} diff --git a/http-client/src/commonMain/kotlin/io/ashdavies/http/ApiBuilder.kt b/http-client/src/commonMain/kotlin/io/ashdavies/http/ApiBuilder.kt deleted file mode 100644 index 86ab82f8b..000000000 --- a/http-client/src/commonMain/kotlin/io/ashdavies/http/ApiBuilder.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.ashdavies.http - -import io.ashdavies.generated.infrastructure.ApiClient - -public fun buildApi(block: () -> T): T = block().apply { - setApiKey(Environment.require("PLAYGROUND_API_KEY")) -} diff --git a/http-client/src/commonMain/kotlin/io/ashdavies/http/Environment.kt b/http-client/src/commonMain/kotlin/io/ashdavies/http/Environment.kt deleted file mode 100644 index eb592fd8c..000000000 --- a/http-client/src/commonMain/kotlin/io/ashdavies/http/Environment.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.ashdavies.http - -public interface Environment { - - public val properties: Map - public val env: Map - - public companion object Default : Environment by System -} - -public fun Environment.require(key: String): String = requireNotNull(env[key]) diff --git a/http-client/src/commonMain/kotlin/io/ashdavies/http/HttpClient.kt b/http-client/src/commonMain/kotlin/io/ashdavies/http/HttpClient.kt index 05e46e2d3..15ec1c289 100644 --- a/http-client/src/commonMain/kotlin/io/ashdavies/http/HttpClient.kt +++ b/http-client/src/commonMain/kotlin/io/ashdavies/http/HttpClient.kt @@ -23,11 +23,15 @@ public val LocalHttpClient: ProvidableCompositionLocal = staticCompo DefaultHttpClient { install(HttpCache) } } -private val defaultUserAgent: String - get() = "${Software.clientName} (${Software.productName}; ${Software.buildVersion})" +public fun DefaultHttpClient( + credentials: HttpCredentials, + configure: HttpClientConfig.() -> Unit = { }, +): HttpClient = DefaultHttpClient { + install(DefaultRequest) { userAgent(credentials.userAgent) } + configure() +} public fun DefaultHttpClient( - logLevel: LogLevel = LogLevel.INFO, configure: HttpClientConfig.() -> Unit = { }, ): HttpClient = HttpClient(CIO) { install(ContentNegotiation) { @@ -42,12 +46,11 @@ public fun DefaultHttpClient( install(DefaultRequest) { contentType(ContentType.Application.Json) accept(ContentType.Application.Json) - userAgent(defaultUserAgent) } install(Logging) { logger = DefaultLogger() - level = logLevel + level = LogLevel.INFO } configure() diff --git a/http-client/src/commonMain/kotlin/io/ashdavies/http/HttpCredentials.kt b/http-client/src/commonMain/kotlin/io/ashdavies/http/HttpCredentials.kt new file mode 100644 index 000000000..642765b04 --- /dev/null +++ b/http-client/src/commonMain/kotlin/io/ashdavies/http/HttpCredentials.kt @@ -0,0 +1,12 @@ +package io.ashdavies.http + +import androidx.compose.runtime.staticCompositionLocalOf + +public val LocalHttpCredentials = staticCompositionLocalOf { + error("CompositionLocal LocalHttpCredentials not present") +} + +public data class HttpCredentials( + val apiKey: String, + val userAgent: String, +) diff --git a/http-client/src/commonMain/kotlin/io/ashdavies/http/Software.kt b/http-client/src/commonMain/kotlin/io/ashdavies/http/Software.kt deleted file mode 100644 index b1273af4d..000000000 --- a/http-client/src/commonMain/kotlin/io/ashdavies/http/Software.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.ashdavies.http - -public expect object Software { - public val buildVersion: String - public val productName: String - public val clientName: String -} diff --git a/http-client/src/commonMain/kotlin/io/ashdavies/http/System.kt b/http-client/src/commonMain/kotlin/io/ashdavies/http/System.kt deleted file mode 100644 index 966c1db6d..000000000 --- a/http-client/src/commonMain/kotlin/io/ashdavies/http/System.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.ashdavies.http - -public expect object System : Environment diff --git a/http-client/src/jvmMain/kotlin/io/ashdavies/http/Software.kt b/http-client/src/jvmMain/kotlin/io/ashdavies/http/Software.kt deleted file mode 100644 index 04c1c3c62..000000000 --- a/http-client/src/jvmMain/kotlin/io/ashdavies/http/Software.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.ashdavies.http - -public actual object Software { - public actual val buildVersion: String = Environment.properties["os.version"] as String - public actual val productName: String = Environment.properties["os.name"] as String - public actual val clientName: String = "Ktor/2.0.0" -} diff --git a/http-client/src/jvmMain/kotlin/io/ashdavies/http/System.kt b/http-client/src/jvmMain/kotlin/io/ashdavies/http/System.kt deleted file mode 100644 index 5d2f5b887..000000000 --- a/http-client/src/jvmMain/kotlin/io/ashdavies/http/System.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.ashdavies.http - -import java.lang.System - -public actual object System : Environment { - override val properties: Map = System.getProperties() - override val env: Map = System.getenv() -}