mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-31 22:06:49 -06:00
* M6: FigJam .jam files open like .fig files (#1342) A .jam is the same archive as a .fig (its canvas header reads fig-jam.), which the .fig reader already took; File > Open and its filter, drag and drop, file.import and the command line now take .jam too, and the home screen shows its thumbnail. FigJam layers come in as the .fig reader makes them (stickies and shapes with text as frames with their generated layers, other FigJam layers as frames or vectors with a note, unknown types left out with a note). Tests use a synthetic fig-jam. canvas and a .jam made from our own export. * M12: a FigJam .jam file opens as a board (#1342) The .fig reader marks a canvas with FigJam's fig-jam. header as FileKind::Board, so a .jam opens with the board toolbar, the dot grid and the board panels and saves as a board; a .fig stays a design file, and importing a .jam into an open file leaves its kind alone. Its objects stay ordinary layers (frames and vectors with the existing import notes). Builds on the .jam opening branch (#1586).
56 lines
2.4 KiB
Rust
56 lines
2.4 KiB
Rust
//! FigJam `.jam` files (#1342) open and import like `.fig` files: File ▸ Open (`file.open`), the
|
|
//! command line (the same command) and File ▸ Import / drag and drop (`file.import`). The file is
|
|
//! made here from our own `.fig` export with the canvas header FigJam writes (`fig-jam.`).
|
|
|
|
use std::io::{Read, Write};
|
|
|
|
use serde_json::json;
|
|
|
|
use crate::Session;
|
|
|
|
/// A `.jam` holding one page with a rectangle named `Card`, written to a temporary file.
|
|
fn jam_file(tag: &str) -> std::path::PathBuf {
|
|
let mut doc = figcraft_doc::Document::new("Synthetic board");
|
|
let page = doc.first_page().unwrap();
|
|
doc.create(page, figcraft_doc::NodeKind::Rectangle, "Card", 10.0, 10.0, 80.0, 40.0).unwrap();
|
|
let (fig, _) = figcraft_format::fig::export(&doc, None).unwrap();
|
|
let mut from = zip::ZipArchive::new(std::io::Cursor::new(fig)).unwrap();
|
|
let mut to = zip::ZipWriter::new(std::io::Cursor::new(Vec::new()));
|
|
for i in 0..from.len() {
|
|
let mut member = from.by_index(i).unwrap();
|
|
let mut bytes = Vec::new();
|
|
member.read_to_end(&mut bytes).unwrap();
|
|
if member.name() == "canvas.fig" {
|
|
assert!(bytes.starts_with(b"fig-kiwi"));
|
|
bytes.splice(..8, *b"fig-jam.");
|
|
}
|
|
to.start_file(member.name(), zip::write::SimpleFileOptions::default()).unwrap();
|
|
to.write_all(&bytes).unwrap();
|
|
}
|
|
let path = std::env::temp_dir().join(format!("figcraft-jam-{tag}-{}.jam", std::process::id()));
|
|
std::fs::write(&path, to.finish().unwrap().into_inner()).unwrap();
|
|
path
|
|
}
|
|
|
|
fn cards(s: &Session) -> usize {
|
|
s.doc().unwrap().nodes().filter(|n| n.name == "Card").count()
|
|
}
|
|
|
|
#[test]
|
|
fn a_jam_file_opens_and_imports_like_a_fig() {
|
|
let path = jam_file("open");
|
|
let mut s = Session::new();
|
|
s.execute("file.open", &json!({"path": path})).unwrap();
|
|
assert_eq!(cards(&s), 1, "opened");
|
|
assert!(crate::board::is_board(s.doc().unwrap()), "a whiteboard opens as a board");
|
|
// Imported into a design file, it adds its pages to it (not an image of its bytes), which
|
|
// stays a design file.
|
|
s.execute("doc.switch", &json!({"index": 0})).unwrap();
|
|
let before = s.doc().unwrap().pages.len();
|
|
s.execute("file.import", &json!({"path": path})).unwrap();
|
|
assert_eq!(s.doc().unwrap().pages.len(), before + 1);
|
|
assert_eq!(cards(&s), 1);
|
|
assert!(!crate::board::is_board(s.doc().unwrap()));
|
|
std::fs::remove_file(path).unwrap();
|
|
}
|