ArticleView.tsx 3.6 KB

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