Skip to content

Commit ef78b01

Browse files
committed
Implement subscription on components and apply new RCK to examples.
1 parent 35ae525 commit ef78b01

File tree

22 files changed

+241
-89
lines changed

22 files changed

+241
-89
lines changed

app/src/main/java/com/github/skyfe79/android/library/app/examples/counter/CounterActivity.kt

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,5 @@ class CounterActivity: AppCompatActivity() {
2424
layout.setContentView(this)
2525

2626
layout.countTextView.text = "${viewModel.count.value}"
27-
28-
viewModel
29-
.count
30-
.asObservable()
31-
.subscribe {
32-
layout.countTextView.text = "$it"
33-
}
34-
.disposedBy(disposeBag)
35-
3627
}
3728
}

app/src/main/java/com/github/skyfe79/android/library/app/examples/counter/CounterLayout.kt

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ import android.view.Gravity
44
import android.view.View
55
import android.widget.Button
66
import android.widget.LinearLayout
7+
import android.widget.ProgressBar
78
import android.widget.TextView
9+
import com.github.skyfe79.android.library.app.examples.counter.action.AsyncIncreaseAction
810
import com.github.skyfe79.android.library.app.examples.counter.action.DecreaseAction
911
import com.github.skyfe79.android.library.app.examples.counter.action.IncreaseAction
1012
import com.github.skyfe79.android.reactcomponentkit.component.LayoutComponent
1113
import com.github.skyfe79.android.reactcomponentkit.dispatcher.dispatch
1214
import com.github.skyfe79.android.reactcomponentkit.eventbus.Token
15+
import com.github.skyfe79.android.reactcomponentkit.redux.Async
1316
import com.github.skyfe79.android.reactcomponentkit.redux.State
17+
import com.github.skyfe79.android.reactcomponentkit.subscriber.subscribeState
1418
import org.jetbrains.anko.*
1519
import org.jetbrains.anko.sdk27.coroutines.onClick
1620

