remnantchat/src/Bootstrap.tsx

257 lines
7.1 KiB
TypeScript
Raw Normal View History

feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
import { useCallback, useEffect, useMemo, useState } from 'react'
2022-10-29 18:09:27 +00:00
import {
BrowserRouter as Router,
Routes,
Route,
Navigate,
} from 'react-router-dom'
2022-08-20 19:20:51 +00:00
import { v4 as uuid } from 'uuid'
2022-08-20 21:52:31 +00:00
import localforage from 'localforage'
2022-08-10 02:28:46 +00:00
2022-09-11 18:44:23 +00:00
import * as serviceWorkerRegistration from 'serviceWorkerRegistration'
import { StorageContext } from 'contexts/StorageContext'
2022-09-05 22:35:40 +00:00
import { SettingsContext } from 'contexts/SettingsContext'
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
import { homepageUrl, routes } from 'config/routes'
2022-09-17 17:39:16 +00:00
import { Home } from 'pages/Home'
import { About } from 'pages/About'
import { Disclaimer } from 'pages/Disclaimer'
import { Settings } from 'pages/Settings'
2022-09-17 17:39:16 +00:00
import { PublicRoom } from 'pages/PublicRoom'
import { PrivateRoom } from 'pages/PrivateRoom'
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
import { ColorMode, UserSettings } from 'models/settings'
2022-08-20 21:52:31 +00:00
import { PersistedStorageKeys } from 'models/storage'
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
import { QueryParamKeys } from 'models/shell'
import { Shell } from 'components/Shell'
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
import {
isConfigMessageEvent,
PostMessageEvent,
PostMessageEventName,
} from 'models/sdk'
2022-08-09 14:35:49 +00:00
2022-08-20 21:52:31 +00:00
export interface BootstrapProps {
persistedStorage?: typeof localforage
getUuid?: typeof uuid
}
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
const configListenerTimeout = 3000
const getConfigFromSdk = () => {
const queryParams = new URLSearchParams(window.location.search)
const { origin: parentFrameOrigin } = new URL(
decodeURIComponent(queryParams.get(QueryParamKeys.PARENT_DOMAIN) ?? '')
)
return new Promise<Partial<UserSettings>>((resolve, reject) => {
let expireTimout: NodeJS.Timeout
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
const expireListener = () => {
window.removeEventListener('message', handleMessage)
clearTimeout(expireTimout)
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
reject()
}
expireTimout = setTimeout(expireListener, configListenerTimeout)
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
const handleMessage = (event: MessageEvent) => {
if (!isConfigMessageEvent(event)) return
resolve(event.data.payload)
expireListener()
}
window.addEventListener('message', handleMessage)
const postMessageEvent: PostMessageEvent['data'] = {
name: PostMessageEventName.CONFIG_REQUESTED,
payload: {},
}
window.parent.postMessage(postMessageEvent, parentFrameOrigin)
})
}
2022-08-20 21:52:31 +00:00
function Bootstrap({
persistedStorage: persistedStorageProp = localforage.createInstance({
2022-08-20 21:52:31 +00:00
name: 'chitchatter',
description: 'Persisted settings data for chitchatter',
}),
getUuid = uuid,
}: BootstrapProps) {
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
const queryParams = useMemo(
() => new URLSearchParams(window.location.search),
[]
)
const [persistedStorage] = useState(persistedStorageProp)
2022-09-11 18:44:23 +00:00
const [appNeedsUpdate, setAppNeedsUpdate] = useState(false)
2022-08-20 21:52:31 +00:00
const [hasLoadedSettings, setHasLoadedSettings] = useState(false)
2022-09-05 22:35:40 +00:00
const [userSettings, setUserSettings] = useState<UserSettings>({
userId: getUuid(),
customUsername: '',
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
colorMode: ColorMode.DARK,
playSoundOnNewMessage: true,
showNotificationOnNewMessage: true,
showActiveTypingStatus: true,
2022-09-05 22:35:40 +00:00
})
const { userId } = userSettings
2022-09-11 18:44:23 +00:00
const handleServiceWorkerUpdate = () => {
setAppNeedsUpdate(true)
}
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
const persistUserSettings = useCallback(
(newUserSettings: UserSettings) => {
if (queryParams.has(QueryParamKeys.IS_EMBEDDED)) {
return Promise.resolve(userSettings)
}
return persistedStorageProp.setItem(
PersistedStorageKeys.USER_SETTINGS,
newUserSettings
)
},
[persistedStorageProp, queryParams, userSettings]
)
2022-09-11 18:44:23 +00:00
useEffect(() => {
serviceWorkerRegistration.register({ onUpdate: handleServiceWorkerUpdate })
}, [])
2022-08-20 21:52:31 +00:00
useEffect(() => {
;(async () => {
if (hasLoadedSettings) return
const persistedUserSettings =
await persistedStorageProp.getItem<UserSettings>(
2022-08-20 21:52:31 +00:00
PersistedStorageKeys.USER_SETTINGS
)
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
const computeUserSettings = async (): Promise<UserSettings> => {
if (queryParams.has(QueryParamKeys.GET_SDK_CONFIG)) {
try {
const configFromSdk = await getConfigFromSdk()
return {
...userSettings,
...persistedUserSettings,
...configFromSdk,
}
} catch (e) {
console.error(
'Chitchatter configuration from parent frame could not be loaded'
)
}
}
return {
...userSettings,
...persistedUserSettings,
}
}
const computedUserSettings = await computeUserSettings()
setUserSettings(computedUserSettings)
if (persistedUserSettings === null) {
await persistUserSettings(computedUserSettings)
2022-08-20 21:52:31 +00:00
}
setHasLoadedSettings(true)
})()
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
}, [
hasLoadedSettings,
persistedStorageProp,
userSettings,
userId,
queryParams,
persistUserSettings,
])
useEffect(() => {
const queryParams = new URLSearchParams(window.location.search)
if (!queryParams.has(QueryParamKeys.IS_EMBEDDED)) return
const handleConfigMessage = (event: MessageEvent) => {
if (!hasLoadedSettings) return
if (!isConfigMessageEvent(event)) return
const overrideConfig: Partial<UserSettings> = event.data.payload
setUserSettings({
...userSettings,
...overrideConfig,
})
}
window.addEventListener('message', handleConfigMessage)
return () => {
window.removeEventListener('message', handleConfigMessage)
}
}, [hasLoadedSettings, userSettings])
2022-09-05 22:35:40 +00:00
const settingsContextValue = {
updateUserSettings: async (changedSettings: Partial<UserSettings>) => {
const newSettings = {
...userSettings,
...changedSettings,
}
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 16:42:58 +00:00
await persistUserSettings(newSettings)
2022-09-05 22:35:40 +00:00
setUserSettings(newSettings)
},
getUserSettings: () => ({ ...userSettings }),
}
2022-08-20 19:20:51 +00:00
const storageContextValue = {
getPersistedStorage: () => persistedStorage,
}
2022-08-10 02:28:46 +00:00
return (
<Router basename={homepageUrl.pathname}>
<StorageContext.Provider value={storageContextValue}>
<SettingsContext.Provider value={settingsContextValue}>
{hasLoadedSettings ? (
<Shell appNeedsUpdate={appNeedsUpdate} userPeerId={userId}>
<Routes>
{[routes.ROOT, routes.INDEX_HTML].map(path => (
<Route
key={path}
path={path}
element={<Home userId={userId} />}
/>
))}
<Route path={routes.ABOUT} element={<About />} />
<Route path={routes.DISCLAIMER} element={<Disclaimer />} />
<Route
path={routes.SETTINGS}
element={<Settings userId={userId} />}
/>
2022-09-05 23:59:59 +00:00
<Route
path={routes.PUBLIC_ROOM}
element={<PublicRoom userId={userId} />}
2022-09-05 23:59:59 +00:00
/>
<Route
path={routes.PRIVATE_ROOM}
element={<PrivateRoom userId={userId} />}
/>
2022-10-29 18:09:27 +00:00
<Route
path="*"
element={<Navigate to={routes.ROOT} replace />}
/>
</Routes>
</Shell>
) : (
<></>
)}
</SettingsContext.Provider>
</StorageContext.Provider>
2022-09-01 03:05:24 +00:00
</Router>
2022-08-10 02:28:46 +00:00
)
2022-08-09 14:35:49 +00:00
}
export default Bootstrap