Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
44 changes: 28 additions & 16 deletions src/ui/ReviewSidebarView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export class ReviewSidebarView extends ItemView {
private draftText = "";
private pendingFocus: PendingFocus | null = null;
private lastDraftKey: string | null = null;
private lastScrolledItemId: string | null = null;

private removeOutsideClickListener: (() => void) | null = null;
private composerSubmits = new WeakMap<HTMLTextAreaElement, () => void>();
private composerHintId = 0;
Expand Down Expand Up @@ -325,22 +325,31 @@ export class ReviewSidebarView extends ItemView {

private renderContent(): void {
const root = this.contentEl;
// Emptying the scroller collapses it and zeroes scrollTop; put it back
// once the new content exists so a rebuild doesn't move the viewport.
const scrollTop = root.scrollTop;
this.resetCommentRenderScope();
root.empty();
root.addClass("critic-sidebar");
const selectedId = this.renderBody(root);
root.scrollTop = scrollTop;
this.scrollSelectedIntoView(root, selectedId);
}

/** Returns the id of the visibly selected card, if any. */
private renderBody(root: HTMLElement): string | null {
const externalState = this.plugin.getActiveExternalCommentState();
if (externalState) {
this.renderHeader(root, externalState.title);
this.renderExternalComments(root, externalState);
return;
return null;
}

const state = this.plugin.getActiveReviewState();
this.renderHeader(root, state?.file.basename ?? "Relay Comments");
if (!state) {
this.renderEmptyState(root, "Open a Markdown note to review comments and suggestions.");
return;
return null;
}

const validMarks = state.marks
Expand Down Expand Up @@ -371,7 +380,7 @@ export class ReviewSidebarView extends ItemView {
"No comments or suggestions in this note yet. Select text and choose “Add comment” to start a discussion.",
);
}
return;
return null;
}

const list = root.createDiv({ cls: "critic-sidebar-list" });
Expand All @@ -391,14 +400,16 @@ export class ReviewSidebarView extends ItemView {
isSelected(item, state.activeMarkId),
state.file.path,
);
if (selected && !visiblySelectedId) {
// The card the user picked wins over the one the editor cursor
// happens to sit in; both render as selected.
if (selected && (!visiblySelectedId || item.id === this.selectedItemId)) {
visiblySelectedId = item.id;
}
}
if (draft && !draftRendered) {
this.renderDraft(list, draft);
}
this.scrollSelectedIntoView(list, visiblySelectedId);
return visiblySelectedId;
}

private renderExternalComments(
Expand Down Expand Up @@ -575,15 +586,14 @@ export class ReviewSidebarView extends ItemView {
}

private scrollSelectedIntoView(
list: HTMLElement,
root: HTMLElement,
selectedId: string | null,
): void {
if (selectedId && selectedId !== this.lastScrolledItemId) {
list
.querySelector(`[data-critic-item-id="${CSS.escape(selectedId)}"]`)
?.scrollIntoView({ block: "nearest" });
}
this.lastScrolledItemId = selectedId;
if (!selectedId) return;

root
.querySelector(`[data-critic-item-id="${CSS.escape(selectedId)}"]`)
?.scrollIntoView({ block: "nearest" });
}

private installOutsideClickListener(): void {
Expand Down Expand Up @@ -697,9 +707,11 @@ export class ReviewSidebarView extends ItemView {
const isThreadSelected =
selected || this.selectedItemId === item.id || this.replyDraftItemId === item.id;
const card = parent.createDiv({
cls: isThreadSelected
? "critic-card critic-card-selected"
: "critic-card",
cls: [
"critic-card",
...(isThreadSelected ? ["critic-card-selected"] : []),
...(this.selectedItemId === item.id ? ["critic-card-current"] : []),
],
attr: {
tabindex: "0",
role: "button",
Expand Down
9 changes: 9 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,15 @@
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.14);
}

/* The card the user picked (clicked, or reached from its anchor in the note)
takes the accent on its spine and border. A card that is merely under the
editor cursor keeps the softer selected look. */
.critic-card.critic-card-current,
.critic-card.critic-card-current:hover {
--critic-rail: var(--interactive-accent);
border-color: var(--interactive-accent);
}

/* ---------- Card header ---------- */

.critic-comment-header {
Expand Down
Loading