Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6028774
feat(review): add comments and suggestion mode
ThisIs-Developer Jul 12, 2026
65a77c7
style(review): align controls with app accent
ThisIs-Developer Jul 12, 2026
a36bd92
feat(review): improve review management controls
ThisIs-Developer Jul 12, 2026
27de057
fix(review): wrap mobile review toolbar
ThisIs-Developer Jul 12, 2026
4ea6b03
Merge origin/main into feature/comments-suggestion-mode
Copilot Jul 12, 2026
f6c310a
fix(share): allow Cloudflare preview origins
ThisIs-Developer Jul 13, 2026
e0bc2ac
fix(live-share): allow Cloudflare preview origins
ThisIs-Developer Jul 13, 2026
7bf20e6
feat(live-share): synchronize review feedback
ThisIs-Developer Jul 13, 2026
504641a
feat(reset): improve all-files confirmation
ThisIs-Developer Jul 13, 2026
3375909
style(reset): shorten confirmation copy
ThisIs-Developer Jul 13, 2026
f1ee6bc
feat(review): refine responsive review UI
ThisIs-Developer Jul 13, 2026
aab0f17
style(review): align target buttons with toolbar
ThisIs-Developer Jul 13, 2026
976eb0c
style(review): switch empty targets to plus icon
ThisIs-Developer Jul 13, 2026
9699162
fix(review): improve target feedback navigation
ThisIs-Developer Jul 13, 2026
31b5aba
fix(review): support follow-up and edited feedback
ThisIs-Developer Jul 13, 2026
894842e
fix(review): keep saved feedback visible
ThisIs-Developer Jul 13, 2026
4e6d44b
fix(review): separate read and add controls
ThisIs-Developer Jul 13, 2026
795a83f
style(review): merge count into toolbar button
ThisIs-Developer Jul 13, 2026
4773acd
feat(review): add lifecycle timestamps
ThisIs-Developer Jul 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable code changes to **Markdown Viewer** are documented here.
Non-code commits (documentation, planning, README-only updates) are excluded.

## Unreleased

- **Comments & Suggestions UI:** Simplified the Review panel, composer, suggestion cards, and preview pins using the app's existing accent, button, border, hover, disabled, and theme tokens. The main toolbar Review button shows its open-item count inline beside the existing icon instead of using a separate count button. Review target buttons match the main toolbar controls, align in a straight column at the preview's right edge, and show a plus before feedback exists. Reviewed targets provide separate controls for reading saved feedback and adding another item, so opening the review count no longer opens the composer. Threads now record and display opened/closed date and time, and copied summaries include lifecycle dates plus open/resolved totals. Opening a new tab closes Review mode automatically. YAML frontmatter tables are reviewable, reviewed text has clear spacing from its side marker, and existing comments and suggestions can be edited in place. Saved feedback appears before the composer in one shared scroll area, keeping previous reviews visible in short panels while new and edited feedback scrolls into view. Refined the layout into a compact desktop side panel, tablet drawer, and touch-friendly mobile bottom sheet without introducing a separate color palette.

---

## v3.9.1

- **Description:** Improved export reliability, file workflows, diagram insertion, shared-document safety, and browser compatibility.
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,12 @@ Markdown Viewer handles the usual Markdown basics, but its real value is helping
- **STL 3D Model Renderer**: inspect 3D model previews alongside technical notes.
- **ABC Music Player & Sheet Music Viewer**: render sheet music and play notation in the browser.

