cd-aichat 1.0.0

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 (356) hide show
  1. package/README.md +188 -0
  2. package/dist/ailogo.png +0 -0
  3. package/dist/cd-aichat.css +1 -0
  4. package/dist/cd-aichat.es.js +32223 -0
  5. package/dist/cd-aichat.umd.js +279 -0
  6. package/dist/index.css +1 -0
  7. package/package.json +61 -0
  8. package/src/ailogo.png +0 -0
  9. package/src/components/AiChat.test.js +538 -0
  10. package/src/components/AiChat.vue +2206 -0
  11. package/src/components/AiChatWidget.test.js +312 -0
  12. package/src/components/AiChatWidget.vue +963 -0
  13. package/src/components/BurnAfterReadDialog.test.js +121 -0
  14. package/src/components/BurnAfterReadDialog.vue +511 -0
  15. package/src/components/BurnAfterReadMessage.test.js +188 -0
  16. package/src/components/BurnAfterReadMessage.vue +193 -0
  17. package/src/components/BurnIndicator.test.js +101 -0
  18. package/src/components/BurnIndicator.vue +164 -0
  19. package/src/components/ChatWindow.vue +0 -0
  20. package/src/components/MentionList.vue +163 -0
  21. package/src/components/ResourceList.vue +194 -0
  22. package/src/components/RichTextEditor.vue +437 -0
  23. package/src/components/ScheduledSendDialog.vue +476 -0
  24. package/src/components/ScreenshotOverlay.vue +78 -0
  25. package/src/components/SendButtonGroup.test.js +174 -0
  26. package/src/components/SendButtonGroup.vue +166 -0
  27. package/src/components/UserDrawer.vue +0 -0
  28. package/src/components/screenshot/ScreenshotsBackground/getBoundsByPoints.ts +41 -0
  29. package/src/components/screenshot/ScreenshotsBackground/index.scss +27 -0
  30. package/src/components/screenshot/ScreenshotsBackground/index.tsx +145 -0
  31. package/src/components/screenshot/ScreenshotsButton/index.scss +29 -0
  32. package/src/components/screenshot/ScreenshotsButton/index.tsx +58 -0
  33. package/src/components/screenshot/ScreenshotsCanvas/getBoundsByPoints.ts +55 -0
  34. package/src/components/screenshot/ScreenshotsCanvas/getPoints.ts +60 -0
  35. package/src/components/screenshot/ScreenshotsCanvas/index.scss +84 -0
  36. package/src/components/screenshot/ScreenshotsCanvas/index.tsx +277 -0
  37. package/src/components/screenshot/ScreenshotsCanvas/isPointInDraw.ts +35 -0
  38. package/src/components/screenshot/ScreenshotsColor/index.scss +45 -0
  39. package/src/components/screenshot/ScreenshotsColor/index.tsx +39 -0
  40. package/src/components/screenshot/ScreenshotsContext.ts +56 -0
  41. package/src/components/screenshot/ScreenshotsMagnifier/index.scss +61 -0
  42. package/src/components/screenshot/ScreenshotsMagnifier/index.tsx +126 -0
  43. package/src/components/screenshot/ScreenshotsOperations/index.scss +25 -0
  44. package/src/components/screenshot/ScreenshotsOperations/index.tsx +118 -0
  45. package/src/components/screenshot/ScreenshotsOption/index.scss +50 -0
  46. package/src/components/screenshot/ScreenshotsOption/index.tsx +150 -0
  47. package/src/components/screenshot/ScreenshotsSize/index.scss +28 -0
  48. package/src/components/screenshot/ScreenshotsSize/index.tsx +41 -0
  49. package/src/components/screenshot/ScreenshotsSizeColor/index.scss +8 -0
  50. package/src/components/screenshot/ScreenshotsSizeColor/index.tsx +25 -0
  51. package/src/components/screenshot/ScreenshotsTextarea/calculateNodeSize.ts +117 -0
  52. package/src/components/screenshot/ScreenshotsTextarea/index.scss +19 -0
  53. package/src/components/screenshot/ScreenshotsTextarea/index.tsx +96 -0
  54. package/src/components/screenshot/composeImage.ts +57 -0
  55. package/src/components/screenshot/exports.ts +4 -0
  56. package/src/components/screenshot/hooks/useBounds.ts +35 -0
  57. package/src/components/screenshot/hooks/useCall.ts +17 -0
  58. package/src/components/screenshot/hooks/useCanvasContextRef.ts +8 -0
  59. package/src/components/screenshot/hooks/useCanvasMousedown.ts +13 -0
  60. package/src/components/screenshot/hooks/useCanvasMousemove.ts +13 -0
  61. package/src/components/screenshot/hooks/useCanvasMouseup.ts +13 -0
  62. package/src/components/screenshot/hooks/useCursor.ts +34 -0
  63. package/src/components/screenshot/hooks/useDispatcher.ts +8 -0
  64. package/src/components/screenshot/hooks/useDrawSelect.ts +16 -0
  65. package/src/components/screenshot/hooks/useEmiter.ts +61 -0
  66. package/src/components/screenshot/hooks/useHistory.ts +160 -0
  67. package/src/components/screenshot/hooks/useLang.ts +8 -0
  68. package/src/components/screenshot/hooks/useOperation.ts +37 -0
  69. package/src/components/screenshot/hooks/useReset.ts +26 -0
  70. package/src/components/screenshot/hooks/useStore.ts +8 -0
  71. package/src/components/screenshot/icons/iconfont.scss +88 -0
  72. package/src/components/screenshot/icons/iconfont.ttf +0 -0
  73. package/src/components/screenshot/icons/iconfont.woff +0 -0
  74. package/src/components/screenshot/icons/iconfont.woff2 +0 -0
  75. package/src/components/screenshot/index.tsx +169 -0
  76. package/src/components/screenshot/operations/Arrow/draw.ts +56 -0
  77. package/src/components/screenshot/operations/Arrow/index.tsx +193 -0
  78. package/src/components/screenshot/operations/Brush/draw.ts +45 -0
  79. package/src/components/screenshot/operations/Brush/index.tsx +169 -0
  80. package/src/components/screenshot/operations/Cancel/index.tsx +18 -0
  81. package/src/components/screenshot/operations/Ellipse/draw.ts +96 -0
  82. package/src/components/screenshot/operations/Ellipse/index.tsx +245 -0
  83. package/src/components/screenshot/operations/Mosaic/index.tsx +223 -0
  84. package/src/components/screenshot/operations/Ok/index.tsx +37 -0
  85. package/src/components/screenshot/operations/Pin/index.tsx +37 -0
  86. package/src/components/screenshot/operations/Rectangle/draw.ts +80 -0
  87. package/src/components/screenshot/operations/Rectangle/index.tsx +245 -0
  88. package/src/components/screenshot/operations/Redo/index.tsx +22 -0
  89. package/src/components/screenshot/operations/Save/index.tsx +37 -0
  90. package/src/components/screenshot/operations/Scan/index.tsx +46 -0
  91. package/src/components/screenshot/operations/Search/index.tsx +39 -0
  92. package/src/components/screenshot/operations/Text/index.tsx +307 -0
  93. package/src/components/screenshot/operations/Undo/index.tsx +22 -0
  94. package/src/components/screenshot/operations/index.ts +34 -0
  95. package/src/components/screenshot/operations/utils.ts +34 -0
  96. package/src/components/screenshot/screenshots.scss +13 -0
  97. package/src/components/screenshot/types.ts +53 -0
  98. package/src/components/screenshot/useGetLoadedImage.ts +29 -0
  99. package/src/components/screenshot/var.scss +107 -0
  100. package/src/components/screenshot/zh_CN.ts +37 -0
  101. package/src/emoji/100.gif +0 -0
  102. package/src/emoji/101.gif +0 -0
  103. package/src/emoji/102.gif +0 -0
  104. package/src/emoji/103.gif +0 -0
  105. package/src/emoji/104.gif +0 -0
  106. package/src/emoji/105.gif +0 -0
  107. package/src/emoji/106.gif +0 -0
  108. package/src/emoji/107.gif +0 -0
  109. package/src/emoji/108.gif +0 -0
  110. package/src/emoji/109.gif +0 -0
  111. package/src/emoji/110.gif +0 -0
  112. package/src/emoji/111.gif +0 -0
  113. package/src/emoji/112.gif +0 -0
  114. package/src/emoji/113.gif +0 -0
  115. package/src/emoji/114.gif +0 -0
  116. package/src/emoji/115.gif +0 -0
  117. package/src/emoji/116.gif +0 -0
  118. package/src/emoji/117.gif +0 -0
  119. package/src/emoji/118.gif +0 -0
  120. package/src/emoji/119.gif +0 -0
  121. package/src/emoji/120.gif +0 -0
  122. package/src/emoji/121.gif +0 -0
  123. package/src/emoji/122.gif +0 -0
  124. package/src/emoji/123.gif +0 -0
  125. package/src/emoji/124.gif +0 -0
  126. package/src/emoji/125.gif +0 -0
  127. package/src/emoji/126.gif +0 -0
  128. package/src/emoji/127.gif +0 -0
  129. package/src/emoji/128.gif +0 -0
  130. package/src/emoji/129.gif +0 -0
  131. package/src/emoji/130.gif +0 -0
  132. package/src/emoji/131.gif +0 -0
  133. package/src/emoji/132.gif +0 -0
  134. package/src/emoji/133.gif +0 -0
  135. package/src/emoji/134.gif +0 -0
  136. package/src/emoji/135.gif +0 -0
  137. package/src/emoji/136.gif +0 -0
  138. package/src/emoji/137.gif +0 -0
  139. package/src/emoji/138.gif +0 -0
  140. package/src/emoji/139.gif +0 -0
  141. package/src/emoji/140.gif +0 -0
  142. package/src/emoji/141.gif +0 -0
  143. package/src/emoji/142.gif +0 -0
  144. package/src/emoji/143.gif +0 -0
  145. package/src/emoji/144.gif +0 -0
  146. package/src/emoji/145.gif +0 -0
  147. package/src/emoji/146.gif +0 -0
  148. package/src/emoji/147.gif +0 -0
  149. package/src/emoji/148.gif +0 -0
  150. package/src/emoji/149.gif +0 -0
  151. package/src/emoji/150.gif +0 -0
  152. package/src/emoji/151.gif +0 -0
  153. package/src/emoji/152.gif +0 -0
  154. package/src/emoji/153.gif +0 -0
  155. package/src/emoji/154.gif +0 -0
  156. package/src/emoji/155.gif +0 -0
  157. package/src/emoji/156.gif +0 -0
  158. package/src/emoji/157.gif +0 -0
  159. package/src/emoji/158.gif +0 -0
  160. package/src/emoji/159.gif +0 -0
  161. package/src/emoji/160.gif +0 -0
  162. package/src/emoji/161.gif +0 -0
  163. package/src/emoji/162.gif +0 -0
  164. package/src/emoji/163.gif +0 -0
  165. package/src/emoji/164.gif +0 -0
  166. package/src/emoji/165.gif +0 -0
  167. package/src/emoji/166.gif +0 -0
  168. package/src/emoji/167.gif +0 -0
  169. package/src/emoji/168.gif +0 -0
  170. package/src/emoji/169.gif +0 -0
  171. package/src/emoji/170.gif +0 -0
  172. package/src/emoji/171.gif +0 -0
  173. package/src/emoji/172.gif +0 -0
  174. package/src/emoji/173.gif +0 -0
  175. package/src/emoji/174.gif +0 -0
  176. package/src/emoji/175.gif +0 -0
  177. package/src/emoji/176.gif +0 -0
  178. package/src/emoji/177.gif +0 -0
  179. package/src/emoji/178.gif +0 -0
  180. package/src/emoji/179.gif +0 -0
  181. package/src/emoji/180.gif +0 -0
  182. package/src/emoji/181.gif +0 -0
  183. package/src/emoji/182.gif +0 -0
  184. package/src/emoji/183.gif +0 -0
  185. package/src/emoji/184.gif +0 -0
  186. package/src/emoji/185.gif +0 -0
  187. package/src/emoji/186.gif +0 -0
  188. package/src/emoji/187.gif +0 -0
  189. package/src/emoji/188.gif +0 -0
  190. package/src/emoji/189.gif +0 -0
  191. package/src/emoji/190.gif +0 -0
  192. package/src/emoji/191.gif +0 -0
  193. package/src/emoji/192.gif +0 -0
  194. package/src/emoji/193.gif +0 -0
  195. package/src/emoji/194.gif +0 -0
  196. package/src/emoji/195.gif +0 -0
  197. package/src/emoji/196.gif +0 -0
  198. package/src/emoji/197.gif +0 -0
  199. package/src/emoji/198.gif +0 -0
  200. package/src/emoji/199.gif +0 -0
  201. package/src/emoji/200.png +0 -0
  202. package/src/emoji/201.png +0 -0
  203. package/src/emoji/202.png +0 -0
  204. package/src/emoji/203.png +0 -0
  205. package/src/emoji/204.png +0 -0
  206. package/src/emoji/205.png +0 -0
  207. package/src/emoji/206.png +0 -0
  208. package/src/emoji/207.png +0 -0
  209. package/src/emoji/208.png +0 -0
  210. package/src/emoji/209.png +0 -0
  211. package/src/emoji/210.png +0 -0
  212. package/src/emoji/211.png +0 -0
  213. package/src/emoji/212.png +0 -0
  214. package/src/emoji/213.png +0 -0
  215. package/src/emoji/214.png +0 -0
  216. package/src/emoji/215.png +0 -0
  217. package/src/emoji/216.png +0 -0
  218. package/src/emoji/217.png +0 -0
  219. package/src/emoji/218.png +0 -0
  220. package/src/emoji/219.png +0 -0
  221. package/src/emoji2/101--Streamline-The-Team.png +0 -0
  222. package/src/emoji2/128--Streamline-The-Team.png +0 -0
  223. package/src/emoji2/134--Streamline-The-Team.png +0 -0
  224. package/src/emoji2/173--Streamline-The-Team.png +0 -0
  225. package/src/emoji2/Airplane--Streamline-Emoji.svg +24 -0
  226. package/src/emoji2/Alien--Streamline-Emoji.svg +21 -0
  227. package/src/emoji2/Amazed-Face--Streamline-Emoji.svg +16 -0
  228. package/src/emoji2/Amusing-Face--Streamline-Emoji.svg +20 -0
  229. package/src/emoji2/Anguished-Face--Streamline-Emoji.svg +19 -0
  230. package/src/emoji2/Anxious-Face--Streamline-Emoji.svg +17 -0
  231. package/src/emoji2/Astonished-Face--Streamline-Emoji.svg +20 -0
  232. package/src/emoji2/Backhand-Index-Pointing-Down-1--Streamline-Emoji.svg +12 -0
  233. package/src/emoji2/Backhand-Index-Pointing-Left-1--Streamline-Emoji.svg +13 -0
  234. package/src/emoji2/Backhand-Index-Pointing-Right-1--Streamline-Emoji.svg +13 -0
  235. package/src/emoji2/Backhand-Index-Pointing-Up-1--Streamline-Emoji.svg +14 -0
  236. package/src/emoji2/Bar-Chart--Streamline-Emoji.svg +22 -0
  237. package/src/emoji2/Beaming-Face-With-Smiling-Eyes--Streamline-Emoji.svg +20 -0
  238. package/src/emoji2/Boy-1--Streamline-Emoji.svg +17 -0
  239. package/src/emoji2/Boy-2--Streamline-Emoji.svg +17 -0
  240. package/src/emoji2/Boy-3--Streamline-Emoji.svg +17 -0
  241. package/src/emoji2/Broken-Heart--Streamline-Emoji.svg +12 -0
  242. package/src/emoji2/Clapping-Hands-1--Streamline-Emoji.svg +23 -0
  243. package/src/emoji2/Clinking-Glasses-2--Streamline-Emoji.svg +43 -0
  244. package/src/emoji2/Confounded-Face--Streamline-Emoji.svg +17 -0
  245. package/src/emoji2/Confused-Face--Streamline-Emoji.svg +15 -0
  246. package/src/emoji2/Construction-Worker--Streamline-Emoji.svg +21 -0
  247. package/src/emoji2/Couple-With-Heart-Woman-Man-1--Streamline-Emoji.svg +40 -0
  248. package/src/emoji2/Couple-With-Heart-Woman-Man-2--Streamline-Emoji.svg +40 -0
  249. package/src/emoji2/Cowboy-Hat-Face--Streamline-Emoji.svg +22 -0
  250. package/src/emoji2/Crazy-Face--Streamline-Emoji.svg +25 -0
  251. package/src/emoji2/Crossed-Fingers-1--Streamline-Emoji.svg +25 -0
  252. package/src/emoji2/Crown--Streamline-Emoji.svg +35 -0
  253. package/src/emoji2/Crying-Face--Streamline-Emoji.svg +26 -0
  254. package/src/emoji2/Delivery-Truck--Streamline-Emoji.svg +31 -0
  255. package/src/emoji2/Determined-Face--Streamline-Emoji.svg +25 -0
  256. package/src/emoji2/Disappointed-Face--Streamline-Emoji.svg +15 -0
  257. package/src/emoji2/Dizzy-Face--Streamline-Emoji.svg +20 -0
  258. package/src/emoji2/Downcast-Face-With-Sweat--Streamline-Emoji.svg +18 -0
  259. package/src/emoji2/Drooling-Face-1--Streamline-Emoji.svg +19 -0
  260. package/src/emoji2/Drooling-Face-2--Streamline-Emoji.svg +18 -0
  261. package/src/emoji2/Ear--Streamline-Emoji.svg +14 -0
  262. package/src/emoji2/Exclamation-Mark--Streamline-Emoji.svg +12 -0
  263. package/src/emoji2/Exploding-Head--Streamline-Emoji.svg +24 -0
  264. package/src/emoji2/Expressionless-Face--Streamline-Emoji.svg +15 -0
  265. package/src/emoji2/Face-Blowing-A-Kiss--Streamline-Emoji.svg +18 -0
  266. package/src/emoji2/Face-Savoring-Food--Streamline-Emoji.svg +18 -0
  267. package/src/emoji2/Face-Screaming-In-Fear--Streamline-Emoji.svg +18 -0
  268. package/src/emoji2/Face-Vomiting--Streamline-Emoji.svg +28 -0
  269. package/src/emoji2/Face-With-Head-Bandage--Streamline-Emoji.svg +25 -0
  270. package/src/emoji2/Face-With-Medical-Mask--Streamline-Emoji.svg +23 -0
  271. package/src/emoji2/Face-With-Monocle--Streamline-Emoji.svg +26 -0
  272. package/src/emoji2/Face-With-Raised-Eyebrow--Streamline-Emoji.svg +17 -0
  273. package/src/emoji2/Face-With-Rolling-Eyes--Streamline-Emoji.svg +17 -0
  274. package/src/emoji2/Face-With-Steam-From-Nose--Streamline-Emoji.svg +19 -0
  275. package/src/emoji2/Face-With-Symbols-On-Mouth--Streamline-Emoji.svg +22 -0
  276. package/src/emoji2/Face-With-Tears-Of-Joy--Streamline-Emoji.svg +34 -0
  277. package/src/emoji2/Face-With-Thermometer--Streamline-Emoji.svg +31 -0
  278. package/src/emoji2/Face-With-Tongue--Streamline-Emoji.svg +18 -0
  279. package/src/emoji2/Face-Without-Mouth--Streamline-Emoji.svg +14 -0
  280. package/src/emoji2/Fearful-Face--Streamline-Emoji.svg +18 -0
  281. package/src/emoji2/Flexed-Biceps-1--Streamline-Emoji.svg +13 -0
  282. package/src/emoji2/Flushed-Face--Streamline-Emoji.svg +19 -0
  283. package/src/emoji2/Folded-Hands-1--Streamline-Emoji.svg +29 -0
  284. package/src/emoji2/Frowning-Face--Streamline-Emoji.svg +15 -0
  285. package/src/emoji2/Fuel-Pump--Streamline-Emoji.svg +30 -0
  286. package/src/emoji2/Girl-1--Streamline-Emoji.svg +23 -0
  287. package/src/emoji2/Glasses-1--Streamline-Emoji.svg +27 -0
  288. package/src/emoji2/Grimacing-Face--Streamline-Emoji.svg +19 -0
  289. package/src/emoji2/Grinning-Cat-Face--Streamline-Emoji.svg +32 -0
  290. package/src/emoji2/Grinning-Face--Streamline-Emoji.svg +16 -0
  291. package/src/emoji2/Grinning-Face-With-Sweat--Streamline-Emoji.svg +19 -0
  292. package/src/emoji2/Grinning-Squinting-Face--Streamline-Emoji.svg +16 -0
  293. package/src/emoji2/Hand-With-Fingers-Splayed-1--Streamline-Emoji.svg +14 -0
  294. package/src/emoji2/Heart-Suit--Streamline-Emoji.svg +9 -0
  295. package/src/emoji2/Hushed-Face-1--Streamline-Emoji.svg +17 -0
  296. package/src/emoji2/Hushed-Face-2--Streamline-Emoji.svg +15 -0
  297. package/src/emoji2/Index-Pointing-Up-1--Streamline-Emoji.svg +17 -0
  298. package/src/emoji2/Kissing-Face-With-Closed-Eyes--Streamline-Emoji.svg +18 -0
  299. package/src/emoji2/Loudly-Crying-Face--Streamline-Emoji.svg +16 -0
  300. package/src/emoji2/Lying-Face--Streamline-Emoji.svg +15 -0
  301. package/src/emoji2/Man-1--Streamline-Emoji.svg +17 -0
  302. package/src/emoji2/Man-Facepalming-1--Streamline-Emoji.svg +21 -0
  303. package/src/emoji2/Man-Gesturing-No-1--Streamline-Emoji.svg +34 -0
  304. package/src/emoji2/Man-Gesturing-Ok-1--Streamline-Emoji.svg +25 -0
  305. package/src/emoji2/Man-Health-Worker-1--Streamline-Emoji.svg +41 -0
  306. package/src/emoji2/Man-Raising-Hand-1--Streamline-Emoji.svg +26 -0
  307. package/src/emoji2/Man-Shrugging-1--Streamline-Emoji.svg +31 -0
  308. package/src/emoji2/Money-Mouth-Face-2--Streamline-Emoji.svg +30 -0
  309. package/src/emoji2/Mouth--Streamline-Emoji.svg +12 -0
  310. package/src/emoji2/Nauseated-Face-2--Streamline-Emoji.svg +19 -0
  311. package/src/emoji2/Neutral-Face--Streamline-Emoji.svg +15 -0
  312. package/src/emoji2/Ok-Hand-1--Streamline-Emoji.svg +14 -0
  313. package/src/emoji2/Old-Man-1--Streamline-Emoji.svg +27 -0
  314. package/src/emoji2/Old-Woman-1--Streamline-Emoji.svg +23 -0
  315. package/src/emoji2/Oncoming-Fist-1--Streamline-Emoji.svg +15 -0
  316. package/src/emoji2/Person-Wearing-Turban-2--Streamline-Emoji.svg +20 -0
  317. package/src/emoji2/Pile-Of-Poo--Streamline-Emoji.svg +15 -0
  318. package/src/emoji2/Police-Car-Light--Streamline-Emoji.svg +26 -0
  319. package/src/emoji2/Rocket--Streamline-Emoji.svg +32 -0
  320. package/src/emoji2/Sailboat--Streamline-Emoji.svg +18 -0
  321. package/src/emoji2/Shaved-Ice--Streamline-Emoji.svg +21 -0
  322. package/src/emoji2/Shortcake-2--Streamline-Emoji.svg +18 -0
  323. package/src/emoji2/Shushing-Face--Streamline-Emoji.svg +21 -0
  324. package/src/emoji2/Sign-Of-The-Horns-1--Streamline-Emoji.svg +19 -0
  325. package/src/emoji2/Sleeping-Face--Streamline-Emoji.svg +21 -0
  326. package/src/emoji2/Slightly-Smiling-Face--Streamline-Emoji.svg +15 -0
  327. package/src/emoji2/Smiling-Face-With-Halo--Streamline-Emoji.svg +20 -0
  328. package/src/emoji2/Smiling-Face-With-Heart-Eyes--Streamline-Emoji.svg +21 -0
  329. package/src/emoji2/Smirking-Face--Streamline-Emoji.svg +17 -0
  330. package/src/emoji2/Sun-With-Face--Streamline-Emoji.svg +24 -0
  331. package/src/emoji2/Thumbs-Down-1--Streamline-Emoji.svg +20 -0
  332. package/src/emoji2/Thumbs-Up-1--Streamline-Emoji.svg +19 -0
  333. package/src/emoji2/Winking-Face--Streamline-Emoji.svg +18 -0
  334. package/src/emoji2/Woman-Gesturing-No-1--Streamline-Emoji.svg +34 -0
  335. package/src/emoji2/Woman-Gesturing-Ok-2--Streamline-Emoji.svg +25 -0
  336. package/src/emoji2/Woman-Raising-Hand-1--Streamline-Emoji.svg +26 -0
  337. package/src/emoji2/Womans-Sandal--Streamline-Emoji.svg +13 -0
  338. package/src/emoji2/Worried-Face--Streamline-Emoji.svg +17 -0
  339. package/src/emoji2/Writing-Hand-1--Streamline-Emoji.svg +17 -0
  340. package/src/emoji2/Zipper-Mouth-Face--Streamline-Emoji.svg +21 -0
  341. package/src/index.js +19 -0
  342. package/src/services/burn-after-read-service.js +313 -0
  343. package/src/services/burn-after-read-service.test.js +325 -0
  344. package/src/services/dify-api.js +338 -0
  345. package/src/services/dify-api.test.js +376 -0
  346. package/src/services/scheduled-send-service.js +311 -0
  347. package/src/services/scheduled-send-service.test.js +317 -0
  348. package/src/styles/index.css +2368 -0
  349. package/src/utils/emoji.js +125 -0
  350. package/src/utils/emojiData.js +267 -0
  351. package/src/utils/eventEmitter.js +114 -0
  352. package/src/utils/state.js +224 -0
  353. package/src/utils/state.test.js +198 -0
  354. package/src/utils/storage.js +122 -0
  355. package/src/utils/storage.test.js +162 -0
  356. package/src/utils/validation.js +249 -0
