| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- import { useEffect, useState } from "react";
- import { Button, Popover, Space, Typography } from "antd";
- import {
- TagTwoTone,
- InfoCircleOutlined,
- CommentOutlined,
- ApartmentOutlined,
- } from "@ant-design/icons";
- import "./wbw.css";
- import WbwDetail from "./WbwDetail";
- import { IWbw, TWbwDisplayMode } from "./WbwWord";
- import { bookMarkColor } from "./WbwDetailBookMark";
- import WbwVideoButton from "./WbwVideoButton";
- import CommentBox from "../../discussion/DiscussionBox";
- import PaliText from "./PaliText";
- import store from "../../../store";
- import { lookup } from "../../../reducers/command";
- import { useAppSelector } from "../../../hooks";
- import { add, relationAddParam } from "../../../reducers/relation-add";
- import { ArticleMode } from "../../article/Article";
- const { Paragraph } = Typography;
- interface IWidget {
- data: IWbw;
- display?: TWbwDisplayMode;
- mode?: ArticleMode;
- onSave?: Function;
- }
- const WbwPaliWidget = ({ data, mode, display, onSave }: IWidget) => {
- const [popOpen, setPopOpen] = useState(false);
- const [paliColor, setPaliColor] = useState("unset");
- const [hasComment, setHasComment] = useState(data.hasComment);
- /**
- * 处理 relation 链接事件
- * 高亮可能的单词
- */
- const addParam = useAppSelector(relationAddParam);
- useEffect(() => {
- let grammar = data.case?.value
- ?.replace("#", "$")
- .replaceAll(".", "")
- .split("$");
- if (data.grammar2?.value) {
- if (grammar) {
- grammar = [data.grammar2?.value, ...grammar];
- } else {
- grammar = [data.grammar2?.value];
- }
- }
- console.log("grammar", grammar);
- if (typeof grammar === "undefined") {
- return;
- }
- const match = addParam?.relations?.filter((value) => {
- let caseMatch = true;
- let spellMatch = true;
- if (!value.to) {
- return false;
- }
- if (value.to?.case) {
- let matchCount = 0;
- if (grammar) {
- for (const iterator of value.to.case) {
- if (grammar?.includes(iterator)) {
- matchCount++;
- }
- }
- }
- if (matchCount !== value.to.case.length) {
- caseMatch = false;
- }
- }
- if (value.from?.spell) {
- if (data.real.value !== value.from?.spell) {
- spellMatch = false;
- }
- }
- return caseMatch && spellMatch;
- });
- if (match && match.length > 0) {
- setPaliColor("greenyellow");
- }
- }, [
- addParam?.relations,
- data.case?.value,
- data.grammar2?.value,
- data.real.value,
- ]);
- /**
- * 点击连接或取消后,打开弹窗
- */
- useEffect(() => {
- if (addParam?.command === "apply" || addParam?.command === "cancel") {
- setPaliColor("unset");
- if (
- addParam.src_sn === data.sn.join("-") &&
- addParam.book === data.book &&
- addParam.para === data.para
- ) {
- setPopOpen(true);
- store.dispatch(
- add({
- book: data.book,
- para: data.para,
- src_sn: data.sn.join("-"),
- command: "finish",
- })
- );
- }
- }
- }, [
- addParam?.book,
- addParam?.command,
- addParam?.para,
- addParam?.src_sn,
- data.book,
- data.para,
- data.sn,
- ]);
- const handleClickChange = (open: boolean) => {
- if (mode === "wbw") {
- if (open) {
- setPaliColor("lightblue");
- } else {
- setPaliColor("unset");
- }
- setPopOpen(open);
- }
- };
- const wbwDetail = (
- <WbwDetail
- data={data}
- onClose={() => {
- setPaliColor("unset");
- setPopOpen(false);
- }}
- onSave={(e: IWbw, isPublish: boolean) => {
- if (typeof onSave !== "undefined") {
- onSave(e, isPublish);
- setPopOpen(false);
- setPaliColor("unset");
- }
- }}
- onCommentCountChange={(count: number) => {
- if (count > 0) {
- setHasComment(true);
- } else {
- setHasComment(false);
- }
- }}
- />
- );
- const noteIcon = data.note?.value ? (
- data.note.value.trim() !== "" ? (
- <Popover content={data.note?.value} placement="bottom">
- <InfoCircleOutlined style={{ color: "blue" }} />
- </Popover>
- ) : undefined
- ) : undefined;
- const color = data.bookMarkColor?.value
- ? bookMarkColor[data.bookMarkColor.value]
- : "white";
- //生成视频播放按钮
- const videoList = data.attachments?.filter((item) =>
- item.content_type?.includes("video")
- );
- const videoIcon = videoList ? (
- <WbwVideoButton
- video={videoList?.map((item) => {
- return {
- videoId: item.id,
- type: item.content_type,
- title: item.title,
- };
- })}
- />
- ) : undefined;
- const relationIcon = data.relation ? (
- <ApartmentOutlined style={{ color: "blue" }} />
- ) : undefined;
- const bookMarkIcon =
- data.bookMarkText?.value && data.bookMarkText.value.trim() !== "" ? (
- <Popover
- content={<Paragraph copyable>{data.bookMarkText.value}</Paragraph>}
- placement="bottom"
- >
- <TagTwoTone twoToneColor={color} />
- </Popover>
- ) : undefined;
- const classPali = data.style?.value === "note" ? "wbw_note" : "pali";
- let padding: string;
- if (typeof data.real !== "undefined" && data.real.value !== "") {
- padding = "4px";
- } else {
- padding = "4px 0";
- }
- let pali = <PaliText text={data.word.value} termToLocal={false} />;
- if (data.word.value.indexOf("}") >= 0) {
- const paliArray = data.word.value.replace("{", "").split("}");
- pali = (
- <>
- <span style={{ fontWeight: 700 }}>
- <PaliText text={paliArray[0]} termToLocal={false} />
- </span>
- <PaliText text={paliArray[1]} termToLocal={false} />
- </>
- );
- }
- const paliWord = (
- <span
- className={classPali}
- style={{
- backgroundColor: paliColor,
- padding: padding,
- borderRadius: 5,
- }}
- onClick={() => {
- //发送点词查询消息
- if (typeof data.real?.value === "string") {
- store.dispatch(lookup(data.real.value));
- }
- }}
- >
- {pali}
- </span>
- );
- let commentShellStyle: React.CSSProperties = {
- display: "inline-block",
- };
- const discussionIcon = hasComment ? (
- <div style={commentShellStyle}>
- <CommentBox
- resId={data.uid}
- resType="wbw"
- trigger={<Button icon={<CommentOutlined />} type="text" title="讨论" />}
- onCommentCountChange={(count: number) => {
- if (count > 0) {
- setHasComment(true);
- } else {
- setHasComment(false);
- }
- }}
- />
- </div>
- ) : undefined;
- if (typeof data.real !== "undefined" && data.real.value !== "") {
- //非标点符号
- return (
- <div className="pali_shell">
- <Popover
- content={wbwDetail}
- placement="bottom"
- trigger="click"
- open={popOpen}
- onOpenChange={handleClickChange}
- >
- {paliWord}
- </Popover>
- <Space>
- {videoIcon}
- {noteIcon}
- {bookMarkIcon}
- {relationIcon}
- {discussionIcon}
- </Space>
- </div>
- );
- } else {
- //标点符号
- return (
- <div className="pali_shell" style={{ cursor: "unset" }}>
- {paliWord}
- </div>
- );
- }
- };
- export default WbwPaliWidget;
|