-
Notifications
You must be signed in to change notification settings - Fork 298
Expand file tree
/
Copy pathApp.tsx
More file actions
116 lines (102 loc) · 3.16 KB
/
App.tsx
File metadata and controls
116 lines (102 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { useEffect } from 'react';
import {
ChannelFilters,
ChannelOptions,
ChannelSort,
LocalMessage,
TextComposerMiddleware,
} from 'stream-chat';
import {
AIStateIndicator,
Channel,
ChannelAvatar,
ChannelHeader,
ChannelList,
Chat,
ChatView,
MessageInput,
SendButtonProps,
Thread,
ThreadList,
useCreateChatClient,
useMessageComposer,
VirtualizedMessageList as MessageList,
Window,
} from 'stream-chat-react';
import { createTextComposerEmojiMiddleware } from 'stream-chat-react/emojis';
import { init, SearchIndex } from 'emoji-mart';
import data from '@emoji-mart/data';
init({ data });
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, property) => searchParams.get(property as string),
}) as unknown as Record<string, string | null>;
const parseUserIdFromToken = (token: string) => {
const [, payload] = token.split('.');
if (!payload) throw new Error('Token is missing');
return JSON.parse(atob(payload))?.user_id;
};
const apiKey = params.key ?? (import.meta.env.VITE_STREAM_KEY as string);
const userToken = params.ut ?? (import.meta.env.VITE_USER_TOKEN as string);
const userId = parseUserIdFromToken(userToken);
const filters: ChannelFilters = {
members: { $in: [userId] },
type: 'messaging',
archived: false,
};
const options: ChannelOptions = { limit: 5, presence: true, state: true };
const sort: ChannelSort = { pinned_at: 1, last_message_at: -1, updated_at: -1 };
// @ts-ignore
const isMessageAIGenerated = (message: LocalMessage) => !!message?.ai_generated;
const App = () => {
const chatClient = useCreateChatClient({
apiKey,
tokenOrProvider: userToken,
userData: { id: userId },
});
useEffect(() => {
if (!chatClient) return;
chatClient.setMessageComposerSetupFunction(({ composer }) => {
composer.textComposer.middlewareExecutor.insert({
middleware: [
createTextComposerEmojiMiddleware(SearchIndex) as TextComposerMiddleware,
],
position: { before: 'stream-io/text-composer/mentions-middleware' },
unique: true,
});
});
}, [chatClient]);
if (!chatClient) return <>Loading...</>;
return (
<Chat client={chatClient} isMessageAIGenerated={isMessageAIGenerated}>
<ChatView>
<ChatView.Selector />
<ChatView.Channels>
<ChannelList
Avatar={ChannelAvatar}
filters={filters}
options={options}
sort={sort}
showChannelSearch
additionalChannelSearchProps={{ searchForChannels: true }}
/>
<Channel emojiSearchIndex={SearchIndex}>
<Window>
<ChannelHeader Avatar={ChannelAvatar} />
<MessageList returnAllReadData />
<AIStateIndicator />
<MessageInput focus audioRecordingEnabled />
</Window>
<Thread virtualized />
</Channel>
</ChatView.Channels>
<ChatView.Threads>
<ThreadList />
<ChatView.ThreadAdapter>
<Thread virtualized />
</ChatView.ThreadAdapter>
</ChatView.Threads>
</ChatView>
</Chat>
);
};
export default App;