Skip to content

Commit

Permalink
Break conference app from launcher app (#1107)
Browse files Browse the repository at this point in the history
* Break conference app from launcher app

* Remove unused imports

* Restructure application per top-level package name

* Resolve package inconsistencies

* Remove unused imports

* Lexicographical import ordering

* Correct activity name in manifest

---------

Co-authored-by: Ashley Davies <[email protected]>
  • Loading branch information
ashdavies and ashdavies authored Aug 9, 2024
1 parent 85a7d69 commit 11e4ecf
Show file tree
Hide file tree
Showing 93 changed files with 431 additions and 259 deletions.
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ https://firebase.google.com/docs/app-check/custom-provider
### Kotlin GB [kotlin-gb]
![Experimental](https://img.shields.io/badge/project-experimental-status.svg?colorA=555555&colorB=red&label=&logo=kotlin&logoColor=ffffff&logoWidth=10)
![Multiplatform](https://img.shields.io/badge/project-multiplatform-component.svg?colorA=555555&colorB=7F52FF&label=&logo=kotlin&logoColor=ffffff&logoWidth=10)
Offers a set of Traditional English aliases for Simplified English Kotlin APIs, largely a parody, thus does not comply to the same level of modularisation.

### Notion Console [notion-console]
![Experimental](https://img.shields.io/badge/project-experimental-status.svg?colorA=555555&colorB=red&label=&logo=kotlin&logoColor=ffffff&logoWidth=10)
![JVM](https://img.shields.io/badge/project-jvm-component.svg?colorA=555555&colorB=7F52FF&label=&logo=kotlin&logoColor=ffffff&logoWidth=10)
Offers a set of Traditional English aliases for Simplified English Kotlin APIs, largely a parody, thus does not comply to the same level of modularisation.

## Talks
- Droidcon Berlin 2022
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
16 changes: 0 additions & 16 deletions after-party/src/androidMain/AndroidManifest.xml

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

9 changes: 0 additions & 9 deletions after-party/src/jvmMain/kotlin/io/ashdavies/android/Layout.kt

This file was deleted.

2 changes: 1 addition & 1 deletion app-launcher/android/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
android:icon="@mipmap/ic_launcher">

<activity
android:name="io.ashdavies.playground.LauncherActivity"
android:name="io.ashdavies.playground.MainActivity"
android:configChanges="keyboardHidden|orientation"
android:exported="true"
android:label="Playground"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.ashdavies.playground

import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
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.http.ProvideHttpClient
import io.ashdavies.http.publicStorage
import io.ashdavies.io.resolveCacheDir
import io.ktor.client.plugins.cache.HttpCache

@Composable
internal fun LauncherApp(context: Context = LocalContext.current, extra: (String) -> String?) {
ProvideHttpClient(
config = {
install(HttpCache) {
publicStorage(context.resolveCacheDir())
}
},
) {
CircuitCompositionLocals(remember { Circuit(context) }) {
ContentWithOverlays {
LauncherContent(context) {
val backStack = rememberSaveableBackStack(extra("route"))

NavigableCircuitContent(
navigator = rememberCircuitNavigator(backStack),
backStack = backStack,
)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.ashdavies.playground

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import io.ashdavies.content.enableStrictMode
import io.ashdavies.content.isDebuggable

internal class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()

if (BuildConfig.ANDROID_STRICT_MODE) {
enableStrictMode(isDebuggable())
}

setContent {
LauncherApp { intent.getStringExtra(it) }
}
}
}
2 changes: 0 additions & 2 deletions app-launcher/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ kotlin {
}

commonMain.dependencies {
implementation(projects.afterParty)
implementation(projects.analytics)
implementation(projects.appCheck.appCheckClient)
implementation(projects.circuitSupport)
Expand Down Expand Up @@ -60,7 +59,6 @@ sqldelight {
databases {
create("PlaygroundDatabase") {
packageName.set(android.namespace)
dependency(projects.afterParty)
dependency(projects.dominionApp)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ import com.slack.circuit.foundation.Circuit
import io.ashdavies.content.PlatformContext
import io.ashdavies.dominion.dominionPresenterFactory
import io.ashdavies.dominion.dominionUiFactory
import io.ashdavies.events.eventsPresenterFactory
import io.ashdavies.events.eventsUiFactory
import io.ashdavies.gallery.galleryPresenterFactory
import io.ashdavies.gallery.galleryUiFactory
import io.ashdavies.party.afterPartyPresenterFactory
import io.ashdavies.party.afterPartyUiFactory
import io.ashdavies.routes.routePresenterFactory
import io.ashdavies.routes.routeUiFactory

Expand All @@ -19,19 +13,13 @@ public fun Circuit(context: PlatformContext): Circuit = Circuit.Builder()
.build()

private fun getPresenterFactories(context: PlatformContext) = listOf(
afterPartyPresenterFactory(context),
dominionPresenterFactory(),
eventsPresenterFactory(),
galleryPresenterFactory(context),
launcherPresenterFactory(),
routePresenterFactory(context),
)

private fun getUiFactories(context: PlatformContext) = listOf(
afterPartyUiFactory(context),
dominionUiFactory(),
eventsUiFactory(),
galleryUiFactory(context),
launcherUiFactory(),
routeUiFactory(context),
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,12 @@ import com.slack.circuit.foundation.onNavEvent
import com.slack.circuit.runtime.Navigator
import com.slack.circuit.runtime.screen.Screen
import io.ashdavies.dominion.dominionScreen
import io.ashdavies.party.afterPartyScreen
import io.ashdavies.routes.routeScreen
import playground.app_launcher.common.generated.resources.Res
import playground.app_launcher.common.generated.resources.after_party
import playground.app_launcher.common.generated.resources.dominion
import playground.app_launcher.common.generated.resources.routes

private enum class LauncherEntries : LauncherScreen.State.Item {
AfterParty {
override val imageModel = Res.drawable.after_party
override val screen = afterPartyScreen()
override val title = "After Party"
},

Dominion {
override val imageModel = Res.drawable.dominion
override val screen = dominionScreen()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package io.ashdavies.playground
import com.slack.circuit.foundation.NavEvent
import com.slack.circuit.test.FakeNavigator
import com.slack.circuit.test.presenterTestOf
import io.ashdavies.party.afterPartyScreen
import io.ashdavies.dominion.dominionScreen
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
Expand All @@ -13,11 +13,11 @@ internal class LauncherPresenterTest {
private val navigator = FakeNavigator(LauncherScreen)

@Test
fun `should navigate to after party screen`() = runTest {
fun `should navigate to next screen`() = runTest {
presenterTestOf({ LauncherPresenter(navigator) }) {
awaitItem().eventSink(NavEvent.GoTo(afterPartyScreen()))
awaitItem().eventSink(NavEvent.GoTo(dominionScreen()))

assertEquals(navigator.awaitNextScreen(), afterPartyScreen())
assertEquals(navigator.awaitNextScreen(), dominionScreen())
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.ashdavies.playground

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
Expand All @@ -26,30 +27,38 @@ private class LauncherCommand : CliktCommand() {
state = rememberWindowState(size = DpSize(450.dp, 975.dp)),
title = commandName,
) {
val circuit = remember { Circuit(PlatformContext.Default) }

CircuitCompositionLocals(circuit) {
ProvideHttpClient(
config = {
install(DefaultRequest) {
header("User-Agent", System.getProperty("os.name"))
header("X-API-Key", BuildConfig.BROWSER_API_KEY)
}
},
) {
LauncherContent(PlatformContext.Default) {
val backStack = rememberSaveableBackStack(route)

NavigableCircuitContent(
navigator = rememberCircuitNavigator(backStack) { exitApplication() },
backStack = backStack,
decoration = KeyNavigationDecoration(
decoration = circuit.defaultNavDecoration,
onBackInvoked = backStack::pop,
),
)
}
LauncherApp(
route = route,
onClose = ::exitApplication,
)
}
}
}

@Composable
internal fun LauncherApp(route: String?, onClose: () -> Unit) {
val circuit = remember { Circuit(PlatformContext.Default) }

CircuitCompositionLocals(circuit) {
ProvideHttpClient(
config = {
install(DefaultRequest) {
header("User-Agent", System.getProperty("os.name"))
header("X-API-Key", BuildConfig.BROWSER_API_KEY)
}
},
) {
LauncherContent(PlatformContext.Default) {
val backStack = rememberSaveableBackStack(route)

NavigableCircuitContent(
navigator = rememberCircuitNavigator(backStack) { onClose() },
backStack = backStack,
decoration = KeyNavigationDecoration(
decoration = circuit.defaultNavDecoration,
onBackInvoked = backStack::pop,
),
)
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions build-plugins/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
`kotlin-dsl`
}
Expand All @@ -23,3 +25,7 @@ dependencies {
kotlin {
explicitApi()
}

tasks.withType<KotlinCompile> {
compilerOptions.freeCompilerArgs.add("-Xcontext-receivers")
}
19 changes: 16 additions & 3 deletions build-plugins/src/main/kotlin/AndroidCommonExtension.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,29 @@ import com.android.build.api.dsl.CommonExtension
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import org.gradle.api.Project
import org.gradle.api.plugins.AppliedPlugin
import org.gradle.api.plugins.PluginManager
import org.gradle.kotlin.dsl.configure

internal fun Project.commonExtension(action: CommonExtension<*, *, *, *, *, *>.() -> Unit) {
val androidApplicationPlugin = libs.plugins.android.application.get()
private val Project.androidApplicationPlugin
get() = libs.plugins.android.application.get()

private val Project.androidLibraryPlugin
get() = libs.plugins.android.library.get()

context(Project)
internal fun PluginManager.commonExtension(action: CommonExtension<*, *, *, *, *, *>.() -> Unit) {
pluginManager.withPlugin(androidApplicationPlugin.pluginId) {
extensions.configure<BaseAppModuleExtension>(action)
}

val androidLibraryPlugin = libs.plugins.android.library.get()
pluginManager.withPlugin(androidLibraryPlugin.pluginId) {
extensions.configure<LibraryExtension>(action)
}
}

context(Project)
internal fun PluginManager.withAndroidPlugin(action: AppliedPlugin.() -> Unit) {
pluginManager.withPlugin(androidApplicationPlugin.pluginId, action)
pluginManager.withPlugin(androidLibraryPlugin.pluginId, action)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ kotlin {
androidTarget()
}

commonExtension {
pluginManager.commonExtension {
compileOptions {
val jvmTargetVersion = libs.versions.kotlin.jvmTarget.get()
sourceCompatibility(jvmTargetVersion)
Expand Down
Loading

0 comments on commit 11e4ecf

Please sign in to comment.