@@ -0,0 +1,325 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import {
3
+ createBurnAfterReadService,
4
+ getBurnAfterReadService,
5
+ resetBurnAfterReadService,
6
+ validateBurnDelay
7
+ } from './burn-after-read-service';
8
+
9
+ describe('Burn After Read Service', () => {
10
+ let service;
11
+
12
+ beforeEach(() => {
13
+ vi.useFakeTimers();
14
+ resetBurnAfterReadService();
15
+ service = createBurnAfterReadService();
16
+ });
17
+
18
+ afterEach(() => {
19
+ service.cleanup();
20
+ vi.useRealTimers();
21
+ });
22
+
23
+ describe('消息标记', () => {
24
+ it('应该标记消息为阅后即焚', () => {
25
+ const message = {
26
+ id: 'msg1',
27
+ burnDelay: 10
28
+ };
29
+ const burnMessage = service.markMessageForBurn(message);
30
+ expect(burnMessage).toBeDefined();
31
+ expect(burnMessage.id).toBe('msg1');
32
+ expect(burnMessage.burnDelay).toBe(10);
33
+ expect(burnMessage.status).toBe('pending');
34
+ });
35
+
36
+ it('应该验证销毁延迟', () => {
37
+ const message = {
38
+ id: 'msg1',
39
+ burnDelay: -1 // 无效的延迟
40
+ };
41
+ expect(() => {
42
+ service.markMessageForBurn(message);
43
+ }).toThrow();
44
+ });
45
+
46
+ it('应该检查消息是否标记为阅后即焚', () => {
47
+ const message = {
48
+ id: 'msg1',
49
+ burnDelay: 10
50
+ };
51
+ expect(service.isMarkedForBurn('msg1')).toBe(false);
52
+ service.markMessageForBurn(message);
53
+ expect(service.isMarkedForBurn('msg1')).toBe(true);
54
+ });
55
+ });
56
+
57
+ describe('消息阅读', () => {
58
+ it('应该标记消息为已读', () => {
59
+ const message = {
60
+ id: 'msg1',
61
+ burnDelay: 10
62
+ };
63
+ service.markMessageForBurn(message);
64
+ const readTime = new Date();
65
+ service.markMessageAsRead('msg1', readTime);
66
+ const burnStatus = service.getBurnStatus('msg1');
67
+ expect(burnStatus.status).toBe('read');
68
+ expect(burnStatus.readTime).toEqual(readTime);
69
+ });
70
+
71
+ it('应该在标记为已读时开始倒计时', () => {
72
+ const callback = vi.fn();
73
+ service.on('burn-countdown-started', callback);
74
+ const message = {
75
+ id: 'msg1',
76
+ burnDelay: 10
77
+ };
78
+ service.markMessageForBurn(message);
79
+ service.markMessageAsRead('msg1');
80
+ expect(callback).toHaveBeenCalled();
81
+ });
82
+
83
+ it('应该在创建时如果已读立即开始倒计时', () => {
84
+ const callback = vi.fn();
85
+ service.on('burn-countdown-started', callback);
86
+ const message = {
87
+ id: 'msg1',
88
+ burnDelay: 10,
89
+ readTime: new Date()
90
+ };
91
+ service.markMessageForBurn(message);
92
+ expect(callback).toHaveBeenCalled();
93
+ });
94
+ });
95
+
96
+ describe('消息销毁', () => {
97
+ it('应该在延迟时间后销毁消息', () => {
98
+ const callback = vi.fn();
99
+ service.on('message-burned', callback);
100
+ const message = {
101
+ id: 'msg1',
102
+ burnDelay: 5 // 5秒
103
+ };
104
+ service.markMessageForBurn(message);
105
+ service.markMessageAsRead('msg1');
106
+ // 快进时间
107
+ vi.advanceTimersByTime(5000);
108
+ expect(callback).toHaveBeenCalled();
109
+ expect(service.isBurned('msg1')).toBe(true);
110
+ });
111
+
112
+ it('应该计算剩余销毁时间', () => {
113
+ const message = {
114
+ id: 'msg1',
115
+ burnDelay: 10
116
+ };
117
+ service.markMessageForBurn(message);
118
+ service.markMessageAsRead('msg1');
119
+ const remaining = service.getRemainingTime('msg1');
120
+ expect(remaining).toBe(10);
121
+ // 快进3秒
122
+ vi.advanceTimersByTime(3000);
123
+ const remainingAfter = service.getRemainingTime('msg1');
124
+ expect(remainingAfter).toBe(7);
125
+ });
126
+
127
+ it('应该在消息不存在时返回null剩余时间', () => {
128
+ const remaining = service.getRemainingTime('nonexistent');
129
+ expect(remaining).toBeNull();
130
+ });
131
+ });
132
+
133
+ describe('消息取消', () => {
134
+ it('应该取消消息销毁', () => {
135
+ const message = {
136
+ id: 'msg1',
137
+ burnDelay: 10
138
+ };
139
+ service.markMessageForBurn(message);
140
+ service.markMessageAsRead('msg1');
141
+ expect(service.isMarkedForBurn('msg1')).toBe(true);
142
+ service.cancelBurn('msg1');
143
+ expect(service.isMarkedForBurn('msg1')).toBe(false);
144
+ });
145
+
146
+ it('应该在取消时清除定时器', () => {
147
+ const burnCallback = vi.fn();
148
+ service.on('message-burned', burnCallback);
149
+ const message = {
150
+ id: 'msg1',
151
+ burnDelay: 5
152
+ };
153
+ service.markMessageForBurn(message);
154
+ service.markMessageAsRead('msg1');
155
+ service.cancelBurn('msg1');
156
+ // 快进时间,消息不应该被销毁
157
+ vi.advanceTimersByTime(5000);
158
+ expect(burnCallback).not.toHaveBeenCalled();
159
+ });
160
+ });
161
+
162
+ describe('状态查询', () => {
163
+ it('应该获取消息的销毁状态', () => {
164
+ const message = {
165
+ id: 'msg1',
166
+ burnDelay: 10
167
+ };
168
+ service.markMessageForBurn(message);
169
+ const status = service.getBurnStatus('msg1');
170
+ expect(status).toBeDefined();
171
+ expect(status.id).toBe('msg1');
172
+ expect(status.status).toBe('pending');
173
+ });
174
+
175
+ it('应该获取所有待销毁消息', () => {
176
+ const message1 = { id: 'msg1', burnDelay: 10 };
177
+ const message2 = { id: 'msg2', burnDelay: 20 };
178
+ service.markMessageForBurn(message1);
179
+ service.markMessageForBurn(message2);
180
+ const messages = service.getBurnMessages();
181
+ expect(messages).toHaveLength(2);
182
+ });
183
+
184
+ it('应该检查消息是否已销毁', () => {
185
+ const message = {
186
+ id: 'msg1',
187
+ burnDelay: 1
188
+ };
189
+ service.markMessageForBurn(message);
190
+ service.markMessageAsRead('msg1');
191
+ expect(service.isBurned('msg1')).toBe(false);
192
+ // 快进时间
193
+ vi.advanceTimersByTime(1000);
194
+ expect(service.isBurned('msg1')).toBe(true);
195
+ });
196
+ });
197
+
198
+ describe('事件系统', () => {
199
+ it('应该在标记消息时触发事件', () => {
200
+ const callback = vi.fn();
201
+ service.on('message-marked', callback);
202
+ const message = {
203
+ id: 'msg1',
204
+ burnDelay: 10
205
+ };
206
+ service.markMessageForBurn(message);
207
+ expect(callback).toHaveBeenCalled();
208
+ });
209
+
210
+ it('应该在消息被读时触发事件', () => {
211
+ const callback = vi.fn();
212
+ service.on('message-read', callback);
213
+ const message = {
214
+ id: 'msg1',
215
+ burnDelay: 10
216
+ };
217
+ service.markMessageForBurn(message);
218
+ service.markMessageAsRead('msg1');
219
+ expect(callback).toHaveBeenCalled();
220
+ });
221
+
222
+ it('应该在消息销毁时触发事件', () => {
223
+ const callback = vi.fn();
224
+ service.on('message-burned', callback);
225
+ const message = {
226
+ id: 'msg1',
227
+ burnDelay: 1
228
+ };
229
+ service.markMessageForBurn(message);
230
+ service.markMessageAsRead('msg1');
231
+ vi.advanceTimersByTime(1000);
232
+ expect(callback).toHaveBeenCalled();
233
+ });
234
+
235
+ it('应该支持取消监听', () => {
236
+ const callback = vi.fn();
237
+ const unsubscribe = service.on('message-marked', callback);
238
+ const message1 = { id: 'msg1', burnDelay: 10 };
239
+ service.markMessageForBurn(message1);
240
+ expect(callback).toHaveBeenCalledTimes(1);
241
+ unsubscribe();
242
+ const message2 = { id: 'msg2', burnDelay: 10 };
243
+ service.markMessageForBurn(message2);
244
+ expect(callback).toHaveBeenCalledTimes(1);
245
+ });
246
+ });
247
+
248
+ describe('统计信息', () => {
249
+ it('应该返回正确的统计信息', () => {
250
+ const message1 = { id: 'msg1', burnDelay: 10 };
251
+ const message2 = { id: 'msg2', burnDelay: 20 };
252
+ service.markMessageForBurn(message1);
253
+ service.markMessageForBurn(message2);
254
+ service.markMessageAsRead('msg1');
255
+ const stats = service.getStats();
256
+ expect(stats.total).toBe(2);
257
+ expect(stats.pending).toBe(1);
258
+ expect(stats.read).toBe(1);
259
+ expect(stats.burned).toBe(0);
260
+ expect(stats.activeTimers).toBe(1);
261
+ });
262
+
263
+ it('应该在消息销毁后更新统计', () => {
264
+ const message = {
265
+ id: 'msg1',
266
+ burnDelay: 1
267
+ };
268
+ service.markMessageForBurn(message);
269
+ service.markMessageAsRead('msg1');
270
+ vi.advanceTimersByTime(1000);
271
+ const stats = service.getStats();
272
+ expect(stats.burned).toBe(1);
273
+ expect(stats.activeTimers).toBe(0);
274
+ });
275
+ });
276
+
277
+ describe('清理', () => {
278
+ it('应该清理所有定时器和数据', () => {
279
+ const message1 = { id: 'msg1', burnDelay: 10 };
280
+ const message2 = { id: 'msg2', burnDelay: 20 };
281
+ service.markMessageForBurn(message1);
282
+ service.markMessageForBurn(message2);
283
+ service.markMessageAsRead('msg1');
284
+ service.markMessageAsRead('msg2');
285
+ expect(service.getStats().activeTimers).toBe(2);
286
+ service.cleanup();
287
+ expect(service.getStats().total).toBe(0);
288
+ expect(service.getStats().activeTimers).toBe(0);
289
+ });
290
+ });
291
+
292
+ describe('全局服务', () => {
293
+ it('应该返回相同的全局实例', () => {
294
+ const service1 = getBurnAfterReadService();
295
+ const service2 = getBurnAfterReadService();
296
+ expect(service1).toBe(service2);
297
+ });
298
+
299
+ it('应该在重置后创建新实例', () => {
300
+ const service1 = getBurnAfterReadService();
301
+ resetBurnAfterReadService();
302
+ const service2 = getBurnAfterReadService();
303
+ expect(service1).not.toBe(service2);
304
+ });
305
+ });
306
+
307
+ describe('验证函数', () => {
308
+ it('应该验证有效的销毁延迟', () => {
309
+ const result = validateBurnDelay(10);
310
+ expect(result.valid).toBe(true);
311
+ expect(result.errors).toHaveLength(0);
312
+ });
313
+
314
+ it('应该拒绝无效的销毁延迟', () => {
315
+ const result = validateBurnDelay(-1);
316
+ expect(result.valid).toBe(false);
317
+ expect(result.errors.length).toBeGreaterThan(0);
318
+ });
319
+
320
+ it('应该拒绝超出范围的销毁延迟', () => {
321
+ const result = validateBurnDelay(3601);
322
+ expect(result.valid).toBe(false);
323
+ });
324
+ });
325
+ });
@@ -0,0 +1,338 @@
1
+ import axios from 'axios';
2
+
3
+ class DifyApiService {
4
+ constructor(config) {
5
+ // 支持旧的构造函数签名 (baseURL, agentId) 和新的配置对象
6
+ if (typeof config === 'string') {
7
+ // 旧的签名:constructor(baseURL, agentId)
8
+ this.baseURL = config || (import.meta.env ? import.meta.env.VITE_AICHAT_API_URL : '');
9
+ this.agentId = arguments[1];
10
+ this.apiKey = '';
11
+ this.platform = '';
12
+ this.scene = '';
13
+ this.knowledgeBase = null;
14
+ this.inputVariables = {};
15
+ this.conversationConfig = {
16
+ id: '',
17
+ autoCreate: true,
18
+ timeout: 1800000 // 30 minutes
19
+ };
20
+ this.responseConfig = {
21
+ mode: 'blocking',
22
+ timeout: 30000,
23
+ maxRetries: 3
24
+ };
25
+ } else {
26
+ // 新的签名:constructor(config)
27
+ this.baseURL = config.url || (import.meta.env ? import.meta.env.VITE_AICHAT_API_URL : '');
28
+ this.agentId = config.agentId;
29
+ this.apiKey = config.apiKey || '';
30
+ this.platform = config.platform || '';
31
+ this.scene = config.scene || '';
32
+ this.knowledgeBase = config.knowledgeBase || null;
33
+ this.inputVariables = config.inputVariables || {};
34
+ this.conversationConfig = {
35
+ id: config.conversation?.id || '',
36
+ autoCreate: config.conversation?.autoCreate !== false,
37
+ timeout: config.conversation?.timeout || 1800000
38
+ };
39
+ this.responseConfig = {
40
+ mode: config.response?.mode || 'blocking',
41
+ timeout: config.response?.timeout || 30000,
42
+ maxRetries: config.response?.maxRetries || 3
43
+ };
44
+ }
45
+
46
+ // 验证必填字段
47
+ this._validateConfig();
48
+
49
+ // 创建 axios 客户端
50
+ this.client = axios.create({
51
+ baseURL: this.baseURL,
52
+ headers: {
53
+ 'Content-Type': 'application/json',
54
+ },
55
+ timeout: this.responseConfig.timeout
56
+ });
57
+
58
+ // 会话状态
59
+ this.currentConversationId = this.conversationConfig.id;
60
+ this.conversationCreatedAt = null;
61
+ }
62
+
63
+ /**
64
+ * 验证配置
65
+ * @private
66
+ */
67
+ _validateConfig() {
68
+ if (!this.baseURL) {
69
+ throw new Error('API URL is required. Please provide it via url prop or VITE_AICHAT_API_URL environment variable.');
70
+ }
71
+
72
+ if (!this.agentId) {
73
+ throw new Error('Agent ID is required');
74
+ }
75
+ }
76
+
77
+ /**
78
+ * 更新配置
79
+ * @param {Object} config - 新的配置对象
80
+ */
81
+ updateConfig(config) {
82
+ if (config.url) {
83
+ this.baseURL = config.url;
84
+ }
85
+ if (config.agentId) {
86
+ this.agentId = config.agentId;
87
+ }
88
+ if (config.apiKey !== undefined) {
89
+ this.apiKey = config.apiKey;
90
+ }
91
+ if (config.platform !== undefined) {
92
+ this.platform = config.platform;
93
+ }
94
+ if (config.scene !== undefined) {
95
+ this.scene = config.scene;
96
+ }
97
+ if (config.knowledgeBase !== undefined) {
98
+ this.knowledgeBase = config.knowledgeBase;
99
+ }
100
+ if (config.inputVariables !== undefined) {
101
+ this.inputVariables = config.inputVariables;
102
+ }
103
+ if (config.conversation) {
104
+ this.conversationConfig = {
105
+ ...this.conversationConfig,
106
+ ...config.conversation
107
+ };
108
+ if (config.conversation.id) {
109
+ this.currentConversationId = config.conversation.id;
110
+ }
111
+ }
112
+ if (config.response) {
113
+ this.responseConfig = {
114
+ ...this.responseConfig,
115
+ ...config.response
116
+ };
117
+ }
118
+
119
+ // 验证更新后的配置
120
+ this._validateConfig();
121
+
122
+ // 重新创建 axios 客户端
123
+ this.client = axios.create({
124
+ baseURL: this.baseURL,
125
+ headers: {
126
+ 'Content-Type': 'application/json',
127
+ },
128
+ timeout: this.responseConfig.timeout
129
+ });
130
+ }
131
+
132
+ setBaseURL(baseURL) {
133
+ if (baseURL) {
134
+ this.baseURL = baseURL;
135
+ this.client = axios.create({
136
+ baseURL: this.baseURL,
137
+ headers: {
138
+ 'Content-Type': 'application/json',
139
+ }
140
+ });
141
+ }
142
+ }
143
+
144
+ setAgentId(agentId) {
145
+ this.agentId = agentId;
146
+ }
147
+
148
+ /**
149
+ * 构建输入变量
150
+ * @private
151
+ * @param {Object} runtimeVariables - 运行时传入的变量
152
+ * @returns {Object} 合并后的输入变量
153
+ */
154
+ _buildInputVariables(runtimeVariables = {}) {
155
+ const inputs = {
156
+ ...this.inputVariables,
157
+ ...runtimeVariables
158
+ };
159
+
160
+ // 添加平台和场景信息
161
+ if (this.platform) {
162
+ inputs._platform = this.platform;
163
+ }
164
+ if (this.scene) {
165
+ inputs._scene = this.scene;
166
+ }
167
+
168
+ // 添加知识库数据
169
+ if (this.knowledgeBase && this.knowledgeBase.data) {
170
+ inputs._knowledgeBase = this.knowledgeBase.data;
171
+ }
172
+
173
+ return inputs;
174
+ }
175
+
176
+ async sendMessage(message, userId, options = {}) {
177
+ try {
178
+ if (!this.baseURL) {
179
+ throw new Error('API URL is required. Please provide it via url prop or VITE_AICHAT_API_URL environment variable.');
180
+ }
181
+
182
+ if (!this.agentId) {
183
+ throw new Error('Agent ID is required');
184
+ }
185
+
186
+ if (!userId) {
187
+ throw new Error('User ID is required');
188
+ }
189
+
190
+ // 构建输入变量
191
+ const inputs = this._buildInputVariables(options.inputVariables);
192
+
193
+ // 使用传入的会话 ID 或当前会话 ID
194
+ const conversationId = options.conversationId || this.currentConversationId;
195
+
196
+ const payload = {
197
+ inputs,
198
+ query: message,
199
+ user: userId,
200
+ response_mode: this.responseConfig.mode
201
+ };
202
+
203
+ // 如果有会话 ID,添加到请求中
204
+ if (conversationId) {
205
+ payload.conversation_id = conversationId;
206
+ }
207
+
208
+ const response = await this.client.post(`/chat-messages`, payload, {
209
+ headers: {
210
+ 'X-Agent-Id': this.agentId
211
+ }
212
+ });
213
+
214
+ // 更新当前会话 ID
215
+ if (response.data.conversation_id) {
216
+ this.currentConversationId = response.data.conversation_id;
217
+ if (!this.conversationCreatedAt) {
218
+ this.conversationCreatedAt = Date.now();
219
+ }
220
+ }
221
+
222
+ return response.data;
223
+ } catch (error) {
224
+ console.error('Error sending message to Dify API:', error);
225
+ throw error;
226
+ }
227
+ }
228
+
229
+ async getConversationHistory(userId, limit = 20) {
230
+ try {
231
+ if (!this.baseURL) {
232
+ throw new Error('API URL is required. Please provide it via url prop or VITE_AICHAT_API_URL environment variable.');
233
+ }
234
+
235
+ if (!this.agentId) {
236
+ throw new Error('Agent ID is required');
237
+ }
238
+
239
+ if (!userId) {
240
+ throw new Error('User ID is required');
241
+ }
242
+
243
+ const response = await this.client.get(`/conversations`, {
244
+ params: {
245
+ user: userId,
246
+ limit
247
+ },
248
+ headers: {
249
+ 'X-Agent-Id': this.agentId
250
+ }
251
+ });
252
+
253
+ return response.data;
254
+ } catch (error) {
255
+ console.error('Error fetching conversation history:', error);
256
+ throw error;
257
+ }
258
+ }
259
+
260
+ /**
261
+ * 创建新会话
262
+ * @param {string} userId - 用户 ID
263
+ * @returns {Promise<string>} 会话 ID
264
+ */
265
+ async createConversation(userId) {
266
+ try {
267
+ if (!userId) {
268
+ throw new Error('User ID is required');
269
+ }
270
+
271
+ // Dify 会在第一次发送消息时自动创建会话
272
+ // 这里我们只是重置本地状态
273
+ this.currentConversationId = '';
274
+ this.conversationCreatedAt = null;
275
+
276
+ return '';
277
+ } catch (error) {
278
+ console.error('Error creating conversation:', error);
279
+ throw error;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * 获取会话信息
285
+ * @param {string} conversationId - 会话 ID
286
+ * @returns {Promise<Object>} 会话信息
287
+ */
288
+ async getConversation(conversationId) {
289
+ try {
290
+ if (!conversationId) {
291
+ throw new Error('Conversation ID is required');
292
+ }
293
+
294
+ // 返回当前会话信息
295
+ return {
296
+ id: this.currentConversationId,
297
+ createdAt: this.conversationCreatedAt,
298
+ platform: this.platform,
299
+ scene: this.scene
300
+ };
301
+ } catch (error) {
302
+ console.error('Error getting conversation:', error);
303
+ throw error;
304
+ }
305
+ }
306
+
307
+ /**
308
+ * 更新知识库
309
+ * @param {Object} knowledgeBase - 知识库配置
310
+ */
311
+ updateKnowledgeBase(knowledgeBase) {
312
+ this.knowledgeBase = knowledgeBase;
313
+ }
314
+
315
+ /**
316
+ * 检查会话是否超时
317
+ * @returns {boolean} 是否超时
318
+ */
319
+ isConversationExpired() {
320
+ if (!this.conversationCreatedAt) {
321
+ return false;
322
+ }
323
+
324
+ const now = Date.now();
325
+ const elapsed = now - this.conversationCreatedAt;
326
+ return elapsed > this.conversationConfig.timeout;
327
+ }
328
+
329
+ /**
330
+ * 重置会话
331
+ */
332
+ resetConversation() {
333
+ this.currentConversationId = '';
334
+ this.conversationCreatedAt = null;
335
+ }
336
+ }
337
+
338
+ export default DifyApiService;