Skip to content
This repository was archived by the owner on Apr 19, 2022. It is now read-only.

Commit 70dd55c

Browse files
authored
Merge pull request #21 from oldergod/mvi-rxjava-kotlin/addedittasks
Mvi rxjava kotlin/addedittasks
2 parents 2df204d + dc9b0b7 commit 70dd55c

File tree

24 files changed

+759
-912
lines changed

24 files changed

+759
-912
lines changed

app/src/androidTest/java/com/example/android/architecture/blueprints/todoapp/tasks/TasksScreenTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public class TasksScreenTest {
9090
protected void beforeActivityLaunched() {
9191
super.beforeActivityLaunched();
9292
// Doing this in @Before generates a race condition.
93-
Injection.provideTasksRepository(InstrumentationRegistry.getTargetContext())
93+
Injection.INSTANCE.provideTasksRepository(InstrumentationRegistry.getTargetContext())
9494
.deleteAllTasks();
9595
}
9696
};

app/src/androidTestMock/java/com/example/android/architecture/blueprints/todoapp/taskdetail/TaskDetailScreenTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ private void startActivityWithWithStubbedTask(Task task) {
100100
// Add a task stub to the fake service api layer.
101101
TasksRepository.Companion.clearInstance();
102102
TasksLocalDataSource.Companion.clearInstance();
103-
Injection.provideTasksRepository(InstrumentationRegistry.getTargetContext()).saveTask(task);
103+
Injection.INSTANCE.provideTasksRepository(InstrumentationRegistry.getTargetContext()).saveTask(task);
104104

105105
// Lazily start the Activity from the ActivityTestRule this time to inject the start Intent
106106
Intent startIntent = new Intent();

app/src/main/java/com/example/android/architecture/blueprints/todoapp/addedittask/AddEditTaskAction.java

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.example.android.architecture.blueprints.todoapp.addedittask
2+
3+
import com.example.android.architecture.blueprints.todoapp.mvibase.MviAction
4+
5+
sealed class AddEditTaskAction : MviAction {
6+
data class PopulateTaskAction(val taskId: String) : AddEditTaskAction()
7+
8+
data class CreateTaskAction(val title: String, val description: String) : AddEditTaskAction()
9+
10+
data class UpdateTaskAction(
11+
val taskId: String,
12+
val title: String,
13+
val description: String
14+
) : AddEditTaskAction()
15+
16+
object SkipMe : AddEditTaskAction()
17+
}

app/src/main/java/com/example/android/architecture/blueprints/todoapp/addedittask/AddEditTaskActionProcessorHolder.java

Lines changed: 0 additions & 105 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package com.example.android.architecture.blueprints.todoapp.addedittask
2+
3+
import com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskAction.CreateTaskAction
4+
import com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskAction.PopulateTaskAction
5+
import com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskAction.UpdateTaskAction
6+
import com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskResult.CreateTaskResult
7+
import com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskResult.PopulateTaskResult
8+
import com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskResult.UpdateTaskResult
9+
import com.example.android.architecture.blueprints.todoapp.data.Task
10+
import com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository
11+
import com.example.android.architecture.blueprints.todoapp.mvibase.MviAction
12+
import com.example.android.architecture.blueprints.todoapp.mvibase.MviResult
13+
import com.example.android.architecture.blueprints.todoapp.mvibase.MviViewModel
14+
import com.example.android.architecture.blueprints.todoapp.util.schedulers.BaseSchedulerProvider
15+
import io.reactivex.Observable
16+
import io.reactivex.ObservableTransformer
17+
18+
19+
/**
20+
* Contains and executes the business logic for all emitted [MviAction]
21+
* and returns one unique [Observable] of [MviResult].
22+
*
23+
*
24+
* This could have been included inside the [MviViewModel]
25+
* but was separated to ease maintenance, as the [MviViewModel] was getting too big.
26+
*/
27+
class AddEditTaskActionProcessorHolder(
28+
private val tasksRepository: TasksRepository,
29+
private val schedulerProvider: BaseSchedulerProvider
30+
) {
31+
private val populateTaskProcessor =
32+
ObservableTransformer<PopulateTaskAction, PopulateTaskResult> { actions ->
33+
actions.flatMap { action ->
34+
tasksRepository.getTask(action.taskId)
35+
// Transform the Single to an Observable to allow emission of multiple
36+
// events down the stream (e.g. the InFlight event)
37+
.toObservable()
38+
// Wrap returned data into an immutable object
39+
.map(PopulateTaskResult::Success)
40+
.cast(PopulateTaskResult::class.java)
41+
// Wrap any error into an immutable object and pass it down the stream
42+
// without crashing.
43+
// Because errors are data and hence, should just be part of the stream.
44+
.onErrorReturn(PopulateTaskResult::Failure)
45+
.subscribeOn(schedulerProvider.io())
46+
.observeOn(schedulerProvider.ui())
47+
// Emit an InFlight event to notify the subscribers (e.g. the UI) we are
48+
// doing work and waiting on a response.
49+
// We emit it after observing on the UI thread to allow the event to be emitted
50+
// on the current frame and avoid jank.
51+
.startWith(PopulateTaskResult.InFlight)
52+
}
53+
}
54+
55+
private val createTaskProcessor =
56+
ObservableTransformer<CreateTaskAction, CreateTaskResult> { actions ->
57+
actions
58+
.map { action -> Task(title = action.title, description = action.description) }
59+
.map { task ->
60+
if (task.empty) {
61+
CreateTaskResult.Empty
62+
} else {
63+
tasksRepository.saveTask(task)
64+
CreateTaskResult.Success
65+
}
66+
}
67+
}
68+
69+
private val updateTaskProcessor =
70+
ObservableTransformer<UpdateTaskAction, UpdateTaskResult> { actions ->
71+
actions.flatMap { action ->
72+
tasksRepository.saveTask(Task.invoke(action.title, action.description, action.taskId))
73+
.andThen(Observable.just(UpdateTaskResult))
74+
}
75+
}
76+
77+
/**
78+
* Splits the [<] to match each type of [MviAction] to
79+
* its corresponding business logic processor. Each processor takes a defined [MviAction],
80+
* returns a defined [MviResult]
81+
* The global actionProcessor then merges all [<] back to
82+
* one unique [<].
83+
*
84+
*
85+
* The splitting is done using [Observable.publish] which allows almost anything
86+
* on the passed [Observable] as long as one and only one [Observable] is returned.
87+
*
88+
*
89+
* An security layer is also added for unhandled [MviAction] to allow early crash
90+
* at runtime to easy the maintenance.
91+
*/
92+
internal var actionProcessor =
93+
ObservableTransformer<AddEditTaskAction, AddEditTaskResult> { actions ->
94+
actions.publish { shared ->
95+
Observable.merge<AddEditTaskResult>(
96+
// Match PopulateTasks to populateTaskProcessor
97+
shared.ofType(AddEditTaskAction.PopulateTaskAction::class.java)
98+
.compose(populateTaskProcessor),
99+
// Match CreateTasks to createTaskProcessor
100+
shared.ofType(AddEditTaskAction.CreateTaskAction::class.java)
101+
.compose(createTaskProcessor),
102+
// Match UpdateTasks to updateTaskProcessor
103+
shared.ofType(AddEditTaskAction.UpdateTaskAction::class.java)
104+
.compose(updateTaskProcessor))
105+
.mergeWith(
106+
// Error for not implemented actions
107+
shared.filter { v ->
108+
v !is AddEditTaskAction.PopulateTaskAction &&
109+
v !is AddEditTaskAction.CreateTaskAction &&
110+
v !is AddEditTaskAction.UpdateTaskAction
111+
}
112+
.flatMap { w ->
113+
Observable.error<AddEditTaskResult>(
114+
IllegalArgumentException("Unknown Action type: " + w))
115+
})
116+
}
117+
}
118+
}

app/src/main/java/com/example/android/architecture/blueprints/todoapp/addedittask/AddEditTaskActivity.java

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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy