Files
kiss-translator/src/views/Options/FavWords.js

156 lines
4.4 KiB
JavaScript
Raw Normal View History

2023-10-26 17:32:55 +08:00
import Stack from "@mui/material/Stack";
2024-04-15 18:04:35 +08:00
import { useState } from "react";
2023-10-26 17:32:55 +08:00
import Typography from "@mui/material/Typography";
import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
2023-10-26 17:59:49 +08:00
import { useI18n } from "../../hooks/I18n";
2023-10-26 17:32:55 +08:00
import Box from "@mui/material/Box";
import { useFavWords } from "../../hooks/FavWords";
2023-10-26 23:55:05 +08:00
import DictCont from "../Selection/DictCont";
2024-04-15 18:04:35 +08:00
import SugCont from "../Selection/SugCont";
2023-10-26 23:55:05 +08:00
import DownloadButton from "./DownloadButton";
import UploadButton from "./UploadButton";
import Button from "@mui/material/Button";
import ClearAllIcon from "@mui/icons-material/ClearAll";
2025-09-26 20:56:52 +08:00
import Alert from "@mui/material/Alert";
2023-10-26 23:55:05 +08:00
import { isValidWord } from "../../libs/utils";
2024-03-19 18:07:18 +08:00
import { kissLog } from "../../libs/log";
2025-10-01 12:30:58 +08:00
import { useConfirm } from "../../hooks/Confirm";
2025-10-03 18:28:50 +08:00
import { useSetting } from "../../hooks/Setting";
2025-10-04 21:25:54 +08:00
import { dictHandlers } from "../Selection/DictHandler";
2023-10-26 17:32:55 +08:00
2023-10-26 23:55:05 +08:00
function FavAccordion({ word, index }) {
2023-10-26 17:32:55 +08:00
const [expanded, setExpanded] = useState(false);
2025-10-03 18:28:50 +08:00
const { setting } = useSetting();
const { enDict, enSug } = setting?.tranboxSetting || {};
2023-10-26 17:32:55 +08:00
const handleChange = (e) => {
setExpanded((pre) => !pre);
};
return (
<Accordion expanded={expanded} onChange={handleChange}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
{/* <Typography>{`[${new Date(
createdAt
).toLocaleString()}] ${word}`}</Typography> */}
2023-10-26 23:55:05 +08:00
<Typography>{`${index + 1}. ${word}`}</Typography>
2023-10-26 17:32:55 +08:00
</AccordionSummary>
<AccordionDetails>
2024-04-15 18:04:35 +08:00
{expanded && (
<Stack spacing={2}>
2025-10-03 18:28:50 +08:00
<DictCont text={word} enDict={enDict} />
<SugCont text={word} enSug={enSug} />
2024-04-15 18:04:35 +08:00
</Stack>
)}
2023-10-26 17:32:55 +08:00
</AccordionDetails>
</Accordion>
);
}
export default function FavWords() {
2023-10-26 17:59:49 +08:00
const i18n = useI18n();
const { favList, wordList, mergeWords, clearWords } = useFavWords();
2025-10-03 22:07:48 +08:00
const { setting } = useSetting();
2025-10-01 12:30:58 +08:00
const confirm = useConfirm();
2023-10-26 17:59:49 +08:00
const handleImport = (data) => {
2023-10-26 17:59:49 +08:00
try {
2023-10-26 23:55:05 +08:00
const newWords = data
.split("\n")
.map((line) => line.split(",")[0].trim())
.filter(isValidWord);
mergeWords(newWords);
2023-10-26 17:59:49 +08:00
} catch (err) {
kissLog("import rules", err);
2023-10-26 17:59:49 +08:00
}
};
2025-10-01 12:30:58 +08:00
const handleClearWords = async () => {
const isConfirmed = await confirm({
confirmText: i18n("confirm_title"),
cancelText: i18n("cancel"),
});
if (isConfirmed) {
clearWords();
}
};
2024-04-16 16:29:59 +08:00
const handleTranslation = async () => {
2025-10-03 22:07:48 +08:00
const { enDict } = setting?.tranboxSetting;
2025-10-04 21:25:54 +08:00
const dict = dictHandlers[enDict];
2025-10-03 22:07:48 +08:00
if (!dict) return "";
2024-04-16 16:29:59 +08:00
const tranList = [];
2025-10-03 22:07:48 +08:00
for (const word of wordList) {
2024-04-16 16:29:59 +08:00
try {
2025-10-03 22:07:48 +08:00
const data = await dict.apiFn(word);
2025-10-04 22:29:03 +08:00
const title = `## ${dict.reWord(data) || word}`;
2025-10-04 21:25:54 +08:00
const tran = dict
.toText(data)
.map((line) => `- ${line}`)
.join("\n");
2025-10-04 22:29:03 +08:00
tranList.push([title, tran].join("\n"));
2024-04-16 16:29:59 +08:00
} catch (err) {
2025-10-04 21:25:54 +08:00
kissLog("export translation", err);
2024-04-16 16:29:59 +08:00
}
}
2025-10-03 22:07:48 +08:00
return tranList.join("\n\n");
2024-04-16 16:29:59 +08:00
};
2023-10-26 17:32:55 +08:00
return (
<Box>
<Stack spacing={3}>
2025-09-26 20:56:52 +08:00
<Alert severity="info">{i18n("favorite_words_helper")}</Alert>
2023-10-26 17:59:49 +08:00
<Stack
direction="row"
alignItems="center"
spacing={2}
useFlexGap
flexWrap="wrap"
>
2023-10-26 23:55:05 +08:00
<UploadButton
text={i18n("import")}
handleImport={handleImport}
fileType="text"
fileExts={[".txt", ".csv"]}
/>
2023-10-26 17:59:49 +08:00
<DownloadButton
handleData={() => wordList.join("\n")}
2023-10-26 17:59:49 +08:00
text={i18n("export")}
2023-10-26 23:55:05 +08:00
fileName={`kiss-words_${Date.now()}.txt`}
2023-10-26 17:59:49 +08:00
/>
2024-04-16 16:29:59 +08:00
<DownloadButton
handleData={handleTranslation}
text={i18n("export_translation")}
fileName={`kiss-words_${Date.now()}.md`}
/>
2023-10-26 23:55:05 +08:00
<Button
size="small"
variant="outlined"
2025-10-01 12:30:58 +08:00
onClick={handleClearWords}
2023-10-26 23:55:05 +08:00
startIcon={<ClearAllIcon />}
>
{i18n("clear_all")}
</Button>
2023-10-26 17:59:49 +08:00
</Stack>
2023-10-26 17:32:55 +08:00
<Box>
{favList.map(([word, { createdAt }], index) => (
<FavAccordion
key={word}
index={index}
word={word}
createdAt={createdAt}
/>
))}
2023-10-26 17:32:55 +08:00
</Box>
</Stack>
</Box>
);
}