Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AND-147] Fix keyboard not closing when opening attachment picker menu and make this behaviour customizable. #5506

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@

## stream-chat-android-compose
### 🐞 Fixed
- Fix keyboard not closing when opening the attachments picker from `MessagesScreen`. [#5506](https://github.com/GetStream/stream-chat-android/pull/5506)

### ⬆️ Improved

### ✅ Added
- The `StreamAttachmentFactories.defaultFactories()` method now accepts a `skipTypes` parameter to skip specific factory types. [#5494](https://github.com/GetStream/stream-chat-android/pull/5494)
- Add `ChatTheme.keyboardBehaviour` property to customize different keyboard behaviours. [#5506](https://github.com/GetStream/stream-chat-android/pull/5506)

### ⚠️ Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2026,6 +2026,7 @@ public final class io/getstream/chat/android/compose/ui/theme/ChatTheme {
public final fun getColors (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/theme/StreamColors;
public final fun getDateFormatter (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/ui/common/helper/DateFormatter;
public final fun getDimens (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/theme/StreamDimens;
public final fun getKeyboardBehaviour (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/theme/StreamKeyboardBehaviour;
public final fun getMessageAlignmentProvider (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/util/MessageAlignmentProvider;
public final fun getMessageComposerTheme (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/theme/MessageComposerTheme;
public final fun getMessageContentFactory (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/components/messages/factory/MessageContentFactory;
Expand Down Expand Up @@ -2060,7 +2061,7 @@ public final class io/getstream/chat/android/compose/ui/theme/ChatTheme {
}

public final class io/getstream/chat/android/compose/ui/theme/ChatThemeKt {
public static final fun ChatTheme (ZZZZLio/getstream/chat/android/compose/ui/theme/StreamColors;Lio/getstream/chat/android/compose/ui/theme/StreamDimens;Lio/getstream/chat/android/compose/ui/theme/StreamTypography;Lio/getstream/chat/android/compose/ui/theme/StreamShapes;Lio/getstream/chat/android/compose/ui/theme/StreamRippleConfiguration;Ljava/util/List;Lio/getstream/chat/android/compose/ui/components/messages/factory/MessageContentFactory;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/compose/ui/util/ReactionIconFactory;Lio/getstream/chat/android/compose/ui/theme/ReactionOptionsTheme;Lio/getstream/chat/android/compose/ui/util/MessagePreviewIconFactory;Lio/getstream/chat/android/compose/ui/util/PollSwitchItemFactory;ZLio/getstream/chat/android/ui/common/helper/DateFormatter;Lio/getstream/chat/android/ui/common/helper/TimeProvider;Lio/getstream/chat/android/ui/common/utils/ChannelNameFormatter;Lio/getstream/chat/android/compose/ui/util/MessagePreviewFormatter;Lio/getstream/chat/android/compose/ui/util/SearchResultNameFormatter;Lio/getstream/chat/android/compose/ui/util/StreamCoilImageLoaderFactory;Lio/getstream/chat/android/ui/common/helper/ImageHeadersProvider;Lio/getstream/chat/android/ui/common/helper/DownloadAttachmentUriGenerator;Lio/getstream/chat/android/ui/common/helper/DownloadRequestInterceptor;Lio/getstream/chat/android/ui/common/helper/ImageAssetTransformer;Lio/getstream/chat/android/compose/ui/util/MessageAlignmentProvider;Lio/getstream/chat/android/compose/ui/theme/MessageOptionsTheme;Lio/getstream/chat/android/ui/common/state/messages/list/MessageOptionsUserReactionAlignment;Ljava/util/List;ZLio/getstream/chat/android/ui/common/images/resizing/StreamCdnImageResizing;ZLio/getstream/chat/android/compose/ui/theme/MessageTheme;Lio/getstream/chat/android/compose/ui/theme/MessageTheme;Lio/getstream/chat/android/compose/ui/theme/MessageDateSeparatorTheme;Lio/getstream/chat/android/compose/ui/theme/MessageUnreadSeparatorTheme;Lio/getstream/chat/android/compose/ui/theme/MessageComposerTheme;Lio/getstream/chat/android/compose/ui/theme/AttachmentPickerTheme;Lio/getstream/chat/android/compose/ui/util/MessageTextFormatter;Lio/getstream/chat/android/compose/ui/util/QuotedMessageTextFormatter;Lio/getstream/sdk/chat/audio/recording/StreamMediaRecorder;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;IIIIIII)V
public static final fun ChatTheme (ZZZZLio/getstream/chat/android/compose/ui/theme/StreamColors;Lio/getstream/chat/android/compose/ui/theme/StreamDimens;Lio/getstream/chat/android/compose/ui/theme/StreamTypography;Lio/getstream/chat/android/compose/ui/theme/StreamShapes;Lio/getstream/chat/android/compose/ui/theme/StreamRippleConfiguration;Ljava/util/List;Lio/getstream/chat/android/compose/ui/components/messages/factory/MessageContentFactory;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/compose/ui/util/ReactionIconFactory;Lio/getstream/chat/android/compose/ui/theme/ReactionOptionsTheme;Lio/getstream/chat/android/compose/ui/util/MessagePreviewIconFactory;Lio/getstream/chat/android/compose/ui/util/PollSwitchItemFactory;ZLio/getstream/chat/android/ui/common/helper/DateFormatter;Lio/getstream/chat/android/ui/common/helper/TimeProvider;Lio/getstream/chat/android/ui/common/utils/ChannelNameFormatter;Lio/getstream/chat/android/compose/ui/util/MessagePreviewFormatter;Lio/getstream/chat/android/compose/ui/util/SearchResultNameFormatter;Lio/getstream/chat/android/compose/ui/util/StreamCoilImageLoaderFactory;Lio/getstream/chat/android/ui/common/helper/ImageHeadersProvider;Lio/getstream/chat/android/ui/common/helper/DownloadAttachmentUriGenerator;Lio/getstream/chat/android/ui/common/helper/DownloadRequestInterceptor;Lio/getstream/chat/android/ui/common/helper/ImageAssetTransformer;Lio/getstream/chat/android/compose/ui/util/MessageAlignmentProvider;Lio/getstream/chat/android/compose/ui/theme/MessageOptionsTheme;Lio/getstream/chat/android/ui/common/state/messages/list/MessageOptionsUserReactionAlignment;Ljava/util/List;ZLio/getstream/chat/android/ui/common/images/resizing/StreamCdnImageResizing;ZLio/getstream/chat/android/compose/ui/theme/MessageTheme;Lio/getstream/chat/android/compose/ui/theme/MessageTheme;Lio/getstream/chat/android/compose/ui/theme/MessageDateSeparatorTheme;Lio/getstream/chat/android/compose/ui/theme/MessageUnreadSeparatorTheme;Lio/getstream/chat/android/compose/ui/theme/MessageComposerTheme;Lio/getstream/chat/android/compose/ui/theme/AttachmentPickerTheme;Lio/getstream/chat/android/compose/ui/util/MessageTextFormatter;Lio/getstream/chat/android/compose/ui/util/QuotedMessageTextFormatter;Lio/getstream/sdk/chat/audio/recording/StreamMediaRecorder;Lio/getstream/chat/android/compose/ui/theme/StreamKeyboardBehaviour;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;IIIIIII)V
}

public final class io/getstream/chat/android/compose/ui/theme/ComponentOffset {
Expand Down Expand Up @@ -2616,6 +2617,23 @@ public final class io/getstream/chat/android/compose/ui/theme/StreamDimens$Compa
public final fun defaultDimens ()Lio/getstream/chat/android/compose/ui/theme/StreamDimens;
}

public final class io/getstream/chat/android/compose/ui/theme/StreamKeyboardBehaviour {
public static final field $stable I
public static final field Companion Lio/getstream/chat/android/compose/ui/theme/StreamKeyboardBehaviour$Companion;
public fun <init> (Z)V
public final fun component1 ()Z
public final fun copy (Z)Lio/getstream/chat/android/compose/ui/theme/StreamKeyboardBehaviour;
public static synthetic fun copy$default (Lio/getstream/chat/android/compose/ui/theme/StreamKeyboardBehaviour;ZILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/theme/StreamKeyboardBehaviour;
public fun equals (Ljava/lang/Object;)Z
public final fun getCloseKeyboardOnAttachmentPickerOpen ()Z
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class io/getstream/chat/android/compose/ui/theme/StreamKeyboardBehaviour$Companion {
public final fun defaultBehaviour ()Lio/getstream/chat/android/compose/ui/theme/StreamKeyboardBehaviour;
}

public final class io/getstream/chat/android/compose/ui/theme/StreamRippleConfiguration {
public static final field $stable I
public static final field Companion Lio/getstream/chat/android/compose/ui/theme/StreamRippleConfiguration$Companion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package io.getstream.chat.android.compose.ui.messages

import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.AnimationConstants
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
Expand All @@ -43,6 +42,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand All @@ -53,6 +53,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -443,7 +444,6 @@ public fun BoxScope.MessageMenus(
* displayed as a link attachment. False by default.
*/
@Suppress("LongMethod")
@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun BoxScope.MessagesScreenMenus(
listViewModel: MessageListViewModel,
Expand Down Expand Up @@ -578,7 +578,6 @@ private fun BoxScope.MessagesScreenMenus(
* @param skipEnrichUrl If the message should skip enriching the URL. If URL is not enriched, it will not be
* displayed as a link attachment. False by default.
*/
@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun BoxScope.MessagesScreenReactionsPicker(
listViewModel: MessageListViewModel,
Expand Down Expand Up @@ -646,6 +645,15 @@ public fun BoxScope.AttachmentsPickerMenu(
) {
val isShowingAttachments = attachmentsPickerViewModel.isShowingAttachments

// Ensure keyboard is closed when the attachments picker is shown (if instructed by ChatTheme)
val keyboardController = LocalSoftwareKeyboardController.current
val shouldCloseKeyboard = ChatTheme.keyboardBehaviour.closeKeyboardOnAttachmentPickerOpen
LaunchedEffect(isShowingAttachments) {
if (shouldCloseKeyboard && isShowingAttachments) {
keyboardController?.hide()
}
}

AnimatedVisibility(
visible = isShowingAttachments,
enter = fadeIn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ private val LocalComposerLinkPreviewEnabled = compositionLocalOf<Boolean> {
private val LocalStreamMediaRecorder = compositionLocalOf<StreamMediaRecorder> {
error("No StreamMediaRecorder provided! Make sure to wrap all usages of Stream components in a ChatTheme.")
}
private val LocalKeyboardBehaviour = compositionLocalOf<StreamKeyboardBehaviour> {
error("No StreamKeyboardBehaviour provided! Make sure to wrap all usages of Stream components in a ChatTheme.")
}

/**
* Our theme that provides all the important properties for styling to the user.
Expand Down Expand Up @@ -265,8 +268,10 @@ private val LocalStreamMediaRecorder = compositionLocalOf<StreamMediaRecorder> {
* @param messageComposerTheme Theme of the message composer.
* @param attachmentPickerTheme Theme of the attachment picker.
* @param streamMediaRecorder Used for recording audio messages.
* @param keyboardBehaviour Configuration for different keyboard behaviours.
* @param content The content shown within the theme wrapper.
*/
@Suppress("LongMethod")
@Composable
public fun ChatTheme(
isInDarkMode: Boolean = isSystemInDarkTheme(),
Expand Down Expand Up @@ -363,6 +368,7 @@ public fun ChatTheme(
otherMessageTheme = otherMessageTheme,
),
streamMediaRecorder: StreamMediaRecorder = DefaultStreamMediaRecorder(LocalContext.current),
keyboardBehaviour: StreamKeyboardBehaviour = StreamKeyboardBehaviour.defaultBehaviour(),
content: @Composable () -> Unit,
) {
LaunchedEffect(Unit) {
Expand Down Expand Up @@ -412,6 +418,7 @@ public fun ChatTheme(
LocalStreamMediaRecorder provides streamMediaRecorder,
LocalAutoTranslationEnabled provides autoTranslationEnabled,
LocalComposerLinkPreviewEnabled provides isComposerLinkPreviewEnabled,
LocalKeyboardBehaviour provides keyboardBehaviour,
) {
if (allowUIAutomationTest) {
Box(
Expand Down Expand Up @@ -738,4 +745,12 @@ public object ChatTheme {
@Composable
@ReadOnlyComposable
get() = LocalStreamMediaRecorder.current

/**
* Retrieves the current [StreamKeyboardBehaviour] at the call site's position in the hierarchy.
*/
public val keyboardBehaviour: StreamKeyboardBehaviour
@Composable
@ReadOnlyComposable
get() = LocalKeyboardBehaviour.current
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2014-2024 Stream.io Inc. All rights reserved.
*
* Licensed under the Stream License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getstream.chat.android.compose.ui.theme

/**
* Class holding configuration for different keyboard behaviours.
*
* @param closeKeyboardOnAttachmentPickerOpen If true, the keyboard will be closed when the attachment picker is opened.
*/
public data class StreamKeyboardBehaviour(
val closeKeyboardOnAttachmentPickerOpen: Boolean,
) {

public companion object {

/**
* Builds the default keyboard behaviour.
*
* @return A [StreamKeyboardBehaviour] instance holding the default configuration.
*/
public fun defaultBehaviour(): StreamKeyboardBehaviour {
return StreamKeyboardBehaviour(closeKeyboardOnAttachmentPickerOpen = true)
}
}
}
Loading