Add loading state to toggle switch and enforce when changing call link admin settings.

This commit is contained in:
Alex Hart
2025-01-07 16:10:14 -04:00
committed by Greyson Parrelli
parent 90fdcbf7b6
commit 8da7ef9a3e
7 changed files with 135 additions and 21 deletions

View File

@@ -89,6 +89,7 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment
override fun SheetContent() {
val callLink: CallLinkTable.CallLink by viewModel.callLink
val displayAlreadyInACallSnackbar: Boolean by viewModel.showAlreadyInACall.collectAsStateWithLifecycle(false)
val isLoadingAdminApprovalChange: Boolean by viewModel.isLoadingAdminApprovalChange.collectAsStateWithLifecycle(false)
CreateCallLinkBottomSheetContent(
callLink = callLink,
@@ -100,7 +101,8 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment
onCopyLinkClicked = this@CreateCallLinkBottomSheetDialogFragment::onCopyLinkClicked,
onShareLinkClicked = this@CreateCallLinkBottomSheetDialogFragment::onShareLinkClicked,
onDoneClicked = this@CreateCallLinkBottomSheetDialogFragment::onDoneClicked,
displayAlreadyInACallSnackbar = displayAlreadyInACallSnackbar
displayAlreadyInACallSnackbar = displayAlreadyInACallSnackbar,
isLoadingAdminApprovalChange = isLoadingAdminApprovalChange
)
}
@@ -236,6 +238,7 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment
private fun CreateCallLinkBottomSheetContent(
callLink: CallLinkTable.CallLink,
displayAlreadyInACallSnackbar: Boolean,
isLoadingAdminApprovalChange: Boolean,
onJoinClicked: () -> Unit = {},
onAddACallNameClicked: () -> Unit = {},
onApproveAllMembersChanged: (Boolean) -> Unit = {},
@@ -288,7 +291,8 @@ private fun CreateCallLinkBottomSheetContent(
checked = callLink.state.restrictions == CallLinkState.Restrictions.ADMIN_APPROVAL,
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__require_admin_approval),
onCheckChanged = onApproveAllMembersChanged,
modifier = Modifier.clickable(onClick = onToggleApproveAllMembersClicked)
modifier = Modifier.clickable(onClick = onToggleApproveAllMembersClicked),
isLoading = isLoadingAdminApprovalChange
)
Dividers.Default()
@@ -347,7 +351,8 @@ private fun CreateCallLinkBottomSheetContentPreview() {
),
deletionTimestamp = 0L
),
displayAlreadyInACallSnackbar = true
displayAlreadyInACallSnackbar = true,
isLoadingAdminApprovalChange = false
)
}
}

View File

@@ -53,6 +53,9 @@ class CreateCallLinkViewModel(
private val internalShowAlreadyInACall = MutableStateFlow(false)
val showAlreadyInACall: StateFlow<Boolean> = internalShowAlreadyInACall
private val internalIsLoadingAdminApprovalChange = MutableStateFlow(false)
val isLoadingAdminApprovalChange: StateFlow<Boolean> = internalIsLoadingAdminApprovalChange
private val disposables = CompositeDisposable()
init {
@@ -88,6 +91,12 @@ class CreateCallLinkViewModel(
}
}
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe {
internalIsLoadingAdminApprovalChange.update { true }
}
.doFinally {
internalIsLoadingAdminApprovalChange.update { false }
}
}
fun toggleApproveAllMembers(): Single<UpdateCallLinkResult> {

View File

@@ -81,7 +81,7 @@ class CallLinkDetailsFragment : ComposeFragment(), CallLinkDetailsCallback {
@Composable
override fun FragmentContent() {
val state by viewModel.state
val state by viewModel.state.collectAsStateWithLifecycle()
val showAlreadyInACall by viewModel.showAlreadyInACall.collectAsStateWithLifecycle(false)
CallLinkDetails(
@@ -236,6 +236,7 @@ private fun CallLinkDetailsPreview() {
SignalTheme(false) {
CallLinkDetails(
CallLinkDetailsState(
false,
false,
callLink
),
@@ -297,7 +298,8 @@ private fun CallLinkDetails(
Rows.ToggleRow(
checked = state.callLink.state.restrictions == Restrictions.ADMIN_APPROVAL,
text = stringResource(id = R.string.CallLinkDetailsFragment__require_admin_approval),
onCheckChanged = callback::onApproveAllMembersChanged
onCheckChanged = callback::onApproveAllMembersChanged,
isLoading = state.isLoadingAdminApprovalChange
)
Dividers.Default()

View File

@@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.service.webrtc.CallLinkPeekInfo
@Immutable
data class CallLinkDetailsState(
val displayRevocationDialog: Boolean = false,
val isLoadingAdminApprovalChange: Boolean = false,
val callLink: CallLinkTable.CallLink? = null,
val peekInfo: CallLinkPeekInfo? = null
)

View File

@@ -5,9 +5,6 @@
package org.thoughtcrime.securesms.calls.links.details
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
@@ -35,8 +32,8 @@ class CallLinkDetailsViewModel(
) : ViewModel() {
private val disposables = CompositeDisposable()
private val _state: MutableState<CallLinkDetailsState> = mutableStateOf(CallLinkDetailsState())
val state: State<CallLinkDetailsState> = _state
private val _state: MutableStateFlow<CallLinkDetailsState> = MutableStateFlow(CallLinkDetailsState())
val state: StateFlow<CallLinkDetailsState> = _state
val nameSnapshot: String
get() = state.value.callLink?.state?.name ?: error("Call link not loaded yet.")
@@ -55,8 +52,8 @@ class CallLinkDetailsViewModel(
disposables += CallLinks.watchCallLink(callLinkRoomId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy {
_state.value = _state.value.copy(callLink = it)
.subscribeBy { callLink ->
_state.update { it.copy(callLink = callLink) }
}
disposables += repository
@@ -77,7 +74,7 @@ class CallLinkDetailsViewModel(
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy { callLinkPeekInfo ->
_state.value = _state.value.copy(peekInfo = callLinkPeekInfo)
_state.update { it.copy(peekInfo = callLinkPeekInfo) }
}
}
@@ -91,12 +88,19 @@ class CallLinkDetailsViewModel(
}
fun setDisplayRevocationDialog(displayRevocationDialog: Boolean) {
_state.value = _state.value.copy(displayRevocationDialog = displayRevocationDialog)
_state.update { it.copy(displayRevocationDialog = displayRevocationDialog) }
}
fun setApproveAllMembers(approveAllMembers: Boolean): Single<UpdateCallLinkResult> {
val credentials = _state.value.callLink?.credentials ?: error("User cannot change the name of this call.")
return mutationRepository.setCallRestrictions(credentials, if (approveAllMembers) CallLinkState.Restrictions.ADMIN_APPROVAL else CallLinkState.Restrictions.NONE)
return mutationRepository
.setCallRestrictions(credentials, if (approveAllMembers) CallLinkState.Restrictions.ADMIN_APPROVAL else CallLinkState.Restrictions.NONE)
.doOnSubscribe {
_state.update { it.copy(isLoadingAdminApprovalChange = true) }
}
.doFinally {
_state.update { it.copy(isLoadingAdminApprovalChange = false) }
}
}
fun setName(name: String): Single<UpdateCallLinkResult> {