SentCanRead.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. import { Button, message } from "antd";
  2. import { useEffect, useState } from "react";
  3. import { ReloadOutlined } from "@ant-design/icons";
  4. import { get } from "../../../request";
  5. import type { TChannelType } from "../../../api/Channel";
  6. import type { ISentenceData, ISentenceListResponse } from "../../../api/Corpus";
  7. import type { ISentence } from "../SentEdit";
  8. import SentCell from "./SentCell";
  9. import SentAdd from "./SentAdd";
  10. import { useAppSelector } from "../../../hooks";
  11. import { currentUser as _currentUser } from "../../../reducers/current-user";
  12. import type { IChannel } from "../../channel/Channel";
  13. import type { IWbw } from "../Wbw/WbwWord";
  14. export const toISentence = (item: ISentenceData, channelsId?: string[]) => {
  15. return {
  16. id: item.id,
  17. content: item.content,
  18. html: item.html,
  19. book: item.book,
  20. para: item.paragraph,
  21. wordStart: item.word_start,
  22. wordEnd: item.word_end,
  23. editor: item.editor,
  24. studio: item.studio,
  25. channel: item.channel,
  26. contentType: item.content_type,
  27. suggestionCount: item.suggestionCount,
  28. translationChannels: channelsId,
  29. forkAt: item.fork_at,
  30. updateAt: item.updated_at,
  31. };
  32. };
  33. interface IWidget {
  34. book: number;
  35. para: number;
  36. wordStart: number;
  37. wordEnd: number;
  38. type: TChannelType;
  39. channelsId?: string[];
  40. origin?: ISentence[];
  41. onReload?: Function;
  42. onCreate?: Function;
  43. }
  44. const SentCanReadWidget = ({
  45. book,
  46. para,
  47. wordStart,
  48. wordEnd,
  49. type,
  50. channelsId,
  51. origin,
  52. onReload,
  53. onCreate,
  54. }: IWidget) => {
  55. const [sentData, setSentData] = useState<ISentence[]>([]);
  56. const [channels, setChannels] = useState<string[]>();
  57. const user = useAppSelector(_currentUser);
  58. const load = () => {
  59. const sentId = `${book}-${para}-${wordStart}-${wordEnd}`;
  60. let url = `/v2/sentence?view=sent-can-read&sentence=${sentId}&type=${type}&mode=edit&html=true`;
  61. url += channelsId ? `&excludes=${channelsId.join()}` : "";
  62. if (type === "commentary" || type === "similar") {
  63. url += channelsId ? `&channels=${channelsId.join()}` : "";
  64. }
  65. console.info("ai request", url);
  66. get<ISentenceListResponse>(url)
  67. .then((json) => {
  68. if (json.ok) {
  69. console.log("sent load", json.data.rows);
  70. const channels: string[] = json.data.rows.map(
  71. (item) => item.channel.id
  72. );
  73. setChannels(channels);
  74. const newData: ISentence[] = json.data.rows.map((item) => {
  75. return toISentence(item, channelsId);
  76. });
  77. console.log("new data", newData);
  78. setSentData(newData);
  79. } else {
  80. message.error(json.message);
  81. }
  82. })
  83. .finally(() => {
  84. onReload && onReload();
  85. });
  86. };
  87. useEffect(() => {
  88. load();
  89. }, []);
  90. return (
  91. <div>
  92. <div style={{ display: "flex", justifyContent: "space-between" }}>
  93. <span></span>
  94. <Button
  95. type="link"
  96. shape="round"
  97. icon={<ReloadOutlined />}
  98. onClick={() => load()}
  99. />
  100. </div>
  101. <div style={{ textAlign: "center" }}>
  102. <SentAdd
  103. disableChannels={channels}
  104. type={type}
  105. onSelect={(channel: IChannel) => {
  106. if (typeof user === "undefined") {
  107. return;
  108. }
  109. const newSent: ISentence = {
  110. content: "",
  111. contentType: "markdown",
  112. html: "",
  113. book: book,
  114. para: para,
  115. wordStart: wordStart,
  116. wordEnd: wordEnd,
  117. editor: {
  118. id: user.id,
  119. nickName: user.nickName,
  120. userName: user.realName,
  121. },
  122. channel: channel,
  123. translationChannels: channelsId,
  124. updateAt: "",
  125. openInEditMode: true,
  126. };
  127. setSentData((origin) => {
  128. return [newSent, ...origin];
  129. });
  130. setChannels((origin) => {
  131. if (origin) {
  132. if (!origin.includes(newSent.channel.id)) {
  133. origin.push(newSent.channel.id);
  134. return origin;
  135. }
  136. } else {
  137. return [newSent.channel.id];
  138. }
  139. });
  140. if (typeof onCreate !== "undefined") {
  141. onCreate();
  142. }
  143. }}
  144. />
  145. </div>
  146. {sentData.map((item, id) => {
  147. let diffText: string | null = null;
  148. if (origin) {
  149. diffText = origin[0].html;
  150. if (origin[0].contentType === "json" && origin[0].content) {
  151. const wbw = JSON.parse(origin[0].content) as IWbw[];
  152. console.debug("wbw data", wbw);
  153. diffText = wbw
  154. .filter((value) => {
  155. if (value.style && value.style.value === "note") {
  156. return false;
  157. } else if (value.type && value.type.value === ".ctl.") {
  158. return false;
  159. } else {
  160. return true;
  161. }
  162. })
  163. .map(
  164. (item) =>
  165. `${item.word.value
  166. .replaceAll("{", "**")
  167. .replaceAll("}", "**")}`
  168. )
  169. .join(" ");
  170. }
  171. console.debug("origin", origin);
  172. }
  173. return (
  174. <SentCell
  175. value={item}
  176. key={id}
  177. isPr={false}
  178. diffText={diffText}
  179. showDiff={origin ? true : false}
  180. editMode={item.openInEditMode}
  181. onChange={(value: ISentence) => {
  182. console.debug("onChange", value);
  183. setSentData((origin) => {
  184. origin.forEach((value1, index, array) => {
  185. if (value1.id === value.id) {
  186. array[index] = value;
  187. }
  188. });
  189. return origin;
  190. });
  191. }}
  192. />
  193. );
  194. })}
  195. </div>
  196. );
  197. };
  198. export default SentCanReadWidget;