Radish alpha
r
rad:z4D5UCArafTzTQpDZNQRuqswh3ury
Radicle desktop app
Radicle
Git
Implement resolving and unresolving comments
Open rudolfs opened 1 year ago
3 files changed +107 -7 efe3c51d 7b28e420
modified src/components/Diff.svelte
@@ -1,6 +1,9 @@
<script lang="ts" module>
  export interface CodeComments {
-
    threads: Thread<CodeLocation>[];
+
    changeCommentStatus: (
+
      commentId: string,
+
      resolved: boolean,
+
    ) => Promise<void>;
    config: Config;
    createComment: (
      body: string,
@@ -21,6 +24,7 @@
    ) => Promise<void>;
    repoDelegates: Author[];
    rid: string;
+
    threads: Thread<CodeLocation>[];
  }
</script>

@@ -192,6 +196,26 @@
      };
    }
  }
+

+
  let threadExpandedStates: Record<string, boolean> = $state(
+
    codeComments
+
      ? Object.fromEntries(
+
          codeComments.threads.map(t => [t.root.id, t.root.resolved]),
+
        )
+
      : {},
+
  );
+

+
  $effect(() => {
+
    threadExpandedStates = codeComments
+
      ? Object.fromEntries(
+
          codeComments.threads.map(t => [t.root.id, t.root.resolved]),
+
        )
+
      : {};
+
  });
+

+
  function toggleCommentExpand(commentId: string) {
+
    threadExpandedStates[commentId] = !threadExpandedStates[commentId];
+
  }
</script>

<style>
@@ -379,22 +403,51 @@

            <div class="global-flex comment-icon">
              {#if thread}
-
                {#if thread.root.resolved && thread.replies.every(r => r.resolved)}
-
                  <Icon name="comment-checkmark" />
+
                {#if thread.root.resolved}
+
                  <Icon
+
                    name="comment-checkmark"
+
                    onclick={() => toggleCommentExpand(thread.root.id)} />
                {:else}
-
                  <Icon name="comment" />
+
                  <Icon
+
                    name="comment"
+
                    onclick={() => toggleCommentExpand(thread.root.id)} />
                {/if}
              {/if}
            </div>
          </div>

-
          {#if codeComments && thread}
+
          {#if codeComments && thread && !threadExpandedStates[thread.root.id]}
            <div class="thread">
-
              <div style:padding="0.5rem">
+
              <div class="global-flex" style:padding="0.5rem">
                {@render commentHeader(
                  thread.root.location?.path,
                  rangeAnchorsFromCodeLocation(thread.root.location),
                )}
+
                {#if roles.isDelegateOrAuthor( codeComments.config.publicKey, codeComments.repoDelegates.map(delegate => delegate.did), thread.root.author.did, )}
+
                  <div style:margin-left="auto">
+
                    {#if thread.root.resolved}
+
                      <div title="Unresolve comment thread">
+
                        <Icon
+
                          name="cross"
+
                          onclick={() =>
+
                            codeComments.changeCommentStatus(
+
                              thread.root.id,
+
                              false,
+
                            )} />
+
                      </div>
+
                    {:else}
+
                      <div title="Resolve comment thread">
+
                        <Icon
+
                          name="checkmark"
+
                          onclick={() =>
+
                            codeComments.changeCommentStatus(
+
                              thread.root.id,
+
                              true,
+
                            )} />
+
                      </div>
+
                    {/if}
+
                  </div>
+
                {/if}
              </div>
              <ThreadComponent
                inline
modified src/components/FileDiff.svelte
@@ -40,6 +40,20 @@
  }

  const commentsOfThisFile = $derived(filterThreadsByFilePath());
+
  const resolvedThreads = $derived(
+
    commentsOfThisFile
+
      ? commentsOfThisFile.threads.filter(t => {
+
          return t.root.resolved === true;
+
        }).length
+
      : 0,
+
  );
+
  const unresolvedThreads = $derived(
+
    commentsOfThisFile
+
      ? commentsOfThisFile.threads.filter(t => {
+
          return t.root.resolved === false;
+
        }).length
+
      : 0,
+
  );
</script>

<style>
@@ -104,7 +118,18 @@
      </div>
    {/if}
    {#if commentsOfThisFile && commentsOfThisFile.threads.length > 0}
-
      <Icon name="comment" />
+
      {#if unresolvedThreads > 0}
+
        <div class="global-flex">
+
          <Icon name="comment" />
+
          {unresolvedThreads}
+
        </div>
+
      {/if}
+
      {#if resolvedThreads > 0}
+
        <div class="global-flex">
+
          <Icon name="comment-checkmark" />
+
          {resolvedThreads}
+
        </div>
+
      {/if}
    {/if}
  {/snippet}

modified src/components/Review.svelte
@@ -218,6 +218,27 @@
      await loadReview();
    }
  }
+

+
  async function changeCommentStatus(commentId: string, resolved: boolean) {
+
    try {
+
      await invoke("edit_patch", {
+
        rid: repo.rid,
+
        cobId: patchId,
+
        action: {
+
          type: resolved
+
            ? "review.comment.resolve"
+
            : "review.comment.unresolve",
+
          comment: commentId,
+
          review: review.id,
+
        },
+
        opts: { announce: $nodeRunning && $announce },
+
      });
+
    } catch (error) {
+
      console.error("Updating comment status failed: ", error);
+
    } finally {
+
      await loadReview();
+
    }
+
  }
</script>

<style>
@@ -378,6 +399,7 @@

  <Changes
    codeComments={{
+
      changeCommentStatus,
      config,
      createComment,
      editComment,