Skip to content

add map comments with collab sync - #1607

Merged
giswqs merged 8 commits into
opengeos:mainfrom
HarshShinde0:feat/comments-collab-improvements
Aug 1, 2026
Merged

add map comments with collab sync#1607
giswqs merged 8 commits into
opengeos:mainfrom
HarshShinde0:feat/comments-collab-improvements

Conversation

@HarshShinde0

@HarshShinde0 HarshShinde0 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

#1518 Users can now pin comments to any map location or feature, reply to them, resolve them, and delete them. Comments save with the project and sync live across collab sessions.
Changes:

  • Comments panel, map pins, and add/reply dialog
  • Comment types and store actions (add, reply, resolve, delete)
  • Collab server syncs comment changes to all session participants

Summary by CodeRabbit

  • New Features

    • Added anchored comments for map points and features.
    • Users can create, reply to, resolve, reopen, delete, and filter threaded comments.
    • Added a dockable Comments panel, map markers, navigation, and toolbar access.
    • Added live collaboration for synchronizing comment changes with edit permissions.
    • Comments persist with project data, including author and resolution details.
  • Bug Fixes

    • Improved remote cursor marker positioning.
    • Added clearer collaboration connection and configuration error messages.

Copilot AI review requested due to automatic review settings August 1, 2026 12:25
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 359421bd-649a-4b1c-9568-a332d59917fc

📥 Commits

Reviewing files that changed from the base of the PR and between 40a7462 and 101ea38.

📒 Files selected for processing (5)
  • apps/geolibre-desktop/src/components/comments/CommentThread.tsx
  • apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx
  • apps/geolibre-desktop/src/components/comments/useCommentTool.ts
  • apps/geolibre-desktop/src/hooks/useCollaboration.ts
  • apps/geolibre-desktop/src/i18n/locales/en.json

📝 Walkthrough

Walkthrough

The PR adds anchored project comments with persistence, map placement, threaded actions, desktop UI integration, and collaboration synchronization. It also updates collaboration connection messaging and remote marker placement.

Changes

Anchored project comments

Layer / File(s) Summary
Comment model and persistence
packages/core/src/types.ts, packages/core/src/project.ts, packages/core/src/store.ts, apps/geolibre-desktop/src/lib/build-project-snapshot.ts, apps/geolibre-desktop/src/lib/project-broadcast-changed.ts
Defines comment data, validates and normalizes comments, persists them in projects, adds store actions, and includes comments in history and snapshot change detection.
Collaboration protocol and transport
apps/geolibre-desktop/src/lib/collab-protocol.ts, apps/geolibre-desktop/src/hooks/useCollaboration.ts, workers/collab/src/protocol.ts, workers/collab/src/session.ts
Adds comment mutation messages for add, reply, resolve, and delete actions. Applies permissions, persistence, store updates, and broadcasts.
Comment placement and creation
apps/geolibre-desktop/src/components/comments/useCommentTool.ts, apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx
Selects point or feature anchors and submits validated comments with persisted author names.
Map markers and comment threads
apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx, apps/geolibre-desktop/src/components/comments/CommentThread.tsx
Resolves coordinates, renders markers, displays comment threads, and supports replies, resolution changes, navigation, and deletion.
Comments panel and session controls
apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx, apps/geolibre-desktop/src/i18n/locales/en.json
Adds comment filtering, author editing, thread rendering, map navigation, collaboration session controls, and English strings.
Desktop shell integration
apps/geolibre-desktop/src/components/layout/DesktopShell.tsx, apps/geolibre-desktop/src/hooks/useRegisterCommentsPanel.ts, apps/geolibre-desktop/src/components/layout/TopToolbar.tsx
Registers and renders the Comments panel, overlay, comment tool, and dialog. Adds toolbar access.
Validation and collaboration tests
tests/comments.test.ts, tests/collab-protocol.test.ts
Tests comment persistence, normalization, store actions, deduplication, mutation messages, configuration errors, and malformed payloads.
Collaboration client and marker updates
apps/geolibre-desktop/src/lib/collab-client.ts, apps/geolibre-desktop/src/components/layout/RemoteCursorsOverlay.tsx
Improves collaboration error messages and sets new remote marker coordinates before adding them to the map.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CommentsPanel
  participant useCollaboration
  participant CollabSession
  participant AppState
  User->>CommentsPanel: Add or edit comment
  CommentsPanel->>useCollaboration: sendCommentMutation(action)
  useCollaboration->>CollabSession: Send comment-mutation
  CollabSession->>CollabSession: Validate and persist action
  CollabSession-->>useCollaboration: Broadcast mutation
  useCollaboration->>AppState: Apply comment mutation
