Skip to content

Commit

Permalink
[PBE-5514] Pick attachment files without the need for permissions (#5380
Browse files Browse the repository at this point in the history
)

* Add an option in compose to pick files without the need for read media permissions.

* Finalize implementation of XML, change to linear layout instead  of  grid

* Spotless and API dump

* Fix detekt, add doc (wip) and fix style issues

* Long parameter list fix

* Spotless

* Fix detekt style issues.

* Fix detekt style issues.

* Spotless

* Add parameters to a new line

* fix spotless

* Spotless and ApiDump

* (compose): change default value to false

* (xml): rename to useDefaultSystemMediaPicker

* clean up

* clean up

* align xml with compose names

* move clickable the content, not the card

* improve docs

* spotless, api dump

---------

Co-authored-by: kanat <[email protected]>
  • Loading branch information
aleksandar-apostolov and kanat authored Aug 30, 2024
1 parent 70da8ba commit edf3ba9
Show file tree
Hide file tree
Showing 20 changed files with 1,158 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# System Media Picker

Sometimes its not desirable for an app to have the `READ_MEDIA_IMAGES` and `READ_MEDIA_VIDEO` permissions.
In this guide, we will explain how to set up the new `useDefaultSystemMediaPicker` parameter in both `ChatTheme` and `ChatUI`, why it is important, and how to remove permissions from the `AndroidManifest.xml` using `tools:node="remove"`.

### The importance of System Media Picker

The `useDefaultSystemMediaPicker` parameter allows you to use the system's default media picker instead of the custom media picker provided by the library. This can be beneficial for several reasons:
- **Consistency**: Provides a consistent user experience by using the familiar system media picker.
- **Permissions**: Reduces the need for additional permissions, as the system media picker handles permissions internally.
- **Simplicity**: Simplifies the implementation by leveraging the built-in functionality of the system media picker.

### Setting Up System Media Picker

#### In Compose UI

To enable the system media picker in `ChatTheme`, set the `useDefaultSystemMediaPicker` parameter to `true` when initializing the theme.

```kotlin
ChatTheme(
useDefaultSystemMediaPicker = true
) {
// Your composable content
}
```

#### In XML-based UI

There are two options for enabling usage of the system media picker in XML-based UI: `XML attributes` and `StyleTransformer`.

Let's start with the `XML Attributes` option.
You can enable the system media picker by setting the `streamUiMessageComposerAttachmentsPickerSystemPickerEnabled` attribute to `true` in the `MessageComposerView` XML layout.

```xml
<io.getstream.chat.android.ui.feature.messages.composer.MessageComposerView
android:id="@+id/messageComposerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:streamUiMessageComposerAttachmentsPickerSystemPickerEnabled="true"
/>
```

You can also enable the system media picker using the `StyleTransformer` as shown below.

```kotlin
// Set the property directly in the AttachmentsPickerDialogStyle
TransformStyle.attachmentsPickerStyleTransformer = StyleTransformer { defaultStyle ->
defaultStyle.copy(
useDefaultSystemMediaPicker = true,
)
}

// Or set the property in the MessageComposerStyle
TransformStyle.messageComposerStyleTransformer = StyleTransformer { defaultStyle ->
defaultStyle.copy(
attachmentsPickerDialogStyle = defaultStyle.attachmentsPickerDialogStyle.copy(
useDefaultSystemMediaPicker = true,
),
)
}
```

Please be advised that setting `useDefaultSystemMediaPicker` in `MessageComposerStyle` will override the value set in `AttachmentsPickerDialogStyle`.

### Removing Permissions from your Project

Let's remove the permissions from the `AndroidManifest.xml`.

When using the system media picker, you can remove unnecessary permissions from your `AndroidManifest.xml` to streamline your app's permission requests.
Use the `tools:node="remove"` attribute to remove permissions.

```xml
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" tools:node="remove" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" tools:node="remove" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" tools:node="remove" />
```

By following these steps you can remove unnecessary permissions from your `AndroidManifest.xml`.
23 changes: 18 additions & 5 deletions stream-chat-android-compose/api/stream-chat-android-compose.api
Original file line number Diff line number Diff line change
Expand Up @@ -1520,11 +1520,21 @@ public final class io/getstream/chat/android/compose/ui/messages/attachments/fac
public fun isPickerTabEnabled (Lio/getstream/chat/android/models/Channel;)Z
}

