Skip to content

Commit 60d4d66

Browse files
committed
feat: implement show in channel button
1 parent c2bc36d commit 60d4d66

File tree

13 files changed

+153
-102
lines changed

13 files changed

+153
-102
lines changed

package/src/components/AutoCompleteInput/AutoCompleteInput.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ const useStyles = () => {
252252
paddingLeft: 16,
253253
paddingVertical: 12,
254254
textAlignVertical: 'center', // for android vertical text centering
255+
alignSelf: 'center',
255256
},
256257
});
257258
}, [semantics]);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
import { StyleSheet, View } from 'react-native';
3+
4+
import { AutoCompleteInput } from './AutoCompleteInput';
5+
6+
import { CommandChip } from '../MessageInput/CommandChip';
7+
import { ShowThreadMessageInChannelButton } from '../MessageInput/ShowThreadMessageInChannelButton';
8+
9+
type InputViewProps = React.ComponentProps<typeof AutoCompleteInput>;
10+
11+
export const InputView = (props: InputViewProps) => (
12+
<View style={styles.container}>
13+
<View style={styles.inputRow}>
14+
<CommandChip />
15+
<AutoCompleteInput {...props} />
16+
</View>
17+
<ShowThreadMessageInChannelButton />
18+
</View>
19+
);
20+
21+
const styles = StyleSheet.create({
22+
container: {
23+
flex: 1,
24+
},
25+
inputRow: {
26+
flexDirection: 'row',
27+
},
28+
});

package/src/components/Channel/Channel.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ import { CooldownTimer as CooldownTimerDefault } from '../MessageInput/component
190190
import { SendButton as SendButtonDefault } from '../MessageInput/components/OutputButtons/SendButton';
191191
import { MessageComposerLeadingView as MessageComposerLeadingViewDefault } from '../MessageInput/MessageComposerLeadingView';
192192
import { MessageComposerTrailingView as MessageComposerTrailingViewDefault } from '../MessageInput/MessageComposerTrailingView';
193+
import { MessageInputFooterView as MessageInputFooterViewDefault } from '../MessageInput/MessageInputFooterView';
193194
import { MessageInputHeaderView as MessageInputHeaderViewDefault } from '../MessageInput/MessageInputHeaderView';
194195
import { MessageInputLeadingView as MessageInputLeadingViewDefault } from '../MessageInput/MessageInputLeadingView';
195196
import { MessageInputTrailingView as MessageInputTrailingViewDefault } from '../MessageInput/MessageInputTrailingView';
@@ -702,6 +703,7 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
702703
MessageDeleted = MessageDeletedDefault,
703704
MessageError = MessageErrorDefault,
704705
messageInputFloating = false,
706+
MessageInputFooterView = MessageInputFooterViewDefault,
705707
MessageInputHeaderView = MessageInputHeaderViewDefault,
706708
MessageInputLeadingView = MessageInputLeadingViewDefault,
707709
MessageInputTrailingView = MessageInputTrailingViewDefault,
@@ -1889,6 +1891,7 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
18891891
MessageComposerTrailingView,
18901892
messageInputFloating,
18911893
messageInputHeightStore,
1894+
MessageInputFooterView,
18921895
MessageInputHeaderView,
18931896
MessageInputLeadingView,
18941897
MessageInputTrailingView,

