Skip to content

[🐛] Image attachment is not rendering properly inside message. #2964

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

Open
Saad-Bashar opened this issue Feb 20, 2025 · 8 comments
Open

[🐛] Image attachment is not rendering properly inside message. #2964

Saad-Bashar opened this issue Feb 20, 2025 · 8 comments

Comments

@Saad-Bashar
Copy link

We are customising the AttachButton as per doc and uploading new images using uploadNewImage. This works fine. However, when the image is attached inside the message list, there is a weird grey view appearing bottom of the image.

Please note that when user goes back and come back to the chat screen again, the image is rendered fine. Only when the image is attached instantly in a message then the issue occurs. I believe this happens mainly when I am taking the picture in Potrait mode.

This is after I attach a photo from camera,
Image

But the image renders fine when I come back to chat,
Image

This is how my code looks,

// Custom attach button component
const CustomAttachButton = () => {
  const {showActionSheetWithOptions} = useActionSheet();
  const {uploadNewImage} = useMessageInputContext();

  const compressAndUploadImage = async imageFile => {
    try {
      const compressedUri = await ImageCompressor.compress(imageFile.uri, {
        compressionMethod: 'auto',
      });

      return uploadNewImage({
        name: imageFile.fileName,
        type: imageFile.type,
        uri: compressedUri,
      });
    } catch (error) {
      // Fallback to original image if compression fails
      return uploadNewImage({
        name: imageFile.fileName,
        type: imageFile.type,
        uri: imageFile.uri,
      });
    }
  };

  const pickImageFromGallery = async () => {
    try {
      const images = await launchImageLibrary({
        selectionLimit: 1,
        mediaType: 'photo',
      });

      if (images?.assets?.length > 0) {
        const selectedImage = images.assets[0];
        await compressAndUploadImage(selectedImage);
      }
    } catch (error) {
      console.error('Error picking image from gallery:', error);
    }
  };

  const pickImageFromCamera = async () => {
    try {
      if (Platform.OS === 'android') {
        const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.CAMERA,
          {
            title: 'Camera Permission',
            message: 'ShiftCare needs camera permission to take photos',
            buttonNeutral: 'Ask Me Later',
            buttonNegative: 'Cancel',
            buttonPositive: 'OK',
          },
        );

        if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
          console.log('Camera permission denied');
          return;
        }
      }

      const images = await launchCamera({
        mediaType: 'photo',
      });

      if (images?.assets?.length > 0) {
        const selectedImage = images.assets[0];
        await compressAndUploadImage(selectedImage);
      }
    } catch (error) {
      console.error('Error picking image from camera:', error);
    }
  };

  const onPress = () => {
    showActionSheetWithOptions(
      {
        cancelButtonIndex: 2,
        destructiveButtonIndex: 2,
        options: ['Photo Library', 'Camera', 'Cancel'],
      },
      buttonIndex => {
        switch (buttonIndex) {
          case 0:
            pickImageFromGallery();
            break;
          case 1:
            pickImageFromCamera();
            break;
          default:
            break;
        }
      },
    );
  };

  return <AttachButton handleOnPress={onPress} />;
};


// Chat component
return (
    <SafeAreaView edges={['bottom']} className="flex-1">
      <ActionSheetProvider>
        <ChannelComponent
          key={channel.cid}
          supportedReactions={supportedReactions}
          hasFilePicker={false}
          MessageFooter={featureReadReceipts ? CustomMessageFooter : () => null}
          CommandsButton={() => null}
          AttachButton={CustomAttachButton}
          channel={channel}>
          <MessageList />
          <MessageInput />
          <BottomSpacing />
        </ChannelComponent>
      </ActionSheetProvider>
    </SafeAreaView>
  );
@khushal87
Copy link
Member

Hey @Saad-Bashar, I tried to triage the issue on my end by sending a similar photo on the Android emulator and capturing the image, but I couldn't reproduce it. I am attaching a video. Do you have any added customization?

Screen.Recording.2025-03-05.at.12.27.03.PM.mov

@khushal87
Copy link
Member

Hey @Saad-Bashar, are you still facing this issue, or can we close it?

@Saad-Bashar
Copy link
Author

Yes, we are still having this issue, unfortunately. This one mostly started to happen when we started to use uploadNewFile instead of the built-in way. We are using react-native-image-picker. We don't have any other customizations. These are the versions,

"@stream-io/flat-list-mvcp": "^0.10.3",
"stream-chat": "^8.44.0",
"stream-chat-react-native": "^5.41.4"

@marijang
Copy link

same problem here

