Skip to content

Commit

Permalink
Merge branch '2.x' into node-mp
Browse files Browse the repository at this point in the history
  • Loading branch information
Ninjars committed Aug 9, 2023
2 parents 07353f5 + 31f2a1b commit d939568
Show file tree
Hide file tree
Showing 33 changed files with 747 additions and 246 deletions.
12 changes: 11 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- name: Build
run: >
./gradlew
build
buildNonMkdocs
projectHealth
mergeLintSarif
mergeDetektSarif
Expand Down Expand Up @@ -143,6 +143,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '11'
- uses: gradle/wrapper-validation-action@v1
- uses: gradle/gradle-build-action@v2
with:
cache-read-only: ${{ env.MAIN_BRANCH != 'true' }}
- name: Generate distributions
run: ./gradlew jsBrowserDistributionMkdocs --continue
- uses: actions/setup-python@v4
with:
python-version: '3.x'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ package com.bumble.appyx.navigation.store
*/
interface RetainedInstanceStore {

fun <T : Any> get(storeId: String, key: String, disposer: (T) -> Unit = {}, factory: () -> T): T
fun <T : Any> get(
storeId: String,
key: String,
disposer: (T) -> Unit = {},
factory: () -> T
): T

fun isRetainedByStoreId(storeId: String, value: Any): Boolean

Expand Down
24 changes: 24 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,33 @@ allprojects {
}
}

val buildNonMkdocsTask = tasks.register("buildNonMkdocs")
val jsBrowserDistributionMkdocsTask = tasks.register("jsBrowserDistributionMkdocs")