package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const useCreateInputMessageInputContext = ({
5050
MessageComposerTrailingView,
5151
messageInputFloating,
5252
messageInputHeightStore,
53+
MessageInputFooterView,
5354
MessageInputHeaderView,
5455
MessageInputLeadingView,
5556
MessageInputTrailingView,
@@ -117,6 +118,7 @@ export const useCreateInputMessageInputContext = ({
117118
MessageComposerTrailingView,
118119
messageInputFloating,
119120
messageInputHeightStore,
121+
MessageInputFooterView,
120122
MessageInputHeaderView,
121123
MessageInputLeadingView,
122124
MessageInputTrailingView,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React, { useEffect } from 'react';
2+
import { StyleSheet } from 'react-native';
3+
4+
import Animated, { LinearTransition, ZoomIn, ZoomOut } from 'react-native-reanimated';
5+
6+
import { textComposerStateSelector } from './utils/messageComposerSelectors';
7+
8+
import { useMessageComposer } from '../../contexts/messageInputContext/hooks/useMessageComposer';
9+
import { useStateStore } from '../../hooks/useStateStore';
10+
import { primitives } from '../../theme';
11+
import { GiphyChip } from '../ui/GiphyChip';
12+
13+
export const CommandChip = () => {
14+
const messageComposer = useMessageComposer();
15+
const { textComposer, attachmentManager } = messageComposer;
16+
const { command } = useStateStore(textComposer.state, textComposerStateSelector);
17+
18+
useEffect(() => {
19+
if (attachmentManager.state.getLatestValue().attachments.length > 0) {
20+
textComposer.clearCommand();
21+
}
22+
}, [textComposer, attachmentManager]);
23+
24+
return command ? (
25+
<Animated.View
26+
entering={ZoomIn.duration(200)}
27+
exiting={ZoomOut.duration(200)}
28+
layout={LinearTransition.duration(200)}
29+
style={styles.giphyContainer}
30+
>
31+
<GiphyChip />
32+
</Animated.View>
33+
) : null;
34+
};
35+
36+
const styles = StyleSheet.create({
37+
giphyContainer: {
38+
padding: primitives.spacingSm,
39+
alignSelf: 'flex-end',
40+
},
41+
});

package/src/components/MessageInput/MessageInput.tsx

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,8 @@ import { useStateStore } from '../../hooks/useStateStore';
5454
import { AudioRecorderManagerState } from '../../state-store/audio-recorder-manager';
5555
import { MessageInputHeightState } from '../../state-store/message-input-height-store';
5656
import { primitives } from '../../theme';
57-
import {
58-
AutoCompleteInput,
59-
type TextInputOverrideComponent,
60-
} from '../AutoCompleteInput/AutoCompleteInput';
57+
import { type TextInputOverrideComponent } from '../AutoCompleteInput/AutoCompleteInput';
58+
import { InputView } from '../AutoCompleteInput/InputView';
6159
import { CreatePoll } from '../Poll/CreatePollContent';
6260
import { PortalWhileClosingView } from '../UIComponents/PortalWhileClosingView';
6361
import { SafeAreaViewWrapper } from '../UIComponents/SafeAreaViewWrapper';
@@ -153,7 +151,7 @@ const useStyles = () => {
153151
};
154152

155153
type MessageInputPropsWithContext = Pick<ChatContextValue, 'isOnline'> &
156-
Pick<ChannelContextValue, 'channel' | 'members' | 'threadList' | 'watchers'> &
154+
Pick<ChannelContextValue, 'channel' | 'members' | 'watchers'> &
157155
Pick<
158156
MessageInputContextValue,
159157
| 'audioRecorderManager'
@@ -179,10 +177,8 @@ type MessageInputPropsWithContext = Pick<ChatContextValue, 'isOnline'> &
179177
| 'messageInputFloating'
180178
| 'messageInputHeightStore'
181179
| 'MessageInputHeaderView'
182-
| 'MessageInputLeadingView'
183180
| 'MessageInputTrailingView'
184181
| 'SendButton'
185-
| 'ShowThreadMessageInChannelButton'
186182
| 'StartAudioRecordingButton'
187183
| 'uploadNewFile'
188184
| 'openPollCreationDialog'
@@ -228,16 +224,13 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => {
228224
messageInputFloating,
229225
messageInputHeightStore,
230226
MessageInputHeaderView,
231-
MessageInputLeadingView,
232227
MessageInputTrailingView,
233228
Input,
234229
inputBoxRef,
235230
isKeyboardVisible,
236231
members,
237-
threadList,
238232
sendMessage,
239233
showPollCreationDialog,
240-
ShowThreadMessageInChannelButton,
241234
TextInputComponent,
242235
watchers,
243236
micLocked,
@@ -451,14 +444,10 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => {
451444
{!isRecordingStateIdle ? (
452445
<AudioRecorder slideToCancelStyle={slideToCancelAnimatedStyle} />
453446
) : (
454-
<>
455-
<MessageInputLeadingView />
456-
457-
<AutoCompleteInput
458-
TextInputComponent={TextInputComponent}
459-
{...additionalTextInputProps}
460-
/>
461-
</>
447+
<InputView
448+
TextInputComponent={TextInputComponent}
449+
{...additionalTextInputProps}
450+
/>
462451
)}
463452

464453
<MessageInputTrailingView />
@@ -467,7 +456,6 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => {
467456
</Animated.View>
468457
</View>
469458
)}
470-
<ShowThreadMessageInChannelButton threadList={threadList} />
471459
{!isRecordingStateIdle ? (
472460
<View
473461
style={[
@@ -538,7 +526,6 @@ const areEqual = (
538526
openPollCreationDialog: prevOpenPollCreationDialog,
539527
showPollCreationDialog: prevShowPollCreationDialog,
540528
t: prevT,
541-
threadList: prevThreadList,
542529
micLocked: prevMicLocked,
543530
isRecordingStateIdle: prevIsRecordingStateIdle,
544531
recordingStatus: prevRecordingStatus,
@@ -558,7 +545,6 @@ const areEqual = (
558545
openPollCreationDialog: nextOpenPollCreationDialog,
559546
showPollCreationDialog: nextShowPollCreationDialog,
560547
t: nextT,
561-
threadList: nextThreadList,
562548
micLocked: nextMicLocked,
563549
isRecordingStateIdle: nextIsRecordingStateIdle,
564550
recordingStatus: nextRecordingStatus,
@@ -627,11 +613,6 @@ const areEqual = (
627613
return false;
628614
}
629615

630-
const threadListEqual = prevThreadList === nextThreadList;
631-
if (!threadListEqual) {
632-
return false;
633-
}
634-
635616
const micLockedEqual = prevMicLocked === nextMicLocked;
636617
if (!micLockedEqual) {
637618
return false;
@@ -670,7 +651,7 @@ export const MessageInput = (props: MessageInputProps) => {
670651
const { isOnline } = useChatContext();
671652
const ownCapabilities = useOwnCapabilitiesContext();
672653

673-
const { channel, members, threadList, watchers } = useChannelContext();
654+
const { channel, members, watchers } = useChannelContext();
674655

675656
const {
676657
audioRecorderManager,
@@ -699,14 +680,12 @@ export const MessageInput = (props: MessageInputProps) => {
699680
messageInputFloating,
700681
messageInputHeightStore,
701682
MessageInputHeaderView,
702-
MessageInputLeadingView,
703683
MessageInputTrailingView,
704684
openPollCreationDialog,
705685
SendButton,
706686
sendMessage,
707687
SendMessageDisallowedIndicator,
708688
showPollCreationDialog,
709-
ShowThreadMessageInChannelButton,
710689
StartAudioRecordingButton,
711690
StopMessageStreamingButton,
712691
uploadNewFile,
@@ -771,19 +750,16 @@ export const MessageInput = (props: MessageInputProps) => {
771750
messageInputFloating,
772751
messageInputHeightStore,
773752
MessageInputHeaderView,
774-
MessageInputLeadingView,
775753
MessageInputTrailingView,
776754
openPollCreationDialog,
777755
Reply,
778756
SendButton,
779757
sendMessage,
780758
SendMessageDisallowedIndicator,
781759
showPollCreationDialog,
782-
ShowThreadMessageInChannelButton,
783760
StartAudioRecordingButton,
784761
StopMessageStreamingButton,
785762
t,
786-
threadList,
787763
uploadNewFile,
788764
watchers,
789765
}}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const MessageInputFooterView = () => {
2+
return null;
3+
};
Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1 @@
1-
import React, { useEffect } from 'react';
2-
import { StyleSheet } from 'react-native';
3-
4-
import Animated, { LinearTransition, ZoomIn, ZoomOut } from 'react-native-reanimated';
5-
6-
import { textComposerStateSelector } from './utils/messageComposerSelectors';
7-
8-
import { useMessageComposer } from '../../contexts/messageInputContext/hooks/useMessageComposer';
9-
import { useStateStore } from '../../hooks/useStateStore';
10-
import { primitives } from '../../theme';
11-
import { GiphyChip } from '../ui/GiphyChip';
12-
13-
export const MessageInputLeadingView = () => {
14-
const messageComposer = useMessageComposer();
15-
const { textComposer, attachmentManager } = messageComposer;
16-
const { command } = useStateStore(textComposer.state, textComposerStateSelector);
17-
18-
useEffect(() => {
19-
if (attachmentManager.state.getLatestValue().attachments.length > 0) {
20-
textComposer.clearCommand();
21-
}
22-
}, [textComposer, attachmentManager]);
23-
24-
return command ? (
25-
<Animated.View
26-
entering={ZoomIn.duration(200)}
27-
exiting={ZoomOut.duration(200)}
28-
layout={LinearTransition.duration(200)}
29-
style={styles.giphyContainer}
30-
>
31-
<GiphyChip />
32-
</Animated.View>
33-
) : null;
34-
};
35-
36-
const styles = StyleSheet.create({
37-
giphyContainer: {
38-
padding: primitives.spacingSm,
39-
alignSelf: 'flex-end',
40-
},
41-
});
1+
export const MessageInputLeadingView = () => null;

package/src/components/MessageInput/MessageInputTrailingView.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from 'react';
2-
import { StyleSheet, View } from 'react-native';
2+
import { StyleSheet } from 'react-native';
3+
4+
import Animated, { LinearTransition } from 'react-native-reanimated';
35

46
import { OutputButtons } from './components/OutputButtons';
57

@@ -22,9 +24,12 @@ export const MessageInputTrailingView = () => {
2224
audioRecorderSelector,
2325
);
2426
return (recordingStatus === 'idle' || recordingStatus === 'recording') && !micLocked ? (
25-
<View style={[styles.outputButtonsContainer, outputButtonsContainer]}>
27+
<Animated.View
28+
layout={LinearTransition.duration(200)}
29+
style={[styles.outputButtonsContainer, outputButtonsContainer]}
30+
>
2631
<OutputButtons />
27-
</View>
32+
</Animated.View>
2833
) : null;
2934
};
3035

0 commit comments

Comments
 (0)