Skip to content

Commit

Permalink
feat(): sync active account across tabs (#651)
Browse files Browse the repository at this point in the history
* feat(): sync active account across tabs

* fix(): tests
  • Loading branch information
AndreasGassmann authored Nov 8, 2023
1 parent ea76c47 commit 570cddd
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 1 deletion.
15 changes: 15 additions & 0 deletions packages/beacon-core/src/storage/ChromeStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,19 @@ export class ChromeStorage implements Storage {
})
})
}

public async subscribeToStorageChanged(
_callback: (arg: {
eventType: 'storageCleared' | 'entryModified'
key: string | null
oldValue: string | null
newValue: string | null
}) => {}
): Promise<void> {
// TODO
}

public getPrefixedKey(key: string): string {
return key
}
}
33 changes: 32 additions & 1 deletion packages/beacon-core/src/storage/LocalStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,38 @@ export class LocalStorage extends Storage {
return Promise.resolve(localStorage.removeItem(this.getPrefixedKey(key)))
}

private getPrefixedKey(key: string): string {
public async subscribeToStorageChanged(
callback: (arg: {
eventType: 'storageCleared' | 'entryModified'
key: string | null
oldValue: string | null
newValue: string | null
}) => {}
): Promise<void> {
window.addEventListener(
'storage',
(event) => {
if (!event.key) {
callback({
eventType: 'storageCleared',
key: null,
oldValue: null,
newValue: null
})
} else {
callback({
eventType: 'entryModified',
key: this.getPrefixedKey(event.key),
oldValue: event.oldValue,
newValue: event.newValue
})
}
},
false
)
}

public getPrefixedKey(key: string): string {
return this.prefix ? `${this.prefix}-${key}` : key
}
}
17 changes: 17 additions & 0 deletions packages/beacon-dapp/src/dapp-client/DAppClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,23 @@ export class DAppClient extends Client {

this.appMetadataManager = new AppMetadataManager(this.storage)

// Subscribe to storage changes and update the active account if it changes on other tabs
this.storage.subscribeToStorageChanged(async (event) => {
if (event.eventType === 'storageCleared') {
this.setActiveAccount(undefined)
} else if (event.eventType === 'entryModified') {
if (event.key === this.storage.getPrefixedKey(StorageKey.ACTIVE_ACCOUNT)) {
const accountIdentifier = event.newValue
if (!accountIdentifier || accountIdentifier === 'undefined') {
this.setActiveAccount(undefined)
} else {
const account = await this.getAccount(accountIdentifier)
this.setActiveAccount(account)
}
}
}
})

this.activeAccountLoaded = this.storage
.get(StorageKey.ACTIVE_ACCOUNT)
.then(async (activeAccountIdentifier) => {
Expand Down
21 changes: 21 additions & 0 deletions packages/beacon-types/src/types/storage/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,25 @@ export abstract class Storage {
* @param key The storage key
*/
abstract delete<K extends StorageKey>(key: K): Promise<void>

/**
* This event will fire if the storage was modified by someone else, eg. on another tab
*
* @param callback The callback to be called when a storage value changes
*/
abstract subscribeToStorageChanged(
callback: (arg: {
eventType: 'storageCleared' | 'entryModified'
key: string | null
oldValue: string | null
newValue: string | null
}) => {}
): Promise<void>

/**
* Get the key with the internal prefix
*
* @param key the storage key
*/
abstract getPrefixedKey<K extends StorageKey>(key: K): string
}
15 changes: 15 additions & 0 deletions test/test-utils/FileStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,19 @@ export class FileStorage implements Storage {

return writeLocalFile(json)
}

public async subscribeToStorageChanged(
_callback: (arg: {
eventType: 'storageCleared' | 'entryModified'
key: string | null
oldValue: string | null
newValue: string | null
}) => {}
): Promise<void> {
// TODO
}

public getPrefixedKey(key: string): string {
return key
}
}

0 comments on commit 570cddd

Please sign in to comment.