SentContent.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import { ISentence } from "../SentEdit";
  2. import SentCell from "./SentCell";
  3. import { WbwSentCtl } from "../WbwSent";
  4. import { useAppSelector } from "../../../hooks";
  5. import { settingInfo } from "../../../reducers/setting";
  6. import { useEffect, useLayoutEffect, useRef, useState } from "react";
  7. import { GetUserSetting } from "../../auth/setting/default";
  8. import { mode as _mode } from "../../../reducers/article-mode";
  9. import { IWbw } from "../Wbw/WbwWord";
  10. import { ArticleMode } from "../../article/Article";
  11. import SuggestionFocus from "./SuggestionFocus";
  12. interface ILayoutFlex {
  13. left: number;
  14. right: number;
  15. }
  16. type TDirection = "row" | "column";
  17. interface IWidgetSentContent {
  18. sid?: string;
  19. book: number;
  20. para: number;
  21. wordStart: number;
  22. wordEnd: number;
  23. origin?: ISentence[];
  24. translation?: ISentence[];
  25. layout?: TDirection;
  26. magicDict?: string;
  27. compact?: boolean;
  28. mode?: ArticleMode;
  29. wbwProgress?: boolean;
  30. onWbwChange?: Function;
  31. onMagicDictDone?: Function;
  32. }
  33. const SentContentWidget = ({
  34. sid,
  35. book,
  36. para,
  37. wordStart,
  38. wordEnd,
  39. origin,
  40. translation,
  41. layout = "column",
  42. compact = false,
  43. mode,
  44. magicDict,
  45. wbwProgress = false,
  46. onWbwChange,
  47. onMagicDictDone,
  48. }: IWidgetSentContent) => {
  49. const [layoutDirection, setLayoutDirection] = useState<TDirection>(layout);
  50. const [layoutFlex, setLayoutFlex] = useState<ILayoutFlex>({
  51. left: 5,
  52. right: 5,
  53. });
  54. const divShell = useRef<HTMLDivElement>(null);
  55. const settings = useAppSelector(settingInfo);
  56. const [divShellWidth, setDivShellWidth] = useState<number>();
  57. useEffect(() => {
  58. const width = divShell.current?.offsetWidth;
  59. if (width && width < 550) {
  60. setLayoutDirection("column");
  61. return;
  62. }
  63. const layoutDirection = GetUserSetting(
  64. "setting.layout.direction",
  65. settings
  66. );
  67. if (typeof layoutDirection === "string") {
  68. setLayoutDirection(layoutDirection as TDirection);
  69. }
  70. }, [settings]);
  71. const newMode = useAppSelector(_mode);
  72. useEffect(() => {
  73. let currMode: ArticleMode | undefined;
  74. if (typeof mode !== "undefined") {
  75. currMode = mode;
  76. } else if (typeof newMode !== "undefined") {
  77. if (typeof newMode.id === "undefined") {
  78. currMode = newMode.mode;
  79. } else {
  80. const sentId = newMode.id.split("-");
  81. if (sentId.length === 2) {
  82. if (book === parseInt(sentId[0]) && para === parseInt(sentId[1])) {
  83. currMode = newMode.mode;
  84. }
  85. }
  86. }
  87. } else {
  88. return;
  89. }
  90. switch (currMode) {
  91. case "edit":
  92. setLayoutFlex({
  93. left: 5,
  94. right: 5,
  95. });
  96. break;
  97. case "wbw":
  98. setLayoutFlex({
  99. left: 7,
  100. right: 3,
  101. });
  102. break;
  103. }
  104. }, [book, mode, newMode, para]);
  105. useLayoutEffect(() => {
  106. const width = divShell.current?.offsetWidth;
  107. setDivShellWidth(width);
  108. if (width && width < 550) {
  109. setLayoutDirection("column");
  110. return;
  111. }
  112. }, []);
  113. return (
  114. <div
  115. ref={divShell}
  116. style={{
  117. display: "flex",
  118. flexDirection: layoutDirection,
  119. marginBottom: 0,
  120. }}
  121. >
  122. <div
  123. dangerouslySetInnerHTML={{
  124. __html: `<div class="pcd_sent" id="sent_${sid}"></div>`,
  125. }}
  126. />
  127. <div style={{ flex: layoutFlex.left, color: "#9f3a01" }}>
  128. {origin?.map((item, id) => {
  129. if (item.contentType === "json") {
  130. return (
  131. <WbwSentCtl
  132. key={id}
  133. book={book}
  134. para={para}
  135. wordStart={wordStart}
  136. wordEnd={wordEnd}
  137. channelId={item.channel.id}
  138. channelType={item.channel.type}
  139. channelLang={item.channel.lang}
  140. data={JSON.parse(item.content ? item.content : "")}
  141. mode={mode}
  142. wbwProgress={wbwProgress}
  143. onChange={(data: IWbw[]) => {
  144. if (typeof onWbwChange !== "undefined") {
  145. onWbwChange(data);
  146. }
  147. }}
  148. onMagicDictDone={() => {
  149. if (typeof onMagicDictDone !== "undefined") {
  150. onMagicDictDone();
  151. }
  152. }}
  153. />
  154. );
  155. } else {
  156. return <SentCell key={id} initValue={item} wordWidget={true} />;
  157. }
  158. })}
  159. </div>
  160. <div style={{ flex: layoutFlex.right }}>
  161. {translation?.map((item, id) => {
  162. return (
  163. <SuggestionFocus
  164. key={id}
  165. book={item.book}
  166. para={item.para}
  167. start={item.wordStart}
  168. end={item.wordEnd}
  169. channelId={item.channel.id}
  170. >
  171. <SentCell key={id} initValue={item} compact={compact} />
  172. </SuggestionFocus>
  173. );
  174. })}
  175. </div>
  176. </div>
  177. );
  178. };
  179. export default SentContentWidget;