mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-08-08 06:46:11 +00:00
Hide the command and mention popups after a message is sent
When a slash command is sent without tapping the autocomplete list, the command popup stays on screen with its old suggestions. The send path clears the input field in code, and the popup is hidden only from the field's text-change handler, which a code-driven clear does not run, so the show flag is never turned off. The mention popup has the same cause. CommandProcessor gains clearSuggestions(), which hides both popups and empties their lists, the same resets the two select functions already do inline. ChatScreen's send handler calls it where it already resets the field. The private chat sheet called updateMentionSuggestions on every keystroke while rendering its own popups as hidden, so the only effect was on the main composer behind it: typing @ in the sheet and then sending or dismissing left a stale mention popup on the main screen. That call is removed. Tests in CommandProcessorTest open each popup and assert clearSuggestions hides it. The unit tests do not drive Compose, so they cover the function the send handler calls rather than the handler itself. Full Android unit suite green; lint and the debug build pass. Fixes #250.
This commit is contained in:
parent
cb6d68958d
commit
862fd8449d
@ -386,6 +386,9 @@ fun ChatScreen(viewModel: ChatViewModel) {
|
||||
if (accepted) {
|
||||
messageText = TextFieldValue("")
|
||||
viewModel.setConversationDraft(selectedPrivatePeer, "")
|
||||
// Clearing the field in code does not run onMessageTextChange,
|
||||
// so the popups have to be dismissed here.
|
||||
viewModel.clearSuggestions()
|
||||
forceScrollToBottom = !forceScrollToBottom
|
||||
}
|
||||
}
|
||||
|
||||
@ -1341,7 +1341,11 @@ class ChatViewModel(
|
||||
fun updateCommandSuggestions(input: String) {
|
||||
commandProcessor.updateCommandSuggestions(input)
|
||||
}
|
||||
|
||||
|
||||
fun clearSuggestions() {
|
||||
commandProcessor.clearSuggestions()
|
||||
}
|
||||
|
||||
fun selectCommandSuggestion(suggestion: CommandSuggestion): String {
|
||||
return commandProcessor.selectCommandSuggestion(suggestion)
|
||||
}
|
||||
|
||||
@ -465,6 +465,18 @@ class CommandProcessor(
|
||||
messageManager.addMessage(systemMessage)
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss the command and mention popups. The composer clears its field in code
|
||||
* after a send, which does not run onValueChange, so the popups need an explicit
|
||||
* clear.
|
||||
*/
|
||||
fun clearSuggestions() {
|
||||
state.setShowCommandSuggestions(false)
|
||||
state.setCommandSuggestions(emptyList())
|
||||
state.setShowMentionSuggestions(false)
|
||||
state.setMentionSuggestions(emptyList())
|
||||
}
|
||||
|
||||
// MARK: - Command Autocomplete
|
||||
|
||||
fun updateCommandSuggestions(input: String) {
|
||||
|
||||
@ -1849,7 +1849,9 @@ fun PrivateChatSheet(
|
||||
onMessageTextChange = { newText ->
|
||||
messageText = newText
|
||||
viewModel.setConversationDraft(peerID, newText.text)
|
||||
viewModel.updateMentionSuggestions(newText.text)
|
||||
// Do not update the shared suggestion state here: this sheet
|
||||
// renders its own popups as hidden, so an update only leaves
|
||||
// a stale popup behind for the main composer.
|
||||
},
|
||||
onSend = {
|
||||
if (messageText.text.trim().isNotEmpty()) {
|
||||
|
||||
@ -8,6 +8,7 @@ import com.bitchat.android.geohash.GeohashChannelLevel
|
||||
import com.bitchat.android.mesh.MeshService
|
||||
import com.bitchat.android.model.BitchatMessage
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import junit.framework.TestCase.assertFalse
|
||||
import junit.framework.TestCase.assertTrue
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
@ -161,4 +162,30 @@ class CommandProcessorTest() {
|
||||
)
|
||||
assertEquals(0, chatState.getMessagesValue().size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clearSuggestions hides the command suggestion popup`() {
|
||||
// Typing "/" opens the command popup.
|
||||
commandProcessor.updateCommandSuggestions("/")
|
||||
assertTrue(chatState.getShowCommandSuggestionsValue())
|
||||
|
||||
// The send handlers call this after clearing the field in code, which does
|
||||
// not run the text-change handler that normally hides the popup.
|
||||
commandProcessor.clearSuggestions()
|
||||
assertFalse(chatState.getShowCommandSuggestionsValue())
|
||||
assertTrue(chatState.getCommandSuggestionsValue().isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clearSuggestions hides the mention suggestion popup`() {
|
||||
whenever(meshService.getPeerNicknames()).thenReturn(mapOf("peer-1" to "alice"))
|
||||
|
||||
// Typing "@a" opens the mention popup.
|
||||
commandProcessor.updateMentionSuggestions("@a", meshService, viewModel = null)
|
||||
assertTrue(chatState.getShowMentionSuggestionsValue())
|
||||
|
||||
commandProcessor.clearSuggestions()
|
||||
assertFalse(chatState.getShowMentionSuggestionsValue())
|
||||
assertTrue(chatState.getMentionSuggestionsValue().isEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user