Merge pull request #2054 from midasdf/jp/ja-dialogs

i18n(ja): panels and dialogs (27% → 39%)
This commit is contained in:
BFlat
2026-10-30 07:10:31 +07:00
committed by GitHub
11 changed files with 1043 additions and 61 deletions
+18 -11
View File
@@ -2,7 +2,7 @@
**Stage: alpha** · next: beta, ~30 points of "ready for real work" and ~350–620 h away
> **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (open-issue count, crash list and localization share re-audited against `upstream/main` 470ea7a3) · **Target:** Adobe After Effects 2026 (26.5.0.89)
> **Last reviewed:** 2026-10-22 · **Last updated:** 2026-10-30 · **Change:** minor (localization: 303 more panel/dialog rows in Japanese and the Chinese catalogs; recounted after #1774: Japanese 27% → 46%, Simplified Chinese 29% → 46%, Traditional Chinese 29% → 38%, overall 18% → 24%) · **Target:** Adobe After Effects 2026 (26.5.0.89)
EffectCraft aims to do what After Effects does, with the same panels, menus and behaviour, written
from scratch in Rust. This page is the one-page summary; the evidence is in
@@ -51,7 +51,7 @@ Linux/Windows reliability (30–50 h) and depth in animation, masks, effects and
| UI/UX fidelity | 65% | 60–120 | [ui-parity.md](docs/ui-parity.md) |
| File formats | 50% | 130–230 | [file-format-parity.md](docs/file-format-parity.md) |
| Hardware | 40% | 60–120 | [hardware-parity.md](docs/hardware-parity.md) |
| Localization | 18% | 60–110 + review | [localization-parity.md](docs/localization-parity.md) |
| Localization | 24% | 60–110 + review | [localization-parity.md](docs/localization-parity.md) |
| Performance | 35% | 50–100 | [gaps.md](docs/gaps.md#g5-performance-at-real-world-scale) |
| Stability | 45% | 40–80 | [gaps.md](docs/gaps.md#g3-stability-and-a-green-main) |
| Platforms | 65% | 30–60 | [gaps.md](docs/gaps.md#g2-real-user-reliability-on-every-platform) |
@@ -80,24 +80,24 @@ Weights and evidence per row: [target-app-parity.md](docs/target-app-parity.md#b
## Languages
UI strings translated out of ≈ 3,900 (detail: [localization-parity.md](docs/localization-parity.md)).
UI strings translated out of ≈ 4,200 (detail: [localization-parity.md](docs/localization-parity.md)).
| Language | Status | % |
|---|---|---:|
| English | full | 100% |
| Simplified Chinese | partial (menus, part of the panels) | 29% |
| Spanish | menus only | 16% |
| Simplified Chinese | partial (menus, most of the panels) | 46% |
| Spanish | menus only | 29% |
| Hindi | none | 0% |
| Arabic | none | 0% |
| French | menus only | 16% |
| Portuguese (Brazil) | partial (menus, part of the panels) | 26% |
| Portuguese (Brazil) | partial (menus, part of the panels) | 34% |
| Indonesian | none | 0% |
| Japanese | partial (menus, part of the panels) | 27% |
| Japanese | partial (menus, most of the panels) | 46% |
| German | menus only | 16% |
| Korean | none | 0% |
| Vietnamese | none | 0% |
Also shipped: Traditional Chinese (partial, 29%), Ukrainian (partial, 29%), Czech (partial, 29%), Georgian (partial, 38%; native-speaker reviewed) and Russian (menus only, 16%). No other language has had
Also shipped: Traditional Chinese (partial, 38%), Ukrainian (partial, 29%), Czech (partial, 29%), Polish (partial, 34%), Georgian (partial, 39%; native-speaker reviewed) and Russian (menus only, 15%). No other language has had
native-speaker review.
## Upcoming
@@ -125,10 +125,17 @@ Come tell us what matters most to you on [Discord](https://discord.gg/artcraft).
rotation of the paths above it by random amounts that change over time, up to the Transform
values it holds. The copies of a Repeater above it wiggle independently as far as its
Correlation allows; with the Repeater below it, they wiggle together.
- 2026-10-22: Localization: the panel/dialog catalogs gain 303 rows in Japanese, Simplified
Chinese and Traditional Chinese — panel tabs, form and dialog labels, panel context menus,
tracker/graph/text-panel controls, File-panel footers and credits. Recounted after #1774:
Japanese is 1,923 of ≈ 4,200 interface strings (46%, with 297 effect names); the Chinese
panel catalogs hold 998 (Simplified) and 951 (Traditional) rows, and Simplified Chinese is
46% with its 307 effect names; the overall share is ≈ 24%.
- 2026-10-16: Convert To Bezier Path turns a shape layer's Rectangle, Ellipse or Polystar
path into an editable Path 1 with the same geometry, as After Effects does; it used to
apply to mask RotoBezier only, so a parametric shape path could not be converted at all
and its vertices could not be edited or animated (#932).
- 2026-10-14: Georgian (`ka`): every menu row, every panel-catalog row the Chinese catalogs have plus 195 Georgian-only ones, and the effect names and categories; Match System for `ka` / `ka-GE` / `ka_GE.UTF-8` locales. Reviewed by a native speaker.
- 2026-10-12: Roto Brush span edits report strokes outside a trimmed layer without panicking;
strokes and undo history are preserved so restoring the timing allows the span edit again.
- 2026-10-11: Ukrainian panels caught up with the Chinese catalogs. The 95 rows the panel
@@ -143,7 +150,6 @@ Come tell us what matters most to you on [Discord](https://discord.gg/artcraft).
follow the shared standard: `docs/parity.md` became `docs/target-app-parity.md`; new
`docs/roadmap.md`, `localization-parity.md`, `file-format-parity.md`, `hardware-parity.md`,
`ui-parity.md`, `effects-parity.md` and `scripting-parity.md`.
- 2026-10-14: Georgian (`ka`): every menu row, every panel-catalog row the Chinese catalogs have plus 195 Georgian-only ones, and the effect names and categories; Match System for `ka` / `ka-GE` / `ka_GE.UTF-8` locales. Reviewed by a native speaker.
- 2026-10-10: Spanish (#460) and Brazilian Portuguese (#217) menu translations.
- 2026-10-10: Japanese now translates the interface below the menu bar too: `crates/ui-egui/src/i18n/ui.rs` has a Japanese table with the same 396 rows as the Chinese ones (panels, dialogs, buttons and tooltips; the shape test keeps the three catalogs listing the same source strings). Menus were already Japanese.
- 2026-10-09: Ukrainian now covers all 396 current panel-catalog strings, including dialogs, buttons and tooltips, alongside its menu translation. The catalog keeps the same source keys and placeholder counts as the Chinese catalogs; missing or engine-generated text still falls back to English.
@@ -163,11 +169,12 @@ Come tell us what matters most to you on [Discord](https://discord.gg/artcraft).
| Date | Change | Summary |
|---|---|---|
| 2026-10-22 | minor | Localization: 300 more panel/dialog rows in Japanese and the Chinese catalogs, plus the review's three missing rows (Basic, Advanced, Play/Stop) — panel tabs, form and dialog labels, context menus, tracker/graph/text-panel controls, File-panel footers, credits; language shares recounted after #1774 (Japanese 27% → 46% with 297 effect names, Simplified Chinese 29% → 46% with 307 effect names, Traditional Chinese 29% → 38%, overall 18% → 24%) |
| 2026-10-12 | minor | Open-issue count (134 to 216), crash list and localization share (12% to 18%) updated to match docs/gaps.md |
| 2026-10-12 | patch | Roto Brush span validation after trimming; command regressions for both layer edges |
| 2026-10-12 | minor | Shared PDF object/xref parsing with bounded app-owned conversion and preserved stream budgets; drawing, EPS and image/font policy remain unchanged |
| 2026-10-10 | minor | Hours to ≈ 95% for each audience |
| 2026-10-10 | minor | Headline adds mainstream practitioner (≈ 47%) and essentials user (≈ 52%) |
| 2026-10-12 | minor | Shared PDF object/xref parsing with bounded app-owned conversion and preserved stream budgets; drawing, EPS and image/font policy remain unchanged |
| 2026-10-10 | minor | Stage checked against the new core-workflow gate (all six pass; still alpha) |
| 2026-10-10 | major | Rewritten to the shared progress-docs standard: stage, two numbers, dimensions, features, languages, upcoming, progress log; milestones moved to docs/roadmap.md |
| 2026-10-10 | minor | Stage checked against the new core-workflow gate (all six pass; still alpha) |
| 2026-10-05 | major | Two numbers (breadth vs real use) and workstreams G1–G9 |
+4 -4
View File
@@ -246,7 +246,7 @@ pub fn contributors_ui(ui: &mut egui::Ui, auto: &mut Registry) {
ui.horizontal_wrapped(|ui| {
ui.label(tr("Show"));
for m in NameMode::ALL {
let r = ui.selectable_label(v.names == m, m.label());
let r = ui.selectable_label(v.names == m, tr(m.label()));
auto.add(&format!("about.credits.show.{}", m.id()), r.rect, m.label());
if r.clicked() {
v.names = m;
@@ -254,9 +254,9 @@ pub fn contributors_ui(ui: &mut egui::Ui, auto: &mut Registry) {
}
ui.separator();
ui.label(tr("Sort"));
let combo = craft_ui::ComboBox::from_id_salt("credits_sort").selected_text(v.key.label().0).show_ui(ui, |ui| {
let combo = craft_ui::ComboBox::from_id_salt("credits_sort").selected_text(tr(v.key.label().0)).show_ui(ui, |ui| {
for k in SortKey::ALL {
let r = ui.selectable_label(v.key == k, k.label().0);
let r = ui.selectable_label(v.key == k, tr(k.label().0));
auto.add(&format!("about.credits.sort.{}", k.id()), r.rect, k.label().0);
if r.clicked() {
v.key = k;
@@ -309,7 +309,7 @@ fn table(ui: &mut egui::Ui, list: &[&Contributor], v: &mut View, auto: &mut Regi
egui::Grid::new("credits_table").striped(true).num_columns(SortKey::ALL.len()).show(ui, |ui| {
for k in SortKey::ALL {
let arrow = if v.key == k { if v.ascending { " ▲" } else { " ▼" } } else { "" };
let r = ui.button(RichText::new(format!("{}{arrow}", k.label().1)).strong()).on_hover_text(k.label().0);
let r = ui.button(RichText::new(format!("{}{arrow}", k.label().1)).strong()).on_hover_text(tr(k.label().0));
auto.add(&format!("about.credits.header.{}", k.id()), r.rect, k.label().0);
if r.clicked() {
if v.key == k {
+13
View File
@@ -7536,6 +7536,19 @@ mod tests {
println!("total: {total}");
}
/// Prints the translated-row counts per language, the numbers `docs/localization-parity.md`
/// quotes. `cargo xtask i18n-report` runs it with `--nocapture`.
#[test]
fn catalog_row_counts_report() {
println!("Localization catalog rows:");
for code in CATALOG_CODES {
let menus = menu_catalog(code).map_or(0, |catalog| catalog.len());
let panels = ui::translated_rows(code);
let effect_names = effects::translated_rows(code);
println!("{code}: menus {menus}, panels {panels}, effect names {effect_names}, total {}", menus + panels + effect_names);
}
}
#[test]
fn menu_catalogs_have_no_stale_or_duplicate_rows() {
let mut actual = BTreeSet::new();
+7
View File
@@ -87,6 +87,13 @@ pub(crate) fn name(id: &str, english: &str) -> String {
catalog(current()).and_then(|c| c.row(id)).map_or_else(|| english.to_string(), |(_, translated)| translated.to_string())
}
/// The number of effect-name rows `language` translates, for the row-count report; 0 when it has
/// no catalog or when it is English.
#[cfg(test)]
pub(super) fn translated_rows(language: &str) -> usize {
catalog(language).map_or(0, |c| c.rows.len())
}
/// The name to draw for an effect group the property tree stores as `stored`: the catalog name,
/// plus the instance index the engine appends to a repeat (`Gaussian Blur 2` → `高斯模糊 2`).
///
File diff suppressed because it is too large Load Diff
+6 -4
View File
@@ -233,7 +233,7 @@ impl ButtonBar {
let chosen = widgets::popup_list(ui, pid, pos, r, rows, 0, |ui| {
let mut chosen = None;
for (id, label, on, tip) in &self.hidden {
let item = ui.selectable_label(*on, label.as_str()).on_hover_text(tip.as_str());
let item = ui.selectable_label(*on, crate::i18n::tr(label)).on_hover_text(crate::i18n::tr(tip));
app.auto.add(&format!("timeline.graph.more.{id}"), item.rect, tip);
if item.clicked() {
chosen = Some(id.clone());
@@ -263,14 +263,16 @@ struct BarBtn<'a> {
fn text_button(app: &mut EffectcraftApp, ui: &mut egui::Ui, p: &egui::Painter, bar: &mut ButtonBar, y: f32, btn: BarBtn) -> bool {
let BarBtn { label, on, id, tip } = btn;
let t = app.tokens;
let w = p.layout_no_wrap(label.to_string(), Tokens::ui(11.0), t.text).size().x + 14.0;
let (shown, shown_tip) = (crate::i18n::tr(label), crate::i18n::tr(tip));
let w = p.layout_no_wrap(shown.to_string(), Tokens::ui(11.0), t.text).size().x + 14.0;
// Once one button overflows, the rest follow it into the menu (they keep their order).
if !bar.hidden.is_empty() || bar.x + w > bar.limit {
// The menu translates these English labels when it draws them; automation keeps them.
bar.hidden.push((id.to_string(), label.to_string(), on, tip.to_string()));
return bar.chosen.as_deref() == Some(id);
}
let r = Rect::from_min_size(pos2(bar.x, y - 9.0), vec2(w, 18.0));
let resp = ui.interact(r, egui::Id::unique(("graph-btn", id)), Sense::click()).on_hover_text(tip);
let resp = ui.interact(r, egui::Id::unique(("graph-btn", id)), Sense::click()).on_hover_text(shown_tip);
p.rect_filled(
r,
3.0,
@@ -282,7 +284,7 @@ fn text_button(app: &mut EffectcraftApp, ui: &mut egui::Ui, p: &egui::Painter, b
Color32::from_rgb(0x2c, 0x2c, 0x2c)
},
);
p.text(r.center(), Align2::CENTER_CENTER, label, Tokens::ui(11.0), if on { Color32::WHITE } else { t.text });
p.text(r.center(), Align2::CENTER_CENTER, shown, Tokens::ui(11.0), if on { Color32::WHITE } else { t.text });
app.auto.add(&format!("timeline.graph.{id}"), r, tip);
bar.x += w + 4.0;
resp.clicked()
+4 -1
View File
@@ -43,7 +43,10 @@ pub fn preview(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
for (icon, cmd, tip) in buttons {
let r = Rect::from_min_size(pos2(x, y), vec2(bw, 28.0));
let icon = if cmd == "playback.toggle" && app.playback.playing { Icon::Pause } else { icon };
if widgets::icon_button(ui, r, icon, cmd == "playback.toggle" && app.playback.playing, &t, egui::Id::unique(("pv", cmd))).on_hover_text(tip).clicked() {
if widgets::icon_button(ui, r, icon, cmd == "playback.toggle" && app.playback.playing, &t, egui::Id::unique(("pv", cmd)))
.on_hover_text(tr(tip))
.clicked()
{
// The play button plays with the options of the shortcut shown below.
let params = if cmd == "playback.toggle" { json!({"shortcut": current.id()}) } else { json!({}) };
let _ = crate::menus::invoke(app, &ctx, cmd, params);
+1 -1
View File
@@ -812,7 +812,7 @@ fn footer(app: &mut EffectcraftApp, ui: &mut egui::Ui, p: &egui::Painter, foot:
(Icon::NewComp, "newComp", "Create a new Composition"),
] {
let r = Rect::from_min_size(pos2(x, foot.min.y + 3.0), vec2(22.0, 22.0));
let resp = widgets::icon_button(ui, r, icon, false, &t, egui::Id::unique(("pfoot", id))).on_hover_text(tip);
let resp = widgets::icon_button(ui, r, icon, false, &t, egui::Id::unique(("pfoot", id))).on_hover_text(crate::i18n::tr(tip));
app.auto.add(&format!("project.{id}"), r, tip);
resp.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, true, crate::i18n::tr(tip)));
if resp.clicked() {
+1 -1
View File
@@ -626,7 +626,7 @@ pub fn apply_dialog(app: &mut EffectcraftApp, ctx: &egui::Context, t: &Tokens) {
super::dialogs::modal(ctx, "Motion Tracker Apply Options", vec2(380.0, 170.0), t, |ui| {
ui.horizontal(|ui| {
ui.label(crate::i18n::tr("Apply Dimensions:"));
let labels = ["X and Y", "X only", "Y only"];
let labels = [crate::i18n::tr("X and Y"), crate::i18n::tr("X only"), crate::i18n::tr("Y only")];
let r = craft_ui::ComboBox::from_id_salt("track-apply-dims")
.selected_text(labels[d.dims.min(2)])
.show_ui(ui, |ui| {
+44 -37
View File
@@ -1,6 +1,6 @@
# Localization parity
> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-23 · **Change:** minor (Georgian: menus, panels and effect names; missing strings show in English; `missing_translations_report` lists them) · **Target:** Adobe After Effects 2026
> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-30 · **Change:** minor (recounted at this tree after #1774: Japanese 1,923 of ≈ 4,200 interface strings (46%, with 297 effect names), Simplified Chinese 1,935 (46%, with 307 effect names), Traditional Chinese 1,581 (38%, its panel catalog 951 rows after #2244); overall ≈ 24%; previously: minor, the panel/dialog catalogs grow by 303 rows in Japanese, Simplified Chinese and Traditional Chinese: panel tabs, form and dialog labels, context menus, tracker/graph/text-panel labels, credits and File-panel footers; previously: minor, catalogs recounted at `upstream/main` 470ea7a3: menus in 10 languages, panels in 6, Hangul probe (#599)) · **Target:** Adobe After Effects 2026
How much of EffectCraft's interface is translated, language by language, compared with After
Effects. [gaps.md](gaps.md) gap 16 and workstream G9 hold the work;
@@ -17,28 +17,31 @@ interface; Arabic and Hebrew text *in layers* is supported through its Middle Ea
## How EffectCraft translates
- **Menus:** `crates/ui-egui/src/i18n.rs`, one catalog per language keyed by
`(command, English label)` (624 catalog rows each at 470ea7a3, counted). A test
(`menu_catalogs_have_no_stale_or_duplicate_rows`) fails on a row whose entry left the menu tree
or on a repeated row. The generated Effect menu is not part of that fixed tree: its entries
and category submenus take their labels from the effect catalog below.
`(command, English label)`. A test (`menu_catalogs_have_no_stale_or_duplicate_rows`) fails on a
row whose entry left the menu tree or on a repeated row, so every catalog covers all fixed
entries (630 catalog rows each at this tree, counted; 629 in Georgian). The generated Effect menu is not part of
that fixed tree: its entries and category submenus take their labels from the effect catalog
below.
- **Panels, dialogs, buttons, tooltips:** `crates/ui-egui/src/i18n/ui.rs`, keyed by the English
source string, with English fallback. Catalogs exist for Japanese (693 rows), Simplified and
Traditional Chinese (695 and 648 since #2244 pruned the Traditional one), Ukrainian (524),
Brazilian Portuguese (695) and Czech (518), counted at this tree. Georgian has every row the
Simplified Chinese catalog has, plus 191 for panels converted to the catalog.
source string, with English fallback. Catalogs exist for Japanese (996 rows), Simplified
Chinese (998), Traditional Chinese (951, after #2244 pruned the table), Ukrainian (524),
Brazilian Portuguese (695), Czech (518) and Spanish (513); counted at this tree. Georgian has
the Simplified Chinese catalog's 694 rows, plus 191 for panels converted to the catalog since
(885 in all).
- **Effect names:** `crates/ui-egui/src/i18n/effects.rs`, keyed by **effect id**, in Simplified
Chinese and Georgian (307 rows, one per effect in the registry, plus its 21 categories). The registry's
Chinese (307 rows, one per effect in the registry), Japanese (297 of the 307 ids) and Georgian
(307 rows, plus its 21 categories). The registry's
English name stays the effect's identity: `effect.list`, `effect.apply {"effect": …}`, scripts
and expressions match on it, and the property tree stores it as the effect group's name. Only
the drawing — the Effect menu, Effect Controls, the Timeline and Effects & Presets — goes
through the catalog, so a project file is identical whichever interface language opens it.
A repeat (`Gaussian Blur 2`) keeps the index the engine appends, and a group the user renamed
in Effect Controls stays verbatim. Adding a language there is two tables and one arm, and no
panel changes: Traditional Chinese and Japanese have their tables in place and empty, so those
languages draw English until a translator fills them (the Japanese set for #821 is what that
slot is for). Each language decides for itself which names stay English — Adobe's Japanese
interface leaves the `CC`, `VR` and `OCIO` sets in English while its Chinese one translates
them — so a row repeating the English name is a choice, not a missing row.
panel changes: Traditional Chinese has its table in place and empty, and Japanese fills 297 of
the 307 ids, so the rest draw English until a translator completes them. Each language decides
for itself which names stay English — Adobe's Japanese interface leaves the `CC`, `VR` and
`OCIO` sets in English while its Chinese one translates them — so a row repeating the English
name is a choice, not a missing row.
- **Missing strings:** a string with no row in the interface language shows in English, and no
test, build or release fails on a missing translation. The `missing_translations_report` test
(`crates/ui-egui/src/i18n.rs`) prints, per language, the fixed menu entries, panel strings, effect
@@ -60,25 +63,27 @@ interface; Arabic and Hebrew text *in layers* is supported through its Middle Ea
## Measurement
Measured 10 October 2026 at `origin/main` 1446e27 and recounted on 12 October at `upstream/main`
470ea7a3 by counting catalog rows (`const` tables in `crates/ui-egui/src/i18n.rs` and
`i18n/ui.rs`; menu rows 624 per language, so the share is computed from 624 rather than 618). The
denominator, **≈ 3,900 user-visible strings**, was estimated on 10 October and is kept: 618 fixed menu entries + ≈ 1,320 capitalised UI
literals in `crates/ui-egui/src` outside tests and catalogs (a regex count, so an upper bound) +
≈ 1,650 distinct effect parameter names + 306 effect names. Engine messages are not counted, so
the true percentages are slightly lower.
Measured 10 October 2026 at `origin/main` 1446e27, recounted on 22 October 2026 at `ad8b6acb`,
and recounted again at this tree after #1774 by counting catalog rows (`const` tables in
`crates/ui-egui/src/i18n.rs`, `i18n/ui.rs` and `i18n/effects.rs`: 630 menu rows, 998
panel/dialog sources in Simplified Chinese, 951 in Traditional Chinese and 996 in Japanese). The
denominator, **≈ 4,200 user-visible strings**, is a rounded estimate: the 630 fixed menu entries,
the 998 panel/dialog sources, 307 effect names, ≈ 1,650 distinct effect parameter names and
≈ 620 other unwrapped interface strings (Home screen literals, engine-built tooltips, error and
status messages). It counts distinct strings, not catalog rows; engine messages are only partly
counted, so the true percentages are slightly lower.
| Language | Code | UI strings translated | Dialogs / tooltips / help | Script support | Native review | Status | To `full` |
|---|---|---|---|---|---|---|---|
| English | `en` | ≈ 3,900 (100%, source) | All; docs in English | — | yes | full | — |
| Simplified Chinese | `zh-hans` | 1,324 (≈ 34%): menus 629 rows, panels 695 | Panels and dialogs at the zh source list; no help, effect names translated (307) and their parameter names not; Home screen literals unwrapped (#574, closed) | System CJK fallback; Han follows the UI language; CJK text in comps renders wrongly (#453); IME in text layers | no | partial | 6–9 h + review |
| English | `en` | ≈ 4,200 (100%, source) | All; docs in English | — | yes | full | — |
| Simplified Chinese | `zh-hans` | 1,935 (≈ 46%): menus 630 rows, panels 998, effect names 307 | Panels and dialogs partly; no help, effect names translated and their parameter names not; Home screen literals unwrapped (#574, closed) | System CJK fallback; Han follows the UI language; CJK text in comps renders wrongly (#453); IME in text layers | no | partial | 6–9 h + review |
| Spanish | `es` | 1,142 (≈ 29%): menus 629 rows, panels 513 | Menus only; the panel catalog from #996 | Latin, fine | no | partial | 9–12 h + review |
| Hindi | `hi` | 0 | — | UI: Devanagari fallback font but no shaping; text layers shape Devanagari | no | none (After Effects: none) | 9–13 h + shaping in the UI |
| Arabic | `ar` | 0 | — | UI: Arabic fallback font but no shaping and no RTL layout; text layers: bidi + shaping | no | none (After Effects: none) | 9–13 h + 15–25 h RTL UI |
| French | `fr` | 624 (≈ 16%) | Menus only | Latin, fine | no | menus only | 7–10 h + review |
| Portuguese (Brazil) | `pt-br` | 1,324 (≈ 34%): menus 629 rows, panels 695 | Panels and dialogs at the Chinese catalogs' source list; the six keys main added after that count are translated too; AI-assisted, not yet native-speaker proofread | Latin, fine | no | partial | independent native review |
| Indonesian | `id` | 0 | — | Latin, fine | no | none (After Effects: none) | 8–12 h + review |
| Japanese | `ja` | 1,322 (≈ 34%): menus 629 rows, panels 693 | Panels and dialogs partly | Japanese system fallback; vertical text and Tate-Chu-Yoko in text layers; IME | no | partial | 6–9 h + review |
| Japanese | `ja` | 1,923 (≈ 46%): menus 630 rows, panels 996, effect names 297 | Panels and dialogs partly; no help, effect names translated for 297 of the 307 ids and their parameter names not; Home screen literals unwrapped (#574, closed) | Japanese system fallback; vertical text and Tate-Chu-Yoko in text layers; IME | no | partial | 6–9 h + review |
| German | `de` | 624 (≈ 16%) | Menus only (open PR #666 adds interface translations) | Latin, fine | no | menus only | 7–10 h + review |
| Korean | `ko` | 0 | — | Hangul fallback probe added (#599, closed); not checked on macOS here | no | none | 9–13 h + review |
| Vietnamese | `vi` | 0 | — | Latin with stacked diacritics; untested | no | none (After Effects: none) | 8–12 h + review |
@@ -87,22 +92,22 @@ Other languages EffectCraft ships (4):
| Language | Code | UI strings translated | Status | To `full` |
|---|---|---|---|---|
| Traditional Chinese | `zh-hant` | 1,277 (≈ 33%): menus 629 rows, panels 648 | partial | 6–9 h + review |
| Traditional Chinese | `zh-hant` | 1,581 (≈ 38%): menus 630 rows, panels 951 | partial | 6–9 h + review |
| Ukrainian | `uk` | 1,153 (≈ 29%): menus 629 rows, panels 524 | partial | 6–9 h + review |
| Czech | `cs` | 1,147 (≈ 29%): menus 629 rows, panels 518 | Existing catalog entries covered; unwrapped UI, effects and engine text still in English; AI-assisted, not yet native-speaker proofread | Remaining strings + independent native review |
| Georgian | `ka` | 1,514 (≈ 39%): menus 628 rows, panels 886 (the Chinese catalogs' 695 plus 191 Georgian-only rows: form dialogs, context menus, column headers), effect names 307 + 21 categories; native-speaker reviewed | partial | 5–8 h |
| Georgian | `ka` | 1,514 (≈ 39%): menus 629 rows, panels 885 (the Simplified Chinese catalog's 694 plus 191 Georgian-only rows: form dialogs, context menus, column headers), effect names 307 + 21 categories; native-speaker reviewed | partial | 5–8 h |
Russian (`ru`) has a menu catalog (624 rows, ≈ 16%); After Effects also ships Italian, which EffectCraft does not (8–12 h).
Russian (`ru`) has a menu catalog (630 rows, ≈ 15%); After Effects also ships Italian, which EffectCraft does not (8–12 h).
**Overall: ≈ 21%**, the average coverage of After Effects' 10 non-English languages
(Simplified Chinese, Traditional Chinese, Japanese and Brazilian Portuguese 34%, Spanish 29%,
French, German and Russian 16%, Korean and Italian 0%; 212 / 10, was ≈ 12% on 10 October;
Ukrainian (≈ 29%) and Czech (≈ 29%) are EffectCraft-only and stay out of that average). This is the localization row in
[target-app-parity.md](target-app-parity.md#by-dimension).
**Overall: ≈ 24%**, the average coverage of After Effects' 10 non-English languages
(Simplified Chinese 46%, Traditional Chinese 38%, Japanese 46%, Brazilian Portuguese 34%,
Spanish 29%, French, German and Russian 16%, Korean and Italian 0%; 241 / 10, was ≈ 21% on
22 October; Ukrainian (≈ 29%) and Czech (≈ 29%) are EffectCraft-only and stay out of that
average). This is the localization row in [target-app-parity.md](target-app-parity.md#by-dimension).
**Effort.** One-time work first: route parameter names and engine messages through
a catalog, wrap the remaining panel literals, and add a Hangul probe (10–20 h). Then each language
needs ≈ 2,900 more strings (≈ 5–9 h per language at the pace of #398 and #401). Parity with After
needs ≈ 2,600 more strings (≈ 5–9 h per language at the pace of #398 and #401). Parity with After
Effects' 10 non-English languages: **≈ 60–110 h**; the four extra languages of the standard list
(Hindi, Arabic, Indonesian, Vietnamese) add ≈ 50–80 h, most of it right-to-left layout and
complex shaping in the interface. Every language needs native-speaker review, which only a human
@@ -112,9 +117,11 @@ can give; only Georgian, contributed by a native speaker (#1843), has had it.
| Date | Change | Summary |
|---|---|---|
| 2026-10-30 | minor | Recounted on the merged tree after #1774: Japanese 1,923 (46%, 297 effect names), Simplified Chinese 1,935 (46%, 307 effect names), Traditional Chinese 1,581 (38%, 951 panel rows after #2244's prune); overall ≈ 24% |
| 2026-10-22 | minor | Panel/dialog second step: 300 more catalog rows in Japanese, Simplified Chinese and Traditional Chinese, plus the three rows the review found missing (Basic, Advanced and Play/Stop) — panel tabs, form and dialog labels, panel context menus, the tracker and graph controls, text-panel options, File-panel footers and credits; the panel tables are now 996 Japanese and 998 Simplified Chinese rows, all drawn through `tr`/`tr_args`, with the tests keeping the three catalogs listing the same sources; the 30 October recount above carries the share |
| 2026-10-18 | minor | Brazilian Portuguese completes its panel catalog (278 new rows, 417 → 695, the Chinese catalogs' source list); the doc recount closes the drift the batch merges left in every language's panel count; AI-assisted, not yet native-speaker proofread |
| 2026-10-12 | minor | Recounted: Russian, French, German and Czech menus (#873, #987), Brazilian Portuguese and Czech panels (#830, #987), Hangul probe (#599); overall ≈ 12% to ≈ 18%; Korean and Italian still absent |
| 2026-10-14 | minor | Georgian (`ka`): menus 628, panels 886 (191 Georgian-only, in `GEORGIAN_PANELS`), effect names and categories in `effects.rs` |
| 2026-10-10 | major | First localization parity document: catalog rows counted for all six languages, the twelve-language table, After Effects' 11 shipped languages from its bundle |
| 2026-10-11 | minor | Ukrainian panel catalog brought level with the Chinese ones (495 of 496 rows, counted at this commit); its share rises to ≈ 29%. The other languages' panel counts are the 10 October measurement |
| 2026-10-13 | minor | Effect names and the generated Effect menu leave English: `i18n/effects.rs` adds 306 rows keyed by effect id (Simplified Chinese, from After Effects 2026's interface and Adobe's Chinese documentation for the `CC` series) and the 21 category names. Parameter names are still English; no other language has rows |
| 2026-10-12 | minor | Recounted: Russian, French, German and Czech menus (#873, #987), Brazilian Portuguese and Czech panels (#830, #987), Hangul probe (#599); overall ≈ 12% to ≈ 18%; Korean and Italian still absent |
| 2026-10-11 | minor | Ukrainian panel catalog brought level with the Chinese ones (495 of 496 rows, counted at this commit); its share rises to ≈ 29%. The other languages' panel counts are the 10 October measurement |
| 2026-10-10 | major | First localization parity document: catalog rows counted for all six languages, the twelve-language table, After Effects' 11 shipped languages from its bundle |
+1 -1
View File
@@ -139,7 +139,7 @@ Feature depth (≈ 50%) feeds the overall *ready* number with the other dimensio
| UI/UX fidelity | 65% | 60–120 | After Effects-shaped menus (587 entries), panels, workspaces, shortcuts; many interaction issues still open; multi-monitor only as separate panel windows (#486 open); Effect Controls not yet like 26.5's | [ui-parity.md](ui-parity.md) |
| File formats | 50% | 130–230 | `.aep` / `.aepx` / `.mogrt` / `.ffx` can't be read; strong modern codecs (H.264, HEVC, AV1, VP9, ProRes) | [file-format-parity.md](file-format-parity.md) |
| Hardware | 40% | 60–120 | wgpu GPU on Metal/Vulkan/Direct3D 12/WebGPU with CPU fallback; no hardware decode/encode; Direct3D 12 compositor fails (#613); no video-out hardware | [hardware-parity.md](hardware-parity.md) |
| Localization | 18% | 60–110 + review | Average coverage of After Effects' 10 non-English languages (measured catalog rows over ≈ 3,900 strings): menus in 10 languages, panels in 6, effects in none; After Effects ships 11 languages fully | [localization-parity.md](localization-parity.md) |
| Localization | 24% | 60–110 + review | Average coverage of After Effects' 10 non-English languages (measured catalog rows over ≈ 4,200 strings): menus in 10 languages, panels in 7, effects in Simplified Chinese and Japanese; After Effects ships 11 languages fully | [localization-parity.md](localization-parity.md) |
| Performance | 35% | 50–100 | Internal numbers only; users report stutter and slow scrubbing | [gaps.md](gaps.md#g5-performance-at-real-world-scale) |
| Stability | 45% | 40–80 | Open crash reports #580, #501, #426, #341, #234, #879 (#591, #306 and #511 are closed); no CI runs the tests on pull requests | [gaps.md](gaps.md#g3-stability-and-a-green-main) |
| Platforms | 65% | 30–60 | Releases for macOS, Windows x64/x86/ARM64, Linux, FreeBSD and the web (more than After Effects), but Linux and Windows users hit basic bugs | [gaps.md](gaps.md#g2-real-user-reliability-on-every-platform) |