Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't use mutable shared flows in UI #4346

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ interface Event
@Singleton
class EventHub @Inject constructor() {

private val sharedEventFlow = MutableSharedFlow<Event>()
val events: SharedFlow<Event> = sharedEventFlow.asSharedFlow()
private val _events = MutableSharedFlow<Event>()
val events: SharedFlow<Event> = _events.asSharedFlow()

suspend fun dispatch(event: Event) {
sharedEventFlow.emit(event)
_events.emit(event)
}

// TODO remove as soon as NotificationsFragment is Kotlin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch

Expand All @@ -53,13 +54,13 @@ class ListsForAccountViewModel @Inject constructor(
) : ViewModel() {

private val _states = MutableSharedFlow<List<AccountListState>>(1)
val states: SharedFlow<List<AccountListState>> = _states
val states: SharedFlow<List<AccountListState>> = _states.asSharedFlow()

private val _loadError = MutableSharedFlow<Throwable>(1)
val loadError: SharedFlow<Throwable> = _loadError
val loadError: SharedFlow<Throwable> = _loadError.asSharedFlow()

private val _actionError = MutableSharedFlow<ActionError>(1)
val actionError: SharedFlow<ActionError> = _actionError
val actionError: SharedFlow<ActionError> = _actionError.asSharedFlow()

fun load(accountId: String?) {
_loadError.resetReplayCache()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.shareIn
Expand Down Expand Up @@ -107,12 +108,12 @@ class ComposeViewModel @Inject constructor(
private val _media = MutableStateFlow(emptyList<QueuedMedia>())
val media: StateFlow<List<QueuedMedia>> = _media.asStateFlow()

val uploadError =
MutableSharedFlow<Throwable>(
replay = 0,
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
private val _uploadError = MutableSharedFlow<Throwable>(
replay = 0,
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val uploadError: SharedFlow<Throwable> = _uploadError.asSharedFlow()

private val _closeConfirmation = MutableStateFlow(ConfirmationKind.NONE)
val closeConfirmation: StateFlow<ConfirmationKind> = _closeConfirmation.asStateFlow()
Expand Down Expand Up @@ -202,7 +203,7 @@ class ComposeViewModel @Inject constructor(
)
is UploadEvent.ErrorEvent -> {
_media.update { mediaList -> mediaList.filter { it.localId != mediaItem.localId } }
uploadError.emit(event.error)
_uploadError.emit(event.error)
return@collect
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import at.connyduck.calladapter.networkresult.onFailure
import com.keylesspalace.tusky.R
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch

class DomainBlocksViewModel @Inject constructor(
Expand All @@ -18,12 +20,13 @@ class DomainBlocksViewModel @Inject constructor(

val domainPager = repo.domainPager.cachedIn(viewModelScope)

val uiEvents = MutableSharedFlow<SnackbarEvent>()
private val _uiEvents = MutableSharedFlow<SnackbarEvent>()
val uiEvents: SharedFlow<SnackbarEvent> = _uiEvents.asSharedFlow()

fun block(domain: String) {
viewModelScope.launch {
repo.block(domain).onFailure { e ->
uiEvents.emit(
_uiEvents.emit(
SnackbarEvent(
message = R.string.error_blocking_domain,
domain = domain,
Expand All @@ -39,7 +42,7 @@ class DomainBlocksViewModel @Inject constructor(
fun unblock(domain: String) {
viewModelScope.launch {
repo.unblock(domain).fold({
uiEvents.emit(
_uiEvents.emit(
SnackbarEvent(
message = R.string.confirmation_domain_unmuted,
domain = domain,
Expand All @@ -49,7 +52,7 @@ class DomainBlocksViewModel @Inject constructor(
)
)
}, { e ->
uiEvents.emit(
_uiEvents.emit(
SnackbarEvent(
message = R.string.error_unblocking_domain,
domain = domain,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import com.keylesspalace.tusky.entity.Filter
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.isHttpNotFound
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

class FiltersViewModel @Inject constructor(
Expand All @@ -30,8 +31,8 @@ class FiltersViewModel @Inject constructor(

data class State(val filters: List<Filter>, val loadingState: LoadingState)

val state: Flow<State> get() = _state
private val _state = MutableStateFlow(State(emptyList(), LoadingState.INITIAL))
val state: StateFlow<State> = _state.asStateFlow()
Comment on lines -33 to +35
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this in #4336.


fun load() {
this@FiltersViewModel._state.value = _state.value.copy(loadingState = LoadingState.LOADING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
Expand All @@ -68,14 +70,12 @@ class ViewThreadViewModel @Inject constructor(
private val _uiState = MutableStateFlow(ThreadUiState.Loading as ThreadUiState)
val uiState: Flow<ThreadUiState> = _uiState.asStateFlow()

private val _errors =
MutableSharedFlow<Throwable>(
replay = 0,
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val errors: Flow<Throwable>
get() = _errors
private val _errors = MutableSharedFlow<Throwable>(
replay = 0,
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val errors: SharedFlow<Throwable> = _errors.asSharedFlow()

var isInitialLoad: Boolean = true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ import java.io.IOException
import java.net.ConnectException
import javax.inject.Inject
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

internal class ListsViewModel @Inject constructor(private val api: MastodonApi) : ViewModel() {
Expand All @@ -49,15 +52,15 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)

data class State(val lists: List<MastoList>, val loadingState: LoadingState)

val state: Flow<State> get() = _state
val events: Flow<Event> get() = _events
private val _state = MutableStateFlow(State(listOf(), LoadingState.INITIAL))
private val _events =
MutableSharedFlow<Event>(
replay = 0,
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val state: StateFlow<State> = _state.asStateFlow()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.


private val _events = MutableSharedFlow<Event>(
replay = 0,
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val events: SharedFlow<Event> = _events.asSharedFlow()

fun retryLoading() {
loadIfNeeded()
Expand Down