This commit is contained in:
@@ -12,7 +12,7 @@ interface FolderSelectorProps {
|
||||
}
|
||||
|
||||
const FolderSelector: React.FC<FolderSelectorProps> = ({ folders }) => {
|
||||
const t = useTranslations("memorize/folder-selector");
|
||||
const t = useTranslations("memorize.folder_selector");
|
||||
const router = useRouter();
|
||||
return (
|
||||
<Center>
|
||||
|
||||
@@ -9,7 +9,7 @@ export default function UploadArea({
|
||||
setVideoUrl: (url: string | null) => void;
|
||||
setSrtUrl: (url: string | null) => void;
|
||||
}) {
|
||||
const t = useTranslations("srt-player");
|
||||
const t = useTranslations("srt_player");
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const uploadVideo = () => {
|
||||
|
||||
@@ -11,7 +11,7 @@ type VideoPanelProps = {
|
||||
|
||||
const VideoPanel = forwardRef<HTMLVideoElement, VideoPanelProps>(
|
||||
({ videoUrl, srtUrl }, videoRef) => {
|
||||
const t = useTranslations("srt-player");
|
||||
const t = useTranslations("srt_player");
|
||||
videoRef = videoRef as React.RefObject<HTMLVideoElement>;
|
||||
const [isPlaying, setIsPlaying] = useState<boolean>(false);
|
||||
const [srtLength, setSrtLength] = useState<number>(0);
|
||||
|
||||
@@ -51,7 +51,7 @@ interface SaveListProps {
|
||||
handleUse: (item: z.infer<typeof TextSpeakerItemSchema>) => void;
|
||||
}
|
||||
export default function SaveList({ show = false, handleUse }: SaveListProps) {
|
||||
const t = useTranslations("text-speaker");
|
||||
const t = useTranslations("text_speaker");
|
||||
const { get: getFromLocalStorage, set: setIntoLocalStorage } =
|
||||
getLocalStorageOperator<typeof TextSpeakerArraySchema>(
|
||||
"text-speaker",
|
||||
|
||||
@@ -4,7 +4,10 @@ import LightButton from "@/components/buttons/LightButton";
|
||||
import IconClick from "@/components/IconClick";
|
||||
import IMAGES from "@/config/images";
|
||||
import { useAudioPlayer } from "@/hooks/useAudioPlayer";
|
||||
import { TextSpeakerArraySchema, TextSpeakerItemSchema } from "@/lib/interfaces";
|
||||
import {
|
||||
TextSpeakerArraySchema,
|
||||
TextSpeakerItemSchema,
|
||||
} from "@/lib/interfaces";
|
||||
import { getLocalStorageOperator, getTTSAudioUrl } from "@/lib/utils";
|
||||
import { ChangeEvent, useEffect, useRef, useState } from "react";
|
||||
import z from "zod";
|
||||
@@ -14,7 +17,7 @@ import { VOICES } from "@/config/locales";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
export default function TextSpeakerPage() {
|
||||
const t = useTranslations("text-speaker");
|
||||
const t = useTranslations("text_speaker");
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const [showSpeedAdjust, setShowSpeedAdjust] = useState(false);
|
||||
const [showSaveList, setShowSaveList] = useState(false);
|
||||
@@ -30,9 +33,11 @@ export default function TextSpeakerPage() {
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const { play, stop, load, audioRef } = useAudioPlayer();
|
||||
|
||||
const { get: getFromLocalStorage, set: setIntoLocalStorage } = getLocalStorageOperator<
|
||||
typeof TextSpeakerArraySchema
|
||||
>("text-speaker", TextSpeakerArraySchema);
|
||||
const { get: getFromLocalStorage, set: setIntoLocalStorage } =
|
||||
getLocalStorageOperator<typeof TextSpeakerArraySchema>(
|
||||
"text-speaker",
|
||||
TextSpeakerArraySchema,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const audio = audioRef.current;
|
||||
|
||||
@@ -19,7 +19,7 @@ interface AddToFolderProps {
|
||||
const AddToFolder: React.FC<AddToFolderProps> = ({ item, setShow }) => {
|
||||
const session = useSession();
|
||||
const [folders, setFolders] = useState<folder[]>([]);
|
||||
const t = useTranslations("translator.add-to-folder");
|
||||
const t = useTranslations("translator.add_to_folder");
|
||||
|
||||
useEffect(() => {
|
||||
const username = session.data!.user!.name as string;
|
||||
|
||||
@@ -20,7 +20,7 @@ export default function AddTextPairModal({
|
||||
onClose,
|
||||
onAdd,
|
||||
}: AddTextPairModalProps) {
|
||||
const t = useTranslations("folders.folder_id");
|
||||
const t = useTranslations("folder_id");
|
||||
const input1Ref = useRef<HTMLInputElement>(null);
|
||||
const input2Ref = useRef<HTMLInputElement>(null);
|
||||
const input3Ref = useRef<HTMLInputElement>(null);
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function InFolder({ folderId }: { folderId: number }) {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [openAddModal, setAddModal] = useState(false);
|
||||
const router = useRouter();
|
||||
const t = useTranslations("folders.folder_id");
|
||||
const t = useTranslations("folder_id");
|
||||
|
||||
useEffect(() => {
|
||||
const fetchTextPairs = async () => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { updateTextPairById } from "@/lib/services/textPairService";
|
||||
import { useState } from "react";
|
||||
import { text_pairUpdateInput } from "../../../../generated/prisma/models";
|
||||
import UpdateTextPairModal from "./UpdateTextPairModal";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
interface TextPairCardProps {
|
||||
textPair: TextPair;
|
||||
@@ -17,6 +18,7 @@ export default function TextPairCard({
|
||||
refreshTextPairs,
|
||||
}: TextPairCardProps) {
|
||||
const [openUpdateModal, setOpenUpdateModal] = useState(false);
|
||||
const t = useTranslations("folder_id");
|
||||
return (
|
||||
<div className="group border-b border-gray-100 hover:bg-gray-50 transition-colors">
|
||||
<div className="p-4">
|
||||
@@ -35,11 +37,16 @@ export default function TextPairCard({
|
||||
<button
|
||||
className="p-1.5 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-md transition-colors"
|
||||
onClick={() => setOpenUpdateModal(true)}
|
||||
title={t("edit")}
|
||||
>
|
||||
<Edit size={14} />
|
||||
</button>
|
||||
<button className="p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 rounded-md transition-colors">
|
||||
<Trash2 size={14} onClick={onDel} />
|
||||
<button
|
||||
className="p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 rounded-md transition-colors"
|
||||
onClick={onDel}
|
||||
title={t("delete")}
|
||||
>
|
||||
<Trash2 size={14} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@ export default function UpdateTextPairModal({
|
||||
onUpdate,
|
||||
textPair,
|
||||
}: UpdateTextPairModalProps) {
|
||||
const t = useTranslations("folders.folder_id");
|
||||
const t = useTranslations("folder_id");
|
||||
const input1Ref = useRef<HTMLInputElement>(null);
|
||||
const input2Ref = useRef<HTMLInputElement>(null);
|
||||
const input3Ref = useRef<HTMLInputElement>(null);
|
||||
|
||||
@@ -11,7 +11,7 @@ export default async function FoldersPage({
|
||||
const session = await getServerSession();
|
||||
const { folder_id } = await params;
|
||||
const id = Number(folder_id);
|
||||
const t = await getTranslations("folders.folder_id");
|
||||
const t = await getTranslations("folder_id");
|
||||
|
||||
if (!id) {
|
||||
redirect("/folders");
|
||||
|
||||
@@ -1,39 +1,6 @@
|
||||
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from "@/config/i18n";
|
||||
import { getRequestConfig } from "next-intl/server";
|
||||
import { cookies } from "next/headers";
|
||||
import { readFileSync, readdirSync, statSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function loadMessagesFromDir(dirPath: string): Record<string, any> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const messages: Record<string, any> = {};
|
||||
try {
|
||||
const items = readdirSync(dirPath);
|
||||
|
||||
for (const item of items) {
|
||||
const fullPath = join(dirPath, item);
|
||||
const stat = statSync(fullPath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
const dirMessages = loadMessagesFromDir(fullPath);
|
||||
Object.assign(messages, { [item]: dirMessages });
|
||||
} else if (item.endsWith(".json")) {
|
||||
try {
|
||||
const content = readFileSync(fullPath, "utf-8");
|
||||
const jsonContent = JSON.parse(content);
|
||||
Object.assign(messages, { [item.replace(".json", "")]: jsonContent });
|
||||
} catch (error) {
|
||||
console.warn(`Failed to load JSON file ${fullPath}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`Failed to read directory ${dirPath}:`, error);
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
export default getRequestConfig(async () => {
|
||||
const store = await cookies();
|
||||
@@ -43,11 +10,8 @@ export default getRequestConfig(async () => {
|
||||
return locale;
|
||||
})();
|
||||
|
||||
const messagesPath = join(process.cwd(), "public/messages", locale);
|
||||
const messages = loadMessagesFromDir(messagesPath);
|
||||
|
||||
return {
|
||||
locale,
|
||||
messages,
|
||||
messages: (await import(`../../messages/${locale}.json`)).default,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user