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
This commit is contained in:
Claude
2026-03-28 16:30:05 +00:00
parent 0054c01921
commit 7caabd9ea2
2 changed files with 44 additions and 9 deletions
@@ -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),
@@ -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)))
},
)
}
}