diff --git a/documentation/1.x/deprecation.md b/documentation/1.x/deprecation.md deleted file mode 100644 index d564e5dce..000000000 --- a/documentation/1.x/deprecation.md +++ /dev/null @@ -1,11 +0,0 @@ -!!! failure "Deprecation warning" - - This page in the documentation is about Appyx `1.x`. - - Appyx is now in its `2.x` iteration. - - To access the `2.x`-related pages please check the sidebar or go to: - - **[Documentation root](../index.md)** - ---- diff --git a/documentation/1.x/faq.md b/documentation/1.x/faq.md deleted file mode 100644 index 6f8c0d9e2..000000000 --- a/documentation/1.x/faq.md +++ /dev/null @@ -1,117 +0,0 @@ -{% include-markdown "./deprecation.md" %} - -# FAQ - - -## Navigation-related - -#### **Q: How does Appyx relate to Jetpack Compose Navigation?** - -We wrote an article on this: [Appyx vs Jetpack Compose Navigation](https://medium.com/bumble-tech/appyx-vs-jetpack-compose-navigation-b91bd23369f2) - -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 [Sample apps](how-to-use-appyx/sample-apps.md) for more details. - ---- - -#### **Q: How does Appyx compare against other navigation 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 -3. On the UI level you can transform what feels like the "screen" itself - -See [Model-driven navigation](navigation/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/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/explicit-navigation.md) and [Deep linking](navigation/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. - ---- - -#### **Q: Can I have a bottom sheet conditionally?** - -You could use a similar approach as we do with back buttons in `SamplesContainerNode` you can find in the `:app` module: store a flag in the `NavTarget` that can be different per instance. - ---- - -## Using Appyx in an app - - -#### **Q: Is it an all or nothing approach?** - -No, you can adopt Appyx gradually: - -- Plug it in to one screen and just utilise its screen transformation capabilities (e.g. [Cards](navmodel/cards.md)) -- Plug it in to a few screens and substitute another navigation mechanism with it, such as [Jetpack Compose Navigation](how-to-use-appyx/sample-apps.md#appyx-jetpack-compose-navigation-example) - ---- - -#### **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?** - -Yes, we'll add an example soon. - ---- - - -#### **Q: Can I use it with Hilt?** - -- Our draft PR: [#115](https://github.com/bumble-tech/appyx/pull/115) (Feel free to provide feedback!) -- [https://github.com/jbreitfeller-sfix/appyx-playground](https://github.com/jbreitfeller-sfix/appyx-playground) another approach on this topic - ---- - -## 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](apps/lifecycle.md#on-screen-off-screen) for more details. - ---- - - -## On the project itself - -#### **Q: Is it production ready?** - -Yes, Appyx matured to its stable version. We also use it at Bumble in production, and as such, we're committed to maintaining and improving it. - ---- - -#### **Q: What's your roadmap?** - -We're full with ideas where to take Appyx further! A more detailed roadmap will be added later. Come back for more updates. - ---- - -## Other - -Have a question? Raise it in [Discussions](https://github.com/bumble-tech/appyx/discussions)!. diff --git a/documentation/1.x/releases/changelog.md b/documentation/1.x/releases/changelog.md deleted file mode 100644 index de4c27ffd..000000000 --- a/documentation/1.x/releases/changelog.md +++ /dev/null @@ -1,246 +0,0 @@ -{% include-markdown "../deprecation.md" %} - -# Changelog - -## Pending changes - -- - ---- - -## 1.3.0 - -- [#425](https://github.com/bumble-tech/appyx/pull/425) – **Fixed**: Up navigation should be properly propagated from Appyx to RIBs -- [#384](https://github.com/bumble-tech/appyx/issues/384) – **Updated**: Compose BOM version and activity-compose version - -
22 Jun 2023
- ---- - -## 1.2.0 - -- [#393](https://github.com/bumble-tech/appyx/pull/393) – **Breaking change**: Removed non-lazy implementations from `NodeCustomisationDirectory` -- [#393](https://github.com/bumble-tech/appyx/pull/393) – **Breaking change**: Removed `NodeCustomisationDirectoryImpl#put(vararg values: T)` due to potential uncaught bugs. Please call the reified `put` extension function instead. - -
11 Apr 2023
- ---- - -## 1.1.2 - -- [#391](https://github.com/bumble-tech/appyx/pull/391) – **Added**: Introduced `putLazy` and `putSubDirectoryLazy` functions within `NodeCustomisationDirectoryImpl` via `LazyMutableNodeCustomisationDirectory` - -
04 Apr 2023
- ---- - -## 1.1.1 - -- [#386](https://github.com/bumble-tech/appyx/pull/386) – **Updated**: RIBs version to 0.39.0 - -
31 Mar 2023
- ---- - -## 1.1.0 - -- [#383](https://github.com/bumble-tech/appyx/pull/383) – **Changed**: Removed deprecated methods in Node, ParentNode and CombinedHandler classes -- [#376](https://github.com/bumble-tech/appyx/issues/376) – **Changed**: Androidx lifecycle version updated to 2.6.1. -- [#376](https://github.com/bumble-tech/appyx/issues/376) – **Updated**: Kotlin and Compose compiler version updated to 1.8.10 to align kotlin version used in androidx lifecycle -- [#375](https://github.com/bumble-tech/appyx/issues/375) – **Fixed**: SaveableStateHolder does no longer save state for destroyed elements - -
27 Mar 2023
- ---- - -## 1.0.5 - -- [#370](https://github.com/bumble-tech/appyx/pull/370) – **Added**: `RetainedInstanceStore` has two new functions which allows a developer to check whether an object is retained. These are: `isRetainedByStoreId` and `isRetained`. - -
04 Mar 2023
- ---- - -## 1.0.4 - -- [#361](https://github.com/bumble-tech/appyx/pull/361) – **Added**: Introduced `RetainedInstanceStore`. This provides developers the ability to retain objects between configuration changes. -- [#336](https://github.com/bumble-tech/appyx/pull/336) – **Updated**: ChildAware API does not enforce Node subtypes only anymore, making it possible to use interfaces as public contracts for child nodes. - -
20 Feb 2023
- ---- - -## 1.0.3 - -- [#325](https://github.com/bumble-tech/appyx/pull/325) – **Fixed**: Crash when using PermanentChild API in View testing - -
23 Jan 2023
- ---- - -## 1.0.2 - -- [#287](https://github.com/bumble-tech/appyx/pull/287) – **Added**: Introduced a new `rememberCombinedHandler` implementation that takes an immutable list to avoid non-skippable compositions. The previous implementation is now deprecated. -- [#287](https://github.com/bumble-tech/appyx/pull/287) – **Added**: `ImmutableList` has been added to avoid non-skippable compositions. -- [#289](https://github.com/bumble-tech/appyx/issues/289) – **Added**: Introduced `interop-rx3` for RxJava 3 support. This has identical functionality to `interop-rx2`. -- [#298](https://github.com/bumble-tech/appyx/pulls/298) – **Updated**: ChildView documentation. `TransitionDescriptor` generics has been renamed to `NavTarget` and `State` -- [#307](https://github.com/bumble-tech/appyx/pull/307) - **Added**: `Spotlight.current()` method to observe currently active `NavTarget`. -- [#314](https://github.com/bumble-tech/appyx/pull/314) – **Fixed**: Lifecycle is properly destroyed for suspended nodes. - -
10 Jan 2023
- ---- - -## 1.0.1 - -- [#268](https://github.com/bumble-tech/appyx/pull/268) – **Fixed**: `PermanentChild` now does not crash in UI tests with `ComposeTestRule`. -- [#276](https://github.com/bumble-tech/appyx/pull/276) – **Fixed**: Back press handlers order is fixed for RIBs-Appyx integration. -- [#272](https://github.com/bumble-tech/appyx/pull/272) – **Changed**: `attachWorkflow` renamed to `attachChild`. `executeWorkflow` renamed to `executeAction`. -- [#272](https://github.com/bumble-tech/appyx/pull/272) – **Added**: `NodeReadyObserver` plugin to observe when the `Node` is ready - -
22 Nov 2022
- ---- - -## 1.0.0 - -- [#247](https://github.com/bumble-tech/appyx/pull/247) – **Added**: Added `EmptyNavModel` to core for cases in which a `ParentNode` only uses `PermanentChild`. The `DummyNavModel` test class is deprecated. -- [#250](https://github.com/bumble-tech/appyx/pull/250) – **Updated**: Jetpack Compose to 1.3.0 - -
31 Oct 2022
- ---- - -## 1.0.0-rc02 - -- [#231](https://github.com/bumble-tech/appyx/pull/231) – **Fixed**: Changing transition handler at runtime does not redraw children -- [#239](https://github.com/bumble-tech/appyx/pull/239) – **Fixed**: Fixed an issue with desynchronisation between NavModel and children's restoration process -- [#218](https://github.com/bumble-tech/appyx/pull/218) – **Updated**: `androidx.core:core-ktx` to 1.9.0. - -
21 Oct 2022
- ---- - -## 1.0.0-rc01 - -- [#214](https://github.com/bumble-tech/appyx/pull/214) – **Breaking change**: `AppyxViewTestRule` stops supporting automatic launching activity. Activities should be started explicitly in tests. -- [#197](https://github.com/bumble-tech/appyx/pull/197) – **Breaking change**: `ParentNodeView` does not implement plugin anymore. `Node` instance is retrieved via `LocalComposition`. `AppyxParentViewTestRule` and `AbstractParentNodeView` have been removed. -- [#196](https://github.com/bumble-tech/appyx/pull/196) – **Breaking change**: `InteropBuilder` now should be supplied with Appyx `IntegrationPointProvider` to attach it at the same time Appyx Node is created. -- [#185](https://github.com/bumble-tech/appyx/issues/185) – **Breaking change**: `Activity` must implement `IntegrationPointProvider` and create `IntegrationPoint` manually. Weak references usage has been removed. -- [#173](https://github.com/bumble-tech/appyx/pull/173) – **Breaking change**: `ActivityStarter` and `PermissionRequester` now exposes coroutine based API instead of `minimal.reactive`. -- [#200](https://github.com/bumble-tech/appyx/pull/200) – **Breaking change**: Reordered the parameters for `ParentNode.Child` and `fun NodeHost` to meet Compose guidelines. -- [#43](https://github.com/bumble-tech/appyx/pull/43) – **Updated**: Jetpack Compose to `1.2.1` and Kotlin to `1.7.10`. -- [#168](https://github.com/bumble-tech/appyx/pull/168) – **Updated**: Kotlin coroutines to `1.6.4`. -- [#171](https://github.com/bumble-tech/appyx/pull/171) – **Updated**: RIBs to `0.36.1`. -- [#212](https://github.com/bumble-tech/appyx/pull/212) – **Updated**: `Node` parent property is now public instead of private. -- [#174](https://github.com/bumble-tech/appyx/issues/174) – **Fixed**: `IntegrationPointExample` does not work with "do not keep activities" -- [#180](https://github.com/bumble-tech/appyx/pull/180) – **Added**: Ensure that `super.onSaveInstanceState()` was called to restore Node's state correctly - -
13 Oct 2022
- ---- - -## 1.0-alpha09 - -- [#151](https://github.com/bumble-tech/appyx/issues/151) - **Breaking change**: Renamed `Routing` to `NavTarget`. All related namings are affected (`RoutingElement`, `RoutingKey`, etc.) -- [#158](https://github.com/bumble-tech/appyx/issues/158) - **Breaking change**: Renamed `TransitionState` to `State` in all NavModel impls. Renamed `STASHED_IN_BACK_STACK` to `STASHED`. -- [#146](https://github.com/bumble-tech/appyx/issues/146) - **Breaking change**: Removed `FragmentIntegrationPoint`. Clients should use `ActivityIntegrationPoint.getIntegrationPoint(context: Context)` to get integration point from Fragment -- [#160](https://github.com/bumble-tech/appyx/issues/160) - **Breaking change**: Renamed `navmodel-addons` to `navmodel-samples` and stopped publishing the binary. If you feel we should add any of the samples to the main codebase, please let us know! -- [#138](https://github.com/bumble-tech/appyx/pull/138) - **Fixed**: `androidx.appcompat:appcompat` from is exposed via `api` within `com.bumble.appyx:core`. This prevents potential compilation bugs. -- [#143](https://github.com/bumble-tech/appyx/issues/143) - **Fixed**: Correctly exposed transitive dependencies that are part of the libraries ABI -- [#162](https://github.com/bumble-tech/appyx/pull/162) - **Fixed**: `NodeTestHelper`'s `moveTo` function can now move to `Lifecycle.State.DESTROYED`. The node itself has safeguards to prevent moving from destroyed state, and moving to destroyed is a valid test case. -- [#145](https://github.com/bumble-tech/appyx/issues/145) - **Updated**: `SpotlightSlider` now uses offset modifier with lambda -- [#159](https://github.com/bumble-tech/appyx/pull/159) - **Added**: `NodeHost` now takes modifier parameter to decorate the view of a root node -- [#162](https://github.com/bumble-tech/appyx/pull/162) - **Added**: `disposeOnDestroyPlugin` extension has been added to interop-rx2. This will allow Rx2 code to be easily disposed when the node it belongs to is destroyed. -- [#161](https://github.com/bumble-tech/appyx/pull/161) - **Added**: Operations helpers - -
22 Sep 2022
- ---- - -## 1.0-alpha08 - -- [#140](https://github.com/bumble-tech/appyx/issues/140) - **Breaking change**: Added `testing-ui-activity` module to avoid needing to add `testing-ui` as a debug implementation as part of instrumentation testing. See the linked issue for more details -- [#139](https://github.com/bumble-tech/appyx/pull/139) - **Fixed**: `IntegrationPoint` memory leak created by `ActivityIntegrationPoint` - -
12 Sep 2022
- ---- - -## 1.0-alpha07 - -- [#122](https://github.com/bumble-tech/appyx/pull/122) - **Breaking change**: `ChildEntry.ChildMode` is removed, now nodes are always created when a nav model changes (previously default behaviour) -- [#99](https://github.com/bumble-tech/appyx/pull/99) – **Breaking change**: Removed `IntegrationPointAppyxProvider` and made `ActivityIntegrationPoint`'s constructor private. Use `ActivityIntegrationPoint.createIntegrationPoint`. This uses a weak reference to keep track of the integration points, and will not introduce memory leaks. -- [#122](https://github.com/bumble-tech/appyx/pull/122) - **Added**: New `ChildEntry.KeepMode` that allows to destroy nodes that are currently not visible on the screen -- [#132](https://github.com/bumble-tech/appyx/pull/132) - **Added**: New `NodeComponentActivity` to extend when wanting to work with `ComponentActivity` as your base activity, eg when migrating from a project built from the Jetpack Compose template -- [#119](https://github.com/bumble-tech/appyx/pull/119) - **Fixed**: Lifecycle observers are invoked in incorrect order (child before parent) -- [#62](https://github.com/bumble-tech/appyx/pull/62) - **Fixed**: Node is marked with stable annotation making some of the composable functions skippable -- [#129](https://github.com/bumble-tech/appyx/pull/129) - **Updated**: Removed sealed interface from operations to allow client to define their own -- [#133](https://github.com/bumble-tech/appyx/pull/133) - **Updated**: `NodeView` interface and `ParentNode` marked as stable improving amount of skippable composables - -
9 Sep 2022
- ---- - -## 1.0-alpha06 - -- [#96](https://github.com/bumble-tech/appyx/pull/96) – **Breaking change**: Removed `InteractorTestHelper`. Please use Node tests instead of Interactor tests. -- [#99](https://github.com/bumble-tech/appyx/pull/99) – **Breaking change**: Modified package of `NodeConnector` and `Connectable` -- [#99](https://github.com/bumble-tech/appyx/pull/99) – **Added**: Source.rx2() to convert Source to io.reactivex.Observable -- [#107](https://github.com/bumble-tech/appyx/pull/107) – **Fixed**: Back press handlers are not properly registered on lifecycle events - -
26 Aug 2022
- ---- - -## 1.0-alpha05 - -- [#83](https://github.com/bumble-tech/appyx/issues/83) – **Breaking change**: `RoutingSource` renamed to `NavModel`. All subclasses, fields, package names, etc., any mentions of the word follow suit. -- [#91](https://github.com/bumble-tech/appyx/pull/91) – **Fixed**: Spotlight next and previous operations crash fix - -
19 Aug 2022
- ---- - -## 1.0-alpha04 - -- [#39](https://github.com/bumble-tech/appyx/pull/39) – **Added**: Workflows implementation to support deeplinks -- [#32](https://github.com/bumble-tech/appyx/pull/32) – **Added**: `BackPressHandler` plugin that allows to control back press behaviour via `androidx.activity.OnBackPressedCallback` -- [#59](https://github.com/bumble-tech/appyx/issues/59) – **Added**: interface for `ParentNodeView<>` -- [#32](https://github.com/bumble-tech/appyx/issues/69) – **Added**: Jetpack Compose Navigation code sample -- [#81](https://github.com/bumble-tech/appyx/issues/81) – **Added**: Support integration point for multiple roots -- [#65](https://github.com/bumble-tech/appyx/pull/65) – **Added**: `InteropBuilderStub` and `InteropSimpleBuilderStub` testing util classes -- [#47](https://github.com/bumble-tech/appyx/issues/47) – **Updated**: The `customisations` module is now pure Java/Kotlin. -- [#85](https://github.com/bumble-tech/appyx/issues/85) – **Updated**: Improved `InteropView` error messaging when `Activity` does not implement `IntegrationPointAppyxProvider` -- [#88](https://github.com/bumble-tech/appyx/issues/88) – **Updated**: Moved `TestUpNavigationHandler` to `testing-unit-common` - -
18 Aug 2022
- ---- - -## 1.0-alpha03 - -- [#38](https://github.com/bumble-tech/appyx/pull/38) – **Added**: JUnit5 support - -
2 Aug 2022
- ---- - -## 1.0-alpha02 - -- [#19](https://github.com/bumble-tech/appyx/pull/19) – **Fixed**: Do not allow setting `Node.integrationPoint` on non-root nodes -- [#23](https://github.com/bumble-tech/appyx/pull/21) – **Fixed**: Integration point attached twice crash when using live literals -- [#14](https://github.com/bumble-tech/appyx/issues/14) – **Fixed**: Transition interruptions bug -- [#23](https://github.com/bumble-tech/appyx/pull/23) – **Added**: Unit test support -- [#26](https://github.com/bumble-tech/appyx/issues/26) – **Added**: Publish snapshot versions -- [#9](https://github.com/bumble-tech/appyx/pull/9) – **Migrated**: [app-tree-utils](https://github.com/badoo/app-tree-utils) into this repository - -
19 Jul 2022
- ---- - -## 1.0-alpha01 - -- Initial release - -
4 Jul 2022
diff --git a/documentation/1.x/releases/downloads.md b/documentation/1.x/releases/downloads.md deleted file mode 100644 index bd8713d96..000000000 --- a/documentation/1.x/releases/downloads.md +++ /dev/null @@ -1,66 +0,0 @@ -{% include-markdown "../deprecation.md" %} - -# Downloads - -## Latest version - -![Maven Central](https://img.shields.io/maven-central/v/com.bumble.appyx/core) - -## Repository - -```groovy -repositories { - mavenCentral() -} -``` - -## Core dependencies - -```groovy -dependencies { - // Core - implementation "com.bumble.appyx:core:$version" - - // Test rules and utility classes for testing on Android - debugImplementation "com.bumble.appyx:testing-ui-activity:$version" - androidTestImplementation "com.bumble.appyx:testing-ui:$version" - - // Utility classes for unit testing - testImplementation "com.bumble.appyx:testing-unit-common:$version" - - // Test rules and utility classes for unit testing using JUnit4 - testImplementation "com.bumble.appyx:testing-junit4:$version" - - // Test extensions and utility classes for unit testing using JUnit5 - testImplementation "com.bumble.appyx:testing-junit5:$version" -} -``` - -## Interop with other libraries - -```groovy -dependencies { - // Optional support for RxJava 2/3 - implementation "com.bumble.appyx:interop-rx2:$version" - implementation "com.bumble.appyx:interop-rx3:$version" - - // Optional interoperability layer between Appyx and badoo/RIBs - // You have to add https://jitpack.io repository to use it because badoo/RIBs is hosted there - implementation "com.bumble.appyx:interop-ribs:$version" - -} -``` - -## Snapshot - -Snapshot version is available for all modules, use the provided repository url and `1-SNAPSHOT` version. - -```groovy -repositories { - maven { url = 'https://s01.oss.sonatype.org/content/repositories/snapshots/' } -} - -dependencies { - implementation "com.bumble.appyx:core:v1-SNAPSHOT" -} -``` diff --git a/documentation/components/backstack.md b/documentation/2.x/components/backstack.md similarity index 100% rename from documentation/components/backstack.md rename to documentation/2.x/components/backstack.md diff --git a/documentation/components/experimental.md b/documentation/2.x/components/experimental.md similarity index 100% rename from documentation/components/experimental.md rename to documentation/2.x/components/experimental.md diff --git a/documentation/components/index.md b/documentation/2.x/components/index.md similarity index 100% rename from documentation/components/index.md rename to documentation/2.x/components/index.md diff --git a/documentation/components/spotlight.md b/documentation/2.x/components/spotlight.md similarity index 100% rename from documentation/components/spotlight.md rename to documentation/2.x/components/spotlight.md diff --git a/documentation/2.x/experimental.md b/documentation/2.x/experimental.md new file mode 100644 index 000000000..86af41a05 --- /dev/null +++ b/documentation/2.x/experimental.md @@ -0,0 +1,11 @@ +!!! failure "Experimental warning" + + We’re stopping the development of Appyx 2.x until further notice. + + We’re fully committed to maintaining and developing new features for the stable 1.x version of Appyx. + + We recommend you use that version instead. The code for 2.x you can find in the `2.x` branch of the repository. + + **[Documentation root](../index.md)** + +--- diff --git a/documentation/2.x/faq.md b/documentation/2.x/faq.md new file mode 100644 index 000000000..db48147ab --- /dev/null +++ b/documentation/2.x/faq.md @@ -0,0 +1,114 @@ +--- +title: FAQ +--- + +# 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! diff --git a/documentation/index_2.x.md b/documentation/2.x/index.md similarity index 92% rename from documentation/index_2.x.md rename to documentation/2.x/index.md index 51b9733fb..fc30f9919 100644 --- a/documentation/index_2.x.md +++ b/documentation/2.x/index.md @@ -2,10 +2,6 @@ title: Appyx 2.x (experimental) – Overview --- -# Disclaimer - -We’re stopping the development of Appyx 2.x until further notice. We’re fully committed to maintaining and developing new features for the stable 1.x version of Appyx. We recommend you use that version instead - # Appyx ![badge-android](https://img.shields.io/badge/platform-android-brightgreen) @@ -119,12 +115,12 @@ Stacks, custom pagers, custom UI components – whether for navigation, or stand ## 2.x migration guide -If you used Appyx `1.x` before, you can find a [summary of differences](2.x/migrationguide.md) here. +If you used Appyx `1.x` before, you can find a [summary of differences](migrationguide.md) here. ## 1.x documentation This page is about Appyx `2.x` (alpha). -You can find `1.x` related documentation [here](1.x/index.md). +You can find `1.x` related documentation [here](../index.md). diff --git a/documentation/interactions/appyxcomponent.md b/documentation/2.x/interactions/appyxcomponent.md similarity index 100% rename from documentation/interactions/appyxcomponent.md rename to documentation/2.x/interactions/appyxcomponent.md diff --git a/documentation/interactions/gestures.md b/documentation/2.x/interactions/gestures.md similarity index 100% rename from documentation/interactions/gestures.md rename to documentation/2.x/interactions/gestures.md diff --git a/documentation/interactions/index.md b/documentation/2.x/interactions/index.md similarity index 100% rename from documentation/interactions/index.md rename to documentation/2.x/interactions/index.md diff --git a/documentation/interactions/ksp.md b/documentation/2.x/interactions/ksp.md similarity index 100% rename from documentation/interactions/ksp.md rename to documentation/2.x/interactions/ksp.md diff --git a/documentation/interactions/operations.md b/documentation/2.x/interactions/operations.md similarity index 100% rename from documentation/interactions/operations.md rename to documentation/2.x/interactions/operations.md diff --git a/documentation/interactions/transitionmodel.md b/documentation/2.x/interactions/transitionmodel.md similarity index 100% rename from documentation/interactions/transitionmodel.md rename to documentation/2.x/interactions/transitionmodel.md diff --git a/documentation/interactions/ui-representation.md b/documentation/2.x/interactions/ui-representation.md similarity index 100% rename from documentation/interactions/ui-representation.md rename to documentation/2.x/interactions/ui-representation.md diff --git a/documentation/interactions/usage.md b/documentation/2.x/interactions/usage.md similarity index 100% rename from documentation/interactions/usage.md rename to documentation/2.x/interactions/usage.md diff --git a/documentation/2.x/migrationguide.md b/documentation/2.x/migrationguide.md index 3501b1a5c..90b99c728 100644 --- a/documentation/2.x/migrationguide.md +++ b/documentation/2.x/migrationguide.md @@ -21,7 +21,7 @@ The library is packaged as multiple artifacts. - Android library - Compose Multiplatform. -Check also [Multiplatform](../navigation/multiplatform.md) documentation and the `:demos:appyx-navigation` module for code examples. +Check also [Multiplatform](navigation/multiplatform.md) documentation and the `:demos:appyx-navigation` module for code examples. #### :appyx-interactions @@ -52,7 +52,7 @@ Check also [Multiplatform](../navigation/multiplatform.md) documentation and the #### Core -Note that [BackStack](../components/backstack.md) and [Spotlight](../components/spotlight.md) are now standalone artifacts. Check your usage, you might only need `backstack`: +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") diff --git a/documentation/navigation/concepts/composable-navigation.md b/documentation/2.x/navigation/concepts/composable-navigation.md similarity index 97% rename from documentation/navigation/concepts/composable-navigation.md rename to documentation/2.x/navigation/concepts/composable-navigation.md index 1f99e7869..0f4e562dc 100644 --- a/documentation/navigation/concepts/composable-navigation.md +++ b/documentation/2.x/navigation/concepts/composable-navigation.md @@ -1,88 +1,88 @@ ---- -title: Appyx Navigation – Composable navigation ---- - -# Composable navigation - -[AppyxComponents](../../components/index.md) in Appyx are composable. - -As a single `AppyxComponent` won't be enough for the whole of your whole app, you can use many in a composable way. That is, any managed element of a `AppyxComponent` can also host its own `AppyxComponent`. - - -## Nodes – structural elements for composing navigation - -```Nodes``` are the main structural element in Appyx. They can form a tree. - -You can think of a `Node` as a standalone unit of your app with: - -- Its own `AppyxComponent` -- Its own [Lifecycle](../features/lifecycle.md) -- State restoration -- A `@Composable` view -- Business logic that's kept alive even when the view isn't added to the composition -- The ability to host generic [Plugins](../features/plugins.md) to extract extra concerns without enforcing any particular architectural pattern - -This allows you to make your app's business logic also composable by leveraging `Nodes` as lifecycled components. - - -## Parent nodes, child nodes - -`Nodes` can have other `Nodes` as children. This means you can represent your whole application as a tree of Appyx nodes. - - - -You can go as granular or as high-level as it fits you. This allows to keep the complexity low in individual `Nodes` by extracting responsibilities to children, as well as composing other components to build more complex functionality. - - -## ChildAware API - -A `Node` can react to dynamically added child `Nodes` in the tree: [ChildAware API](../features/childaware.md) - - -## Navigation in the tree - - - -Once you've structured your navigation in a composable way, you can add an `AppyxComponent` to a `Node` of this tree and make it dynamic: - -- Some parts in this tree are active while others ore not -- The active parts define what state the application is in, and what the user sees on the screen -- We can change what's active by using an `AppyxComponent` on each level of the tree -- Changes will feel like navigation to the user - -See [Implicit navigation](implicit-navigation.md) and [Explicit navigation](explicit-navigation.md) for building complex navigation behaviours with this approach. - - - -## How AppyxComponents affect Nodes - -`AppyxComponent` operations will typically result in: - -- Adding or removing child `Nodes` of a `Node` -- Move them on and off the screen -- Change their states - -As an illustration: - - - -Here: - -- `Back stack` illustrates adding and removing child `Nodes` -- `Tiles` illustrates changing the state of children and removing them from the `Node` - -These are just two examples, you're of course not limited to using them. - - - -## Summary - -A summary of Appyx's approach to structuring applications: - -- Compose your app out of `Nodes` with their own lifecycles and state -- Navigation is local, composed of individual pieces of `AppyxComponents` -- Navigation is stateful -- Navigation is unit-testable -- Nested navigation and multi-module navigation works as a default -- You're free to implement your own navigable components by utilising `AppyxComponents` -- Avoid global navigation concerns, like shared modules needing to know about the application, or the application needing to know about all its possible modules +--- +title: Appyx Navigation – Composable navigation +--- + +# Composable navigation + +[AppyxComponents](../../components/index.md) in Appyx are composable. + +As a single `AppyxComponent` won't be enough for the whole of your whole app, you can use many in a composable way. That is, any managed element of a `AppyxComponent` can also host its own `AppyxComponent`. + + +## Nodes – structural elements for composing navigation + +```Nodes``` are the main structural element in Appyx. They can form a tree. + +You can think of a `Node` as a standalone unit of your app with: + +- Its own `AppyxComponent` +- Its own [Lifecycle](../features/lifecycle.md) +- State restoration +- A `@Composable` view +- Business logic that's kept alive even when the view isn't added to the composition +- The ability to host generic [Plugins](../features/plugins.md) to extract extra concerns without enforcing any particular architectural pattern + +This allows you to make your app's business logic also composable by leveraging `Nodes` as lifecycled components. + + +## Parent nodes, child nodes + +`Nodes` can have other `Nodes` as children. This means you can represent your whole application as a tree of Appyx nodes. + + + +You can go as granular or as high-level as it fits you. This allows to keep the complexity low in individual `Nodes` by extracting responsibilities to children, as well as composing other components to build more complex functionality. + + +## ChildAware API + +A `Node` can react to dynamically added child `Nodes` in the tree: [ChildAware API](../features/childaware.md) + + +## Navigation in the tree + + + +Once you've structured your navigation in a composable way, you can add an `AppyxComponent` to a `Node` of this tree and make it dynamic: + +- Some parts in this tree are active while others ore not +- The active parts define what state the application is in, and what the user sees on the screen +- We can change what's active by using an `AppyxComponent` on each level of the tree +- Changes will feel like navigation to the user + +See [Implicit navigation](implicit-navigation.md) and [Explicit navigation](explicit-navigation.md) for building complex navigation behaviours with this approach. + + + +## How AppyxComponents affect Nodes + +`AppyxComponent` operations will typically result in: + +- Adding or removing child `Nodes` of a `Node` +- Move them on and off the screen +- Change their states + +As an illustration: + + + +Here: + +- `Back stack` illustrates adding and removing child `Nodes` +- `Tiles` illustrates changing the state of children and removing them from the `Node` + +These are just two examples, you're of course not limited to using them. + + + +## Summary + +A summary of Appyx's approach to structuring applications: + +- Compose your app out of `Nodes` with their own lifecycles and state +- Navigation is local, composed of individual pieces of `AppyxComponents` +- Navigation is stateful +- Navigation is unit-testable +- Nested navigation and multi-module navigation works as a default +- You're free to implement your own navigable components by utilising `AppyxComponents` +- Avoid global navigation concerns, like shared modules needing to know about the application, or the application needing to know about all its possible modules diff --git a/documentation/navigation/concepts/explicit-navigation.md b/documentation/2.x/navigation/concepts/explicit-navigation.md similarity index 96% rename from documentation/navigation/concepts/explicit-navigation.md rename to documentation/2.x/navigation/concepts/explicit-navigation.md index 7b1bb8edf..b9ef884a9 100644 --- a/documentation/navigation/concepts/explicit-navigation.md +++ b/documentation/2.x/navigation/concepts/explicit-navigation.md @@ -1,213 +1,213 @@ ---- -title: Appyx Navigation – Explicit navigation ---- - -# Explicit navigation - -When [Implicit navigation](implicit-navigation.md) doesn't fit your use case, you can try an explicit approach. - -!!! info "Relevant methods" - - - Node.attachChild() - - Node.waitForChildAttached() - -Using these methods we can chain together a path which leads from the root of the tree to a specific `Node`. - -## Use case - -We want to navigate from `Chat` - - - -to onboarding's first screen `O1`: - - - -This time we'll want to do this explicitly by calling a function. - - -## The plan - -1. Create a public method on `Root` that attaches `Onboarding` -2. Create a public method on `Onboarding` that attaches the first onboarding screen -3. Create a `Navigator`, that starting from an instance of `Root`, can chain these public methods together into a single action: `navigateToO1()` -4. Capture an instance of `Root` to use with `Navigator` -5. Call `navigateToO1()` on our `Navigator` instance - - -## Step 1 – `Root` → `Onboarding` - -First, we need to define how to programmatically attach `Onboarding` to the `Root`: - -```kotlin -class RootNode( - nodeContext: NodeContext, - backStack: BackStack -) : Node( - nodeContext = nodeContext, - appyxComponent = backStack, -) { - - suspend fun attachOnboarding(): OnboardingNode { - return attachChild { - backStack.replace(NavTarget.Onboarding) - } - } -} -``` - -Let's break down what happens here: - -1. Since `attachChild` has a generic `` return type, it will conform to the defined `OnboardingNode` type -2. However, `attachChild` doesn't know how to create navigation to `OnboardingNode` – that's something only we can do with the provided lambda -3. We replace `NavTarget.Onboarding` into the back stack -4. Doing this _should_ result in `OnboardingNode` being created and added to `RootNode` as a child -5. `attachChild` expects an instance of `OnboardingNode` to appear as a child of `Root` as a consequence of executing our lambda -6. Once it appears, `attachChild` returns it - - -!!! info "Important" - - It's our responsibility to make sure that the provided lambda actually results in the expected child being added. If we accidentally do something else instead, for example: - - ```kotlin - suspend fun attachOnboarding(): OnboardingNode { - return attachChild { - backStack.replace(NavTarget.Main) // Wrong NavTarget - } - } - ``` - - Then an exception will be thrown after a timeout. - - -## Step 2 – `Onboarding` → `O1` - -Unlike `Root`, `Onboarding` uses [Spotlight](../../components/spotlight.md) instead of [BackStack](../../components/backstack.md) as an `AppyxComponent`, so navigation to the first screen is slightly different: - -```kotlin -class OnboardingNode( - nodeContext: NodeContext, - spotlight: Spotlight -) : Node( - nodeContext = nodeContext, - appyxComponent = spotlight, -) { - - suspend fun attachO1(): O1Node { - return attachChild { - spotlight.activate(index = 0) - } - } -} -``` - - -## Step 3 – Our `Navigator` - -```kotlin -interface Navigator { - fun navigateToO1() -} -``` - -In this case we'll implement it directly with our activity: - -```kotlin -class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { - - lateinit var rootNode: RootNode // See the next step - - override fun navigateToO1() { - lifecycleScope.launch { - rootNode - .attachOnboarding() - .attachO1() - } - } -} -``` - -## Step 4 – An instance of `RootNode` - -As the last piece of the puzzle, we'll also need to capture the instance of `RootNode` to make it all work. We can do that by a `NodeReadyObserver` plugin when setting up our tree: - - -```kotlin -class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { - - lateinit var rootNode: RootNode - - override fun navigateToO1() { /*...*/ } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - NodeHost(integrationPoint = appyxIntegrationPoint) { - RootNode( - nodeContext = it, - navigator = this@ExplicitNavigationExampleActivity, - plugins = listOf(object : NodeReadyObserver { - override fun init(node: RootNode) { - rootNode = node - } - }) - ) - } - } - } -} -``` - -## Step 5 – Using the `Navigator` - -See how in the previous snippet `RootNode` receives a `navigator` dependency. - -It can pass it further down the tree as a dependency to other nodes. Those nodes can call the methods of the `Navigator`, which will change the global navigation state directly. - - ---- - -## Bonus: Wait for a child to be attached - -There might be cases when we want to wait for a certain action to be _performed by the user_, rather than us, to result in a child being attached. - -In these cases we can use `Node.waitForChildAttached()` instead. - - -### Use case – Wait for login - -A typical case building an explicit navigation chain that relies on `Logged in` being attached. Most probably `Logged in` has a dependency on some kind of a `User` object. Here we want to wait for the user to authenticate themselves, rather than creating a dummy user object ourselves. - - -```kotlin -class RootNode( - nodeContext: NodeContext, -) : Node( - nodeContext = nodeContext -) { - - suspend fun waitForLoggedIn(): LoggedInNode = - waitForChildAttached() -} -``` - -This method will wait for `LoggedInNode` to appear in the child list of `RootNode` and return with it. If it's already there, it returns immediately. - -A navigation chain using it could look like: - -```kotlin -class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { - - override fun navigateToProfile() { - lifecycleScope.launch { - rootNode - .waitForLoggedIn() - .attachMain() - .attachProfile() - } - } -} -``` - -You can find related code examples in `ExplicitNavigationExampleActivity` in our samples. +--- +title: Appyx Navigation – Explicit navigation +--- + +# Explicit navigation + +When [Implicit navigation](implicit-navigation.md) doesn't fit your use case, you can try an explicit approach. + +!!! info "Relevant methods" + + - Node.attachChild() + - Node.waitForChildAttached() + +Using these methods we can chain together a path which leads from the root of the tree to a specific `Node`. + +## Use case + +We want to navigate from `Chat` + + + +to onboarding's first screen `O1`: + + + +This time we'll want to do this explicitly by calling a function. + + +## The plan + +1. Create a public method on `Root` that attaches `Onboarding` +2. Create a public method on `Onboarding` that attaches the first onboarding screen +3. Create a `Navigator`, that starting from an instance of `Root`, can chain these public methods together into a single action: `navigateToO1()` +4. Capture an instance of `Root` to use with `Navigator` +5. Call `navigateToO1()` on our `Navigator` instance + + +## Step 1 – `Root` → `Onboarding` + +First, we need to define how to programmatically attach `Onboarding` to the `Root`: + +```kotlin +class RootNode( + nodeContext: NodeContext, + backStack: BackStack +) : Node( + nodeContext = nodeContext, + appyxComponent = backStack, +) { + + suspend fun attachOnboarding(): OnboardingNode { + return attachChild { + backStack.replace(NavTarget.Onboarding) + } + } +} +``` + +Let's break down what happens here: + +1. Since `attachChild` has a generic `` return type, it will conform to the defined `OnboardingNode` type +2. However, `attachChild` doesn't know how to create navigation to `OnboardingNode` – that's something only we can do with the provided lambda +3. We replace `NavTarget.Onboarding` into the back stack +4. Doing this _should_ result in `OnboardingNode` being created and added to `RootNode` as a child +5. `attachChild` expects an instance of `OnboardingNode` to appear as a child of `Root` as a consequence of executing our lambda +6. Once it appears, `attachChild` returns it + + +!!! info "Important" + + It's our responsibility to make sure that the provided lambda actually results in the expected child being added. If we accidentally do something else instead, for example: + + ```kotlin + suspend fun attachOnboarding(): OnboardingNode { + return attachChild { + backStack.replace(NavTarget.Main) // Wrong NavTarget + } + } + ``` + + Then an exception will be thrown after a timeout. + + +## Step 2 – `Onboarding` → `O1` + +Unlike `Root`, `Onboarding` uses [Spotlight](../../components/spotlight.md) instead of [BackStack](../../components/backstack.md) as an `AppyxComponent`, so navigation to the first screen is slightly different: + +```kotlin +class OnboardingNode( + nodeContext: NodeContext, + spotlight: Spotlight +) : Node( + nodeContext = nodeContext, + appyxComponent = spotlight, +) { + + suspend fun attachO1(): O1Node { + return attachChild { + spotlight.activate(index = 0) + } + } +} +``` + + +## Step 3 – Our `Navigator` + +```kotlin +interface Navigator { + fun navigateToO1() +} +``` + +In this case we'll implement it directly with our activity: + +```kotlin +class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { + + lateinit var rootNode: RootNode // See the next step + + override fun navigateToO1() { + lifecycleScope.launch { + rootNode + .attachOnboarding() + .attachO1() + } + } +} +``` + +## Step 4 – An instance of `RootNode` + +As the last piece of the puzzle, we'll also need to capture the instance of `RootNode` to make it all work. We can do that by a `NodeReadyObserver` plugin when setting up our tree: + + +```kotlin +class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { + + lateinit var rootNode: RootNode + + override fun navigateToO1() { /*...*/ } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + NodeHost(integrationPoint = appyxIntegrationPoint) { + RootNode( + nodeContext = it, + navigator = this@ExplicitNavigationExampleActivity, + plugins = listOf(object : NodeReadyObserver { + override fun init(node: RootNode) { + rootNode = node + } + }) + ) + } + } + } +} +``` + +## Step 5 – Using the `Navigator` + +See how in the previous snippet `RootNode` receives a `navigator` dependency. + +It can pass it further down the tree as a dependency to other nodes. Those nodes can call the methods of the `Navigator`, which will change the global navigation state directly. + + +--- + +## Bonus: Wait for a child to be attached + +There might be cases when we want to wait for a certain action to be _performed by the user_, rather than us, to result in a child being attached. + +In these cases we can use `Node.waitForChildAttached()` instead. + + +### Use case – Wait for login + +A typical case building an explicit navigation chain that relies on `Logged in` being attached. Most probably `Logged in` has a dependency on some kind of a `User` object. Here we want to wait for the user to authenticate themselves, rather than creating a dummy user object ourselves. + + +```kotlin +class RootNode( + nodeContext: NodeContext, +) : Node( + nodeContext = nodeContext +) { + + suspend fun waitForLoggedIn(): LoggedInNode = + waitForChildAttached() +} +``` + +This method will wait for `LoggedInNode` to appear in the child list of `RootNode` and return with it. If it's already there, it returns immediately. + +A navigation chain using it could look like: + +```kotlin +class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { + + override fun navigateToProfile() { + lifecycleScope.launch { + rootNode + .waitForLoggedIn() + .attachMain() + .attachProfile() + } + } +} +``` + +You can find related code examples in `ExplicitNavigationExampleActivity` in our samples. diff --git a/documentation/navigation/concepts/implicit-navigation.md b/documentation/2.x/navigation/concepts/implicit-navigation.md similarity index 100% rename from documentation/navigation/concepts/implicit-navigation.md rename to documentation/2.x/navigation/concepts/implicit-navigation.md diff --git a/documentation/navigation/concepts/model-driven-navigation.md b/documentation/2.x/navigation/concepts/model-driven-navigation.md similarity index 100% rename from documentation/navigation/concepts/model-driven-navigation.md rename to documentation/2.x/navigation/concepts/model-driven-navigation.md diff --git a/documentation/navigation/features/childaware.md b/documentation/2.x/navigation/features/childaware.md similarity index 100% rename from documentation/navigation/features/childaware.md rename to documentation/2.x/navigation/features/childaware.md diff --git a/documentation/navigation/features/deep-linking.md b/documentation/2.x/navigation/features/deep-linking.md similarity index 100% rename from documentation/navigation/features/deep-linking.md rename to documentation/2.x/navigation/features/deep-linking.md diff --git a/documentation/navigation/features/lifecycle.md b/documentation/2.x/navigation/features/lifecycle.md similarity index 100% rename from documentation/navigation/features/lifecycle.md rename to documentation/2.x/navigation/features/lifecycle.md diff --git a/documentation/navigation/features/material3.md b/documentation/2.x/navigation/features/material3.md similarity index 100% rename from documentation/navigation/features/material3.md rename to documentation/2.x/navigation/features/material3.md diff --git a/documentation/navigation/features/plugins.md b/documentation/2.x/navigation/features/plugins.md similarity index 100% rename from documentation/navigation/features/plugins.md rename to documentation/2.x/navigation/features/plugins.md diff --git a/documentation/navigation/features/scoped-di.md b/documentation/2.x/navigation/features/scoped-di.md similarity index 100% rename from documentation/navigation/features/scoped-di.md rename to documentation/2.x/navigation/features/scoped-di.md diff --git a/documentation/navigation/features/surviving-configuration-changes.md b/documentation/2.x/navigation/features/surviving-configuration-changes.md similarity index 100% rename from documentation/navigation/features/surviving-configuration-changes.md rename to documentation/2.x/navigation/features/surviving-configuration-changes.md diff --git a/documentation/navigation/index.md b/documentation/2.x/navigation/index.md similarity index 100% rename from documentation/navigation/index.md rename to documentation/2.x/navigation/index.md diff --git a/documentation/navigation/integrations/compose-navigation.md b/documentation/2.x/navigation/integrations/compose-navigation.md similarity index 100% rename from documentation/navigation/integrations/compose-navigation.md rename to documentation/2.x/navigation/integrations/compose-navigation.md diff --git a/documentation/navigation/integrations/di-frameworks.md b/documentation/2.x/navigation/integrations/di-frameworks.md similarity index 100% rename from documentation/navigation/integrations/di-frameworks.md rename to documentation/2.x/navigation/integrations/di-frameworks.md diff --git a/documentation/navigation/integrations/ribs.md b/documentation/2.x/navigation/integrations/ribs.md similarity index 100% rename from documentation/navigation/integrations/ribs.md rename to documentation/2.x/navigation/integrations/ribs.md diff --git a/documentation/navigation/integrations/rx.md b/documentation/2.x/navigation/integrations/rx.md similarity index 100% rename from documentation/navigation/integrations/rx.md rename to documentation/2.x/navigation/integrations/rx.md diff --git a/documentation/navigation/integrations/viewmodel.md b/documentation/2.x/navigation/integrations/viewmodel.md similarity index 100% rename from documentation/navigation/integrations/viewmodel.md rename to documentation/2.x/navigation/integrations/viewmodel.md diff --git a/documentation/navigation/multiplatform.md b/documentation/2.x/navigation/multiplatform.md similarity index 100% rename from documentation/navigation/multiplatform.md rename to documentation/2.x/navigation/multiplatform.md diff --git a/documentation/navigation/quick-start.md b/documentation/2.x/navigation/quick-start.md similarity index 100% rename from documentation/navigation/quick-start.md rename to documentation/2.x/navigation/quick-start.md diff --git a/documentation/navigation/sample-app.md b/documentation/2.x/navigation/sample-app.md similarity index 100% rename from documentation/navigation/sample-app.md rename to documentation/2.x/navigation/sample-app.md diff --git a/documentation/releases/2.0.0-alpha10.md b/documentation/2.x/releases/2.0.0-alpha10.md similarity index 100% rename from documentation/releases/2.0.0-alpha10.md rename to documentation/2.x/releases/2.0.0-alpha10.md diff --git a/documentation/releases/2.0.0.md b/documentation/2.x/releases/2.0.0.md similarity index 100% rename from documentation/releases/2.0.0.md rename to documentation/2.x/releases/2.0.0.md diff --git a/documentation/2.x/releases/changelog.md b/documentation/2.x/releases/changelog.md new file mode 100644 index 000000000..03cb73106 --- /dev/null +++ b/documentation/2.x/releases/changelog.md @@ -0,0 +1 @@ +../../CHANGELOG.md diff --git a/documentation/2.x/releases/downloads.md b/documentation/2.x/releases/downloads.md new file mode 100644 index 000000000..a5defc870 --- /dev/null +++ b/documentation/2.x/releases/downloads.md @@ -0,0 +1,247 @@ +--- +title: Downloads +--- + +# Downloads + +## Latest version + +![Maven Central](https://img.shields.io/maven-central/v/com.bumble.appyx/appyx-navigation) + +## Repository + +```kotlin +repositories { + mavenCentral() +} +``` + + +## Appyx Navigation + +Adding the gradle dependency in a non-multiplatform project: + +```kotlin +dependencies { + // Platform-specific (pick the right one for your platform) + implementation("com.bumble.appyx:appyx-navigation-android:$version") + implementation("com.bumble.appyx:appyx-navigation-desktop:$version") + implementation("com.bumble.appyx:appyx-navigation-js:$version") + + // For iOS, you need separate dependencies for Simulator, x86 & Arm + implementation("com.bumble.appyx:appyx-navigation-iossimulatorarm64:$version") + implementation("com.bumble.appyx:appyx-navigation-iosx64:$version") + implementation("com.bumble.appyx:appyx-navigation-iosarm64:$version") +} +``` + +Adding the gradle dependency in a multiplatform project: + +```kotlin +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation("com.bumble.appyx:appyx-navigation:$version") + } + } + } +} +``` + +## Appyx Interactions + +Adding the gradle dependency in a non-multiplatform project: + +```kotlin +dependencies { + // Platform-specific (pick the right one for your platform) + implementation("com.bumble.appyx:appyx-interactions-android:$version") + implementation("com.bumble.appyx:appyx-interactions-desktop:$version") + implementation("com.bumble.appyx:appyx-interactions-js:$version") + + // For iOS, you need separate dependencies for Simulator, x86 & Arm + implementation("com.bumble.appyx:appyx-interactions-iossimulatorarm64:$version") + implementation("com.bumble.appyx:appyx-interactions-iosx64:$version") + implementation("com.bumble.appyx:appyx-interactions-iosarm64:$version") +} +``` + +Adding the gradle dependency in a multiplatform project: + +```kotlin +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation("com.bumble.appyx:appyx-interactions:$version") + } + } + } +} +``` + +## Appyx Components + +### Back stack + +Adding the gradle dependency in a non-multiplatform project: + +```kotlin +dependencies { + // Platform-specific (pick the right one for your platform) + implementation("com.bumble.appyx:backstack-android:$version") + implementation("com.bumble.appyx:backstack-desktop:$version") + implementation("com.bumble.appyx:backstack-js:$version") + + // For iOS, you need separate dependencies for Simulator, x86 & Arm + implementation("com.bumble.appyx:backstack-iossimulatorarm64:$version") + implementation("com.bumble.appyx:backstack-iosx64:$version") + implementation("com.bumble.appyx:backstack-iosarm64:$version") +} +``` + +Adding the gradle dependency in a multiplatform project: + +```kotlin +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + // Use api, not implementation! + api("com.bumble.appyx:backstack:$version") + } + } + + } +} +``` + +### Spotlight + +Adding the gradle dependency in a non-multiplatform project: + +```kotlin +dependencies { + // Platform-specific (pick the right one for your platform) + implementation("com.bumble.appyx:spotlight-android:$version") + implementation("com.bumble.appyx:spotlight-desktop:$version") + implementation("com.bumble.appyx:spotlight-js:$version") + + // For iOS, you need separate dependencies for Simulator, x86 & Arm + implementation("com.bumble.appyx:spotlight-iossimulatorarm64:$version") + implementation("com.bumble.appyx:spotlight-iosx64:$version") + implementation("com.bumble.appyx:spotlight-iosarm64:$version") +} +``` + +Adding the gradle dependency in a multiplatform project: + +```kotlin +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + // Use api, not implementation! + api("com.bumble.appyx:spotlight:$version") + } + } + + } +} +``` + +## Utils and interop with other libraries + +### Material 3 support + +Support for [Navigation bar](https://m3.material.io/components/navigation-bar/overview), [Navigation rail](https://m3.material.io/components/navigation-rail/overview) to use easily together with **Appyx Navigation**. + +See more in [Material 3 support](../navigation/features/material3.md). + +Adding the gradle dependency in a non-multiplatform project: + +```kotlin +dependencies { + // Platform-specific (pick the right one for your platform) + implementation("com.bumble.appyx:utils-material3-android:$version") + implementation("com.bumble.appyx:utils-material3-desktop:$version") + implementation("com.bumble.appyx:utils-material3-js:$version") + implementation("com.bumble.appyx:utils-material3-iosarm64:$version") + implementation("com.bumble.appyx:utils-material3-iossimulatorarm64:$version") + implementation("com.bumble.appyx:utils-material3-iosx64:$version") +} +``` + +Adding the gradle dependency in a multiplatform project: + +```kotlin +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + // Use api, not implementation! + api("com.bumble.appyx:utils-material3:$version") + } + } + } +} +``` + +### RxJava 2 + +```kotlin +dependencies { + // Optional support for RxJava 2/3 + implementation("com.bumble.appyx:utils-interop-rx2:$version") +} +``` + +### RxJava 3 + +```kotlin +dependencies { + implementation("com.bumble.appyx:utils-interop-rx3:$version") +} +``` + +### badoo/RIBs + +```kotlin +repositories { + // Don't forget to add this, since badoo/RIBs is hosted on jitpack: + maven(url = "https://jitpack.io") +} + +dependencies { + implementation("com.bumble.appyx:utils-interop-ribs:$version") +} +``` + +### RIBs like helpers + +Adds client code helper classes like `Builder`, `SimpleBuilder`, and `Interactor` + +```kotlin +dependencies { + implementation("com.bumble.appyx:utils-ribs-helpers:$version") +} +``` + + +### Testing + +```kotlin +// Test rules and utility classes for testing on Android +debugImplementation("com.bumble.appyx:utils-testing-ui-activity:$version") +androidTestImplementation("com.bumble.appyx:utils-testing-ui:$version") + +// Utility classes for unit testing +testImplementation("com.bumble.appyx:utils-testing-unit-common:$version") + +// Test rules and utility classes for unit testing using JUnit4 +testImplementation("com.bumble.appyx:utils-testing-junit4:$version") + +// Test extensions and utility classes for unit testing using JUnit5 +testImplementation("com.bumble.appyx:utils-testing-junit5:$version") +``` diff --git a/documentation/1.x/apps/childaware.md b/documentation/apps/childaware.md similarity index 98% rename from documentation/1.x/apps/childaware.md rename to documentation/apps/childaware.md index 31b1dede6..52695fcac 100644 --- a/documentation/1.x/apps/childaware.md +++ b/documentation/apps/childaware.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # ChildAware API diff --git a/documentation/1.x/apps/configuration.md b/documentation/apps/configuration.md similarity index 97% rename from documentation/1.x/apps/configuration.md rename to documentation/apps/configuration.md index 07112d1e4..1855dc470 100644 --- a/documentation/1.x/apps/configuration.md +++ b/documentation/apps/configuration.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Configuration change diff --git a/documentation/1.x/apps/lifecycle.md b/documentation/apps/lifecycle.md similarity index 97% rename from documentation/1.x/apps/lifecycle.md rename to documentation/apps/lifecycle.md index 9a5e77721..365206f14 100644 --- a/documentation/1.x/apps/lifecycle.md +++ b/documentation/apps/lifecycle.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Lifecycle diff --git a/documentation/1.x/apps/plugins.md b/documentation/apps/plugins.md similarity index 98% rename from documentation/1.x/apps/plugins.md rename to documentation/apps/plugins.md index 5c17863a9..4d7beab0b 100644 --- a/documentation/1.x/apps/plugins.md +++ b/documentation/apps/plugins.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Plugins diff --git a/documentation/1.x/apps/structure.md b/documentation/apps/structure.md similarity index 90% rename from documentation/1.x/apps/structure.md rename to documentation/apps/structure.md index 842722700..557f7089c 100644 --- a/documentation/1.x/apps/structure.md +++ b/documentation/apps/structure.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Structuring your app navigation @@ -24,7 +24,7 @@ You can think of a `Node` as a standalone component with: - State restoration - A `@Composable` view - Business logic that's kept alive even when the view isn't added to the composition -- The ability to host generic [Plugins](../apps/plugins.md) to extract extra concerns without enforcing any particular architectural pattern +- The ability to host generic [Plugins](.md) to extract extra concerns without enforcing any particular architectural pattern ## Parent nodes, child nodes @@ -49,7 +49,7 @@ Read more in [Composable navigation](../navigation/composable-navigation.md) Nodes have their own lifecycles, directly using the related classes of `androidx.lifecycle`. -Read more in [Lifecycle](../apps/lifecycle.md) +Read more in [Lifecycle](le.md) ## ChildAware API diff --git a/documentation/faq.md b/documentation/faq.md index db48147ab..265806d5b 100644 --- a/documentation/faq.md +++ b/documentation/faq.md @@ -1,42 +1,36 @@ ---- -title: FAQ ---- - # FAQ ## Navigation-related -#### **Q: How does Appyx Navigation relate to Jetpack Compose Navigation?** +#### **Q: How does Appyx 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. +We wrote an article on this: [Appyx vs Jetpack Compose Navigation](https://medium.com/bumble-tech/appyx-vs-jetpack-compose-navigation-b91bd23369f2) 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. +See [Sample apps](how-to-use-appyx/sample-apps.md) for more details. --- -#### **Q: How does Appyx Navigation compare against other solutions?** +#### **Q: How does Appyx compare against other navigation 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) +2. You can define your own navigation models 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. +See [Model-driven navigation](navigation/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. +In most cases [Implicit navigation](navigation/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. +For those cases when you can't avoid it, [Explicit navigation](navigation/explicit-navigation.md) and [Deep linking](navigation/deep-linking.md) covers you. --- @@ -47,9 +41,13 @@ 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. - --- +#### **Q: Can I have a bottom sheet conditionally?** + +You could use a similar approach as we do with back buttons in `SamplesContainerNode` you can find in the `:app` module: store a flag in the `NavTarget` that can be different per instance. + +--- ## Using Appyx in an app @@ -58,8 +56,8 @@ If you wish, you can model your own Modal with Appyx too. We'll add an example s 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) +- Plug it in to one screen and just utilise its screen transformation capabilities (e.g. [Cards](navmodel/cards.md)) +- Plug it in to a few screens and substitute another navigation mechanism with it, such as [Jetpack Compose Navigation](how-to-use-appyx/sample-apps.md#appyx-jetpack-compose-navigation-example) --- @@ -71,14 +69,15 @@ Appyx is agnostic of architectural patterns. You can use any architectural patte #### **Q: Can I use it with ViewModel?** -Please see [Appyx + ViewModel](navigation/integrations/viewmodel.md). +Yes, we'll add an example soon. --- #### **Q: Can I use it with Hilt?** -Please see [Appyx + DI frameworks](navigation/integrations/di-frameworks.md). +- Our draft PR: [#115](https://github.com/bumble-tech/appyx/pull/115) (Feel free to provide feedback!) +- [https://github.com/jbreitfeller-sfix/appyx-playground](https://github.com/jbreitfeller-sfix/appyx-playground) another approach on this topic --- @@ -92,7 +91,7 @@ In short: you can decide whether a `Node`: - 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. +Check the [Lifecycle](apps/lifecycle.md#on-screen-off-screen) for more details. --- @@ -101,14 +100,16 @@ Check the [Lifecycle](navigation/features/lifecycle.md#on-screen-off-screen) for #### **Q: Is it production ready?** -Appyx matured to its stable version in the `1.x` branch. +Yes, Appyx matured to its stable version. We also use it at Bumble in production, and as such, we're committed to maintaining and improving it. + +--- -The `2.x` branch is currently in alpha. +#### **Q: What's your roadmap?** -We use Appyx at Bumble in production, and as such, we're committed to maintaining and improving it. +We're full with ideas where to take Appyx further! A more detailed roadmap will be added later. Come back for more updates. --- ## Other -Have a question? Come over to **#appyx** on Kotlinlang Slack! +Have a question? Raise it in [Discussions](https://github.com/bumble-tech/appyx/discussions)!. diff --git a/documentation/1.x/how-to-use-appyx/codelabs.md b/documentation/how-to-use-appyx/codelabs.md similarity index 94% rename from documentation/1.x/how-to-use-appyx/codelabs.md rename to documentation/how-to-use-appyx/codelabs.md index 5db19dfe9..3a96d8aaa 100644 --- a/documentation/1.x/how-to-use-appyx/codelabs.md +++ b/documentation/how-to-use-appyx/codelabs.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Appyx codelabs diff --git a/documentation/1.x/how-to-use-appyx/coding-challenges.md b/documentation/how-to-use-appyx/coding-challenges.md similarity index 94% rename from documentation/1.x/how-to-use-appyx/coding-challenges.md rename to documentation/how-to-use-appyx/coding-challenges.md index 207d4afe2..a6846bb01 100644 --- a/documentation/1.x/how-to-use-appyx/coding-challenges.md +++ b/documentation/how-to-use-appyx/coding-challenges.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Appyx coding challenges diff --git a/documentation/1.x/how-to-use-appyx/quick-start.md b/documentation/how-to-use-appyx/quick-start.md similarity index 99% rename from documentation/1.x/how-to-use-appyx/quick-start.md rename to documentation/how-to-use-appyx/quick-start.md index 2bdcdd52d..abd0c20a9 100644 --- a/documentation/1.x/how-to-use-appyx/quick-start.md +++ b/documentation/how-to-use-appyx/quick-start.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Quick start guide diff --git a/documentation/1.x/how-to-use-appyx/sample-apps.md b/documentation/how-to-use-appyx/sample-apps.md similarity index 96% rename from documentation/1.x/how-to-use-appyx/sample-apps.md rename to documentation/how-to-use-appyx/sample-apps.md index e6ed660df..9ee9fefc4 100644 --- a/documentation/1.x/how-to-use-appyx/sample-apps.md +++ b/documentation/how-to-use-appyx/sample-apps.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Appyx sample apps diff --git a/documentation/1.x/index.md b/documentation/index.md similarity index 98% rename from documentation/1.x/index.md rename to documentation/index.md index d26b3dd91..81126abc9 100644 --- a/documentation/1.x/index.md +++ b/documentation/index.md @@ -1,5 +1,3 @@ -{% include-markdown "./deprecation.md" %} - # Appyx diff --git a/documentation/1.x/navigation/composable-navigation.md b/documentation/navigation/composable-navigation.md similarity index 95% rename from documentation/1.x/navigation/composable-navigation.md rename to documentation/navigation/composable-navigation.md index 1a0dc6973..b0d1bd52e 100644 --- a/documentation/1.x/navigation/composable-navigation.md +++ b/documentation/navigation/composable-navigation.md @@ -1,51 +1,51 @@ -{% include-markdown "../deprecation.md" %} - -# Composable navigation - -[NavModels](../navmodel/index.md) in Appyx are composable. - -As a single `NavModel` won't be enough for the whole of your whole app, you can use many in a composable way. That is, any navigation target of a `NavModel` can also host its own `NavModel`. - - -## Structural element for composing navigation - -```Nodes``` are the main structural element in Appyx. They can host `NavModels`, and they form a tree. - -This allows you to make your app's business logic also composable by leveraging `Nodes` as lifecycled components. - -Read more in [Structuring your app navigation](../apps/structure.md) - - -## Navigation in the tree - - - -Once you've structured your navigation in a composable way, you can add `NavModels` to `Node` of this tree and make it dynamic: - -- Some parts in this tree are active while others ore not -- The active parts define what state the application is in, and what the user sees on the screen -- We can change what's active by using `NavModels` on each level of the tree -- Changes will feel like navigation to the user - -See [Implicit navigation](implicit-navigation.md) and [Explicit navigation](explicit-navigation.md) for building complex navigation behaviours with this approach. - - - -## How NavModels affect Nodes - -NavModel operations will typically result in: - -- Adding or removing child `Nodes` of a `ParentNode` -- Move them on and off the screen -- Change their states - -As an illustration: - - - -Here: - -- `Back stack` illustrates adding and removing child `Nodes` -- `Tiles` illustrates changing the state of children and removing them from the `ParentNode` - -These are just two examples, you're of course not limited to using them. + + +# Composable navigation + +[NavModels](../navmodel/index.md) in Appyx are composable. + +As a single `NavModel` won't be enough for the whole of your whole app, you can use many in a composable way. That is, any navigation target of a `NavModel` can also host its own `NavModel`. + + +## Structural element for composing navigation + +```Nodes``` are the main structural element in Appyx. They can host `NavModels`, and they form a tree. + +This allows you to make your app's business logic also composable by leveraging `Nodes` as lifecycled components. + +Read more in [Structuring your app navigation](../apps/structure.md) + + +## Navigation in the tree + + + +Once you've structured your navigation in a composable way, you can add `NavModels` to `Node` of this tree and make it dynamic: + +- Some parts in this tree are active while others ore not +- The active parts define what state the application is in, and what the user sees on the screen +- We can change what's active by using `NavModels` on each level of the tree +- Changes will feel like navigation to the user + +See [Implicit navigation](implicit-navigation.md) and [Explicit navigation](explicit-navigation.md) for building complex navigation behaviours with this approach. + + + +## How NavModels affect Nodes + +NavModel operations will typically result in: + +- Adding or removing child `Nodes` of a `ParentNode` +- Move them on and off the screen +- Change their states + +As an illustration: + + + +Here: + +- `Back stack` illustrates adding and removing child `Nodes` +- `Tiles` illustrates changing the state of children and removing them from the `ParentNode` + +These are just two examples, you're of course not limited to using them. diff --git a/documentation/1.x/navigation/deep-linking.md b/documentation/navigation/deep-linking.md similarity index 96% rename from documentation/1.x/navigation/deep-linking.md rename to documentation/navigation/deep-linking.md index 8fc37cf0e..ae194a90d 100644 --- a/documentation/1.x/navigation/deep-linking.md +++ b/documentation/navigation/deep-linking.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Deep linking diff --git a/documentation/1.x/navigation/explicit-navigation.md b/documentation/navigation/explicit-navigation.md similarity index 96% rename from documentation/1.x/navigation/explicit-navigation.md rename to documentation/navigation/explicit-navigation.md index a9a0d3957..acfa21415 100644 --- a/documentation/1.x/navigation/explicit-navigation.md +++ b/documentation/navigation/explicit-navigation.md @@ -1,211 +1,211 @@ -{% include-markdown "../deprecation.md" %} - -# Explicit navigation - -When [Implicit navigation](implicit-navigation.md) doesn't fit your use case, you can try an explicit approach. - -!!! info "Relevant methods" - - - ParentNode.attachChild() - - ParentNode.waitForChildAttached() - -Using these methods we can chain together a path which leads from the root of the tree to a specific `Node`. - -## Use case - -We want to navigate from `Chat` - - - -to onboarding's first screen `O1`: - - - -This time we'll want to do this explicitly by calling a function. - - -## The plan - -1. Create a public method on `Root` that attaches `Onboarding` -2. Create a public method on `Onboarding` that attaches the first onboarding screen -3. Create a `Navigator`, that starting from an instance of `Root`, can chain these public methods together into a single action: `navigateToO1()` -4. Capture an instance of `Root` to use with `Navigator` -5. Call `navigateToO1()` on our `Navigator` instance - - -## Step 1 – `Root` → `Onboarding` - -First, we need to define how to programmatically attach `Onboarding` to the `Root`: - -```kotlin -class RootNode( - buildContext: BuildContext, - backStack: BackStack -) : ParentNode( - buildContext = buildContext, - navModel = backStack, -) { - - suspend fun attachOnboarding(): OnboardingNode { - return attachChild { - backStack.replace(NavTarget.Onboarding) - } - } -} -``` - -Let's break down what happens here: - -1. Since `attachChild` has a generic `` return type, it will conform to the defined `OnboardingNode` type -2. However, `attachChild` doesn't know how to create navigation to `OnboardingNode` – that's something only we can do with the provided lambda -3. We replace `NavTarget.Onboarding` into the back stack -4. Doing this _should_ result in `OnboardingNode` being created and added to `RootNode` as a child -5. `attachChild` expects an instance of `OnboardingNode` to appear as a child of `Root` as a consequence of executing our lambda -6. Once it appears, `attachChild` returns it - - -!!! info "Important" - - It's our responsibility to make sure that the provided lambda actually results in the expected child being added. If we accidentally do something else instead, for example: - - ```kotlin - suspend fun attachOnboarding(): OnboardingNode { - return attachChild { - backStack.replace(NavTarget.Main) // Wrong NavTarget - } - } - ``` - - Then an exception will be thrown after a timeout. - - -## Step 2 – `Onboarding` → `O1` - -Unlike `Root`, `Onboarding` uses [Spotlight](../navmodel/spotlight.md) instead of [BackStack](../navmodel/backstack.md) as a `NavModel`, so navigation to the first screen is slightly different: - -```kotlin -class OnboardingNode( - buildContext: BuildContext, - spotlight: Spotlight -) : ParentNode( - buildContext = buildContext, - navModel = spotlight, -) { - - suspend fun attachO1(): O1Node { - return attachChild { - spotlight.activate(index = 0) - } - } -} -``` - - -## Step 3 – Our `Navigator` - -```kotlin -interface Navigator { - fun navigateToO1() -} -``` - -In this case we'll implement it directly with our activity: - -```kotlin -class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { - - lateinit var rootNode: RootNode // See the next step - - override fun navigateToO1() { - lifecycleScope.launch { - rootNode - .attachOnboarding() - .attachO1() - } - } -} -``` - -## Step 4 – An instance of `RootNode` - -As the last piece of the puzzle, we'll also need to capture the instance of `RootNode` to make it all work. We can do that by a `NodeReadyObserver` plugin when setting up our tree: - - -```kotlin -class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { - - lateinit var rootNode: RootNode - - override fun navigateToO1() { /*...*/ } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - NodeHost(integrationPoint = appyxIntegrationPoint) { - RootNode( - buildContext = it, - navigator = this@ExplicitNavigationExampleActivity, - plugins = listOf(object : NodeReadyObserver { - override fun init(node: RootNode) { - rootNode = node - } - }) - ) - } - } - } -} -``` - -## Step 5 – Using the `Navigator` - -See how in the previous snippet `RootNode` receives a `navigator` dependency. - -It can pass it further down the tree as a dependency to other nodes. Those nodes can call the methods of the `Navigator`, which will change the global navigation state directly. - - ---- - -## Bonus: Wait for a child to be attached - -There might be cases when we want to wait for a certain action to be _performed by the user_, rather than us, to result in a child being attached. - -In these cases we can use `ParentNode.waitForChildAttached()` instead. - - -### Use case – Wait for login - -A typical case building an explicit navigation chain that relies on `Logged in` being attached. Most probably `Logged in` has a dependency on some kind of a `User` object. Here we want to wait for the user to authenticate themselves, rather than creating a dummy user object ourselves. - - -```kotlin -class RootNode( - buildContext: BuildContext, -) : ParentNode( - buildContext = buildContext -) { - - suspend fun waitForLoggedIn(): LoggedInNode = - waitForChildAttached() -} -``` - -This method will wait for `LoggedInNode` to appear in the child list of `RootNode` and return with it. If it's already there, it returns immediately. - -A navigation chain using it could look like: - -```kotlin -class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { - - override fun navigateToProfile() { - lifecycleScope.launch { - rootNode - .waitForLoggedIn() - .attachMain() - .attachProfile() - } - } -} -``` - -You can find related code examples in `ExplicitNavigationExampleActivity` in our samples. + + +# Explicit navigation + +When [Implicit navigation](implicit-navigation.md) doesn't fit your use case, you can try an explicit approach. + +!!! info "Relevant methods" + + - ParentNode.attachChild() + - ParentNode.waitForChildAttached() + +Using these methods we can chain together a path which leads from the root of the tree to a specific `Node`. + +## Use case + +We want to navigate from `Chat` + + + +to onboarding's first screen `O1`: + + + +This time we'll want to do this explicitly by calling a function. + + +## The plan + +1. Create a public method on `Root` that attaches `Onboarding` +2. Create a public method on `Onboarding` that attaches the first onboarding screen +3. Create a `Navigator`, that starting from an instance of `Root`, can chain these public methods together into a single action: `navigateToO1()` +4. Capture an instance of `Root` to use with `Navigator` +5. Call `navigateToO1()` on our `Navigator` instance + + +## Step 1 – `Root` → `Onboarding` + +First, we need to define how to programmatically attach `Onboarding` to the `Root`: + +```kotlin +class RootNode( + buildContext: BuildContext, + backStack: BackStack +) : ParentNode( + buildContext = buildContext, + navModel = backStack, +) { + + suspend fun attachOnboarding(): OnboardingNode { + return attachChild { + backStack.replace(NavTarget.Onboarding) + } + } +} +``` + +Let's break down what happens here: + +1. Since `attachChild` has a generic `` return type, it will conform to the defined `OnboardingNode` type +2. However, `attachChild` doesn't know how to create navigation to `OnboardingNode` – that's something only we can do with the provided lambda +3. We replace `NavTarget.Onboarding` into the back stack +4. Doing this _should_ result in `OnboardingNode` being created and added to `RootNode` as a child +5. `attachChild` expects an instance of `OnboardingNode` to appear as a child of `Root` as a consequence of executing our lambda +6. Once it appears, `attachChild` returns it + + +!!! info "Important" + + It's our responsibility to make sure that the provided lambda actually results in the expected child being added. If we accidentally do something else instead, for example: + + ```kotlin + suspend fun attachOnboarding(): OnboardingNode { + return attachChild { + backStack.replace(NavTarget.Main) // Wrong NavTarget + } + } + ``` + + Then an exception will be thrown after a timeout. + + +## Step 2 – `Onboarding` → `O1` + +Unlike `Root`, `Onboarding` uses [Spotlight](../navmodel/spotlight.md) instead of [BackStack](../navmodel/backstack.md) as a `NavModel`, so navigation to the first screen is slightly different: + +```kotlin +class OnboardingNode( + buildContext: BuildContext, + spotlight: Spotlight +) : ParentNode( + buildContext = buildContext, + navModel = spotlight, +) { + + suspend fun attachO1(): O1Node { + return attachChild { + spotlight.activate(index = 0) + } + } +} +``` + + +## Step 3 – Our `Navigator` + +```kotlin +interface Navigator { + fun navigateToO1() +} +``` + +In this case we'll implement it directly with our activity: + +```kotlin +class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { + + lateinit var rootNode: RootNode // See the next step + + override fun navigateToO1() { + lifecycleScope.launch { + rootNode + .attachOnboarding() + .attachO1() + } + } +} +``` + +## Step 4 – An instance of `RootNode` + +As the last piece of the puzzle, we'll also need to capture the instance of `RootNode` to make it all work. We can do that by a `NodeReadyObserver` plugin when setting up our tree: + + +```kotlin +class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { + + lateinit var rootNode: RootNode + + override fun navigateToO1() { /*...*/ } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + NodeHost(integrationPoint = appyxIntegrationPoint) { + RootNode( + buildContext = it, + navigator = this@ExplicitNavigationExampleActivity, + plugins = listOf(object : NodeReadyObserver { + override fun init(node: RootNode) { + rootNode = node + } + }) + ) + } + } + } +} +``` + +## Step 5 – Using the `Navigator` + +See how in the previous snippet `RootNode` receives a `navigator` dependency. + +It can pass it further down the tree as a dependency to other nodes. Those nodes can call the methods of the `Navigator`, which will change the global navigation state directly. + + +--- + +## Bonus: Wait for a child to be attached + +There might be cases when we want to wait for a certain action to be _performed by the user_, rather than us, to result in a child being attached. + +In these cases we can use `ParentNode.waitForChildAttached()` instead. + + +### Use case – Wait for login + +A typical case building an explicit navigation chain that relies on `Logged in` being attached. Most probably `Logged in` has a dependency on some kind of a `User` object. Here we want to wait for the user to authenticate themselves, rather than creating a dummy user object ourselves. + + +```kotlin +class RootNode( + buildContext: BuildContext, +) : ParentNode( + buildContext = buildContext +) { + + suspend fun waitForLoggedIn(): LoggedInNode = + waitForChildAttached() +} +``` + +This method will wait for `LoggedInNode` to appear in the child list of `RootNode` and return with it. If it's already there, it returns immediately. + +A navigation chain using it could look like: + +```kotlin +class ExplicitNavigationExampleActivity : NodeActivity(), Navigator { + + override fun navigateToProfile() { + lifecycleScope.launch { + rootNode + .waitForLoggedIn() + .attachMain() + .attachProfile() + } + } +} +``` + +You can find related code examples in `ExplicitNavigationExampleActivity` in our samples. diff --git a/documentation/1.x/navigation/implicit-navigation.md b/documentation/navigation/implicit-navigation.md similarity index 98% rename from documentation/1.x/navigation/implicit-navigation.md rename to documentation/navigation/implicit-navigation.md index 30f00b2a8..f03e61eab 100644 --- a/documentation/1.x/navigation/implicit-navigation.md +++ b/documentation/navigation/implicit-navigation.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Implicit navigation diff --git a/documentation/1.x/navigation/model-driven-navigation.md b/documentation/navigation/model-driven-navigation.md similarity index 97% rename from documentation/1.x/navigation/model-driven-navigation.md rename to documentation/navigation/model-driven-navigation.md index 499a414e4..bdd8399df 100644 --- a/documentation/1.x/navigation/model-driven-navigation.md +++ b/documentation/navigation/model-driven-navigation.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Model-driven navigation diff --git a/documentation/1.x/navmodel/backstack.md b/documentation/navmodel/backstack.md similarity index 99% rename from documentation/1.x/navmodel/backstack.md rename to documentation/navmodel/backstack.md index b70b54e15..47c70be8c 100644 --- a/documentation/1.x/navmodel/backstack.md +++ b/documentation/navmodel/backstack.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Back stack diff --git a/documentation/1.x/navmodel/cards.md b/documentation/navmodel/cards.md similarity index 98% rename from documentation/1.x/navmodel/cards.md rename to documentation/navmodel/cards.md index 102d9deca..e797f53cd 100644 --- a/documentation/1.x/navmodel/cards.md +++ b/documentation/navmodel/cards.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Cards diff --git a/documentation/1.x/navmodel/custom.md b/documentation/navmodel/custom.md similarity index 99% rename from documentation/1.x/navmodel/custom.md rename to documentation/navmodel/custom.md index f7d7a14a6..ff3499ea8 100644 --- a/documentation/1.x/navmodel/custom.md +++ b/documentation/navmodel/custom.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Implementing your own navigation models diff --git a/documentation/1.x/navmodel/index.md b/documentation/navmodel/index.md similarity index 96% rename from documentation/1.x/navmodel/index.md rename to documentation/navmodel/index.md index 76eaf3629..3d0c00cc0 100644 --- a/documentation/1.x/navmodel/index.md +++ b/documentation/navmodel/index.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Navigation models diff --git a/documentation/1.x/navmodel/promoter.md b/documentation/navmodel/promoter.md similarity index 96% rename from documentation/1.x/navmodel/promoter.md rename to documentation/navmodel/promoter.md index c28c71e18..7c3b956b6 100644 --- a/documentation/1.x/navmodel/promoter.md +++ b/documentation/navmodel/promoter.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Promoter carousel diff --git a/documentation/1.x/navmodel/spotlight.md b/documentation/navmodel/spotlight.md similarity index 98% rename from documentation/1.x/navmodel/spotlight.md rename to documentation/navmodel/spotlight.md index 8552f4030..4d2b1d6f5 100644 --- a/documentation/1.x/navmodel/spotlight.md +++ b/documentation/navmodel/spotlight.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Spotlight diff --git a/documentation/1.x/navmodel/tiles.md b/documentation/navmodel/tiles.md similarity index 97% rename from documentation/1.x/navmodel/tiles.md rename to documentation/navmodel/tiles.md index 4ad864706..da81e1d1a 100644 --- a/documentation/1.x/navmodel/tiles.md +++ b/documentation/navmodel/tiles.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Tiles diff --git a/documentation/releases/changelog.md b/documentation/releases/changelog.md deleted file mode 120000 index 699cc9e7b..000000000 --- a/documentation/releases/changelog.md +++ /dev/null @@ -1 +0,0 @@ -../../CHANGELOG.md \ No newline at end of file diff --git a/documentation/releases/changelog.md b/documentation/releases/changelog.md new file mode 100644 index 000000000..1dd05de4b --- /dev/null +++ b/documentation/releases/changelog.md @@ -0,0 +1,246 @@ + + +# Changelog + +## Pending changes + +- + +--- + +## 1.3.0 + +- [#425](https://github.com/bumble-tech/appyx/pull/425) – **Fixed**: Up navigation should be properly propagated from Appyx to RIBs +- [#384](https://github.com/bumble-tech/appyx/issues/384) – **Updated**: Compose BOM version and activity-compose version + +
22 Jun 2023
+ +--- + +## 1.2.0 + +- [#393](https://github.com/bumble-tech/appyx/pull/393) – **Breaking change**: Removed non-lazy implementations from `NodeCustomisationDirectory` +- [#393](https://github.com/bumble-tech/appyx/pull/393) – **Breaking change**: Removed `NodeCustomisationDirectoryImpl#put(vararg values: T)` due to potential uncaught bugs. Please call the reified `put` extension function instead. + +
11 Apr 2023
+ +--- + +## 1.1.2 + +- [#391](https://github.com/bumble-tech/appyx/pull/391) – **Added**: Introduced `putLazy` and `putSubDirectoryLazy` functions within `NodeCustomisationDirectoryImpl` via `LazyMutableNodeCustomisationDirectory` + +
04 Apr 2023
+ +--- + +## 1.1.1 + +- [#386](https://github.com/bumble-tech/appyx/pull/386) – **Updated**: RIBs version to 0.39.0 + +
31 Mar 2023
+ +--- + +## 1.1.0 + +- [#383](https://github.com/bumble-tech/appyx/pull/383) – **Changed**: Removed deprecated methods in Node, ParentNode and CombinedHandler classes +- [#376](https://github.com/bumble-tech/appyx/issues/376) – **Changed**: Androidx lifecycle version updated to 2.6.1. +- [#376](https://github.com/bumble-tech/appyx/issues/376) – **Updated**: Kotlin and Compose compiler version updated to 1.8.10 to align kotlin version used in androidx lifecycle +- [#375](https://github.com/bumble-tech/appyx/issues/375) – **Fixed**: SaveableStateHolder does no longer save state for destroyed elements + +
27 Mar 2023
+ +--- + +## 1.0.5 + +- [#370](https://github.com/bumble-tech/appyx/pull/370) – **Added**: `RetainedInstanceStore` has two new functions which allows a developer to check whether an object is retained. These are: `isRetainedByStoreId` and `isRetained`. + +
04 Mar 2023
+ +--- + +## 1.0.4 + +- [#361](https://github.com/bumble-tech/appyx/pull/361) – **Added**: Introduced `RetainedInstanceStore`. This provides developers the ability to retain objects between configuration changes. +- [#336](https://github.com/bumble-tech/appyx/pull/336) – **Updated**: ChildAware API does not enforce Node subtypes only anymore, making it possible to use interfaces as public contracts for child nodes. + +
20 Feb 2023
+ +--- + +## 1.0.3 + +- [#325](https://github.com/bumble-tech/appyx/pull/325) – **Fixed**: Crash when using PermanentChild API in View testing + +
23 Jan 2023
+ +--- + +## 1.0.2 + +- [#287](https://github.com/bumble-tech/appyx/pull/287) – **Added**: Introduced a new `rememberCombinedHandler` implementation that takes an immutable list to avoid non-skippable compositions. The previous implementation is now deprecated. +- [#287](https://github.com/bumble-tech/appyx/pull/287) – **Added**: `ImmutableList` has been added to avoid non-skippable compositions. +- [#289](https://github.com/bumble-tech/appyx/issues/289) – **Added**: Introduced `interop-rx3` for RxJava 3 support. This has identical functionality to `interop-rx2`. +- [#298](https://github.com/bumble-tech/appyx/pulls/298) – **Updated**: ChildView documentation. `TransitionDescriptor` generics has been renamed to `NavTarget` and `State` +- [#307](https://github.com/bumble-tech/appyx/pull/307) - **Added**: `Spotlight.current()` method to observe currently active `NavTarget`. +- [#314](https://github.com/bumble-tech/appyx/pull/314) – **Fixed**: Lifecycle is properly destroyed for suspended nodes. + +
10 Jan 2023
+ +--- + +## 1.0.1 + +- [#268](https://github.com/bumble-tech/appyx/pull/268) – **Fixed**: `PermanentChild` now does not crash in UI tests with `ComposeTestRule`. +- [#276](https://github.com/bumble-tech/appyx/pull/276) – **Fixed**: Back press handlers order is fixed for RIBs-Appyx integration. +- [#272](https://github.com/bumble-tech/appyx/pull/272) – **Changed**: `attachWorkflow` renamed to `attachChild`. `executeWorkflow` renamed to `executeAction`. +- [#272](https://github.com/bumble-tech/appyx/pull/272) – **Added**: `NodeReadyObserver` plugin to observe when the `Node` is ready + +
22 Nov 2022
+ +--- + +## 1.0.0 + +- [#247](https://github.com/bumble-tech/appyx/pull/247) – **Added**: Added `EmptyNavModel` to core for cases in which a `ParentNode` only uses `PermanentChild`. The `DummyNavModel` test class is deprecated. +- [#250](https://github.com/bumble-tech/appyx/pull/250) – **Updated**: Jetpack Compose to 1.3.0 + +
31 Oct 2022
+ +--- + +## 1.0.0-rc02 + +- [#231](https://github.com/bumble-tech/appyx/pull/231) – **Fixed**: Changing transition handler at runtime does not redraw children +- [#239](https://github.com/bumble-tech/appyx/pull/239) – **Fixed**: Fixed an issue with desynchronisation between NavModel and children's restoration process +- [#218](https://github.com/bumble-tech/appyx/pull/218) – **Updated**: `androidx.core:core-ktx` to 1.9.0. + +
21 Oct 2022
+ +--- + +## 1.0.0-rc01 + +- [#214](https://github.com/bumble-tech/appyx/pull/214) – **Breaking change**: `AppyxViewTestRule` stops supporting automatic launching activity. Activities should be started explicitly in tests. +- [#197](https://github.com/bumble-tech/appyx/pull/197) – **Breaking change**: `ParentNodeView` does not implement plugin anymore. `Node` instance is retrieved via `LocalComposition`. `AppyxParentViewTestRule` and `AbstractParentNodeView` have been removed. +- [#196](https://github.com/bumble-tech/appyx/pull/196) – **Breaking change**: `InteropBuilder` now should be supplied with Appyx `IntegrationPointProvider` to attach it at the same time Appyx Node is created. +- [#185](https://github.com/bumble-tech/appyx/issues/185) – **Breaking change**: `Activity` must implement `IntegrationPointProvider` and create `IntegrationPoint` manually. Weak references usage has been removed. +- [#173](https://github.com/bumble-tech/appyx/pull/173) – **Breaking change**: `ActivityStarter` and `PermissionRequester` now exposes coroutine based API instead of `minimal.reactive`. +- [#200](https://github.com/bumble-tech/appyx/pull/200) – **Breaking change**: Reordered the parameters for `ParentNode.Child` and `fun NodeHost` to meet Compose guidelines. +- [#43](https://github.com/bumble-tech/appyx/pull/43) – **Updated**: Jetpack Compose to `1.2.1` and Kotlin to `1.7.10`. +- [#168](https://github.com/bumble-tech/appyx/pull/168) – **Updated**: Kotlin coroutines to `1.6.4`. +- [#171](https://github.com/bumble-tech/appyx/pull/171) – **Updated**: RIBs to `0.36.1`. +- [#212](https://github.com/bumble-tech/appyx/pull/212) – **Updated**: `Node` parent property is now public instead of private. +- [#174](https://github.com/bumble-tech/appyx/issues/174) – **Fixed**: `IntegrationPointExample` does not work with "do not keep activities" +- [#180](https://github.com/bumble-tech/appyx/pull/180) – **Added**: Ensure that `super.onSaveInstanceState()` was called to restore Node's state correctly + +
13 Oct 2022
+ +--- + +## 1.0-alpha09 + +- [#151](https://github.com/bumble-tech/appyx/issues/151) - **Breaking change**: Renamed `Routing` to `NavTarget`. All related namings are affected (`RoutingElement`, `RoutingKey`, etc.) +- [#158](https://github.com/bumble-tech/appyx/issues/158) - **Breaking change**: Renamed `TransitionState` to `State` in all NavModel impls. Renamed `STASHED_IN_BACK_STACK` to `STASHED`. +- [#146](https://github.com/bumble-tech/appyx/issues/146) - **Breaking change**: Removed `FragmentIntegrationPoint`. Clients should use `ActivityIntegrationPoint.getIntegrationPoint(context: Context)` to get integration point from Fragment +- [#160](https://github.com/bumble-tech/appyx/issues/160) - **Breaking change**: Renamed `navmodel-addons` to `navmodel-samples` and stopped publishing the binary. If you feel we should add any of the samples to the main codebase, please let us know! +- [#138](https://github.com/bumble-tech/appyx/pull/138) - **Fixed**: `androidx.appcompat:appcompat` from is exposed via `api` within `com.bumble.appyx:core`. This prevents potential compilation bugs. +- [#143](https://github.com/bumble-tech/appyx/issues/143) - **Fixed**: Correctly exposed transitive dependencies that are part of the libraries ABI +- [#162](https://github.com/bumble-tech/appyx/pull/162) - **Fixed**: `NodeTestHelper`'s `moveTo` function can now move to `Lifecycle.State.DESTROYED`. The node itself has safeguards to prevent moving from destroyed state, and moving to destroyed is a valid test case. +- [#145](https://github.com/bumble-tech/appyx/issues/145) - **Updated**: `SpotlightSlider` now uses offset modifier with lambda +- [#159](https://github.com/bumble-tech/appyx/pull/159) - **Added**: `NodeHost` now takes modifier parameter to decorate the view of a root node +- [#162](https://github.com/bumble-tech/appyx/pull/162) - **Added**: `disposeOnDestroyPlugin` extension has been added to interop-rx2. This will allow Rx2 code to be easily disposed when the node it belongs to is destroyed. +- [#161](https://github.com/bumble-tech/appyx/pull/161) - **Added**: Operations helpers + +
22 Sep 2022
+ +--- + +## 1.0-alpha08 + +- [#140](https://github.com/bumble-tech/appyx/issues/140) - **Breaking change**: Added `testing-ui-activity` module to avoid needing to add `testing-ui` as a debug implementation as part of instrumentation testing. See the linked issue for more details +- [#139](https://github.com/bumble-tech/appyx/pull/139) - **Fixed**: `IntegrationPoint` memory leak created by `ActivityIntegrationPoint` + +
12 Sep 2022
+ +--- + +## 1.0-alpha07 + +- [#122](https://github.com/bumble-tech/appyx/pull/122) - **Breaking change**: `ChildEntry.ChildMode` is removed, now nodes are always created when a nav model changes (previously default behaviour) +- [#99](https://github.com/bumble-tech/appyx/pull/99) – **Breaking change**: Removed `IntegrationPointAppyxProvider` and made `ActivityIntegrationPoint`'s constructor private. Use `ActivityIntegrationPoint.createIntegrationPoint`. This uses a weak reference to keep track of the integration points, and will not introduce memory leaks. +- [#122](https://github.com/bumble-tech/appyx/pull/122) - **Added**: New `ChildEntry.KeepMode` that allows to destroy nodes that are currently not visible on the screen +- [#132](https://github.com/bumble-tech/appyx/pull/132) - **Added**: New `NodeComponentActivity` to extend when wanting to work with `ComponentActivity` as your base activity, eg when migrating from a project built from the Jetpack Compose template +- [#119](https://github.com/bumble-tech/appyx/pull/119) - **Fixed**: Lifecycle observers are invoked in incorrect order (child before parent) +- [#62](https://github.com/bumble-tech/appyx/pull/62) - **Fixed**: Node is marked with stable annotation making some of the composable functions skippable +- [#129](https://github.com/bumble-tech/appyx/pull/129) - **Updated**: Removed sealed interface from operations to allow client to define their own +- [#133](https://github.com/bumble-tech/appyx/pull/133) - **Updated**: `NodeView` interface and `ParentNode` marked as stable improving amount of skippable composables + +
9 Sep 2022
+ +--- + +## 1.0-alpha06 + +- [#96](https://github.com/bumble-tech/appyx/pull/96) – **Breaking change**: Removed `InteractorTestHelper`. Please use Node tests instead of Interactor tests. +- [#99](https://github.com/bumble-tech/appyx/pull/99) – **Breaking change**: Modified package of `NodeConnector` and `Connectable` +- [#99](https://github.com/bumble-tech/appyx/pull/99) – **Added**: Source.rx2() to convert Source to io.reactivex.Observable +- [#107](https://github.com/bumble-tech/appyx/pull/107) – **Fixed**: Back press handlers are not properly registered on lifecycle events + +
26 Aug 2022
+ +--- + +## 1.0-alpha05 + +- [#83](https://github.com/bumble-tech/appyx/issues/83) – **Breaking change**: `RoutingSource` renamed to `NavModel`. All subclasses, fields, package names, etc., any mentions of the word follow suit. +- [#91](https://github.com/bumble-tech/appyx/pull/91) – **Fixed**: Spotlight next and previous operations crash fix + +
19 Aug 2022
+ +--- + +## 1.0-alpha04 + +- [#39](https://github.com/bumble-tech/appyx/pull/39) – **Added**: Workflows implementation to support deeplinks +- [#32](https://github.com/bumble-tech/appyx/pull/32) – **Added**: `BackPressHandler` plugin that allows to control back press behaviour via `androidx.activity.OnBackPressedCallback` +- [#59](https://github.com/bumble-tech/appyx/issues/59) – **Added**: interface for `ParentNodeView<>` +- [#32](https://github.com/bumble-tech/appyx/issues/69) – **Added**: Jetpack Compose Navigation code sample +- [#81](https://github.com/bumble-tech/appyx/issues/81) – **Added**: Support integration point for multiple roots +- [#65](https://github.com/bumble-tech/appyx/pull/65) – **Added**: `InteropBuilderStub` and `InteropSimpleBuilderStub` testing util classes +- [#47](https://github.com/bumble-tech/appyx/issues/47) – **Updated**: The `customisations` module is now pure Java/Kotlin. +- [#85](https://github.com/bumble-tech/appyx/issues/85) – **Updated**: Improved `InteropView` error messaging when `Activity` does not implement `IntegrationPointAppyxProvider` +- [#88](https://github.com/bumble-tech/appyx/issues/88) – **Updated**: Moved `TestUpNavigationHandler` to `testing-unit-common` + +
18 Aug 2022
+ +--- + +## 1.0-alpha03 + +- [#38](https://github.com/bumble-tech/appyx/pull/38) – **Added**: JUnit5 support + +
2 Aug 2022
+ +--- + +## 1.0-alpha02 + +- [#19](https://github.com/bumble-tech/appyx/pull/19) – **Fixed**: Do not allow setting `Node.integrationPoint` on non-root nodes +- [#23](https://github.com/bumble-tech/appyx/pull/21) – **Fixed**: Integration point attached twice crash when using live literals +- [#14](https://github.com/bumble-tech/appyx/issues/14) – **Fixed**: Transition interruptions bug +- [#23](https://github.com/bumble-tech/appyx/pull/23) – **Added**: Unit test support +- [#26](https://github.com/bumble-tech/appyx/issues/26) – **Added**: Publish snapshot versions +- [#9](https://github.com/bumble-tech/appyx/pull/9) – **Migrated**: [app-tree-utils](https://github.com/badoo/app-tree-utils) into this repository + +
19 Jul 2022
+ +--- + +## 1.0-alpha01 + +- Initial release + +
4 Jul 2022
diff --git a/documentation/releases/downloads.md b/documentation/releases/downloads.md index a5defc870..27a60c9bd 100644 --- a/documentation/releases/downloads.md +++ b/documentation/releases/downloads.md @@ -1,247 +1,66 @@ ---- -title: Downloads ---- + # Downloads ## Latest version -![Maven Central](https://img.shields.io/maven-central/v/com.bumble.appyx/appyx-navigation) +![Maven Central](https://img.shields.io/maven-central/v/com.bumble.appyx/core) ## Repository -```kotlin +```groovy repositories { mavenCentral() } ``` +## Core dependencies -## Appyx Navigation - -Adding the gradle dependency in a non-multiplatform project: - -```kotlin -dependencies { - // Platform-specific (pick the right one for your platform) - implementation("com.bumble.appyx:appyx-navigation-android:$version") - implementation("com.bumble.appyx:appyx-navigation-desktop:$version") - implementation("com.bumble.appyx:appyx-navigation-js:$version") - - // For iOS, you need separate dependencies for Simulator, x86 & Arm - implementation("com.bumble.appyx:appyx-navigation-iossimulatorarm64:$version") - implementation("com.bumble.appyx:appyx-navigation-iosx64:$version") - implementation("com.bumble.appyx:appyx-navigation-iosarm64:$version") -} -``` - -Adding the gradle dependency in a multiplatform project: - -```kotlin -kotlin { - sourceSets { - val commonMain by getting { - dependencies { - implementation("com.bumble.appyx:appyx-navigation:$version") - } - } - } -} -``` - -## Appyx Interactions - -Adding the gradle dependency in a non-multiplatform project: - -```kotlin -dependencies { - // Platform-specific (pick the right one for your platform) - implementation("com.bumble.appyx:appyx-interactions-android:$version") - implementation("com.bumble.appyx:appyx-interactions-desktop:$version") - implementation("com.bumble.appyx:appyx-interactions-js:$version") - - // For iOS, you need separate dependencies for Simulator, x86 & Arm - implementation("com.bumble.appyx:appyx-interactions-iossimulatorarm64:$version") - implementation("com.bumble.appyx:appyx-interactions-iosx64:$version") - implementation("com.bumble.appyx:appyx-interactions-iosarm64:$version") -} -``` - -Adding the gradle dependency in a multiplatform project: - -```kotlin -kotlin { - sourceSets { - val commonMain by getting { - dependencies { - implementation("com.bumble.appyx:appyx-interactions:$version") - } - } - } -} -``` - -## Appyx Components - -### Back stack - -Adding the gradle dependency in a non-multiplatform project: - -```kotlin -dependencies { - // Platform-specific (pick the right one for your platform) - implementation("com.bumble.appyx:backstack-android:$version") - implementation("com.bumble.appyx:backstack-desktop:$version") - implementation("com.bumble.appyx:backstack-js:$version") - - // For iOS, you need separate dependencies for Simulator, x86 & Arm - implementation("com.bumble.appyx:backstack-iossimulatorarm64:$version") - implementation("com.bumble.appyx:backstack-iosx64:$version") - implementation("com.bumble.appyx:backstack-iosarm64:$version") -} -``` - -Adding the gradle dependency in a multiplatform project: - -```kotlin -kotlin { - sourceSets { - val commonMain by getting { - dependencies { - // Use api, not implementation! - api("com.bumble.appyx:backstack:$version") - } - } - - } -} -``` - -### Spotlight - -Adding the gradle dependency in a non-multiplatform project: - -```kotlin +```groovy dependencies { - // Platform-specific (pick the right one for your platform) - implementation("com.bumble.appyx:spotlight-android:$version") - implementation("com.bumble.appyx:spotlight-desktop:$version") - implementation("com.bumble.appyx:spotlight-js:$version") - - // For iOS, you need separate dependencies for Simulator, x86 & Arm - implementation("com.bumble.appyx:spotlight-iossimulatorarm64:$version") - implementation("com.bumble.appyx:spotlight-iosx64:$version") - implementation("com.bumble.appyx:spotlight-iosarm64:$version") -} -``` - -Adding the gradle dependency in a multiplatform project: - -```kotlin -kotlin { - sourceSets { - val commonMain by getting { - dependencies { - // Use api, not implementation! - api("com.bumble.appyx:spotlight:$version") - } - } - - } -} -``` + // Core + implementation "com.bumble.appyx:core:$version" -## Utils and interop with other libraries + // Test rules and utility classes for testing on Android + debugImplementation "com.bumble.appyx:testing-ui-activity:$version" + androidTestImplementation "com.bumble.appyx:testing-ui:$version" -### Material 3 support + // Utility classes for unit testing + testImplementation "com.bumble.appyx:testing-unit-common:$version" + + // Test rules and utility classes for unit testing using JUnit4 + testImplementation "com.bumble.appyx:testing-junit4:$version" -Support for [Navigation bar](https://m3.material.io/components/navigation-bar/overview), [Navigation rail](https://m3.material.io/components/navigation-rail/overview) to use easily together with **Appyx Navigation**. - -See more in [Material 3 support](../navigation/features/material3.md). - -Adding the gradle dependency in a non-multiplatform project: - -```kotlin -dependencies { - // Platform-specific (pick the right one for your platform) - implementation("com.bumble.appyx:utils-material3-android:$version") - implementation("com.bumble.appyx:utils-material3-desktop:$version") - implementation("com.bumble.appyx:utils-material3-js:$version") - implementation("com.bumble.appyx:utils-material3-iosarm64:$version") - implementation("com.bumble.appyx:utils-material3-iossimulatorarm64:$version") - implementation("com.bumble.appyx:utils-material3-iosx64:$version") + // Test extensions and utility classes for unit testing using JUnit5 + testImplementation "com.bumble.appyx:testing-junit5:$version" } ``` -Adding the gradle dependency in a multiplatform project: - -```kotlin -kotlin { - sourceSets { - val commonMain by getting { - dependencies { - // Use api, not implementation! - api("com.bumble.appyx:utils-material3:$version") - } - } - } -} -``` +## Interop with other libraries -### RxJava 2 - -```kotlin +```groovy dependencies { // Optional support for RxJava 2/3 - implementation("com.bumble.appyx:utils-interop-rx2:$version") -} -``` + implementation "com.bumble.appyx:interop-rx2:$version" + implementation "com.bumble.appyx:interop-rx3:$version" -### RxJava 3 + // Optional interoperability layer between Appyx and badoo/RIBs + // You have to add https://jitpack.io repository to use it because badoo/RIBs is hosted there + implementation "com.bumble.appyx:interop-ribs:$version" -```kotlin -dependencies { - implementation("com.bumble.appyx:utils-interop-rx3:$version") } ``` -### badoo/RIBs +## Snapshot -```kotlin -repositories { - // Don't forget to add this, since badoo/RIBs is hosted on jitpack: - maven(url = "https://jitpack.io") -} +Snapshot version is available for all modules, use the provided repository url and `1-SNAPSHOT` version. -dependencies { - implementation("com.bumble.appyx:utils-interop-ribs:$version") +```groovy +repositories { + maven { url = 'https://s01.oss.sonatype.org/content/repositories/snapshots/' } } -``` - -### RIBs like helpers -Adds client code helper classes like `Builder`, `SimpleBuilder`, and `Interactor` - -```kotlin dependencies { - implementation("com.bumble.appyx:utils-ribs-helpers:$version") + implementation "com.bumble.appyx:core:v1-SNAPSHOT" } ``` - - -### Testing - -```kotlin -// Test rules and utility classes for testing on Android -debugImplementation("com.bumble.appyx:utils-testing-ui-activity:$version") -androidTestImplementation("com.bumble.appyx:utils-testing-ui:$version") - -// Utility classes for unit testing -testImplementation("com.bumble.appyx:utils-testing-unit-common:$version") - -// Test rules and utility classes for unit testing using JUnit4 -testImplementation("com.bumble.appyx:utils-testing-junit4:$version") - -// Test extensions and utility classes for unit testing using JUnit5 -testImplementation("com.bumble.appyx:utils-testing-junit5:$version") -``` diff --git a/documentation/1.x/ui/children-view.md b/documentation/ui/children-view.md similarity index 98% rename from documentation/1.x/ui/children-view.md rename to documentation/ui/children-view.md index c4ee95244..c3abf5b76 100644 --- a/documentation/1.x/ui/children-view.md +++ b/documentation/ui/children-view.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Adding children to the view diff --git a/documentation/1.x/ui/transitions.md b/documentation/ui/transitions.md similarity index 98% rename from documentation/1.x/ui/transitions.md rename to documentation/ui/transitions.md index d04d9b996..9ca6a9507 100644 --- a/documentation/1.x/ui/transitions.md +++ b/documentation/ui/transitions.md @@ -1,4 +1,4 @@ -{% include-markdown "../deprecation.md" %} + # Transitions diff --git a/mkdocs.yml b/mkdocs.yml index 061c006d7..c3d69fc47 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,84 +16,84 @@ copyright: Copyright © 2022 - 2023 Bumble docs_dir: documentation nav: - - Home: 1.x/index.md + - Home: index.md - Using Appyx: - - Quick start guide: 1.x/how-to-use-appyx/quick-start.md - - Codelabs: 1.x/how-to-use-appyx/codelabs.md - - Coding challenges: 1.x/how-to-use-appyx/coding-challenges.md - - Sample apps: 1.x/how-to-use-appyx/sample-apps.md + - Quick start guide: how-to-use-appyx/quick-start.md + - Codelabs: how-to-use-appyx/codelabs.md + - Coding challenges: how-to-use-appyx/coding-challenges.md + - Sample apps: how-to-use-appyx/sample-apps.md - Navigation: - - Model-driven navigation: 1.x/navigation/model-driven-navigation.md + - Model-driven navigation: navigation/model-driven-navigation.md - NavModel: - - Overview: 1.x/navmodel/index.md - - Back stack: 1.x/navmodel/backstack.md - - Spotlight: 1.x/navmodel/spotlight.md - - Cards: 1.x/navmodel/cards.md - - Tiles: 1.x/navmodel/tiles.md - - Promoter: 1.x/navmodel/promoter.md - - Writing your own: 1.x/navmodel/custom.md - - Composable navigation: 1.x/navigation/composable-navigation.md - - Implicit navigation: 1.x/navigation/implicit-navigation.md - - Explicit navigation: 1.x/navigation/explicit-navigation.md - - Deep linking: 1.x/navigation/deep-linking.md + - Overview: navmodel/index.md + - Back stack: navmodel/backstack.md + - Spotlight: navmodel/spotlight.md + - Cards: navmodel/cards.md + - Tiles: navmodel/tiles.md + - Promoter: navmodel/promoter.md + - Writing your own: navmodel/custom.md + - Composable navigation: navigation/composable-navigation.md + - Implicit navigation: navigation/implicit-navigation.md + - Explicit navigation: navigation/explicit-navigation.md + - Deep linking: navigation/deep-linking.md - UI: - - Children: 1.x/ui/children-view.md - - Transitions: 1.x/ui/transitions.md + - Children: ui/children-view.md + - Transitions: ui/transitions.md - App: - - Structuring your app navigation: 1.x/apps/structure.md - - Lifecycle: 1.x/apps/lifecycle.md - - Plugins: 1.x/apps/plugins.md - - ChildAware API: 1.x/apps/childaware.md - - Configuration changes: 1.x/apps/configuration.md + - Structuring your app navigation: apps/structure.md + - Lifecycle: apps/lifecycle.md + - Plugins: apps/plugins.md + - ChildAware API: apps/childaware.md + - Configuration changes: apps/configuration.md - Releases: - - Downloads: 1.x/releases/downloads.md - - Changelog: 1.x/releases/changelog.md - - FAQ: 1.x/faq.md + - Downloads: releases/downloads.md + - Changelog: releases/changelog.md + - FAQ: faq.md - Appyx 2.x (experimental): - - Home: index.md + - Home: 2.x/index.md - Appyx Navigation: - - Overview: navigation/index_2.x.md - - Sample app: navigation/sample-app.md - - Quick start guide: navigation/quick-start.md + - Overview: 2.x/navigation/index.md + - Sample app: 2.x/navigation/sample-app.md + - Quick start guide: 2.x/navigation/quick-start.md - Concepts: - - Model-driven navigation: navigation/concepts/model-driven-navigation.md - - Composable navigation: navigation/concepts/composable-navigation.md - - Implicit navigation: navigation/concepts/implicit-navigation.md - - Explicit navigation: navigation/concepts/explicit-navigation.md + - Model-driven navigation: 2.x/navigation/concepts/model-driven-navigation.md + - Composable navigation: 2.x/navigation/concepts/composable-navigation.md + - Implicit navigation: 2.x/navigation/concepts/implicit-navigation.md + - Explicit navigation: 2.x/navigation/concepts/explicit-navigation.md - Features: - - Deep linking: navigation/features/deep-linking.md - - Scoped DI: navigation/features/scoped-di.md - - Lifecycle: navigation/features/lifecycle.md - - Material 3 support: navigation/features/material3.md - - Plugins: navigation/features/plugins.md - - ChildAware API: navigation/features/childaware.md - - Surviving configuration changes: navigation/features/surviving-configuration-changes.md + - Deep linking: 2.x/navigation/features/deep-linking.md + - Scoped DI: 2.x/navigation/features/scoped-di.md + - Lifecycle: 2.x/navigation/features/lifecycle.md + - Material 3 support: 2.x/navigation/features/material3.md + - Plugins: 2.x/navigation/features/plugins.md + - ChildAware API: 2.x/navigation/features/childaware.md + - Surviving configuration changes: 2.x/navigation/features/surviving-configuration-changes.md - Integrations: - - Compose Navigation: navigation/integrations/compose-navigation.md - - DI frameworks: navigation/integrations/di-frameworks.md - - RIBs: navigation/integrations/ribs.md - - RxJava: navigation/integrations/rx.md - - ViewModel: navigation/integrations/viewmodel.md - - Multiplatform: navigation/multiplatform.md + - Compose Navigation: 2.x/navigation/integrations/compose-navigation.md + - DI frameworks: 2.x/navigation/integrations/di-frameworks.md + - RIBs: 2.x/navigation/integrations/ribs.md + - RxJava: 2.x/navigation/integrations/rx.md + - ViewModel: 2.x/navigation/integrations/viewmodel.md + - Multiplatform: 2.x/navigation/multiplatform.md - Appyx Interactions: - - Overview: interactions/index.md - - Using components: interactions/usage.md + - Overview: 2.x/interactions/index.md + - Using components: 2.x/interactions/usage.md - Creating your own: - - Component overview: interactions/appyxcomponent.md - - Transition model: interactions/transitionmodel.md - - Operations: interactions/operations.md - - UI representation: interactions/ui-representation.md - - KSP setup: interactions/ksp.md - - Gestures: interactions/gestures.md + - Component overview: 2.x/interactions/appyxcomponent.md + - Transition model: 2.x/interactions/transitionmodel.md + - Operations: 2.x/interactions/operations.md + - UI representation: 2.x/interactions/ui-representation.md + - KSP setup: 2.x/interactions/ksp.md + - Gestures: 2.x/interactions/gestures.md - Appyx Components: - - Overview: components/index.md - - Back stack: components/backstack.md - - Spotlight: components/spotlight.md - - Experimental: components/experimental.md + - Overview: 2.x/components/index.md + - Back stack: 2.x/components/backstack.md + - Spotlight: 2.x/components/spotlight.md + - Experimental: 2.x/components/experimental.md - Releases: - - Downloads: releases/downloads.md - - Changelog: releases/changelog.md - - FAQ: faq.md + - Downloads: 2.x/releases/downloads.md + - Changelog: 2.x/releases/changelog.md + - FAQ: 2.x/faq.md - Migration guide: 2.x/migrationguide.md