Redesign FwLite comments panel with responsive layout - #2470
Redesign FwLite comments panel with responsive layout#2470hahn-kev-bot wants to merge 24 commits into
Conversation
Split the monolithic dialog into focused components and keep reply/edit draft text local to avoid Svelte bind errors on new threads. Co-authored-by: Cursor <cursoragent@cursor.com>
Collapse/expand threads, resolve controls, and mobile thread detail with always-visible reply inputs adapted per breakpoint. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the entry scrollable behind a non-modal drawer, open threads in full detail below xl, work around vaul-svelte's Svelte 5 activeSnapPoint bug, and keep the reply input pinned to the visible drawer bottom. Co-authored-by: Cursor <cursoragent@cursor.com>
- Adds ds-bundle with token + visual-reference system (not a React bundle) - HTML preview cards for core primitives: button, badge, input, label, textarea, alert, card, multi-ws-field, app-shell, master-detail, typography, colors - .design-sync/ config explaining the off-script Svelte approach - Compiled Tailwind CSS and design token imports via styles.css
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughChangesComments interface rework
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
- Disable vaul's default handle (it was hidden under the absolute panel) - Render a custom handle div inside the panel instead
|
It's interesting that new comments and replies have such different buttons 🤔 |
This reverts commit 3cd4cf9.
|
Yeah, I found that semi consistent between other apps interestingly enough. |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (7)
frontend/viewer/src/lib/entry-editor/comments/CommentDialog.svelte (1)
74-92: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winPrefer Vaul's
onAnimationEndover a hardcodedsetTimeout(…, 500).Vaul's Root already clears the active snap point back to the first entry via its own timer tied to the close transition duration, and exposes an
onAnimationEndcallback described as "Useful to revert any state changes for example." Duplicating that with a hand-tuned 500ms timeout risks racing Vaul's own internal reset if its transition duration ever changes, and thewatchcallback here doesn't return a cleanup function, so a pending timer can still fire after the drawer state changes again or the component is destroyed.♻️ Proposed direction
- watch( - () => open, - (isOpen) => { - if (isOpen) { - if (dockBottom) activeSnapPoint = defaultCommentSnap; - return; - } - showResolved = false; - addingComment = false; - newThreadText = ''; - editingCommentId = undefined; - expandedThreadIds = new Set(); - mobileThreadId = null; - // Vaul assigns snapPoints[0] after close; restore default for the next open. - window.setTimeout(() => { - if (!open) activeSnapPoint = defaultCommentSnap; - }, 500); - }, - ); + watch( + () => open, + (isOpen) => { + if (isOpen) { + if (dockBottom) activeSnapPoint = defaultCommentSnap; + return; + } + showResolved = false; + addingComment = false; + newThreadText = ''; + editingCommentId = undefined; + expandedThreadIds = new Set(); + mobileThreadId = null; + }, + ); + + // Pass onAnimationEnd to Drawer.Root instead, e.g.: + // <Drawer.Root onAnimationEnd={(isOpen) => { if (!isOpen) activeSnapPoint = defaultCommentSnap; }} ...>Please confirm
vaul-svelte1.0.0-next.7 exposes the sameonAnimationEndprop as core Vaul before applying.🤖 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 `@frontend/viewer/src/lib/entry-editor/comments/CommentDialog.svelte` around lines 74 - 92, Confirm that vaul-svelte 1.0.0-next.7 exposes Root's onAnimationEnd prop, then replace the hardcoded 500ms setTimeout in the open-state watch with that callback to restore activeSnapPoint to defaultCommentSnap after the close animation. Remove the timer and ensure the callback only restores state when the drawer remains closed, preserving the existing reset behavior.frontend/viewer/src/lib/entry-editor/comments/types.ts (1)
4-7: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win
ThreadViewcarries a redundantcommentsfield alongsideICommentThread.comments.ICommentThreadalready has an optionalcommentsarray, andThreadViewre-wraps the same data in a sibling top-level field, giving two places that must stay in sync.
frontend/viewer/src/lib/entry-editor/comments/types.ts#L4-L7: drop the extracommentsfield and have consumers readthread.comments ?? []directly, or makeThreadViewjust an alias/refinement ofICommentThreadwithcommentsrequired.frontend/viewer/src/lib/entry-editor/comments/CommentDialog.svelte#L49-L58: stop copyingthread.commentsinto a siblingcommentsfield in thethreadsResourcemapper once the type is simplified.🤖 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 `@frontend/viewer/src/lib/entry-editor/comments/types.ts` around lines 4 - 7, The ThreadView type duplicates ICommentThread.comments and the threadsResource mapper copies that duplicate data. In frontend/viewer/src/lib/entry-editor/comments/types.ts:4-7, remove the top-level comments field or refine ICommentThread so comments is required; update consumers to use thread.comments ?? [] as needed. In frontend/viewer/src/lib/entry-editor/comments/CommentDialog.svelte:49-58, stop adding a sibling comments property in the threadsResource mapper and rely on thread.comments.frontend/viewer/src/lib/entry-editor/comments/CommentReplyInput.svelte (1)
53-56: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueEscape discards typed text.
cancel()clearsvalueoutright, so Escape destroys an in-progress reply with no undo. Consider blurring only (and clearing just when the field is already empty).🤖 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 `@frontend/viewer/src/lib/entry-editor/comments/CommentReplyInput.svelte` around lines 53 - 56, Update the Escape-key handling in CommentReplyInput so it blurs or exits the input without clearing an in-progress reply. Adjust the cancel flow to clear the value only when the field is already empty, preserving typed text when Escape is pressed.frontend/viewer/src/lib/entry-editor/comments/CommentPanel.svelte (1)
134-164: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winThe
{:else}"Sign in to add comments." branch is unreachable.
addingCommentcan only become true viastartAdding, which is only reachable from the+ Addbutton on Line 127 — itself gated oncanComment. So the whole composer block iscanComment-only and the inner{#ifcanComment}/{:else}is dead. Either drop the else branch (and the inner guard), or surface the sign-in prompt somewhere actually reachable whencanCommentis false.🤖 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 `@frontend/viewer/src/lib/entry-editor/comments/CommentPanel.svelte` around lines 134 - 164, Remove the unreachable inner canComment guard and its “Sign in to add comments.” else branch from the addingComment composer in CommentPanel.svelte. Keep the composer rendered only when addingComment is true, preserving the existing textarea, controls, and submission behavior.frontend/viewer/src/lib/components/ui/drawer/drawer.svelte (2)
28-39: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueStale
targetcan be re-applied on a rapid close/reopen.The async chain captures
targetat open time, but only re-checksopen(not identity of the open cycle) before restoring. If the drawer closes and reopens with a differentactiveSnapPointbefore the two ticks settle, the stale value wins. A generation counter makes this deterministic.♻️ Guard with an open-generation counter
+ let openGeneration = 0; watch( () => open, (isOpen) => { if (!isOpen || !snapPoints?.length || activeSnapPoint == null) return; const target = activeSnapPoint; + const generation = ++openGeneration; void tick().then(async () => { activeSnapPoint = null; await tick(); - if (open) activeSnapPoint = target; + if (open && generation === openGeneration) activeSnapPoint = target; }); }, );🤖 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 `@frontend/viewer/src/lib/components/ui/drawer/drawer.svelte` around lines 28 - 39, Update the open-state watcher to track an incrementing open-generation counter for each open cycle. Capture the current generation alongside target in the tick chain, and only clear and restore activeSnapPoint when both open remains true and the captured generation is still current, preventing stale async work from reapplying an earlier snap point.
28-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the duplicated vaul snap-point workaround.
The same
watch(open, …)/ double-tick()block is copied verbatim into both drawer wrappers, so both the stale-targetrace and the eventual removal of the workaround (once huntabyte/vaul-svelte#129 is fixed) have to be handled twice.
frontend/viewer/src/lib/components/ui/drawer/drawer.svelte#L28-L39: move the block into a shared helper (e.g.useSnapPointWorkaround) that takes getters/setters foropen,snapPoints, andactiveSnapPoint, and include the open-generation guard.frontend/viewer/src/lib/components/ui/drawer/drawer-nested.svelte#L16-L27: replace the copied block with a call to that shared helper.🤖 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 `@frontend/viewer/src/lib/components/ui/drawer/drawer.svelte` around lines 28 - 39, Extract the duplicated watch/tick workaround from frontend/viewer/src/lib/components/ui/drawer/drawer.svelte lines 28-39 into a shared useSnapPointWorkaround helper accepting getters/setters for open, snapPoints, and activeSnapPoint, and add an open-generation guard to prevent stale target updates. Replace the copied block in frontend/viewer/src/lib/components/ui/drawer/drawer-nested.svelte lines 16-27 with a call to the shared helper; both sites should use the centralized implementation.frontend/viewer/src/lib/entry-editor/comments/CommentThread.svelte (1)
71-75: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse Lingui pluralization for reply counts.
replyCount === 1 ? $t1 reply: $t${replyCount} replies$creates two separate message IDs, so locales with zero/few/many plural categories need a single pluralized key. Use Lingui’spluralmacro: importplural, tfromsvelte-i18n-linguiand render{$plural(replyCount, { one: $t1 reply, other: $t${replyCount} replies, })}.🤖 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 `@frontend/viewer/src/lib/entry-editor/comments/CommentThread.svelte` around lines 71 - 75, Update the reply-count rendering in CommentThread.svelte to use Lingui pluralization instead of the replyCount ternary. Import the plural and t macros from svelte-i18n-lingui, then render the count through plural(replyCount) with one and other forms so all locale plural categories use a single pluralized message.Source: Coding guidelines
🤖 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 `@frontend/viewer/src/lib/entry-editor/comments/CommentItem.svelte`:
- Around line 32-36: Update the $effect in CommentItem.svelte to seed draftText
only when editing transitions from false to true, without reactively tracking
comment.text changes while editing. Preserve the existing comment.text value as
the initial draft and prevent refetches or other comment updates from
overwriting in-progress edits.
In `@frontend/viewer/src/lib/entry-editor/comments/CommentPanel.svelte`:
- Around line 226-231: Update the empty state around CommentPanel’s
visibleThreads condition to distinguish resolved-view/overall-empty results from
the “no open comments” case, and only show an add-comment action when canComment
is true. Replace the hardcoded “+ Add” prose with a real action button that
reuses the existing add-thread handler and shared button label, keeping it
consistent with the button rendered near line 128.
In `@frontend/viewer/src/lib/entry-editor/comments/CommentReplyInput.svelte`:
- Around line 27-34: Update submit() in CommentReplyInput so it exits
immediately when a submission is already in progress, using the existing saving
state before invoking onSubmit. Keep the current trimmed-text validation and
post-submit cleanup unchanged, ensuring repeated button or Ctrl/Cmd+Enter events
cannot trigger concurrent replies.
In `@frontend/viewer/src/lib/entry-editor/comments/CommentThread.svelte`:
- Around line 52-96: Restructure the header in CommentThread.svelte so the
expand/collapse toggle and resolve control are sibling elements rather than
nesting the resolve Button inside the toggle button. Preserve the existing
layout, toggle behavior via onToggle, resolve behavior via onResolve,
accessibility labels, and saving-disabled state; remove reliance on
stopPropagation for separating the actions.
---
Nitpick comments:
In `@frontend/viewer/src/lib/components/ui/drawer/drawer.svelte`:
- Around line 28-39: Update the open-state watcher to track an incrementing
open-generation counter for each open cycle. Capture the current generation
alongside target in the tick chain, and only clear and restore activeSnapPoint
when both open remains true and the captured generation is still current,
preventing stale async work from reapplying an earlier snap point.
- Around line 28-39: Extract the duplicated watch/tick workaround from
frontend/viewer/src/lib/components/ui/drawer/drawer.svelte lines 28-39 into a
shared useSnapPointWorkaround helper accepting getters/setters for open,
snapPoints, and activeSnapPoint, and add an open-generation guard to prevent
stale target updates. Replace the copied block in
frontend/viewer/src/lib/components/ui/drawer/drawer-nested.svelte lines 16-27
with a call to the shared helper; both sites should use the centralized
implementation.
In `@frontend/viewer/src/lib/entry-editor/comments/CommentDialog.svelte`:
- Around line 74-92: Confirm that vaul-svelte 1.0.0-next.7 exposes Root's
onAnimationEnd prop, then replace the hardcoded 500ms setTimeout in the
open-state watch with that callback to restore activeSnapPoint to
defaultCommentSnap after the close animation. Remove the timer and ensure the
callback only restores state when the drawer remains closed, preserving the
existing reset behavior.
In `@frontend/viewer/src/lib/entry-editor/comments/CommentPanel.svelte`:
- Around line 134-164: Remove the unreachable inner canComment guard and its
“Sign in to add comments.” else branch from the addingComment composer in
CommentPanel.svelte. Keep the composer rendered only when addingComment is true,
preserving the existing textarea, controls, and submission behavior.
In `@frontend/viewer/src/lib/entry-editor/comments/CommentReplyInput.svelte`:
- Around line 53-56: Update the Escape-key handling in CommentReplyInput so it
blurs or exits the input without clearing an in-progress reply. Adjust the
cancel flow to clear the value only when the field is already empty, preserving
typed text when Escape is pressed.
In `@frontend/viewer/src/lib/entry-editor/comments/CommentThread.svelte`:
- Around line 71-75: Update the reply-count rendering in CommentThread.svelte to
use Lingui pluralization instead of the replyCount ternary. Import the plural
and t macros from svelte-i18n-lingui, then render the count through
plural(replyCount) with one and other forms so all locale plural categories use
a single pluralized message.
In `@frontend/viewer/src/lib/entry-editor/comments/types.ts`:
- Around line 4-7: The ThreadView type duplicates ICommentThread.comments and
the threadsResource mapper copies that duplicate data. In
frontend/viewer/src/lib/entry-editor/comments/types.ts:4-7, remove the top-level
comments field or refine ICommentThread so comments is required; update
consumers to use thread.comments ?? [] as needed. In
frontend/viewer/src/lib/entry-editor/comments/CommentDialog.svelte:49-58, stop
adding a sibling comments property in the threadsResource mapper and rely on
thread.comments.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 425168f5-f1ae-4ee5-a4ec-9d2863f50257
📒 Files selected for processing (22)
frontend/viewer/src/css-breakpoints.tsfrontend/viewer/src/lib/components/ui/drawer/drawer-nested.sveltefrontend/viewer/src/lib/components/ui/drawer/drawer.sveltefrontend/viewer/src/lib/entry-editor/CommentDialog.sveltefrontend/viewer/src/lib/entry-editor/comments/CommentAuthorAvatar.sveltefrontend/viewer/src/lib/entry-editor/comments/CommentDialog.sveltefrontend/viewer/src/lib/entry-editor/comments/CommentItem.sveltefrontend/viewer/src/lib/entry-editor/comments/CommentPanel.sveltefrontend/viewer/src/lib/entry-editor/comments/CommentReplyInput.sveltefrontend/viewer/src/lib/entry-editor/comments/CommentThread.sveltefrontend/viewer/src/lib/entry-editor/comments/comment-author.tsfrontend/viewer/src/lib/entry-editor/comments/types.tsfrontend/viewer/src/lib/hooks/is-extra-large.svelte.tsfrontend/viewer/src/locales/en.pofrontend/viewer/src/locales/es.pofrontend/viewer/src/locales/fr.pofrontend/viewer/src/locales/id.pofrontend/viewer/src/locales/ko.pofrontend/viewer/src/locales/ms.pofrontend/viewer/src/locales/sw.pofrontend/viewer/src/locales/vi.pofrontend/viewer/src/project/browse/EntryView.svelte
💤 Files with no reviewable changes (1)
- frontend/viewer/src/lib/entry-editor/CommentDialog.svelte
| $effect(() => { | ||
| if (editing) { | ||
| draftText = comment.text; | ||
| } | ||
| }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
In-progress edits get clobbered when the comment reloads.
The effect reads comment.text reactively, so it re-runs on any change to the comment text — not just when editing flips to true. CommentDialog refetches threads after every mutation (reply, resolve, another user's edit), so a user typing in this textarea can have their draft silently reset. Seed the draft only on the edit transition.
🐛 Seed the draft without tracking `comment.text`
- import {t} from 'svelte-i18n-lingui';
+ import {untrack} from 'svelte';
+ import {t} from 'svelte-i18n-lingui'; $effect(() => {
if (editing) {
- draftText = comment.text;
+ untrack(() => {
+ draftText = comment.text;
+ });
}
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $effect(() => { | |
| if (editing) { | |
| draftText = comment.text; | |
| } | |
| }); | |
| import {untrack} from 'svelte'; | |
| import {t} from 'svelte-i18n-lingui'; | |
| $effect(() => { | |
| if (editing) { | |
| untrack(() => { | |
| draftText = comment.text; | |
| }); | |
| } | |
| }); |
🤖 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 `@frontend/viewer/src/lib/entry-editor/comments/CommentItem.svelte` around
lines 32 - 36, Update the $effect in CommentItem.svelte to seed draftText only
when editing transitions from false to true, without reactively tracking
comment.text changes while editing. Preserve the existing comment.text value as
the initial draft and prevent refetches or other comment updates from
overwriting in-progress edits.
| {:else if visibleThreads.length === 0} | ||
| <div class="pt-8 text-center text-[13px] leading-relaxed text-muted-foreground"> | ||
| {$t`No open comments`} | ||
| <br /> | ||
| <span class="text-xs">{$t`Use "+ Add" to start a thread`}</span> | ||
| </div> |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Empty state is wrong in two reachable cases.
- With
showResolvedtrue and zero threads overall, "No open comments" is misleading. - When
canCommentis false the+ Addbutton isn't rendered, yet the hint still instructs the user to use it.
Also, "+ Add" is hardcoded inside this sentence and duplicated from the button label on Line 128, so the two must be kept in sync in every locale — the PR feedback already asks to rename that button. Prefer rendering an actual action button here instead of embedding the label in prose.
♻️ Condition the empty state and drop the embedded label
{:else if visibleThreads.length === 0}
<div class="pt-8 text-center text-[13px] leading-relaxed text-muted-foreground">
- {$t`No open comments`}
- <br />
- <span class="text-xs">{$t`Use "+ Add" to start a thread`}</span>
+ {threadViews.length === 0 ? $t`No comments yet` : $t`No open comments`}
+ {`#if` canComment}
+ <div class="mt-2">
+ <Button size="sm" onclick={startAdding}>{$t`Add a comment`}</Button>
+ </div>
+ {/if}
</div>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {:else if visibleThreads.length === 0} | |
| <div class="pt-8 text-center text-[13px] leading-relaxed text-muted-foreground"> | |
| {$t`No open comments`} | |
| <br /> | |
| <span class="text-xs">{$t`Use "+ Add" to start a thread`}</span> | |
| </div> | |
| {:else if visibleThreads.length === 0} | |
| <div class="pt-8 text-center text-[13px] leading-relaxed text-muted-foreground"> | |
| {threadViews.length === 0 ? $t`No comments yet` : $t`No open comments`} | |
| {`#if` canComment} | |
| <div class="mt-2"> | |
| <Button size="sm" onclick={startAdding}>{$t`Add a comment`}</Button> | |
| </div> | |
| {/if} | |
| </div> |
🤖 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 `@frontend/viewer/src/lib/entry-editor/comments/CommentPanel.svelte` around
lines 226 - 231, Update the empty state around CommentPanel’s visibleThreads
condition to distinguish resolved-view/overall-empty results from the “no open
comments” case, and only show an add-comment action when canComment is true.
Replace the hardcoded “+ Add” prose with a real action button that reuses the
existing add-thread handler and shared button label, keeping it consistent with
the button rendered near line 128.
| async function submit(): Promise<void> { | ||
| const text = value.trim(); | ||
| if (!text) return; | ||
| await onSubmit(text); | ||
| value = ''; | ||
| focused = false; | ||
| textareaEl?.blur(); | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
submit() has no re-entrancy guard.
canSend disables the button once the parent flips saving, but submit() itself doesn't check saving, and Ctrl/Cmd+Enter bypasses the button entirely. Holding the shortcut or double-firing before the parent updates can post duplicate replies.
🐛 Guard against concurrent submits
async function submit(): Promise<void> {
const text = value.trim();
- if (!text) return;
+ if (!text || saving) return;
await onSubmit(text);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async function submit(): Promise<void> { | |
| const text = value.trim(); | |
| if (!text) return; | |
| await onSubmit(text); | |
| value = ''; | |
| focused = false; | |
| textareaEl?.blur(); | |
| } | |
| async function submit(): Promise<void> { | |
| const text = value.trim(); | |
| if (!text || saving) return; | |
| await onSubmit(text); | |
| value = ''; | |
| focused = false; | |
| textareaEl?.blur(); | |
| } |
🤖 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 `@frontend/viewer/src/lib/entry-editor/comments/CommentReplyInput.svelte`
around lines 27 - 34, Update submit() in CommentReplyInput so it exits
immediately when a submission is already in progress, using the existing saving
state before invoking onSubmit. Keep the current trimmed-text validation and
post-submit cleanup unchanged, ensuring repeated button or Ctrl/Cmd+Enter events
cannot trigger concurrent replies.
… the empty state, handle the case where they can't comment properly in an empty state.
…lve button Co-authored-by: Cursor <cursoragent@cursor.com>
- Read drawer snapPoints from restProps so the optional prop flows through the spread (fixes svelte-check non-optional type mismatch) - Drop unused Button import in CommentDialog - void the optional onThreadOpen promise calls in CommentPanel - Use SvelteSet for the mutated expanded-threads copy - Remove unnecessary non-null assertions in comment-author Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…green-dd1c6a # Conflicts: # frontend/viewer/src/lib/layout/DevToolsDialog.svelte
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hosted runners no longer permit `sudo timedatectl set-timezone`
("Failed to set time zone: Access denied"), which failed the FW Lite
build deterministically. Set TZ=America/New_York on the dotnet test
step instead; .NET honours TZ for TimeZoneInfo.Local on Linux, so the
non-UTC/DST/negative-offset intent from #2092 is preserved without
privileges and scoped to the tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
myieye
left a comment
There was a problem hiding this comment.
When I add a reply, start a new thread, resolve a thread etc, it re-renders the whole list of threads which is quite dissatisfying.
I suppose the expand/collapse arrow on threads shouldn't really be visible on mobile, where that's not the behaviour.
New threads should probably be expanded after creation.
I'm seeing lots of these warning logs:
https://svelte.dev/e/derived_inert

There was a problem hiding this comment.
I might try to merge this with the colouring in the activity later.
But, it's totally fine for now.
| } | ||
| } | ||
|
|
||
| async function resolveThread(threadView: ThreadView): Promise<void> { |
There was a problem hiding this comment.
Maybe not the best name, considering this sometimes unresolves.
| msgid "{num, plural, one {# new FieldWorks Lite commit} other {# new FieldWorks Lite commits}}" | ||
| msgstr "{num, plural, one {# new FieldWorks Lite commit} other {# new FieldWorks Lite commits}}" | ||
|
|
||
| #. Button revealing the rest of a truncated possible-duplicates list in the New Entry dialog; # is the number of hidden matches |
There was a problem hiding this comment.
Devin noticed that lots of translator context is being lost here. task i18n should preserve it. It seems to get wedged sometimes. You probably need to revert your changes and start fresh or something.





Summary
CommentDialog.svelteinto a modularentry-editor/comments/component tree (CommentPanel,CommentThread,CommentItem,CommentReplyInput,CommentAuthorAvatar,CommentDialog)is-extra-large.svelte.tsbreakpoint hook and two new CSS breakpoints to drive the responsive layoutScreenshots
thread list (desktop)

thread list (tablet)

thread list (mobile)

thread open at default drawer stop

max drawer stop

minimum drawer stop

start new thread (mobile)

start new thread (desktop)