3. **Live Share Temporary Rooms**: collaborate in real time for quick editing sessions, reviews, or pair-writing, with server-checked host, editable, and view-only capabilities.
4. **Share Snapshot Links**: create view-only or editable point-in-time links when you need to send a document state quickly. Large stored snapshots expire after 90 days.
5. **LaTeX Math Notation**: render inline and display formulas with MathJax, useful for math-heavy notes, papers, and technical explanations.
6. **Markdown to PDF, HTML & PNG Export**: export Markdown, HTML, PNG, Browser Print / Save as PDF, or Legacy Raster PDF for documents that need sharing, printing, or archiving.
7. **Privacy and Security Controls**: use Private mode to prevent document persistence, clear saved local data, and rely on sanitized previews, hardened export HTML, and restricted desktop native APIs.
3. **Comments & Suggestions**: open a read-only Review workspace and attach feedback to rendered YAML frontmatter tables, headings, paragraphs, code blocks, and diagrams without changing the Markdown source. The responsive side panel uses the same controls and theme as the rest of the app.
4. **Live Share Temporary Rooms**: collaborate in real time for quick editing sessions, reviews, or pair-writing, with server-checked host, editable, and view-only capabilities.
5. **Share Snapshot Links**: create view-only or editable point-in-time links when you need to send a document state quickly. Large stored snapshots expire after 90 days.
6. **LaTeX Math Notation**: render inline and display formulas with MathJax, useful for math-heavy notes, papers, and technical explanations.
7. **Markdown to PDF, HTML & PNG Export**: export Markdown, HTML, PNG, Browser Print / Save as PDF, or Legacy Raster PDF for documents that need sharing, printing, or archiving.
8. **Privacy and Security Controls**: use Private mode to prevent document persistence, clear saved local data, and rely on sanitized previews, hardened export HTML, and restricted desktop native APIs.

