stream-chat-react icon indicating copy to clipboard operation
stream-chat-react copied to clipboard

overrideSubmitHandler not called when dragAndDropWindow is true

Open rvanlaarhoven opened this issue 3 years ago • 8 comments

I'm trying to encrypt messages before sending them, but noticed that the overrideSubmitHandler on the MessageInput is never called when dragAndDropWindow is marked as true on the Channel component. It's being caused by this line: https://github.com/GetStream/stream-chat-react/blob/0651fe693ef8752bf5453b05d7fb9e033cf17d01/src/components/MessageInput/MessageInput.tsx#L124

I still want to allow users to drag-and-drop files, so I'm not really sure how to work around this problem. Is there a specific reason why the MessageInputProvider is not used when drag and drop is enabled? And is there a potential workaround?

rvanlaarhoven avatar Mar 11 '22 07:03 rvanlaarhoven

Had a look through the commit that introduced the change (https://github.com/GetStream/stream-chat-react/commit/528d56465fd2f099dcc19a1a04e3aa357cc1a53e) and found that I could use the optionalMessageInputProps on the Channel.

This works, but the problem now is that I need to depend on the useChannelActionContext to access the sendMessage, which is not accessible outside of the Channel context.

Would it make sense to pass the sendMessage (or the whole Channel action context) as a third argument to the overrideSubmitHandler? Or maybe introduce a transformMessage prop on the MessageInput.

rvanlaarhoven avatar Mar 11 '22 08:03 rvanlaarhoven

Hi @rvanlaarhoven thanks for submitting this issue, and we can look into this!

In the meantime, you can use the the optionalMessageInputProps on Channel, and then are you able to create a ChannelInner component that contains all of the components within, including your submit handler? This ensures you're within the correct Contexts.

<Channel>
  <ChannelInner />
</Channel>

ambaldwin avatar Mar 11 '22 19:03 ambaldwin

Thanks for the reply @ambaldwin . I'm not sure if I understand what you mean by "including your submit handler". How can I add a submit handler in the ChannelInner component?

I tried the example below which does not work because when I pass the overrideSubmitHandler to optionalMessageInputProps, the callback will be outside of the Channel context:

const Component = () => {
  const { sendMessage } = useChannelActionContext()
  const overrideSubmitHandler = (message) => {
    message.text = 'Encrypted message'

    // This sendMessage won't  work, because its outside of the channel context
    sendMessage(message)
  }
  return (
    <Channel optionalMessageInputProps={{ overrideSubmitHandler }}>
      <ChannelInner />
    </Channel>
  )
}

rvanlaarhoven avatar Mar 12 '22 12:03 rvanlaarhoven

@rvanlaarhoven the solution they advise here is the following:

Use a ref in your "Component" e.g const sendMessageRef = useRef<TSendMessageRef>(null);;

create a component which just has the job of assigning the sendMessageRef:

const SendMessageCapture: FC<ISendMessageCaptureProps> = ({
  sendMessageRef,
}) => {
  const { sendMessage } = useChannelActionContext();
  useEffect(() => {
    sendMessageRef.current = sendMessage;
    return () => {
      sendMessageRef.current = null;
    };
  }, []);
  return null;
};

Then inside the render of Component do the following

...
<Channel>
    <SendMessageCapture sendMessageRef={sendMessageRef} />
</Channel>
...

Then you can have an override function like:

const overrideSubmitHandler = (message) => {
    message.text = 'Encrypted message'
    // This sendMessage will work as it is assigned by a component inside of the channel context
    sendMessageRef.current?.sendMessage?.(message)
  }

joelpierre avatar Jan 19 '23 09:01 joelpierre

Thanks for the suggestion! That could've been a fine workaround.

We eventually went with the overrideSubmitHandler prop on the MessageInput instead and just disabled drag & drop in favor of our own drag & drop implementation.

rvanlaarhoven avatar Jan 19 '23 10:01 rvanlaarhoven

I found this issue to be similar to mine. I'm attempting to add a new feature to my Q&A management chat. Instead of transforming the message, I want to forward it from one channel to another, but without creating a custom MessageInput component since that's a lot of work for a small change. I found overrideSubmitHandler, which has the channelCId as an argument, but sendMessage won't work for this. So, I think I need to access handleSubmit from useMessageInputContext.

Is there something that I'm overlooking, or will I inevitably need to create a custom MessageInput component?

shroy avatar Apr 17 '23 18:04 shroy

@shroy if you would like to forward a message to a specific channel as a side effect, you can do:

const channel = client.channel(channelType, channelId);
channel.sendMessage(message)

MartinCupela avatar Apr 18 '23 07:04 MartinCupela

@MartinCupela That is easy enough, thanks!

shroy avatar Apr 18 '23 15:04 shroy