From 22dddeb3b7dd942601c3e751d3e769b4747a05a6 Mon Sep 17 00:00:00 2001 From: Jeffrey Starke Date: Wed, 24 Jun 2026 13:11:14 -0400 Subject: [PATCH] Hide delete button on call link details for non-admin users. --- .../links/details/CallLinkDetailsScreen.kt | 18 +++++++------ .../webrtc/controls/CallInfoView.kt | 2 +- .../securesms/database/CallLinkTable.kt | 27 ++++++++++--------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsScreen.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsScreen.kt index f5871e9738..2da4fb0064 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsScreen.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsScreen.kt @@ -221,7 +221,7 @@ fun CallLinkDetailsScreen( ) } - if (state.callLink.credentials?.adminPassBytes != null) { + if (state.callLink.canModify) { item { Rows.TextRow( text = stringResource( @@ -273,13 +273,15 @@ fun CallLinkDetailsScreen( ) } - item { - Rows.TextRow( - text = stringResource(id = R.string.CallLinkDetailsFragment__delete_call_link), - icon = SignalIcons.Trash.imageVector, - foregroundTint = MaterialTheme.colorScheme.error, - onClick = callback::onDeleteClicked - ) + if (state.callLink.canModify) { + item { + Rows.TextRow( + text = stringResource(id = R.string.CallLinkDetailsFragment__delete_call_link), + icon = SignalIcons.Trash.imageVector, + foregroundTint = MaterialTheme.colorScheme.error, + onClick = callback::onDeleteClicked + ) + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/CallInfoView.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/CallInfoView.kt index a034896f77..b70e4346cb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/CallInfoView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/CallInfoView.kt @@ -319,7 +319,7 @@ private fun CallInfo( } } - if (controlAndInfoState.callLink?.credentials?.adminPassBytes != null) { + if (controlAndInfoState.callLink?.canModify == true) { item { if (!participantsState.inCallLobby) { Dividers.Default() diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/CallLinkTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/CallLinkTable.kt index abbb1561c6..13ec864aae 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/CallLinkTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/CallLinkTable.kt @@ -203,7 +203,7 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database ) insertCallLink(link) - return getCallLinkByRoomId(roomId)!! + getCallLinkByRoomId(roomId)!! } else { callLink } @@ -287,7 +287,7 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database deletionTimestamp = 0L ) insertCallLink(link) - return getCallLinkByRoomId(callLinkRoomId)!! + getCallLinkByRoomId(callLinkRoomId)!! } else { callLink } @@ -468,7 +468,7 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database } } - override fun deserialize(data: ContentValues): CallLink { + override fun deserialize(input: ContentValues): CallLink { throw UnsupportedOperationException() } } @@ -478,21 +478,21 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database throw UnsupportedOperationException() } - override fun deserialize(data: Cursor): CallLink { + override fun deserialize(input: Cursor): CallLink { return CallLink( - recipientId = data.requireLong(RECIPIENT_ID).let { if (it > 0) RecipientId.from(it) else RecipientId.UNKNOWN }, - roomId = CallLinkRoomId.DatabaseSerializer.deserialize(data.requireNonNullString(ROOM_ID)), - credentials = data.requireBlob(ROOT_KEY)?.let { linkKey -> + recipientId = input.requireLong(RECIPIENT_ID).let { if (it > 0) RecipientId.from(it) else RecipientId.UNKNOWN }, + roomId = CallLinkRoomId.DatabaseSerializer.deserialize(input.requireNonNullString(ROOM_ID)), + credentials = input.requireBlob(ROOT_KEY)?.let { linkKey -> CallLinkCredentials( linkKeyBytes = linkKey, - adminPassBytes = data.requireBlob(ADMIN_KEY) + adminPassBytes = input.requireBlob(ADMIN_KEY) ) }, state = SignalCallLinkState( - name = data.requireNonNullString(NAME), - restrictions = data.requireInt(RESTRICTIONS).mapToRestrictions(), - revoked = data.requireBoolean(REVOKED), - expiration = data.requireLong(EXPIRATION).let { + name = input.requireNonNullString(NAME), + restrictions = input.requireInt(RESTRICTIONS).mapToRestrictions(), + revoked = input.requireBoolean(REVOKED), + expiration = input.requireLong(EXPIRATION).let { if (it == -1L) { Instant.MAX } else { @@ -500,7 +500,7 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database } } ), - deletionTimestamp = data.requireLong(DELETION_TIMESTAMP) + deletionTimestamp = input.requireLong(DELETION_TIMESTAMP) ) } @@ -521,6 +521,7 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database val deletionTimestamp: Long ) { val avatarColor: AvatarColor = credentials?.let { AvatarColorHash.forCallLink(it.linkKeyBytes) } ?: AvatarColor.UNKNOWN + val canModify: Boolean = credentials?.adminPassBytes != null } override fun remapRecipient(fromId: RecipientId, toId: RecipientId) {