From 5a978292b2fb3e52440bb8f8a22d331cca2d7186 Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Wed, 4 Feb 2026 15:23:22 +1100 Subject: [PATCH 1/6] Adding logs to networking layer --- .../org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt | 2 ++ .../securesms/api/onion/OnionSessionApiExecutor.kt | 3 +++ .../java/org/thoughtcrime/securesms/api/server/ServerApi.kt | 3 +++ .../org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt | 3 +++ 4 files changed, 11 insertions(+) diff --git a/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt b/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt index 3bb3370aa7..ccb038be8f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import okhttp3.RequestBody.Companion.toRequestBody import org.session.libsignal.utilities.ByteArraySlice.Companion.toRequestBody +import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.api.ApiExecutorContext class OkHttpApiExecutor( @@ -16,6 +17,7 @@ class OkHttpApiExecutor( override suspend fun send(ctx: ApiExecutorContext, req: HttpRequest): HttpResponse { return semaphore.withPermit { withContext(Dispatchers.IO) { + Log.d("OkHttpApiExecutor", "Sending request: $req, with context: $ctx") client.newCall(req.toOkHttpRequest()).execute().toHttpResponse() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/api/onion/OnionSessionApiExecutor.kt b/app/src/main/java/org/thoughtcrime/securesms/api/onion/OnionSessionApiExecutor.kt index 3b4f814626..b8c7ff54b4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/api/onion/OnionSessionApiExecutor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/api/onion/OnionSessionApiExecutor.kt @@ -22,6 +22,7 @@ import org.session.libsession.utilities.AESGCM import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.ByteArraySlice import org.session.libsignal.utilities.ByteArraySlice.Companion.view +import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.api.ApiExecutorContext import org.thoughtcrime.securesms.api.SessionApiExecutor import org.thoughtcrime.securesms.api.SessionApiRequest @@ -193,6 +194,8 @@ class OnionSessionApiExecutor @Inject constructor( ): OnionError { val guardSnode = path.first() + Log.d("OnionSessionApiExecutor", "Networking Error, got a non 200 response code: $httpResponseCode, body: $httpResponseBody") + // ---- 502: hop can't find/contact next hop ---- val nextNodeNotFound = "Next node not found: " val nextNodeUnreachable = "Next node is currently unreachable: " diff --git a/app/src/main/java/org/thoughtcrime/securesms/api/server/ServerApi.kt b/app/src/main/java/org/thoughtcrime/securesms/api/server/ServerApi.kt index 4df8c0e514..c3e18bd217 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/api/server/ServerApi.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/api/server/ServerApi.kt @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.api.server +import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.api.ApiExecutorContext import org.thoughtcrime.securesms.api.error.ErrorWithFailureDecision import org.thoughtcrime.securesms.api.http.HttpRequest @@ -44,6 +45,8 @@ abstract class ServerApi( ctx = failureContext, ) + Log.d("ServerApi", "Network error for a Server endpoint ($baseUrl), with status:${response.statusCode} - error: $error") + executorContext.set( key = ServerClientFailureContextKey, value = failureContext.copy(previousErrorCode = response.statusCode) diff --git a/app/src/main/java/org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt b/app/src/main/java/org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt index 89197b49c3..48c8a564fc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt @@ -4,6 +4,7 @@ import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import org.session.libsession.snode.SwarmAuth +import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Snode import org.thoughtcrime.securesms.api.ApiExecutorContext import org.thoughtcrime.securesms.api.error.ErrorWithFailureDecision @@ -47,6 +48,8 @@ abstract class AbstractSnodeApi( ctx = failureContext ) + Log.d("SnodeApi", "Network error for a Snode endpoint (${snode.ed25519Key}), with status:${code} - error: $error") + ctx.set(SnodeClientFailureKey, failureContext.copy(previousErrorCode = code)) if (decision != null) { From 4312a89981fd934373b5cedb9e8a48a464ff889f Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Wed, 4 Feb 2026 17:32:23 +1100 Subject: [PATCH 2/6] Adding "Unban" functionality --- .../messaging/open_groups/Endpoint.kt | 81 ------------------- .../messaging/open_groups/api/BanUserApi.kt | 14 ++++ .../messaging/open_groups/api/UnbanUserApi.kt | 47 +++++++++++ .../conversation/v2/ConversationActivityV2.kt | 9 +++ .../v2/ConversationReactionOverlay.kt | 5 +- .../conversation/v2/ConversationViewModel.kt | 13 +++ .../menus/ConversationActionModeCallback.kt | 6 +- .../repository/ConversationRepository.kt | 1 + .../DefaultConversationRepository.kt | 14 ++++ .../menu/menu_conversation_item_action.xml | 6 ++ app/src/main/res/values/attrs.xml | 1 + app/src/main/res/values/themes.xml | 1 + 12 files changed, 113 insertions(+), 85 deletions(-) delete mode 100644 app/src/main/java/org/session/libsession/messaging/open_groups/Endpoint.kt create mode 100644 app/src/main/java/org/session/libsession/messaging/open_groups/api/UnbanUserApi.kt diff --git a/app/src/main/java/org/session/libsession/messaging/open_groups/Endpoint.kt b/app/src/main/java/org/session/libsession/messaging/open_groups/Endpoint.kt deleted file mode 100644 index e50fe293e1..0000000000 --- a/app/src/main/java/org/session/libsession/messaging/open_groups/Endpoint.kt +++ /dev/null @@ -1,81 +0,0 @@ -package org.session.libsession.messaging.open_groups - -sealed class Endpoint(val value: String) { - - object Onion : Endpoint("oxen/v4/lsrpc") - object Batch : Endpoint("batch") - object Sequence : Endpoint("sequence") - object Capabilities : Endpoint("capabilities") - - // Rooms - - object Rooms : Endpoint("rooms") - data class Room(val roomToken: String) : Endpoint("room/$roomToken") - data class RoomPollInfo(val roomToken: String, val infoUpdated: Int) : - Endpoint("room/$roomToken/pollInfo/$infoUpdated") - - // Messages - - data class RoomMessage(val roomToken: String) : Endpoint("room/$roomToken/message") - - data class RoomMessageIndividual(val roomToken: String, val messageId: Long) : - Endpoint("room/$roomToken/message/$messageId") - - data class RoomMessagesRecent(val roomToken: String) : - Endpoint("room/$roomToken/messages/recent") - - data class RoomMessagesBefore(val roomToken: String, val messageId: Long) : - Endpoint("room/$roomToken/messages/before/$messageId") - - data class RoomMessagesSince(val roomToken: String, val seqNo: Long) : - Endpoint("room/$roomToken/messages/since/$seqNo") - - data class RoomDeleteMessages(val roomToken: String, val accountId: String) : - Endpoint("room/$roomToken/all/$accountId") - - data class Reactors(val roomToken: String, val messageId: Long, val emoji: String): - Endpoint("room/$roomToken/reactors/$messageId/$emoji") - - data class Reaction(val roomToken: String, val messageId: Long, val emoji: String): - Endpoint("room/$roomToken/reaction/$messageId/$emoji") - - data class ReactionDelete(val roomToken: String, val messageId: Long, val emoji: String): - Endpoint("room/$roomToken/reactions/$messageId/$emoji") - - // Pinning - - data class RoomPinMessage(val roomToken: String, val messageId: Long) : - Endpoint("room/$roomToken/pin/$messageId") - - data class RoomUnpinMessage(val roomToken: String, val messageId: Long) : - Endpoint("room/$roomToken/unpin/$messageId") - - data class RoomUnpinAll(val roomToken: String) : Endpoint("room/$roomToken/unpin/all") - - // Files - - object File: Endpoint("file") - data class FileIndividual(val fileId: Long): Endpoint("file/$fileId") - - data class RoomFile(val roomToken: String) : Endpoint("room/$roomToken/file") - data class RoomFileIndividual( - val roomToken: String, - val fileId: String - ) : Endpoint("room/$roomToken/file/$fileId") - - // Inbox/Outbox (Message Requests) - - object Inbox : Endpoint("inbox") - data class InboxSince(val id: Long) : Endpoint("inbox/since/$id") - data class InboxFor(val accountId: String) : Endpoint("inbox/$accountId") - - object Outbox : Endpoint("outbox") - data class OutboxSince(val id: Long) : Endpoint("outbox/since/$id") - - // Users - - data class UserBan(val accountId: String) : Endpoint("user/$accountId/ban") - data class UserUnban(val accountId: String) : Endpoint("user/$accountId/unban") - data class UserModerator(val accountId: String) : Endpoint("user/$accountId/moderator") - -} diff --git a/app/src/main/java/org/session/libsession/messaging/open_groups/api/BanUserApi.kt b/app/src/main/java/org/session/libsession/messaging/open_groups/api/BanUserApi.kt index 59e7aff6dc..ab5e7b9394 100644 --- a/app/src/main/java/org/session/libsession/messaging/open_groups/api/BanUserApi.kt +++ b/app/src/main/java/org/session/libsession/messaging/open_groups/api/BanUserApi.kt @@ -4,8 +4,11 @@ import android.net.Uri import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import kotlinx.serialization.Serializable import org.thoughtcrime.securesms.api.ApiExecutorContext +import org.thoughtcrime.securesms.api.http.HttpBody import org.thoughtcrime.securesms.api.http.HttpResponse +import okhttp3.MediaType class BanUserApi @AssistedInject constructor( @Assisted("user") private val userToBan: String, @@ -17,6 +20,17 @@ class BanUserApi @AssistedInject constructor( override val httpEndpoint: String = "/user/${Uri.encode(userToBan)}/ban" + @Serializable + private data class BanBody(val rooms: List) + + override fun buildRequestBody( + serverBaseUrl: String, + x25519PubKeyHex: String + ): Pair { + // JSON body {"rooms":[room]} + return buildJsonRequestBody(BanBody(rooms = listOf(room))) + } + override suspend fun handleSuccessResponse( executorContext: ApiExecutorContext, baseUrl: String, diff --git a/app/src/main/java/org/session/libsession/messaging/open_groups/api/UnbanUserApi.kt b/app/src/main/java/org/session/libsession/messaging/open_groups/api/UnbanUserApi.kt new file mode 100644 index 0000000000..598944c6c9 --- /dev/null +++ b/app/src/main/java/org/session/libsession/messaging/open_groups/api/UnbanUserApi.kt @@ -0,0 +1,47 @@ +package org.session.libsession.messaging.open_groups.api + +import android.net.Uri +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import kotlinx.serialization.Serializable +import org.thoughtcrime.securesms.api.ApiExecutorContext +import org.thoughtcrime.securesms.api.http.HttpBody +import org.thoughtcrime.securesms.api.http.HttpResponse +import okhttp3.MediaType + +class UnbanUserApi @AssistedInject constructor( + @Assisted("user") private val userToBan: String, + @Assisted override val room: String, + deps: CommunityApiDependencies, +) : CommunityApi(deps) { + override val requiresSigning: Boolean get() = true + override val httpMethod: String get() = "POST" + override val httpEndpoint: String = + "/user/${Uri.encode(userToBan)}/unban" + + @Serializable + private data class BanBody(val rooms: List) + + override fun buildRequestBody( + serverBaseUrl: String, + x25519PubKeyHex: String + ): Pair { + // JSON body {"rooms":[room]} + return buildJsonRequestBody(BanBody(rooms = listOf(room))) + } + + override suspend fun handleSuccessResponse( + executorContext: ApiExecutorContext, + baseUrl: String, + response: HttpResponse + ) = Unit + + @AssistedFactory + interface Factory { + fun create( + @Assisted("user") userToBan: String, + room: String + ): UnbanUserApi + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index d001fd95c2..629d2d84e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -2645,6 +2645,14 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate, } } + override fun unbanUser(messages: Set) { + showSessionDialog { + title(R.string.banUnbanUser) + dangerButton(R.string.theContinue) { viewModel.unbanUser(messages.first().individualRecipient.address); endActionMode() } + cancelButton(::endActionMode) + } + } + override fun banAndDeleteAll(messages: Set) { showSessionDialog { title(R.string.banDeleteAll) @@ -2979,6 +2987,7 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate, ConversationReactionOverlay.Action.DELETE -> deleteMessages(selectedItems) ConversationReactionOverlay.Action.BAN_AND_DELETE_ALL -> banAndDeleteAll(selectedItems) ConversationReactionOverlay.Action.BAN_USER -> banUser(selectedItems) + ConversationReactionOverlay.Action.UNBAN_USER -> unbanUser(selectedItems) ConversationReactionOverlay.Action.COPY_ACCOUNT_ID -> copyAccountID(selectedItems) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt index 10297977f7..efab1a11aa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt @@ -673,10 +673,8 @@ class ConversationReactionOverlay : FrameLayout { // Ban user if (userCanBanSelectedUsers(message) && !isDeleteOnly && !isDeprecatedLegacyGroup) { items += ActionItem(R.attr.menu_ban_icon, R.string.banUser, { handleActionItemClicked(Action.BAN_USER) }) - } - // Ban and delete all - if (userCanBanSelectedUsers(message) && !isDeleteOnly && !isDeprecatedLegacyGroup) { items += ActionItem(R.attr.menu_trash_icon, R.string.banDeleteAll, { handleActionItemClicked(Action.BAN_AND_DELETE_ALL) }) + items += ActionItem(R.attr.menu_unban_icon, R.string.banUnbanUser, { handleActionItemClicked(Action.UNBAN_USER) }) } // Message detail if(!isDeleteOnly) { @@ -833,6 +831,7 @@ class ConversationReactionOverlay : FrameLayout { SELECT, DELETE, BAN_USER, + UNBAN_USER, BAN_AND_DELETE_ALL } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt index ad8c2bd07f..2047e2f893 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt @@ -1112,6 +1112,19 @@ class ConversationViewModel @AssistedInject constructor( } } + fun unbanUser(recipient: Address) = viewModelScope.launch { + repository.unbanUser( + community = address as Address.Community, + userId = (recipient as Address.WithAccountId).accountId + ) + .onSuccess { + showMessage(application.getString(R.string.banUnbanUserUnbanned)) + } + .onFailure { + showMessage(application.getString(R.string.banUnbanErrorFailed)) + } + } + fun banAndDeleteAll(messageRecord: MessageRecord) = viewModelScope.launch { repository.banAndDeleteAll( community = address as Address.Community, diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt index b1546c3d1c..c8cc8d56e4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt @@ -68,7 +68,9 @@ class ConversationActionModeCallback( // Delete message menu.findItem(R.id.menu_context_delete_message).isVisible = !isDeprecatedLegacyGroup // can always delete since delete logic will be handled by the VM // Ban user - menu.findItem(R.id.menu_context_ban_user).isVisible = userCanBanSelectedUsers() && !isDeprecatedLegacyGroup + val canBan = userCanBanSelectedUsers() && !isDeprecatedLegacyGroup + menu.findItem(R.id.menu_context_ban_user).isVisible = canBan + menu.findItem(R.id.menu_context_unban_user).isVisible = canBan // Ban and delete all menu.findItem(R.id.menu_context_ban_and_delete_all).isVisible = userCanBanSelectedUsers() && !isDeprecatedLegacyGroup // Copy message text @@ -99,6 +101,7 @@ class ConversationActionModeCallback( when (item.itemId) { R.id.menu_context_delete_message -> delegate?.deleteMessages(selectedItems) R.id.menu_context_ban_user -> delegate?.banUser(selectedItems) + R.id.menu_context_unban_user -> delegate?.unbanUser(selectedItems) R.id.menu_context_ban_and_delete_all -> delegate?.banAndDeleteAll(selectedItems) R.id.menu_context_copy -> delegate?.copyMessages(selectedItems) R.id.menu_context_resync -> delegate?.resyncMessage(selectedItems) @@ -122,6 +125,7 @@ interface ConversationActionModeCallbackDelegate { fun selectMessages(messages: Set) fun deleteMessages(messages: Set) fun banUser(messages: Set) + fun unbanUser(messages: Set) fun banAndDeleteAll(messages: Set) fun copyMessages(messages: Set) fun resyncMessage(messages: Set) diff --git a/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt index f9ab5d885a..675a3510cf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt @@ -52,6 +52,7 @@ interface ConversationRepository { suspend fun deleteGroupV2MessagesRemotely(recipient: Address, messages: Set) suspend fun banUser(community: Address.Community, userId: AccountId): Result + suspend fun unbanUser(community: Address.Community, userId: AccountId): Result suspend fun banAndDeleteAll(community: Address.Community, userId: AccountId): Result suspend fun deleteMessageRequest(thread: ThreadRecord): Result suspend fun clearAllMessageRequests(): Result diff --git a/app/src/main/java/org/thoughtcrime/securesms/repository/DefaultConversationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/repository/DefaultConversationRepository.kt index e9c188a2a1..fc373ac95d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/repository/DefaultConversationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/repository/DefaultConversationRepository.kt @@ -26,6 +26,7 @@ import org.session.libsession.messaging.open_groups.api.BanUserApi import org.session.libsession.messaging.open_groups.api.CommunityApiExecutor import org.session.libsession.messaging.open_groups.api.CommunityApiRequest import org.session.libsession.messaging.open_groups.api.DeleteUserMessagesApi +import org.session.libsession.messaging.open_groups.api.UnbanUserApi import org.session.libsession.messaging.open_groups.api.execute import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.network.SnodeClock @@ -92,6 +93,7 @@ class DefaultConversationRepository @Inject constructor( private val deleteSwarmMessageApiFactory: DeleteSnodeMessageApi.Factory, private val deleteCommunityMessageApiFactory: DeleteCommunityMessageApi.Factory, private val banUserApiFactory: BanUserApi.Factory, + private val unbanUserApiFactory: UnbanUserApi.Factory, private val deleteUserMessageApiFactory: DeleteUserMessagesApi.Factory, ) : ConversationRepository { @@ -480,6 +482,18 @@ class DefaultConversationRepository @Inject constructor( ) } + override suspend fun unbanUser(community: Address.Community, userId: AccountId): Result = runCatching { + communityApiExecutor.execute( + CommunityApiRequest( + serverBaseUrl = community.serverUrl, + api = unbanUserApiFactory.create( + userToBan = userId.hexString, + room = community.room + ) + ) + ) + } + override suspend fun banAndDeleteAll(community: Address.Community, userId: AccountId) = runCatching { communityApiExecutor.execute( CommunityApiRequest( diff --git a/app/src/main/res/menu/menu_conversation_item_action.xml b/app/src/main/res/menu/menu_conversation_item_action.xml index f2b8313236..d29d7a8cf3 100644 --- a/app/src/main/res/menu/menu_conversation_item_action.xml +++ b/app/src/main/res/menu/menu_conversation_item_action.xml @@ -56,6 +56,12 @@ android:id="@+id/menu_context_ban_and_delete_all" app:showAsAction="never" /> + + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index c73762f95f..de700da4e4 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -29,6 +29,7 @@ ?backgroundSecondary @drawable/ic_trash_2 @drawable/ic_ban + @drawable/ic_user_round_tick @drawable/ic_arrow_down_to_line= @drawable/ic_copy @drawable/ic_reply From aa0e7219f7b1cb547a79570327f4fd7e7133bf21 Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Thu, 5 Feb 2026 08:39:02 +1100 Subject: [PATCH 3/6] Updated icons --- .../securesms/components/FromTextView.java | 2 +- .../v2/settings/ConversationSettingsViewModel.kt | 2 +- .../home/search/SearchContactActionBottomSheet.kt | 3 +-- app/src/main/res/drawable/ic_ban.xml | 7 ------- app/src/main/res/drawable/ic_user_round_block.xml | 11 +++++++++++ app/src/main/res/drawable/ic_user_round_x.xml | 14 ++++---------- .../layout/fragment_conversation_bottom_sheet.xml | 2 +- .../res/layout/layout_conversation_block_icon.xml | 2 +- app/src/main/res/menu/menu_message_request.xml | 2 +- app/src/main/res/values/themes.xml | 2 +- 10 files changed, 22 insertions(+), 25 deletions(-) delete mode 100644 app/src/main/res/drawable/ic_ban.xml create mode 100644 app/src/main/res/drawable/ic_user_round_block.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/FromTextView.java b/app/src/main/java/org/thoughtcrime/securesms/components/FromTextView.java index d045e82b14..556c192b68 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/FromTextView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/FromTextView.java @@ -77,7 +77,7 @@ public void setText(Recipient recipient, boolean read) { setText(builder); - if (recipient.getBlocked()) setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_user_round_x, 0, 0, 0); + if (recipient.getBlocked()) setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_user_round_block, 0, 0, 0); else if (recipient.isMuted()) setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_volume_off, 0, 0, 0); else setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/settings/ConversationSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/settings/ConversationSettingsViewModel.kt index c6c8da0f8d..64b504f2da 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/settings/ConversationSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/settings/ConversationSettingsViewModel.kt @@ -183,7 +183,7 @@ class ConversationSettingsViewModel @AssistedInject constructor( private val optionBlock: OptionsItem by lazy{ OptionsItem( name = context.getString(R.string.block), - icon = R.drawable.ic_user_round_x, + icon = R.drawable.ic_user_round_block, qaTag = R.string.qa_conversation_settings_block, onClick = ::confirmBlockUser ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/search/SearchContactActionBottomSheet.kt b/app/src/main/java/org/thoughtcrime/securesms/home/search/SearchContactActionBottomSheet.kt index 64ad38bee3..b412d22cb5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/search/SearchContactActionBottomSheet.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/search/SearchContactActionBottomSheet.kt @@ -17,7 +17,6 @@ import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.core.os.BundleCompat -import androidx.core.view.doOnLayout import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment @@ -72,7 +71,7 @@ class SearchContactActionBottomSheet : BottomSheetDialogFragment() { if (address is Address.Standard) { ActionSheetItem( text = stringResource(R.string.block), - leadingIcon = R.drawable.ic_user_round_x, + leadingIcon = R.drawable.ic_user_round_block, qaTag = stringResource(R.string.AccessibilityId_block), onClick = { showBlockConfirmation() diff --git a/app/src/main/res/drawable/ic_ban.xml b/app/src/main/res/drawable/ic_ban.xml deleted file mode 100644 index 744936981f..0000000000 --- a/app/src/main/res/drawable/ic_ban.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_user_round_block.xml b/app/src/main/res/drawable/ic_user_round_block.xml new file mode 100644 index 0000000000..8130e38b89 --- /dev/null +++ b/app/src/main/res/drawable/ic_user_round_block.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_user_round_x.xml b/app/src/main/res/drawable/ic_user_round_x.xml index 4bcbd0d2c1..b09d84fcca 100644 --- a/app/src/main/res/drawable/ic_user_round_x.xml +++ b/app/src/main/res/drawable/ic_user_round_x.xml @@ -1,17 +1,11 @@ - + - - - - - - - - - + + + diff --git a/app/src/main/res/layout/fragment_conversation_bottom_sheet.xml b/app/src/main/res/layout/fragment_conversation_bottom_sheet.xml index 935f95e341..98adbe57db 100644 --- a/app/src/main/res/layout/fragment_conversation_bottom_sheet.xml +++ b/app/src/main/res/layout/fragment_conversation_bottom_sheet.xml @@ -69,7 +69,7 @@ android:contentDescription="@string/AccessibilityId_block" android:text="@string/block" android:visibility="gone" - app:drawableStartCompat="@drawable/ic_user_round_x" + app:drawableStartCompat="@drawable/ic_user_round_block" app:drawableTint="?attr/colorControlNormal" tools:visibility="visible" /> diff --git a/app/src/main/res/layout/layout_conversation_block_icon.xml b/app/src/main/res/layout/layout_conversation_block_icon.xml index a5af51c476..80022231f5 100644 --- a/app/src/main/res/layout/layout_conversation_block_icon.xml +++ b/app/src/main/res/layout/layout_conversation_block_icon.xml @@ -12,7 +12,7 @@ android:layout_margin="@dimen/very_small_spacing" android:layout_width="13dp" android:layout_height="13dp" - android:src="@drawable/ic_user_round_x" + android:src="@drawable/ic_user_round_block" app:tint="?danger" /> diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index de700da4e4..b552d54691 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -28,7 +28,7 @@ ?android:textColorPrimary ?backgroundSecondary @drawable/ic_trash_2 - @drawable/ic_ban + @drawable/ic_user_round_x @drawable/ic_user_round_tick @drawable/ic_arrow_down_to_line= @drawable/ic_copy From cdd88ff73801c6ad84462ccf00666e271a60056d Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Thu, 5 Feb 2026 09:29:29 +1100 Subject: [PATCH 4/6] Lighter logs for requests --- .../org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt b/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt index ccb038be8f..268aca254e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt @@ -17,7 +17,7 @@ class OkHttpApiExecutor( override suspend fun send(ctx: ApiExecutorContext, req: HttpRequest): HttpResponse { return semaphore.withPermit { withContext(Dispatchers.IO) { - Log.d("OkHttpApiExecutor", "Sending request: $req, with context: $ctx") + Log.d("OkHttpApiExecutor", "Sending request: ${req.url}") client.newCall(req.toOkHttpRequest()).execute().toHttpResponse() } } From 64b037673ad4484a05c66a480b635e15dab0cd41 Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Thu, 5 Feb 2026 09:56:20 +1100 Subject: [PATCH 5/6] More logs --- .../org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt | 1 - .../securesms/api/onion/OnionSessionApiExecutor.kt | 3 +++ .../org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt b/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt index 268aca254e..bd79820754 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/api/http/OkHttpApiExecutor.kt @@ -17,7 +17,6 @@ class OkHttpApiExecutor( override suspend fun send(ctx: ApiExecutorContext, req: HttpRequest): HttpResponse { return semaphore.withPermit { withContext(Dispatchers.IO) { - Log.d("OkHttpApiExecutor", "Sending request: ${req.url}") client.newCall(req.toOkHttpRequest()).execute().toHttpResponse() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/api/onion/OnionSessionApiExecutor.kt b/app/src/main/java/org/thoughtcrime/securesms/api/onion/OnionSessionApiExecutor.kt index b8c7ff54b4..2a59e4c68b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/api/onion/OnionSessionApiExecutor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/api/onion/OnionSessionApiExecutor.kt @@ -70,12 +70,15 @@ class OnionSessionApiExecutor @Inject constructor( when (req) { is SessionApiRequest.SnodeJsonRPC -> { + Log.d("OnionSessionApiExecutor", "Sending Onion request to Snode destination. Method: ${req.request.method} -- Destination: ${req.snode}") + onionRequestVersion = OnionRequestVersion.V3 onionDestination = OnionDestination.SnodeDestination(req.snode) payload = json.encodeToString(req.request).toByteArray() } is SessionApiRequest.HttpServerRequest -> { + Log.d("OnionSessionApiExecutor", "Sending Onion request to Server destination. Url: ${req.request.url}") onionRequestVersion = OnionRequestVersion.V4 onionDestination = OnionDestination.ServerDestination( host = req.request.url.host, diff --git a/app/src/main/java/org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt b/app/src/main/java/org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt index 48c8a564fc..d2b5c8a77e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/api/snode/AbstractSnodeApi.kt @@ -48,7 +48,7 @@ abstract class AbstractSnodeApi( ctx = failureContext ) - Log.d("SnodeApi", "Network error for a Snode endpoint (${snode.ed25519Key}), with status:${code} - error: $error") + Log.d("SnodeApi", "Network error for a Snode endpoint ($snode), with status:${code} - error: $error") ctx.set(SnodeClientFailureKey, failureContext.copy(previousErrorCode = code)) From e2900edec7933bcebaa42a155668dc34b8b2b964 Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Thu, 5 Feb 2026 10:17:54 +1100 Subject: [PATCH 6/6] Menu string change --- .../securesms/conversation/v2/ConversationReactionOverlay.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt index efab1a11aa..bf28bf7eb3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt @@ -680,7 +680,7 @@ class ConversationReactionOverlay : FrameLayout { if(!isDeleteOnly) { items += ActionItem( R.attr.menu_info_icon, - R.string.messageInfo, + R.string.info, { handleActionItemClicked(Action.VIEW_INFO) }) } // Resend