Radish alpha
r
Radicle desktop app
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add `get_file_by_oid` command, enables support for embeds
Sebastian Martinez committed 1 year ago
commit 8c80f7b2288815c38ed9899dc1c8e1e5f2df500d
parent e5f90e20b806bbf54165d51316cb24b823c1f6cd
8 files changed +52 -1
modified src-tauri/Cargo.lock
@@ -3839,6 +3839,7 @@ name = "radicle-desktop"
version = "0.0.0"
dependencies = [
 "anyhow",
+
 "base64 0.22.1",
 "log",
 "radicle",
 "radicle-surf",
modified src-tauri/Cargo.toml
@@ -20,6 +20,7 @@ tauri-build = { version = "2.0", features = ["isolation"] }

[dependencies]
anyhow = { version = "1.0" }
+
base64 = { version = "0.22" }
log = { version = "0.4" }
radicle = { version = "0.13.0" }
radicle-surf = { version = "0.22.0" }
modified src-tauri/src/commands/cob.rs
@@ -1,6 +1,26 @@
+
use base64::{engine::general_purpose::STANDARD, Engine as _};
+

+
use radicle::git;
+
use radicle::identity;
+
use radicle::storage::{ReadRepository, ReadStorage};
+

+
use crate::{error, AppState};
+

pub mod issue;
pub mod patch;

+
#[tauri::command]
+
pub async fn get_file_by_oid(
+
    ctx: tauri::State<'_, AppState>,
+
    rid: identity::RepoId,
+
    oid: git::Oid,
+
) -> Result<String, error::Error> {
+
    let repo = ctx.profile.storage.repository(rid)?;
+
    let blob = repo.blob(oid)?;
+

+
    Ok::<_, error::Error>(STANDARD.encode(blob.content()))
+
}
+

mod query {
    use serde::{Deserialize, Serialize};

modified src-tauri/src/error.rs
@@ -42,6 +42,10 @@ pub enum Error {
    #[error(transparent)]
    Routing(#[from] radicle::node::routing::Error),

+
    /// Radicle Git error.
+
    #[error(transparent)]
+
    Git(#[from] radicle::git::Error),
+

    /// Git2 error.
    #[error(transparent)]
    Git2(#[from] radicle::git::raw::Error),
modified src-tauri/src/lib.rs
@@ -76,6 +76,7 @@ pub fn run() {
            repo::list_repos,
            repo::repo_by_id,
            repo::diff_stats,
+
            cob::get_file_by_oid,
            cob::issue::list_issues,
            cob::issue::issue_by_id,
            cob::issue::create_issue,
modified src/components/Markdown.svelte
@@ -6,8 +6,10 @@

  import { Renderer, markdownWithExtensions } from "@app/lib/markdown";
  import { highlight } from "@app/lib/syntax";
-
  import { twemoji, scrollIntoView } from "@app/lib/utils";
+
  import { twemoji, scrollIntoView, isCommit } from "@app/lib/utils";
+
  import { invoke } from "@tauri-apps/api/core";

+
  export let rid: string;
  export let content: string;
  // If true, add <br> on a single line break
  export let breaks: boolean = false;
@@ -71,6 +73,23 @@
      i.remove();
    }

+
    // Iterate over all images, and replace the source with a canonicalized URL
+
    // pointing at the repos /raw endpoint.
+
    for (const i of container.querySelectorAll("img")) {
+
      const imagePath = i.getAttribute("src");
+

+
      // If the image is an oid embed
+
      if (imagePath && isCommit(imagePath)) {
+
        let base64Content = await invoke<string>("get_file_by_oid", {
+
          rid,
+
          oid: imagePath,
+
        });
+

+
        i.setAttribute("src", `data:image/jpeg;base64,${base64Content}`);
+
        continue;
+
      }
+
    }
+

    // Replaces code blocks in the background with highlighted code.
    const prefix = "language-";
    const nodes = Array.from(document.body.querySelectorAll("pre code"));
modified src/lib/utils.ts
@@ -38,6 +38,10 @@ export function truncateId(pubkey: string): string {
  return `${pubkey.substring(0, 6)}…${pubkey.slice(-6)}`;
}

+
export function isCommit(input: string): boolean {
+
  return /^[a-f0-9]{40}$/.test(input);
+
}
+

export function formatOid(id: string): string {
  return id.substring(0, 7);
}
modified src/views/repo/Issue.svelte
@@ -127,6 +127,7 @@
    <div class="txt-small body">
      {#if issue.discussion[0].edits.slice(-1)[0].body !== ""}
        <Markdown
+
          rid={repo.rid}
          breaks
          content={issue.discussion[0].edits.slice(-1)[0].body} />
      {:else}