subprojects {
plugins.apply("release-dependencies-diff-create")

// Allows avoiding building these modules as part of CI as they are also built for mkdocs.
if (!path.startsWith(":demos:mkdocs:")) {
plugins.withId("com.android.application") {
buildNonMkdocsTask.configure { dependsOn(tasks.named("build")) }
}
plugins.withId("com.android.library") {
buildNonMkdocsTask.configure { dependsOn(tasks.named("build")) }
}
plugins.withId("org.jetbrains.kotlin.multiplatform") {
buildNonMkdocsTask.configure { dependsOn(tasks.named("build")) }
}
plugins.withId("java-library") {
buildNonMkdocsTask.configure { dependsOn(tasks.named("build")) }
}
} else {
plugins.withId("org.jetbrains.kotlin.multiplatform") {
jsBrowserDistributionMkdocsTask
.configure { dependsOn(tasks.named("jsBrowserDistribution")) }
}
}

tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
if (project.findProperty("enableComposeCompilerReports") == "true") {
Expand Down
43 changes: 22 additions & 21 deletions documentation/2.x/migrationguide.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Appyx


## 2.x vs 1.x project organisation
## Project organisation

### Appyx 1.0
### 1.x
Packaged as a single library, implementing Model-driven navigation with transitions together.

### Appyx 2.0
### 2.x
The library is packaged as multiple artifacts.

#### :appyx-navigation
Expand All @@ -31,13 +31,14 @@ The library is packaged as multiple artifacts.
- Compose multiplatform


## 1.x ~ 2.x rough equivalents
## Rough equivalents

- `NavModel` -> `AppyxComponent`
- `TransitionHandler` -> `MotionController`
- 1.x → 2.x
- `NavModel``AppyxComponent`
- `TransitionHandler``MotionController`


## 1.x → 2.x Migration guide
## Migration guide

### Gradle

Expand All @@ -48,10 +49,10 @@ The library is packaged as multiple artifacts.
Note that [BackStack](../components/backstack.md) and [Spotlight](../components/spotlight.md) are now standalone artifacts. Check your usage, you might only need `backstack`:

```diff
- implementation("com.bumble.appyx:core:1.x.x")
+ implementation("com.bumble.appyx:appyx-navigation:2.0.0-alpha01")
+ implementation("com.bumble.appyx:backstack-android:2.0.0-alpha01")
+ implementation("com.bumble.appyx:spotlight-android:2.0.0-alpha01")
-implementation("com.bumble.appyx:core:1.x.x")
+implementation("com.bumble.appyx:appyx-navigation:2.0.0-alpha01")
+implementation("com.bumble.appyx:backstack-android:2.0.0-alpha01")
+implementation("com.bumble.appyx:spotlight-android:2.0.0-alpha01")
```


Expand All @@ -61,15 +62,15 @@ Note that [BackStack](../components/backstack.md) and [Spotlight](../components/
Artifacts have a `utils-` prefix:

```diff
-"com.bumble.appyx:testing-ui"
-"com.bumble.appyx:testing-unit-common"
-"com.bumble.appyx:testing-junit4"
-"com.bumble.appyx:testing-junit5"

+"com.bumble.appyx:utils-testing-ui"
+"com.bumble.appyx:utils-testing-unit-common"
+"com.bumble.appyx:utils-testing-junit4"
+"com.bumble.appyx:utils-testing-junit5"
-implementation("com.bumble.appyx:testing-ui")
-implementation("com.bumble.appyx:testing-unit-common")
-implementation("com.bumble.appyx:testing-junit4")
-implementation("com.bumble.appyx:testing-junit5")

+implementation("com.bumble.appyx:utils-testing-ui")
+implementation("com.bumble.appyx:utils-testing-unit-common")
+implementation("com.bumble.appyx:utils-testing-junit4")
+implementation("com.bumble.appyx:utils-testing-junit5")
```


Expand Down Expand Up @@ -116,7 +117,7 @@ Artifacts have a `utils-` prefix:

class RootNode(
buildContext: BuildContext,
private val backStack: BackStack<NavTarget> = BackStack(
private val backStack: BackStack<NavTarget> = BackStack(
- initialElement = Child1,
- savedStateMap = buildContext.savedStateMap
+ model = BackStackModel(
Expand Down
2 changes: 1 addition & 1 deletion documentation/components/backstack.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Class: `BackStackFader`

### Custom

You can always create your own visualisations for Appyx components. Find more info in [UI representation](../interactions/uirepresentation.md).
You can always create your own visualisations for Appyx components. Find more info in [UI representation](../interactions/ui-representation.md).



Expand Down
2 changes: 1 addition & 1 deletion documentation/components/spotlight.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Class: `SpotlightFader`

### Custom

You can always create your own visualisations for Appyx components. Find more info in [UI representation](../interactions/uirepresentation.md).
You can always create your own visualisations for Appyx components. Find more info in [UI representation](../interactions/ui-representation.md).



Expand Down
110 changes: 110 additions & 0 deletions documentation/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# FAQ


## Navigation-related

#### **Q: How does Appyx Navigation relate to Jetpack Compose Navigation?**

We wrote an article on this in the context of Appyx 1.x: [Appyx vs Jetpack Compose Navigation](https://medium.com/bumble-tech/appyx-vs-jetpack-compose-navigation-b91bd23369f2).

Most of the same arguments apply to Appyx 2.x too.

While Appyx represents a different paradigm, it can also co-exist with Jetpack Compose Navigation. This can be helpful if you want to use Appyx for in-screen mechanisms only, or if you plan to migrate gradually.

See [Appyx + Compose Navigation](navigation/integrations/compose-navigation.md) for more details.

---

#### **Q: How does Appyx Navigation compare against other solutions?**

The core concepts of navigation in Appyx differ from most navigation libraries:

1. You don't have a concept of the "screen" present in the model
2. You can define your own navigation models using [Appyx Components](components/index.md)
3. On the UI level you can transform what feels like the "screen" itself

See [Model-driven navigation](navigation/concepts/model-driven-navigation.md) for more details.

---


#### **Q: How can I navigate to a specific part of my Appyx tree?**

In most cases [Implicit navigation](navigation/concepts/implicit-navigation.md) can be your primary choice, and you don't need to explicitly specify a remote point in the tree. This is helpful to avoid coupling.

For those cases when you can't avoid it, [Explicit navigation](navigation/concepts/explicit-navigation.md) and [Deep linking](navigation/features/deep-linking.md) covers you.

---


#### **Q: What about dialogs & bottom sheets?**

You can use Appyx in conjunction with Accompanist or any other Compose mechanism.

If you wish, you can model your own Modal with Appyx too. We'll add an example soon.


---


## Using Appyx in an app


#### **Q: Is it an all or nothing approach?**

No, you can adopt Appyx gradually:

- Plug an [Appyx Components](components/index.md) in to any screen and just use it as a UI component.
- Plug it in to a few screens and substitute another navigation mechanism with it, such as [Jetpack Compose Navigation](navigation/integrations/compose-navigation.md)

---

#### **Q: What architectural patterns can I use?**

Appyx is agnostic of architectural patterns. You can use any architectural pattern in the `Nodes` you'd like. You can even use a different one in each.

---

#### **Q: Can I use it with ViewModel?**

Please see [Appyx + ViewModel](navigation/integrations/viewmodel.md).

---


#### **Q: Can I use it with Hilt?**

Please see [Appyx + DI frameworks](navigation/integrations/di-frameworks.md).

---

## Performance-related

#### **Q: Are `Nodes` kept alive?**

In short: you can decide whether a `Node`:

- is on-screen
- is off-screen but kept alive
- is off-screen and becomes destroyed

Check the [Lifecycle](navigation/features/lifecycle.md#on-screen-off-screen) for more details.

---


## On the project itself

#### **Q: Is it production ready?**

Appyx matured to its stable version in the `1.x` branch.

The `2.x` branch is currently in alpha.

We use Appyx at Bumble in production, and as such, we're committed to maintaining and improving it.

---

## Other

Have a question? Come over to **#appyx** on Kotlinlang Slack!
11 changes: 7 additions & 4 deletions documentation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Model-driven navigation + UI components with gesture control for Compose Multipl

Find us on Kotlinlang Slack: **#appyx**

## Setup

See [Downloads](releases/downloads.md) and [Navigation quick start guide](navigation/quick-start.md).

## Overview

Expand All @@ -17,11 +20,11 @@ Appyx is a collection of libraries:

## Appyx Navigation

**Type-safe navigation directly from code.**
**Type-safe navigation for Compose directly from code.**

- Tree-based, composable
- Leverages the transitions and gesture-based capabilities to **Appyx Interactions** to build beautiful, custom navigation.
- Use any component for navigation, whether pre-built (see: [Appyx Components](components/index.md)), or custom-built by you (see: [Appyx Interactions](interactions/index.md)).
- Leverages the transitions and gesture-based capabilities of [Appyx Interactions](interactions/index.md) to build beautiful, custom navigation.
- Use any component for navigation, whether pre-built ([Appyx Components](components/index.md)), or custom-built by you ([Appyx Interactions](interactions/index.md)).

[» More details](navigation/index.md)

Expand Down Expand Up @@ -65,7 +68,7 @@ Appyx is a collection of libraries:

**Component gallery.**

Back stack, Spotlight (pager), and other UI components built using Appyx Interactions.
Back stack, Spotlight (pager), and other UI components built using [Appyx Interactions](interactions/index.md).

[» More details](components/index.md)

Expand Down
50 changes: 50 additions & 0 deletions documentation/interactions/ksp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Appyx Interactions – KSP setup

Defining `TargetUiStates` is easy, as demonstrated in [UI representation](ui-representation.md)

```kotlin
@MutableUiStateSpecs
class TargetUiState(
val position: Position.Target,
val rotation: Rotation.Target,
val backgroundColor: BackgroundColor.Target,
)
```

However, for every `TargetUiState`, there needs to exist a corresponding `MutableUiState` class containing the animation code.

By adding the `@MutableUiStateSpecs` annotation, if you follow the below setup guide, you can have the Appyx KSP mutable ui state processor generate this class for you automatically.


## Setup

Works with **Kotlin 1.8.10**. For our migration to **Kotlin 1.9** please check:

- [#547](https://github.com/bumble-tech/appyx/issues/547) - Upgrade Compose Multiplatform / Kotlin


### Main `build.gradle`

```kotlin
plugins {
id("com.google.devtools.ksp") version libs.versions.ksp.get() apply false
// Alternatively:
// id("com.google.devtools.ksp") version '1.8.0-1.0.8' apply false
}
```

### App `build.gradle`

```kotlin
plugins {
id("com.google.devtools.ksp")
}

composeOptions {
kotlinCompilerExtensionVersion = '1.4.3'
}

dependencies {
ksp("com.bumble.appyx:mutable-ui-processor:{latest version}")
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -166,21 +166,8 @@ class TargetUiState(

You might have noticed that the above classes are annotated with `@MutableUiStateSpecs`. Appyx comes with a KSP processor that will generate the corresponding `MutableUiState` class for you, so that you don't have to.

You can configure the processor in your `build.gradle.kts` such as:
Please refer to the [KSP setup](ksp.md) guide.

```kotlin
plugins {
id("com.google.devtools.ksp")
}

dependencies {
add("kspCommonMainMetadata", project(":ksp:mutable-ui-processor"))
// Add for each of your target platforms:
add("kspAndroid", project(":ksp:mutable-ui-processor"))
add("kspDesktop", project(":ksp:mutable-ui-processor"))
add("kspJs", project(":ksp:mutable-ui-processor"))
}
```

## Observing MotionProperty in children UI

Expand Down
Loading

0 comments on commit d939568

Please sign in to comment.