Radish alpha
r
rad:z4D5UCArafTzTQpDZNQRuqswh3ury
Radicle desktop app
Radicle
Git
Narrow down `IssueOp` type by flattening it
Merged did:key:z6MkkfM3...sVz5 opened 1 year ago
4 files changed +79 -40 5ed10a40 caebd0a3
added crates/radicle-tauri/bindings/IssueOp.ts
@@ -0,0 +1,48 @@
+
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
+
import type { Author } from "./Author";
+

+
export type IssueOp = { entryId: string; timestamp: number; author: Author } & (
+
  | { type: "assign"; assignees: Array<string> }
+
  | { type: "edit"; title: string }
+
  | {
+
      type: "lifecycle";
+
      state:
+
        | { status: "closed"; reason: "other" | "solved" }
+
        | { status: "open" };
+
    }
+
  | { type: "label"; labels: Array<string> }
+
  | {
+
      type: "comment";
+
      /**
+
       * Comment body.
+
       */
+
      body: string;
+
      /**
+
       * Comment this is a reply to.
+
       * Should be [`None` | `null`] if it's the top-level comment.
+
       * Should be the root [`CommentId`] if it's a top-level comment.
+
       */
+
      replyTo: string | null;
+
      /**
+
       * Embeded content.
+
       */
+
      embeds: Array<string>;
+
    }
+
  | {
+
      type: "comment.edit";
+
      /**
+
       * Comment being edited.
+
       */
+
      id: string;
+
      /**
+
       * New value for the comment body.
+
       */
+
      body: string;
+
      /**
+
       * New value for the embeds list.
+
       */
+
      embeds: Array<string>;
+
    }
+
  | { type: "comment.redact"; id: string }
+
  | { type: "comment.react"; id: string; reaction: string; active: boolean }
+
);
deleted crates/radicle-tauri/bindings/IssueOps.ts
@@ -1,10 +0,0 @@
-
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
-
import type { Author } from "./Author";
-
import type { IssueAction } from "./IssueAction";
-

-
export type IssueOps = {
-
  id: string;
-
  action: IssueAction;
-
  timestamp: number;
-
  author: Author;
-
};
modified crates/radicle-tauri/src/commands/cob.rs
@@ -5,6 +5,7 @@ use radicle::git;
use radicle::identity;
use radicle::storage::{ReadRepository, ReadStorage};

+
use crate::types::cobs::IssueAction;
use crate::{error, types, AppState};

pub mod draft;
@@ -12,14 +13,16 @@ pub mod issue;
pub mod patch;

#[derive(serde::Serialize, ts_rs::TS)]
+
#[serde(rename_all = "camelCase")]
#[ts(export)]
-
pub struct IssueOps {
+
pub struct IssueOp {
    #[ts(as = "String")]
-
    id: git::Oid,
-
    action: types::cobs::IssueAction,
+
    pub entry_id: git::Oid,
+
    #[serde(flatten)]
+
    pub action: types::cobs::IssueAction,
    #[ts(type = "number")]
-
    timestamp: cob::Timestamp,
-
    author: types::cobs::Author,
+
    pub timestamp: cob::Timestamp,
+
    pub author: types::cobs::Author,
}

#[tauri::command]
@@ -53,25 +56,24 @@ pub fn activity_by_id(
    rid: identity::RepoId,
    type_name: cob::TypeName,
    id: git::Oid,
-
) -> Result<Vec<serde_json::Value>, error::Error> {
+
) -> Result<Vec<IssueOp>, error::Error> {
    let aliases = ctx.profile.aliases();
    let repo = ctx.profile.storage.repository(rid)?;
    let ops = cob::store::ops(&id.into(), &type_name, &repo).unwrap();
-
    let mut actions: Vec<serde_json::Value> = Vec::new();
+
    let mut actions: Vec<IssueOp> = Vec::new();

    for op in ops.into_iter() {
        actions.extend(
            op.actions
                .iter()
-
                .filter_map(|action: &Vec<u8>| -> Option<serde_json::Value> {
-
                    serde_json::from_slice(action).ok()
-
                })
-
                .map(|action| {
-
                    serde_json::json!({
-
                        "id": op.id,
-
                        "action": action,
-
                        "author": types::cobs::Author::new(op.author.into(), &aliases),
-
                        "timestamp": op.timestamp
+
                .filter_map(|action: &Vec<u8>| -> Option<IssueOp> {
+
                    let action: IssueAction = serde_json::from_slice(action).ok()?;
+

+
                    Some(IssueOp {
+
                        entry_id: op.id,
+
                        action,
+
                        author: types::cobs::Author::new(op.author.into(), &aliases),
+
                        timestamp: op.timestamp,
                    })
                }),
        )
modified src/views/repo/Issue.svelte
@@ -2,7 +2,7 @@
  import type { Config } from "@bindings/Config";
  import type { Issue } from "@bindings/Issue";
  import type { RepoInfo } from "@bindings/RepoInfo";
-
  import type { IssueOps } from "@bindings/IssueOps";
+
  import type { IssueOp } from "@bindings/IssueOp";

  import capitalize from "lodash/capitalize";

@@ -221,32 +221,31 @@
      {/if}
    </div>
    <div>
-
      {#await invoke<IssueOps[]>( "activity_by_id", { rid: repo.rid, typeName: "xyz.radicle.issue", id: issue.id }, ) then activity}
-
        {#each activity.slice(1) as { action, timestamp, author }}
-
          {#if action.type === "lifecycle"}
+
      {#await invoke<IssueOp[]>( "activity_by_id", { rid: repo.rid, typeName: "xyz.radicle.issue", id: issue.id }, ) then activity}
+
        {#each activity.slice(1) as op}
+
          {#if op.type === "lifecycle"}
            <div class="txt-small body">
              <div class="global-flex txt-small">
-
                <NodeId {...authorForNodeId(author)} />
-
                alias={author.alias} /> change of status to {action.state
-
                  .status}
+
                <NodeId {...authorForNodeId(op.author)} />
+
                alias={op.author.alias} /> change of status to {op.state.status}
                <!-- <div class="global-oid"></div> -->
-
                {formatTimestamp(timestamp)}
+
                {formatTimestamp(op.timestamp)}
              </div>
            </div>
-
          {:else if action.type === "comment"}
+
          {:else if op.type === "comment"}
            <div class="txt-small body">
-
              <Markdown rid={repo.rid} breaks content={action.body} />
+
              <Markdown rid={repo.rid} breaks content={op.body} />
              <div class="global-flex txt-small" style:margin-top="1.5rem">
-
                <NodeId {...authorForNodeId(author)} />
-
                {#if action.replyTo}
+
                <NodeId {...authorForNodeId(op.author)} />
+
                {#if op.replyTo}
                  replied to <div class="global-oid">
-
                    {formatOid(action.replyTo)}
+
                    {formatOid(op.replyTo)}
                  </div>
                {:else}
                  commented
                {/if}
                <!-- <div class="global-oid"></div> -->
-
                {formatTimestamp(timestamp)}
+
                {formatTimestamp(op.timestamp)}
              </div>
            </div>
          {/if}