Skip to content

Commit

Permalink
Add embeds to the Textarea
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastinez committed Dec 13, 2024
1 parent 9fd2d48 commit ca4d9d1
Show file tree
Hide file tree
Showing 20 changed files with 1,156 additions and 278 deletions.
771 changes: 685 additions & 86 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions crates/radicle-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ tauri-plugin-window-state = { version = "2.0.1" }
thiserror = { version = "1.0.64" }
ts-rs = { version = "10.0.0", features = ["serde-json-impl", "no-serde-warnings"] }
tokio = { version = "1.40.0", features = ["time"] }
tauri-plugin-dialog = { version = "2.2.0" }

[features]
# by default Tauri runs in production mode
Expand Down
3 changes: 2 additions & 1 deletion crates/radicle-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"shell:allow-open",
"clipboard-manager:default",
"clipboard-manager:allow-write-text",
"log:default"
"log:default",
"dialog:default"
]
}
65 changes: 59 additions & 6 deletions crates/radicle-tauri/src/commands/cob.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
use std::path::PathBuf;

use anyhow::{Context, Result};

use radicle::cob;
use radicle::git;
use radicle::identity;
use radicle_types as types;
use radicle_types::error::Error;
use radicle_types::traits::cobs::Cobs;
use radicle_types::traits::thread::Thread;
use tauri_plugin_clipboard_manager::ClipboardExt;
use tauri_plugin_dialog::DialogExt;

use crate::AppState;

Expand All @@ -13,22 +19,69 @@ pub mod issue;
pub mod patch;