Loading

Possibly related issues

  • opengeos/GeoLibre#1518 — This PR implements anchored, persistent project comments with storage, UI, threading, resolution, and collaboration synchronization.

Possibly related PRs

  • opengeos/GeoLibre#1575 — Both modify collaboration snapshot-change detection and project broadcast comparisons.

Suggested reviewers: giswqs

Poem

A rabbit marks a point on the map,
Then adds a note and taps submit.
Replies hop through the thread,
Resolved pins fade from view.
Across the relay, comments race. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding map comments with collaborative synchronization.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🔍 Cloudflare PR preview

Item Value
Site https://9b174efa.geolibre-preview.pages.dev
Demo app https://9b174efa.geolibre-preview.pages.dev/demo/
Commit 101ea38

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🔍 GitHub Pages PR preview

Item Value
Site Deploy failed. See the job log.
Demo app Unavailable
Commit 101ea38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds anchored, persistent project comments (threads pinned to map points/features) and syncs comment mutations across live collaboration sessions. This extends the existing project schema + Zustand store and integrates UI (panel + map pins + add/reply/resolve/delete flows) alongside the collab relay.

Changes:

  • Introduces ProjectComment types and project parsing/serialization support for comments.
  • Adds comment state + actions to the app store, plus UI for creating and managing comment threads and map pins.
  • Extends the collaboration protocol/relay to broadcast comment mutations to other session participants.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
