ArticleView.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import { Typography, Divider, Skeleton, Space } from "antd";
  2. import MdView from "../template/MdView";
  3. import TocPath, {
  4. type ITocPathNode,
  5. } from "../../../src/components/tipitaka/TocPath";
  6. import PaliChapterChannelList from "../../../src/components/tipitaka/PaliChapterChannelList";
  7. import type { ArticleMode, ArticleType } from "./Article";
  8. import VisibleObserver from "../general/VisibleObserver";
  9. import type { IStudio } from "../auth/Studio";
  10. const { Paragraph, Title, Text } = Typography;
  11. export interface IFirstAnthology {
  12. id: string;
  13. title: string;
  14. count: number;
  15. }
  16. export interface IWidgetArticleData {
  17. id?: string;
  18. title?: string;
  19. subTitle?: string;
  20. summary?: string | null;
  21. content?: string;
  22. html?: string[];
  23. path?: ITocPathNode[];
  24. mode?: ArticleMode | null;
  25. created_at?: string;
  26. updated_at?: string;
  27. owner?: IStudio;
  28. channels?: string[];
  29. type?: ArticleType;
  30. articleId?: string;
  31. remains?: boolean;
  32. anthology?: IFirstAnthology;
  33. hideTitle?: boolean;
  34. onEnd?: () => void;
  35. onPathChange?: (
  36. node: ITocPathNode,
  37. e: React.MouseEvent<HTMLSpanElement | HTMLAnchorElement, MouseEvent>
  38. ) => void;
  39. }
  40. const ArticleViewWidget = ({
  41. title = "",
  42. subTitle,
  43. summary,
  44. content,
  45. html = [],
  46. path = [],
  47. channels,
  48. type,
  49. articleId,
  50. hideTitle,
  51. onEnd,
  52. remains,
  53. onPathChange,
  54. }: IWidgetArticleData) => {
  55. console.log("ArticleViewWidget render");
  56. let currChannelList = <></>;
  57. switch (type) {
  58. case "chapter": {
  59. const chapterProps = articleId?.split("-");
  60. if (Array.isArray(chapterProps) && chapterProps.length >= 2) {
  61. const book = Number(chapterProps[0]);
  62. const para = Number(chapterProps[1]);
  63. if (!Number.isNaN(book) && !Number.isNaN(para)) {
  64. currChannelList = (
  65. <PaliChapterChannelList
  66. para={{ book, para }}
  67. channelId={channels}
  68. openTarget="_self"
  69. />
  70. );
  71. }
  72. }
  73. break;
  74. }
  75. default:
  76. break;
  77. }
  78. return (
  79. <>
  80. <Space orientation="vertical">
  81. {hideTitle ? (
  82. <></>
  83. ) : (
  84. <TocPath
  85. data={path}
  86. channels={channels}
  87. onChange={(
  88. node: ITocPathNode,
  89. e: React.MouseEvent<
  90. HTMLSpanElement | HTMLAnchorElement,
  91. MouseEvent
  92. >
  93. ) => {
  94. if (typeof onPathChange !== "undefined") {
  95. onPathChange(node, e);
  96. }
  97. }}
  98. />
  99. )}
  100. {hideTitle ? (
  101. <></>
  102. ) : (
  103. <Title level={4}>
  104. <div
  105. dangerouslySetInnerHTML={{
  106. __html: title ? title : "",
  107. }}
  108. />
  109. </Title>
  110. )}
  111. <Text type="secondary">{subTitle}</Text>
  112. {currChannelList}
  113. <Paragraph ellipsis={{ rows: 2, expandable: true, symbol: "more" }}>
  114. {summary}
  115. </Paragraph>
  116. <Divider />
  117. </Space>
  118. {html
  119. ? html.map((item, id) => {
  120. return (
  121. <div key={id}>
  122. <MdView className="pcd_article paper paper_zh" html={item} />
  123. </div>
  124. );
  125. })
  126. : content}
  127. {remains ? (
  128. <>
  129. <VisibleObserver
  130. onVisible={(visible: boolean) => {
  131. console.log("visible", visible);
  132. if (visible && typeof onEnd !== "undefined") {
  133. onEnd();
  134. }
  135. }}
  136. />
  137. <Skeleton title={{ width: 200 }} paragraph={{ rows: 5 }} active />
  138. </>
  139. ) : undefined}
  140. </>
  141. );
  142. };
  143. export default ArticleViewWidget;