Filter call link events we don't have root keys for and disambiguate return / join.

This commit is contained in:
Alex Hart 2024-09-17 09:23:27 -03:00 committed by Greyson Parrelli
parent 88d1c0cf87
commit 8933d89b56
6 changed files with 47 additions and 14 deletions

View file

@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.databinding.CallLogAdapterItemBinding
import org.thoughtcrime.securesms.databinding.CallLogCreateCallLinkItemBinding
import org.thoughtcrime.securesms.databinding.ConversationListItemClearFilterBinding
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.SearchUtil
import org.thoughtcrime.securesms.util.adapter.mapping.BindingFactory
@ -84,14 +85,15 @@ class CallLogAdapter(
fun submitCallRows(
rows: List<CallLogRow?>,
selectionState: CallLogSelectionState,
localCallRecipientId: RecipientId,
onCommit: () -> Unit
): Int {
val filteredRows = rows
.filterNotNull()
.map {
when (it) {
is CallLogRow.Call -> CallModel(it, selectionState, itemCount)
is CallLogRow.CallLink -> CallLinkModel(it, selectionState, itemCount)
is CallLogRow.Call -> CallModel(it, selectionState, itemCount, it.peer.id == localCallRecipientId)
is CallLogRow.CallLink -> CallLinkModel(it, selectionState, itemCount, it.recipient.id == localCallRecipientId)
is CallLogRow.ClearFilter -> ClearFilterModel()
is CallLogRow.CreateCallLink -> CreateCallLinkModel()
}
@ -105,14 +107,16 @@ class CallLogAdapter(
private class CallModel(
val call: CallLogRow.Call,
val selectionState: CallLogSelectionState,
val itemCount: Int
val itemCount: Int,
val isLocalDeviceInCall: Boolean
) : MappingModel<CallModel> {
override fun areItemsTheSame(newItem: CallModel): Boolean = call.id == newItem.call.id
override fun areContentsTheSame(newItem: CallModel): Boolean {
return call == newItem.call &&
isSelectionStateTheSame(newItem) &&
isItemCountTheSame(newItem)
isItemCountTheSame(newItem) &&
isLocalDeviceInCall == newItem.isLocalDeviceInCall
}
override fun getChangePayload(newItem: CallModel): Any? {
@ -136,7 +140,8 @@ class CallLogAdapter(
private class CallLinkModel(
val callLink: CallLogRow.CallLink,
val selectionState: CallLogSelectionState,
val itemCount: Int
val itemCount: Int,
val isLocalDeviceInCall: Boolean
) : MappingModel<CallLinkModel> {
override fun areItemsTheSame(newItem: CallLinkModel): Boolean {
@ -146,7 +151,8 @@ class CallLogAdapter(
override fun areContentsTheSame(newItem: CallLinkModel): Boolean {
return callLink == newItem.callLink &&
isSelectionStateTheSame(newItem) &&
isItemCountTheSame(newItem)
isItemCountTheSame(newItem) &&
isLocalDeviceInCall == newItem.isLocalDeviceInCall
}
override fun getChangePayload(newItem: CallLinkModel): Any? {
@ -230,7 +236,7 @@ class CallLogAdapter(
if (model.callLink.callLinkPeekInfo?.isActive == true) {
binding.groupCallButton.setText(
if (model.callLink.callLinkPeekInfo.isJoined) {
if (model.callLink.callLinkPeekInfo.isJoined && model.isLocalDeviceInCall) {
R.string.CallLogAdapter__return
} else {
R.string.CallLogAdapter__join
@ -364,7 +370,7 @@ class CallLogAdapter(
binding.groupCallButton.visible = true
binding.groupCallButton.setText(
if (model.call.callLinkPeekInfo.isJoined) {
if (model.call.callLinkPeekInfo.isJoined && model.isLocalDeviceInCall) {
R.string.CallLogAdapter__return
} else {
R.string.CallLogAdapter__join
@ -393,7 +399,7 @@ class CallLogAdapter(
binding.groupCallButton.visible = true
binding.groupCallButton.setText(
if (model.call.groupCallState == CallLogRow.GroupCallState.LOCAL_USER_JOINED) {
if (model.call.groupCallState == CallLogRow.GroupCallState.LOCAL_USER_JOINED && model.isLocalDeviceInCall) {
R.string.CallLogAdapter__return
} else {
R.string.CallLogAdapter__join

View file

@ -152,6 +152,7 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal
val filteredCount = callLogAdapter.submitCallRows(
data,
selected,
viewModel.callLogPeekHelper.localDeviceCallRecipientId,
scrollToPositionDelegate::notifyListCommitted
)
binding.emptyState.visible = filteredCount == 0

View file

@ -5,12 +5,15 @@
package org.thoughtcrime.securesms.calls.log
import android.os.Bundle
import android.os.ResultReceiver
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.service.webrtc.ActiveCallData
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
import org.thoughtcrime.securesms.util.ThrottledDebouncer
import org.thoughtcrime.securesms.util.concurrent.SerialExecutor
@ -37,6 +40,10 @@ class CallLogPeekHelper : DefaultLifecycleObserver {
private var isFirstLoad = true
private var isPaused = false
@Volatile
var localDeviceCallRecipientId: RecipientId = RecipientId.UNKNOWN
private set
override fun onResume(owner: LifecycleOwner) {
executor.execute {
isPaused = false
@ -147,6 +154,19 @@ class CallLogPeekHelper : DefaultLifecycleObserver {
return@execute
}
Log.d(TAG, "Checking if user is in a call locally.")
AppDependencies.signalCallManager.isCallActive(object : ResultReceiver(null) {
override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
if (resultCode == 1 && resultData != null) {
val activeCallData = ActiveCallData.fromBundle(resultData)
localDeviceCallRecipientId = activeCallData.recipientId
} else {
localDeviceCallRecipientId = RecipientId.UNKNOWN
}
}
})
Log.d(TAG, "Peeks in queue. Taking first $PEEK_SIZE.")
val items = peekQueue.take(PEEK_SIZE)

View file

@ -19,6 +19,7 @@ class CallLogRepository(
private val updateCallLinkRepository: UpdateCallLinkRepository = UpdateCallLinkRepository(),
private val callLogPeekHelper: CallLogPeekHelper
) : CallLogPagedDataSource.CallRepository {
override fun getCallsCount(query: String?, filter: CallLogFilter): Int {
return SignalDatabase.calls.getCallsCount(query, filter)
}

View file

@ -48,19 +48,19 @@ sealed class CallLogRow {
/**
* A row which can be used to clear the current filter.
*/
object ClearFilter : CallLogRow() {
data object ClearFilter : CallLogRow() {
override val id: Id = Id.ClearFilter
}
object CreateCallLink : CallLogRow() {
data object CreateCallLink : CallLogRow() {
override val id: Id = Id.CreateCallLink
}
sealed class Id {
data class Call(val children: Set<Long>) : Id()
data class CallLink(val roomId: CallLinkRoomId) : Id()
object ClearFilter : Id()
object CreateCallLink : Id()
data object ClearFilter : Id()
data object CreateCallLink : Id()
}
enum class GroupCallState {

View file

@ -1365,7 +1365,12 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
INNER JOIN ${RecipientTable.TABLE_NAME} ON ${RecipientTable.TABLE_NAME}.${RecipientTable.ID} = $PEER
LEFT JOIN ${MessageTable.TABLE_NAME} ON ${MessageTable.TABLE_NAME}.${MessageTable.ID} = $MESSAGE_ID
LEFT JOIN ${GroupTable.TABLE_NAME} ON ${GroupTable.TABLE_NAME}.${GroupTable.RECIPIENT_ID} = ${RecipientTable.TABLE_NAME}.${RecipientTable.ID}
WHERE true_parent = p.$ID ${if (queryClause.where.isNotEmpty()) "AND ${queryClause.where}" else ""}
WHERE true_parent = p.$ID
AND CASE
WHEN p.$TYPE = ${Type.serialize(Type.AD_HOC_CALL)} THEN EXISTS (SELECT * FROM ${CallLinkTable.TABLE_NAME} WHERE ${CallLinkTable.RECIPIENT_ID} = $PEER AND ${CallLinkTable.ROOT_KEY} NOT NULL)
ELSE 1
END
${if (queryClause.where.isNotEmpty()) "AND ${queryClause.where}" else ""}
GROUP BY CASE WHEN p.type = 4 THEN p.peer ELSE p._id END
ORDER BY p.$TIMESTAMP DESC
$offsetLimit