fuzzyworld

north-star / commit

improved "create new room" link

764d68de7187bf7f1997af215e35c1ebee447551 · Pavel Safronov · 2026-03-16 13:26:49 -0700 · parents 32796e531025

improved "create new room" link
 src/app.ts                      | 37 +++++++++++++++++++++++++++++--------
 src/features/session/session.ts |  4 +++-
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/src/app.ts b/src/app.ts
index f81e40f..91545bd 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -5,7 +5,7 @@ import { initDarkMode } from './platform/darkmode';
 import { initWakeLockController } from './features/ui';
 import { initFirebaseSession } from './platform/firebase';
 import { initSession, initSelfProfile, bumpQrAutoCollapseCountdown } from './features/session';
-import { parseRoomFromHash } from './core/room';
+import { buildRoomHash, parseRoomFromHash } from './core/room';
 import { subscribeToFriends, createFriendsPanelController, renderArrows } from './features/friends';
 import { initCompassController } from './features/compass';
 import { PUBLIC_SETTINGS } from './public_settings';
@@ -55,6 +55,7 @@ let friends: any[] = [];
 let sessionStarted = false;
 let startInProgress = false;
 let previousRemoteFriendCount = 0;
+let activeSessionRoomHash: string | null = null;
 
 initDarkMode(darkModeToggle);
 const wakeLockController = initWakeLockController({
@@ -103,6 +104,14 @@ const selfPosition = {
 };
 
 const BASE_ROOM_URL = `${window.location.origin}${window.location.pathname}`;
+const CREATE_ROOM_URL = `${BASE_ROOM_URL}?new=1`;
+
+const shouldAutoCreateRoomFromUrl = () => {
+    const raw = new URLSearchParams(location.search).get('new');
+    if (raw === null) return false;
+    if (raw === '') return true;
+    return ['1', 'true', 'yes', 'on'].includes(raw.toLowerCase());
+};
 
 const appTitleLink = document.getElementById('app-title-link');
 if (appTitleLink instanceof HTMLAnchorElement) {
@@ -265,10 +274,12 @@ const startSession = async () => {
             inviteRoomQrList,
             isLocalCommit,
             BASE_ROOM_URL,
+            CREATE_ROOM_URL,
             GITLAB_PAGES_BASE_URL: PUBLIC_SETTINGS.links.gitlabPagesBaseUrl
         });
         roomId = session.roomId;
         roomKey = session.roomKey;
+        activeSessionRoomHash = buildRoomHash(session.roomId, session.roomKeyBase64);
 
         friendRef = ref(db, `rooms/${roomId}/friends/${selfFriend.id}`);
 
@@ -339,7 +350,7 @@ if (startRoomButton instanceof HTMLButtonElement) {
     });
 }
 
-if (parseRoomFromHash(location.hash)) {
+if (parseRoomFromHash(location.hash) || shouldAutoCreateRoomFromUrl()) {
     void startSession();
 } else {
     const savedRoomHash = localStorage.getItem(LAST_ROOM_HASH_STORAGE_KEY);
@@ -356,16 +367,26 @@ if (parseRoomFromHash(location.hash)) {
 }
 
 window.addEventListener('hashchange', () => {
-    // Back-navigation can clear the room hash while runtime state is still active.
-    // Reload to re-enter the proper landing/resume flow for the new URL.
-    if (sessionStarted && !parseRoomFromHash(location.hash)) {
-        window.location.reload();
-        return;
+    const parsedRoom = parseRoomFromHash(location.hash);
+
+    // If the URL hash changes while a session is active, reload so runtime state
+    // (subscriptions/refs/key) is rebuilt against the room in the URL.
+    if (sessionStarted) {
+        if (!parsedRoom) {
+            window.location.reload();
+            return;
+        }
+
+        const nextRoomHash = buildRoomHash(parsedRoom.roomId, parsedRoom.roomKeyBase64);
+        if (activeSessionRoomHash && nextRoomHash !== activeSessionRoomHash) {
+            window.location.reload();
+            return;
+        }
     }
 
     // Forward-navigation can restore a valid room hash while still on landing.
     // Start the room session to match the URL state.
-    if (!sessionStarted && parseRoomFromHash(location.hash)) {
+    if (!sessionStarted && parsedRoom) {
         void startSession();
     }
 });
diff --git a/src/features/session/session.ts b/src/features/session/session.ts
index 0aeb03e..2a31f60 100644
--- a/src/features/session/session.ts
+++ b/src/features/session/session.ts
@@ -14,6 +14,7 @@ export async function initSession({
     inviteRoomQrList,
     isLocalCommit,
     BASE_ROOM_URL,
+    CREATE_ROOM_URL,
     GITLAB_PAGES_BASE_URL
 }: {
     roomCurrent: HTMLElement | null;
@@ -21,6 +22,7 @@ export async function initSession({
     inviteRoomQrList: HTMLElement | null;
     isLocalCommit: boolean;
     BASE_ROOM_URL: string;
+    CREATE_ROOM_URL: string;
     GITLAB_PAGES_BASE_URL: string;
 }) {
     let roomKey: CryptoKey | null = null;
@@ -46,7 +48,7 @@ export async function initSession({
     }
 
     if (roomCurrent) roomCurrent.textContent = `You are currently in room ${roomId}`;
-    if (createRoomLink) createRoomLink.href = BASE_ROOM_URL;
+    if (createRoomLink) createRoomLink.href = CREATE_ROOM_URL;
 
     if (inviteRoomQrList) {
         const inviteRoomUrl = `${BASE_ROOM_URL}#${buildRoomHash(roomId, roomKeyBase64)}`;