@marijang
Copy link

marijang commented Apr 7, 2025

?

@mach-an
Copy link

mach-an commented May 8, 2025

Same problem here
when I uploaded the picture, this issue occurred.
it didn't do it with that horizontal picture, only occurred in the case I uploaded a vertical picture. I am using iOS Emulator

Image

@kevinmcalear
Copy link

kevinmcalear commented May 11, 2025

I'm having the same issue and have done no UI customization.

@bridgetrosefitz figured out that if you adjust this styling property, it looks better:

theme.messageSimple.gallery = {
    ...theme.messageSimple.gallery,
    galleryItemColumn: {
      justifyContent: "center",
    }
}

But using the sendMessage API still doesn't recognize vertical images, and makes every attached image horizontal:

https://getstream.io/chat/docs/react-native/send_message/#complex-example

"stream-chat-expo": "^6.7.4",

Image

After applying the style fix:

Image

@mach-an
Copy link

mach-an commented May 12, 2025

Hello, @kevinmcalear, thanks for considering my problem

I did like this:

import {defaultTheme} from 'stream-chat-react-native';

const customTheme = {
  ...defaultTheme,
  messageSimple: {
    ...defaultTheme.messageSimple,
    gallery: {
      ...defaultTheme.messageSimple.gallery,
      galleryItemColumn: {
        justifyContent: 'center',
      },
    },
  },
};

  return channel ? (
    <SafeAreaView edges={['top', 'bottom']} style={styles.container}>
      <Header rightButtons={headerIcons} />
      {!loading ? (
        <View style={{flex: 1}}>
          <TouchableOpacity
            onPress={() =>
              navigateToProfile(chatPartnerId || chatPartnerUserId)
            }>
            <View style={styles.partnerHeader}>
              <PartnerHeader
                chatPartnerId={chatPartnerId || chatPartnerUserId}
              />
              <TDText variant="h3" paddingLeft={5}>
                {chatPartnerName} {!clientIsReady ? ' (Pending)' : ''}
              </TDText>
              <OnlineStatus
                status={chatPartnerOnline ? 'online' : 'offline'}
                hasLabel={false}
              />
            </View>
          </TouchableOpacity>
          <KeyboardAvoidingView
            behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
            style={{flex: 1}}
            keyboardVerticalOffset={Platform.OS === 'ios' ? 135 : 120}>
            <Channel
              theme={customTheme} // Pass the custom theme here
              EmptyStateIndicator={CustomEmptyStateIndicator}
              MessageAvatar={() => (
                <TruDateMessageAvatar
                  onPress={() =>
                    navigateToProfile(chatPartnerId || chatPartnerUserId)
                  }
                  userId={chatPartnerId || chatPartnerUserId}
                />
              )}
              channel={channel}
              maxNumberOfFiles={1}
              FileAttachment={ChatFileAttachment}
              allowThreadMessagesInChannel={false}
              reactionListPosition="top"
              ReactionList={CustomReactionList}
              supportedReactions={supportedReactions}
              disableTypingIndicator
              giphyEnabled={false}
              hasCommands={false}
              hasImagePicker={Platform.OS === 'ios' ? true : true}
              AttachButton={CustomAttachButton}
              hasFilePicker={false}
              initialScrollToFirstUnreadMessage
              keyboardVerticalOffset={Platform.OS === 'ios' ? 120 : 100}
              messageId={messageId}
              mentionAllAppUsersEnabled={false}
              autoCompleteTriggerSettings={() => ({})}
              messageActions={({
                isMyMessage,
                copyMessage,
                flagMessage,
                messageReactions,
                retry,
              }) =>
                isMyMessage
                  ? [copyMessage, retry]
                  : [flagMessage, messageReactions]
              }
              NetworkDownIndicator={() => null}>
              <MessageList<StreamChatGenerics> />
              <MessageInput />
            </Channel>
          </KeyboardAvoidingView>
        </View>
      ) : (
        ''
      )}
      <ReportUserActionSheet
        show={showReport}
        userId={(chatPartnerId || chatPartnerUserId)?.replace('-', '|')}
        reportUserName={chatPartnerName || 'user'}
        setIsLoading={setLoading}
        onHide={() => setShowReport(false)}
        onPressSafetyCenter={() => navigation.navigate('SafetyCenter')}
      />
    </SafeAreaView>
  ) : invitationSent ? (
    <View>
      <Text>Invitation to chat was sent and is awaiting acceptance</Text>
    </View>
  ) : null;
};

but this code didn't fix the problem. Please kindly guide me. thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants