Skip to content

Commit

Permalink
i18n: Translate avm2 page
Browse files Browse the repository at this point in the history
  • Loading branch information
danielhjacobs committed Nov 15, 2024
1 parent 1ab4da2 commit 6c03b92
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 101 deletions.
17 changes: 12 additions & 5 deletions src/app/compatibility/avm2/class_box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import classes from "./avm2.module.css";
import React from "react";
import {
ClassStatus,
ProgressIcon,
displayedPercentage,
} from "@/app/compatibility/avm2/report_utils";
import { ProgressIcon } from "@/app/compatibility/avm2/icons";
import { useTranslation } from "@/app/translate";

export function ClassBox(props: ClassStatus) {
const { t } = useTranslation();
const [opened, { toggle }] = useDisclosure(false);
const pctDone = displayedPercentage(
props.summary.impl_points - props.summary.stub_penalty,
Expand All @@ -33,21 +35,23 @@ export function ClassBox(props: ClassStatus) {
);
return (
<Card bg="var(--ruffle-blue-9)" className={classes.class}>
<Title order={4}>{props.name || "(Package level)"}</Title>
<Title order={4}>
{props.name || t("compatibility.avm2.package-level")}
</Title>
<ProgressRoot size="xl" radius={10} className={classes.progress}>
<ProgressSection
striped
value={pctDone}
color="var(--mantine-color-green-9)"
title={`${pctDone}% done`}
title={`${pctDone}% ${t("compatibility.done")}`}
></ProgressSection>
{pctStub > 0 && (
<ProgressSection
striped
value={pctStub}
color="ruffle-orange"
className={classes.progressStub}
title={`${pctStub}% partially done`}
title={`${pctStub}% ${t("compatibility.partial")}`}
></ProgressSection>
)}
</ProgressRoot>
Expand All @@ -58,7 +62,10 @@ export function ClassBox(props: ClassStatus) {
className={classes.showMemberButton}
onClick={toggle}
>
{opened ? "Hide" : "Show"} Missing Members
{opened
? t("compatibility.avm2.hide")
: t("compatibility.avm2.show")}{" "}
{t("compatibility.avm2.missing-members")}
</Button>
<List hidden={!opened}>
{props.items.map((item, i) => (
Expand Down
65 changes: 65 additions & 0 deletions src/app/compatibility/avm2/icons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"use client";

import { rem, ThemeIcon } from "@mantine/core";
import { IconCheck, IconProgress, IconX } from "@tabler/icons-react";
import { useTranslation } from "@/app/translate";

export function IconDone() {
const { t } = useTranslation();
return (
<ThemeIcon
size={20}
radius="xl"
color="var(--mantine-color-green-9)"
title={t("compatibility.avm2.done")}
>
<IconCheck
color="white"
style={{ width: rem(12), height: rem(12) }}
stroke={4}
/>
</ThemeIcon>
);
}

export function IconStub() {
const { t } = useTranslation();
return (
<ThemeIcon size={20} radius="xl" title={t("compatibility.avm2.partial")}>
<IconProgress
color="#3c1518"
style={{ width: rem(12), height: rem(12) }}
stroke={4}
/>
</ThemeIcon>
);
}

export function IconMissing() {
const { t } = useTranslation();
return (
<ThemeIcon
size={20}
radius="xl"
color="#3c1518"
title={t("compatibility.avm2.missing")}
>
<IconX
color="white"
style={{ width: rem(12), height: rem(12) }}
stroke={4}
/>
</ThemeIcon>
);
}

export function ProgressIcon(type: "stub" | "missing" | "done") {
switch (type) {
case "stub":
return <IconStub />;
case "missing":
return <IconMissing />;
case "done":
return <IconDone />;
}
}
97 changes: 63 additions & 34 deletions src/app/compatibility/avm2/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import {
Container,
Group,
Expand All @@ -8,22 +10,26 @@ import {
Title,
} from "@mantine/core";
import Image from "next/image";
import React from "react";
import React, { useEffect, useState } from "react";
import classes from "./avm2.module.css";
import { ClassBox } from "@/app/compatibility/avm2/class_box";
import {
getReportByNamespace,
NamespaceStatus,
} from "@/app/compatibility/avm2/report_utils";
import {
IconDone,
IconMissing,
IconStub,
NamespaceStatus,
} from "@/app/compatibility/avm2/report_utils";
} from "@/app/compatibility/avm2/icons";
import Link from "next/link";
import { useTranslation, Trans } from "@/app/translate";

function NamespaceBox(props: NamespaceStatus) {
const { t } = useTranslation();
return (
<Stack className={classes.namespace}>
<Title order={2}>{props.name || "(Top Level)"}</Title>
<Title order={2}>{props.name || t("compatibility.avm2.top-level")}</Title>
<Group align="baseline">
{Object.entries(props.classes).map(([classname, classinfo]) => (
<ClassBox key={classname} {...classinfo} />
Expand All @@ -33,8 +39,22 @@ function NamespaceBox(props: NamespaceStatus) {
);
}

export default async function Page() {
const byNamespace = await getReportByNamespace();
export default function Page() {
const { t } = useTranslation();
const [byNamespace, setByNamespace] = useState<
{ [name: string]: NamespaceStatus } | undefined
>(undefined);
useEffect(() => {
const fetchData = async () => {
try {
const byNamespace = await getReportByNamespace();
setByNamespace(byNamespace);
} catch (error) {
console.error("Error fetching data", error);
}
};
fetchData();
}, []);
return (
<Container size="xl">
<Stack gap="xl">
Expand All @@ -48,43 +68,52 @@ export default async function Page() {
className={classes.progressImage}
/>
<Stack className={classes.actionscriptInfo}>
<Title className={classes.title}>ActionScript 3 API Progress</Title>
<Text>
ActionScript 3 contains many different methods and classes - not
all of which is ultimately <i>useful</i> to every application. The
majority of content only uses a small portion of the available
API, so even if we aren&apos;t 100% &quot;complete&quot; across
the entirely of AVM 2, we may have enough for that content to run
completely fine.
</Text>
<Text>
On this page, we list every single ActionScript 3 API that exists
but Ruffle does not yet 100% implement. We classify items into
three different stages:
</Text>
<Title className={classes.title}>
{t("compatibility.avm2.title")}
</Title>
<Text>{t("compatibility.avm2.description")}</Text>
<Text>{t("compatibility.avm2.classification")}</Text>
<List spacing="sm">
<ListItem icon={<IconDone />}>
<b>Implemented</b> items are marked as &quot;Done&quot;, and we
believe they are fully functional. For brevity, we do not list
completed items on this page.
<Trans
i18nKey="compatibility.avm2.implemented-description"
components={[
<b key="implemented">
{t("compatibility.avm2.implemented")}
</b>,
]}
/>
</ListItem>
<ListItem icon={<IconStub />}>
<b>Partial</b> items exist and are enough for most content to
work, but are incomplete. A partial class may be missing items,
or a method may just simply return a value without performing
its intended function.
<Trans
i18nKey="compatibility.avm2.partial-description"
components={[
<b key="partial">{t("compatibility.avm2.partial")}</b>,
]}
/>
</ListItem>
<ListItem icon={<IconMissing />}>
<b>Missing</b> items do not exist at all in Ruffle yet, and
trying to use them will give an error.
<Trans
i18nKey="compatibility.avm2.missing-description"
components={[
<b key="missing">{t("compatibility.avm2.missing")}</b>,
]}
/>
</ListItem>
</List>
<Text>
You can also visualize the progress{" "}
<Link href="/compatibility/avm2/tree.svg" target="_blank">
as a tree graph
</Link>
.
<Trans
i18nKey="compatibility.avm2.tree"
components={[
<Link
key="link"
href="/compatibility/avm2/tree.svg"
target="_blank"
>
{t("compatibility.avm2.tree-link")}
</Link>,
]}
/>
</Text>
</Stack>
</Group>
Expand Down
60 changes: 3 additions & 57 deletions src/app/compatibility/avm2/report_utils.tsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,4 @@
import { rem, ThemeIcon } from "@mantine/core";
import { IconCheck, IconProgress, IconX } from "@tabler/icons-react";
import { fetchReport } from "@/app/downloads/github";
import React from "react";

export function IconDone() {
return (
<ThemeIcon
size={20}
radius="xl"
color="var(--mantine-color-green-9)"
title="Done"
>
<IconCheck
color="white"
style={{ width: rem(12), height: rem(12) }}
stroke={4}
/>
</ThemeIcon>
);
}

export function IconStub() {
return (
<ThemeIcon size={20} radius="xl" title="Partial">
<IconProgress
color="#3c1518"
style={{ width: rem(12), height: rem(12) }}
stroke={4}
/>
</ThemeIcon>
);
}

export function IconMissing() {
return (
<ThemeIcon size={20} radius="xl" color="#3c1518" title="Missing">
<IconX
color="white"
style={{ width: rem(12), height: rem(12) }}
stroke={4}
/>
</ThemeIcon>
);
}

export function ProgressIcon(type: "stub" | "missing" | "done") {
switch (type) {
case "stub":
return <IconStub />;
case "missing":
return <IconMissing />;
case "done":
return <IconDone />;
}
}
import type { AVM2Report } from "@/app/downloads/config";

export interface SummaryStatistics {
max_points: number;
Expand Down Expand Up @@ -82,7 +27,8 @@ export async function getReportByNamespace(): Promise<
{ [name: string]: NamespaceStatus } | undefined
> {
let byNamespace: { [name: string]: NamespaceStatus } = {};
const report = await fetchReport();
const reportReq = await fetch("/compatibility/fetch-report");
const report: AVM2Report = await reportReq.json();
if (!report) {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/compatibility/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export default function Downloads() {
className={classes.avms}
>
<AvmBlock
name="compatibility.avm1"
name="compatibility.avm1-title"
language={{ done: 95 }}
api={{ done: avm1ApiDone }}
info_link_target="_blank"
Expand All @@ -119,7 +119,7 @@ export default function Downloads() {
</AvmBlock>

<AvmBlock
name="compatibility.avm2"
name="compatibility.avm2-title"
language={{ done: 90 }}
api={{ done: avm2ApiDone, stubbed: avm2ApiStubbed }}
info_link="/compatibility/avm2"
Expand Down
25 changes: 22 additions & 3 deletions src/i18n/translations.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,35 @@
"language": "Language",
"api-description": "The {{api}} is the underlying virtual machine itself and the language concepts that it understands, like variables and classes and how they all interact together.",
"api": "API",
"avm1": "AVM 1: ActionScript 1 & 2",
"avm1-title": "AVM 1: ActionScript 1 & 2",
"avm1-description": "AVM 1 is the original ActionScript Virtual Machine. All movies made before Flash Player 9 (June 2006) will be made with AVM 1, and it remained supported & available to authors until the release of Flash Professional CC (2013), after which point content started moving to AVM 2.",
"avm1-support": "We believe that most AVM 1 content will work, but we are aware of some graphical inaccuracies and smaller bugs here and there. Please feel free to report any issues you find that are not present in the original Flash Player!",
"avm2": "AVM 2: ActionScript 3",
"avm2-title": "AVM 2: ActionScript 3",
"avm2-description": "AVM 2 was introduced with Flash Player 9 (June 2006), to replace the earlier AVM 1. After the release of Flash Professional CC (2013), authors are required to use ActionScript 3 - making any movie made after that date very likely to fall under this category.",
"avm2-support": "Ruffle now has decent support for AVM 2, and it's our experience that most games will work well enough to be played. We're still rapidly improving in this area though, so bug reports about any broken content are always welcome!",
"weekly-contributions": "Weekly Contributions",
"done": "done",
"partial": "partially done",
"more": "More Info",
"commits-description": "{{commitNumber}} commits on the week of {{week}}"
"commits-description": "{{commitNumber}} commits on the week of {{week}}",
"avm2": {
"title": "ActionScript 3 API Progress",
"description": "ActionScript 3 contains many different methods and classes - not all of which is ultimately useful to every application. The majority of content only uses a small portion of the available API, so even if we aren't 100% \"complete\" across the entirely of AVM 2, we may have enough for that content to run completely fine.",
"classification": "On this page, we list every single ActionScript 3 API that exists but Ruffle does not yet 100% implement. We classify items into three different stages:",
"implemented": "Implemented",
"implemented-description": "{{implemented}} items are marked as \"Done\", and we believe they are fully functional. For brevity, we do not list completed items on this page.",
"partial": "Partial",
"partial-description": "{{partial}} items exist and are enough for most content to work, but are incomplete. A partial class may be missing items, or a method may just simply return a value without performing its intended function.",
"missing": "Missing",
"missing-description": "{{missing}} items do not exist at all in Ruffle yet, and trying to use them will give an error.",
"tree": "You can also visualize the progress {{link}}.",
"tree-link": "as a tree graph",
"top-level": "(Top Level)",
"package-level": "(Package Level)",
"hide": "Hide",
"show": "Show",
"missing-members": "Missing Members",
"done": "Done"
}
}
}

0 comments on commit 6c03b92

Please sign in to comment.