ArticleView.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import { Typography, Divider, Button, Skeleton } from "antd";
  2. import { ReloadOutlined } from "@ant-design/icons";
  3. import MdView from "../template/MdView";
  4. import TocPath, { ITocPathNode } from "../corpus/TocPath";
  5. import PaliChapterChannelList from "../corpus/PaliChapterChannelList";
  6. import { ArticleType } from "./Article";
  7. import VisibleObserver from "../general/VisibleObserver";
  8. const { Paragraph, Title, Text } = Typography;
  9. export interface IWidgetArticleData {
  10. id?: string;
  11. title?: string;
  12. subTitle?: string;
  13. summary?: string;
  14. content?: string;
  15. html?: string[];
  16. path?: ITocPathNode[];
  17. created_at?: string;
  18. updated_at?: string;
  19. channels?: string[];
  20. type?: ArticleType;
  21. articleId?: string;
  22. remains?: boolean;
  23. onEnd?: Function;
  24. onPathChange?: Function;
  25. }
  26. const ArticleViewWidget = ({
  27. id,
  28. title = "",
  29. subTitle,
  30. summary,
  31. content,
  32. html = [],
  33. path = [],
  34. created_at,
  35. updated_at,
  36. channels,
  37. type,
  38. articleId,
  39. onEnd,
  40. remains,
  41. onPathChange,
  42. }: IWidgetArticleData) => {
  43. let currChannelList = <></>;
  44. switch (type) {
  45. case "chapter":
  46. const chapterProps = articleId?.split("-");
  47. if (typeof chapterProps === "object" && chapterProps.length > 0) {
  48. currChannelList = (
  49. <PaliChapterChannelList
  50. para={{
  51. book: parseInt(chapterProps[0]),
  52. para: parseInt(chapterProps[1]),
  53. }}
  54. channelId={channels}
  55. openTarget="_self"
  56. />
  57. );
  58. }
  59. break;
  60. default:
  61. break;
  62. }
  63. return (
  64. <>
  65. <div style={{ textAlign: "right" }}>
  66. <Button
  67. type="link"
  68. shape="round"
  69. size="small"
  70. icon={<ReloadOutlined />}
  71. />
  72. </div>
  73. <div>
  74. <TocPath
  75. data={path}
  76. channel={channels}
  77. onChange={(
  78. node: ITocPathNode,
  79. e: React.MouseEvent<HTMLSpanElement | HTMLAnchorElement, MouseEvent>
  80. ) => {
  81. if (typeof onPathChange !== "undefined") {
  82. onPathChange(node, e);
  83. }
  84. }}
  85. />
  86. <Title level={4}>
  87. <div
  88. dangerouslySetInnerHTML={{
  89. __html: title ? title : "",
  90. }}
  91. />
  92. </Title>
  93. <Text type="secondary">{subTitle}</Text>
  94. {currChannelList}
  95. <Paragraph ellipsis={{ rows: 2, expandable: true, symbol: "more" }}>
  96. {summary}
  97. </Paragraph>
  98. <Divider />
  99. </div>
  100. {html
  101. ? html.map((item, id) => {
  102. return (
  103. <div key={id}>
  104. <MdView className="pcd_article" html={item} />
  105. </div>
  106. );
  107. })
  108. : content}
  109. {remains ? (
  110. <>
  111. <VisibleObserver
  112. onVisible={(visible: boolean) => {
  113. console.log("visible", visible);
  114. if (visible && typeof onEnd !== "undefined") {
  115. onEnd();
  116. }
  117. }}
  118. />
  119. <Skeleton title={{ width: 200 }} paragraph={{ rows: 5 }} active />
  120. </>
  121. ) : undefined}
  122. </>
  123. );
  124. };
  125. export default ArticleViewWidget;