cathode/src-tauri/src/fs.rs

117 lines
3.2 KiB
Rust
Raw Normal View History

2022-09-15 03:22:43 -04:00
use std::collections::HashMap;
2022-10-12 15:18:49 -04:00
use std::fs;
2022-09-04 04:12:10 -04:00
use std::io::Cursor;
2022-10-12 15:18:49 -04:00
use std::path::Path;
2022-09-04 04:12:10 -04:00
use base64_url as base64;
use image::ImageFormat;
2022-09-17 13:52:30 -04:00
use log::{debug, trace};
2022-09-15 03:22:43 -04:00
use ray_format::Ray;
use serde::{Deserialize, Serialize};
2022-09-04 04:12:10 -04:00
use tauri::api::dialog::blocking::FileDialogBuilder;
2022-09-25 19:11:32 -04:00
use tauri::api::path::{cache_dir, home_dir, picture_dir};
2022-09-15 03:22:43 -04:00
const OBJ_URL: &'static str = "data:image/png;base64,";
2022-09-04 04:12:10 -04:00
2022-09-17 13:52:30 -04:00
#[derive(Serialize, Deserialize, Clone, Debug)]
pub(crate) struct WebRay {
frames: [String; 4],
meta: HashMap<String, String>,
}
2022-09-04 04:12:10 -04:00
#[tauri::command]
pub(crate) async fn open_image() -> Option<String> {
debug!("Opening iamge dialog...");
2022-09-04 04:12:10 -04:00
let path = FileDialogBuilder::new()
.add_filter("Images", &["png", "jpg"])
2022-09-25 19:11:32 -04:00
.set_directory(picture_dir().unwrap_or_else(|| home_dir().unwrap()))
2022-09-15 03:22:43 -04:00
.set_title("Select an image")
2022-09-04 04:12:10 -04:00
.pick_file()?;
if let Ok(b) = image::open(path) {
let mut buf = Cursor::new(vec![]);
b.write_to(&mut buf, ImageFormat::Png).unwrap();
let encoded = base64::encode(buf.get_ref());
trace!("Encoded: {:?}", encoded);
2022-09-15 03:22:43 -04:00
Some(format!("{}{}", OBJ_URL, encoded))
2022-09-04 04:12:10 -04:00
} else {
None
}
}
2022-09-15 03:22:43 -04:00
#[tauri::command]
pub(crate) async fn open_ray() -> Option<WebRay> {
let path = FileDialogBuilder::new()
.add_filter("Rays", &["ray"])
.set_directory(home_dir()?)
.pick_file()?;
2022-09-17 12:45:26 -04:00
2022-10-12 15:18:49 -04:00
load_ray(path)
2022-09-17 12:45:26 -04:00
}
2022-10-12 15:18:49 -04:00
pub(crate) fn load_ray(path: impl AsRef<Path>) -> Option<WebRay> {
2022-09-25 19:11:32 -04:00
let ray = Ray::load(path.as_ref()).ok()?;
2022-09-16 14:17:27 -04:00
let mut frames = [String::new(), String::new(), String::new(), String::new()];
let mut meta = HashMap::new();
2022-09-15 03:22:43 -04:00
2022-09-16 14:17:27 -04:00
for i in 0..4 {
2022-09-17 13:52:30 -04:00
debug!("Trying frame {}", i);
2022-09-16 14:17:27 -04:00
if let Some(f) = ray.get_frame(i as usize) {
2022-09-17 13:52:30 -04:00
debug!("Got frame {}", i);
2022-09-16 14:17:27 -04:00
if f.is_empty() {
2022-09-17 13:52:30 -04:00
debug!("Frame {} was empty", i);
2022-09-16 14:17:27 -04:00
continue;
}
let encoded = base64::encode(&f);
frames[i as usize] = format!("{}{}", OBJ_URL, encoded);
}
}
for k in ray.get_meta_keys() {
if let Some(v) = ray.get_meta_value(&k) {
meta.insert(k.clone(), v.clone());
}
}
2022-09-25 19:11:32 -04:00
fs::write(
2022-10-12 15:18:49 -04:00
cache_dir().unwrap().join("cathode").join("last_selected"),
2022-09-25 19:11:32 -04:00
path.as_ref()
.canonicalize()
.unwrap()
.to_str()
.unwrap()
.as_bytes(),
)
.unwrap();
2022-09-16 14:17:27 -04:00
Some(WebRay { frames, meta })
2022-09-15 03:22:43 -04:00
}
#[tauri::command]
pub(crate) async fn save_ray(ray: WebRay) -> Result<(), String> {
if let Some(path) = FileDialogBuilder::new()
.add_filter("Rays", &["ray"])
.set_directory(home_dir().unwrap())
.set_title("Save Ray")
.set_file_name("new.ray")
.save_file()
{
let mut res = Ray::default();
for (i, f) in ray.frames.iter().enumerate() {
let stripped = f.strip_prefix(OBJ_URL).unwrap_or(f);
let decoded = base64::decode(stripped).unwrap();
res.set_frame(i as usize, decoded);
}
for (k, v) in ray.meta {
res.add_meta(k, v);
}
res.save(&path)
.map_err(|e| format!("Failed to save ray file: {}", e))
} else {
Ok(())
}
}