Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Pending changes

- [#289](https://github.com/bumble-tech/appyx/issues/289) – **Added**: Introduced `interop-rx3` for RxJava 3 support. This has identical functionality to `interop-rx2`.

---

Expand Down
3 changes: 2 additions & 1 deletion documentation/releases/downloads.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ dependencies {

```groovy
dependencies {
// Optional support for RxJava 2
// 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
Expand Down
12 changes: 6 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ ribs = "0.36.1"
mvicore = "1.2.6"
coroutines = "1.6.4"
kotlin = "1.7.10"
rxjava2 = "2.2.21"
rxandroid = "2.1.1"
junit5 = "5.8.2"
detekt = "1.21.0"
dependencyAnalysis = "1.13.1"
Expand Down Expand Up @@ -57,11 +55,13 @@ ribs-base-test = { module = "com.github.badoo.RIBs:rib-base-test", version.ref =
ribs-base-test-activity = { module = "com.github.badoo.RIBs:rib-base-test-activity", version.ref = "ribs" }
ribs-base-test-rx2 = { module = "com.github.badoo.RIBs:rib-base-test-rx2", version.ref = "ribs" }
ribs-compose = { module = "com.github.badoo.RIBs:rib-compose", version.ref = "ribs" }
ribs-rx = { module = "com.github.badoo.RIBs:rib-rx2", version.ref = "ribs" }

rxjava2 = { module = "io.reactivex.rxjava2:rxjava", version.ref = "rxjava2" }
rxandroid = { module = "io.reactivex.rxjava2:rxandroid", version.ref = "rxandroid" }
rxrelay = "com.jakewharton.rxrelay2:rxrelay:2.1.1"
rxjava2 = "io.reactivex.rxjava2:rxjava:2.2.21"
rxjava3 = "io.reactivex.rxjava3:rxjava:3.1.5"
rxandroid2 = "io.reactivex.rxjava2:rxandroid:2.1.1"
rxandroid3 = "io.reactivex.rxjava3:rxandroid:3.0.2"
rxrelay2 = "com.jakewharton.rxrelay2:rxrelay:2.1.1"
rxrelay3 = "com.jakewharton.rxrelay3:rxrelay:3.0.1"

kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit5" }
Expand Down
2 changes: 1 addition & 1 deletion libraries/interop-rx2/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ android {
dependencies {
api(project(":libraries:core"))
api(libs.rxjava2)
api(libs.rxrelay)
api(libs.rxrelay2)

implementation(libs.kotlin.coroutines.rx2)
implementation(libs.androidx.lifecycle.java8)
Expand Down
35 changes: 35 additions & 0 deletions libraries/interop-rx3/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
plugins {
id("com.android.library")
id("kotlin-android")
id("appyx-publish-android")
id("appyx-lint")
id("appyx-detekt")
}

android {
namespace = "com.bumble.appyx.interop.rx3"
compileSdk = libs.versions.androidCompileSdk.get().toInt()

defaultConfig {
minSdk = libs.versions.androidMinSdk.get().toInt()
targetSdk = libs.versions.androidTargetSdk.get().toInt()

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
testOptions {
unitTests.all {
it.useJUnitPlatform()
}
}
}

dependencies {
api(project(":libraries:core"))
api(libs.rxjava3)
api(libs.rxrelay3)

implementation(libs.androidx.lifecycle.java8)

testImplementation(libs.junit.api)
testRuntimeOnly(libs.junit.engine)
}
4 changes: 4 additions & 0 deletions libraries/interop-rx3/lint-baseline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<issues format="6" by="lint 7.3.1" type="baseline" client="gradle" dependencies="false" name="AGP (7.3.1)" variant="all" version="7.3.1">

</issues>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.bumble.appyx.interop.rx3.connectable

import com.bumble.appyx.core.plugin.NodeLifecycleAware
import com.jakewharton.rxrelay3.Relay

interface Connectable<Input, Output> : NodeLifecycleAware {
val input: Relay<Input>
val output: Relay<Output>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.bumble.appyx.interop.rx3.connectable

import androidx.lifecycle.Lifecycle
import com.bumble.appyx.core.lifecycle.subscribe
import com.jakewharton.rxrelay3.PublishRelay
import com.jakewharton.rxrelay3.Relay
import io.reactivex.rxjava3.core.Observer

class NodeConnector<Input, Output : Any>(
override val input: Relay<Input> = PublishRelay.create(),
) : Connectable<Input, Output> {

private val intake: Relay<Output> = PublishRelay.create()
private val exhaust: Relay<Output> = PublishRelay.create()
private var isFlushed = false
private val outputCache = mutableListOf<Output>()

override val output: Relay<Output> = object : Relay<Output>() {

override fun subscribeActual(observer: Observer<in Output>) {
exhaust.subscribe(observer)
}

override fun accept(value: Output) {
intake.accept(value)
}

override fun hasObservers() = exhaust.hasObservers()

}

override fun onCreate(lifecycle: Lifecycle) {
lifecycle.subscribe(onCreate = { flushOutputCache() })
}

private val cacheSubscription = intake.subscribe {
synchronized(this) {
if (!isFlushed) {
outputCache.add(it)
} else {
exhaust.accept(it)
switchToExhaust()
}
}
}

private fun flushOutputCache() {
synchronized(this) {
if (isFlushed) error("Already flushed")
isFlushed = true
outputCache.forEach { exhaust.accept(it) }
outputCache.clear()
}
}

private fun switchToExhaust() {
intake.subscribe { exhaust.accept(it) }
cacheSubscription.dispose()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.bumble.appyx.interop.rx3.plugin

import com.bumble.appyx.core.plugin.Destroyable
import com.bumble.appyx.core.plugin.Plugin
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable

private class DisposeOnDestroy(disposables: List<Disposable>) : Destroyable {
private val disposable = CompositeDisposable(disposables)

override fun destroy() {
disposable.dispose()
}
}

fun disposeOnDestroyPlugin(vararg disposables: Disposable): Plugin =
DisposeOnDestroy(disposables.toList())
Loading