ParaHandle.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { Button, Divider, Dropdown, MenuProps, message } from "antd";
  2. import { useNavigate, useSearchParams } from "react-router-dom";
  3. import { fullUrl } from "../../utils";
  4. interface IWidgetParaHandleCtl {
  5. book: number;
  6. para: number;
  7. mode?: string;
  8. channels?: string[];
  9. sentences: string[];
  10. }
  11. const ParaHandleCtl = ({
  12. book,
  13. para,
  14. mode = "read",
  15. channels,
  16. sentences,
  17. }: IWidgetParaHandleCtl) => {
  18. const navigate = useNavigate();
  19. const [searchParams] = useSearchParams();
  20. const items: MenuProps["items"] = [
  21. {
  22. key: "solo",
  23. label: "仅显示此段",
  24. },
  25. {
  26. key: "solo-in-tab",
  27. label: "在标签页打开此段",
  28. },
  29. {
  30. key: "copy-sent",
  31. label: "复制句子链接",
  32. },
  33. ];
  34. const onClick: MenuProps["onClick"] = (e) => {
  35. /**
  36. * TODO 临时的解决方案。以后应该从传参获取其他参数,然后reducer 通知更新。
  37. * 因为如果是Article组件被嵌入其他页面。不能直接更新浏览器,而是应该更新Article组件内部
  38. */
  39. let url = `/article/para/${book}-${para}?book=${book}&par=${para}`;
  40. let param: string[] = [];
  41. searchParams.forEach((value, key) => {
  42. if (key !== "book" && key !== "par") {
  43. param.push(`${key}=${value}`);
  44. }
  45. });
  46. if (param.length > 0) {
  47. url += "&" + param.join("&");
  48. }
  49. switch (e.key) {
  50. case "solo":
  51. navigate(url);
  52. break;
  53. case "solo-in-tab":
  54. window.open(fullUrl(url), "_blank");
  55. break;
  56. case "copy-sent":
  57. navigator.clipboard
  58. .writeText(sentences.map((item) => `{{${item}}}`).join(""))
  59. .then(() => {
  60. message.success("链接地址已经拷贝到剪贴板");
  61. });
  62. break;
  63. default:
  64. break;
  65. }
  66. };
  67. return (
  68. <Divider orientation="left">
  69. <Dropdown
  70. menu={{ items, onClick }}
  71. placement="bottomLeft"
  72. trigger={["click"]}
  73. >
  74. <Button type="text">{para}</Button>
  75. </Dropdown>
  76. </Divider>
  77. );
  78. };
  79. interface IWidget {
  80. props: string;
  81. }
  82. const Widget = ({ props }: IWidget) => {
  83. const prop = JSON.parse(atob(props)) as IWidgetParaHandleCtl;
  84. return (
  85. <>
  86. <ParaHandleCtl {...prop} />
  87. </>
  88. );
  89. };
  90. export default Widget;