SentCanRead.tsx 6.0 KB

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