1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-20 05:19:08 -05:00

Add coroutines scope to presenter (#1554)

This commit is contained in:
Rafał Borcz 2021-10-03 10:36:17 +02:00 committed by GitHub
parent e02d93f979
commit 8e607d48f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 31 additions and 33 deletions

View File

@ -6,29 +6,27 @@ import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancelChildren
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import timber.log.Timber import timber.log.Timber
import kotlin.coroutines.CoroutineContext
open class BasePresenter<T : BaseView>( open class BasePresenter<T : BaseView>(
protected val errorHandler: ErrorHandler, protected val errorHandler: ErrorHandler,
protected val studentRepository: StudentRepository protected val studentRepository: StudentRepository
) : CoroutineScope { ) {
private val job = SupervisorJob()
private var job = Job() protected val presenterScope = CoroutineScope(job + Dispatchers.Main)
private val jobs = mutableMapOf<String, Job>() private val childrenJobs = mutableMapOf<String, Job>()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
var view: T? = null var view: T? = null
open fun onAttachView(view: T) { open fun onAttachView(view: T) {
job = Job()
this.view = view this.view = view
errorHandler.apply { errorHandler.apply {
showErrorMessage = view::showError showErrorMessage = view::showError
@ -64,22 +62,22 @@ open class BasePresenter<T : BaseView>(
} }
fun <T> Flow<T>.launch(individualJobTag: String = "load"): Job { fun <T> Flow<T>.launch(individualJobTag: String = "load"): Job {
jobs[individualJobTag]?.cancel() childrenJobs[individualJobTag]?.cancel()
val job = catch { errorHandler.dispatch(it) }.launchIn(this@BasePresenter) val job = catch { errorHandler.dispatch(it) }.launchIn(presenterScope)
jobs[individualJobTag] = job childrenJobs[individualJobTag] = job
Timber.d("Job $individualJobTag launched in ${this@BasePresenter.javaClass.simpleName}: $job") Timber.d("Job $individualJobTag launched in ${this@BasePresenter.javaClass.simpleName}: $job")
return job return job
} }
fun cancelJobs(vararg names: String) { fun cancelJobs(vararg names: String) {
names.forEach { names.forEach {
jobs[it]?.cancel() childrenJobs[it]?.cancel()
} }
} }
open fun onDetachView() { open fun onDetachView() {
view = null job.cancelChildren()
job.cancel()
errorHandler.clear() errorHandler.clear()
view = null
} }
} }

View File

@ -149,7 +149,7 @@ class DashboardPresenter @Inject constructor(
tileList: List<DashboardItem.Type>, tileList: List<DashboardItem.Type>,
forceRefresh: Boolean forceRefresh: Boolean
) { ) {
launch { presenterScope.launch {
Timber.i("Loading dashboard account data started") Timber.i("Loading dashboard account data started")
val student = runCatching { studentRepository.getCurrentStudent(true) } val student = runCatching { studentRepository.getCurrentStudent(true) }
.onFailure { .onFailure {

View File

@ -88,7 +88,7 @@ class NotificationDebugPresenter @Inject constructor(
} }
private fun withStudent(block: suspend (Student) -> Unit) { private fun withStudent(block: suspend (Student) -> Unit) {
launch { presenterScope.launch {
block(studentRepository.getCurrentStudent(false)) block(studentRepository.getCurrentStudent(false))
} }
} }

View File

@ -15,7 +15,7 @@ class MessagePresenter @Inject constructor(
override fun onAttachView(view: MessageView) { override fun onAttachView(view: MessageView) {
super.onAttachView(view) super.onAttachView(view)
launch { presenterScope.launch {
delay(150) delay(150)
view.initView() view.initView()
Timber.i("Message view was initialized") Timber.i("Message view was initialized")

View File

@ -224,14 +224,14 @@ class SendMessagePresenter @Inject constructor(
} }
fun onMessageContentChange() { fun onMessageContentChange() {
launch { presenterScope.launch {
messageUpdateChannel.send(Unit) messageUpdateChannel.send(Unit)
} }
} }
@OptIn(FlowPreview::class) @OptIn(FlowPreview::class)
private fun initializeSubjectStream() { private fun initializeSubjectStream() {
launch { presenterScope.launch {
messageUpdateChannel.consumeAsFlow() messageUpdateChannel.consumeAsFlow()
.debounce(250) .debounce(250)
.catch { Timber.e(it) } .catch { Timber.e(it) }

View File

@ -173,14 +173,14 @@ class MessageTabPresenter @Inject constructor(
} }
fun onSearchQueryTextChange(query: String) { fun onSearchQueryTextChange(query: String) {
launch { presenterScope.launch {
searchChannel.send(query) searchChannel.send(query)
} }
} }
@OptIn(FlowPreview::class) @OptIn(FlowPreview::class)
private fun initializeSearchStream() { private fun initializeSearchStream() {
launch { presenterScope.launch {
searchChannel.consumeAsFlow() searchChannel.consumeAsFlow()
.debounce(250) .debounce(250)
.map { query -> .map { query ->

View File

@ -11,7 +11,6 @@ import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.afterLoading import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.flowWithResourceIn import io.github.wulkanowy.utils.flowWithResourceIn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -148,6 +147,6 @@ class MobileDevicePresenter @Inject constructor(
errorHandler.dispatch(it.error!!) errorHandler.dispatch(it.error!!)
} }
} }
}.launchIn(this) }.launch("unregister")
} }
} }

View File

@ -11,7 +11,6 @@ import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.afterLoading import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.flowWithResourceIn import io.github.wulkanowy.utils.flowWithResourceIn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -123,7 +122,8 @@ class NotePresenter @Inject constructor(
} }
private fun updateNote(note: Note) { private fun updateNote(note: Note) {
flowWithResource { noteRepository.updateNote(note) }.onEach { flowWithResource { noteRepository.updateNote(note) }
.onEach {
when (it.status) { when (it.status) {
Status.LOADING -> Timber.i("Attempt to update note ${note.id}") Status.LOADING -> Timber.i("Attempt to update note ${note.id}")
Status.SUCCESS -> Timber.i("Update note result: Success") Status.SUCCESS -> Timber.i("Update note result: Success")
@ -132,6 +132,7 @@ class NotePresenter @Inject constructor(
errorHandler.dispatch(it.error!!) errorHandler.dispatch(it.error!!)
} }
} }
}.launchIn(this) }
.launch("update_note")
} }
} }

View File

@ -15,7 +15,7 @@ class SchoolAndTeachersPresenter @Inject constructor(
override fun onAttachView(view: SchoolAndTeachersView) { override fun onAttachView(view: SchoolAndTeachersView) {
super.onAttachView(view) super.onAttachView(view)
launch { presenterScope.launch {
delay(150) delay(150)
view.initView() view.initView()
Timber.i("Message view was initialized") Timber.i("Message view was initialized")