Skip to content

Commit

Permalink
[AND-147] Fix keyboard not closing when opening attachment picker men…
Browse files Browse the repository at this point in the history
…u and make this behaviour customizable. (#5506)

* [AND-147] Ensure keyboard is closed when opening attachments menu.

* [AND-147] Add StreamKeyboardBehaviour to CHANGELOG.md.

---------

Co-authored-by: PetarVelikov <[email protected]>
  • Loading branch information
VelikovPetar and PetarVelikov authored Dec 5, 2024
1 parent 731832d commit 8e0ed84
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 4 deletions.
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
20 changes: 19 additions & 1 deletion stream-chat-android-compose/api/stream-chat-android-compose.api
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)
}
}
}

0 comments on commit 8e0ed84

Please sign in to comment.