@spacecorexdev/core 0.0.2 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. package/package.json +20 -38
  2. package/public/cmaps/78-EUC-H.bcmap +0 -0
  3. package/public/cmaps/78-EUC-V.bcmap +0 -0
  4. package/public/cmaps/78-H.bcmap +0 -0
  5. package/public/cmaps/78-RKSJ-H.bcmap +0 -0
  6. package/public/cmaps/78-RKSJ-V.bcmap +0 -0
  7. package/public/cmaps/78-V.bcmap +0 -0
  8. package/public/cmaps/78ms-RKSJ-H.bcmap +0 -0
  9. package/public/cmaps/78ms-RKSJ-V.bcmap +0 -0
  10. package/public/cmaps/83pv-RKSJ-H.bcmap +0 -0
  11. package/public/cmaps/90ms-RKSJ-H.bcmap +0 -0
  12. package/public/cmaps/90ms-RKSJ-V.bcmap +0 -0
  13. package/public/cmaps/90msp-RKSJ-H.bcmap +0 -0
  14. package/public/cmaps/90msp-RKSJ-V.bcmap +0 -0
  15. package/public/cmaps/90pv-RKSJ-H.bcmap +0 -0
  16. package/public/cmaps/90pv-RKSJ-V.bcmap +0 -0
  17. package/public/cmaps/Add-H.bcmap +0 -0
  18. package/public/cmaps/Add-RKSJ-H.bcmap +0 -0
  19. package/public/cmaps/Add-RKSJ-V.bcmap +0 -0
  20. package/public/cmaps/Add-V.bcmap +0 -0
  21. package/public/cmaps/Adobe-CNS1-0.bcmap +0 -0
  22. package/public/cmaps/Adobe-CNS1-1.bcmap +0 -0
  23. package/public/cmaps/Adobe-CNS1-2.bcmap +0 -0
  24. package/public/cmaps/Adobe-CNS1-3.bcmap +0 -0
  25. package/public/cmaps/Adobe-CNS1-4.bcmap +0 -0
  26. package/public/cmaps/Adobe-CNS1-5.bcmap +0 -0
  27. package/public/cmaps/Adobe-CNS1-6.bcmap +0 -0
  28. package/public/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  29. package/public/cmaps/Adobe-GB1-0.bcmap +0 -0
  30. package/public/cmaps/Adobe-GB1-1.bcmap +0 -0
  31. package/public/cmaps/Adobe-GB1-2.bcmap +0 -0
  32. package/public/cmaps/Adobe-GB1-3.bcmap +0 -0
  33. package/public/cmaps/Adobe-GB1-4.bcmap +0 -0
  34. package/public/cmaps/Adobe-GB1-5.bcmap +0 -0
  35. package/public/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  36. package/public/cmaps/Adobe-Japan1-0.bcmap +0 -0
  37. package/public/cmaps/Adobe-Japan1-1.bcmap +0 -0
  38. package/public/cmaps/Adobe-Japan1-2.bcmap +0 -0
  39. package/public/cmaps/Adobe-Japan1-3.bcmap +0 -0
  40. package/public/cmaps/Adobe-Japan1-4.bcmap +0 -0
  41. package/public/cmaps/Adobe-Japan1-5.bcmap +0 -0
  42. package/public/cmaps/Adobe-Japan1-6.bcmap +0 -0
  43. package/public/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  44. package/public/cmaps/Adobe-Korea1-0.bcmap +0 -0
  45. package/public/cmaps/Adobe-Korea1-1.bcmap +0 -0
  46. package/public/cmaps/Adobe-Korea1-2.bcmap +0 -0
  47. package/public/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  48. package/public/cmaps/B5-H.bcmap +0 -0
  49. package/public/cmaps/B5-V.bcmap +0 -0
  50. package/public/cmaps/B5pc-H.bcmap +0 -0
  51. package/public/cmaps/B5pc-V.bcmap +0 -0
  52. package/public/cmaps/CNS-EUC-H.bcmap +0 -0
  53. package/public/cmaps/CNS-EUC-V.bcmap +0 -0
  54. package/public/cmaps/CNS1-H.bcmap +0 -0
  55. package/public/cmaps/CNS1-V.bcmap +0 -0
  56. package/public/cmaps/CNS2-H.bcmap +0 -0
  57. package/public/cmaps/CNS2-V.bcmap +3 -0
  58. package/public/cmaps/ETHK-B5-H.bcmap +0 -0
  59. package/public/cmaps/ETHK-B5-V.bcmap +0 -0
  60. package/public/cmaps/ETen-B5-H.bcmap +0 -0
  61. package/public/cmaps/ETen-B5-V.bcmap +0 -0
  62. package/public/cmaps/ETenms-B5-H.bcmap +3 -0
  63. package/public/cmaps/ETenms-B5-V.bcmap +0 -0
  64. package/public/cmaps/EUC-H.bcmap +0 -0
  65. package/public/cmaps/EUC-V.bcmap +0 -0
  66. package/public/cmaps/Ext-H.bcmap +0 -0
  67. package/public/cmaps/Ext-RKSJ-H.bcmap +0 -0
  68. package/public/cmaps/Ext-RKSJ-V.bcmap +0 -0
  69. package/public/cmaps/Ext-V.bcmap +0 -0
  70. package/public/cmaps/GB-EUC-H.bcmap +0 -0
  71. package/public/cmaps/GB-EUC-V.bcmap +0 -0
  72. package/public/cmaps/GB-H.bcmap +4 -0
  73. package/public/cmaps/GB-V.bcmap +0 -0
  74. package/public/cmaps/GBK-EUC-H.bcmap +0 -0
  75. package/public/cmaps/GBK-EUC-V.bcmap +0 -0
  76. package/public/cmaps/GBK2K-H.bcmap +0 -0
  77. package/public/cmaps/GBK2K-V.bcmap +0 -0
  78. package/public/cmaps/GBKp-EUC-H.bcmap +0 -0
  79. package/public/cmaps/GBKp-EUC-V.bcmap +0 -0
  80. package/public/cmaps/GBT-EUC-H.bcmap +0 -0
  81. package/public/cmaps/GBT-EUC-V.bcmap +0 -0
  82. package/public/cmaps/GBT-H.bcmap +0 -0
  83. package/public/cmaps/GBT-V.bcmap +0 -0
  84. package/public/cmaps/GBTpc-EUC-H.bcmap +0 -0
  85. package/public/cmaps/GBTpc-EUC-V.bcmap +0 -0
  86. package/public/cmaps/GBpc-EUC-H.bcmap +0 -0
  87. package/public/cmaps/GBpc-EUC-V.bcmap +0 -0
  88. package/public/cmaps/H.bcmap +0 -0
  89. package/public/cmaps/HKdla-B5-H.bcmap +0 -0
  90. package/public/cmaps/HKdla-B5-V.bcmap +0 -0
  91. package/public/cmaps/HKdlb-B5-H.bcmap +0 -0
  92. package/public/cmaps/HKdlb-B5-V.bcmap +0 -0
  93. package/public/cmaps/HKgccs-B5-H.bcmap +0 -0
  94. package/public/cmaps/HKgccs-B5-V.bcmap +0 -0
  95. package/public/cmaps/HKm314-B5-H.bcmap +0 -0
  96. package/public/cmaps/HKm314-B5-V.bcmap +0 -0
  97. package/public/cmaps/HKm471-B5-H.bcmap +0 -0
  98. package/public/cmaps/HKm471-B5-V.bcmap +0 -0
  99. package/public/cmaps/HKscs-B5-H.bcmap +0 -0
  100. package/public/cmaps/HKscs-B5-V.bcmap +0 -0
  101. package/public/cmaps/Hankaku.bcmap +0 -0
  102. package/public/cmaps/Hiragana.bcmap +0 -0
  103. package/public/cmaps/KSC-EUC-H.bcmap +0 -0
  104. package/public/cmaps/KSC-EUC-V.bcmap +0 -0
  105. package/public/cmaps/KSC-H.bcmap +0 -0
  106. package/public/cmaps/KSC-Johab-H.bcmap +0 -0
  107. package/public/cmaps/KSC-Johab-V.bcmap +0 -0
  108. package/public/cmaps/KSC-V.bcmap +0 -0
  109. package/public/cmaps/KSCms-UHC-H.bcmap +0 -0
  110. package/public/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  111. package/public/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  112. package/public/cmaps/KSCms-UHC-V.bcmap +0 -0
  113. package/public/cmaps/KSCpc-EUC-H.bcmap +0 -0
  114. package/public/cmaps/KSCpc-EUC-V.bcmap +0 -0
  115. package/public/cmaps/Katakana.bcmap +0 -0
  116. package/public/cmaps/LICENSE +36 -0
  117. package/public/cmaps/NWP-H.bcmap +0 -0
  118. package/public/cmaps/NWP-V.bcmap +0 -0
  119. package/public/cmaps/RKSJ-H.bcmap +0 -0
  120. package/public/cmaps/RKSJ-V.bcmap +0 -0
  121. package/public/cmaps/Roman.bcmap +0 -0
  122. package/public/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  123. package/public/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  124. package/public/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  125. package/public/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  126. package/public/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  127. package/public/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  128. package/public/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  129. package/public/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  130. package/public/cmaps/UniGB-UCS2-H.bcmap +0 -0
  131. package/public/cmaps/UniGB-UCS2-V.bcmap +0 -0
  132. package/public/cmaps/UniGB-UTF16-H.bcmap +0 -0
  133. package/public/cmaps/UniGB-UTF16-V.bcmap +0 -0
  134. package/public/cmaps/UniGB-UTF32-H.bcmap +0 -0
  135. package/public/cmaps/UniGB-UTF32-V.bcmap +0 -0
  136. package/public/cmaps/UniGB-UTF8-H.bcmap +0 -0
  137. package/public/cmaps/UniGB-UTF8-V.bcmap +0 -0
  138. package/public/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  139. package/public/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  140. package/public/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  141. package/public/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  142. package/public/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  143. package/public/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  144. package/public/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  145. package/public/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  146. package/public/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  147. package/public/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  148. package/public/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  149. package/public/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  150. package/public/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  151. package/public/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  152. package/public/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  153. package/public/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  154. package/public/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  155. package/public/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  156. package/public/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  157. package/public/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  158. package/public/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  159. package/public/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  160. package/public/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  161. package/public/cmaps/UniKS-UCS2-H.bcmap +0 -0
  162. package/public/cmaps/UniKS-UCS2-V.bcmap +0 -0
  163. package/public/cmaps/UniKS-UTF16-H.bcmap +0 -0
  164. package/public/cmaps/UniKS-UTF16-V.bcmap +0 -0
  165. package/public/cmaps/UniKS-UTF32-H.bcmap +0 -0
  166. package/public/cmaps/UniKS-UTF32-V.bcmap +0 -0
  167. package/public/cmaps/UniKS-UTF8-H.bcmap +0 -0
  168. package/public/cmaps/UniKS-UTF8-V.bcmap +0 -0
  169. package/public/cmaps/V.bcmap +0 -0
  170. package/public/cmaps/WP-Symbol.bcmap +0 -0
  171. package/public/polyfills/polyfills.js +802 -0
  172. package/public/vendor/docx/docx.worker.js +5 -0
  173. package/public/vendor/docx/jszip.min.js +13 -0
  174. package/public/vendor/libarchive/libarchive.wasm +0 -0
  175. package/public/vendor/libarchive/worker-bundle.js +6 -0
  176. package/public/vendor/pptx/pptx.worker.js +26 -0
  177. package/public/wasm/cad/0.8.2/dwfv-render.wasm +0 -0
  178. package/public/wasm/cad/0.8.2/dwg-worker.js +24 -0
  179. package/public/wasm/cad/0.8.2/dwg-worker.js.map +1 -0
  180. package/public/wasm/cad/0.8.2/libredwg-web.js +2 -0
  181. package/public/wasm/cad/0.8.2/libredwg-web.wasm +0 -0
  182. package/public/wasm/cad/dwfv-render.wasm +0 -0
  183. package/public/wasm/cad/dwg-worker.js +24 -0
  184. package/public/wasm/cad/dwg-worker.js.map +1 -0
  185. package/public/wasm/cad/libredwg-web.js +2 -0
  186. package/public/wasm/cad/libredwg-web.wasm +0 -0
  187. package/public/wasm/data/sql-wasm.wasm +0 -0
  188. package/public/wasm/hdiff.wasm +0 -0
  189. package/public/wasm/model/LICENSE.occt-import-js.txt +504 -0
  190. package/public/wasm/model/LICENSE.occt.txt +502 -0
  191. package/public/wasm/model/occt-import-js.js +19 -0
  192. package/public/wasm/model/occt-import-js.wasm +0 -0
  193. package/public/wasm/model/occt-worker.js +83 -0
  194. package/public/wasm/typst/fonts/DejaVuSansMono-Bold.ttf +0 -0
  195. package/public/wasm/typst/fonts/DejaVuSansMono-BoldOblique.ttf +0 -0
  196. package/public/wasm/typst/fonts/DejaVuSansMono-Oblique.ttf +0 -0
  197. package/public/wasm/typst/fonts/DejaVuSansMono.ttf +0 -0
  198. package/public/wasm/typst/fonts/LibertinusSerif-Bold.otf +0 -0
  199. package/public/wasm/typst/fonts/LibertinusSerif-BoldItalic.otf +0 -0
  200. package/public/wasm/typst/fonts/LibertinusSerif-Italic.otf +0 -0
  201. package/public/wasm/typst/fonts/LibertinusSerif-Regular.otf +0 -0
  202. package/public/wasm/typst/fonts/LibertinusSerif-Semibold.otf +0 -0
  203. package/public/wasm/typst/fonts/LibertinusSerif-SemiboldItalic.otf +0 -0
  204. package/public/wasm/typst/fonts/NewCM10-Bold.otf +0 -0
  205. package/public/wasm/typst/fonts/NewCM10-BoldItalic.otf +0 -0
  206. package/public/wasm/typst/fonts/NewCM10-Italic.otf +0 -0
  207. package/public/wasm/typst/fonts/NewCM10-Regular.otf +0 -0
  208. package/public/wasm/typst/fonts/NewCMMath-Bold.otf +0 -0
  209. package/public/wasm/typst/fonts/NewCMMath-Book.otf +0 -0
  210. package/public/wasm/typst/fonts/NewCMMath-Regular.otf +0 -0
  211. package/public/wasm/typst/fonts/README.md +7 -0
  212. package/public/wasm/typst/typst_ts_renderer_bg.wasm +0 -0
  213. package/public/wasm/typst/typst_ts_web_compiler_bg.wasm +0 -0
  214. package/scripts/patch-docx-grid.cjs +412 -0
  215. package/src/api/_base.ts +243 -0
  216. package/src/api/index.ts +17 -0
  217. package/src/api/project.ts +1345 -0
  218. package/src/api/user.ts +1174 -0
  219. package/src/contract.ts +50 -0
  220. package/src/hooks/index.ts +2 -0
  221. package/{dist/hooks/index.js → src/hooks/useLongPress.ts} +53 -49
  222. package/src/hooks/useOnlineStatus.ts +22 -0
  223. package/src/index.ts +14 -0
  224. package/src/types/id.ts +2 -0
  225. package/src/types/index.ts +5 -0
  226. package/src/types/project/base.ts +63 -0
  227. package/src/types/project/contract.ts +79 -0
  228. package/src/types/project/contractStatus.tsx +15 -0
  229. package/src/types/project/index.ts +5 -0
  230. package/src/types/project/member.ts +46 -0
  231. package/src/types/project/progress.ts +43 -0
  232. package/src/types/projectRole.ts +17 -0
  233. package/src/types/theme.ts +1 -0
  234. package/src/types/user/index.ts +1 -0
  235. package/src/types/user/role.ts +7 -0
  236. package/src/ui/CommentTimeline/index.tsx +330 -0
  237. package/src/ui/FileManager/FileContextMenu.tsx +628 -0
  238. package/src/ui/FileManager/FileGridView.tsx +529 -0
  239. package/src/ui/FileManager/FileTableView.tsx +405 -0
  240. package/src/ui/FileManager/FileToolbar.tsx +119 -0
  241. package/src/ui/FileManager/FileVersionHistoryModal.tsx +175 -0
  242. package/src/ui/FileManager/MoveCopyToProjectModal.tsx +119 -0
  243. package/src/ui/FileManager/ShareToWechatModal.tsx +419 -0
  244. package/src/ui/FileManager/hooks/useFileManagerActions.ts +2532 -0
  245. package/src/ui/FileManager/hooks/useFileManagerState.ts +419 -0
  246. package/src/ui/FileManager/index.tsx +580 -0
  247. package/src/ui/FileManager/projectFileManagerApi.ts +57 -0
  248. package/src/ui/FileManager/types.ts +184 -0
  249. package/src/ui/FileManager/utils/fileDeltaWorker.ts +193 -0
  250. package/src/ui/FileManager/utils/fileTree.ts +178 -0
  251. package/src/ui/FileManager/utils/fileUpload.ts +714 -0
  252. package/src/ui/FileManager/utils/fileUtils.ts +65 -0
  253. package/src/ui/InvoiceRecordsList/index.tsx +813 -0
  254. package/src/ui/MyFileSelectorModal.tsx +261 -0
  255. package/src/ui/ProjectSelector/index.tsx +472 -0
  256. package/src/ui/ProjectSelector/projectCache.ts +40 -0
  257. package/src/ui/RoleSelector/index.tsx +473 -0
  258. package/src/ui/RoleSelector/roleCache.ts +40 -0
  259. package/src/ui/UIAlert.tsx +399 -0
  260. package/src/ui/UIAlertExample.tsx +129 -0
  261. package/src/ui/UIConfirm.tsx +335 -0
  262. package/src/ui/UIConfirmExample.tsx +165 -0
  263. package/src/ui/UIDatePicker.tsx +146 -0
  264. package/src/ui/UIDateRangePicker.tsx +38 -0
  265. package/src/ui/UIFilePreview/ExcelEditor/index.tsx +617 -0
  266. package/src/ui/UIFilePreview/ExcelEditor/types.ts +24 -0
  267. package/src/ui/UIFilePreview/ExportDropdown.css +85 -0
  268. package/src/ui/UIFilePreview/ExportDropdown.tsx +109 -0
  269. package/src/ui/UIFilePreview/IndexedDBUtils.ts +564 -0
  270. package/src/ui/UIFilePreview/MarkdownEditor/exportMarkdownPdf.ts +576 -0
  271. package/src/ui/UIFilePreview/MarkdownEditor/index.tsx +677 -0
  272. package/src/ui/UIFilePreview/MarkdownEditor/markdownEditor.css +1005 -0
  273. package/src/ui/UIFilePreview/MarkdownEditor/types.ts +15 -0
  274. package/src/ui/UIFilePreview/PPTXEditor/index.tsx +602 -0
  275. package/src/ui/UIFilePreview/RichDocEditor/exportRDocMarkdown.ts +77 -0
  276. package/src/ui/UIFilePreview/RichDocEditor/exportRDocPdf.ts +374 -0
  277. package/src/ui/UIFilePreview/RichDocEditor/index.tsx +730 -0
  278. package/src/ui/UIFilePreview/RichDocEditor/richdoc-editor.css +59 -0
  279. package/src/ui/UIFilePreview/UIFilePreview.tsx +611 -0
  280. package/src/ui/UIFilePreview/WordEditor/index.tsx +3933 -0
  281. package/src/ui/UIFilePreview/WordEditor/style.ts +1213 -0
  282. package/src/ui/UIFilePreview/WordEditor/word-editor.css +999 -0
  283. package/src/ui/UIFilePreview/filePreview.css +193 -0
  284. package/src/ui/UIFilePreview/filetypes/archive.tsx +66 -0
  285. package/src/ui/UIFilePreview/filetypes/cad.tsx +287 -0
  286. package/src/ui/UIFilePreview/filetypes/excel.tsx +355 -0
  287. package/src/ui/UIFilePreview/filetypes/image.tsx +20 -0
  288. package/src/ui/UIFilePreview/filetypes/imageLoader.ts +63 -0
  289. package/src/ui/UIFilePreview/filetypes/pdf.tsx +156 -0
  290. package/src/ui/UIFilePreview/filetypes/ppt.tsx +535 -0
  291. package/src/ui/UIFilePreview/filetypes/pptExportPdf.ts +523 -0
  292. package/src/ui/UIFilePreview/filetypes/video.tsx +482 -0
  293. package/src/ui/UIFilePreview/filetypes/word.tsx +245 -0
  294. package/src/ui/UIFilePreview/filetypes/wordExportMarkdown.ts +86 -0
  295. package/src/ui/UIFilePreview/filetypes/wordExportPdf.tsx +427 -0
  296. package/src/ui/UIFilePreview/index.ts +35 -0
  297. package/src/ui/UIFilePreview/pdfPagination.ts +143 -0
  298. package/src/ui/UIFilePreview/previewUtils.tsx +531 -0
  299. package/src/ui/UIFileUpload.tsx +382 -0
  300. package/src/ui/UIImageUpload.tsx +195 -0
  301. package/src/ui/UILoading.tsx +255 -0
  302. package/src/ui/UILoadingExample.tsx +139 -0
  303. package/src/ui/UISelect.tsx +105 -0
  304. package/src/ui/UIToast.tsx +381 -0
  305. package/src/ui/UIToastExample.tsx +69 -0
  306. package/src/ui/UIToastSingle.tsx +279 -0
  307. package/src/ui/UIViewToggle.tsx +64 -0
  308. package/src/ui/UserSelector/index.tsx +583 -0
  309. package/src/ui/index.ts +84 -0
  310. package/src/ui/upload/image.ts +135 -0
  311. package/src/ui/upload/index.ts +73 -0
  312. package/src/ui/upload/submitFile.ts +106 -0
  313. package/src/ui/upload/submitForm.ts +124 -0
  314. package/src/ui/upload/upload.err.ts +15 -0
  315. package/src/ui/upload/upload.ts +250 -0
  316. package/src/utils/CacheDepartmentInfo.ts +372 -0
  317. package/src/utils/CacheFileContent.ts +315 -0
  318. package/src/utils/CachePermissionInfo.ts +235 -0
  319. package/src/utils/CacheRoleInfo.ts +303 -0
  320. package/src/utils/CacheUserInfo.ts +818 -0
  321. package/src/utils/CacheViewToggleInfo.ts +182 -0
  322. package/src/utils/MessageContentUtils.ts +268 -0
  323. package/src/utils/clipboard.ts +70 -0
  324. package/src/utils/companyEmail.ts +19 -0
  325. package/src/utils/forbidDebugger.ts +59 -0
  326. package/src/utils/formatters.ts +94 -0
  327. package/src/utils/htmlUtils.tsx +59 -0
  328. package/src/utils/index.ts +18 -0
  329. package/src/utils/keyboard.ts +114 -0
  330. package/src/utils/mammothApi.ts +16 -0
  331. package/src/utils/polyfills.ts +928 -0
  332. package/src/utils/regex.ts +14 -0
  333. package/src/utils/storage.ts +95 -0
  334. package/src/utils/workerBootstrap.ts +87 -0
  335. package/dist/api/index.js +0 -1553
  336. package/dist/contract.js +0 -5
  337. package/dist/index.js +0 -4492
  338. package/dist/types/index.js +0 -49
  339. package/dist/ui/index.css +0 -1876
  340. package/dist/ui/index.js +0 -22245
  341. package/dist/utils/index.js +0 -4296
  342. /package/{dist → src}/styles/ant-modal.css +0 -0
  343. /package/{dist → src}/styles/ant-spin.css +0 -0
  344. /package/{dist → src}/styles/ant-table.css +0 -0
  345. /package/{dist → src}/styles/index.css +0 -0
