import { useEffect, useMemo, useState, useCallback } from "react"; import { Button, Dropdown, type MenuProps, Typography } from "antd"; import { LoadingOutlined, CloseOutlined } from "@ant-design/icons"; import { useAppSelector } from "../../hooks"; import { settingInfo } from "../../reducers/setting"; import { GetUserSetting } from "../auth/setting/default"; import type { TCodeConvertor } from "./utilities"; import { type ISentence, type IWidgetSentEditInner, SentEditInner, } from "./SentEdit"; import MdView from "./MdView"; import store from "../../store"; import { push } from "../../reducers/sentence"; import "./style.css"; import InteractiveButton from "./SentEdit/InteractiveButton"; import { prOpen } from "./SentEdit/SuggestionButton"; import { openDiscussion } from "../discussion/DiscussionButton"; import type { IEditableSentence } from "../../api/Corpus"; import { get } from "../../request"; const { Text } = Typography; const items: MenuProps["items"] = [ { label: "编辑", key: "edit" }, { label: "讨论", key: "discussion" }, { label: "修改建议", key: "pr" }, { label: "标签", key: "tag" }, ]; interface IWidgetSentReadFrame { origin?: ISentence[]; translation?: ISentence[]; layout?: "row" | "column"; book?: number; para?: number; wordStart?: number; wordEnd?: number; sentId?: string; error?: string; } const SentReadFrame = ({ origin, translation, book, para, wordStart, wordEnd, error, }: IWidgetSentReadFrame) => { const settings = useAppSelector(settingInfo); const [loadingId, setLoadingId] = useState(null); const [active, setActive] = useState(false); const [sentData, setSentData] = useState(); const [showEdit, setShowEdit] = useState(false); /** 派生数据:主巴利编码 */ const paliCode = useMemo(() => { const v = GetUserSetting("setting.pali.script.primary", settings); return (v ?? "roman") as TCodeConvertor; }, [settings]); /** 派生数据:是否显示原文 */ const displayOriginal = useMemo(() => { return GetUserSetting("setting.display.original", settings); }, [settings]); /** 派生数据:布局方向 */ const layoutDirection = useMemo(() => { const v = GetUserSetting("setting.layout.direction", settings); if ( v === "row" || v === "column" || v === "row-reverse" || v === "column-reverse" ) { return v; } return "row"; }, [settings]); /** push 到 store(副作用) */ useEffect(() => { store.dispatch( push({ id: `${book}-${para}-${wordStart}-${wordEnd}`, origin: origin?.map((item) => item.html), translation: translation?.map((item) => item.html), }) ); }, [book, origin, para, translation, wordEnd, wordStart]); /** 菜单点击 */ const handleMenuClick = useCallback(async (key: string, item: ISentence) => { switch (key) { case "edit": if (!item.id) return; setLoadingId(item.id); try { const json = await get( `/v2/editable-sentence/${item.id}` ); if (json.ok) { setSentData(json.data); setShowEdit(true); } } finally { setLoadingId(null); } break; case "discussion": if (item.id) { openDiscussion(item.id, "sentence", false); } break; case "pr": prOpen(item); break; } }, []); return ( {error} {/* anchor */} `, }} /> {/* 原文 */} {origin?.map((item, id) => ( ))} {/* 译文 */} {translation?.map((item, id) => ( {loadingId === item.id && } handleMenuClick(e.key, item), }} > {/* 编辑面板 */} {showEdit && (
{sentData ? ( { if (!translation) return; const copy = [...translation]; copy[id] = data; }} /> ) : ( "无数据" )}
)} setActive(true)} onMouseLeave={() => setActive(false)} />
))}
); }; interface IWidget { props: string; } const Widget = ({ props }: IWidget) => { const prop = JSON.parse(atob(props)) as IWidgetSentReadFrame; return ; }; export default Widget;