Radish alpha
r
rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5
Radicle web interface
Radicle
Git
Add file path and line for comments with code locations
Merged did:key:z6MkkfM3...sVz5 opened 10 months ago

Instead of only displaying a comment, we need to make sure users know that this has been a line comment.

Linking to changes for the display of the comment is a bit trickier, will do so in a follow up


Stop propagation of Link click

By not stopping the propagation of the click event on Link components weird things happen around the app like i.e. the Popover component things someone clicked outside and updates the url hash.

We should make sure to only propagate clicks where needed.

check check-visual check-unit-test check-http-client-unit-test check-radicle-httpd check-e2e check-build check-http

👉 Preview 👉 Workflow runs 👉 Branch on GitHub

2 files changed +47 -0 0603f63c 18afaa12
modified src/components/Comment.svelte
@@ -3,6 +3,10 @@

  import * as utils from "@app/lib/utils";

+
  type Side = "left" | "right";
+
  type SelectionAnchor = { side: Side; lineNumber: number };
+
  type SelectionRange = { start: SelectionAnchor; end?: SelectionAnchor };
+

  import Id from "@app/components/Id.svelte";
  import Markdown from "@app/components/Markdown.svelte";
  import NodeId from "@app/components/NodeId.svelte";
@@ -14,12 +18,28 @@
  export let baseUrl: BaseUrl;
  export let body: string;
  export let reactions: Comment["reactions"] | undefined = undefined;
+
  export let location: Comment["location"] | undefined = undefined;
  export let caption = "commented";
  export let rawPath: string;
  export let timestamp: number;
  export let isReply: boolean = false;
  export let isLastReply: boolean = false;
  export let lastEdit: Comment["edits"][0] | undefined = undefined;
+

+
  function rangeAnchorsFromCodeLocation(
+
    location: Comment["location"] | null,
+
  ): SelectionRange | undefined {
+
    if (location?.old?.type === "lines") {
+
      return {
+
        start: { side: "left", lineNumber: location.old.range.start },
+
      };
+
    } else if (location?.new?.type === "lines") {
+
      return {
+
        start: { side: "right", lineNumber: location.new.range.start },
+
      };
+
    }
+
  }
+
  $: selectionRange = rangeAnchorsFromCodeLocation(location);
</script>

<style>
@@ -42,6 +62,13 @@
    gap: 0.5rem;
    font-size: var(--font-size-small);
  }
+
  .code-location {
+
    font-family: var(--font-family-monospace);
+
    background-color: var(--color-fill-ghost);
+
    font-size: var(--font-size-tiny);
+
    border-radius: var(--border-radius-tiny);
+
    padding: 0.125rem 0.25rem;
+
  }
  .reply-dot {
    border-radius: var(--border-radius-round);
    width: 4px;
@@ -108,6 +135,25 @@
      <NodeId {baseUrl} nodeId={authorId} alias={authorAlias} />
      <slot name="caption">{caption}</slot>
      <Id {id} />
+
      {#if location}
+
        on change
+
        <div class="code-location">
+
          {#if location.path && selectionRange}
+
            <div class="comment-header">
+
              {location.path.split("/").length > 1 ? "…/" : ""}{location.path
+
                .split("/")
+
                .slice(-1)}:{selectionRange.start.side === "left"
+
                ? "L"
+
                : "R"}{selectionRange.start.lineNumber}
+
              {#if selectionRange.end}
+
                ->
+
                {selectionRange.end.side === "left" ? "L" : "R"}{selectionRange
+
                  .end.lineNumber}
+
              {/if}
+
            </div>
+
          {/if}
+
        </div>
+
      {/if}
      <span class="timestamp" title={utils.absoluteTimestamp(timestamp)}>
        {utils.formatTimestamp(timestamp)}
      </span>
modified src/components/Thread.svelte
@@ -50,6 +50,7 @@
      lastEdit={root.edits.length > 1 ? root.edits.at(-1) : undefined}
      authorId={root.author.id}
      authorAlias={root.author.alias}
+
      location={root.location}
      reactions={root.reactions}
      timestamp={root.timestamp}
      body={root.body}>