Skip to content
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: 1 addition & 1 deletion package/src/components/MessageInput/MessageInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,13 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => {
isOnline,
members,
Reply,
threadList,
SendButton,
sendMessage,
showPollCreationDialog,
ShowThreadMessageInChannelButton,
StartAudioRecordingButton,
StopMessageStreamingButton,
threadList,
watchers,
} = props;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,60 +1,35 @@
import React from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import React, { useCallback } from 'react';
import { Pressable, StyleSheet, Text, View } from 'react-native';

import {
MessageInputContextValue,
useMessageInputContext,
} from '../../contexts/messageInputContext/MessageInputContext';
import { MessageComposerState } from 'stream-chat';

import { ChannelContextValue } from '../../contexts/channelContext/ChannelContext';
import { useMessageComposer } from '../../contexts/messageInputContext/hooks/useMessageComposer';
import { useTheme } from '../../contexts/themeContext/ThemeContext';
import { ThreadContextValue, useThreadContext } from '../../contexts/threadContext/ThreadContext';
import {
TranslationContextValue,
useTranslationContext,
} from '../../contexts/translationContext/TranslationContext';
import { useStateStore } from '../../hooks/useStateStore';
import { Check } from '../../icons';

const styles = StyleSheet.create({
checkBox: {
alignItems: 'center',
borderRadius: 3,
borderWidth: 2,
height: 16,
justifyContent: 'center',
width: 16,
},
container: {
flexDirection: 'row',
marginHorizontal: 2,
marginTop: 8,
},
innerContainer: {
flexDirection: 'row',
},
text: {
fontSize: 13,
marginLeft: 12,
},
const stateSelector = (state: MessageComposerState) => ({
showReplyInChannel: state.showReplyInChannel,
});

export type ShowThreadMessageInChannelButtonWithContextProps = Pick<
MessageInputContextValue,
'sendThreadMessageInChannel' | 'setSendThreadMessageInChannel'
ThreadContextValue,
'allowThreadMessagesInChannel'
> &
Pick<ThreadContextValue, 'allowThreadMessagesInChannel'> &
Pick<TranslationContextValue, 't'> & {
threadList?: boolean;
};
Pick<TranslationContextValue, 't'> & { threadList?: ChannelContextValue['threadList'] };

export const ShowThreadMessageInChannelButtonWithContext = (
props: ShowThreadMessageInChannelButtonWithContextProps,
) => {
const {
allowThreadMessagesInChannel,
sendThreadMessageInChannel,
setSendThreadMessageInChannel,
t,
threadList,
} = props;
const { allowThreadMessagesInChannel, t, threadList } = props;
const messageComposer = useMessageComposer();
const { showReplyInChannel } = useStateStore(messageComposer.state, stateSelector);

const {
theme: {
Expand All @@ -72,20 +47,22 @@ export const ShowThreadMessageInChannelButtonWithContext = (
},
} = useTheme();

const onPressHandler = useCallback(() => {
messageComposer.toggleShowReplyInChannel();
}, [messageComposer]);

if (!threadList || !allowThreadMessagesInChannel) {
return null;
}

return (
<View style={[styles.container, container]} testID='show-thread-message-in-channel-button'>
<TouchableOpacity
onPress={() => setSendThreadMessageInChannel((prevSendInChannel) => !prevSendInChannel)}
>
<Pressable onPress={onPressHandler} style={({ pressed }) => ({ opacity: pressed ? 0.8 : 1 })}>
<View style={[styles.innerContainer, innerContainer]}>
<View
style={[
styles.checkBox,
sendThreadMessageInChannel
showReplyInChannel
? {
backgroundColor: accent_blue,
borderColor: accent_blue,
Expand All @@ -94,15 +71,13 @@ export const ShowThreadMessageInChannelButtonWithContext = (
: { borderColor: grey, ...checkBoxInactive },
]}
>
{sendThreadMessageInChannel && (
<Check height={16} pathFill={white} width={16} {...check} />
)}
{showReplyInChannel && <Check height={16} pathFill={white} width={16} {...check} />}
</View>
<Text style={[styles.text, { color: grey }, text]}>
{t<string>('Also send to channel')}
</Text>
</View>
</TouchableOpacity>
</Pressable>
</View>
);
};
Expand All @@ -113,13 +88,11 @@ const areEqual = (
) => {
const {
allowThreadMessagesInChannel: prevAllowThreadMessagesInChannel,
sendThreadMessageInChannel: prevSendThreadMessageInChannel,
t: prevT,
threadList: prevThreadList,
} = prevProps;
const {
allowThreadMessagesInChannel: nextAllowThreadMessagesInChannel,
sendThreadMessageInChannel: nexSendThreadMessageInChannel,
t: nextT,
threadList: nextThreadList,
} = nextProps;
Expand All @@ -129,12 +102,6 @@ const areEqual = (
return false;
}

const sendThreadMessageInChannelEqual =
prevSendThreadMessageInChannel === nexSendThreadMessageInChannel;
if (!sendThreadMessageInChannelEqual) {
return false;
}

const threadListEqual = prevThreadList === nextThreadList;
if (!threadListEqual) {
return false;
Expand All @@ -160,14 +127,11 @@ export type ShowThreadMessageInChannelButtonProps =
export const ShowThreadMessageInChannelButton = (props: ShowThreadMessageInChannelButtonProps) => {
const { t } = useTranslationContext();
const { allowThreadMessagesInChannel } = useThreadContext();
const { sendThreadMessageInChannel, setSendThreadMessageInChannel } = useMessageInputContext();

return (
<MemoizedShowThreadMessageInChannelButton
{...{
allowThreadMessagesInChannel,
sendThreadMessageInChannel,
setSendThreadMessageInChannel,
t,
}}
{...props}
Expand All @@ -177,3 +141,26 @@ export const ShowThreadMessageInChannelButton = (props: ShowThreadMessageInChann

ShowThreadMessageInChannelButton.displayName =
'ShowThreadMessageInChannelButton{messageInput{showThreadMessageInChannelButton}}';

const styles = StyleSheet.create({
checkBox: {
alignItems: 'center',
borderRadius: 3,
borderWidth: 2,
height: 16,
justifyContent: 'center',
width: 16,
},
container: {
flexDirection: 'row',
marginHorizontal: 2,
marginTop: 8,
},
innerContainer: {
flexDirection: 'row',
},
text: {
fontSize: 13,
marginLeft: 12,
},
});
29 changes: 6 additions & 23 deletions package/src/contexts/messageInputContext/MessageInputContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {
LegacyRef,
PropsWithChildren,
Ref,
useCallback,
useContext,
useEffect,
Expand All @@ -15,7 +15,6 @@ import {
// createCommandStringExtractionMiddleware,
// createDraftCommandInjectionMiddleware,
LocalMessage,
Message,
MessageComposer,
SendMessageOptions,
StreamChat,
Expand Down Expand Up @@ -89,7 +88,7 @@ export type LocalMessageInputContext = {
/** The time at which the active cooldown will end */
cooldownEndsAt: Date;

inputBoxRef: React.MutableRefObject<TextInput | null>;
inputBoxRef: React.RefObject<TextInput | null>;
openAttachmentPicker: () => void;
openFilePicker: () => void;
/**
Expand All @@ -98,13 +97,11 @@ export type LocalMessageInputContext = {
pickAndUploadImageFromNativePicker: () => Promise<void>;
pickFile: () => Promise<void>;
selectedPicker?: 'images';
sendMessage: (params?: { customMessageData?: Partial<Message> }) => Promise<void>;
sendThreadMessageInChannel: boolean;
sendMessage: () => Promise<void>;
/**
* Ref callback to set reference on input box
*/
setInputBoxRef: LegacyRef<TextInput> | undefined;
setSendThreadMessageInChannel: React.Dispatch<React.SetStateAction<boolean>>;
setInputBoxRef: Ref<TextInput> | undefined;
/**
* Function for taking a photo and uploading it
*/
Expand Down Expand Up @@ -439,7 +436,6 @@ export const MessageInputProvider = ({
const { t } = useTranslationContext();
const inputBoxRef = useRef<TextInput | null>(null);

const [sendThreadMessageInChannel, setSendThreadMessageInChannel] = useState(false);
const [showPollCreationDialog, setShowPollCreationDialog] = useState(false);

const defaultOpenPollCreationDialog = useCallback(() => setShowPollCreationDialog(true), []);
Expand All @@ -453,11 +449,6 @@ export const MessageInputProvider = ({
const { attachmentManager, editedMessage } = messageComposer;
const { availableUploadSlots } = useAttachmentManagerState();

const threadId = thread?.id;
useEffect(() => {
setSendThreadMessageInChannel(false);
}, [threadId]);

/**
* These are the RN SDK specific middlewares that are added to the message composer to provide the default behaviour.
* TODO: Discuss and decide if we provide them by default in the SDK or leave it to the user to add them if they want the feature.
Expand Down Expand Up @@ -638,14 +629,8 @@ export const MessageInputProvider = ({
messageComposer.clear();
}
await value.sendMessage({
localMessage: {
...localMessage,
show_in_channel: sendThreadMessageInChannel || undefined,
},
message: {
...message,
show_in_channel: sendThreadMessageInChannel || undefined,
},
localMessage,
message,
options: sendOptions,
});
} catch (error) {
Expand Down Expand Up @@ -697,9 +682,7 @@ export const MessageInputProvider = ({
openFilePicker: pickFile,
pickAndUploadImageFromNativePicker,
pickFile,
sendThreadMessageInChannel,
setInputBoxRef,
setSendThreadMessageInChannel,
takeAndUploadImage,
thread,
toggleAttachmentPicker,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,8 @@ export const useCreateMessageInputContext = ({
SendButton,
sendMessage,
SendMessageDisallowedIndicator,
sendThreadMessageInChannel,
setInputBoxRef,
setInputRef,
setSendThreadMessageInChannel,
showPollCreationDialog,
ShowThreadMessageInChannelButton,
StartAudioRecordingButton,
Expand Down Expand Up @@ -143,10 +141,8 @@ export const useCreateMessageInputContext = ({
SendButton,
sendMessage,
SendMessageDisallowedIndicator,
sendThreadMessageInChannel,
setInputBoxRef,
setInputRef,
setSendThreadMessageInChannel,
showPollCreationDialog,
ShowThreadMessageInChannelButton,
StartAudioRecordingButton,
Expand All @@ -158,14 +154,7 @@ export const useCreateMessageInputContext = ({
VideoRecorderSelectorIcon,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[
cooldownEndsAt,
isCommandUIEnabled,
sendThreadMessageInChannel,
threadId,
showPollCreationDialog,
selectedPicker,
],
[cooldownEndsAt, isCommandUIEnabled, threadId, showPollCreationDialog, selectedPicker],
);

return messageInputContext;
Expand Down
Loading