send user prefs data in broadcast msg (#1466)
fixes #1464 The user preference changes were not broadcasting correctly in firefox because it has a race condition wherein the broadcast message was being received by a peer tab before the localStorage data was ready to be consumed in that tab. ### Change Type <!-- 💡 Indicate the type of change your pull request is. --> <!-- 🤷♀️ If you're not sure, don't select anything --> <!-- ✂️ Feel free to delete unselected options --> <!-- To select one, put an x in the box: [x] --> - [x] `patch` — Bug Fix - [ ] `minor` — New Feature - [ ] `major` — Breaking Change - [ ] `dependencies` — Dependency Update (publishes a `patch` release, for devDependencies use `internal`) - [ ] `documentation` — Changes to the documentation only (will not publish a new version) - [ ] `tests` — Changes to any testing-related code only (will not publish a new version) - [ ] `internal` — Any other changes that don't affect the published package (will not publish a new version) ### Test Plan 1. in firefox, have two tabs open in the same user context. 2. toggle dark mode. 3. the change should propagate to the other tab
This commit is contained in:
parent
f551528ddf
commit
b742783577
1 changed files with 26 additions and 20 deletions
|
@ -27,18 +27,16 @@ interface UserDataSnapshot {
|
|||
interface UserChangeBroadcastMessage {
|
||||
type: typeof broadcastEventKey
|
||||
origin: string
|
||||
data: UserDataSnapshot
|
||||
}
|
||||
|
||||
const userTypeValidator: T.Validator<TLUserPreferences> = T.model(
|
||||
'user',
|
||||
T.object({
|
||||
const userTypeValidator: T.Validator<TLUserPreferences> = T.object({
|
||||
id: T.string,
|
||||
name: T.string,
|
||||
locale: T.string,
|
||||
color: T.string,
|
||||
isDarkMode: T.boolean,
|
||||
})
|
||||
)
|
||||
|
||||
const userTypeMigrations = defineMigrations({})
|
||||
|
||||
|
@ -72,18 +70,12 @@ function getFreshUserPreferences(): TLUserPreferences {
|
|||
isDarkMode: false,
|
||||
}
|
||||
}
|
||||
|
||||
function loadUserPreferences(): TLUserPreferences {
|
||||
const userData =
|
||||
typeof window === 'undefined'
|
||||
? null
|
||||
: ((JSON.parse(window?.localStorage?.getItem(USER_DATA_KEY) || 'null') ??
|
||||
null) as null | UserDataSnapshot)
|
||||
if (userData === null) {
|
||||
function migrateUserPreferences(userData: unknown) {
|
||||
if (userData === null || typeof userData !== 'object') {
|
||||
return getFreshUserPreferences()
|
||||
}
|
||||
|
||||
if (!('version' in userData) || !('user' in userData)) {
|
||||
if (!('version' in userData) || !('user' in userData) || typeof userData.version !== 'number') {
|
||||
return getFreshUserPreferences()
|
||||
}
|
||||
|
||||
|
@ -107,6 +99,16 @@ function loadUserPreferences(): TLUserPreferences {
|
|||
return migrationResult.value
|
||||
}
|
||||
|
||||
function loadUserPreferences(): TLUserPreferences {
|
||||
const userData =
|
||||
typeof window === 'undefined'
|
||||
? null
|
||||
: ((JSON.parse(window?.localStorage?.getItem(USER_DATA_KEY) || 'null') ??
|
||||
null) as null | UserDataSnapshot)
|
||||
|
||||
return migrateUserPreferences(userData)
|
||||
}
|
||||
|
||||
const globalUserPreferences = atom<TLUserPreferences>('globalUserData', loadUserPreferences())
|
||||
|
||||
function storeUserPreferences() {
|
||||
|
@ -138,7 +140,7 @@ const channel =
|
|||
channel?.addEventListener('message', (e) => {
|
||||
const data = e.data as undefined | UserChangeBroadcastMessage
|
||||
if (data?.type === broadcastEventKey && data?.origin !== broadcastOrigin) {
|
||||
globalUserPreferences.set(loadUserPreferences())
|
||||
globalUserPreferences.set(migrateUserPreferences(data.data))
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -149,6 +151,10 @@ function broadcastUserPreferencesChange() {
|
|||
channel?.postMessage({
|
||||
type: broadcastEventKey,
|
||||
origin: broadcastOrigin,
|
||||
data: {
|
||||
user: globalUserPreferences.value,
|
||||
version: userTypeMigrations.currentVersion,
|
||||
},
|
||||
} satisfies UserChangeBroadcastMessage)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue