Video.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { Card, Collapse, Modal, Space } from "antd";
  2. import { Typography } from "antd";
  3. import { useState } from "react";
  4. import { Link } from "react-router-dom";
  5. import { TDisplayStyle } from "./Article";
  6. import Video from "../general/Video";
  7. import { VideoIcon } from "../../assets/icon";
  8. import { useIntl } from "react-intl";
  9. const { Text } = Typography;
  10. interface IVideoCtl {
  11. url?: string;
  12. title?: React.ReactNode;
  13. style?: TDisplayStyle;
  14. }
  15. export const VideoCtl = ({ url, title, style = "modal" }: IVideoCtl) => {
  16. const intl = useIntl();
  17. const [isModalOpen, setIsModalOpen] = useState(false);
  18. const showModal = () => {
  19. setIsModalOpen(true);
  20. };
  21. const handleOk = () => {
  22. setIsModalOpen(false);
  23. };
  24. const handleCancel = () => {
  25. setIsModalOpen(false);
  26. };
  27. let output = <></>;
  28. let articleLink = url ? url : "";
  29. switch (style) {
  30. case "modal":
  31. output = (
  32. <>
  33. <Typography.Link
  34. onClick={(event: React.MouseEvent<HTMLElement, MouseEvent>) => {
  35. if (event.ctrlKey || event.metaKey) {
  36. window.open(articleLink, "_blank");
  37. } else {
  38. showModal();
  39. }
  40. }}
  41. >
  42. <Space>
  43. <VideoIcon />
  44. {title}
  45. </Space>
  46. </Typography.Link>
  47. <Modal
  48. width={"90%"}
  49. destroyOnClose
  50. style={{ maxWidth: 1000, top: 20, height: 700 }}
  51. title={
  52. <div
  53. style={{
  54. display: "flex",
  55. justifyContent: "space-between",
  56. marginRight: 30,
  57. }}
  58. >
  59. <Text>{title}</Text>
  60. <Text>
  61. <Link to={articleLink} target="_blank">
  62. {intl.formatMessage({
  63. id: "buttons.open.in.new.tab",
  64. })}
  65. </Link>
  66. </Text>
  67. </div>
  68. }
  69. open={isModalOpen}
  70. onOk={handleOk}
  71. onCancel={handleCancel}
  72. footer={[]}
  73. >
  74. <div style={{ height: 550 }}>
  75. <Video src={url} />
  76. </div>
  77. </Modal>
  78. </>
  79. );
  80. break;
  81. case "card":
  82. output = (
  83. <Card title={title}>
  84. <Video src={url} />
  85. </Card>
  86. );
  87. break;
  88. case "toggle":
  89. output = (
  90. <Collapse bordered={false}>
  91. <Collapse.Panel header={title} key="parent2">
  92. <Video src={url} />
  93. </Collapse.Panel>
  94. </Collapse>
  95. );
  96. break;
  97. case "link":
  98. output = (
  99. <Link to={articleLink} target="_blank">
  100. <Space>
  101. <VideoIcon />
  102. {title}
  103. </Space>
  104. </Link>
  105. );
  106. break;
  107. default:
  108. break;
  109. }
  110. return output;
  111. };
  112. interface IWidget {
  113. props: string;
  114. children?: React.ReactNode;
  115. }
  116. const VideoWidget = ({ props, children }: IWidget) => {
  117. const prop = JSON.parse(atob(props)) as IVideoCtl;
  118. return <VideoCtl {...prop} />;
  119. };
  120. export default VideoWidget;