Skip to content

Commit ef986a1

Browse files
committed
i18n: Translate logo by rewriting it to a modern functional component
1 parent 1da5a09 commit ef986a1

File tree

2 files changed

+47
-64
lines changed

2 files changed

+47
-64
lines changed

src/components/logo.tsx

+44-64
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"use client";
22

3-
import React from "react";
3+
import React, { useEffect, useRef, useState } from "react";
44
import Image from "next/image";
55
import Script from "next/script";
66
import classes from "../app/index.module.css";
7+
import { t } from "@/app/translate";
78

89
declare global {
910
interface Window {
@@ -27,44 +28,28 @@ interface LogoProps {
2728
className?: string;
2829
}
2930

30-
interface LogoState {
31-
player: RufflePlayer | null;
32-
}
33-
34-
export default class InteractiveLogo extends React.Component<
35-
LogoProps,
36-
LogoState
37-
> {
38-
private readonly container: React.RefObject<HTMLDivElement>;
39-
private player: RufflePlayer | null = null;
31+
export default function InteractiveLogo({ className }: LogoProps) {
32+
const container = useRef<HTMLDivElement>(null);
33+
const [player, setPlayer] = useState<RufflePlayer | null>(null);
4034

41-
constructor(props: LogoProps) {
42-
super(props);
43-
44-
this.container = React.createRef();
45-
this.state = {
46-
player: null,
47-
};
48-
}
35+
const removeRufflePlayer = () => {
36+
player?.remove();
37+
setPlayer(null);
38+
};
4939

50-
private removeRufflePlayer() {
51-
this.player?.remove();
52-
this.player = null;
53-
this.setState({ player: null });
54-
}
55-
56-
private load() {
57-
if (this.player) {
58-
// Already loaded.
40+
const loadPlayer = () => {
41+
if (player) {
5942
return;
6043
}
6144

62-
this.player = (window.RufflePlayer as PublicAPI)?.newest()?.createPlayer();
45+
const rufflePlayer = (window.RufflePlayer as PublicAPI)
46+
?.newest()
47+
?.createPlayer();
6348

64-
if (this.player) {
65-
this.container.current!.appendChild(this.player);
49+
if (rufflePlayer) {
50+
container.current!.appendChild(rufflePlayer);
6651

67-
this.player
52+
rufflePlayer
6853
.load({
6954
url: "/logo-anim.swf",
7055
autoplay: "on",
@@ -75,39 +60,34 @@ export default class InteractiveLogo extends React.Component<
7560
preferredRenderer: "canvas",
7661
})
7762
.catch(() => {
78-
this.removeRufflePlayer();
63+
removeRufflePlayer();
7964
});
80-
this.player.style.width = "100%";
81-
this.player.style.height = "100%";
82-
this.setState({ player: this.player });
65+
rufflePlayer.style.width = "100%";
66+
rufflePlayer.style.height = "100%";
67+
setPlayer(rufflePlayer);
8368
}
84-
}
85-
86-
componentDidMount() {
87-
this.load();
88-
}
89-
90-
componentWillUnmount() {
91-
this.removeRufflePlayer();
92-
}
93-
94-
render() {
95-
return (
96-
<>
97-
<Script
98-
src="https://unpkg.com/@ruffle-rs/ruffle"
99-
onReady={() => this.load()}
69+
};
70+
71+
useEffect(() => {
72+
loadPlayer();
73+
return () => removeRufflePlayer();
74+
}, []);
75+
76+
return (
77+
<>
78+
<Script
79+
src="https://unpkg.com/@ruffle-rs/ruffle"
80+
onReady={() => loadPlayer()}
81+
/>
82+
<div ref={container} className={className}>
83+
<Image
84+
src="/logo.svg"
85+
alt={t("logo.alt-tag")}
86+
className={player ? classes.hidden : classes.staticLogo}
87+
width="340"
88+
height="110"
10089
/>
101-
<div ref={this.container} className={this.props.className}>
102-
<Image
103-
src="/logo.svg"
104-
alt="Ruffle Logo"
105-
className={this.state.player ? classes.hidden : classes.staticLogo}
106-
width="340"
107-
height="110"
108-
/>
109-
</div>
110-
</>
111-
);
112-
}
90+
</div>
91+
</>
92+
);
11393
}

src/i18n/translations.en.json

+3
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,8 @@
2727
"mastodon": "Mastodon",
2828
"discord": "Discord",
2929
"tagline": "Putting Flash back on the web"
30+
},
31+
"logo": {
32+
"alt-tag": "Ruffle Logo"
3033
}
3134
}

0 commit comments

Comments
 (0)