diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogAdapter.kt index b8440134dd..da4557f780 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogAdapter.kt @@ -182,7 +182,7 @@ class CallLogAdapter( binding: CallLogAdapterItemBinding, private val onCallLinkClicked: (CallLogRow.CallLink) -> Unit, private val onCallLinkLongClicked: (View, CallLogRow.CallLink) -> Boolean, - private val onStartVideoCallClicked: (Recipient) -> Unit + private val onStartVideoCallClicked: (Recipient, Boolean) -> Unit ) : BindingViewHolder(binding) { override fun bind(model: CallLinkModel) { if (payload.size == 1 && payload.contains(PAYLOAD_TIMESTAMP)) { @@ -231,7 +231,7 @@ 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) + onStartVideoCallClicked(model.callLink.recipient, true) } binding.callType.visible = true binding.groupCallButton.visible = false @@ -243,7 +243,7 @@ class CallLogAdapter( private val onCallClicked: (CallLogRow.Call) -> Unit, private val onCallLongClicked: (View, CallLogRow.Call) -> Boolean, private val onStartAudioCallClicked: (Recipient) -> Unit, - private val onStartVideoCallClicked: (Recipient) -> Unit + private val onStartVideoCallClicked: (Recipient, Boolean) -> Unit ) : BindingViewHolder(binding) { override fun bind(model: CallModel) { itemView.setOnClickListener { @@ -333,7 +333,7 @@ class CallLogAdapter( CallTable.Type.VIDEO_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) } + binding.callType.setOnClickListener { onStartVideoCallClicked(model.call.peer, true) } binding.callType.visible = true binding.groupCallButton.visible = false } @@ -341,8 +341,8 @@ class CallLogAdapter( CallTable.Type.GROUP_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) } - binding.groupCallButton.setOnClickListener { onStartVideoCallClicked(model.call.peer) } + binding.callType.setOnClickListener { onStartVideoCallClicked(model.call.peer, model.call.canUserBeginCall) } + binding.groupCallButton.setOnClickListener { onStartVideoCallClicked(model.call.peer, model.call.canUserBeginCall) } when (model.call.groupCallState) { CallLogRow.GroupCallState.NONE, CallLogRow.GroupCallState.FULL -> { @@ -472,6 +472,6 @@ class CallLogAdapter( /** * Invoked when user presses the video icon */ - fun onStartVideoCallClicked(recipient: Recipient) + fun onStartVideoCallClicked(recipient: Recipient, canUserBeginCall: Boolean) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogFragment.kt index 54b4bc5084..937d31b966 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogFragment.kt @@ -45,6 +45,7 @@ import org.thoughtcrime.securesms.components.settings.app.notifications.manual.N import org.thoughtcrime.securesms.components.settings.conversation.ConversationSettingsActivity import org.thoughtcrime.securesms.conversation.ConversationUpdateTick import org.thoughtcrime.securesms.conversation.SignalBottomActionBarController +import org.thoughtcrime.securesms.conversation.v2.ConversationDialogs import org.thoughtcrime.securesms.conversationlist.ConversationFilterBehavior import org.thoughtcrime.securesms.conversationlist.chatfilter.ConversationFilterSource import org.thoughtcrime.securesms.conversationlist.chatfilter.ConversationListFilterPullView.OnCloseClicked @@ -376,8 +377,12 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal CommunicationActions.startVoiceCall(this, recipient) } - override fun onStartVideoCallClicked(recipient: Recipient) { - CommunicationActions.startVideoCall(this, recipient) + override fun onStartVideoCallClicked(recipient: Recipient, canUserBeginCall: Boolean) { + if (canUserBeginCall) { + CommunicationActions.startVideoCall(this, recipient) + } else { + ConversationDialogs.displayCannotStartGroupCallDueToPermissionsDialog(requireContext()) + } } override fun startSelection(call: CallLogRow) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRow.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRow.kt index 89f2cf4a5a..f97808e49b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRow.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRow.kt @@ -41,6 +41,7 @@ sealed class CallLogRow { val children: Set, val searchQuery: String?, val callLinkPeekInfo: CallLinkPeekInfo?, + val canUserBeginCall: Boolean, override val id: Id = Id.Call(children) ) : CallLogRow() diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt index 22ed8a52ba..03d04e6cc6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt @@ -12,6 +12,7 @@ import org.signal.core.util.delete import org.signal.core.util.deleteAll import org.signal.core.util.flatten import org.signal.core.util.insertInto +import org.signal.core.util.isAbsent import org.signal.core.util.logging.Log import org.signal.core.util.readToList import org.signal.core.util.readToMap @@ -406,6 +407,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl Log.w(TAG, "[acceptOutgoingGroupCall] This shouldn't have been an outgoing ring because the call already existed!") Event.ACCEPTED } + else -> { Log.d(TAG, "[acceptOutgoingGroupCall] Call in state ${call.event} cannot be transitioned by ACCEPTED") return @@ -1255,6 +1257,16 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl val actualChildren = inPeriod.takeWhile { children.contains(it) } val peer = Recipient.resolved(call.peer) + val canUserBeginCall = if (peer.isGroup) { + val record = SignalDatabase.groups.getGroup(peer.id) + + !record.isAbsent() && + record.get().isActive && + (!record.get().isAnnouncementGroup || record.get().memberLevel(Recipient.self()) == GroupTable.MemberLevel.ADMINISTRATOR) + } else { + true + } + CallLogRow.Call( record = call, date = call.timestamp, @@ -1262,7 +1274,8 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl groupCallState = CallLogRow.GroupCallState.fromDetails(groupCallDetails), children = actualChildren.toSet(), searchQuery = searchTerm, - callLinkPeekInfo = ApplicationDependencies.getSignalCallManager().peekInfoSnapshot[peer.id] + callLinkPeekInfo = ApplicationDependencies.getSignalCallManager().peekInfoSnapshot[peer.id], + canUserBeginCall = canUserBeginCall ) } }