workers/collab/src/session.ts Adds server-side handling and fan-out for comment-mutation messages.
workers/collab/src/protocol.ts Extends worker protocol unions with comment-mutation.
tests/comments.test.ts Adds unit tests for comment normalization, project round-trips, and store actions.
tests/collab-protocol.test.ts Updates collab client/protocol tests, including comment-mutation cases.
packages/core/src/types.ts Adds comment-related types and comments field on the project type.
packages/core/src/store.ts Adds comments state and actions (add/reply/resolve/delete) and includes comments in history comparisons.
packages/core/src/project.ts Adds normalization for comments and includes comments in project parse/store apply/serialize.
package-lock.json Lockfile updates.
apps/geolibre-desktop/src/lib/project-broadcast-changed.ts Treats comment changes as project changes for broadcasting snapshots.
apps/geolibre-desktop/src/lib/collab-protocol.ts Adds typed comment-mutation message definitions to the desktop collab protocol.
apps/geolibre-desktop/src/lib/collab-client.ts Tweaks collab client error messages and keeps the reconnecting WebSocket wrapper.
apps/geolibre-desktop/src/lib/build-project-snapshot.ts Includes state.comments in the collaboration snapshot payload.
apps/geolibre-desktop/src/hooks/useRegisterCommentsPanel.ts Registers the new Comments right panel.
apps/geolibre-desktop/src/hooks/useCollaboration.ts Applies inbound comment mutations and adds sendCommentMutation; refactors reconnect handling.
apps/geolibre-desktop/src/components/layout/TopToolbar.tsx Adds a command to open the Comments panel.
apps/geolibre-desktop/src/components/layout/RemoteCursorsOverlay.tsx Small marker positioning adjustment.
apps/geolibre-desktop/src/components/layout/DesktopShell.tsx Wires in Comments panel portal, comment tool/dialog, and map overlay pins.
apps/geolibre-desktop/src/components/comments/useCommentTool.ts Implements a map “comment tool” to place anchored comments.
apps/geolibre-desktop/src/components/comments/CommentThread.tsx Renders a comment thread with replies + resolve/delete/zoom actions.
apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx Implements the comments sidebar UI, filters, and live-session controls.
apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx Renders numbered map pins for open/resolved comments.
apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx Dialog for submitting a new comment (including author name capture).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/collab-protocol.test.ts Outdated
Comment thread apps/geolibre-desktop/src/hooks/useCollaboration.ts
Comment thread apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx
Comment thread apps/geolibre-desktop/src/components/comments/useCommentTool.ts Outdated
Comment thread apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 28

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx`:
- Around line 60-64: Update the AddCommentDialog component to use
react-i18next’s useTranslation and wrap every listed user-facing string,
including labels, descriptions, placeholders, and buttons, with t(). Add
matching keys to the locale catalogs using en.json as the source of truth. Leave
the "Author" fallback unchanged because it is persisted and shared across
locales.
- Around line 90-100: Update the author-name and comment fields in
AddCommentDialog by assigning unique id values to the Input and Textarea, then
set each corresponding label’s htmlFor to the matching id so assistive
technologies associate the labels with their controls.
- Around line 22-27: Update AddCommentDialog’s saved-name flow to use the
existing getStoredName and saveStoredName helpers, storing the saved name in
React state so the UI branch and submit fallback stay consistent. Replace raw
localStorage reads/removal with the helpers, clear the saved-name state in the
“Change Name” handler, and ensure submission does not restore the removed name.

In `@apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx`:
- Around line 31-39: Extract a shared geometry-to-anchor helper used by both
CommentMapOverlay and CommentsPanel.handleZoomTo, covering Point, LineString,
Polygon, MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection.
Select a representative coordinate rather than the first endpoint or polygon
corner, reusing any existing centroid or pole-of-inaccessibility utility before
adding dependencies, and return null only when no valid coordinate can be
derived.
- Around line 136-148: Update renderMarkers to reuse markers keyed by comment id
instead of removing and recreating every marker on each styledata event: remove
markers for deleted comments, reposition existing markers with setLngLat, and
create markers only for comments without one. Preserve the effect cleanup’s full
marker teardown and the existing styledata subscription.
- Around line 90-93: Replace the unsupported hover:scale-115 utility in
CommentMapOverlay with the arbitrary Tailwind class hover:scale-[1.15] so the
intended hover scaling rule is generated.

In `@apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx`:
- Line 284: Replace the physical Tailwind utilities in the CommentsPanel
edit-name and copy-icon controls: change ml-auto to ms-auto and mr-1 to me-1,
preserving the existing spacing and RTL-aware layout behavior.
- Line 134: Update CommentsPanel to use react-i18next’s useTranslation and route
every listed user-facing string, fallback error, and icon-only control title
through t(). Add the corresponding keys to the locale catalogs with en.json as
the source of truth, and use i18next pluralization for the three filter counts
instead of constructing count text in JavaScript.
- Around line 184-207: Collapse handleZoomTo into a single
resolveCommentCoordinates(comment, map) call, removing the feature-specific
layer/feature lookup and zero-area fitBounds path. Preserve the existing
fallback behavior by applying the resolved coordinates through map.flyTo with
Math.max(map.getZoom(), 15) when both coordinates and map are available.

In `@apps/geolibre-desktop/src/components/comments/CommentThread.tsx`:
- Around line 46-51: Update the comment and reply date formatting in
CommentThread using the active react-i18next language instead of undefined as
the toLocaleDateString locale. Obtain i18n.language and pass it to both
formattedDate and the reply timestamp while preserving the existing dateFormat
options.
- Line 89: Update CommentThread to use useTranslation and route all specified
user-facing button titles, anchor labels, Reply, placeholder, and Cancel text
through t(), including icon-only title attributes; add the corresponding keys to
the locale catalogs with en.json as the source of truth. Leave the existing
“Author” fallbacks unchanged and untranslated.
- Line 157: Update the reply thread container in CommentThread to replace the
physical Tailwind utilities pl-2.5 and border-l-2 with the logical equivalents
ps-2.5 and border-s-2, preserving the existing spacing and border styling while
supporting RTL layouts.
- Around line 114-123: Update the delete button handler in CommentThread to show
a translated confirmation prompt before invoking onDelete(comment.id). Only call
onDelete when the user confirms, preserving the existing deletion behavior and
avoiding removal or broadcast when canceled.

In `@apps/geolibre-desktop/src/components/comments/useCommentTool.ts`:
- Around line 103-138: Update the feature-selection logic around userLayerIds to
match feat.source, which uses the collected source IDs, instead of
feat.layer.id. When creating the feature CommentAnchor, store the corresponding
store layer ID so resolveCommentCoordinates can find it, and update the related
resolution/query logic to consistently use the chosen ID namespace for both
layer lookup and queryRenderedFeatures.
- Around line 98-99: Update handleMapClick and the other MapLibre click handlers
to honor the comment tool’s active state, using a shared active-mute state if
appropriate. When the comment tool is enabled, bypass notebook bridge
identification and persistent drawing/picking handlers so the click only places
or attaches a comment; retain existing behavior when it is inactive.

In `@apps/geolibre-desktop/src/components/layout/DesktopShell.tsx`:
- Line 1: Remove the `// `@refresh` reset` directive from the `DesktopShell`
module so edits preserve workspace state. If Fast Refresh warnings remain,
inspect `useRegisterCommentsPanel` and separate the exported `COMMENTS_PANEL_ID`
constant from the hook module; document any remaining necessity only if the
warning cannot otherwise be resolved.
- Around line 2110-2114: Memoize the comment-selection handler in DesktopShell
with useCallback and an empty dependency array, since it only calls the
module-level openRightPanel with COMMENTS_PANEL_ID. Replace the inline
onSelectComment arrow passed to CommentMapOverlay with this stable handler,
placing it near the related comment state.
- Around line 697-712: Refactor the right-panel portal host setup in
DesktopShell to use a single panel-id-to-host map while retaining the existing
browserContentEl and commentsContentEl bindings for their createPortal call
sites. Replace the nested ternary assigning dockContentEl with a lookup by
activePanelId, falling back to pluginContentEl for panels without dedicated
hosts.
- Around line 1981-1992: Wrap the CommentsPanel portal with the existing
SectionErrorBoundary pattern so failures remain isolated from the workspace row.
Move CommentMapOverlay behind SilentErrorBoundary, matching the collaboration
badge rather than allowing it to replace the shared map boundary. Add the
shell.section.commentsPanel translation key to all locale catalogs, using
en.json as the source of truth.

