Document Comments
Introduction
Sutram offers a powerful document commenting system that lets project teams collaborate directly on documents by placing comments at specific locations. Comments are anchored to precise positions within PDFs, images, Office documents, markdown files, and CAD/BIM models, enabling contextual discussions without leaving the platform.
Key Features
- Contextual Anchoring: Three different anchoring methods depending on the file type
- Threaded Discussions: Reply to comments to create threaded conversations
- Real-Time Collaboration: See comments from other users instantly via PubSub
- Multi-Format Support: Works with PDFs, images, Office documents (Word, Excel, PowerPoint), markdown, and CAD/BIM files
- Comment Resolution: Mark comments as resolved once the issues have been addressed
- Visual Markers: Numbered balloon-style markers show the location of comments directly on the documents
- Comments Panel: Bottom panel with filters (All/Open/Resolved) to navigate and locate comments
- Navigation: Click markers or panel items to jump to specific comments
- 6-Language Support: Full internationalization (English, Portuguese, Spanish, French, German, Italian)
Anchoring Methods by File Type
The system uses three distinct anchoring methods depending on the file type, each optimized for how users interact with that kind of content:
1. Positional Anchoring (PDF and Images)
Used for: PDF files, Images, Office documents (converted to PDF)
How it works: The user clicks anywhere in the document and the comment is anchored to relative coordinates (0.0-1.0).
| File Type | Position Type | Storage | User Interaction |
|---|---|---|---|
pdf_page |
pdf_page_number + pdf_relative_x/y (0.0-1.0) |
Click anywhere on the page | |
| Images | image |
pdf_relative_x/y (0.0-1.0) |
Click anywhere on the image |
| Office | pdf_page |
Converted to PDF first, same as PDF | Click on the converted PDF |
Advantages:
- Works regardless of zoom level or window size
- Precise positioning on visual content
- Simple and intuitive for users
Button text: "Click to add..." (translated into 6 languages)
2. Camera View Anchoring (CAD/BIM)
Used for: 2D CAD drawings (DWG, DXF), 3D CAD models (IFC, RVT, etc.)
How it works: The user clicks on the model and the comment captures both the world coordinates and the camera state (view position, zoom, rotation).
| File Type | Position Type | Storage | User Interaction |
|---|---|---|---|
| 3D CAD | aps_3d |
aps_world_coordinates {x,y,z} + aps_db_id + aps_camera_state |
Click on the 3D model surface |
| 2D CAD | aps_2d |
aps_world_coordinates {x,y,z} + aps_sheet_guid + aps_camera_state |
Click on the 2D drawing |
Advantages:
- Markers track the model during zoom/pan/rotation
- "Go to location" restores exactly the view the comment author saw
- Works with exploded views and section planes
- Element ID captured for future integrations
Button text: "Click to add..." (translated into 6 languages)
3. Text-Anchored Comments (markdown)
Used for: markdown files (in the viewer and in the editor)
How it works: The user selects text (instead of clicking) and the comment is anchored to the selected text with surrounding context for resilience against edits.
| File Type | Position Type | Storage | User Interaction |
|---|---|---|---|
| markdown | markdown |
text_anchor {exact_text, prefix, suffix} + pdf_relative_y (fallback) |
Select text to comment |
Text Anchor Structure:
{
"exact_text": "the selected text",
"prefix": "50 characters before the selection",
"suffix": "50 characters after the selection",
"selection_length": 18
}
Advantages:
- Comments survive document edits (text-based search, not pixel position)
- The prefix/suffix context helps locate the text even if the exact match moves
- Visual highlighting of the commented text in the viewer
- Mobile support with a floating "Comment" button
Button text: "Select text..." (translated into 6 languages)
Mobile Experience:
- Touch device detected automatically
- The user long-presses to select text
- A floating "Comment" button appears below the selection (avoids conflict with the native menu)
- A 600ms debounce lets the user adjust the selection handles before the button appears
How It Works
Enabling Comment Mode
- Open a document preview (PDF, image, markdown, Office, or CAD file)
- Click the comments button in the preview toolbar
- The overlay is activated and markers appear for existing comments
- The Comments Panel appears at the bottom with filter options
Adding a Comment
The interaction differs by file type:
PDF, Images, Office, CAD
- With comment mode enabled, click Add in the Comments Panel
- Click on the document at the desired location
- A modal appears with a text field
- Type your comment text
- Click Post Comment to create the comment
- A numbered marker appears at the clicked location
markdown
- With comment mode enabled, click Add in the Comments Panel
- Select text by clicking and dragging (desktop) or long-pressing and dragging the handles (mobile)
- On desktop: the modal opens immediately after the selection
- On mobile: tap the floating "Comment" button that appears below the selection
- Type your comment text
- Click Post Comment to create the comment
- A numbered marker appears in the left margin, aligned with the selected text
Viewing Existing Comments
- Markers: Numbered balloon-style markers show the location of comments
- Purple markers: Open comments
- Green markers: Resolved comments
- Orange badge: Number of replies
- Click the marker: Opens the comment thread modal
- Comments Panel: Bottom panel showing all comments
- Expand/collapse by clicking the header
- Filter by status: All / Open / Resolved
- Click any comment to navigate to its location
- Navigation: Use "Go to location" or the panel to jump to comments
Replying to Comments
- Click an existing comment marker (or select it in the Comments Panel)
- The thread modal opens showing the original comment and any replies
- Type your reply in the text field
- Click Post reply to add your reply
Resolving Comments
- Open a comment thread
- Click Mark as resolved (button above the reply area)
- The marker turns green to indicate the resolution
- Resolved comments can be Reopened from the modal actions
Deleting Comments
- Open a comment thread
- Click the Delete button (visible only to the comment author or project admin)
- Confirm the deletion
- The marker is removed from the document
Office Documents (Word, Excel, PowerPoint)
Office files require special handling because comments need a static surface for positioning.
How It Works
- Project configuration: "Allow comments on Office files" must be enabled
- First activation: When you click the comments button on an Office file:
- If the PDF is cached: Switches to the PDF viewer immediately
- If not cached: Shows the "Converting document..." loading state
- Conversion: LibreOffice converts the Office file to PDF (run once, cached permanently)
- Result: The PDF viewer with the comment overlay appears
- Badge: The "Comment mode" badge appears in the header when viewing the converted PDF
Configuration
Project owners can enable comments on Office files in the Project Settings:
- Navigate to Settings > File Settings
- Enable "Allow comments on Office files"
- Save the settings
Limitations
- Comments are positioned on the PDF conversion, not the original Office file
- Complex formatting may render differently in the PDF
- Excel formulas show only the calculated values
- PowerPoint animations/transitions are lost
CAD/BIM Files (Autodesk APS)
The commenting system integrates fully with the Autodesk Viewer for CAD and BIM files.
3D Models (IFC, RVT, etc.)
For 3D models, comments are anchored using:
- World Coordinates: The 3D point where the user clicked
- Element ID: The specific model element (if the hit test succeeds)
- Camera State: The exact view position when the comment was created
Behavior:
- Markers update their position in real time as you rotate/zoom the model
- "Go to location" restores exactly the camera view from when the comment was created
- Works with exploded views and section planes
2D Drawings (DWG, DXF)
For 2D drawings, comments use:
- Model Coordinates: Position in drawing units (not screen pixels)
- Sheet GUID: Identifies which sheet the comment is on
Behavior:
- Markers stay fixed to the drawing points during zoom/pan
- Camera change events trigger the re-rendering of the markers
- Works across different zoom levels and pan positions
Technical Details
The system uses Autodesk Viewer SDK methods:
| Operation | Method |
|---|---|
| Get click position (3D) | viewer.impl.hitTest() |
| Get click position (2D) | viewer.clientToWorld() |
| Render marker position | viewer.impl.worldToClient() |
| Navigate to comment | viewer.restoreState() |
| Track camera changes | CAMERA_CHANGE_EVENT listener |
Real-Time Collaboration
Comments are synchronized in real time across all connected users.
PubSub Topics
Topic format: document_comments:{content_item_id}
Events
| Event | Description |
|---|---|
comment_added |
New comment created by another user |
comment_updated |
Comment edited, reply added, or status changed |
comment_deleted |
Comment removed by another user |
Behavior
- New markers appear instantly when other users add comments
- Reply counts are updated in real time
- Resolution status is synchronized across all viewers
- If you are viewing a deleted comment, the modal closes automatically
User Interface
Comment Markers
Markers use a chat balloon design with a pointer:
┌───────┐
│ 1.2 │ ← Number (page.index or just index)
└───┬───┘
▽ ← Pointer indicates the exact position
Style:
- Background: Indigo (#6366f1) for open, Green (#22c55e) for resolved
- Reply badge: Orange (#f97316) circle in the top-right corner
- Hover effect: Slight scale-up (1.1x)
- Shadow: Drop shadow for visibility on any background
Comment Modal
The modal displays:
Header:
- Name and avatar of the comment author
- Timestamp (relative, e.g., "2 hours ago")
- Position information (e.g., "Page 3" or "3D Point")
Body:
- Comment text
- Replies (threaded, chronological)
- Text field for replying
Actions (thread view):
- Mark as resolved: Button above the reply form (green, highlighted)
- Post reply: Send reply button
- Delete: Trash icon (author/admin only)
- Reopen: Available when the comment is resolved
- Close: Dismiss modal
Architecture
Database Schema
Table: document_comments
| Column | Type | Description |
|---|---|---|
id |
UUID | Primary key |
content |
Text | Comment text |
content_item_id |
UUID | FK to content_items |
user_id |
UUID | FK to users (author) |
project_id |
UUID | FK to projects |
parent_id |
UUID | FK to document_comments (for replies) |
position_type |
String | pdf_page, image, markdown, aps_3d, aps_2d |
pdf_page_number |
Integer | Page number (PDF only) |
pdf_relative_x |
Float | X position 0.0-1.0 (or pixels for markdown) |
pdf_relative_y |
Float | Y position 0.0-1.0 (or pixels for markdown) |
aps_world_coordinates |
Map | {x, y, z} for CAD |
aps_db_id |
Integer | Autodesk element ID |
aps_camera_state |
Map | Viewer state for navigation |
aps_sheet_guid |
String | 2D sheet identifier |
resolved |
Boolean | Resolution status |
resolved_at |
DateTime | When it was resolved |
resolved_by_id |
UUID | FK to users |
inserted_at |
DateTime | Creation timestamp |
updated_at |
DateTime | Last modification |
Backend Modules
| Module | Purpose |
|---|---|
Sutram.Content.DocumentComment |
Ecto schema with validations |
Sutram.Content |
CRUD functions for comments |
SutramWeb.ProjectLive.Content.CommentHandler |
LiveView event handlers |
SutramWeb.ProjectLive.Components.CommentModal |
Modal LiveComponent |
SutramWeb.ProjectLive.Components.CommentsPanel |
Bottom panel with filters |
SutramWeb.ProjectLive.Components.PreviewModal |
Preview with overlay |
Frontend (JavaScript)
| File | Purpose |
|---|---|
assets/js/hooks/comment_overlay.js |
Main overlay hook |
assets/js/viewers/pdf_viewer.js |
PDF viewer with page tracking |
assets/js/viewers/autodesk_viewer.js |
CAD viewer with getViewerInstance() |
Core Functions
CommentOverlay Hook:
calculatePdfPosition(): Convert click to PDF coordinatescalculateImagePosition(): Convert click to image coordinatescalculateMarkdownPosition(): Convert click to markdown pixel coordinatescalculateApsPosition(): Convert click to CAD world coordinatescalculateScreenPosition(): Convert stored position to screen pixelsrenderMarkers(): Draw all visible markersnavigateToComment(): Scroll/zoom to the comment location
Configuration
Project Settings
| Setting | Default | Description |
|---|---|---|
allow_office_comments |
false |
Enable comments on Office files |
Application Settings
Comments are enabled by default for:
- PDF files
- Image files
- CAD files (when APS is configured)
Office files require explicit opt-in at the project level due to the need for PDF conversion.
Troubleshooting
Comments Not Appearing
Cause: Comment mode not enabled
Solution:
- Click the comments button in the preview toolbar
- Wait for the markers to render
- Check the browser console for errors
Markers in the Wrong Position
Cause: Resizing or zoom changed after the markers were rendered
Solution:
- Markers reposition automatically when resizing/zooming
- If they are still wrong, close and reopen the preview
CAD Comments Not Saving
Cause: APS viewer not fully loaded
Solution:
- Wait for the 3D model to load completely
- Try clicking on a visible surface
- Check that the viewer responds to navigation
Office Comment Button Missing
Cause: Project setting not enabled
Solution:
- Go to Project Settings > File Settings
- Enable "Allow comments on Office files"
- Save and refresh the page
API Reference
LiveView Events (Client to Server)
| Event | Payload | Description |
|---|---|---|
position_selected |
Position data | User clicked to add a comment |
marker_clicked |
{comment_id, marker_number} |
User clicked an existing marker |
create_comment |
{content} |
Save new comment |
create_reply |
{content, parent_id} |
Add reply to thread |
resolve_comment |
{comment_id} |
Mark as resolved |
reopen_comment |
{comment_id} |
Reopen resolved comment |
delete_comment |
{comment_id} |
Remove comment |
navigate_to_comment |
{comment_id} |
Go to location |
request_markers |
{content_item_id} |
Request initial markers |
Push Events (Server to Client)
| Event | Payload | Description |
|---|---|---|
render_markers |
{markers: [...]} |
Complete list of markers |
add_marker |
{marker: {...}} |
New individual marker |
update_marker |
{marker: {...}} |
Updated marker data |
remove_marker |
{comment_id} |
Delete marker |
navigate_to_comment |
{comment: {...}} |
Trigger navigation |
Version History
| Version | Date | Changes |
|---|---|---|
| v0.58.0 | 12/22/2025 | Initial PDF comments with threads |
| v0.59.0 | 12/23/2025 | Comments in the Chat context |
| v0.60.0 | 12/24/2025 | Support for comments on images |
| v0.61.0 | 12/24/2025 | Comments on Office files (via PDF) |
| v0.61.1 | 12/24/2025 | Comments on CAD/APS (2D and 3D) |
| v0.62.0 | 12/24/2025 | Onboarding tip in a toast |
| v0.63.0 | 12/25/2025 | Comments Panel (V3) - bottom panel with filters and navigation |
| v0.64.0 | 12/26/2025 | Support for comments on markdown |
| v0.64.1 | 12/26/2025 | UI improvements: reorganized modal actions, toast tip removed |
| v0.65.0 | 12/26/2025 | Comment mode in the markdown editor with manual position adjustment |
| v0.65.1 | 12/29/2025 | Mobile text selection support for markdown comments |
| v0.65.2 | 12/29/2025 | UX improvements: floating button positioned below the selection to avoid the native menu |
| v0.65.3 | 12/29/2025 | Internationalization: floating "Comment" button translated into 6 languages |
Comments Panel (V3)
The Comments Panel is a bottom panel that lists all of the document's comments, providing a unified navigation experience for mobile and desktop.
Layout
The panel uses a bottom-panel design (unified for mobile and desktop):
┌─────────────────────────────────────────────────┐
│ │
│ Viewer (PDF/Image/CAD) │
│ │
│ 📍 │
│ │
├─────────────────────────────────────────────────┤
│ 💬 4 comments ▼ │ ← Click expands
├─────────────────────────────────────────────────┤
│ ◉ All ○ Open ○ Resolved │ ← Filters
├─────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────┐ │
│ │ 🗨️1 👤 John · 2h ago │ │
│ │ Check whether the quota is correct... │ │
│ └─────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 🗨️2 👤 Mary · 1d ago ✅ │ │
│ │ Conflict with the existing structure │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
States
| State | Description |
|---|---|
| Minimized | Shows only the header with the comment count (48px height) |
| Expanded | Shows filters and a scrollable list (max 50vh) |
Features
- Toggle: Click the header to expand/collapse
- Filters: All / Open / Resolved (radio buttons)
- Comment List: Scrollable list with balloon markers in the same style as the canvas
- Navigation: Click any comment to jump to its location (page change for PDF, camera restore for CAD)
- Real-time: Updates automatically via the existing PubSub
Marker Style
Comments in the list use the same balloon marker style as the canvas:
┌───────┐
│ 1 │ ← Number (insertion order)
└───┬───┘
▽ ← Pointer (chat balloon tail)
- Background: Indigo (#6366f1) for open, Green (#22c55e) for resolved
- Reply badge: Orange (#f97316) in the top-right corner
- Drop shadow: For visibility
Technical Details
New Component: SutramWeb.ProjectLive.Components.CommentsPanel
Props:
comments- List of DocumentComment structsexpanded- Boolean (panel state)filter- Atom (:all, :open, :resolved)
Events (sent to the parent via send/2):
{:comments_panel, :toggle}- Toggle expand/collapse{:comments_panel, :filter, filter}- Change filter{:comments_panel, :go_to_comment, comment_id}- Navigate to comment
State Management (in the Content LiveView):
comments_panel_expanded- Booleancomments_panel_filter- Atom
Comment Mode in the markdown Editor (v0.65.0)
The markdown editor includes a dedicated comment mode that lets users view and reposition comment markers while editing. This solves the problem where markers become misaligned after editing the markdown content (since markdown uses absolute pixel coordinates).
Two Modes
| Mode | Description |
|---|---|
| Editing (default) | Normal Milkdown WYSIWYG editor, no visible markers |
| Comments | Rendered preview with comment overlay and side panel |
Layout (Comment Mode)
┌─────────────────────────────────────────────────────────────────┐
│ ← Back [Editing] [Comments 📍3] Upload │ Header │
├─────────────────────────────────────┬───────────────────────────┤
│ │ 💬 3 comments │
│ markdown Preview │ ─────────────────────────│
│ Rendered (read-only) │ ◉ All ○ Open ○ Resolved │
│ │ ─────────────────────────│
│ 📍 Marker 1 │ [1] John · 2h ago │
│ │ Check this section │
│ 📍 Marker 2 │ [Adjust] [Go to] │
│ │ ─────────────────────────│
│ │ [2] Mary · 1d ago ✅ │
│ │ Fixed │
└─────────────────────────────────────┴───────────────────────────┘
Manual Position Adjustment
When the markdown content is edited, comment markers may become misaligned because they use absolute pixel coordinates. Users can manually reposition the markers:
- Enter Comment mode in the markdown editor
- Find the misaligned comment in the side panel
- Click the "Adjust position" button
- The cursor changes to a crosshair, and the side panel shows "Click the new position"
- Click the correct location in the preview
- The marker moves to the new position and is saved
Mobile Restriction
Note: Comment mode is not available on mobile devices (viewport < 768px). A tooltip on the disabled button explains: "Use a desktop computer to manage comments".
Technical Details
New Assigns (in markdown_editor.ex):
editor_mode- Atom (:editing|:comments)comments- List of DocumentComment structscomments_panel_expanded- Booleancomments_panel_filter- Atom (:all|:open|:resolved)repositioning_comment_id- UUID or nil
New Events:
toggle_editor_mode- Toggle between editing and comment modesstart_reposition- Enter reposition mode for a specific commentcancel_reposition- Exit reposition modeupdate_marker_position- Save the new position from the reposition clickgo_to_comment- Navigate/scroll to the comment location
JavaScript Changes (comment_overlay.js):
- Added
repositioningCommentIdstate - Added
enter_reposition_mode/exit_reposition_modeevent handlers - Modified click handler to detect reposition mode and send
update_marker_position - Updated markdown element selectors to work in both the viewer and the editor
Document Version: 1.3 Last Updated: December 29, 2025 Author: Sutram Development Team