#[tauri::command]
pub async fn get_file_by_oid(
pub async fn get_embed(
ctx: tauri::State<'_, AppState>,
rid: identity::RepoId,
oid: git::Oid,
) -> Result<String, Error> {
) -> Result<Vec<u8>, Error> {
ctx.get_embed(rid, oid)
}

#[tauri::command]
pub async fn save_embed(
pub async fn save_embed_by_path(
ctx: tauri::State<'_, AppState>,
rid: identity::RepoId,
path: PathBuf,
) -> Result<git::Oid, Error> {
ctx.save_embed_by_path(rid, path)
}

#[tauri::command]
pub async fn save_embed_by_clipboard(
app_handle: tauri::AppHandle,
ctx: tauri::State<'_, AppState>,
rid: identity::RepoId,
name: &str,
bytes: &[u8],
name: String,
) -> Result<git::Oid, Error> {
ctx.save_embed(rid, name, bytes)
let content = app_handle
.clipboard()
.read_image()
.map(|i| i.rgba().to_vec())
.context("Not able to read the image from the clipboard")?;

ctx.save_embed_by_bytes(rid, name, content)
}

#[tauri::command]
pub async fn save_embed_by_bytes(
ctx: tauri::State<'_, AppState>,
rid: identity::RepoId,
name: String,
bytes: Vec<u8>,
) -> Result<git::Oid, Error> {
ctx.save_embed_by_bytes(rid, name, bytes)
}

#[tauri::command]
pub async fn save_embed_to_disk(
app_handle: tauri::AppHandle,
ctx: tauri::State<'_, AppState>,
rid: identity::RepoId,
oid: git::Oid,
name: String,
) -> Result<(), Error> {
let path = app_handle
.dialog()
.file()
.set_file_name(name)
.blocking_save_file()
.context("no path defined")?;

let path = path
.into_path()
.context("Not able to convert into PathBuf")?;

ctx.save_embed_to_disk(rid, oid, path)
}

#[tauri::command]
Expand Down
11 changes: 8 additions & 3 deletions crates/radicle-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use commands::{auth, cob, diff, profile, repo, thread};
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
#[cfg(debug_assertions)]
let builder = tauri::Builder::default().plugin(tauri_plugin_log::Builder::new().build());
let builder = tauri::Builder::default()
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_log::Builder::new().build());
#[cfg(not(debug_assertions))]
let builder = tauri::Builder::default();

Expand Down Expand Up @@ -74,9 +76,12 @@ pub fn run() {
repo::diff_stats,
repo::list_commits,
diff::get_diff,
cob::get_file_by_oid,
cob::get_embed,
cob::save_embed_to_disk,
cob::activity_by_id,
cob::save_embed,
cob::save_embed_by_path,
cob::save_embed_by_clipboard,
cob::save_embed_by_bytes,
cob::issue::list_issues,
cob::issue::issue_by_id,
cob::issue::comment_threads_by_issue_id,
Expand Down
8 changes: 8 additions & 0 deletions crates/radicle-types/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ pub enum Error {
#[error(transparent)]
Profile(#[from] radicle::profile::Error),

/// Anyhow error.
#[error(transparent)]
Anyhow(#[from] anyhow::Error),

/// Io error.
#[error(transparent)]
Io(#[from] std::io::Error),

/// Crypto error.
#[error(transparent)]
Crypto(#[from] radicle::crypto::ssh::keystore::Error),
Expand Down
1 change: 1 addition & 0 deletions crates/radicle-types/src/traits/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ pub trait Repo: Profile {
#[allow(clippy::unwrap_used)]
mod test {
use std::str::FromStr;
use std::vec;

use radicle::crypto::test::signer::MockSigner;
use radicle::{git, test};
Expand Down
43 changes: 36 additions & 7 deletions crates/radicle-types/src/traits/thread.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use base64::{engine::general_purpose::STANDARD, Engine as _};
use std::fs;

use localtime::LocalTime;

use radicle::cob;
Expand All @@ -14,23 +15,51 @@ use crate::error::Error;
use crate::traits::Profile;

pub trait Thread: Profile {
fn get_embed(&self, rid: identity::RepoId, oid: git::Oid) -> Result<String, Error> {
fn get_embed(&self, rid: identity::RepoId, oid: git::Oid) -> Result<Vec<u8>, Error> {
let profile = self.profile();
let repo = profile.storage.repository(rid)?;
let blob = repo.blob(oid)?;

Ok::<_, Error>(blob.content().to_vec())
}

fn save_embed_to_disk(
&self,
rid: identity::RepoId,
oid: git::Oid,
path: std::path::PathBuf,
) -> Result<(), Error> {
let profile = self.profile();
let repo = profile.storage.repository(rid)?;
let blob = repo.blob(oid)?;
fs::write(path, blob.content())?;

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

fn save_embed_by_path(
&self,
rid: identity::RepoId,
path: std::path::PathBuf,
) -> Result<git::Oid, Error> {
let profile = self.profile();
let repo = profile.storage.repository(rid)?;
let bytes = fs::read(path.clone())?;
let name = path.file_name().and_then(|s| s.to_str()).unwrap_or("embed");
let embed = radicle::cob::Embed::<git::Oid>::store(name, &bytes, &repo.backend)?;

Ok(embed.oid())
}

fn save_embed(
fn save_embed_by_bytes(
&self,
rid: identity::RepoId,
name: &str,
bytes: &[u8],
name: String,
bytes: Vec<u8>,
) -> Result<git::Oid, Error> {
let profile = self.profile();
let repo = profile.storage.repository(rid)?;
let embed = radicle::cob::Embed::<git::Oid>::store(name, bytes, &repo.backend)?;
let embed = radicle::cob::Embed::<git::Oid>::store(&name, &bytes, &repo.backend)?;

Ok(embed.oid())
}
Expand Down
15 changes: 9 additions & 6 deletions crates/test-http-api/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;

use axum::extract::State;
Expand Down Expand Up @@ -67,8 +68,11 @@ pub fn router(ctx: Context) -> Router {
.route("/list_patches", post(patches_handler))
.route("/patch_by_id", post(patch_handler))
.route("/revisions_by_patch", post(revision_handler))
.route("/get_file_by_oid", post(get_embeds_handler))
.route("/save_embed", post(save_embed_handler))
.route("/get_embed", post(get_embeds_handler))
.route("/save_embed_by_path", post(save_embed_handler))
.route("/save_embed_by_clipboard", post(save_embed_handler))
.route("/save_embed_by_bytes", post(save_embed_handler))
.route("/save_embed_to_disk", post(save_embed_handler))
.layer(
CorsLayer::new()
.allow_origin(cors::Any)
Expand Down Expand Up @@ -255,15 +259,14 @@ async fn get_embeds_handler(
#[derive(Serialize, Deserialize)]
struct CreateEmbedBody {
pub rid: identity::RepoId,
pub name: String,
pub content: Vec<u8>,
pub path: PathBuf,
}

async fn save_embed_handler(
State(ctx): State<Context>,
Json(CreateEmbedBody { rid, name, content }): Json<CreateEmbedBody>,
Json(CreateEmbedBody { rid, path }): Json<CreateEmbedBody>,
) -> impl IntoResponse {
let embed = ctx.save_embed(rid, &name, &content)?;
let embed = ctx.save_embed_by_path(rid, path)?;

Ok::<_, Error>(Json(embed))
}
Expand Down
18 changes: 13 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"license": "MIT",
"dependencies": {
"@tauri-apps/api": "^2.1.1",
"@tauri-apps/plugin-clipboard-manager": "^2.0.0",
"@tauri-apps/plugin-clipboard-manager": "^2.2.0",
"@tauri-apps/plugin-dialog": "^2.2.0",
"@tauri-apps/plugin-log": "^2.0.0",
"@tauri-apps/plugin-shell": "^2.0.0",
"@tauri-apps/plugin-window-state": "^2.0.0"
Expand Down
6 changes: 6 additions & 0 deletions public/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ body {
font-weight: var(--font-weight-regular);
}

@media (max-width: 1600px) {
.global-hide-on-small-desktop-down {
display: none !important;
}
}

:root {
--elevation-low: 0 0 48px 0 #000000ee;
}
Expand Down
3 changes: 3 additions & 0 deletions src/components/Border.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
variant: "primary" | "secondary" | "ghost" | "float" | "danger";
hoverable?: boolean;
onclick?: () => void;
stylePosition?: string;
stylePadding?: string;
styleHeight?: string;
styleMinHeight?: string;
Expand All @@ -27,6 +28,7 @@
stylePadding,
styleHeight,
styleMinHeight,
stylePosition,
styleWidth,
styleCursor = "default",
styleGap = "0.5rem",
Expand Down Expand Up @@ -222,6 +224,7 @@
<div class="p3-2"></div>
<div
class="p3-3"
style:position={stylePosition}
style:padding={stylePadding}
style:gap={styleGap}
style:overflow={styleOverflow}
Expand Down
Loading

0 comments on commit ca4d9d1

Please sign in to comment.