-
Notifications
You must be signed in to change notification settings - Fork 298
Expand file tree
/
Copy pathuseChannelPreviewInfo.ts
More file actions
90 lines (78 loc) · 2.81 KB
/
Copy pathuseChannelPreviewInfo.ts
File metadata and controls
90 lines (78 loc) · 2.81 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
import { useMemo } from 'react';
import type { Channel, StateStore } from 'stream-chat';
import { useStateStore } from '../../../store';
import type { GroupChannelDisplayInfo } from '../utils';
export type ChannelPreviewInfoParams = {
/** Channel to read display info from; when undefined, returns undefined display title/image */
channel?: Channel;
/** Manually set the image to render, defaults to the Channel image */
overrideImage?: string;
/** Set title manually */
overrideTitle?: string;
};
/** ChannelState with reactive display and members stores (stream-chat-js) */
type ChannelStateWithStores = {
displayStore?: {
getLatestValue(): { displayName: string | null; displayImage: string | null };
};
membersStore?: {
getLatestValue(): {
members: Record<string, { user?: { name?: string; image?: string } }>;
};
};
};
const displayStoreSelector = (s: {
displayName: string | null;
displayImage: string | null;
}) => ({
displayImage: s.displayImage,
displayName: s.displayName,
});
type MembersState = {
members: Record<string, { user?: { name?: string; image?: string } }>;
};
function buildGroupChannelDisplayInfo(
s: MembersState | undefined,
): GroupChannelDisplayInfo {
if (!s?.members) return { members: [], overflowCount: undefined };
const memberList = (Object.values(s.members) as MembersState['members'][string][])
.filter((m) => m.user?.name || m.user?.image)
.map((m) => ({ imageUrl: m.user?.image, userName: m.user?.name }));
if (memberList.length <= 2) return { members: [], overflowCount: undefined };
return {
members: memberList,
overflowCount: memberList.length > 4 ? memberList.length - 2 : undefined,
};
}
export const useChannelPreviewInfo = (props: ChannelPreviewInfoParams) => {
const { channel, overrideImage, overrideTitle } = props;
const channelState = (channel?.state ?? undefined) as
| ChannelStateWithStores
| undefined;
const displayFromStore = useStateStore(
(channelState?.displayStore ?? undefined) as
| StateStore<{ displayName: string | null; displayImage: string | null }>
| undefined,
displayStoreSelector,
);
const groupChannelDisplayInfo = useStateStore(
(channelState?.membersStore ?? undefined) as
| StateStore<{
members: Record<string, { user?: { name?: string; image?: string } }>;
}>
| undefined,
buildGroupChannelDisplayInfo,
);
const displayTitleResolved =
overrideTitle ?? displayFromStore?.displayName ?? undefined;
const displayImageResolved =
overrideImage ?? displayFromStore?.displayImage ?? undefined;
return useMemo(
() => ({
displayImage: displayImageResolved,
displayTitle: displayTitleResolved,
groupChannelDisplayInfo,
}),
[displayImageResolved, displayTitleResolved, groupChannelDisplayInfo],
);
};