In `@apps/geolibre-desktop/src/components/layout/TopToolbar.tsx`:
- Around line 1292-1299: Update the view.comments command entry to use
t("toolbar.command.viewComments") for its title and pass the exported
COMMENTS_PANEL_ID constant to openRightPanel instead of the "comments" literal.
Add the toolbar.command.viewComments translation key to every locale catalog,
using en.json as the source of truth and preserving the existing English
keywords.

In `@apps/geolibre-desktop/src/hooks/useRegisterCommentsPanel.ts`:
- Around line 16-21: Update the panel registration in useRegisterCommentsPanel
so the user-facing title uses the package’s configured react-i18next instance
and a getter calling t(), allowing live language changes without
re-registration. Follow the existing getTitle pattern and add the corresponding
“Comments” translation to the locale catalogs with en.json as the source of
truth.
- Around line 22-25: Update useRegisterCommentsPanel() to register and collapse
the Comments panel through a passive path without calling
openRightPanel(COMMENTS_PANEL_ID). Preserve Browser as the active panel while
leaving Comments available as a collapsed rail entry, using the existing
DesktopShell panel-registration/collapse APIs rather than activating Comments
during startup.

In `@apps/geolibre-desktop/src/lib/collab-client.ts`:
- Around line 64-71: The createSession contract and its test disagree when
baseUrl is null. Keep the existing throw behavior in createSession, and update
tests/collab-protocol.test.ts lines 149-151 to assert that
createSession("co-edit", null) rejects with the configuration error instead of
expecting a sessionId; no direct change is needed in collab-client.ts.

