解决多语言切换的bug
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"Index": {
|
||||
"Header": {
|
||||
"appName": "Fast3DText",
|
||||
"editorName": "Editor"
|
||||
},
|
||||
"HomePage": {
|
||||
"heroTitle": "Create Stunning 3D Text Designs",
|
||||
"heroSubtitle": "Generate and customize beautiful 3D text effects for your projects",
|
||||
"toolTitle": "3D Text Generator Tool",
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"Index": {
|
||||
"Header": {
|
||||
"appName": "Fast3DText",
|
||||
"editorName": "编辑器"
|
||||
},
|
||||
"HomePage": {
|
||||
"heroTitle": "创建惊艳的3D文字设计",
|
||||
"heroSubtitle": "为您的项目生成并定制精美的3D文字效果",
|
||||
"toolTitle": "3D文字生成工具",
|
||||
|
||||
@@ -7,17 +7,10 @@ import { Metadata } from "next";
|
||||
import Editor from "@/components/SimpleEditor";
|
||||
import { FontNames, FontWeights, TextProp } from "@/components/common/TextSetting";
|
||||
|
||||
export default function Page({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = use(params);
|
||||
// Enable static rendering
|
||||
setRequestLocale(locale);
|
||||
export default function Page() {
|
||||
|
||||
const t = useTranslations("DoNotWriteOnThisPage");
|
||||
const indexT = useTranslations("Index");
|
||||
const indexT = useTranslations("HomePage");
|
||||
|
||||
const text = TextProp.default("Do Not Write On This Page");
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@ import Footer from "@/components/Footer";
|
||||
import FullEditor from "@/components/FullEditor";
|
||||
import Header from "@/components/Header";
|
||||
import { Locales } from "@/i18n/config";
|
||||
import { Box, Flex } from "@radix-ui/themes";
|
||||
import { Flex } from "@radix-ui/themes";
|
||||
import { Metadata } from "next";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { getTranslations, setRequestLocale } from "next-intl/server";
|
||||
import { use } from "react";
|
||||
const host = process.env.NEXT_PUBLIC_HOST;
|
||||
export default function Page() {
|
||||
|
||||
|
||||
@@ -8,16 +8,9 @@ import { Locales } from "@/i18n/config";
|
||||
import { Metadata } from "next";
|
||||
import { Box, Flex, Heading, Section, Text } from "@radix-ui/themes";
|
||||
const host = process.env.NEXT_PUBLIC_HOST;
|
||||
export default function HomePage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = use(params);
|
||||
// Enable static rendering
|
||||
setRequestLocale(locale);
|
||||
export default function HomePage() {
|
||||
|
||||
const t = useTranslations("Index");
|
||||
const t = useTranslations("HomePage");
|
||||
|
||||
return (
|
||||
<div className="flex flex-col min-h-screen overflow-hidden">
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
'use client'
|
||||
import { useTranslations } from "next-intl";
|
||||
import LanguageSwitcher from "./LanguageSwitcher";
|
||||
import { ModeToggle } from "./ModeToggle";
|
||||
import { Box, Flex, Link, Strong, Text } from "@radix-ui/themes";
|
||||
import { useRouter } from "@/i18n/navigation";
|
||||
|
||||
export default function Header() {
|
||||
const t = useTranslations("Index");
|
||||
|
||||
const t = useTranslations("Header");
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<header className="w-full py-2 border-b-1 ">
|
||||
<Flex justify="center" gap="9" align="center">
|
||||
@@ -16,9 +22,9 @@ export default function Header() {
|
||||
|
||||
<Flex gap={"4"} justify={"center"} align={"center"} className="w-1/2">
|
||||
<Link
|
||||
href="/editor"
|
||||
onClick={() => { router.push("/editor") }}
|
||||
>
|
||||
Editor
|
||||
{t("editorName")}
|
||||
</Link>
|
||||
</Flex>
|
||||
|
||||
|
||||
@@ -1,44 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
'use client';
|
||||
import { usePathname, useRouter } from "@/i18n/navigation";
|
||||
import { Locales } from "@/i18n/config";
|
||||
import { Button, DropdownMenu } from "@radix-ui/themes";
|
||||
import { useLocale } from "next-intl";
|
||||
|
||||
const LanguageSwitcher = () => {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const [currentLanguage, setCurrentLanguage] = useState("en");
|
||||
const locale = useLocale();
|
||||
|
||||
useEffect(() => {
|
||||
const savedLanguage =
|
||||
document.cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("NEXT_LOCALE="))
|
||||
?.split("=")[1] || "en";
|
||||
setCurrentLanguage(savedLanguage);
|
||||
|
||||
const urlLanguage = pathname.split("/")[1];
|
||||
if (Locales.includes(urlLanguage)) {
|
||||
setCurrentLanguage(urlLanguage);
|
||||
}
|
||||
}, [pathname]);
|
||||
|
||||
const changeLanguage = (newLanguage: string) => {
|
||||
setCurrentLanguage(newLanguage);
|
||||
document.cookie = `NEXT_LOCALE=${newLanguage}; path=/;`;
|
||||
|
||||
const segments = pathname.split("/");
|
||||
if (Locales.includes(segments[1])) {
|
||||
segments[1] = newLanguage;
|
||||
} else {
|
||||
segments.splice(1, 0, newLanguage);
|
||||
}
|
||||
|
||||
router.push(segments.join("/"));
|
||||
router.refresh();
|
||||
};
|
||||
|
||||
const languageLabels = {
|
||||
en: "English",
|
||||
@@ -48,21 +16,26 @@ const LanguageSwitcher = () => {
|
||||
// jp: "日本語",
|
||||
};
|
||||
|
||||
const router = useRouter();
|
||||
const labels = [];
|
||||
for (let l in languageLabels) {
|
||||
const key = l as keyof typeof languageLabels;
|
||||
labels.push(
|
||||
<DropdownMenu.Item key={l} onClick={() => changeLanguage(l)}>
|
||||
<DropdownMenu.Item key={l} onClick={() => {
|
||||
if (l !== locale) {
|
||||
router.push(pathname, { locale: l });
|
||||
}
|
||||
}}>
|
||||
{languageLabels[key]}
|
||||
</DropdownMenu.Item>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<DropdownMenu.Root dir={currentLanguage === "ar" ? "rtl" : "ltr"}>
|
||||
<DropdownMenu.Root dir={locale === "ar" ? "rtl" : "ltr"}>
|
||||
<DropdownMenu.Trigger >
|
||||
<Button variant="outline" size={"2"}>
|
||||
{languageLabels[currentLanguage as keyof typeof languageLabels]}
|
||||
{languageLabels[locale as keyof typeof languageLabels]}
|
||||
</Button>
|
||||
</DropdownMenu.Trigger>
|
||||
<DropdownMenu.Content align="end">
|
||||
|
||||
@@ -5,9 +5,10 @@ import BackgroundSelector, {
|
||||
} from "./common/BackgroundSelector";
|
||||
import PreviewToolbar from "./common/PreviewToolbar";
|
||||
import SimpleTextSetting from "./common/SimpleTextSetting";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TextProp } from "./common/TextSetting";
|
||||
import { useRouter } from "@/i18n/navigation";
|
||||
|
||||
/**
|
||||
* 简易工具
|
||||
@@ -16,7 +17,9 @@ import { TextProp } from "./common/TextSetting";
|
||||
export default function Page({ textProp, backgroundProp }: { textProp: TextProp | undefined, backgroundProp: BackgroundProp | undefined }) {
|
||||
|
||||
const t = useTranslations("TextEditor");
|
||||
const tIndex = useTranslations("Index");
|
||||
const tIndex = useTranslations("HomePage");
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const [background, setBackground] = useState<BackgroundProp>(backgroundProp || {
|
||||
type: "color",
|
||||
@@ -26,6 +29,34 @@ export default function Page({ textProp, backgroundProp }: { textProp: TextProp
|
||||
|
||||
const [text, setText] = useState<TextProp>(textProp || TextProp.default(t("defaultText")));
|
||||
|
||||
useEffect(() => {
|
||||
let bg = sessionStorage.getItem("background");
|
||||
|
||||
if (bg) {
|
||||
console.log("初始化设置 bg", bg);
|
||||
|
||||
setBackground(JSON.parse(bg));
|
||||
}
|
||||
|
||||
let txt = sessionStorage.getItem("text");
|
||||
|
||||
if (txt) {
|
||||
console.log("初始化设置 txt", txt);
|
||||
|
||||
setText(JSON.parse(txt));
|
||||
}
|
||||
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
sessionStorage.setItem("background", JSON.stringify(background));
|
||||
}, [background]);
|
||||
|
||||
useEffect(() => {
|
||||
sessionStorage.setItem("text", JSON.stringify(text));
|
||||
|
||||
}, [text]);
|
||||
|
||||
return (
|
||||
<Flex gap={"2"}>
|
||||
<Flex gap={"2"} direction={"column"} className="w-1/3">
|
||||
@@ -39,7 +70,7 @@ export default function Page({ textProp, backgroundProp }: { textProp: TextProp
|
||||
<Flex className="w-2/3" direction={"column"} justify={"between"}>
|
||||
<PreviewToolbar background={background} text={text} />
|
||||
|
||||
<Box className="text-center"> <Link href="./editor">{tIndex("toolMore")}?</Link> </Box>
|
||||
<Box className="text-center"> <Link onClick={() => { router.push("/editor") }}>{tIndex("toolMore")}?</Link> </Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -47,8 +47,8 @@ export default function PreviewToolbar({
|
||||
} else {
|
||||
const box = container.current;
|
||||
const split = Sizes[aspectRadio].split("x").map(Number);
|
||||
threeInit(box, split[0], split[1]);
|
||||
console.log("three init");
|
||||
const initSuccess = threeInit(box, split[0], split[1]);
|
||||
console.log("three init ", initSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,13 +59,26 @@ export default function PreviewToolbar({
|
||||
useEffect(updateSize, [aspectRadio]);
|
||||
|
||||
useEffect(() => {
|
||||
updateBackground(background);
|
||||
console.log("background init");
|
||||
|
||||
const timeoutId = setTimeout(() => {
|
||||
updateBackground(background);
|
||||
|
||||
console.log("background change", background);
|
||||
}, 200);
|
||||
|
||||
return () => clearTimeout(timeoutId);
|
||||
|
||||
}, [background]);
|
||||
|
||||
useEffect(() => {
|
||||
updateTextProps(text);
|
||||
console.log("text init");
|
||||
|
||||
const timeoutId = setTimeout(() => {
|
||||
updateTextProps(text);
|
||||
|
||||
console.log("text change", text);
|
||||
}, 1000);
|
||||
|
||||
return () => clearTimeout(timeoutId);
|
||||
}, [text]);
|
||||
|
||||
const handleDownload = () => {
|
||||
|
||||
@@ -13,11 +13,20 @@ let camera: THREE.PerspectiveCamera,
|
||||
controls: OrbitControls,
|
||||
container: HTMLCanvasElement;
|
||||
|
||||
console.log("three tool loaded");
|
||||
|
||||
let inited = false;
|
||||
|
||||
export function init(
|
||||
_container: HTMLCanvasElement,
|
||||
width: number,
|
||||
height: number
|
||||
) {
|
||||
// if (inited) {
|
||||
// renderer.dispose();
|
||||
// }
|
||||
|
||||
inited = true;
|
||||
container = _container;
|
||||
scene = new THREE.Scene();
|
||||
|
||||
@@ -156,6 +165,7 @@ export async function updateTextProps(textProps: TextProp) {
|
||||
(textMesh.material as THREE.MeshLambertMaterial).color.set(textProps.color);
|
||||
}
|
||||
|
||||
scene.add(textMesh);
|
||||
lastTextProps = textProps;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ export const routing = defineRouting({
|
||||
|
||||
// Used when no locale matches
|
||||
defaultLocale: "en",
|
||||
localeDetection: true,
|
||||
localeDetection: false,
|
||||
//to remove the locale prefix from the url
|
||||
localePrefix: "never",
|
||||
localePrefix: "as-needed",
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user