forked from github/wulkanowy-mirror
Add coroutines scope to presenter (#1554)
This commit is contained in:
parent
e02d93f979
commit
8e607d48f7
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
|
@ -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) }
|
||||||
|
@ -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 ->
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,15 +122,17 @@ class NotePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateNote(note: Note) {
|
private fun updateNote(note: Note) {
|
||||||
flowWithResource { noteRepository.updateNote(note) }.onEach {
|
flowWithResource { noteRepository.updateNote(note) }
|
||||||
when (it.status) {
|
.onEach {
|
||||||
Status.LOADING -> Timber.i("Attempt to update note ${note.id}")
|
when (it.status) {
|
||||||
Status.SUCCESS -> Timber.i("Update note result: Success")
|
Status.LOADING -> Timber.i("Attempt to update note ${note.id}")
|
||||||
Status.ERROR -> {
|
Status.SUCCESS -> Timber.i("Update note result: Success")
|
||||||
Timber.i("Update note result: An exception occurred")
|
Status.ERROR -> {
|
||||||
errorHandler.dispatch(it.error!!)
|
Timber.i("Update note result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it.error!!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launchIn(this)
|
.launch("update_note")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user