In `@apps/geolibre-desktop/src/lib/collab-protocol.ts`:
- Around line 85-100: Remove the unused optional origin field and its
accompanying documentation from CommentMutationMessage, since no sender or
receiver uses it. Keep the existing comment-mutation action contract unchanged.

In `@packages/core/src/store.ts`:
- Around line 1014-1020: The replyToComment updater should ignore replies whose
ID already exists in the target comment’s replies. Before appending, use
c.replies.some((r) => r.id === reply.id); preserve existing replies when
duplicated and only append new replies.
- Around line 1006-1036: Update handleMessage’s remote comment-mutation handling
so addComment, replyToComment, toggleResolveComment, and deleteComment apply
through a non-undo-tracked store update, reusing the snapshot-sync path that
clears useAppStore.temporal where appropriate. Ensure remote mutations do not
create local undo entries or set isDirty, while preserving the existing mutation
and de-duplication behavior.

In `@tests/collab-protocol.test.ts`:
- Around line 299-322: Extend the comment-mutation coverage near the existing
“sends comment-mutation client messages correctly” test with a malformed
action.comment case, such as a string instead of an object. Assert that the
server-side session handling rejects or safely ignores the invalid payload,
using the relevant session message-processing symbol from
workers/collab/src/session.ts, while preserving the existing valid
toggle-resolve behavior.

In `@workers/collab/src/session.ts`:
- Around line 659-717: Update handleCommentMutation to validate add comments and
replies as object-shaped payloads before modifying the snapshot, rejecting
invalid actions with an error frame and never persisting malformed entries.
Track whether snapshot persistence succeeds, and call broadcast only after a
successful storage.put; when parsing or persistence fails, report the failure to
the sender instead of broadcasting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5783aa1e-0722-4339-a9a8-256d1ff60ec7

📥 Commits

Reviewing files that changed from the base of the PR and between ecef212 and 66408bd.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (21)
  • apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx
  • apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx
  • apps/geolibre-desktop/src/components/comments/CommentThread.tsx
  • apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx
  • apps/geolibre-desktop/src/components/comments/useCommentTool.ts
  • apps/geolibre-desktop/src/components/layout/DesktopShell.tsx
  • apps/geolibre-desktop/src/components/layout/RemoteCursorsOverlay.tsx
  • apps/geolibre-desktop/src/components/layout/TopToolbar.tsx
  • apps/geolibre-desktop/src/hooks/useCollaboration.ts
  • apps/geolibre-desktop/src/hooks/useRegisterCommentsPanel.ts
  • apps/geolibre-desktop/src/lib/build-project-snapshot.ts
  • apps/geolibre-desktop/src/lib/collab-client.ts
  • apps/geolibre-desktop/src/lib/collab-protocol.ts
  • apps/geolibre-desktop/src/lib/project-broadcast-changed.ts
  • packages/core/src/project.ts
  • packages/core/src/store.ts
  • packages/core/src/types.ts
  • tests/collab-protocol.test.ts
  • tests/comments.test.ts
  • workers/collab/src/protocol.ts
  • workers/collab/src/session.ts

Comment thread apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx Outdated
Comment thread apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx Outdated
Comment thread apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx Outdated
Comment thread apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx Outdated
Comment thread apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx
Comment thread apps/geolibre-desktop/src/lib/collab-protocol.ts
Comment thread packages/core/src/store.ts
Comment thread packages/core/src/store.ts Outdated
Comment thread tests/collab-protocol.test.ts
Comment thread workers/collab/src/session.ts
@HarshShinde0

Copy link
Copy Markdown
Contributor Author
video.mp4

@giswqs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/geolibre-desktop/src/components/comments/useCommentTool.ts (1)

106-136: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Use the correct MapLibre ID namespace for feature anchors.