@@ -23,6 +27,12 @@ class CounterLayout(token: Token): LayoutComponent<CounterActivity>(token) {
2327
lateinit var countTextView: TextView
2428
private lateinit var increaseButton: Button
2529
private lateinit var decreaseButton: Button
30+
private lateinit var asyncIncreaseButton: Button
31+
private lateinit var progress: ProgressBar
32+
33+
override fun onInit() {
34+
subscribeState()
35+
}
2636

2737
override fun createView(ui: AnkoContext<CounterActivity>): View = with(ui) {
2838
val view = relativeLayout {
@@ -34,13 +44,18 @@ class CounterLayout(token: Token): LayoutComponent<CounterActivity>(token) {
3444
centerInParent()
3545
}
3646

47+
progress = progressBar().lparams {
48+
centerInParent()
49+
}
50+
progress.visibility = View.GONE
51+
3752
linearLayout {
3853
orientation = LinearLayout.HORIZONTAL
3954
gravity = Gravity.CENTER
4055

4156
decreaseButton = button(" - ").lparams(width = 0, weight = 1f)
4257
increaseButton = button(" + ").lparams(width = 0, weight = 1f)
43-
58+
asyncIncreaseButton = button("async +").lparams(width = 0, weight = 1f)
4459
}.applyRecursively {
4560
when(it) {
4661
is Button -> it.textSize = 20f
@@ -54,6 +69,10 @@ class CounterLayout(token: Token): LayoutComponent<CounterActivity>(token) {
5469
}
5570

5671

72+
asyncIncreaseButton.setOnClickListener {
73+
dispatch(AsyncIncreaseAction())
74+
}
75+
5776
increaseButton.setOnClickListener {
5877
dispatch(IncreaseAction())
5978
}
@@ -68,5 +87,15 @@ class CounterLayout(token: Token): LayoutComponent<CounterActivity>(token) {
6887
override fun on(state: State) {
6988
val countState = (state as? CounterState) ?: return
7089
countTextView.text = "${countState.count}"
90+
91+
when (state.asyncCount) {
92+
is Async.Loading -> {
93+
progress.visibility = View.VISIBLE
94+
progress.animate()
95+
}
96+
is Async.Success -> {
97+
progress.visibility = View.GONE
98+
}
99+
}
71100
}
72101
}

app/src/main/java/com/github/skyfe79/android/library/app/examples/counter/CounterViewModel.kt

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.skyfe79.android.library.app.examples.counter
22

33
import android.app.Application
4+
import com.github.skyfe79.android.library.app.examples.counter.action.AsyncIncreaseAction
45
import com.github.skyfe79.android.library.app.examples.counter.action.DecreaseAction
56
import com.github.skyfe79.android.library.app.examples.counter.action.IncreaseAction
67
import com.github.skyfe79.android.reactcomponentkit.redux.*
@@ -19,12 +20,9 @@ data class CounterState(
1920
class CounterViewModel(application: Application): RCKViewModel<CounterState>(application) {
2021

2122
val count: Output<Int> = Output(0)
23+
val asyncCount: Output<Async<Int>> = Output(Async.Uninitialized)
2224

23-
fun showLoading() = setState { state ->
24-
state.copy(asyncCount = Async.Loading)
25-
}
26-
27-
fun asyncIncrease(state: CounterState, action: IncreaseAction) = asyncReducer(state, action) {
25+
fun asyncIncrease(state: CounterState, action: AsyncIncreaseAction) = asyncReducer(state, action) {
2826
Single.create<CounterState> { emitter ->
2927
Thread.sleep(1000L)
3028
withState { state ->
@@ -37,21 +35,30 @@ class CounterViewModel(application: Application): RCKViewModel<CounterState>(app
3735
initStore { store ->
3836
store.initialState(CounterState(0))
3937

40-
store.flow<IncreaseAction>(
38+
store.flow<AsyncIncreaseAction>(
39+
{ _, _ ->
40+
setState {
41+
it.copy(asyncCount = Async.Loading)
42+
}
43+
},
4144
{ state, action ->
42-
state.copy(count = state.count + 3)
45+
state.copy(count = state.count + action.payload)
4346
},
4447
::asyncIncrease,
4548
asyncFlow { action ->
4649
Single.create<CounterState> { emitter ->
47-
Thread.sleep(5000L)
50+
Thread.sleep(2000L)
4851
withState { state ->
49-
emitter.onSuccess(state.copy(count = state.count + action.payload))
52+
emitter.onSuccess(state.copy(count = state.count + action.payload, asyncCount = Async.Success(state.count + action.payload)))
5053
}
5154
}.toObservable()
5255
}
5356
)
5457

58+
store.flow<IncreaseAction>({ state, action ->
59+
state.copy(count = state.count + action.payload)
60+
})
61+
5562
store.flow<DecreaseAction>({ state, action ->
5663
state.copy(count = state.count - action.payload)
5764
})
@@ -60,5 +67,6 @@ class CounterViewModel(application: Application): RCKViewModel<CounterState>(app
6067

6168
override fun on(newState: CounterState) {
6269
count.accept(newState.count)
70+
asyncCount.accept(newState.asyncCount)
6371
}
6472
}

app/src/main/java/com/github/skyfe79/android/library/app/examples/emojicollection/EmojiCollectionViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class EmojiCollectionViewModel(application: Application): RCKViewModel<EmojiColl
4141

4242

4343
store.flow<ClickEmojiAction>({ state, action ->
44-
state.copy(route = EmojiRoute.AlertEmoji(action.emoji))
44+
state.copy(route = EmojiRoute.AlertEmoji(action.emoji))
4545
})
4646

4747
store.flow<AddEmojiAction>(

app/src/main/java/com/github/skyfe79/android/library/app/examples/emojicollection/actions/Actions.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ import com.github.skyfe79.android.reactcomponentkit.redux.Action
44

55
data class AddEmojiAction(val emoji: String): Action
66
object RemoveEmojiAction: Action
7-
object ShuffleEmojiAction: Action
8-
object MakeItemModelsAction: Action
7+
object ShuffleEmojiAction: Action

app/src/main/java/com/github/skyfe79/android/library/app/examples/emojicollection/afters/Reset.kt

Lines changed: 0 additions & 8 deletions
This file was deleted.

app/src/main/java/com/github/skyfe79/android/library/app/examples/emojicollection/components/EmojiViewComponent.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.github.skyfe79.android.reactcomponentkit.dispatcher.dispatch
1212
import com.github.skyfe79.android.reactcomponentkit.eventbus.Token
1313
import com.github.skyfe79.android.reactcomponentkit.redux.Action
1414
import com.github.skyfe79.android.reactcomponentkit.redux.State
15+
import com.github.skyfe79.android.reactcomponentkit.subscriber.subscribeState
1516
import kotlinx.android.synthetic.main.activity_main.view.*
1617
import org.jetbrains.anko.*
1718
import org.jetbrains.anko.sdk27.coroutines.onClick
@@ -41,10 +42,6 @@ class EmojiViewComponent(token: Token): ViewComponent(token) {
4142
return rootLayout
4243
}
4344

44-
override fun on(state: State) {
45-
//ignore
46-
}
47-
4845
override fun on(item: ItemModel, position: Int) {
4946
val emojiProvider = (item as? EmojiProvider) ?: return
5047
emojiTextView.text = emojiProvider.emoji

app/src/main/java/com/github/skyfe79/android/library/app/examples/emojicollection/reducers/Reducers.kt

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,19 @@ package com.github.skyfe79.android.library.app.examples.emojicollection.reducers
22

33
import com.github.skyfe79.android.library.app.examples.emojicollection.EmojiCollectionState
44
import com.github.skyfe79.android.library.app.examples.emojicollection.EmojiCollectionViewModel
5-
import com.github.skyfe79.android.library.app.examples.emojicollection.EmojiRoute
65
import com.github.skyfe79.android.library.app.examples.emojicollection.actions.AddEmojiAction
7-
import com.github.skyfe79.android.library.app.examples.emojicollection.actions.MakeItemModelsAction
86
import com.github.skyfe79.android.library.app.examples.emojicollection.actions.RemoveEmojiAction
97
import com.github.skyfe79.android.library.app.examples.emojicollection.actions.ShuffleEmojiAction
10-
import com.github.skyfe79.android.library.app.examples.emojicollection.components.ClickEmojiAction
118
import com.github.skyfe79.android.library.app.examples.emojicollection.models.EmojiBoxModel
129
import com.github.skyfe79.android.library.app.examples.emojicollection.util.EmojiHelper
13-
import com.github.skyfe79.android.reactcomponentkit.redux.Action
14-
import com.github.skyfe79.android.reactcomponentkit.redux.State
15-
import io.reactivex.Observable
16-
import io.reactivex.Single
17-
import io.reactivex.rxkotlin.subscribeBy
1810
import java.lang.Exception
19-
import kotlin.random.Random
2011

2112

2213
fun EmojiCollectionViewModel.addEmoji(state: EmojiCollectionState, action: AddEmojiAction): EmojiCollectionState {
2314
val mutableEmojiList = state.emojis.toMutableList()
2415
val index = if (mutableEmojiList.isEmpty()) 0 else (0 until mutableEmojiList.size).random()
2516
mutableEmojiList.add(index, EmojiHelper.emoji)
26-
return state.copy(emojis = mutableEmojiList)
17+
return makeItemModels(state.copy(emojis = mutableEmojiList))
2718
}
2819

2920

@@ -32,7 +23,7 @@ fun EmojiCollectionViewModel.removeEmoji(state: EmojiCollectionState, action: Re
3223
val mutableEmojiList = state.emojis.toMutableList()
3324
val index = if (mutableEmojiList.isEmpty()) 0 else (0 until mutableEmojiList.size).random()
3425
mutableEmojiList.removeAt(index)
35-
return state.copy(emojis = mutableEmojiList)
26+
return makeItemModels(state.copy(emojis = mutableEmojiList))
3627
} catch (e: Exception) {
3728
throw e
3829
}

reactcomponentkit/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ publish {
2323
}
2424

2525
android {
26-
compileSdkVersion 28
26+
compileSdkVersion 29
2727

2828

2929
defaultConfig {
3030
minSdkVersion 16
31-
targetSdkVersion 28
32-
versionCode 10
33-
versionName "1.2.8"
31+
targetSdkVersion 29
32+
versionCode 11
33+
versionName "2.0.0"
3434

3535
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
3636
}

reactcomponentkit/src/main/java/com/github/skyfe79/android/reactcomponentkit/RCK.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ internal object RCK {
1313
this.map[token] = WeakReference(viewModel)
1414
}
1515

16-
internal fun <S: State> unregisterViewModel(token: Token) {
16+
internal fun unregisterViewModel(token: Token) {
1717
this.map.remove(token)
1818
}
1919

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package com.github.skyfe79.android.reactcomponentkit
22

33
import com.github.skyfe79.android.reactcomponentkit.eventbus.Token
4+
import com.github.skyfe79.android.reactcomponentkit.redux.State
45

6+
interface StateSubscriber {
7+
fun on(state: State) = Unit
8+
}
59

6-
interface ReactComponent {
10+
interface ReactComponent: StateSubscriber {
711
var token: Token
812
}

reactcomponentkit/src/main/java/com/github/skyfe79/android/reactcomponentkit/component/FragmentComponent.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ import android.content.Context
44
import android.os.Bundle
55
import androidx.fragment.app.Fragment
66
import androidx.fragment.app.FragmentActivity
7-
import com.github.skyfe79.android.reactcomponentkit.RCK
87
import com.github.skyfe79.android.reactcomponentkit.ReactComponent
98
import com.github.skyfe79.android.reactcomponentkit.eventbus.Token
10-
import com.github.skyfe79.android.reactcomponentkit.redux.Action
119
import com.github.skyfe79.android.reactcomponentkit.redux.State
1210

1311
internal enum class FragmentComponentState {
@@ -41,9 +39,12 @@ abstract class FragmentComponent: Fragment(), ReactComponent {
4139
this@FragmentComponent.token = (it.getParcelable("token") as? Token) ?: Token.empty
4240
}
4341
}
42+
43+
this.onInit()
4444
}
4545

46-
abstract fun on(state: State)
46+
open fun onInit() = Unit
47+
abstract override fun on(state: State)
4748
}
4849

4950
inline fun <reified T: FragmentComponent> FragmentActivity.fragmentComponent(token: Token): T {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.github.skyfe79.android.reactcomponentkit.component
2+
3+
import android.app.IntentService
4+
import com.github.skyfe79.android.reactcomponentkit.ReactComponent
5+
import com.github.skyfe79.android.reactcomponentkit.eventbus.Token
6+
import com.github.skyfe79.android.reactcomponentkit.redux.State
7+
8+
abstract class IntentServiceComponent(token: Token, name: String): IntentService(name), ReactComponent {
9+
override var token: Token = token
10+
11+
init {
12+
this.onInit()
13+
}
14+
15+
open fun onInit() = Unit
16+
17+
/**
18+
* It is called when the component is standalone view component.
19+
*/
20+
override fun on(state: State) = Unit
21+
}

reactcomponentkit/src/main/java/com/github/skyfe79/android/reactcomponentkit/component/LayoutComponent.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ abstract class LayoutComponent<in T> : AnkoComponent<T>, ReactComponent {
1414

1515
constructor(token: Token) {
1616
this.token = token
17+
this.onInit()
1718
}
1819

19-
abstract fun on(state: State)
20+
open fun onInit() = Unit
21+
22+
abstract override fun on(state: State)
2023
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.github.skyfe79.android.reactcomponentkit.component
2+
3+
import android.app.Service
4+
import com.github.skyfe79.android.reactcomponentkit.ReactComponent
5+
import com.github.skyfe79.android.reactcomponentkit.eventbus.Token
6+
7+
abstract class ServiceComponent(token: Token): Service(), ReactComponent {
8+
override var token: Token = token
9+
10+
init {
11+
this.onInit()
12+
}
13+
14+
open fun onInit() = Unit
15+
}

0 commit comments

Comments
 (0)