SentTab.tsx 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. import { useEffect, useState } from "react";
  2. import { Badge, Space, Tabs, Typography } from "antd";
  3. import {
  4. TranslationOutlined,
  5. CloseOutlined,
  6. BlockOutlined,
  7. } from "@ant-design/icons";
  8. import SentTabButton from "./SentTabButton";
  9. import SentCanRead from "./SentCanRead";
  10. import SentSim from "./SentSim";
  11. import { useIntl } from "react-intl";
  12. import TocPath, { ITocPathNode } from "../../corpus/TocPath";
  13. import { IWbw } from "../Wbw/WbwWord";
  14. import RelaGraphic from "../Wbw/RelaGraphic";
  15. import SentMenu from "./SentMenu";
  16. import { ArticleMode } from "../../article/Article";
  17. import { IResNumber } from "../SentEdit";
  18. const { Text } = Typography;
  19. interface IWidget {
  20. id: string;
  21. book: number;
  22. para: number;
  23. wordStart: number;
  24. wordEnd: number;
  25. channelsId?: string[];
  26. path?: ITocPathNode[];
  27. layout?: "row" | "column";
  28. tranNum?: number;
  29. nissayaNum?: number;
  30. commNum?: number;
  31. originNum: number;
  32. simNum?: number;
  33. wbwData?: IWbw[];
  34. magicDictLoading?: boolean;
  35. compact?: boolean;
  36. mode?: ArticleMode;
  37. loadedRes?: IResNumber;
  38. onMagicDict?: Function;
  39. onCompact?: Function;
  40. onModeChange?: Function;
  41. }
  42. const SentTabWidget = ({
  43. id,
  44. book,
  45. para,
  46. wordStart,
  47. wordEnd,
  48. channelsId,
  49. path,
  50. tranNum,
  51. nissayaNum,
  52. commNum,
  53. originNum,
  54. simNum = 0,
  55. wbwData,
  56. magicDictLoading = false,
  57. compact = false,
  58. mode,
  59. loadedRes,
  60. onMagicDict,
  61. onCompact,
  62. onModeChange,
  63. }: IWidget) => {
  64. const intl = useIntl();
  65. const [isCompact, setIsCompact] = useState(compact);
  66. const [hover, setHover] = useState(false);
  67. const [currKey, setCurrKey] = useState("close");
  68. useEffect(() => setIsCompact(compact), [compact]);
  69. const mPath = path
  70. ? [
  71. ...path,
  72. { book: book, paragraph: para, title: para.toString(), level: 100 },
  73. ]
  74. : [];
  75. if (typeof id === "undefined") {
  76. return <></>;
  77. }
  78. const sentId = id.split("_");
  79. const sId = sentId[0].split("-");
  80. const tabButtonStyle: React.CSSProperties | undefined = compact
  81. ? { visibility: hover || currKey !== "close" ? "visible" : "hidden" }
  82. : undefined;
  83. return (
  84. <Tabs
  85. onMouseEnter={() => setHover(true)}
  86. onMouseLeave={() => setHover(false)}
  87. activeKey={currKey}
  88. onChange={(activeKey: string) => {
  89. setCurrKey(activeKey);
  90. }}
  91. style={
  92. isCompact
  93. ? {
  94. position: currKey === "close" ? "absolute" : "unset",
  95. marginTop: -32,
  96. width: "100%",
  97. marginRight: 10,
  98. backgroundColor:
  99. hover || currKey !== "close" ? "#80808030" : "unset",
  100. }
  101. : {
  102. padding: "0 8px",
  103. backgroundColor: "#80808030",
  104. }
  105. }
  106. tabBarStyle={{ marginBottom: 0 }}
  107. size="small"
  108. tabBarGutter={0}
  109. tabBarExtraContent={
  110. <Space>
  111. <TocPath
  112. link="none"
  113. data={mPath}
  114. trigger={path ? path.length > 0 ? path[0].title : <></> : <></>}
  115. />
  116. <Text copyable={{ text: `{{${sentId[0]}}}` }}>{sentId[0]}</Text>
  117. <SentMenu
  118. book={book}
  119. para={para}
  120. loading={magicDictLoading}
  121. mode={mode}
  122. onMagicDict={(type: string) => {
  123. if (typeof onMagicDict !== "undefined") {
  124. onMagicDict(type);
  125. }
  126. }}
  127. onMenuClick={(key: string) => {
  128. switch (key) {
  129. case "compact" || "normal":
  130. if (typeof onCompact !== "undefined") {
  131. setIsCompact(true);
  132. onCompact(true);
  133. }
  134. break;
  135. case "normal":
  136. if (typeof onCompact !== "undefined") {
  137. setIsCompact(false);
  138. onCompact(false);
  139. }
  140. break;
  141. case "origin-edit":
  142. if (typeof onModeChange !== "undefined") {
  143. onModeChange("edit");
  144. }
  145. break;
  146. case "origin-wbw":
  147. if (typeof onModeChange !== "undefined") {
  148. onModeChange("wbw");
  149. }
  150. break;
  151. default:
  152. break;
  153. }
  154. }}
  155. />
  156. </Space>
  157. }
  158. items={[
  159. {
  160. label: (
  161. <span style={tabButtonStyle}>
  162. <Badge size="small" count={0}>
  163. <CloseOutlined />
  164. </Badge>
  165. </span>
  166. ),
  167. key: "close",
  168. children: <></>,
  169. },
  170. {
  171. label: (
  172. <SentTabButton
  173. style={tabButtonStyle}
  174. icon={<TranslationOutlined />}
  175. type="translation"
  176. sentId={id}
  177. count={
  178. tranNum
  179. ? tranNum -
  180. (loadedRes?.translation ? loadedRes.translation : 0)
  181. : undefined
  182. }
  183. title={intl.formatMessage({
  184. id: "channel.type.translation.label",
  185. })}
  186. />
  187. ),
  188. key: "translation",
  189. children: (
  190. <SentCanRead
  191. book={parseInt(sId[0])}
  192. para={parseInt(sId[1])}
  193. wordStart={parseInt(sId[2])}
  194. wordEnd={parseInt(sId[3])}
  195. type="translation"
  196. channelsId={channelsId}
  197. />
  198. ),
  199. },
  200. {
  201. label: (
  202. <SentTabButton
  203. style={tabButtonStyle}
  204. icon={<CloseOutlined />}
  205. type="nissaya"
  206. sentId={id}
  207. count={
  208. nissayaNum
  209. ? nissayaNum - (loadedRes?.nissaya ? loadedRes.nissaya : 0)
  210. : undefined
  211. }
  212. title={intl.formatMessage({
  213. id: "channel.type.nissaya.label",
  214. })}
  215. />
  216. ),
  217. key: "nissaya",
  218. children: (
  219. <SentCanRead
  220. book={parseInt(sId[0])}
  221. para={parseInt(sId[1])}
  222. wordStart={parseInt(sId[2])}
  223. wordEnd={parseInt(sId[3])}
  224. type="nissaya"
  225. channelsId={channelsId}
  226. />
  227. ),
  228. },
  229. {
  230. label: (
  231. <SentTabButton
  232. style={tabButtonStyle}
  233. icon={<TranslationOutlined />}
  234. type="commentary"
  235. sentId={id}
  236. count={
  237. commNum
  238. ? commNum - (loadedRes?.commentary ? loadedRes.commentary : 0)
  239. : undefined
  240. }
  241. title={intl.formatMessage({
  242. id: "channel.type.commentary.label",
  243. })}
  244. />
  245. ),
  246. key: "commentary",
  247. children: (
  248. <SentCanRead
  249. book={parseInt(sId[0])}
  250. para={parseInt(sId[1])}
  251. wordStart={parseInt(sId[2])}
  252. wordEnd={parseInt(sId[3])}
  253. type="commentary"
  254. channelsId={channelsId}
  255. />
  256. ),
  257. },
  258. /*{
  259. label: (
  260. <SentTabButton
  261. icon={<BlockOutlined />}
  262. type="original"
  263. sentId={id}
  264. count={originNum}
  265. title={intl.formatMessage({
  266. id: "channel.type.original.label",
  267. })}
  268. />
  269. ),
  270. key: "original",
  271. children: (
  272. <SentCanRead
  273. book={parseInt(sId[0])}
  274. para={parseInt(sId[1])}
  275. wordStart={parseInt(sId[2])}
  276. wordEnd={parseInt(sId[3])}
  277. type="original"
  278. />
  279. ),
  280. },*/
  281. {
  282. label: (
  283. <SentTabButton
  284. style={tabButtonStyle}
  285. icon={<BlockOutlined />}
  286. type="original"
  287. sentId={id}
  288. count={simNum}
  289. title={intl.formatMessage({
  290. id: "buttons.sim",
  291. })}
  292. />
  293. ),
  294. key: "sim",
  295. children: (
  296. <SentSim
  297. book={parseInt(sId[0])}
  298. para={parseInt(sId[1])}
  299. wordStart={parseInt(sId[2])}
  300. wordEnd={parseInt(sId[3])}
  301. channelsId={channelsId}
  302. limit={5}
  303. />
  304. ),
  305. },
  306. {
  307. label: <span style={tabButtonStyle}>{"关系图"}</span>,
  308. key: "relation-graphic",
  309. children: <RelaGraphic wbwData={wbwData} />,
  310. },
  311. ]}
  312. />
  313. );
  314. };
  315. export default SentTabWidget;