From bca027de6af119f7f5b0f718f7ab89c39dd56fc2 Mon Sep 17 00:00:00 2001 From: MarekSpodBiedry <73122968+MarekSpodBiedry@users.noreply.github.com> Date: Fri, 9 Oct 2026 21:11:41 +0200 Subject: [PATCH] Scripting: importFile(ImportOptions) imports one file unless sequence is set (#475) --- crates/script/src/prelude.js | 5 ++++- crates/script/src/tests.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/crates/script/src/prelude.js b/crates/script/src/prelude.js index f52765e7..cfd4d85a 100644 --- a/crates/script/src/prelude.js +++ b/crates/script/src/prelude.js @@ -1703,7 +1703,10 @@ Project.prototype = { importFile: function (opts) { var f = opts instanceof ImportOptions ? opts.file : opts; if (!f) throw __err("importFile(): no file"); - var r = __call("file.import", { paths: [__str(f)] }); + var args = { paths: [__str(f)] }; + // After Effects imports just the picked file unless ImportOptions.sequence is set. + if (opts instanceof ImportOptions) args.sequence = !!opts.sequence; + var r = __call("file.import", args); if (r.errors && r.errors.length) throw __err(r.errors.join("; ")); return __item(r.items[0]); }, diff --git a/crates/script/src/tests.rs b/crates/script/src/tests.rs index 10deb79b..1ae6def5 100644 --- a/crates/script/src/tests.rs +++ b/crates/script/src/tests.rs @@ -524,3 +524,36 @@ fn comp_preserves_nested_frame_rate_and_resolution() { let (_, c) = comp_named(&s, "Nested"); assert!(c.preserve_frame_rate && c.preserve_resolution); } + +/// Probes every file as a 64x32 still (the media layer's single-file probe). +struct Stills; +impl effectcraft_engine::Importer for Stills { + fn probe(&self, path: &str) -> Result { + use effectcraft_engine::project::{Footage, FootageKind}; + Ok(Footage { path: path.into(), kind: FootageKind::Still, width: 64, height: 32, has_video: true, codec: "PNG".into(), ..Default::default() }) + } +} + +/// `importFile(new ImportOptions(file))` imports just the picked file unless `sequence` is set (#475). +#[test] +fn import_options_sequence_picks_one_still_or_the_run() { + use effectcraft_engine::project::{FootageKind, ItemKind}; + let dir = std::env::temp_dir().join(format!("ec-script-seq-{}", std::process::id())); + std::fs::create_dir_all(&dir).unwrap(); + for n in ["shot_0001.png", "shot_0002.png", "shot_0003.png"] { + std::fs::write(dir.join(n), b"").unwrap(); + } + let pick = dir.join("shot_0002.png").to_string_lossy().replace('\\', "/"); + let mut s = session(); + s.importer = Some(Arc::new(Stills)); + let kind_of = |s: &Session, name: &str| { + let it = s.project.items.values().find(|i| i.name == name).unwrap_or_else(|| panic!("no item {name}")); + let ItemKind::Footage(f) = &it.kind else { panic!("footage") }; + f.kind + }; + ok(&mut s, &format!("var io = new ImportOptions(new File('{pick}')); app.project.importFile(io);")); + assert_eq!(kind_of(&s, "shot_0002.png"), FootageKind::Still); + ok(&mut s, &format!("var io = new ImportOptions(new File('{pick}')); io.sequence = true; app.project.importFile(io);")); + assert_eq!(kind_of(&s, "shot_[0001-0003].png"), FootageKind::Sequence); + let _ = std::fs::remove_dir_all(&dir); +}