Line 132 checks feat.layer.id, but layerMap also contains metadata.sourceIds. A rendered style-layer ID does not equal its source ID in general. Feature selection then falls back to a point anchor.

Persist the canonical store layer ID from feat.source. Also update resolveCommentCoordinates to derive a rendered style-layer ID before it passes layers: [layerId] to queryRenderedFeatures. The resolver currently receives the store layer ID, not a MapLibre style-layer ID.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/geolibre-desktop/src/components/comments/useCommentTool.ts` around lines
106 - 136, Update feature-anchor creation in the comment tool to resolve the
canonical store layer through feat.source rather than feat.layer.id, while
preserving the existing feature-ID validation. In resolveCommentCoordinates, map
the received store layer ID to the appropriate rendered MapLibre style-layer ID
before calling queryRenderedFeatures with layers: [layerId], so the query uses
the correct namespace.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx`:
- Around line 98-109: Translate the new comment UI strings using react-i18next:
in apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx lines
98-109 and 138-148, use the component’s t() function for the author-name label,
author placeholder, comment label, and comment placeholder; in
apps/geolibre-desktop/src/components/comments/CommentThread.tsx lines 119-127,
pass a translated delete-confirmation message to window.confirm. Add
corresponding locale entries with en.json as the source of truth, while keeping
persisted fallback author values such as "Author" locale-invariant.

In `@apps/geolibre-desktop/src/hooks/useCollaboration.ts`:
- Around line 305-306: Update the onClose cleanup flow in useCollaboration so
each callback captures its own CollabConnection and only clears or invokes
teardownRef when that connection is still active. Apply the same
connection-identity guard to error handling, preventing stale close callbacks
from affecting the newer connection’s teardown.

In `@packages/core/src/store.ts`:
- Around line 1016-1022: Update the state updater containing the comments map to
track whether the reply was appended; set that flag only when modifying the
matching comment, and return the original state s when no comment changed.
Preserve the existing reply deduplication behavior while only setting isDirty to
true for an actual append.

In `@workers/collab/src/session.ts`:
- Around line 688-690: Update the reply handling branch for action.type ===
"reply" to detect whether action.reply.id already exists in the target comment’s
replies before appending. Preserve the current reply list when the ID is already
present, and persist the snapshot only when the target comment is actually
changed.

---

Outside diff comments:
In `@apps/geolibre-desktop/src/components/comments/useCommentTool.ts`:
- Around line 106-136: Update feature-anchor creation in the comment tool to
resolve the canonical store layer through feat.source rather than feat.layer.id,
while preserving the existing feature-ID validation. In
resolveCommentCoordinates, map the received store layer ID to the appropriate
rendered MapLibre style-layer ID before calling queryRenderedFeatures with
layers: [layerId], so the query uses the correct namespace.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 390c0106-5a02-46fd-b700-04033bd32d36

📥 Commits

Reviewing files that changed from the base of the PR and between 66408bd and 0faa763.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx
  • apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx
  • apps/geolibre-desktop/src/components/comments/CommentThread.tsx
  • apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx
  • apps/geolibre-desktop/src/components/comments/useCommentTool.ts
  • apps/geolibre-desktop/src/hooks/useCollaboration.ts
  • apps/geolibre-desktop/src/lib/collab-protocol.ts
  • packages/core/src/store.ts
  • tests/collab-protocol.test.ts
  • workers/collab/src/session.ts
💤 Files with no reviewable changes (1)
  • apps/geolibre-desktop/src/lib/collab-protocol.ts

Comment thread apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx Outdated
Comment thread apps/geolibre-desktop/src/hooks/useCollaboration.ts
Comment thread packages/core/src/store.ts Outdated
Comment thread workers/collab/src/session.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/geolibre-desktop/src/hooks/useCollaboration.ts (2)

324-334: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Reject the pending connection Promise during disconnect.

If disconnect runs before welcome, Line 334 discards the only resolve and reject callbacks. The Promise returned by the previous start or join call never settles. This can leave the caller in a permanent connecting state.

