From 7caabd9ea2cb630c762e8f3e6e8119febe9a6842 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Mar 2026 03:27:10 +0000 Subject: [PATCH] feat: add GIF keyboard support to short new post screen Add contentReceiver modifier to MessageField to receive images/GIFs directly from Android's keyboard. When a GIF is selected from the keyboard, its URI is passed to the post ViewModel's selectImage flow for upload handling. https://claude.ai/code/session_014FZPV258VfdeE1mcyeU7wU --- .../creators/messagefield/MessageField.kt | 48 +++++++++++++++---- .../loggedIn/home/ShortNotePostScreen.kt | 5 ++ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/messagefield/MessageField.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/messagefield/MessageField.kt index 63509dca64..7b72885e4e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/messagefield/MessageField.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/messagefield/MessageField.kt @@ -20,6 +20,12 @@ */ package com.vitorpamplona.amethyst.ui.note.creators.messagefield +import android.net.Uri +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.content.ReceiveContentListener +import androidx.compose.foundation.content.TransferableContent +import androidx.compose.foundation.content.consume +import androidx.compose.foundation.content.contentReceiver import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.LocalTextStyle @@ -46,11 +52,13 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText import kotlinx.coroutines.delay import kotlinx.coroutines.launch +@OptIn(ExperimentalFoundationApi::class) @Composable fun MessageField( placeholder: Int, viewModel: IMessageField, requestFocus: Boolean = true, + onReceiveUri: ((Uri) -> Unit)? = null, ) { val focusRequester = remember { FocusRequester() } val keyboardController = LocalSoftwareKeyboardController.current @@ -64,6 +72,36 @@ fun MessageField( } } + val baseModifier = + Modifier + .fillMaxWidth() + .focusRequester(focusRequester) + .onFocusChanged { + if (it.isFocused) { + keyboardController?.show() + } + } + + val modifier = + if (onReceiveUri != null) { + baseModifier.contentReceiver( + object : ReceiveContentListener { + override fun onReceive(content: TransferableContent): TransferableContent? = + content.consume { item -> + val uri = item.uri + if (uri != null) { + onReceiveUri(uri) + true + } else { + false + } + } + }, + ) + } else { + baseModifier + } + ThinPaddingTextField( value = viewModel.message, onValueChange = viewModel::updateMessage, @@ -71,15 +109,7 @@ fun MessageField( KeyboardOptions.Default.copy( capitalization = KeyboardCapitalization.Sentences, ), - modifier = - Modifier - .fillMaxWidth() - .focusRequester(focusRequester) - .onFocusChanged { - if (it.isFocused) { - keyboardController?.show() - } - }, + modifier = modifier, placeholder = { Text( text = stringRes(placeholder), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt index b0c5890587..160c430c00 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt @@ -319,9 +319,14 @@ private fun NewPostScreenBody( ) } } + val context = LocalContext.current MessageField( R.string.what_s_on_your_mind, postViewModel, + onReceiveUri = { uri -> + val mediaType = context.contentResolver.getType(uri) + postViewModel.selectImage(persistentListOf(SelectedMedia(uri, mediaType))) + }, ) } }