-
Notifications
You must be signed in to change notification settings - Fork 337
Fix/embedded chat channelname not switching #1048
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
41b242a
4612126
1cb376d
b47d66c
1cbe0af
f19ab01
903b7b5
d01c4f8
b0067ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,9 @@ | ||
| node_modules | ||
| .parcel-cache | ||
|
|
||
| .env | ||
| .env.local | ||
| .env.*.local | ||
|
|
||
| # yarn | ||
| .pnp.* | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,12 @@ import { | |
| import { ChatLayout } from './ChatLayout'; | ||
| import { ChatHeader } from './ChatHeader'; | ||
| import { RCInstanceProvider } from '../context/RCInstance'; | ||
| import { useUserStore, useLoginStore, useMessageStore } from '../store'; | ||
| import { | ||
| useUserStore, | ||
| useLoginStore, | ||
| useMessageStore, | ||
| useChannelStore, | ||
| } from '../store'; | ||
| import DefaultTheme from '../theme/DefaultTheme'; | ||
| import { getTokenStorage } from '../lib/auth'; | ||
| import { styles } from './EmbeddedChat.styles'; | ||
|
|
@@ -27,9 +32,17 @@ import { overrideECProps } from '../lib/overrideECProps'; | |
|
|
||
| const EmbeddedChat = (props) => { | ||
| const [config, setConfig] = useState(() => props); | ||
| const [explicitRoomId, setExplicitRoomId] = useState(() => props.roomId); | ||
| const [resolvedRoomId, setResolvedRoomId] = useState(() => { | ||
| if (props.roomId) { | ||
| return props.roomId; | ||
| } | ||
| return props.channelName ? null : 'GENERAL'; | ||
| }); | ||
|
|
||
| useEffect(() => { | ||
| setConfig(props); | ||
| setExplicitRoomId(props.roomId); | ||
| }, [props]); | ||
|
|
||
| const { | ||
|
|
@@ -61,6 +74,7 @@ const EmbeddedChat = (props) => { | |
| } = config; | ||
|
|
||
| const hasMounted = useRef(false); | ||
| const previousResolvedRoomId = useRef(resolvedRoomId); | ||
| const { classNames, styleOverrides } = useComponentOverrides('EmbeddedChat'); | ||
| const [fullScreen, setFullScreen] = useState(false); | ||
| const [isSynced, setIsSynced] = useState(!remoteOpt); | ||
|
|
@@ -72,6 +86,7 @@ const EmbeddedChat = (props) => { | |
| setUserId: setAuthenticatedUserId, | ||
| setName: setAuthenticatedName, | ||
| setRoles: setAuthenticatedUserRoles, | ||
| isUserAuthenticated, | ||
| } = useUserStore((state) => ({ | ||
| isUserAuthenticated: state.isUserAuthenticated, | ||
| setIsUserAuthenticated: state.setIsUserAuthenticated, | ||
|
|
@@ -90,34 +105,144 @@ const EmbeddedChat = (props) => { | |
| } | ||
|
|
||
| const initializeRCInstance = useCallback(() => { | ||
| const newRCInstance = new EmbeddedChatApi(host, roomId, { | ||
| const roomIdToUse = resolvedRoomId || 'GENERAL'; | ||
| const newRCInstance = new EmbeddedChatApi(host, roomIdToUse, { | ||
| getToken, | ||
| deleteToken, | ||
| saveToken, | ||
| }); | ||
|
|
||
| return newRCInstance; | ||
| }, [host, roomId, getToken, deleteToken, saveToken]); | ||
| }, [host, resolvedRoomId, getToken, deleteToken, saveToken]); | ||
|
|
||
| const [RCInstance, setRCInstance] = useState(() => initializeRCInstance()); | ||
| const [RCInstance, setRCInstance] = useState(() => { | ||
| const initialRoomId = resolvedRoomId || 'GENERAL'; | ||
| return new EmbeddedChatApi(host, initialRoomId, { | ||
| getToken, | ||
| deleteToken, | ||
| saveToken, | ||
| }); | ||
| }); | ||
| const setMessages = useMessageStore((state) => state.setMessages); | ||
| const setChannelInfo = useChannelStore((state) => state.setChannelInfo); | ||
|
|
||
| useEffect(() => { | ||
| const reInstantiate = () => { | ||
| const resolveRoomId = async () => { | ||
| if (explicitRoomId) { | ||
| setResolvedRoomId(explicitRoomId); | ||
| return; | ||
| } | ||
|
|
||
| if (channelName) { | ||
| try { | ||
| if (!RCInstance) { | ||
| return; | ||
| } | ||
|
|
||
| if (!isUserAuthenticated) { | ||
| return; | ||
| } | ||
|
|
||
| const currentUser = await RCInstance.auth.getCurrentUser(); | ||
| const authToken = currentUser?.authToken; | ||
| const userId = currentUser?.userId || currentUser?._id; | ||
|
|
||
| if (!authToken || !userId) { | ||
| return; | ||
| } | ||
|
|
||
| const response = await fetch( | ||
| `${host}/api/v1/rooms.info?roomName=${encodeURIComponent( | ||
| channelName | ||
| )}`, | ||
| { | ||
| method: 'GET', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| 'X-Auth-Token': authToken, | ||
| 'X-User-Id': userId, | ||
| }, | ||
| } | ||
| ); | ||
|
|
||
| if (!response.ok) { | ||
| if (response.status === 401) { | ||
| return; | ||
| } | ||
| throw new Error(`HTTP error! status: ${response.status}`); | ||
| } | ||
|
|
||
| const data = await response.json(); | ||
| if (data?.success && data?.room?._id) { | ||
| setResolvedRoomId(data.room._id); | ||
| } else { | ||
| setResolvedRoomId('GENERAL'); | ||
| } | ||
| } catch (error) { | ||
| setResolvedRoomId('GENERAL'); | ||
| } | ||
| } else { | ||
| setResolvedRoomId('GENERAL'); | ||
| } | ||
| }; | ||
|
|
||
| resolveRoomId(); | ||
| }, [channelName, explicitRoomId, host, RCInstance, isUserAuthenticated]); | ||
|
|
||
| useEffect(() => { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please explain the use for this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This useEffect resolves a channelName to a roomId (e.g., "GENERAL", "6956b4ced42fcf35") when only the channel name is provided. |
||
| const reInstantiate = async () => { | ||
| if (!hasMounted.current) { | ||
| hasMounted.current = true; | ||
| previousResolvedRoomId.current = resolvedRoomId; | ||
| if (resolvedRoomId === null) { | ||
| return; | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| if (resolvedRoomId === null) { | ||
| return; | ||
| } | ||
|
|
||
| if (previousResolvedRoomId.current === resolvedRoomId) { | ||
| return; | ||
| } | ||
|
|
||
| previousResolvedRoomId.current = resolvedRoomId; | ||
|
|
||
| await RCInstance.close(); | ||
|
|
||
| setMessages([], false); | ||
| setChannelInfo({}); | ||
| useMessageStore.setState({ | ||
| messages: [], | ||
| threadMessages: [], | ||
| filtered: false, | ||
| threadMainMessage: null, | ||
| deletedMessage: {}, | ||
| quoteMessage: [], | ||
| editMessage: {}, | ||
| messagesOffset: 0, | ||
| isMessageLoaded: false, | ||
| }); | ||
|
|
||
| const newRCInstance = initializeRCInstance(); | ||
| setRCInstance(newRCInstance); | ||
| }; | ||
|
|
||
| if (!hasMounted.current) { | ||
| hasMounted.current = true; | ||
| return; | ||
| } | ||
|
|
||
| RCInstance.close().then(reInstantiate).catch(console.error); | ||
| reInstantiate().catch(console.error); | ||
|
|
||
| return () => { | ||
| RCInstance.close().catch(console.error); | ||
| }; | ||
| }, [roomId, host, initializeRCInstance]); | ||
| }, [ | ||
| resolvedRoomId, | ||
| host, | ||
| initializeRCInstance, | ||
| setMessages, | ||
| setChannelInfo, | ||
| RCInstance, | ||
| ]); | ||
|
|
||
| useEffect(() => { | ||
| const autoLogin = async () => { | ||
|
|
@@ -138,7 +263,6 @@ const EmbeddedChat = (props) => { | |
| if (user) { | ||
| RCInstance.connect() | ||
| .then(() => { | ||
| console.log(`Connected to RocketChat ${RCInstance.host}`); | ||
| const { me } = user; | ||
| setAuthenticatedAvatarUrl(me.avatarUrl); | ||
| setAuthenticatedUsername(me.username); | ||
|
|
@@ -189,7 +313,7 @@ const EmbeddedChat = (props) => { | |
| width, | ||
| height, | ||
| host, | ||
| roomId, | ||
| roomId: resolvedRoomId, | ||
| channelName, | ||
| showName, | ||
| showRoles, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need to have this fallback ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I set this If a user provides a channelName that doesn't exist or they lack access, falling back to 'GENERAL' hides the failure.