public final class io/getstream/chat/android/compose/ui/messages/attachments/factory/AttachmentsPickerSystemTabFactory : io/getstream/chat/android/compose/ui/messages/attachments/factory/AttachmentsPickerTabFactory {
public static final field $stable I
public fun <init> (Ljava/util/List;)V
public fun PickerTabContent (Lkotlin/jvm/functions/Function1;Ljava/util/List;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
public fun PickerTabIcon (ZZLandroidx/compose/runtime/Composer;I)V
public fun getAttachmentsPickerMode ()Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentsPickerMode;
public fun isPickerTabEnabled (Lio/getstream/chat/android/models/Channel;)Z
}

public final class io/getstream/chat/android/compose/ui/messages/attachments/factory/AttachmentsPickerTabFactories {
public static final field $stable I
public static final field INSTANCE Lio/getstream/chat/android/compose/ui/messages/attachments/factory/AttachmentsPickerTabFactories;
public final fun defaultFactories (ZZZZZ)Ljava/util/List;
public static synthetic fun defaultFactories$default (Lio/getstream/chat/android/compose/ui/messages/attachments/factory/AttachmentsPickerTabFactories;ZZZZZILjava/lang/Object;)Ljava/util/List;
public final fun defaultFactoriesWithoutStoragePermissions ()Ljava/util/List;
}

public abstract interface class io/getstream/chat/android/compose/ui/messages/attachments/factory/AttachmentsPickerTabFactory {
Expand Down Expand Up @@ -1891,12 +1901,13 @@ public final class io/getstream/chat/android/compose/ui/theme/ChatTheme {
public final fun getStreamMediaRecorder (Landroidx/compose/runtime/Composer;I)Lio/getstream/sdk/chat/audio/recording/StreamMediaRecorder;
public final fun getTimeProvider (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/ui/common/helper/TimeProvider;
public final fun getTypography (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/theme/StreamTypography;
public final fun getUseDefaultSystemMediaPicker (Landroidx/compose/runtime/Composer;I)Z
public final fun getVideoThumbnailsEnabled (Landroidx/compose/runtime/Composer;I)Z
public final fun isComposerLinkPreviewEnabled (Landroidx/compose/runtime/Composer;I)Z
}

public final class io/getstream/chat/android/compose/ui/theme/ChatThemeKt {
public static final fun ChatTheme (ZZZLio/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;Landroidx/compose/material/ripple/RippleTheme;Ljava/util/List;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/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/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;IIIIII)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;Landroidx/compose/material/ripple/RippleTheme;Ljava/util/List;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/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/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;IIIIII)V
}

public final class io/getstream/chat/android/compose/ui/theme/ComponentSize {
Expand Down Expand Up @@ -2205,8 +2216,8 @@ public final class io/getstream/chat/android/compose/ui/theme/StreamColors$Compa
public final class io/getstream/chat/android/compose/ui/theme/StreamDimens {
public static final field $stable I
public static final field Companion Lio/getstream/chat/android/compose/ui/theme/StreamDimens$Companion;
public synthetic fun <init> (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFIILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFLkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFIILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFLkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1-D9Ej5fM ()F
public final fun component10-D9Ej5fM ()F
public final fun component11-D9Ej5fM ()F
Expand Down Expand Up @@ -2255,12 +2266,13 @@ public final class io/getstream/chat/android/compose/ui/theme/StreamDimens {
public final fun component50-D9Ej5fM ()F
public final fun component51-D9Ej5fM ()F
public final fun component52-D9Ej5fM ()F
public final fun component53-D9Ej5fM ()F
public final fun component6-D9Ej5fM ()F
public final fun component7-D9Ej5fM ()F
public final fun component8-D9Ej5fM ()F
public final fun component9-D9Ej5fM ()F
public final fun copy-EfCTRKU (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)Lio/getstream/chat/android/compose/ui/theme/StreamDimens;
public static synthetic fun copy-EfCTRKU$default (Lio/getstream/chat/android/compose/ui/theme/StreamDimens;FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFIILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/theme/StreamDimens;
public final fun copy-m-3Q45M (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)Lio/getstream/chat/android/compose/ui/theme/StreamDimens;
public static synthetic fun copy-m-3Q45M$default (Lio/getstream/chat/android/compose/ui/theme/StreamDimens;FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFIILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/theme/StreamDimens;
public fun equals (Ljava/lang/Object;)Z
public final fun getAttachmentsContentFileUploadWidth-D9Ej5fM ()F
public final fun getAttachmentsContentFileWidth-D9Ej5fM ()F
Expand All @@ -2278,6 +2290,7 @@ public final class io/getstream/chat/android/compose/ui/theme/StreamDimens {
public final fun getAttachmentsContentVideoMaxHeight-D9Ej5fM ()F
public final fun getAttachmentsContentVideoWidth-D9Ej5fM ()F
public final fun getAttachmentsPickerHeight-D9Ej5fM ()F
public final fun getAttachmentsSystemPickerHeight-D9Ej5fM ()F
public final fun getChannelAvatarSize-D9Ej5fM ()F
public final fun getChannelItemHorizontalPadding-D9Ej5fM ()F
public final fun getChannelItemVerticalPadding-D9Ej5fM ()F
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,11 @@ public fun BoxScope.AttachmentsPickerMenu(
var isFullScreenContent by rememberSaveable { mutableStateOf(false) }
val screenHeight = LocalConfiguration.current.screenHeightDp
val pickerHeight by animateDpAsState(
targetValue = if (isFullScreenContent) screenHeight.dp else ChatTheme.dimens.attachmentsPickerHeight,
targetValue = when {
isFullScreenContent -> screenHeight.dp
ChatTheme.useDefaultSystemMediaPicker -> ChatTheme.dimens.attachmentsSystemPickerHeight
else -> ChatTheme.dimens.attachmentsPickerHeight
},
label = "full sized picker animation",
)

Expand Down
Loading

0 comments on commit edf3ba9

Please sign in to comment.