Capture and reject the pending Promise before clearing the reference and closing the connection.

Proposed fix
 const disconnect = (): void => {
+  const pending = pendingConnectRef.current;
+  pendingConnectRef.current = null;
   teardownRef.current?.();
   teardownRef.current = null;
   connRef.current?.close();
   connRef.current = null;
   selfIdRef.current = null;
   if (restoreTimerRef.current) {
     clearTimeout(restoreTimerRef.current);
     restoreTimerRef.current = null;
   }
-  pendingConnectRef.current = null;
+  pending?.reject(new Error("Connection cancelled."));
 };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/geolibre-desktop/src/hooks/useCollaboration.ts` around lines 324 - 334,
Update disconnect in useCollaboration to capture and reject the pending
connection Promise before clearing pendingConnectRef and closing the connection.
Ensure the existing teardown and cleanup behavior remains unchanged, and settle
only when a pending connection exists.

378-380: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Gate comment edit actions before optimistically updating the store.

useCommentTool.ts and CommentsPanel.tsx call addComment, replyToComment, toggleResolveComment, and deleteComment before sending mutations. sendCommentMutation() only dispatches if collab.isActive, so view-only non-host participants can have remote-rejected mutations reflected locally. Expose the current client edit permission from useCollaboration via CollaborationApi, then gate those store actions on permission as well as remote session state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/geolibre-desktop/src/hooks/useCollaboration.ts` around lines 378 - 380,
Update useCollaboration’s CollaborationApi to expose the current client edit
permission, then update useCommentTool.ts and CommentsPanel.tsx so addComment,
replyToComment, toggleResolveComment, and deleteComment run only when both
collaboration is active and editing is permitted; keep sendCommentMutation
aligned with the same permission gate.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx`:
- Around line 56-76: Update the layer resolution in the CommentMapOverlay
feature-query flow so metadata.sourceIds are matched against active map style
layers’ source fields, producing their style-layer IDs for map.getLayer and
queryRenderedFeatures. Retain layerId only when it is itself a valid MapLibre
layer ID, then continue filtering and querying with the resolved style-layer
IDs.

---

Outside diff comments:
In `@apps/geolibre-desktop/src/hooks/useCollaboration.ts`:
- Around line 324-334: Update disconnect in useCollaboration to capture and
reject the pending connection Promise before clearing pendingConnectRef and
closing the connection. Ensure the existing teardown and cleanup behavior
remains unchanged, and settle only when a pending connection exists.
- Around line 378-380: Update useCollaboration’s CollaborationApi to expose the
current client edit permission, then update useCommentTool.ts and
CommentsPanel.tsx so addComment, replyToComment, toggleResolveComment, and
deleteComment run only when both collaboration is active and editing is
permitted; keep sendCommentMutation aligned with the same permission gate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 60a78496-6679-4785-9f1e-4aed575302c3

📥 Commits

Reviewing files that changed from the base of the PR and between 0faa763 and ca6285c.

📒 Files selected for processing (8)
  • apps/geolibre-desktop/src/components/comments/AddCommentDialog.tsx
  • apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx
  • apps/geolibre-desktop/src/components/comments/CommentThread.tsx
  • apps/geolibre-desktop/src/components/comments/useCommentTool.ts
  • apps/geolibre-desktop/src/hooks/useCollaboration.ts
  • apps/geolibre-desktop/src/i18n/locales/en.json
  • packages/core/src/store.ts
  • workers/collab/src/session.ts

Comment thread apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/geolibre-desktop/src/components/comments/useCommentTool.ts (1)

46-63: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Translate the fallback author name.

"Author" is stored as the comment author when no author name exists, so route it through t() and add the translation key if it does not already exist.

Proposed fix
+const { t } = useTranslation();
+
-        selfName = authorName?.trim() || storedName || "Author";
+        selfName = authorName?.trim() || storedName || t("comments.author");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/geolibre-desktop/src/components/comments/useCommentTool.ts` around lines
46 - 63, Update the fallback assignment in the selfName logic of useCommentTool
to use the existing translation function t() for the "Author" label, while
preserving the priority of authorName and storedName. Add the corresponding
translation key if it is not already defined.