For the full feature list, details, limitations, and privacy notes, see the [features reference](wiki/Features.md#product-summary).

Expand Down Expand Up @@ -128,6 +129,7 @@ Markdown Viewer works well as a Markdown diagram editor for technical notes, doc

## Sharing, Collaboration, and Export

- **Comments & Suggestions** provides a per-document review layer. Review pins attach comments or suggestions to rendered YAML frontmatter tables, headings, paragraphs, code blocks, and diagrams while the Markdown stays read-only. Empty targets show a plus. Reviewed targets show two separate controls: the review count opens saved feedback, and the adjacent plus opens the composer for another item. Threads show their opened and closed date/time, can be edited, resolved, reopened, deleted, or copied in a detailed Markdown summary. Opening a new tab closes Review mode automatically. The interface uses a desktop side panel, a tablet drawer, and a touch-friendly mobile bottom sheet. Review data stays with the local tab workspace, is excluded from Share Snapshot, and is relayed only while an existing Live Share room is active.
- **Share Snapshot** creates quick links for point-in-time Markdown sharing. Small documents can stay in the URL hash; larger snapshots use temporary Cloudflare KV storage for up to 90 days when that backend is configured. Snapshot links are bearer links: anyone who has the link can open it.
<p align="center">
<img src="https://github.com/user-attachments/assets/e62ca1a0-011a-4b01-90f9-e72638b9a6d5" alt="Share Snapshot" width="90%" />
Expand Down
113 changes: 107 additions & 6 deletions desktop-app/resources/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ <h1 class="h4 mb-0 me-2">Markdown Viewer<span class="visually-hidden"> - Online
<i class="bi bi-broadcast"></i> <span class="btn-text">Live Share</span>
</button>
<div id="live-share-toolbar-participants" class="live-share-toolbar-participants" aria-label="Live Share participants" hidden></div>

<button id="review-toggle" class="tool-button" type="button" title="Open comments and suggestions" aria-label="Open comments and suggestions" aria-controls="review-panel" aria-expanded="false" aria-pressed="false">
<i class="bi bi-chat-square-text"></i><span id="review-toolbar-count" class="review-toolbar-count" aria-hidden="true" hidden>0</span><span class="btn-text">Review</span>
</button>

<div class="dropdown me-1">
<button class="tool-button dropdown-toggle" type="button" id="languageDropdown" data-bs-toggle="dropdown" aria-expanded="false" title="Switch Language">
Expand Down Expand Up @@ -236,6 +240,11 @@ <h2 class="h5 m-0">Menu</h2>
<span class="mobile-menu-item-label"><i class="bi bi-broadcast me-2"></i><span id="mobile-live-share-label">Live Share</span></span>
<span id="mobile-live-share-participants" class="live-share-toolbar-participants mobile-live-share-participants" aria-label="Live Share participants" hidden></span>
</button>

<button id="mobile-review-toggle" class="mobile-menu-item" type="button" title="Open comments and suggestions" aria-controls="review-panel" aria-expanded="false" aria-pressed="false">
<span><i class="bi bi-chat-square-text me-2"></i>Review</span>
<span id="mobile-review-count-badge" class="mobile-review-count-badge" aria-hidden="true" hidden>0</span>
</button>

<div class="mobile-menu-item dropdown w-100 p-0 border-0">
<button class="mobile-menu-item w-100 text-start dropdown-toggle" type="button" id="mobileLanguageDropdown" data-bs-toggle="dropdown" aria-expanded="false" title="Switch Language">
Expand Down Expand Up @@ -338,12 +347,35 @@ <h2 class="h5 m-0">Menu</h2>
</div>

<!-- Reset Confirmation Modal -->
<div id="reset-confirm-modal" class="reset-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="reset-modal-title" aria-hidden="true" style="display:none;">
<div class="reset-modal-box reset-modal-box--wide">
<p id="reset-modal-title" class="reset-modal-message">Are you sure you want to delete all files?</p>
<div id="reset-confirm-modal" class="reset-modal-overlay modal-overlay" role="dialog" aria-modal="true" aria-labelledby="reset-modal-title" aria-describedby="reset-modal-description" aria-hidden="true" style="display:none;">
<div class="reset-modal-box modal-box">
<div class="modal-header">
<p id="reset-modal-title" class="reset-modal-message">Reset all files?</p>
<button type="button" class="modal-close-btn" id="reset-modal-close" aria-label="Close reset confirmation dialog">
<i class="bi bi-x-lg" aria-hidden="true"></i>
</button>
</div>
<p id="reset-modal-description" class="modal-subtext">This will remove all open files and review items. Unsaved changes cannot be recovered.</p>
<div class="reset-modal-actions">
<button class="reset-modal-btn reset-modal-cancel" id="reset-modal-cancel">Cancel</button>
<button class="reset-modal-btn reset-modal-confirm" id="reset-modal-confirm">Delete All</button>
<button type="button" class="reset-modal-btn reset-modal-cancel" id="reset-modal-cancel">Cancel</button>
<button type="button" class="reset-modal-btn reset-modal-confirm" id="reset-modal-confirm">Reset all</button>
</div>
</div>
</div>

<!-- Review Delete Confirmation Modal -->
<div id="review-delete-modal" class="reset-modal-overlay modal-overlay" role="dialog" aria-modal="true" aria-labelledby="review-delete-title" aria-describedby="review-delete-description" aria-hidden="true" style="display:none;">
<div class="reset-modal-box modal-box">
<div class="modal-header">
<p id="review-delete-title" class="reset-modal-message">Delete review item?</p>
<button type="button" class="modal-close-btn" id="review-delete-close" aria-label="Close review deletion dialog">
<i class="bi bi-x-lg" aria-hidden="true"></i>
</button>
</div>
<p id="review-delete-description" class="modal-subtext">This comment or suggestion will be permanently deleted.</p>
<div class="reset-modal-actions">
<button type="button" class="reset-modal-btn reset-modal-cancel" id="review-delete-cancel">Cancel</button>
<button type="button" class="reset-modal-btn reset-modal-confirm" id="review-delete-confirm">Delete</button>
</div>
</div>
</div>
Expand Down Expand Up @@ -538,6 +570,7 @@ <h3 class="modal-section-title">Application shortcuts</h3>
<ul class="modal-list">
<li>Use the view buttons in the toolbar to switch between Editor, Split, and Preview modes.</li>
<li>Sync scrolling is available in Split view to keep the editor and preview aligned.</li>
<li>Review opens a read-only preview where you can comment on or suggest changes to headings, paragraphs, code blocks, and diagrams.</li>
<li>Import, Export, Copy, Share, and Theme toggle actions are always available in the header toolbar.</li>
</ul>
</div>
Expand Down Expand Up @@ -1069,7 +1102,75 @@ <h3 class="modal-section-title">Open-source credits</h3>
<div class="skeleton-placeholder skeleton-line skeleton-w45"></div>
</div>
</div>
</div>
<div id="review-pins-layer" class="review-pins-layer" role="group" aria-label="Review pins" hidden></div>
</div>
<button id="review-panel-backdrop" class="review-panel-backdrop" type="button" aria-label="Close comments and suggestions" hidden></button>
<aside id="review-panel" class="review-panel" aria-labelledby="review-panel-title" hidden>
<div class="review-panel-header">
<div>
<h2 id="review-panel-title">Comments &amp; suggestions</h2>
<p id="review-panel-summary" class="review-panel-summary">No open feedback</p>
</div>
<button id="review-panel-close" class="review-icon-btn" type="button" aria-label="Close comments and suggestions" title="Close review mode">
<i class="bi bi-x-lg" aria-hidden="true"></i>
</button>
</div>

<div class="review-panel-toolbar">
<div class="review-filter-group" role="group" aria-label="Filter review items">
<button class="review-filter-btn is-active" type="button" data-review-filter="open" aria-pressed="true">Open</button>
<button class="review-filter-btn" type="button" data-review-filter="resolved" aria-pressed="false">Resolved</button>
<button class="review-filter-btn" type="button" data-review-filter="all" aria-pressed="false">All</button>
</div>
<div class="review-panel-actions" role="group" aria-label="Review actions">
<button id="review-copy-summary" class="review-icon-btn" type="button" aria-label="Copy review summary" title="Copy review summary" disabled>
<i class="bi bi-clipboard" aria-hidden="true"></i>
</button>
<button id="review-resolve-all" class="review-icon-btn" type="button" aria-label="Resolve all open review items" title="Resolve all open review items" disabled>
<i class="bi bi-check2-all" aria-hidden="true"></i>
</button>
<button id="review-delete-all" class="review-icon-btn is-danger" type="button" aria-label="Delete all review items" title="Delete all review items" disabled>
<i class="bi bi-trash3" aria-hidden="true"></i>
</button>
</div>
</div>

<div class="review-panel-body">
<div id="review-list" class="review-list" aria-live="polite"></div>
<div id="review-empty-state" class="review-empty-state">
<i class="bi bi-chat-square-dots" aria-hidden="true"></i>
<h3>No open feedback</h3>
<p>Select a comment pin in the preview to add feedback.</p>
</div>

<section id="review-composer" class="review-composer" aria-labelledby="review-composer-title" hidden>
<div class="review-composer-heading">
<div>
<p class="review-panel-eyebrow">Selected block</p>
<h3 id="review-composer-title">Add feedback</h3>
</div>
<button id="review-composer-cancel" class="review-icon-btn" type="button" aria-label="Cancel feedback" title="Cancel">
<i class="bi bi-x" aria-hidden="true"></i>
</button>
</div>
<p id="review-composer-anchor" class="review-anchor-preview"></p>
<div class="review-kind-group" role="group" aria-label="Feedback type">
<button class="review-kind-btn is-active" type="button" data-review-kind="comment" aria-pressed="true">
<i class="bi bi-chat-left-text" aria-hidden="true"></i> Comment
</button>
<button class="review-kind-btn" type="button" data-review-kind="suggestion" aria-pressed="false">
<i class="bi bi-pencil-square" aria-hidden="true"></i> Suggestion
</button>
</div>
<label id="review-feedback-label" class="review-feedback-label" for="review-feedback-input">Comment</label>
<textarea id="review-feedback-input" class="review-feedback-input" rows="4" maxlength="2000" placeholder="Leave a focused comment for the author..."></textarea>
<div class="review-composer-footer">
<span id="review-feedback-count" class="review-feedback-count">0 / 2000</span>
<button id="review-feedback-submit" class="review-primary-btn" type="button" disabled>Add comment</button>
</div>
</section>
</div>
</aside>
</main>
</div>

Expand Down
Loading
Loading