Skip to content

Commit 37cf1d0

Browse files
committed
Migrate CreateChannelProvider
1 parent 880a28b commit 37cf1d0

File tree

5 files changed

+108
-41
lines changed

5 files changed

+108
-41
lines changed

src/modules/CreateChannel/components/CreateChannelUI/index.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import './create-channel-ui.scss';
22

33
import React from 'react';
44

5-
import { useCreateChannelContext } from '../../context/CreateChannelProvider';
65
import InviteUsers from '../InviteUsers';
76

87
import SelectChannelType from '../SelectChannelType';
8+
import { useCreateChannel } from '../../context/useCreateChannel';
99

1010
export interface CreateChannelUIProps {
1111
onCancel?(): void;
@@ -16,10 +16,14 @@ const CreateChannel: React.FC<CreateChannelUIProps> = (props: CreateChannelUIPro
1616
const { onCancel, renderStepOne } = props;
1717

1818
const {
19-
step,
20-
setStep,
21-
userListQuery,
22-
} = useCreateChannelContext();
19+
state: {
20+
step,
21+
userListQuery,
22+
},
23+
actions: {
24+
setStep,
25+
},
26+
} = useCreateChannel();
2327

2428
return (
2529
<>

src/modules/CreateChannel/components/InviteUsers/index.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type { GroupChannelCreateParams } from '@sendbird/chat/groupChannel';
44

55
import './invite-users.scss';
66
import { LocalizationContext } from '../../../../lib/LocalizationContext';
7-
import { useCreateChannelContext } from '../../context/CreateChannelProvider';
87
import useSendbirdStateContext from '../../../../hooks/useSendbirdStateContext';
98
import { useMediaQueryContext } from '../../../../lib/MediaQueryContext';
109
import Modal from '../../../../ui/Modal';
@@ -15,6 +14,7 @@ import UserListItem from '../../../../ui/UserListItem';
1514
import { createDefaultUserListQuery, filterUser, setChannelType } from './utils';
1615
import { noop } from '../../../../utils/utils';
1716
import { UserListQuery } from '../../../../types';
17+
import { useCreateChannel } from '../../context/useCreateChannel';
1818

1919
export interface InviteUsersProps {
2020
onCancel?: () => void;
@@ -28,14 +28,16 @@ const InviteUsers: React.FC<InviteUsersProps> = ({
2828
userListQuery,
2929
}: InviteUsersProps) => {
3030
const {
31-
onCreateChannelClick,
32-
onBeforeCreateChannel,
33-
onChannelCreated,
34-
createChannel,
35-
onCreateChannel,
36-
overrideInviteUser,
37-
type,
38-
} = useCreateChannelContext();
31+
state: {
32+
onCreateChannelClick,
33+
onBeforeCreateChannel,
34+
onChannelCreated,
35+
createChannel,
36+
onCreateChannel,
37+
overrideInviteUser,
38+
type,
39+
},
40+
} = useCreateChannel();
3941

4042
const globalStore = useSendbirdStateContext();
4143
const userId = globalStore?.config?.userId;

src/modules/CreateChannel/components/SelectChannelType.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import React, { useContext } from 'react';
33
import * as sendbirdSelectors from '../../../lib/selectors';
44
import useSendbirdStateContext from '../../../hooks/useSendbirdStateContext';
55

6-
import { useCreateChannelContext } from '../context/CreateChannelProvider';
7-
86
import { LocalizationContext } from '../../../lib/LocalizationContext';
97
import Label, { LabelColors, LabelTypography } from '../../../ui/Label';
108
import Icon, { IconTypes, IconColors } from '../../../ui/Icon';
@@ -16,6 +14,7 @@ import {
1614
isSuperGroupChannelEnabled,
1715
} from '../utils';
1816
import { CHANNEL_TYPE } from '../types';
17+
import { useCreateChannel } from '../context/useCreateChannel';
1918

2019
export interface SelectChannelTypeProps {
2120
onCancel?(): void;
@@ -27,11 +26,12 @@ const SelectChannelType: React.FC<SelectChannelTypeProps> = (props: SelectChanne
2726

2827
const sdk = sendbirdSelectors.getSdk(store);
2928

30-
const createChannelProps = useCreateChannelContext();
3129
const {
32-
setStep,
33-
setType,
34-
} = createChannelProps;
30+
actions: {
31+
setStep,
32+
setType,
33+
},
34+
} = useCreateChannel();
3535

3636
const { stringSet } = useContext(LocalizationContext);
3737

src/modules/CreateChannel/context/CreateChannelProvider.tsx

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
1-
import React, { useState } from 'react';
1+
import React, { useEffect, useRef } from 'react';
22
import { User } from '@sendbird/chat';
33
import type {
44
GroupChannel,
55
GroupChannelCreateParams,
66
} from '@sendbird/chat/groupChannel';
77

8-
import { getCreateGroupChannel } from '../../../lib/selectors';
98
import useSendbirdStateContext from '../../../hooks/useSendbirdStateContext';
109
import { CHANNEL_TYPE } from '../types';
1110
import { SendbirdChatType } from '../../../lib/types';
12-
13-
const CreateChannelContext = React.createContext<CreateChannelContextInterface | null>(null);
11+
import { createStore } from '../../../utils/storeManager';
12+
import { useStore } from '../../../hooks/useStore';
13+
14+
const CreateChannelContext = React.createContext<ReturnType<typeof createStore<CreateChannelState>> | null>(null);
15+
16+
const initialState = {
17+
sdk: undefined,
18+
createChannel: undefined,
19+
userListQuery: undefined,
20+
onCreateChannelClick: undefined,
21+
onChannelCreated: undefined,
22+
onBeforeCreateChannel: undefined,
23+
step: 0,
24+
setStep: () => {},
25+
type: CHANNEL_TYPE.GROUP,
26+
setType: () => {},
27+
onCreateChannel: undefined,
28+
overrideInviteUser: undefined,
29+
};
1430

1531
export interface UserListQuery {
1632
hasNext?: boolean;
@@ -56,7 +72,7 @@ export interface CreateChannelProviderProps {
5672

5773
type CreateChannel = (channelParams: GroupChannelCreateParams) => Promise<GroupChannel>;
5874

59-
export interface CreateChannelContextInterface {
75+
export interface CreateChannelState {
6076
sdk: SendbirdChatType;
6177
createChannel: CreateChannel;
6278
userListQuery?(): UserListQuery;
@@ -76,9 +92,7 @@ export interface CreateChannelContextInterface {
7692
onBeforeCreateChannel?(users: Array<string>): GroupChannelCreateParams;
7793

7894
step: number,
79-
setStep: React.Dispatch<React.SetStateAction<number>>,
8095
type: CHANNEL_TYPE,
81-
setType: React.Dispatch<React.SetStateAction<CHANNEL_TYPE>>,
8296
/**
8397
* @deprecated
8498
* Use the onChannelCreated instead
@@ -91,9 +105,8 @@ export interface CreateChannelContextInterface {
91105
overrideInviteUser?(params: OverrideInviteUserType): void;
92106
}
93107

94-
const CreateChannelProvider: React.FC<CreateChannelProviderProps> = (props: CreateChannelProviderProps) => {
108+
const CreateChannelManager: React.FC<CreateChannelProviderProps> = (props: CreateChannelProviderProps) => {
95109
const {
96-
children,
97110
onCreateChannelClick,
98111
onBeforeCreateChannel,
99112
onChannelCreated,
@@ -102,32 +115,57 @@ const CreateChannelProvider: React.FC<CreateChannelProviderProps> = (props: Crea
102115
overrideInviteUser,
103116
} = props;
104117

118+
const { updateState } = useCreateChannelStore();
105119
const store = useSendbirdStateContext();
106120
const _userListQuery = userListQuery ?? store?.config?.userListQuery;
107121

108-
const [step, setStep] = useState(0);
109-
const [type, setType] = useState(CHANNEL_TYPE.GROUP);
110-
111-
return (
112-
<CreateChannelContext.Provider value={{
113-
sdk: store.stores.sdkStore.sdk,
114-
createChannel: getCreateGroupChannel(store),
122+
useEffect(() => {
123+
updateState({
115124
onCreateChannelClick,
116125
onBeforeCreateChannel,
117126
onChannelCreated,
118127
userListQuery: _userListQuery,
119-
step,
120-
setStep,
121-
type,
122-
setType,
123128
onCreateChannel,
124129
overrideInviteUser,
125-
}}>
130+
});
131+
}, [
132+
onCreateChannelClick,
133+
onBeforeCreateChannel,
134+
onChannelCreated,
135+
userListQuery,
136+
onCreateChannel,
137+
overrideInviteUser,
138+
_userListQuery,
139+
]);
140+
141+
return null;
142+
};
143+
const CreateChannelProvider: React.FC<CreateChannelProviderProps> = (props: CreateChannelProviderProps) => {
144+
const { children } = props;
145+
146+
return (
147+
<InternalCreateChannelProvider>
148+
<CreateChannelManager {...props} />
149+
{children}
150+
</InternalCreateChannelProvider>
151+
);
152+
};
153+
154+
const createCreateChannelStore = () => createStore(initialState);
155+
const InternalCreateChannelProvider: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
156+
const storeRef = useRef(createCreateChannelStore());
157+
158+
return (
159+
<CreateChannelContext.Provider value={storeRef.current}>
126160
{children}
127161
</CreateChannelContext.Provider>
128162
);
129163
};
130164

165+
const useCreateChannelStore = () => {
166+
return useStore(CreateChannelContext, state => state, initialState);
167+
};
168+
131169
const useCreateChannelContext = () => {
132170
const context = React.useContext(CreateChannelContext);
133171
if (!context) throw new Error('CreateChannelContext not found. Use within the CreateChannel module.');
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useSyncExternalStore } from 'use-sync-external-store/shim';
2+
import { useMemo } from 'react';
3+
import { CreateChannelState, useCreateChannelContext } from './CreateChannelProvider';
4+
import { CHANNEL_TYPE } from '../types';
5+
6+
export const useCreateChannel = () => {
7+
const store = useCreateChannelContext();
8+
if (!store) throw new Error('useCreateChannel must be used within a CreateChannelProvider');
9+
10+
const state: CreateChannelState = useSyncExternalStore(store.subscribe, store.getState);
11+
const actions = useMemo(() => ({
12+
setStep: (step: number) => store.setState(state => ({
13+
...state,
14+
step,
15+
})),
16+
setType: (type: CHANNEL_TYPE) => store.setState(state => ({
17+
...state,
18+
type,
19+
})),
20+
}), [store]);
21+
22+
return { state, actions };
23+
};

0 commit comments

Comments
 (0)