拆分解耦

This commit is contained in:
2025-09-18 16:18:12 +08:00
parent dc0ffce3c0
commit 2edd0b05d1
9 changed files with 39 additions and 36 deletions

View File

@@ -1,5 +1,5 @@
import { useRef, useState } from "react";
import Button from "./Button";
import Button from "../../../components/Button";
export default function UploadArea(
{

View File

@@ -1,14 +1,7 @@
import inspect from "@/utilities";
export default function SubtitleDisplay({ subtitle }: { subtitle: string }) {
const words = subtitle.match(/\b[\w']+(?:-[\w']+)*\b/g) || [];
const goto = (url: string) => {
window.open(url, '_blank');
}
const inspect = (word: string) => {
return () => {
word = word.toLowerCase();
goto(`https://www.youdao.com/result?word=${word}&lang=en`);
}
}
let i = 0;
return (
<div className="subtitle overflow-y-auto h-16 mt-2 break-words bg-black/50 font-sans text-white text-center text-2xl">

View File

@@ -1,5 +1,5 @@
import { useState, useRef, forwardRef, useEffect, KeyboardEvent, useCallback } from "react";
import Button from "../Button";
import Button from "../../../../components/Button";
import { getIndex, getNearistIndex, parseSrt } from "../../subtitle";
import SubtitleDisplay from "./SubtitleDisplay";

View File

@@ -1,7 +0,0 @@
export default function Button({ label, onClick }: { label: string, onClick?: () => void }) {
return (
<button onClick={onClick} className="m-1 px-2 py-1 rounded bg-white shadow-2xs font-bold hover:bg-gray-300">
{label}
</button>
);
}

View File

@@ -1,14 +1,29 @@
'use client';
import Word from "@/interfaces/Word";
import inspect from "@/utilities";
import { Dispatch, SetStateAction } from "react";
function DraggableWord({ word }: { word: Word }) {
return ((<span
style={{
left: `${Math.floor(word.x * (1000 - 18 * word.word.length))}px`,
top: `${Math.floor(word.y * (600 - 30))}px`,
}}
className={`select-none cursor-pointer absolute font-mono text-[30px] border-amber-100 border-1`}
onClick={inspect(word.word)}>{word.word}</span>))
}
export default function WordBoard(
{ words }: {
{ words, setWords }: {
words: [
{
word: string,
x: number,
y: number
}
]
],
setWords: Dispatch<SetStateAction<Word[]>>
}
) {
const inspect = (word: string) => {
@@ -28,14 +43,7 @@ export default function WordBoard(
x: number,
y: number
}, i: number) => {
return (<span
style={{
left: `${Math.floor(v.x * (1000 - 18 * v.word.length))}px`,
top: `${Math.floor(v.y * (600 - 30))}px`,
}}
className={`select-none cursor-pointer absolute font-mono text-[30px] border-amber-100 border-1`}
key={i}
onClick={inspect(v.word)}>{v.word}</span>)
return (<DraggableWord word={v} key={i}></DraggableWord>)
})}
</div>
)

View File

@@ -1,13 +1,8 @@
'use client';
import WordBoard from "@/app/word-board/WordBoard";
import Button from "./Button";
import Button from "../../components/Button";
import { useRef, useState } from "react";
interface Word {
word: string,
x: number,
y: number
}
import Word from "@/interfaces/Word";
export default function Home() {
const inputRef = useRef<HTMLInputElement>(null);
@@ -79,7 +74,7 @@ export default function Home() {
}
return (
<div className="p-5 my-10 mx-auto bg-gray-200 rounded shadow-2xl w-[1050px]">
<WordBoard words={words as [Word]} />
<WordBoard words={words as [Word]} setWords={setWords} />
<div className="flex justify-center rounded mt-3 w-[1000px]">
<input ref={inputRef} placeholder="在此插入/删除单词" type="text" className="focus:outline-none border-b-2 border-black" />
<Button label="插入" onClick={insertWord}></Button>

5
src/interfaces/Word.ts Normal file
View File

@@ -0,0 +1,5 @@
export default interface Word {
word: string,
x: number,
y: number
}

9
src/utilities.ts Normal file
View File

@@ -0,0 +1,9 @@
export default function inspect(word: string) {
const goto = (url: string) => {
window.open(url, '_blank');
}
return () => {
word = word.toLowerCase();
goto(`https://www.youdao.com/result?word=${word}&lang=en`);
}
}