From 35879aa2466e27d133b57940218347ed549943ba Mon Sep 17 00:00:00 2001 From: HarshShinde0 Date: Tue, 11 Aug 2026 23:05:58 +0530 Subject: [PATCH 01/15] implement collaboration upgrade proposals (invite roles, identity, durable overrides, moderation, layer locks) #1681 --- .../components/layout/CollaborateDialog.tsx | 69 ++-- .../layout/CollaborationParticipantRow.tsx | 61 ++- .../src/hooks/useCollaboration.ts | 138 +++++-- .../geolibre-desktop/src/i18n/locales/en.json | 3 + .../geolibre-desktop/src/lib/collab-client.ts | 11 +- .../src/lib/collab-protocol.ts | 99 ++++- docs/collaboration.md | 21 +- packages/collab-core/src/protocol.ts | 100 ++++- packages/collab-core/src/session.ts | 92 ++++- packages/core/src/store.ts | 4 + packages/core/src/types.ts | 25 ++ tests/collab-comment-validate.test.ts | 4 +- tests/collab-upgrade.test.ts | 177 ++++++++ workers/collab-node/src/server.ts | 294 +++++++++++-- workers/collab-node/src/store.ts | 153 ++++++- workers/collab/src/index.ts | 63 ++- workers/collab/src/session.ts | 387 ++++++++++++++++-- 17 files changed, 1524 insertions(+), 177 deletions(-) create mode 100644 tests/collab-upgrade.test.ts diff --git a/apps/geolibre-desktop/src/components/layout/CollaborateDialog.tsx b/apps/geolibre-desktop/src/components/layout/CollaborateDialog.tsx index fb51b0be88..fefeb8df32 100644 --- a/apps/geolibre-desktop/src/components/layout/CollaborateDialog.tsx +++ b/apps/geolibre-desktop/src/components/layout/CollaborateDialog.tsx @@ -114,6 +114,8 @@ export function CollaborateDialog({ open, onOpenChange, api }: CollaborateDialog }); }; + const [requireIdentity, setRequireIdentity] = useState(false); + const handleStart = async () => { if (!name.trim()) { setError(t("collaborate.nameRequired")); @@ -122,10 +124,8 @@ export function CollaborateDialog({ open, onOpenChange, api }: CollaborateDialog setBusy(true); setError(null); try { - await api.start(name.trim(), color, mode); + await api.start(name.trim(), color, mode, requireIdentity); } catch (err) { - // Show a localized message; keep the raw error in the console for - // diagnostics (collab-client throws human-readable English strings). console.error("[GeoLibre] Collaboration error", err); setError(t("collaborate.connectFailed")); } finally { @@ -147,12 +147,8 @@ export function CollaborateDialog({ open, onOpenChange, api }: CollaborateDialog try { await api.join(code.trim(), name.trim(), color); } catch (err) { - // Show a localized message; keep the raw error in the console for - // diagnostics (collab-client throws human-readable English strings). console.error("[GeoLibre] Collaboration error", err); setError(t("collaborate.connectFailed")); - // The invite link could not connect (e.g. an expired or invalid code), so - // reveal the full layout and let the user fix the code or host instead. setInvited(false); } finally { setBusy(false); @@ -184,13 +180,13 @@ export function CollaborateDialog({ open, onOpenChange, api }: CollaborateDialog onDismiss={() => onOpenChange(false)} onSetMode={api.setMode} onSetParticipantMode={api.setParticipantMode} + onKickParticipant={api.kickParticipant} + onBlockParticipant={api.blockParticipant} + onSetSessionConfig={api.setSessionConfig} onSetFollowHost={api.setFollowHost} /> ) : (
- {/* Name and color feed both actions below, so group them in a - shaded panel above the cards to read as shared profile inputs - rather than belonging to either Start or Join (#706). */}
@@ -206,8 +202,6 @@ export function CollaborateDialog({ open, onOpenChange, api }: CollaborateDialog
- {/* Full panel width keeps every swatch on one row instead of - wrapping a lone dot to a second line (#706). */}
{COLOR_PALETTE.map((c) => (
- {/* An invited participant (arrived via a `?collab=` link) only needs - to join, so collapse the layout to a single Join action and hide - the "Start a session" controls that are irrelevant to them - (#753). They can still fall back to hosting via the link below. */} {invited ? (
@@ -269,9 +256,6 @@ export function CollaborateDialog({ open, onOpenChange, api }: CollaborateDialog
+
- {/* Cameras are independent by default; a non-host can opt to follow the - host's viewport (presenter mode). */} {!isHost && (