diff --git a/src/components/App.tsx b/src/components/App.tsx index c0c6d1ee..7fcdd249 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -113,6 +113,10 @@ import { unstable_batchedUpdates } from "react-dom"; import { SceneStateCallbackRemover } from "../scene/globalScene"; import { isLinearElement } from "../element/typeChecks"; import { actionFinalize } from "../actions"; +import { + restoreUsernameFromLocalStorage, + saveUsernameToLocalStorage, +} from "../data/localStorage"; /** * @param func handler taking at most single parameter (event). @@ -239,6 +243,14 @@ export class App extends React.Component { elements={globalSceneState.getElements()} onRoomCreate={this.openPortal} onRoomDestroy={this.closePortal} + onUsernameChange={(username) => { + if (this.portal.socket && this.portal.roomID && username) { + saveUsernameToLocalStorage(this.portal.roomID, username); + } + this.setState({ + username, + }); + }} onLockToggle={this.toggleLock} />
@@ -909,8 +921,17 @@ export class App extends React.Component { ); this.portal.socket!.on("init-room", () => { - this.portal.socket && + if (this.portal.socket && this.portal.roomID) { + const username = restoreUsernameFromLocalStorage(this.portal.roomID); + this.portal.socket.emit("join-room", this.portal.roomID); + + if (username) { + this.setState({ + username, + }); + } + } }); this.portal.socket!.on( "client-broadcast", diff --git a/src/components/LayerUI.tsx b/src/components/LayerUI.tsx index 3e710395..0fe02954 100644 --- a/src/components/LayerUI.tsx +++ b/src/components/LayerUI.tsx @@ -34,6 +34,7 @@ interface LayerUIProps { setAppState: any; elements: readonly NonDeletedExcalidrawElement[]; onRoomCreate: () => void; + onUsernameChange: (username: string) => void; onRoomDestroy: () => void; onLockToggle: () => void; } @@ -46,6 +47,7 @@ export const LayerUI = React.memo( canvas, elements, onRoomCreate, + onUsernameChange, onRoomDestroy, onLockToggle, }: LayerUIProps) => { @@ -98,6 +100,7 @@ export const LayerUI = React.memo( actionManager={actionManager} exportButton={renderExportDialog()} setAppState={setAppState} + onUsernameChange={onUsernameChange} onRoomCreate={onRoomCreate} onRoomDestroy={onRoomDestroy} onLockToggle={onLockToggle} @@ -132,11 +135,7 @@ export const LayerUI = React.memo( isCollaborating={appState.isCollaborating} collaboratorCount={appState.collaborators.size} username={appState.username} - onUsernameChange={(username) => { - setAppState({ - username, - }); - }} + onUsernameChange={onUsernameChange} onRoomCreate={onRoomCreate} onRoomDestroy={onRoomDestroy} /> diff --git a/src/components/MobileMenu.tsx b/src/components/MobileMenu.tsx index 315203ef..1222c5a3 100644 --- a/src/components/MobileMenu.tsx +++ b/src/components/MobileMenu.tsx @@ -24,6 +24,7 @@ type MobileMenuProps = { setAppState: any; elements: readonly NonDeletedExcalidrawElement[]; onRoomCreate: () => void; + onUsernameChange: (username: string) => void; onRoomDestroy: () => void; onLockToggle: () => void; }; @@ -35,6 +36,7 @@ export function MobileMenu({ exportButton, setAppState, onRoomCreate, + onUsernameChange, onRoomDestroy, onLockToggle, }: MobileMenuProps) { @@ -87,7 +89,7 @@ export function MobileMenu({ isCollaborating={appState.isCollaborating} collaboratorCount={appState.collaborators.size} username={appState.username} - onUsernameChange={(username) => setAppState({ username })} + onUsernameChange={onUsernameChange} onRoomCreate={onRoomCreate} onRoomDestroy={onRoomDestroy} /> diff --git a/src/data/localStorage.ts b/src/data/localStorage.ts index 2c283a99..d49b4767 100644 --- a/src/data/localStorage.ts +++ b/src/data/localStorage.ts @@ -5,6 +5,33 @@ import { restore } from "./restore"; const LOCAL_STORAGE_KEY = "excalidraw"; const LOCAL_STORAGE_KEY_STATE = "excalidraw-state"; +const LOCAL_STORAGE_KEY_COLLAB = "excalidraw-collab"; + +export function saveUsernameToLocalStorage(id: string, username: string) { + try { + localStorage.setItem( + `${LOCAL_STORAGE_KEY_COLLAB}-${id}`, + JSON.stringify({ username }), + ); + } catch (error) { + // Unable to access window.localStorage + console.error(error); + } +} + +export function restoreUsernameFromLocalStorage(id: string): string | null { + try { + const data = localStorage.getItem(`${LOCAL_STORAGE_KEY_COLLAB}-${id}`); + if (data) { + return JSON.parse(data).username; + } + } catch (error) { + // Unable to access localStorage + console.error(error); + } + + return null; +} export function saveToLocalStorage( elements: readonly ExcalidrawElement[],