mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 09:49:30 +01:00
Add snackbar that is displayed if you're currently in a different call.
This commit is contained in:
committed by
Greyson Parrelli
parent
c36c6e62e2
commit
5bd3eda17d
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.calls
|
||||
|
||||
import android.view.View
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.signal.core.ui.Snackbars
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
||||
/**
|
||||
* Snackbar which can be displayed whenever the user tries to join a call but is already in another.
|
||||
*/
|
||||
object YouAreAlreadyInACallSnackbar {
|
||||
/**
|
||||
* Composable component
|
||||
*/
|
||||
@Composable
|
||||
fun YouAreAlreadyInACallSnackbar(
|
||||
displaySnackbar: Boolean,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val message = stringResource(R.string.CommunicationActions__you_are_already_in_a_call)
|
||||
val hostState = remember { SnackbarHostState() }
|
||||
Snackbars.Host(hostState, modifier = modifier)
|
||||
|
||||
LaunchedEffect(displaySnackbar) {
|
||||
if (displaySnackbar) {
|
||||
hostState.showSnackbar(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View system component
|
||||
*/
|
||||
@JvmStatic
|
||||
fun show(view: View) {
|
||||
Snackbar.make(
|
||||
view,
|
||||
view.context.getString(R.string.CommunicationActions__you_are_already_in_a_call),
|
||||
Snackbar.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@@ -21,6 +22,7 @@ import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -36,21 +38,28 @@ import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import org.signal.core.ui.BottomSheets
|
||||
import org.signal.core.ui.Buttons
|
||||
import org.signal.core.ui.Dividers
|
||||
import org.signal.core.ui.Previews
|
||||
import org.signal.core.ui.Rows
|
||||
import org.signal.core.ui.SignalPreview
|
||||
import org.signal.core.util.concurrent.LifecycleDisposable
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.ringrtc.CallLinkState
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar.YouAreAlreadyInACallSnackbar
|
||||
import org.thoughtcrime.securesms.calls.links.CallLinks
|
||||
import org.thoughtcrime.securesms.calls.links.EditCallLinkNameDialogFragment
|
||||
import org.thoughtcrime.securesms.calls.links.SignalCallRow
|
||||
import org.thoughtcrime.securesms.compose.ComposeBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.database.CallLinkTable
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CreateCallLinkResult
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.SignalCallLinkState
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.UpdateCallLinkResult
|
||||
import org.thoughtcrime.securesms.sharing.v2.ShareActivity
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import java.time.Instant
|
||||
|
||||
/**
|
||||
* Bottom sheet for creating call links
|
||||
@@ -77,84 +86,21 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment
|
||||
|
||||
@Composable
|
||||
override fun SheetContent() {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentSize(Alignment.Center)
|
||||
) {
|
||||
val callLink: CallLinkTable.CallLink by viewModel.callLink
|
||||
val callLink: CallLinkTable.CallLink by viewModel.callLink
|
||||
val displayAlreadyInACallSnackbar: Boolean by viewModel.showAlreadyInACall.collectAsState(false)
|
||||
|
||||
BottomSheets.Handle(modifier = Modifier.align(Alignment.CenterHorizontally))
|
||||
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__create_call_link),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
SignalCallRow(
|
||||
callLink = callLink,
|
||||
callLinkPeekInfo = null,
|
||||
onJoinClicked = this@CreateCallLinkBottomSheetDialogFragment::onJoinClicked
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(
|
||||
id = if (callLink.state.name.isEmpty()) {
|
||||
R.string.CreateCallLinkBottomSheetDialogFragment__add_call_name
|
||||
} else {
|
||||
R.string.CreateCallLinkBottomSheetDialogFragment__edit_call_name
|
||||
}
|
||||
),
|
||||
onClick = this@CreateCallLinkBottomSheetDialogFragment::onAddACallNameClicked
|
||||
)
|
||||
|
||||
Rows.ToggleRow(
|
||||
checked = callLink.state.restrictions == CallLinkState.Restrictions.ADMIN_APPROVAL,
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__require_admin_approval),
|
||||
onCheckChanged = this@CreateCallLinkBottomSheetDialogFragment::setApproveAllMembers,
|
||||
modifier = Modifier.clickable(onClick = this@CreateCallLinkBottomSheetDialogFragment::toggleApproveAllMembers)
|
||||
)
|
||||
|
||||
Dividers.Default()
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__share_link_via_signal),
|
||||
icon = painterResource(id = R.drawable.symbol_forward_24),
|
||||
onClick = this@CreateCallLinkBottomSheetDialogFragment::onShareViaSignalClicked
|
||||
)
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__copy_link),
|
||||
icon = painterResource(id = R.drawable.symbol_copy_android_24),
|
||||
onClick = this@CreateCallLinkBottomSheetDialogFragment::onCopyLinkClicked
|
||||
)
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__share_link),
|
||||
icon = painterResource(id = R.drawable.symbol_share_android_24),
|
||||
onClick = this@CreateCallLinkBottomSheetDialogFragment::onShareLinkClicked
|
||||
)
|
||||
|
||||
Buttons.MediumTonal(
|
||||
onClick = this@CreateCallLinkBottomSheetDialogFragment::onDoneClicked,
|
||||
modifier = Modifier
|
||||
.padding(end = dimensionResource(id = R.dimen.core_ui__gutter))
|
||||
.align(Alignment.End)
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__done))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
}
|
||||
CreateCallLinkBottomSheetContent(
|
||||
callLink = callLink,
|
||||
onJoinClicked = this@CreateCallLinkBottomSheetDialogFragment::onJoinClicked,
|
||||
onAddACallNameClicked = this@CreateCallLinkBottomSheetDialogFragment::onAddACallNameClicked,
|
||||
onApproveAllMembersChanged = this@CreateCallLinkBottomSheetDialogFragment::setApproveAllMembers,
|
||||
onToggleApproveAllMembersClicked = this@CreateCallLinkBottomSheetDialogFragment::toggleApproveAllMembers,
|
||||
onShareViaSignalClicked = this@CreateCallLinkBottomSheetDialogFragment::onShareViaSignalClicked,
|
||||
onCopyLinkClicked = this@CreateCallLinkBottomSheetDialogFragment::onCopyLinkClicked,
|
||||
onShareLinkClicked = this@CreateCallLinkBottomSheetDialogFragment::onShareLinkClicked,
|
||||
onDoneClicked = this@CreateCallLinkBottomSheetDialogFragment::onDoneClicked,
|
||||
displayAlreadyInACallSnackbar = displayAlreadyInACallSnackbar
|
||||
)
|
||||
}
|
||||
|
||||
private fun setCallName(callName: String) {
|
||||
@@ -195,7 +141,9 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment
|
||||
lifecycleDisposable += viewModel.commitCallLink().subscribeBy(onSuccess = {
|
||||
when (it) {
|
||||
is EnsureCallLinkCreatedResult.Success -> {
|
||||
CommunicationActions.startVideoCall(requireActivity(), it.recipient)
|
||||
CommunicationActions.startVideoCall(requireActivity(), it.recipient) {
|
||||
viewModel.setShowAlreadyInACall(true)
|
||||
}
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
@@ -282,3 +230,123 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment
|
||||
Toast.makeText(requireContext(), R.string.CallLinkDetailsFragment__couldnt_save_changes, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CreateCallLinkBottomSheetContent(
|
||||
callLink: CallLinkTable.CallLink,
|
||||
displayAlreadyInACallSnackbar: Boolean,
|
||||
onJoinClicked: () -> Unit = {},
|
||||
onAddACallNameClicked: () -> Unit = {},
|
||||
onApproveAllMembersChanged: (Boolean) -> Unit = {},
|
||||
onToggleApproveAllMembersClicked: () -> Unit = {},
|
||||
onShareViaSignalClicked: () -> Unit = {},
|
||||
onCopyLinkClicked: () -> Unit = {},
|
||||
onShareLinkClicked: () -> Unit = {},
|
||||
onDoneClicked: () -> Unit = {}
|
||||
) {
|
||||
Box {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentSize(Alignment.Center)
|
||||
) {
|
||||
BottomSheets.Handle(modifier = Modifier.align(Alignment.CenterHorizontally))
|
||||
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__create_call_link),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
SignalCallRow(
|
||||
callLink = callLink,
|
||||
callLinkPeekInfo = null,
|
||||
onJoinClicked = onJoinClicked
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(
|
||||
id = if (callLink.state.name.isEmpty()) {
|
||||
R.string.CreateCallLinkBottomSheetDialogFragment__add_call_name
|
||||
} else {
|
||||
R.string.CreateCallLinkBottomSheetDialogFragment__edit_call_name
|
||||
}
|
||||
),
|
||||
onClick = onAddACallNameClicked
|
||||
)
|
||||
|
||||
Rows.ToggleRow(
|
||||
checked = callLink.state.restrictions == CallLinkState.Restrictions.ADMIN_APPROVAL,
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__require_admin_approval),
|
||||
onCheckChanged = onApproveAllMembersChanged,
|
||||
modifier = Modifier.clickable(onClick = onToggleApproveAllMembersClicked)
|
||||
)
|
||||
|
||||
Dividers.Default()
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__share_link_via_signal),
|
||||
icon = painterResource(id = R.drawable.symbol_forward_24),
|
||||
onClick = onShareViaSignalClicked
|
||||
)
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__copy_link),
|
||||
icon = painterResource(id = R.drawable.symbol_copy_android_24),
|
||||
onClick = onCopyLinkClicked
|
||||
)
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__share_link),
|
||||
icon = painterResource(id = R.drawable.symbol_share_android_24),
|
||||
onClick = onShareLinkClicked
|
||||
)
|
||||
|
||||
Buttons.MediumTonal(
|
||||
onClick = onDoneClicked,
|
||||
modifier = Modifier
|
||||
.padding(end = dimensionResource(id = R.dimen.core_ui__gutter))
|
||||
.align(Alignment.End)
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__done))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
}
|
||||
|
||||
YouAreAlreadyInACallSnackbar(
|
||||
displaySnackbar = displayAlreadyInACallSnackbar,
|
||||
modifier = Modifier.align(Alignment.BottomCenter)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@SignalPreview
|
||||
@Composable
|
||||
private fun CreateCallLinkBottomSheetContentPreview() {
|
||||
Previews.BottomSheetPreview {
|
||||
CreateCallLinkBottomSheetContent(
|
||||
callLink = CallLinkTable.CallLink(
|
||||
recipientId = RecipientId.UNKNOWN,
|
||||
roomId = CallLinkRoomId.fromBytes(byteArrayOf(1, 2, 3, 4)),
|
||||
credentials = null,
|
||||
state = SignalCallLinkState(
|
||||
name = "Test Call",
|
||||
restrictions = CallLinkState.Restrictions.ADMIN_APPROVAL,
|
||||
revoked = false,
|
||||
expiration = Instant.MAX
|
||||
),
|
||||
deletionTimestamp = 0L
|
||||
),
|
||||
displayAlreadyInACallSnackbar = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import org.signal.ringrtc.CallLinkState.Restrictions
|
||||
import org.thoughtcrime.securesms.calls.links.CallLinks
|
||||
import org.thoughtcrime.securesms.calls.links.UpdateCallLinkRepository
|
||||
@@ -47,6 +50,9 @@ class CreateCallLinkViewModel(
|
||||
val callLink: State<CallLinkTable.CallLink> = _callLink
|
||||
val linkKeyBytes: ByteArray = credentials.linkKeyBytes
|
||||
|
||||
private val internalShowAlreadyInACall = MutableStateFlow(false)
|
||||
val showAlreadyInACall: StateFlow<Boolean> = internalShowAlreadyInACall
|
||||
|
||||
private val disposables = CompositeDisposable()
|
||||
|
||||
init {
|
||||
@@ -61,6 +67,10 @@ class CreateCallLinkViewModel(
|
||||
disposables.dispose()
|
||||
}
|
||||
|
||||
fun setShowAlreadyInACall(showAlreadyInACall: Boolean) {
|
||||
internalShowAlreadyInACall.update { showAlreadyInACall }
|
||||
}
|
||||
|
||||
fun commitCallLink(): Single<EnsureCallLinkCreatedResult> {
|
||||
return repository.ensureCallLinkCreated(credentials)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -37,6 +38,8 @@ import org.signal.core.util.concurrent.LifecycleDisposable
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.ringrtc.CallLinkState.Restrictions
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar
|
||||
import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar.YouAreAlreadyInACallSnackbar
|
||||
import org.thoughtcrime.securesms.calls.links.CallLinks
|
||||
import org.thoughtcrime.securesms.calls.links.EditCallLinkNameDialogFragment
|
||||
import org.thoughtcrime.securesms.calls.links.SignalCallRow
|
||||
@@ -44,6 +47,7 @@ import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.database.CallLinkTable
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkCredentials
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.SignalCallLinkState
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.UpdateCallLinkResult
|
||||
import org.thoughtcrime.securesms.sharing.v2.ShareActivity
|
||||
@@ -79,9 +83,11 @@ class CallLinkDetailsFragment : ComposeFragment(), CallLinkDetailsCallback {
|
||||
@Composable
|
||||
override fun FragmentContent() {
|
||||
val state by viewModel.state
|
||||
val showAlreadyInACall by viewModel.showAlreadyInACall.collectAsState(false)
|
||||
|
||||
CallLinkDetails(
|
||||
state,
|
||||
showAlreadyInACall,
|
||||
this
|
||||
)
|
||||
}
|
||||
@@ -93,7 +99,9 @@ class CallLinkDetailsFragment : ComposeFragment(), CallLinkDetailsCallback {
|
||||
override fun onJoinClicked() {
|
||||
val recipientSnapshot = viewModel.recipientSnapshot
|
||||
if (recipientSnapshot != null) {
|
||||
CommunicationActions.startVideoCall(this, recipientSnapshot)
|
||||
CommunicationActions.startVideoCall(this, recipientSnapshot) {
|
||||
viewModel.showAlreadyInACall(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +214,7 @@ private fun CallLinkDetailsPreview() {
|
||||
)
|
||||
CallLinkTable.CallLink(
|
||||
recipientId = RecipientId.UNKNOWN,
|
||||
roomId = credentials.roomId,
|
||||
roomId = CallLinkRoomId.fromBytes(byteArrayOf(1, 2, 3, 4)),
|
||||
credentials = credentials,
|
||||
state = SignalCallLinkState(
|
||||
name = "Call Name",
|
||||
@@ -224,6 +232,7 @@ private fun CallLinkDetailsPreview() {
|
||||
false,
|
||||
callLink
|
||||
),
|
||||
true,
|
||||
object : CallLinkDetailsCallback {
|
||||
override fun onDeleteConfirmed() = Unit
|
||||
override fun onDeleteCanceled() = Unit
|
||||
@@ -243,10 +252,14 @@ private fun CallLinkDetailsPreview() {
|
||||
@Composable
|
||||
private fun CallLinkDetails(
|
||||
state: CallLinkDetailsState,
|
||||
showAlreadyInACall: Boolean,
|
||||
callback: CallLinkDetailsCallback
|
||||
) {
|
||||
Scaffolds.Settings(
|
||||
title = stringResource(id = R.string.CallLinkDetailsFragment__call_details),
|
||||
snackbarHost = {
|
||||
YouAreAlreadyInACallSnackbar(showAlreadyInACall)
|
||||
},
|
||||
onNavigationClick = callback::onNavigationClicked,
|
||||
navigationIconPainter = painterResource(id = R.drawable.ic_arrow_left_24)
|
||||
) { paddingValues ->
|
||||
|
||||
@@ -17,6 +17,9 @@ import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import org.signal.ringrtc.CallLinkState
|
||||
import org.thoughtcrime.securesms.calls.links.CallLinks
|
||||
import org.thoughtcrime.securesms.calls.links.UpdateCallLinkRepository
|
||||
@@ -44,6 +47,9 @@ class CallLinkDetailsViewModel(
|
||||
val recipientSnapshot: Recipient?
|
||||
get() = recipientSubject.value
|
||||
|
||||
private val internalShowAlreadyInACall = MutableStateFlow(false)
|
||||
val showAlreadyInACall: StateFlow<Boolean> = internalShowAlreadyInACall
|
||||
|
||||
init {
|
||||
disposables += repository.refreshCallLinkState(callLinkRoomId)
|
||||
disposables += CallLinks.watchCallLink(callLinkRoomId)
|
||||
@@ -80,6 +86,10 @@ class CallLinkDetailsViewModel(
|
||||
disposables.dispose()
|
||||
}
|
||||
|
||||
fun showAlreadyInACall(showAlreadyInACall: Boolean) {
|
||||
internalShowAlreadyInACall.update { showAlreadyInACall }
|
||||
}
|
||||
|
||||
fun setDisplayRevocationDialog(displayRevocationDialog: Boolean) {
|
||||
_state.value = _state.value.copy(displayRevocationDialog = displayRevocationDialog)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import org.signal.core.util.concurrent.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar
|
||||
import org.thoughtcrime.securesms.calls.links.details.CallLinkDetailsActivity
|
||||
import org.thoughtcrime.securesms.components.menu.ActionItem
|
||||
import org.thoughtcrime.securesms.components.menu.SignalContextMenu
|
||||
@@ -72,7 +73,9 @@ class CallLogContextMenu(
|
||||
iconRes = R.drawable.symbol_video_24,
|
||||
title = fragment.getString(R.string.CallContextMenu__video_call)
|
||||
) {
|
||||
CommunicationActions.startVideoCall(fragment, peer)
|
||||
CommunicationActions.startVideoCall(fragment, peer) {
|
||||
YouAreAlreadyInACallSnackbar.show(fragment.requireView())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +88,9 @@ class CallLogContextMenu(
|
||||
iconRes = R.drawable.symbol_phone_24,
|
||||
title = fragment.getString(R.string.CallContextMenu__audio_call)
|
||||
) {
|
||||
CommunicationActions.startVoiceCall(fragment, call.peer)
|
||||
CommunicationActions.startVoiceCall(fragment, call.peer) {
|
||||
YouAreAlreadyInACallSnackbar.show(fragment.requireView())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.signal.core.util.concurrent.addTo
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.MainActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar
|
||||
import org.thoughtcrime.securesms.calls.links.details.CallLinkDetailsActivity
|
||||
import org.thoughtcrime.securesms.calls.new.NewCallActivity
|
||||
import org.thoughtcrime.securesms.components.Material3SearchToolbar
|
||||
@@ -391,12 +392,16 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
|
||||
}
|
||||
|
||||
override fun onStartAudioCallClicked(recipient: Recipient) {
|
||||
CommunicationActions.startVoiceCall(this, recipient)
|
||||
CommunicationActions.startVoiceCall(this, recipient) {
|
||||
YouAreAlreadyInACallSnackbar.show(requireView())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStartVideoCallClicked(recipient: Recipient, canUserBeginCall: Boolean) {
|
||||
if (canUserBeginCall) {
|
||||
CommunicationActions.startVideoCall(this, recipient)
|
||||
CommunicationActions.startVideoCall(this, recipient) {
|
||||
YouAreAlreadyInACallSnackbar.show(requireView())
|
||||
}
|
||||
} else {
|
||||
ConversationDialogs.displayCannotStartGroupCallDueToPermissionsDialog(requireContext())
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.ContactSelectionActivity
|
||||
import org.thoughtcrime.securesms.ContactSelectionListFragment
|
||||
import org.thoughtcrime.securesms.InviteActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
@@ -81,9 +82,13 @@ class NewCallActivity : ContactSelectionActivity(), ContactSelectionListFragment
|
||||
|
||||
private fun launch(recipient: Recipient) {
|
||||
if (recipient.isGroup) {
|
||||
CommunicationActions.startVideoCall(this, recipient)
|
||||
CommunicationActions.startVideoCall(this, recipient) {
|
||||
YouAreAlreadyInACallSnackbar.show(findViewById(android.R.id.content))
|
||||
}
|
||||
} else {
|
||||
CommunicationActions.startVoiceCall(this, recipient)
|
||||
CommunicationActions.startVoiceCall(this, recipient) {
|
||||
YouAreAlreadyInACallSnackbar.show(findViewById(android.R.id.content))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user