Source: Coding guidelines

apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx (1)

157-187: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Disable comment actions for read-only collaborators.

canModifyComments is only checked inside handleReply, handleToggleResolve, and handleDelete, but CommentThread never receives this permission. The thread renders reply, resolve, and delete controls for every user, so read-only collaborators can still submit actions. Pass the permission state to CommentThread and disable or hide those controls.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx` around lines
157 - 187, Pass canModifyComments from CommentsPanel into each CommentThread,
then use it to disable or hide the thread’s reply, resolve, and delete controls.
Keep the existing guards in handleReply, handleToggleResolve, and handleDelete
so both the UI and action handlers enforce read-only collaborator permissions.
apps/geolibre-desktop/src/hooks/useCollaboration.ts (1)

302-305: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Bind lifecycle callbacks to the current connection only.

CollabConnection keeps a WebSocket event listener around until its socket closes. If replacement or a stale delayed reconnect leaves the old connection open, its old onOpen/onMessage callbacks can still run after connRef.current is overwritten. Pass the owning CollabConnection into attach(...)/handleMessage(...) and ignore these callbacks when connRef.current !== conn.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/geolibre-desktop/src/hooks/useCollaboration.ts` around lines 302 - 305,
Update the connection lifecycle around CollabConnection and the
attach/handleMessage callbacks so each callback receives its owning connection
and exits without acting when connRef.current !== conn. Ensure stale onOpen and
onMessage events from replaced or delayed-reconnect connections cannot mutate
current collaboration state, while preserving behavior for the active
connection.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/geolibre-desktop/src/hooks/useCollaboration.ts`:
- Around line 328-332: Replace the hardcoded “Session disconnected.” error in
the pendingConnectRef rejection flow with i18n.t(...) using a new locale key,
and add the corresponding translation key to every locale catalog. Ensure the
localized error propagates unchanged through the public start and join
connection flows.

---

Outside diff comments:
In `@apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx`:
- Around line 157-187: Pass canModifyComments from CommentsPanel into each
CommentThread, then use it to disable or hide the thread’s reply, resolve, and
delete controls. Keep the existing guards in handleReply, handleToggleResolve,
and handleDelete so both the UI and action handlers enforce read-only
collaborator permissions.

In `@apps/geolibre-desktop/src/components/comments/useCommentTool.ts`:
- Around line 46-63: Update the fallback assignment in the selfName logic of
useCommentTool to use the existing translation function t() for the "Author"
label, while preserving the priority of authorName and storedName. Add the
corresponding translation key if it is not already defined.

In `@apps/geolibre-desktop/src/hooks/useCollaboration.ts`:
- Around line 302-305: Update the connection lifecycle around CollabConnection
and the attach/handleMessage callbacks so each callback receives its owning
connection and exits without acting when connRef.current !== conn. Ensure stale
onOpen and onMessage events from replaced or delayed-reconnect connections
cannot mutate current collaboration state, while preserving behavior for the
active connection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ea62ab75-dc03-475d-91be-0e1be1b8f015

📥 Commits

Reviewing files that changed from the base of the PR and between ca6285c and 40a7462.

📒 Files selected for processing (4)
  • apps/geolibre-desktop/src/components/comments/CommentMapOverlay.tsx
  • apps/geolibre-desktop/src/components/comments/CommentsPanel.tsx
  • apps/geolibre-desktop/src/components/comments/useCommentTool.ts
  • apps/geolibre-desktop/src/hooks/useCollaboration.ts

Comment thread apps/geolibre-desktop/src/hooks/useCollaboration.ts
@HarshShinde0

Copy link
Copy Markdown
Contributor Author

Can you please review it @giswqs whenever you have time.
Many Thanks!

video.mp4
@giswqs

@giswqs

giswqs commented Aug 1, 2026

Copy link
Copy Markdown
Member

@HarshShinde0 This is an amazing feature! Thank you for implementing it and sharing the demo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants