mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-13 05:42:38 +00:00
Merge remote-tracking branch 'origin/main' into landb/2147
This commit is contained in:
commit
699963a257
4 files changed
+88
-24
No files matched your search
@@ -37,7 +37,7 @@ use figcraft_ui_egui::{ControlReply, ControlRequest, RequestGate};
|
||||
use serde_json::{Value, json};
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_futures::{JsFuture, future_to_promise};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
|
||||
use crate::saved_files::SavedFiles;
|
||||
|
||||
@@ -150,15 +150,6 @@ async fn sleep(ms: i32) {
|
||||
let _ = JsFuture::from(promise).await;
|
||||
}
|
||||
|
||||
/// A reply as a promise outcome: the `result`, or an `Error` carrying the `error`.
|
||||
fn outcome(reply: &Value) -> Result<JsValue, JsValue> {
|
||||
if reply.get("ok").and_then(Value::as_bool) == Some(true) {
|
||||
Ok(to_js(reply.get("result").unwrap_or(&Value::Null)))
|
||||
} else {
|
||||
Err(js_sys::Error::new(reply.get("error").and_then(Value::as_str).unwrap_or("error")).into())
|
||||
}
|
||||
}
|
||||
|
||||
fn set_fn(obj: &js_sys::Object, name: &str, f: JsValue) -> Result<(), JsValue> {
|
||||
js_sys::Reflect::set(obj, &name.into(), &f).map(|_| ())
|
||||
}
|
||||
@@ -169,20 +160,20 @@ pub fn install() -> Result<(), JsValue> {
|
||||
Rc::new(PageApi::new(APP, Methods::default(), request)).install()?;
|
||||
let window = web_sys::window().ok_or("no window")?;
|
||||
let obj: js_sys::Object = js_sys::Reflect::get(&window, &APP.into())?.unchecked_into();
|
||||
set_fn(
|
||||
&obj,
|
||||
"inspect",
|
||||
Closure::<dyn Fn() -> js_sys::Promise>::new(|| future_to_promise(async { outcome(&send("document.inspect", json!({})).await) }))
|
||||
.into_js_value(),
|
||||
)?;
|
||||
// `inspect` is `docInspect` under its earlier name: the crate's function, so it times out too.
|
||||
let doc_inspect = js_sys::Reflect::get(&obj, &"docInspect".into())?;
|
||||
js_sys::Reflect::set(&obj, &"inspect".into(), &doc_inspect)?;
|
||||
// `openFile` runs `file.open` through the crate's `execute`, so a call the app does not answer times out and is cancelled.
|
||||
let execute: js_sys::Function = js_sys::Reflect::get(&obj, &"execute".into())?.unchecked_into();
|
||||
let this = obj.clone();
|
||||
set_fn(
|
||||
&obj,
|
||||
"openFile",
|
||||
Closure::<dyn Fn(String, js_sys::Uint8Array) -> js_sys::Promise>::new(|name: String, bytes: js_sys::Uint8Array| {
|
||||
Closure::<dyn Fn(String, js_sys::Uint8Array) -> JsValue>::new(move |name: String, bytes: js_sys::Uint8Array| {
|
||||
let data = base64::engine::general_purpose::STANDARD.encode(bytes.to_vec());
|
||||
future_to_promise(async move {
|
||||
outcome(&send("engine.execute", json!({"command": "file.open", "params": {"name": name, "data": data}})).await)
|
||||
})
|
||||
execute
|
||||
.call2(&this, &"file.open".into(), &to_js(&json!({"name": name, "data": data})))
|
||||
.unwrap_or_else(|e| js_sys::Promise::reject(&e).into())
|
||||
})
|
||||
.into_js_value(),
|
||||
)?;
|
||||
|
||||
@@ -417,12 +417,16 @@ fn assert_slot_text(s: &mut Session, instance: NodeId, expected: &str) {
|
||||
assert!(html.contains(&format!(">{expected}</p>")), "slot Label HTML: {html}");
|
||||
}
|
||||
|
||||
fn assert_local_slot_text(s: &mut Session, instance: NodeId, expected: &str) {
|
||||
fn assert_stored_slot_text(s: &Session, instance: NodeId, expected: &str) {
|
||||
assert!(
|
||||
matches!(&node(s, instance).kind, NodeKind::Instance { props, .. } if props.get("Text") == Some(&json!(expected))),
|
||||
"instance {instance} must store its own Text value {expected:?}: {:?}",
|
||||
node(s, instance).kind
|
||||
);
|
||||
}
|
||||
|
||||
fn assert_local_slot_text(s: &mut Session, instance: NodeId, expected: &str) {
|
||||
assert_stored_slot_text(s, instance, expected);
|
||||
let properties = props_of(s, instance);
|
||||
let text = properties.iter().find(|p| p["name"] == "Text").unwrap_or_else(|| panic!("instance {instance} has no Text property: {properties:?}"));
|
||||
assert_eq!(text["value"], expected, "instance {instance} Text property");
|
||||
@@ -475,14 +479,15 @@ fn slot_text_properties_do_not_read_an_unbound_base_property() {
|
||||
ex(&mut s, "component.addProperty", json!({"id": base, "name": "Text", "type": "text", "default": "Wrong owner"}));
|
||||
let i = idv(&ex(&mut s, "instance.create", json!({"component": composition, "x": 400})));
|
||||
let nested_base = kids(&s, i)[0];
|
||||
assert_local_slot_text(&mut s, nested_base, "Wrong owner");
|
||||
// Bound to no layer, the base's Text isn't listed on its instance (#2269); its value stays stored.
|
||||
assert_stored_slot_text(&s, nested_base, "Wrong owner");
|
||||
let nested = copy_of(&s, i, main_content);
|
||||
assert_local_slot_text(&mut s, nested, "Default");
|
||||
assert_slot_text(&mut s, nested, "Default");
|
||||
ex(&mut s, "instance.setProperties", json!({"ids": [nested], "properties": {"Text": "Custom"}}));
|
||||
assert_local_slot_text(&mut s, nested, "Custom");
|
||||
assert_slot_text(&mut s, nested, "Custom");
|
||||
assert_local_slot_text(&mut s, nested_base, "Wrong owner");
|
||||
assert_stored_slot_text(&s, nested_base, "Wrong owner");
|
||||
assert_slot_text(&mut s, main_content, "Default");
|
||||
healthy(&s);
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ name = "Svenska"
|
||||
"Another server, or one that needs its key. The usual server is set in Preferences." = "En annan server, eller en som kräver sin nyckel. Standardservern anges i Inställningar."
|
||||
"Any status" = "Valfri status"
|
||||
"Anyone on your network with this code can edit the file, while this app stays open." = "Alla i ditt nätverk som har den här koden kan redigera filen så länge appen är öppen."
|
||||
"Anyone on your network with this code can look at the file, not change it, while this app stays open." = "Alla i ditt nätverk som har den här koden kan titta på filen, men inte ändra den, så länge appen är öppen."
|
||||
"Anyone with the edit link can change the file; the view link only lets people look. The links carry their secrets: share them like passwords. `figcraft-server links` makes more and revokes them." = "Alla med redigeringslänken kan ändra filen; visningslänken låter bara andra titta. Länkarna innehåller sina hemligheter: dela dem som lösenord. `figcraft-server links` skapar fler och återkallar dem."
|
||||
"Anyone with this code can edit the file." = "Alla med den här koden kan redigera filen."
|
||||
"Anyone with this code can look at the file, not change it." = "Alla med den här koden kan titta på filen, men inte ändra den."
|
||||
@@ -388,6 +389,8 @@ name = "Svenska"
|
||||
"Crop marks" = "Skärmärken"
|
||||
"Ctrl+arrows" = "Ctrl+piltangenter"
|
||||
"Ctrl+click" = "Ctrl+klick"
|
||||
"Ctrl+click a padding field" = "Ctrl+klicka på ett padding-fält"
|
||||
"⌘ click a padding field" = "⌘ klicka på ett padding-fält"
|
||||
"Ctrl+scroll" = "Ctrl+rullning"
|
||||
"Current name" = "Aktuellt namn"
|
||||
"Current version" = "Aktuell version"
|
||||
@@ -407,6 +410,40 @@ name = "Svenska"
|
||||
"Decoration style" = "Dekorationsstil"
|
||||
"Decoration" = "Dekoration"
|
||||
"Deep select" = "Djupmarkering"
|
||||
"Scrub a field faster (2x) or slower (1/2, 1/4)" = "Dragjustera ett fält snabbare (2x) eller långsammare (1/2, 1/4)"
|
||||
"Move up or down while dragging its label" = "Flytta upp eller ned medan du drar dess etikett"
|
||||
"Scrubbing at 2x" = "Dragjustering med 2x hastighet"
|
||||
"Scrubbing at 1x" = "Dragjustering med 1x hastighet"
|
||||
"Scrubbing at 1/2" = "Dragjustering med 1/2 hastighet"
|
||||
"Scrubbing at 1/4" = "Dragjustering med 1/4 hastighet"
|
||||
"Delete {n} variables" = { one = "Radera {n} variabel", other = "Radera {n} variabler" }
|
||||
"Move out of any group" = "Flytta ut ur alla grupper"
|
||||
"Move to group {group}" = "Flytta till gruppen {group}"
|
||||
"Scope: all supported properties" = "Omfång: alla egenskaper som stöds"
|
||||
"Scope: hidden from pickers" = "Omfång: dold i väljare"
|
||||
"Scope: only {scope}" = "Omfång: endast {scope}"
|
||||
"Disconnected. Reconnecting…" = "Frånkopplad. Återansluter…"
|
||||
"Disconnected. Your edits stay here and sync when the connection returns. Reconnecting…" = "Frånkopplad. Dina redigeringar finns kvar här och synkas när anslutningen är tillbaka. Återansluter…"
|
||||
"Dismiss" = "Stäng"
|
||||
"Not connected: {reason}. Your work is still in this tab." = "Inte ansluten: {reason}. Ditt arbete finns kvar i den här fliken."
|
||||
"Retry now" = "Försök igen nu"
|
||||
"Save a copy…" = "Spara en kopia…"
|
||||
"Wrap style" = "Radbrytningsstil"
|
||||
"Text direction" = "Textriktning"
|
||||
"Auto: by the first letter with a direction" = "Auto: efter den första bokstaven som har en riktning"
|
||||
"Left to right" = "Vänster till höger"
|
||||
"Right to left" = "Höger till vänster"
|
||||
"Balance" = "Balans"
|
||||
"Pretty" = "Snygg"
|
||||
"Auto: as many words as fit on each line" = "Auto: så många ord som får plats på varje rad"
|
||||
"Balance: every line close to the same length" = "Balans: alla rader ungefär lika långa"
|
||||
"Pretty: full lines, no one word alone on the last" = "Snygg: fulla rader, inget ensamt ord på den sista"
|
||||
"Set hug contents" = "Ställ in Omslut innehåll"
|
||||
"Set fill container" = "Ställ in Fyll behållaren"
|
||||
"Double-click an edge of an auto layout frame" = "Dubbelklicka på en kant av en auto layout-frame"
|
||||
"{name}, disconnected from its live session" = "{name}, frånkopplad från sin livesession"
|
||||
"⌥ double-click an edge of an auto layout child" = "⌥ dubbelklicka på en kant av ett underordnat objekt i auto layout"
|
||||
"Alt+double-click an edge of an auto layout child" = "Alt+dubbelklicka på en kant av ett underordnat objekt i auto layout"
|
||||
"Default" = "Standard"
|
||||
"Default content" = "Standardinnehåll"
|
||||
"Default value (the top-left variant)" = "Standardvärde (varianten längst upp till vänster)"
|
||||
@@ -494,6 +531,7 @@ name = "Svenska"
|
||||
"Edit dev resource" = "Redigera utvecklarresurs"
|
||||
"Edit link" = "Redigeringslänk"
|
||||
"Edit link copied" = "Redigeringslänken har kopierats"
|
||||
"Edit padding on all sides" = "Redigera padding på alla sidor"
|
||||
"Edit style" = "Redigera stil"
|
||||
"Edit variable" = "Redigera variabel"
|
||||
"Edit with the builder" = "Redigera med byggaren"
|
||||
@@ -531,6 +569,7 @@ name = "Svenska"
|
||||
"Exclusion" = "Uteslutning"
|
||||
"Exit focus view (Esc)" = "Lämna fokusvyn (Esc)"
|
||||
"Expand" = "Expandera"
|
||||
"Expand the interface" = "Expandera gränssnittet"
|
||||
"Export" = "Exportera"
|
||||
"Export all" = "Exportera alla"
|
||||
"Export frames and layers as PNG, JPG, SVG or PDF" = "Exportera frames och lager som PNG, JPG, SVG eller PDF"
|
||||
@@ -1073,6 +1112,7 @@ name = "Svenska"
|
||||
"Pages: {pages}" = "Sidor: {pages}"
|
||||
"Paint bucket" = "Färghink"
|
||||
"Pan the canvas" = "Panorera arbetsytan"
|
||||
"Show and move the placement crosshair (its tool chosen, nothing selected)" = "Visa och flytta placeringshårkorset (med dess verktyg valt och inget markerat)"
|
||||
"Pan with nothing selected (Shift: farther)" = "Panorera när inget är markerat (Shift: längre)"
|
||||
"Panels" = "Paneler"
|
||||
"Paper" = "Papper"
|
||||
@@ -1297,6 +1337,7 @@ name = "Svenska"
|
||||
"See all templates" = "Se alla mallar"
|
||||
"Select layers and they space themselves as their content changes" = "Markera lager så fördelar de avståndet själva när innehållet ändras"
|
||||
"SHA-256: {sha}…" = "SHA-256: {sha}…"
|
||||
"Same as file ({profile})" = "Samma som filen ({profile})"
|
||||
"Same as layer" = "Samma som lagret"
|
||||
"Saturation" = "Mättnad"
|
||||
"Save" = "Spara"
|
||||
@@ -1969,6 +2010,17 @@ name = "Svenska"
|
||||
"⌘ click" = "⌘ klicka"
|
||||
"⌘ scroll" = "⌘ rulla"
|
||||
"⌥ drag" = "⌥ dra"
|
||||
"Selection box: switch to pick select" = "Markeringsruta: växla till plockmarkering"
|
||||
"Pick select: next or previous layer" = "Plockmarkering: nästa eller föregående lager"
|
||||
"Pick select: into a layer, out to its parent" = "Plockmarkering: in i ett lager, ut till dess överordnade"
|
||||
"Pick select: select the picked layer" = "Plockmarkering: markera det valda lagret"
|
||||
"⇥ or ⌥ Space again" = "⇥ eller ⌥ Blanksteg igen"
|
||||
"Tab or Ctrl+Space again" = "Tab eller Ctrl+Blanksteg igen"
|
||||
"↵ / ⇧↵" = "↵ / ⇧↵"
|
||||
"Enter / Shift+Enter" = "Enter / Shift+Enter"
|
||||
"Space" = "Blanksteg"
|
||||
"Nothing to pick: the page is empty" = "Inget att välja: sidan är tom"
|
||||
"Pick select: Tab and Shift+Tab move between layers, Enter goes into one, Shift+Enter out, Space selects, Escape cancels" = "Plockmarkering: Tab och Shift+Tab flyttar mellan lager, Enter går in i ett, Shift+Enter ut, Blanksteg markerar, Esc avbryter"
|
||||
|
||||
[commands]
|
||||
|
||||
@@ -2005,6 +2057,7 @@ name = "Svenska"
|
||||
"board.label" = "Kopplingsetikett"
|
||||
"board.nextSticky" = "Nästa lapp"
|
||||
"board.reattach" = "Koppla om koppling"
|
||||
"board.reshape" = "Omforma koppling"
|
||||
"board.setColor" = "Whiteboardfärg"
|
||||
"board.setStyle" = "Whiteboardstil"
|
||||
"board.shape" = "Form med text"
|
||||
@@ -2047,6 +2100,7 @@ name = "Svenska"
|
||||
"collab.openFile" = "Öppna onlinefil"
|
||||
"collab.peers" = "Personer i den här filen"
|
||||
"collab.publish" = "Publicera på server"
|
||||
"collab.reconnect" = "Återanslut livesessionen"
|
||||
"collab.recoverFile" = "Återställ onlinefil"
|
||||
"collab.registerLinks" = "Öppna inbjudningslänkar i FigCraft"
|
||||
"collab.removePerson" = "Ta bort från session"
|
||||
@@ -2195,6 +2249,7 @@ name = "Svenska"
|
||||
"image.deletePreset" = "Radera förinställning"
|
||||
"image.place" = "Placera bild"
|
||||
"image.presets" = "Bildförinställningar"
|
||||
"image.replace" = "Ersätt bild"
|
||||
"image.savePreset" = "Spara förinställning"
|
||||
"inspect.assets" = "Resurser"
|
||||
"inspect.code" = "Kod"
|
||||
@@ -2212,6 +2267,7 @@ name = "Svenska"
|
||||
"layers.collapseAll" = "Fäll ihop alla"
|
||||
"layout.add" = "Lägg till auto layout"
|
||||
"layout.remove" = "Ta bort auto layout"
|
||||
"layout.removeAll" = "Ta bort all auto layout"
|
||||
"layout.setTrack" = "Ange spår"
|
||||
"layout.suggest" = "Föreslå layout"
|
||||
"libraries.open" = "Öppna bibliotek"
|
||||
@@ -2306,6 +2362,9 @@ name = "Svenska"
|
||||
"pref.showDimensions" = "Visa dimensioner på objekt"
|
||||
"pref.startOnHome" = "Börja på Start"
|
||||
"pref.uiScale" = "Gränssnittsstorlek"
|
||||
"pref.uiScaleDown" = "Mindre gränssnitt"
|
||||
"pref.uiScaleReset" = "Standardstorlek för gränssnittet"
|
||||
"pref.uiScaleUp" = "Större gränssnitt"
|
||||
"pref.userName" = "Ditt namn"
|
||||
"proto.action.add" = "Lägg till prototypåtgärd"
|
||||
"proto.action.move" = "Ändra ordning på prototypåtgärd"
|
||||
@@ -2353,6 +2412,7 @@ name = "Svenska"
|
||||
"selection.applyColorStyle" = "Använd färgformatmall på markeringen"
|
||||
"selection.bindColorVariable" = "Använd färgvariabel på markeringen"
|
||||
"selection.colors" = "Markeringsfärger"
|
||||
"selection.createColorStyle" = "Skapa färgstil från markeringen"
|
||||
"selection.detachColor" = "Koppla bort markeringsfärg"
|
||||
"selection.selectColor" = "Markera lager med den här färgen"
|
||||
"selection.setPaint" = "Ändra markeringens färg"
|
||||
@@ -2399,6 +2459,10 @@ name = "Svenska"
|
||||
"text.caseUpper" = "Versaler"
|
||||
"text.create" = "Text"
|
||||
"text.decoration" = "Dekoration"
|
||||
"text.direction" = "Textriktning"
|
||||
"text.directionAuto" = "Textriktning: auto"
|
||||
"text.directionLtr" = "Textriktning: vänster till höger"
|
||||
"text.directionRtl" = "Textriktning: höger till vänster"
|
||||
"text.edit.begin" = "Redigera text"
|
||||
"text.edit.caret" = "Placera markören"
|
||||
"text.edit.end" = "Sluta redigera text"
|
||||
@@ -2423,6 +2487,7 @@ name = "Svenska"
|
||||
"text.missingFonts" = "Saknade typsnitt"
|
||||
"text.numberList" = "Numrerad lista"
|
||||
"text.onPath" = "Text på bana"
|
||||
"text.openLink" = "Öppna länk"
|
||||
"text.paragraphIndent" = "Styckeindrag"
|
||||
"text.paragraphSpacing" = "Styckeavstånd"
|
||||
"text.pathOptions" = "Alternativ för textbana"
|
||||
@@ -2442,9 +2507,11 @@ name = "Svenska"
|
||||
"text.underline" = "Understrykning"
|
||||
"text.weightDown" = "Minska teckenvikten"
|
||||
"text.weightUp" = "Öka teckenvikten"
|
||||
"text.wrapStyle" = "Radbrytningsstil"
|
||||
"tool.arrow" = "Pil"
|
||||
"tool.comment" = "Kommentar"
|
||||
"tool.connector" = "Koppling"
|
||||
"tool.crosshair" = "Flytta placeringshårkorset"
|
||||
"tool.ellipse" = "Ellips"
|
||||
"tool.eraser" = "Suddgummi"
|
||||
"tool.frame" = "Frame"
|
||||
@@ -2488,6 +2555,7 @@ name = "Svenska"
|
||||
"variable.deleteCollection" = "Radera samling"
|
||||
"variable.duplicate" = "Duplicera variabel"
|
||||
"variable.export" = "Exportera variabler"
|
||||
"variable.extendCollection" = "Utöka samlingen"
|
||||
"variable.import" = "Importera variabler"
|
||||
"variable.list" = "Lista variabler"
|
||||
"variable.moveMode" = "Flytta läge"
|
||||
@@ -2561,6 +2629,7 @@ name = "Svenska"
|
||||
"view.layoutGrids" = "Layoutrutnät"
|
||||
"view.leftSidebar" = "Visa/dölj vänster sidofält"
|
||||
"view.maskOutlines" = "Konturlinjer för masker"
|
||||
"view.minimize" = "Minimera gränssnittet"
|
||||
"view.multiplayerCursors" = "Samarbetsmarkörer"
|
||||
"view.nextFrame" = "Zooma till nästa frame"
|
||||
"view.nextPage" = "Nästa sida"
|
||||
|
||||
@@ -1575,7 +1575,6 @@ status = "draft — needs native review"
|
||||
"Texts" = "உரைகள்"
|
||||
"Texture" = "அமைப்பு"
|
||||
"The bars are hidden. {shortcut} shows them again" = "பட்டைகள் மறைக்கப்பட்டுள்ளன. {shortcut} அவற்றை மீண்டும் காட்டும்"
|
||||
"The canvas previews colors in sRGB; exported PNG, JPG and WebP files are tagged Display P3." = "கேன்வாஸ் நிறங்களை sRGB இல் காட்டுகிறது; ஏற்றுமதி செய்த PNG, JPG, WebP கோப்புகள் Display P3 எனக் குறிக்கப்படும்."
|
||||
"The destination document is unavailable. Nothing was imported." = "இலக்கு ஆவணம் கிடைக்கவில்லை. எதுவும் இறக்குமதி செய்யப்படவில்லை."
|
||||
"The destination document was closed. Nothing was imported." = "இலக்கு ஆவணம் மூடப்பட்டது. எதுவும் இறக்குமதி செய்யப்படவில்லை."
|
||||
"The destination page was removed. Nothing was imported." = "இலக்குப் பக்கம் அகற்றப்பட்டது. எதுவும் இறக்குமதி செய்யப்படவில்லை."
|
||||
|
||||
Reference in new issue
Block a user