@@ -0,0 +1,677 @@
1
+ import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
2
+ import SimpleMDE from 'react-simplemde-editor';
3
+ import 'easymde/dist/easymde.min.css';
4
+ import './markdownEditor.css';
5
+ import EasyMDE from 'easymde';
6
+ import { Button, Modal, Space, message, Popconfirm, Tag } from 'antd';
7
+ import { SaveOutlined, FileMarkdownFilled, UploadOutlined, CloseOutlined, CloudOutlined, CloudServerOutlined } from '@ant-design/icons';
8
+ import { saveFile, loadFile, deleteFile } from '../IndexedDBUtils';
9
+ import { CacheUserInfo } from '../../../utils/CacheUserInfo';
10
+ import uiConfirm from '../../UIConfirm';
11
+ import { exportMarkdownPdf } from './exportMarkdownPdf';
12
+ import { ExportDropdown } from '../ExportDropdown';
13
+ import { downloadBlob } from '../previewUtils';
14
+
15
+ export interface MarkdownEditorProps {
16
+ value?: string;
17
+ hiddenClose?: boolean;
18
+ visible?: boolean;
19
+ isCreate?: boolean; // 是否为新建模式
20
+ onClose?: () => void;
21
+ onSaveLocal?: (value: string) => void;
22
+ onChange?: (value: string) => void;
23
+ fileName?: string;
24
+ onUpload?: (oldValue:string, value: string, fileName: string) => Promise<void>;
25
+ placeholder?: string;
26
+ readOnly?: boolean;
27
+ allowFullscreen?: boolean;
28
+ defaultPreviewMode?: boolean;
29
+ /** 是否显示「导出PDF」按钮,默认显示 */
30
+ showExportPdf?: boolean;
31
+ /**
32
+ * 不适用本地缓存方式,如果为true,也不会出现上传按钮;
33
+ * true:不会使用modal方式展示.
34
+ */
35
+ noLocalCache?: boolean;
36
+ uploadPercent?: number;
37
+ uploadSuccess?: boolean|undefined; // 上传成功.
38
+ // ---- 新增:本地文件 / 离线模式支持 ----
39
+ isOffline?: boolean;
40
+ isLocalOnly?: boolean;
41
+ hasUnsyncedChanges?: boolean;
42
+ onSaveLocalMarkdown?: (content: string, fileName: string, markUnsynced?: boolean) => Promise<void>;
43
+ }
44
+ function mde_toggleSideBySide(editor:any) {
45
+ let cm = editor.codemirror;
46
+ let wrapper = cm.getWrapperElement();
47
+ let preview = wrapper.nextSibling;
48
+ let toolbarButton = editor.toolbarElements && editor.toolbarElements['side-by-side'];
49
+ let useSideBySideListener = false;
50
+
51
+ let easyMDEContainer = wrapper.parentNode;
52
+
53
+ if (preview.classList.contains('editor-preview-active-side')) {
54
+ if (editor.options.sideBySideFullscreen === false) {
55
+ // if side-by-side not-fullscreen ok, remove classes when hiding side
56
+ easyMDEContainer.classList.remove('sided--no-fullscreen');
57
+ }
58
+ preview.classList.remove('editor-preview-active-side');
59
+ if (toolbarButton) toolbarButton.classList.remove('active');
60
+ wrapper.classList.remove('CodeMirror-sided');
61
+ } else {
62
+ // When the preview button is clicked for the first time,
63
+ // give some time for the transition from editor.css to fire and the view to slide from right to left,
64
+ // instead of just appearing.
65
+ setTimeout(function () {
66
+ preview.classList.add('editor-preview-active-side');
67
+ }, 1);
68
+ if (toolbarButton) toolbarButton.classList.add('active');
69
+ wrapper.classList.add('CodeMirror-sided');
70
+ useSideBySideListener = true;
71
+ }
72
+
73
+ // Hide normal preview if active
74
+ let previewNormal = wrapper.lastChild;
75
+ if (previewNormal.classList.contains('editor-preview-active')) {
76
+ previewNormal.classList.remove('editor-preview-active');
77
+ let toolbar = editor.toolbarElements.preview;
78
+ let toolbar_div = editor.toolbar_div;
79
+ toolbar.classList.remove('active');
80
+ toolbar_div.classList.remove('disabled-for-preview');
81
+ }
82
+
83
+ let sideBySideRenderingFunction = function () {
84
+ let newValue = editor.options.previewRender(editor.value(), preview);
85
+ if (newValue != null) {
86
+ preview.innerHTML = newValue;
87
+ }
88
+ };
89
+
90
+ if (!cm.sideBySideRenderingFunction) {
91
+ cm.sideBySideRenderingFunction = sideBySideRenderingFunction;
92
+ }
93
+
94
+ if (useSideBySideListener) {
95
+ let newValue = editor.options.previewRender(editor.value(), preview);
96
+ if (newValue != null) {
97
+ preview.innerHTML = newValue;
98
+ }
99
+ cm.on('update', cm.sideBySideRenderingFunction);
100
+ } else {
101
+ cm.off('update', cm.sideBySideRenderingFunction);
102
+ }
103
+
104
+ // Refresh to fix selection being off (#309)
105
+ cm.refresh();
106
+ }
107
+
108
+ function mde_setPreview(editor: any) {
109
+ let cm = editor.codemirror;
110
+ let wrapper = cm.getWrapperElement();
111
+ let toolbar_div = editor.toolbar_div;
112
+ let toolbar = editor.options.toolbar ? editor.toolbarElements.preview : false;
113
+ let preview = wrapper.lastChild;
114
+
115
+ // Turn off side by side if needed
116
+ let sidebyside = cm.getWrapperElement().nextSibling;
117
+ if (sidebyside && sidebyside.classList.contains('editor-preview-active-side'))
118
+ mde_toggleSideBySide(editor);
119
+
120
+ if (!preview || !preview.classList.contains('editor-preview-full')) {
121
+
122
+ preview = document.createElement('div');
123
+ preview.className = 'editor-preview-full';
124
+
125
+ if (editor.options.previewClass) {
126
+
127
+ if (Array.isArray(editor.options.previewClass)) {
128
+ for (let i = 0; i < editor.options.previewClass.length; i++) {
129
+ preview.classList.add(editor.options.previewClass[i]);
130
+ }
131
+
132
+ } else if (typeof editor.options.previewClass === 'string') {
133
+ preview.classList.add(editor.options.previewClass);
134
+ }
135
+ }
136
+
137
+ wrapper.appendChild(preview);
138
+ }
139
+
140
+ if (preview.classList.contains('editor-preview-active')) {
141
+ return true;
142
+ } else {
143
+ // When the preview button is clicked for the first time,
144
+ // give some time for the transition from editor.css to fire and the view to slide from right to left,
145
+ // instead of just appearing.
146
+ setTimeout(function () {
147
+ preview.classList.add('editor-preview-active');
148
+ }, 1);
149
+ if (toolbar) {
150
+ toolbar.classList.add('active');
151
+ toolbar_div.classList.add('disabled-for-preview');
152
+ }
153
+ }
154
+
155
+ let preview_result = editor.options.previewRender(editor.value(), preview);
156
+ if (preview_result !== null) {
157
+ preview.innerHTML = preview_result;
158
+ return true;
159
+ }
160
+ else {
161
+ return false;
162
+ }
163
+
164
+ }
165
+
166
+ const MarkdownEditor: React.FC<MarkdownEditorProps> = ({
167
+ hiddenClose = false,
168
+ value = '',
169
+ visible,
170
+ isCreate,
171
+ onClose,
172
+ fileName = 'document.md',
173
+ onUpload,
174
+ onSaveLocal,
175
+ onChange,
176
+ placeholder = '请输入Markdown内容...',
177
+ readOnly = false,
178
+ allowFullscreen = true,
179
+ defaultPreviewMode = true,
180
+ showExportPdf = true,
181
+ noLocalCache = false,
182
+ uploadPercent,
183
+ isOffline,
184
+ isLocalOnly,
185
+ hasUnsyncedChanges,
186
+ onSaveLocalMarkdown,
187
+ }) => {
188
+ const [content, setContent] = useState(value);
189
+ const [userId, setUserId] = useState<string | null>(null);
190
+ const [editorKey, setEditorKey] = useState(0);
191
+ const [hasLocalCache, setHasLocalCache] = useState(false);
192
+ const [hasUploaded, setHasUploaded] = useState(!isCreate);
193
+ const [exporting, setExporting] = useState(false);
194
+ const markdownInstanceRef = useRef<EasyMDE | null>(null);
195
+ const saveTimerRef = useRef<NodeJS.Timeout | null>(null);
196
+ // 跟踪"标记为未同步"的调用是否已在本次编辑会话中执行过,避免每次 onChange 都写 IndexedDB
197
+ const markUnsyncedTriggeredRef = useRef(false);
198
+ // 用 ref 跟踪当前内容,用于在 handleContentChange 中判断内容是否真的变化
199
+ // 避免 EasyMDE 初始化等场景触发 onChange 但内容未变时误标记"未同步"
200
+ const contentRef = useRef(value);
201
+ contentRef.current = content;
202
+
203
+ // 跟踪当前差分上传的基准内容(即服务器上最新的文件内容)。
204
+ // 上传成功后会更新为本次上传的内容,确保下次差分基准与服务器一致。
205
+ // 与 Word/Excel/PPTX 的 baseBlobRef 行为对齐。
206
+ const baseContentRef = useRef(value);
207
+
208
+ // 用 ref 跟踪这些"状态标记"属性,避免它们的变化(如保存/上传后更新标记)
209
+ // 触发编辑器相关 useCallback 重新创建,导致画面闪动。
210
+ const hasUnsyncedChangesRef = useRef(hasUnsyncedChanges);
211
+ const onSaveLocalMarkdownRef = useRef(onSaveLocalMarkdown);
212
+ hasUnsyncedChangesRef.current = hasUnsyncedChanges;
213
+ onSaveLocalMarkdownRef.current = onSaveLocalMarkdown;
214
+
215
+ // 获取当前登录用户
216
+ useEffect(() => {
217
+ if (visible && !noLocalCache) {
218
+ const getUserId = async () => {
219
+ try {
220
+ const userInfo = CacheUserInfo.currentLocalUser();
221
+ if (userInfo?.id) {
222
+ setUserId(userInfo.id);
223
+ } else {
224
+ setUserId(null);
225
+ }
226
+ } catch (error) {
227
+ console.error('获取用户信息失败:', error);
228
+ setUserId(null);
229
+ }
230
+ };
231
+ getUserId();
232
+ }
233
+ }, [visible, noLocalCache]);
234
+
235
+
236
+ // 加载本地缓存的文件
237
+ useEffect(() => {
238
+ if (noLocalCache) {
239
+ setContent(value);
240
+ return;
241
+ }
242
+
243
+ if (visible && userId) {
244
+ // 如果有传入的 value 且不为空,优先使用 value
245
+ if (value) {
246
+ // 需求3:彻底移除旧缓存检查。既然有了 value,直接加载
247
+ setContent(value);
248
+ setEditorKey((prev) => prev + 1);
249
+ setHasLocalCache(false);
250
+ } else if (isCreate && fileName) {
251
+ // 需求3:新建模式下不再自动检查/加载旧的本地缓存
252
+ setContent(value);
253
+ setHasLocalCache(false);
254
+ }
255
+ } else if (visible && fileName && !userId) {
256
+ setContent(value);
257
+ setHasLocalCache(false);
258
+ }
259
+ }, [visible, fileName, userId, value, isCreate, noLocalCache, readOnly]);
260
+
261
+ // value 变化时(文件切换/加载)重置差分基准
262
+ useEffect(() => {
263
+ baseContentRef.current = value;
264
+ }, [value]);
265
+
266
+ // 初始化时切换到预览模式
267
+ useEffect(() => {
268
+ if (defaultPreviewMode && markdownInstanceRef.current) {
269
+ setTimeout(() => {
270
+ if (!mde_setPreview(markdownInstanceRef.current as EasyMDE)) {
271
+ setTimeout(() => {
272
+ mde_setPreview(markdownInstanceRef.current as EasyMDE);
273
+ }, 1000);
274
+ }
275
+ }, 100);
276
+ }
277
+ }, [defaultPreviewMode, editorKey]);
278
+
279
+ // 自动保存到 IndexedDB(防抖)+ 同步 localFiles store
280
+ const handleContentChange = useCallback((newContent: string) => {
281
+ // 内容未实际变化时跳过(如 EasyMDE 初始化触发 onChange)
282
+ if (newContent === contentRef.current) return;
283
+ setContent(newContent);
284
+ setHasUploaded(false);
285
+ onChange?.(newContent);
286
+
287
+ if (!fileName || !userId) return;
288
+
289
+ // 首次编辑(且 hasUnsyncedChanges 目前为 false)时,立即标记未同步。
290
+ // 上传成功后 hasUnsyncedChanges 被清除,用户继续编辑后应立即重新显示"有未同步修改"。
291
+ if (!markUnsyncedTriggeredRef.current && !hasUnsyncedChangesRef.current && onSaveLocalMarkdownRef.current) {
292
+ markUnsyncedTriggeredRef.current = true;
293
+ onSaveLocalMarkdownRef.current(newContent, fileName).catch(err => {
294
+ console.warn('编辑时立即标记未同步失败(不影响编辑,等待自动/手动保存即可):', err);
295
+ });
296
+ }
297
+
298
+ if (saveTimerRef.current) {
299
+ clearTimeout(saveTimerRef.current);
300
+ }
301
+
302
+ setHasLocalCache(true);
303
+
304
+ saveTimerRef.current = setTimeout(async () => {
305
+ try {
306
+ await saveFile(userId, fileName, 'md', newContent);
307
+ setHasLocalCache(false);
308
+ // 同步更新 localFiles store,确保自动保存也持久化到 localFiles
309
+ if (onSaveLocalMarkdownRef.current) {
310
+ try {
311
+ await onSaveLocalMarkdownRef.current(newContent, fileName, false);
312
+ } catch (err) {
313
+ console.warn('自动保存时同步 localFiles store 失败(不影响本地保存):', err);
314
+ }
315
+ }
316
+ } catch (error) {
317
+ console.error('自动保存到 IndexedDB 失败:', error);
318
+ }
319
+ }, 20000);
320
+ }, [fileName, userId]);
321
+
322
+ const modalEditorOptions = useMemo(() => ({
323
+ autoDownloadFontAwesome: true,
324
+ // 只读预览时不自动聚焦:autofocus 会让 CodeMirror 把初始光标(文档末尾)
325
+ // 滚动进可视区,导致打开文件时滚动条自动滚到最底部
326
+ autofocus: !readOnly,
327
+ spellChecker: false,
328
+ placeholder,
329
+ toolbar: readOnly ? [
330
+ 'guide',
331
+ ...(allowFullscreen ? ['side-by-side', 'fullscreen'] : []),
332
+ ] : [
333
+ 'bold',
334
+ 'italic',
335
+ 'strikethrough',
336
+ '|',
337
+ 'heading-1',
338
+ 'heading-2',
339
+ 'heading-3',
340
+ '|',
341
+ 'code',
342
+ 'quote',
343
+ 'table',
344
+ '|',
345
+ 'unordered-list',
346
+ 'ordered-list',
347
+ '|',
348
+ 'link',
349
+ 'image',
350
+ '|',
351
+ 'preview',
352
+ 'guide',
353
+ ...(allowFullscreen ? ['side-by-side', 'fullscreen'] : []),
354
+ ] as any[],
355
+ }), [allowFullscreen, placeholder, readOnly]);
356
+
357
+ const inlineEditorOptions = useMemo(() => ({
358
+ spellChecker: false,
359
+ placeholder,
360
+ toolbar: readOnly ? false : [
361
+ 'bold',
362
+ 'italic',
363
+ 'strikethrough',
364
+ '|',
365
+ 'heading-1',
366
+ 'heading-2',
367
+ 'heading-3',
368
+ '|',
369
+ 'code',
370
+ 'quote',
371
+ '|',
372
+ 'unordered-list',
373
+ 'ordered-list',
374
+ '|',
375
+ 'link',
376
+ 'image',
377
+ '|',
378
+ 'preview',
379
+ ...(allowFullscreen ? ['side-by-side', 'fullscreen'] : []),
380
+ ] as any[],
381
+ }), [allowFullscreen, placeholder, readOnly]);
382
+
383
+ // 保存到 IndexedDB
384
+ const handleSaveLocal = useCallback(async () => {
385
+ const newContent = (markdownInstanceRef.current as EasyMDE).value();
386
+ if (noLocalCache) {
387
+ onSaveLocal?.(newContent);
388
+ // 非缓存模式下,也同步到 localFiles store(如果提供了回调)
389
+ if (onSaveLocalMarkdownRef.current) {
390
+ try {
391
+ await onSaveLocalMarkdownRef.current(newContent, fileName);
392
+ } catch (err) {
393
+ console.warn('同步本地文件内容到 localFiles store 失败:', err);
394
+ }
395
+ }
396
+ return;
397
+ }
398
+ try {
399
+ if (!userId) {
400
+ message.error('无法获取用户信息');
401
+ return;
402
+ }
403
+
404
+ await saveFile(userId, fileName, 'md', newContent);
405
+ setHasLocalCache(false);
406
+
407
+ // 通知父组件更新 localFiles store
408
+ if (onSaveLocalMarkdownRef.current) {
409
+ try {
410
+ await onSaveLocalMarkdownRef.current(newContent, fileName);
411
+ } catch (err) {
412
+ console.warn('同步本地文件内容到 localFiles store 失败(不影响本地保存):', err);
413
+ }
414
+ }
415
+
416
+ message.success('已保存到本地缓存');
417
+ } catch (error) {
418
+ console.error('保存到本地缓存失败:', error);
419
+ message.error('保存失败');
420
+ }
421
+ }, [fileName, userId, noLocalCache, onSaveLocal]);
422
+
423
+ // 上传到服务器
424
+ const handleUpload = useCallback(async () => {
425
+ if (!onUpload) {
426
+ message.error('未提供上传功能');
427
+ return;
428
+ }
429
+ try {
430
+ const newContent = (markdownInstanceRef.current as EasyMDE).value();
431
+ // 使用 baseContentRef 作为差分基准,而非 value。
432
+ // 上传成功后 baseContentRef 会更新为本次上传的内容,确保下次差分基准与服务器一致。
433
+ const oldContent = baseContentRef.current;
434
+ await onUpload(oldContent, newContent, fileName);
435
+
436
+ // 上传成功后,更新差分基准为本次上传的内容,确保下次差分基准与服务器一致
437
+ baseContentRef.current = newContent;
438
+
439
+ // 上传成功后,清空本地缓存
440
+ if (userId) {
441
+ await deleteFile(userId, fileName, 'md');
442
+ setHasLocalCache(false);
443
+ setHasUploaded(true);
444
+ }
445
+ // 上传成功后重置"立即标记未同步"触发器,使后续编辑可再次立即触发
446
+ markUnsyncedTriggeredRef.current = false;
447
+ } catch (error) {
448
+ console.error('上传失败:', error);
449
+ message.error('上传失败');
450
+ }
451
+ }, [fileName, onUpload, userId]);
452
+
453
+ // 导出为 PDF(纯前端生成,不经过浏览器打印对话框)
454
+ const handleExportPdf = useCallback(async () => {
455
+ const instance = markdownInstanceRef.current;
456
+ const exportContent = instance ? instance.value() : contentRef.current;
457
+ if (!exportContent || !exportContent.trim()) {
458
+ message.warning('内容为空,无法导出 PDF');
459
+ return;
460
+ }
461
+ setExporting(true);
462
+ message.loading({ key: 'md-export-pdf', content: '正在生成 PDF...', duration: 0 });
463
+ try {
464
+ await exportMarkdownPdf({
465
+ content: exportContent,
466
+ fileName,
467
+ editor: instance,
468
+ onProgress: (page, total) => {
469
+ message.loading({
470
+ key: 'md-export-pdf',
471
+ content: `正在生成 PDF(${page}/${total} 页)...`,
472
+ duration: 0,
473
+ });
474
+ },
475
+ });
476
+ message.success({ key: 'md-export-pdf', content: 'PDF 已导出' });
477
+ } catch (error) {
478
+ console.error('导出 PDF 失败:', error);
479
+ message.error({
480
+ key: 'md-export-pdf',
481
+ content: (error as Error)?.message || '导出 PDF 失败',
482
+ });
483
+ } finally {
484
+ setExporting(false);
485
+ }
486
+ }, [fileName]);
487
+
488
+ // 下载原始文件:markdown 文本本身即文件内容
489
+ const handleDownload = useCallback(() => {
490
+ const instance = markdownInstanceRef.current;
491
+ const downloadContent = instance ? instance.value() : contentRef.current;
492
+ if (!downloadContent || !downloadContent.trim()) {
493
+ message.warning('内容为空,无法下载');
494
+ return;
495
+ }
496
+ downloadBlob(new Blob([downloadContent], { type: 'text/markdown;charset=utf-8' }), fileName);
497
+ }, [fileName]);
498
+ const onDownload = !isCreate || content.trim() ? handleDownload : undefined;
499
+
500
+ // Ctrl+S / Cmd+S 保存到本地缓存
501
+ useEffect(() => {
502
+ if (!visible) return;
503
+ const handleKeyDown = (e: KeyboardEvent) => {
504
+ if ((e.ctrlKey || e.metaKey) && e.key === 's') {
505
+ e.preventDefault();
506
+ handleSaveLocal();
507
+ }
508
+ };
509
+ window.addEventListener('keydown', handleKeyDown);
510
+ return () => window.removeEventListener('keydown', handleKeyDown);
511
+ }, [visible, handleSaveLocal]);
512
+
513
+ // 重置状态和清理定时器(当编辑器打开/关闭时)
514
+ useEffect(() => {
515
+ if (visible) {
516
+ setHasUploaded(!isCreate);
517
+ // 重置"立即标记未同步"触发器
518
+ markUnsyncedTriggeredRef.current = false;
519
+ // 清理之前的定时器
520
+ if (saveTimerRef.current) {
521
+ clearTimeout(saveTimerRef.current);
522
+ saveTimerRef.current = null;
523
+ }
524
+ }
525
+
526
+ // 组件卸载时清理定时器
527
+ return () => {
528
+ if (saveTimerRef.current) {
529
+ clearTimeout(saveTimerRef.current);
530
+ saveTimerRef.current = null;
531
+ }
532
+ };
533
+ }, [visible, isCreate]);
534
+
535
+ const getMdeInstance = useCallback((instance: EasyMDE) => {
536
+ markdownInstanceRef.current = instance;
537
+ if (defaultPreviewMode) {
538
+ setTimeout(() => {
539
+ if (!mde_setPreview(markdownInstanceRef.current as EasyMDE)) {
540
+ setTimeout(() => {
541
+ mde_setPreview(markdownInstanceRef.current as EasyMDE);
542
+ }, 1000);
543
+ }
544
+ }, 100);
545
+ }
546
+ }, [defaultPreviewMode]);
547
+
548
+ if (!noLocalCache) {
549
+ return (
550
+ <Modal
551
+ open={visible}
552
+ onCancel={onClose}
553
+ keyboard={false}
554
+ closeIcon={null}
555
+ footer={null}
556
+ width="100%"
557
+ style={{ top: 0, maxWidth: '100vw' }}
558
+ styles={{
559
+ body: {
560
+ height: '100dvh',
561
+ padding: 0,
562
+ },
563
+ }}
564
+ className="ant-modal-nopadding ant-modal-fullscreen relative"
565
+ transitionName='none'
566
+ >
567
+ <div className="h-full flex flex-col bg-white p-0 m-0">
568
+ <div className={`flex items-center justify-between px-4 py-2 pr-0 flex-shrink-0 ${isOffline ? 'bg-orange-50 border-b border-orange-200' : 'bg-gray-50 border-b border-gray-200'}`}>
569
+ <span>&nbsp;</span>
570
+ {!readOnly && <span>&nbsp;</span>}
571
+ <div className="flex items-center gap-2 flex-wrap min-w-[40%]">
572
+ {!isOffline && isLocalOnly && (
573
+ <Tag icon={<CloudOutlined />} color="orange" style={{ margin: 0 }}>
574
+ 本地文件
575
+ </Tag>
576
+ )}
577
+ {!isOffline && !isLocalOnly && hasUnsyncedChanges && (
578
+ <Tag icon={<CloudOutlined />} color="warning" style={{ margin: 0 }}>
579
+ 有未同步修改
580
+ </Tag>
581
+ )}
582
+ {!isOffline && !isLocalOnly && !hasUnsyncedChanges && !onUpload ? (
583
+ <Tag icon={<CloudServerOutlined />} color="default" style={{ margin: 0 }}>
584
+ 同步完成
585
+ </Tag>
586
+ ) : null}
587
+ <FileMarkdownFilled className="text-gray-800" />
588
+ <span className="text-sm font-medium">{hasLocalCache ? '*' : ''}{fileName}</span>
589
+ </div>
590
+ {!readOnly && !hiddenClose && (<Space wrap={true} align="center" direction="horizontal">
591
+ {/* <Button icon={<DeleteOutlined />} onClick={handleClearCache}>
592
+ 清除缓存
593
+ </Button> */}
594
+ <ExportDropdown
595
+ onExportPdf={showExportPdf ? handleExportPdf : undefined}
596
+ onDownload={onDownload}
597
+ exportingPdf={exporting}
598
+ buttonProps={{ style: { paddingLeft: 4, paddingRight: 4 } }}
599
+ />
600
+ {onUpload && (
601
+ <Button type="text" style={{ paddingLeft: 4, paddingRight: 4 }} title="每次上传将保留一个历史版本,最多保留10个版本" icon={<UploadOutlined />} onClick={handleUpload} disabled={uploadPercent !== undefined && uploadPercent < 100}>
602
+ {uploadPercent !== undefined && uploadPercent < 100 ? `上传中 ${Math.round(uploadPercent * 100)}%` : '上传'}
603
+ </Button>
604
+ )}
605
+ {!readOnly && (<Button type="primary" icon={<SaveOutlined />} disabled={readOnly} onClick={handleSaveLocal}>
606
+ 保存
607
+ </Button>)}
608
+ {(!readOnly && (hasLocalCache || !hasUploaded)) ?
609
+ (<Popconfirm
610
+ title="确定要退出吗?"
611
+ description={hasLocalCache?"修改未保存,确定要退出吗?": "修改未上传,确定要退出吗?"}
612
+ onConfirm={onClose}
613
+ okText="确定"
614
+ cancelText="取消"
615
+ >
616
+ <Button type="text" className="ml-3 mr-2 text-gray-600 hover:text-gray-900" icon={<CloseOutlined className="w-6 h-6" />} />
617
+ </Popconfirm>) : (<CloseOutlined onClick={onClose} className='ml-3 mr-2 w-6 h-6'/>)}
618
+ </Space>)}
619
+ {readOnly && !hiddenClose && (
620
+ <Space className='ml-3 mr-2'>
621
+ <ExportDropdown
622
+ onExportPdf={showExportPdf ? handleExportPdf : undefined}
623
+ onDownload={onDownload}
624
+ exportingPdf={exporting}
625
+ />
626
+ <CloseOutlined onClick={onClose} className='w-6 h-6'/>
627
+ </Space>)}
628
+ {hiddenClose && <span>&nbsp;</span>}
629
+ </div>
630
+
631
+ <div className="flex-1 overflow-y-auto h-full ineditor-toolbar">
632
+ <SimpleMDE
633
+ key={editorKey}
634
+ value={content}
635
+ onChange={handleContentChange}
636
+ options={modalEditorOptions}
637
+ getMdeInstance={getMdeInstance}
638
+ />
639
+ </div>
640
+ </div>
641
+ </Modal>
642
+ );
643
+ } else {
644
+ const showInlineHeader = showExportPdf || (!readOnly && onSaveLocal);
645
+ return (
646
+ <div className="h-full flex flex-col bg-white p-0 m-0 relative">
647
+ {showInlineHeader && (
648
+ <div className="flex items-center justify-end gap-2 px-0 py-2 flex-shrink-0">
649
+ <ExportDropdown
650
+ onExportPdf={showExportPdf ? handleExportPdf : undefined}
651
+ onDownload={onDownload}
652
+ exportingPdf={exporting}
653
+ />
654
+ {!readOnly && onSaveLocal && (
655
+ <Button type="primary" icon={<SaveOutlined />} onClick={handleSaveLocal}>
656
+ 保存
657
+ </Button>
658
+ )}
659
+ </div>
660
+ )}
661
+
662
+ <div className="flex-1 overflow-y-auto h-full">
663
+ <SimpleMDE
664
+ key={editorKey}
665
+ value={content}
666
+ onChange={handleContentChange}
667
+ options={inlineEditorOptions}
668
+ getMdeInstance={getMdeInstance}
669
+ />
670
+ </div>
671
+ </div>
672
+ );
673
+ }
674
+ };
675
+
676
+ export default MarkdownEditor;
677
+ export { MarkdownEditor };