mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 09:49:30 +01:00
Add proper call tab return state.
This commit is contained in:
committed by
Cody Henthorne
parent
514f7cc767
commit
1f09f48e6b
@@ -8,6 +8,7 @@ package org.thoughtcrime.securesms.calls.links
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Arrangement.spacedBy
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@@ -33,20 +34,21 @@ import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.signal.core.ui.Buttons
|
||||
import org.signal.core.ui.theme.SignalTheme
|
||||
import org.signal.core.ui.Previews
|
||||
import org.signal.core.ui.SignalPreview
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.conversation.colors.AvatarColorPair
|
||||
import org.thoughtcrime.securesms.database.CallLinkTable
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.service.webrtc.CallLinkPeekInfo
|
||||
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 java.time.Instant
|
||||
|
||||
@Preview
|
||||
@SignalPreview
|
||||
@Composable
|
||||
private fun SignalCallRowPreview() {
|
||||
val callLink = remember {
|
||||
@@ -63,17 +65,29 @@ private fun SignalCallRowPreview() {
|
||||
)
|
||||
)
|
||||
}
|
||||
SignalTheme(false) {
|
||||
SignalCallRow(
|
||||
callLink = callLink,
|
||||
onJoinClicked = {}
|
||||
)
|
||||
Previews.Preview {
|
||||
Column(
|
||||
verticalArrangement = spacedBy(8.dp)
|
||||
) {
|
||||
SignalCallRow(
|
||||
callLink = callLink,
|
||||
callLinkPeekInfo = null,
|
||||
onJoinClicked = {}
|
||||
)
|
||||
|
||||
SignalCallRow(
|
||||
callLink = callLink,
|
||||
callLinkPeekInfo = CallLinkPeekInfo(null, true, true),
|
||||
onJoinClicked = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SignalCallRow(
|
||||
callLink: CallLinkTable.CallLink,
|
||||
callLinkPeekInfo: CallLinkPeekInfo?,
|
||||
onJoinClicked: (() -> Unit)?,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
@@ -140,7 +154,13 @@ fun SignalCallRow(
|
||||
),
|
||||
modifier = Modifier.align(CenterVertically)
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__join))
|
||||
val textId = if (callLinkPeekInfo?.isJoined == true) {
|
||||
R.string.CallLogAdapter__return
|
||||
} else {
|
||||
R.string.CreateCallLinkBottomSheetDialogFragment__join
|
||||
}
|
||||
|
||||
Text(text = stringResource(id = textId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,7 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment
|
||||
|
||||
SignalCallRow(
|
||||
callLink = callLink,
|
||||
callLinkPeekInfo = null,
|
||||
onJoinClicked = this@CreateCallLinkBottomSheetDialogFragment::onJoinClicked
|
||||
)
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ 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.ComposeFragment
|
||||
import org.thoughtcrime.securesms.conversation.colors.AvatarColor
|
||||
import org.thoughtcrime.securesms.database.CallLinkTable
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkCredentials
|
||||
@@ -200,12 +199,11 @@ private interface CallLinkDetailsCallback {
|
||||
@Preview
|
||||
@Composable
|
||||
private fun CallLinkDetailsPreview() {
|
||||
val avatarColor = remember {
|
||||
AvatarColor.random()
|
||||
}
|
||||
|
||||
val callLink = remember {
|
||||
val credentials = CallLinkCredentials.generate()
|
||||
val credentials = CallLinkCredentials(
|
||||
byteArrayOf(1, 2, 3, 4),
|
||||
byteArrayOf(3, 4, 5, 6)
|
||||
)
|
||||
CallLinkTable.CallLink(
|
||||
recipientId = RecipientId.UNKNOWN,
|
||||
roomId = credentials.roomId,
|
||||
@@ -258,6 +256,7 @@ private fun CallLinkDetails(
|
||||
Column(modifier = Modifier.padding(paddingValues)) {
|
||||
SignalCallRow(
|
||||
callLink = state.callLink,
|
||||
callLinkPeekInfo = state.peekInfo,
|
||||
onJoinClicked = callback::onJoinClicked,
|
||||
modifier = Modifier.padding(top = 16.dp, bottom = 12.dp)
|
||||
)
|
||||
|
||||
@@ -7,9 +7,11 @@ package org.thoughtcrime.securesms.calls.links.details
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import org.thoughtcrime.securesms.database.CallLinkTable
|
||||
import org.thoughtcrime.securesms.service.webrtc.CallLinkPeekInfo
|
||||
|
||||
@Immutable
|
||||
data class CallLinkDetailsState(
|
||||
val displayRevocationDialog: Boolean = false,
|
||||
val callLink: CallLinkTable.CallLink? = null
|
||||
val callLink: CallLinkTable.CallLink? = null,
|
||||
val peekInfo: CallLinkPeekInfo? = null
|
||||
)
|
||||
|
||||
@@ -10,14 +10,17 @@ 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
|
||||
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 io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject
|
||||
import org.signal.ringrtc.CallLinkState
|
||||
import org.thoughtcrime.securesms.calls.links.CallLinks
|
||||
import org.thoughtcrime.securesms.calls.links.UpdateCallLinkRepository
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.UpdateCallLinkResult
|
||||
@@ -43,13 +46,33 @@ class CallLinkDetailsViewModel(
|
||||
|
||||
init {
|
||||
disposables += repository.refreshCallLinkState(callLinkRoomId)
|
||||
disposables += CallLinks.watchCallLink(callLinkRoomId).subscribeBy {
|
||||
_state.value = _state.value.copy(callLink = it)
|
||||
}
|
||||
disposables += CallLinks.watchCallLink(callLinkRoomId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeBy {
|
||||
_state.value = _state.value.copy(callLink = it)
|
||||
}
|
||||
|
||||
disposables += repository
|
||||
.watchCallLinkRecipient(callLinkRoomId)
|
||||
.subscribeBy(onNext = recipientSubject::onNext)
|
||||
|
||||
disposables += recipientSubject
|
||||
.map { it.id }
|
||||
.distinctUntilChanged()
|
||||
.flatMap { recipientId ->
|
||||
AppDependencies.signalCallManager.peekInfoCache
|
||||
.distinctUntilChanged()
|
||||
.filter { it.containsKey(recipientId) }
|
||||
.map { it[recipientId]!! }
|
||||
.distinctUntilChanged()
|
||||
.toObservable()
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeBy { callLinkPeekInfo ->
|
||||
_state.value = _state.value.copy(peekInfo = callLinkPeekInfo)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
||||
@@ -228,13 +228,28 @@ class CallLogAdapter(
|
||||
)
|
||||
)
|
||||
|
||||
binding.callType.setImageResource(R.drawable.symbol_video_24)
|
||||
binding.callType.contentDescription = context.getString(R.string.CallLogAdapter__start_a_video_call)
|
||||
binding.callType.setOnClickListener {
|
||||
onStartVideoCallClicked(model.callLink.recipient, true)
|
||||
if (model.callLink.callLinkPeekInfo?.isActive == true) {
|
||||
binding.groupCallButton.setText(
|
||||
if (model.callLink.callLinkPeekInfo.isJoined) {
|
||||
R.string.CallLogAdapter__return
|
||||
} else {
|
||||
R.string.CallLogAdapter__join
|
||||
}
|
||||
)
|
||||
binding.groupCallButton.setOnClickListener {
|
||||
onStartVideoCallClicked(model.callLink.recipient, true)
|
||||
}
|
||||
binding.callType.visible = false
|
||||
binding.groupCallButton.visible = true
|
||||
} else {
|
||||
binding.callType.setImageResource(R.drawable.symbol_video_24)
|
||||
binding.callType.contentDescription = context.getString(R.string.CallLogAdapter__start_a_video_call)
|
||||
binding.callType.setOnClickListener {
|
||||
onStartVideoCallClicked(model.callLink.recipient, true)
|
||||
}
|
||||
binding.callType.visible = true
|
||||
binding.groupCallButton.visible = false
|
||||
}
|
||||
binding.callType.visible = true
|
||||
binding.groupCallButton.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,7 +353,30 @@ class CallLogAdapter(
|
||||
binding.groupCallButton.visible = false
|
||||
}
|
||||
|
||||
CallTable.Type.GROUP_CALL, CallTable.Type.AD_HOC_CALL -> {
|
||||
CallTable.Type.AD_HOC_CALL -> {
|
||||
binding.callType.setImageResource(R.drawable.symbol_video_24)
|
||||
binding.callType.contentDescription = context.getString(R.string.CallLogAdapter__start_a_video_call)
|
||||
binding.callType.setOnClickListener { onStartVideoCallClicked(model.call.peer, model.call.canUserBeginCall) }
|
||||
binding.groupCallButton.setOnClickListener { onStartVideoCallClicked(model.call.peer, model.call.canUserBeginCall) }
|
||||
|
||||
if (model.call.callLinkPeekInfo?.isActive == true) {
|
||||
binding.callType.visible = false
|
||||
binding.groupCallButton.visible = true
|
||||
|
||||
binding.groupCallButton.setText(
|
||||
if (model.call.callLinkPeekInfo.isJoined) {
|
||||
R.string.CallLogAdapter__return
|
||||
} else {
|
||||
R.string.CallLogAdapter__join
|
||||
}
|
||||
)
|
||||
} else {
|
||||
binding.callType.visible = true
|
||||
binding.groupCallButton.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
CallTable.Type.GROUP_CALL -> {
|
||||
binding.callType.setImageResource(R.drawable.symbol_video_24)
|
||||
binding.callType.contentDescription = context.getString(R.string.CallLogAdapter__start_a_video_call)
|
||||
binding.callType.setOnClickListener { onStartVideoCallClicked(model.call.peer, model.call.canUserBeginCall) }
|
||||
@@ -401,6 +439,7 @@ class CallLogAdapter(
|
||||
call.direction == CallTable.Direction.OUTGOING -> R.string.CallLogAdapter__outgoing
|
||||
else -> throw AssertionError()
|
||||
}
|
||||
|
||||
else -> if (call.isDisplayedAsMissedCallInUi) R.string.CallLogAdapter__missed else R.string.CallLogAdapter__incoming
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.thoughtcrime.securesms.database.CallLinkTable
|
||||
import org.thoughtcrime.securesms.database.DatabaseObserver
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.jobs.CallLinkPeekJob
|
||||
import org.thoughtcrime.securesms.jobs.CallLogEventSendJob
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.UpdateCallLinkResult
|
||||
@@ -158,29 +157,4 @@ class CallLogRepository(
|
||||
SignalDatabase.calls.updateAdHocCallEventDeletionTimestamps()
|
||||
}
|
||||
}
|
||||
|
||||
fun peekCallLinks(): Completable {
|
||||
return Completable.fromAction {
|
||||
val callLinks: List<CallLogRow.CallLink> = SignalDatabase.callLinks.getCallLinks(
|
||||
query = null,
|
||||
offset = 0,
|
||||
limit = 10
|
||||
)
|
||||
|
||||
val callEvents: List<CallLogRow.Call> = SignalDatabase.calls.getCalls(
|
||||
offset = 0,
|
||||
limit = 10,
|
||||
searchTerm = null,
|
||||
filter = CallLogFilter.AD_HOC
|
||||
)
|
||||
|
||||
val recipients = (callLinks.map { it.recipient } + callEvents.map { it.peer }).toSet()
|
||||
|
||||
val jobs = recipients.take(10).map {
|
||||
CallLinkPeekJob(it.id)
|
||||
}
|
||||
|
||||
AppDependencies.jobManager.addAll(jobs)
|
||||
}.subscribeOn(Schedulers.io())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import androidx.lifecycle.ViewModel
|
||||
import io.reactivex.rxjava3.core.BackpressureStrategy
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Maybe
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import io.reactivex.rxjava3.processors.BehaviorProcessor
|
||||
@@ -16,9 +15,7 @@ import org.signal.paging.PagedData
|
||||
import org.signal.paging.PagingConfig
|
||||
import org.signal.paging.ProxyPagingController
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
import org.thoughtcrime.securesms.util.rx.RxStore
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* ViewModel for call log management.
|
||||
@@ -82,22 +79,15 @@ class CallLogViewModel(
|
||||
controller.onDataInvalidated()
|
||||
}
|
||||
|
||||
if (RemoteConfig.adHocCalling) {
|
||||
disposables += Observable
|
||||
.interval(30, TimeUnit.SECONDS, Schedulers.computation())
|
||||
.flatMapCompletable { callLogRepository.peekCallLinks() }
|
||||
.subscribe()
|
||||
|
||||
disposables += AppDependencies
|
||||
.signalCallManager
|
||||
.peekInfoCache
|
||||
.observeOn(Schedulers.computation())
|
||||
.distinctUntilChanged()
|
||||
.subscribe {
|
||||
callLogPeekHelper.onDataSetInvalidated()
|
||||
controller.onDataInvalidated()
|
||||
}
|
||||
}
|
||||
disposables += AppDependencies
|
||||
.signalCallManager
|
||||
.peekInfoCache
|
||||
.observeOn(Schedulers.computation())
|
||||
.distinctUntilChanged()
|
||||
.subscribe {
|
||||
callLogPeekHelper.onDataSetInvalidated()
|
||||
controller.onDataInvalidated()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
||||
Reference in New Issue
Block a user