@tencentcloud/ai-desk-customer-vue 0.1.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 (351) hide show
  1. package/.code.yml +17 -0
  2. package/.eslintignore +6 -0
  3. package/.stylelintrc.json +40 -0
  4. package/CHANGELOG.md +5 -0
  5. package/README.md +12 -0
  6. package/adapter-vue-web.ts +73 -0
  7. package/adapter-vue.ts +10 -0
  8. package/assets/audio-before-delete.svg +4 -0
  9. package/assets/audio-blue.png +0 -0
  10. package/assets/audio-bubble-blue.svg +3 -0
  11. package/assets/audio-bubble-red.svg +3 -0
  12. package/assets/audio-delete.svg +10 -0
  13. package/assets/audio.svg +6 -0
  14. package/assets/back.svg +16 -0
  15. package/assets/background_mobile.png +0 -0
  16. package/assets/camera-uni.png +0 -0
  17. package/assets/close-quote-icon.svg +3 -0
  18. package/assets/customer_avatar.png +0 -0
  19. package/assets/customer_avatar_mobile.png +0 -0
  20. package/assets/dialog-close.png +0 -0
  21. package/assets/double-arrow.svg +1 -0
  22. package/assets/download.svg +6 -0
  23. package/assets/emoji.png +0 -0
  24. package/assets/face-uni.png +0 -0
  25. package/assets/face.png +0 -0
  26. package/assets/file-h5.png +0 -0
  27. package/assets/files.png +0 -0
  28. package/assets/form-dialog-bg.png +0 -0
  29. package/assets/icon-arrow-left.svg +7 -0
  30. package/assets/icon-close.svg +6 -0
  31. package/assets/iconRight.svg +3 -0
  32. package/assets/icon_form.png +0 -0
  33. package/assets/icon_form_filled.png +0 -0
  34. package/assets/icon_question.png +0 -0
  35. package/assets/icon_refresh.png +0 -0
  36. package/assets/icon_success.png +0 -0
  37. package/assets/imRobotGuess.svg +4 -0
  38. package/assets/image-uni.png +0 -0
  39. package/assets/image.png +0 -0
  40. package/assets/keyboard_icon.png +0 -0
  41. package/assets/loading.png +0 -0
  42. package/assets/more-uni.png +0 -0
  43. package/assets/more_tools.png +0 -0
  44. package/assets/msg-audio.svg +1 -0
  45. package/assets/msg-copy.svg +30 -0
  46. package/assets/msg-del.svg +33 -0
  47. package/assets/msg-quote.svg +8 -0
  48. package/assets/msg-revoke.svg +29 -0
  49. package/assets/radio-check.png +0 -0
  50. package/assets/radio-uncheck.png +0 -0
  51. package/assets/radio.svg +6 -0
  52. package/assets/refresh.svg +4 -0
  53. package/assets/rotate-left.svg +7 -0
  54. package/assets/rotate-right.svg +7 -0
  55. package/assets/star.png +0 -0
  56. package/assets/starLine.png +0 -0
  57. package/assets/translate.svg +12 -0
  58. package/assets/video-play.png +0 -0
  59. package/assets/video-uni.png +0 -0
  60. package/assets/video.png +0 -0
  61. package/assets/zoom-in.svg +9 -0
  62. package/assets/zoom-out.svg +9 -0
  63. package/components/CustomerServiceChat/chat-header/index-web.vue +141 -0
  64. package/components/CustomerServiceChat/emoji-config/custom-emoji.ts +15 -0
  65. package/components/CustomerServiceChat/emoji-config/default-emoji.ts +114 -0
  66. package/components/CustomerServiceChat/emoji-config/index.ts +140 -0
  67. package/components/CustomerServiceChat/emoji-config/locales/en.ts +66 -0
  68. package/components/CustomerServiceChat/emoji-config/locales/zh_cn.ts +66 -0
  69. package/components/CustomerServiceChat/index-web.vue +250 -0
  70. package/components/CustomerServiceChat/message-input/index-web.vue +214 -0
  71. package/components/CustomerServiceChat/message-input/index.ts +2 -0
  72. package/components/CustomerServiceChat/message-input/message-input-button.vue +95 -0
  73. package/components/CustomerServiceChat/message-input/message-input-editor-web.vue +884 -0
  74. package/components/CustomerServiceChat/message-input/message-input-file-web.ts +38 -0
  75. package/components/CustomerServiceChat/message-input/message-input-quote/index.vue +204 -0
  76. package/components/CustomerServiceChat/message-input-toolbar/emoji-dialog-mobile/emoji-dialog-mobile.vue +145 -0
  77. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/emoji-picker-dialog.vue +180 -0
  78. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/index.ts +2 -0
  79. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/index.vue +90 -0
  80. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/style/h5.scss +26 -0
  81. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/style/index.scss +4 -0
  82. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/style/web.scss +55 -0
  83. package/components/CustomerServiceChat/message-input-toolbar/file-upload/index.ts +2 -0
  84. package/components/CustomerServiceChat/message-input-toolbar/file-upload/index.vue +77 -0
  85. package/components/CustomerServiceChat/message-input-toolbar/image-upload/index.ts +2 -0
  86. package/components/CustomerServiceChat/message-input-toolbar/image-upload/index.vue +185 -0
  87. package/components/CustomerServiceChat/message-input-toolbar/index-web.vue +191 -0
  88. package/components/CustomerServiceChat/message-input-toolbar/index.ts +2 -0
  89. package/components/CustomerServiceChat/message-input-toolbar/style/uni.scss +111 -0
  90. package/components/CustomerServiceChat/message-input-toolbar/toolbar-item-container/index.vue +149 -0
  91. package/components/CustomerServiceChat/message-input-toolbar/toolbar-item-container/style/color.scss +6 -0
  92. package/components/CustomerServiceChat/message-input-toolbar/toolbar-item-container/style/h5.scss +20 -0
  93. package/components/CustomerServiceChat/message-input-toolbar/toolbar-item-container/style/index.scss +5 -0
  94. package/components/CustomerServiceChat/message-input-toolbar/toolbar-item-container/style/uni.scss +36 -0
  95. package/components/CustomerServiceChat/message-input-toolbar/toolbar-item-container/style/web.scss +19 -0
  96. package/components/CustomerServiceChat/message-input-toolbar/video-upload/index.ts +2 -0
  97. package/components/CustomerServiceChat/message-input-toolbar/video-upload/index.vue +146 -0
  98. package/components/CustomerServiceChat/message-list/index-web.vue +712 -0
  99. package/components/CustomerServiceChat/message-list/link/index.ts +23 -0
  100. package/components/CustomerServiceChat/message-list/message-elements/message-audio-web.vue +223 -0
  101. package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +504 -0
  102. package/components/CustomerServiceChat/message-list/message-elements/message-custom.vue +5 -0
  103. package/components/CustomerServiceChat/message-list/message-elements/message-face.vue +45 -0
  104. package/components/CustomerServiceChat/message-list/message-elements/message-file.vue +151 -0
  105. package/components/CustomerServiceChat/message-list/message-elements/message-image-web.vue +97 -0
  106. package/components/CustomerServiceChat/message-list/message-elements/message-location.vue +34 -0
  107. package/components/CustomerServiceChat/message-list/message-elements/message-quote/index-web.vue +286 -0
  108. package/components/CustomerServiceChat/message-list/message-elements/message-quote/interface.ts +60 -0
  109. package/components/CustomerServiceChat/message-list/message-elements/message-record/index.vue +139 -0
  110. package/components/CustomerServiceChat/message-list/message-elements/message-text.vue +94 -0
  111. package/components/CustomerServiceChat/message-list/message-elements/message-timestamp.vue +76 -0
  112. package/components/CustomerServiceChat/message-list/message-elements/message-video-web.vue +319 -0
  113. package/components/CustomerServiceChat/message-list/message-elements/plugins/plugin-components/index.ts +9 -0
  114. package/components/CustomerServiceChat/message-list/message-elements/plugins/plugin-components/message-customer/index.ts +5 -0
  115. package/components/CustomerServiceChat/message-list/message-elements/plugins/plugin-components/message-customer/message-customer-service.vue +22 -0
  116. package/components/CustomerServiceChat/message-list/message-elements/plugins/plugin-components/message-plugin-layout-web.vue +133 -0
  117. package/components/CustomerServiceChat/message-list/message-elements/plugins/plugin-components/message-plugin-web.vue +83 -0
  118. package/components/CustomerServiceChat/message-list/message-elements/read-status/index.vue +193 -0
  119. package/components/CustomerServiceChat/message-list/message-elements/simple-message-list/index.vue +462 -0
  120. package/components/CustomerServiceChat/message-list/message-elements/simple-message-list/message-container.vue +105 -0
  121. package/components/CustomerServiceChat/message-list/message-elements/video-play.vue +59 -0
  122. package/components/CustomerServiceChat/message-list/message-tool/index-web.vue +312 -0
  123. package/components/CustomerServiceChat/message-list/message-tool/message-revoked.vue +63 -0
  124. package/components/CustomerServiceChat/message-list/scroll-button/index.vue +201 -0
  125. package/components/CustomerServiceChat/message-list/style/color.scss +32 -0
  126. package/components/CustomerServiceChat/message-list/style/h5.scss +16 -0
  127. package/components/CustomerServiceChat/message-list/style/index.scss +11 -0
  128. package/components/CustomerServiceChat/message-list/style/web.scss +180 -0
  129. package/components/CustomerServiceChat/style/common.scss +59 -0
  130. package/components/CustomerServiceChat/style/h5.scss +51 -0
  131. package/components/CustomerServiceChat/style/index.scss +12 -0
  132. package/components/CustomerServiceChat/style/uni.scss +13 -0
  133. package/components/CustomerServiceChat/style/web.scss +46 -0
  134. package/components/CustomerServiceChat/style/wx.scss +5 -0
  135. package/components/CustomerServiceChat/utils/conversationDraft.ts +86 -0
  136. package/components/CustomerServiceChat/utils/sendMessage.ts +140 -0
  137. package/components/common/Avatar/index.vue +148 -0
  138. package/components/common/BottomPopup/index.ts +3 -0
  139. package/components/common/BottomPopup/index.vue +160 -0
  140. package/components/common/BottomPopup/style/h5.scss +62 -0
  141. package/components/common/BottomPopup/style/index.scss +3 -0
  142. package/components/common/BottomPopup/style/modal.scss +5 -0
  143. package/components/common/Dialog/index.ts +3 -0
  144. package/components/common/Dialog/index.vue +120 -0
  145. package/components/common/Dialog/style/color.scss +43 -0
  146. package/components/common/Dialog/style/dialog.scss +4 -0
  147. package/components/common/Dialog/style/h5.scss +56 -0
  148. package/components/common/Dialog/style/web.scss +61 -0
  149. package/components/common/Drawer/index.vue +164 -0
  150. package/components/common/Icon.vue +83 -0
  151. package/components/common/ImagePreviewer/image-item-web.vue +42 -0
  152. package/components/common/ImagePreviewer/index-web.vue +682 -0
  153. package/components/common/ImagePreviewer/index.ts +3 -0
  154. package/components/common/Overlay/index.vue +126 -0
  155. package/components/common/ProgressMessage/index.vue +95 -0
  156. package/components/common/RadioSelect/index.vue +59 -0
  157. package/components/common/RichText/LICENSE +21 -0
  158. package/components/common/RichText/README.md +244 -0
  159. package/components/common/RichText/dist/mp-alipay/index.acss +1 -0
  160. package/components/common/RichText/dist/mp-alipay/index.axml +1 -0
  161. package/components/common/RichText/dist/mp-alipay/index.js +8 -0
  162. package/components/common/RichText/dist/mp-alipay/index.json +1 -0
  163. package/components/common/RichText/dist/mp-alipay/node/node.acss +1 -0
  164. package/components/common/RichText/dist/mp-alipay/node/node.axml +1 -0
  165. package/components/common/RichText/dist/mp-alipay/node/node.js +1 -0
  166. package/components/common/RichText/dist/mp-alipay/node/node.json +1 -0
  167. package/components/common/RichText/dist/mp-alipay/parser.js +1 -0
  168. package/components/common/RichText/dist/mp-baidu/index.css +1 -0
  169. package/components/common/RichText/dist/mp-baidu/index.js +8 -0
  170. package/components/common/RichText/dist/mp-baidu/index.json +1 -0
  171. package/components/common/RichText/dist/mp-baidu/index.swan +1 -0
  172. package/components/common/RichText/dist/mp-baidu/node/node.css +1 -0
  173. package/components/common/RichText/dist/mp-baidu/node/node.js +1 -0
  174. package/components/common/RichText/dist/mp-baidu/node/node.json +1 -0
  175. package/components/common/RichText/dist/mp-baidu/node/node.swan +1 -0
  176. package/components/common/RichText/dist/mp-baidu/parser.js +1 -0
  177. package/components/common/RichText/dist/mp-qq/index.js +8 -0
  178. package/components/common/RichText/dist/mp-qq/index.json +1 -0
  179. package/components/common/RichText/dist/mp-qq/index.qml +1 -0
  180. package/components/common/RichText/dist/mp-qq/index.qss +1 -0
  181. package/components/common/RichText/dist/mp-qq/node/node.js +1 -0
  182. package/components/common/RichText/dist/mp-qq/node/node.json +1 -0
  183. package/components/common/RichText/dist/mp-qq/node/node.qml +1 -0
  184. package/components/common/RichText/dist/mp-qq/node/node.qss +1 -0
  185. package/components/common/RichText/dist/mp-qq/parser.js +1 -0
  186. package/components/common/RichText/dist/mp-toutiao/index.js +8 -0
  187. package/components/common/RichText/dist/mp-toutiao/index.json +1 -0
  188. package/components/common/RichText/dist/mp-toutiao/index.ttml +1 -0
  189. package/components/common/RichText/dist/mp-toutiao/index.ttss +1 -0
  190. package/components/common/RichText/dist/mp-toutiao/node/node.js +1 -0
  191. package/components/common/RichText/dist/mp-toutiao/node/node.json +1 -0
  192. package/components/common/RichText/dist/mp-toutiao/node/node.ttml +1 -0
  193. package/components/common/RichText/dist/mp-toutiao/node/node.ttss +1 -0
  194. package/components/common/RichText/dist/mp-toutiao/parser.js +1 -0
  195. package/components/common/RichText/dist/mp-weixin/index.js +8 -0
  196. package/components/common/RichText/dist/mp-weixin/index.json +1 -0
  197. package/components/common/RichText/dist/mp-weixin/index.wxml +1 -0
  198. package/components/common/RichText/dist/mp-weixin/index.wxss +1 -0
  199. package/components/common/RichText/dist/mp-weixin/node/node.js +1 -0
  200. package/components/common/RichText/dist/mp-weixin/node/node.json +1 -0
  201. package/components/common/RichText/dist/mp-weixin/node/node.wxml +1 -0
  202. package/components/common/RichText/dist/mp-weixin/node/node.wxss +1 -0
  203. package/components/common/RichText/dist/mp-weixin/parser.js +1 -0
  204. package/components/common/RichText/dist/uni-app/components/mp-html/mp-html.vue +498 -0
  205. package/components/common/RichText/dist/uni-app/components/mp-html/node/node.vue +587 -0
  206. package/components/common/RichText/dist/uni-app/components/mp-html/parser.js +1393 -0
  207. package/components/common/RichText/dist/uni-app/static/app-plus/mp-html/js/handler.js +1 -0
  208. package/components/common/RichText/dist/uni-app/static/app-plus/mp-html/js/uni.webview.min.js +1 -0
  209. package/components/common/RichText/dist/uni-app/static/app-plus/mp-html/local.html +1 -0
  210. package/components/common/RichText/docs/.nojekyll +0 -0
  211. package/components/common/RichText/docs/index.html +50 -0
  212. package/components/common/RichText/docs/lib/docsify.min.js +1 -0
  213. package/components/common/RichText/docs/lib/prism-bash.min.js +1 -0
  214. package/components/common/RichText/docs/lib/search.min.js +1 -0
  215. package/components/common/RichText/docs/lib/vue.css +858 -0
  216. package/components/common/RichText/gulpfile.js +113 -0
  217. package/components/common/RichText/lint.js +63 -0
  218. package/components/common/RichText/package.json +74 -0
  219. package/components/common/RichText/plugins/README.md +2 -0
  220. package/components/common/RichText/plugins/audio/README.md +25 -0
  221. package/components/common/RichText/plugins/audio/build.js +11 -0
  222. package/components/common/RichText/plugins/audio/context.js +7 -0
  223. package/components/common/RichText/plugins/audio/index.js +34 -0
  224. package/components/common/RichText/plugins/audio/miniprogram/audio.js +189 -0
  225. package/components/common/RichText/plugins/audio/miniprogram/audio.json +3 -0
  226. package/components/common/RichText/plugins/audio/miniprogram/audio.wxml +17 -0
  227. package/components/common/RichText/plugins/audio/miniprogram/audio.wxss +127 -0
  228. package/components/common/RichText/plugins/audio/miniprogram/build.js +3 -0
  229. package/components/common/RichText/plugins/audio/uni-app/audio.vue +269 -0
  230. package/components/common/RichText/plugins/audio/uni-app/build.js +3 -0
  231. package/components/common/RichText/plugins/card/README.md +30 -0
  232. package/components/common/RichText/plugins/card/build.js +14 -0
  233. package/components/common/RichText/plugins/card/index.js +7 -0
  234. package/components/common/RichText/plugins/card/miniprogram/build.js +3 -0
  235. package/components/common/RichText/plugins/card/miniprogram/card.js +26 -0
  236. package/components/common/RichText/plugins/card/miniprogram/card.json +3 -0
  237. package/components/common/RichText/plugins/card/miniprogram/card.wxml +9 -0
  238. package/components/common/RichText/plugins/card/miniprogram/card.wxss +55 -0
  239. package/components/common/RichText/plugins/card/uni-app/build.js +3 -0
  240. package/components/common/RichText/plugins/card/uni-app/card.vue +122 -0
  241. package/components/common/RichText/plugins/editable/README.md +137 -0
  242. package/components/common/RichText/plugins/editable/config.js +15 -0
  243. package/components/common/RichText/plugins/editable/miniprogram/build.js +813 -0
  244. package/components/common/RichText/plugins/editable/miniprogram/index.js +551 -0
  245. package/components/common/RichText/plugins/editable/uni-app/build.js +744 -0
  246. package/components/common/RichText/plugins/editable/uni-app/index.js +553 -0
  247. package/components/common/RichText/plugins/emoji/README.md +15 -0
  248. package/components/common/RichText/plugins/emoji/index.js +203 -0
  249. package/components/common/RichText/plugins/highlight/README.md +26 -0
  250. package/components/common/RichText/plugins/highlight/config.js +5 -0
  251. package/components/common/RichText/plugins/highlight/index.js +96 -0
  252. package/components/common/RichText/plugins/highlight/miniprogram/build.js +88 -0
  253. package/components/common/RichText/plugins/highlight/prism.css +125 -0
  254. package/components/common/RichText/plugins/highlight/prism.min.js +7 -0
  255. package/components/common/RichText/plugins/highlight/uni-app/build.js +88 -0
  256. package/components/common/RichText/plugins/img-cache/README.md +24 -0
  257. package/components/common/RichText/plugins/img-cache/build.js +16 -0
  258. package/components/common/RichText/plugins/img-cache/index.js +138 -0
  259. package/components/common/RichText/plugins/latex/README.md +16 -0
  260. package/components/common/RichText/plugins/latex/build.js +14 -0
  261. package/components/common/RichText/plugins/latex/index.js +77 -0
  262. package/components/common/RichText/plugins/latex/katex.css +1070 -0
  263. package/components/common/RichText/plugins/latex/katex.min.js +1 -0
  264. package/components/common/RichText/plugins/markdown/README.md +17 -0
  265. package/components/common/RichText/plugins/markdown/index.js +34 -0
  266. package/components/common/RichText/plugins/markdown/marked.min.js +6 -0
  267. package/components/common/RichText/plugins/markdown/miniprogram/build.js +70 -0
  268. package/components/common/RichText/plugins/markdown/uni-app/build.js +68 -0
  269. package/components/common/RichText/plugins/search/README.md +46 -0
  270. package/components/common/RichText/plugins/search/miniprogram/index.js +137 -0
  271. package/components/common/RichText/plugins/search/uni-app/index.js +132 -0
  272. package/components/common/RichText/plugins/style/README.md +30 -0
  273. package/components/common/RichText/plugins/style/index.js +129 -0
  274. package/components/common/RichText/plugins/style/parser.js +175 -0
  275. package/components/common/RichText/plugins/template/README.md +2 -0
  276. package/components/common/RichText/plugins/template/build.js +65 -0
  277. package/components/common/RichText/plugins/template/index.js +67 -0
  278. package/components/common/RichText/plugins/txv-video/README.md +18 -0
  279. package/components/common/RichText/plugins/txv-video/build.js +3 -0
  280. package/components/common/RichText/plugins/txv-video/index.js +46 -0
  281. package/components/common/RichText/plugins/txv-video/miniprogram/build.js +6 -0
  282. package/components/common/RichText/plugins/txv-video/uni-app/build.js +3 -0
  283. package/components/common/RichText/src/miniprogram/index.js +396 -0
  284. package/components/common/RichText/src/miniprogram/index.json +6 -0
  285. package/components/common/RichText/src/miniprogram/index.wxml +7 -0
  286. package/components/common/RichText/src/miniprogram/index.wxss +13 -0
  287. package/components/common/RichText/src/miniprogram/node/node.js +247 -0
  288. package/components/common/RichText/src/miniprogram/node/node.json +6 -0
  289. package/components/common/RichText/src/miniprogram/node/node.wxml +112 -0
  290. package/components/common/RichText/src/miniprogram/node/node.wxss +164 -0
  291. package/components/common/RichText/src/miniprogram/parser.js +1269 -0
  292. package/components/common/RichText/src/uni-app/components/mp-html/mp-html.vue +498 -0
  293. package/components/common/RichText/src/uni-app/components/mp-html/node/node.vue +585 -0
  294. package/components/common/RichText/src/uni-app/components/mp-html/parser.js +1393 -0
  295. package/components/common/RichText/src/uni-app/static/app-plus/mp-html/js/handler.js +254 -0
  296. package/components/common/RichText/src/uni-app/static/app-plus/mp-html/js/uni.webview.min.js +1 -0
  297. package/components/common/RichText/src/uni-app/static/app-plus/mp-html/local.html +33 -0
  298. package/components/common/RichText/tools/config.js +82 -0
  299. package/components/common/RichText/tools/converter.js +205 -0
  300. package/components/common/RichText/tools/ifdef.js +115 -0
  301. package/components/common/RichText/tools/minifier.js +40 -0
  302. package/components/common/RichText/tools/plugin.js +248 -0
  303. package/components/common/Toast/index-web.ts +122 -0
  304. package/components/common/Toast/index-web.vue +178 -0
  305. package/components/common/Toast/type.ts +8 -0
  306. package/components/common/common.scss +59 -0
  307. package/components/customer-icon.vue +56 -0
  308. package/components/message-branch.vue +120 -0
  309. package/components/message-customer-service.vue +114 -0
  310. package/components/message-form/form-branch.vue +68 -0
  311. package/components/message-form/form-input.vue +242 -0
  312. package/components/message-form/index.vue +80 -0
  313. package/components/message-multi-branch/branch-pc.vue +79 -0
  314. package/components/message-multi-branch/index.vue +60 -0
  315. package/components/message-multi-form/component-mobile/form-popup.vue +37 -0
  316. package/components/message-multi-form/component-mobile/input-mobile.vue +102 -0
  317. package/components/message-multi-form/component-mobile/label-mobile.vue +32 -0
  318. package/components/message-multi-form/component-mobile/radios-mobile.vue +161 -0
  319. package/components/message-multi-form/component-pc/input-pc.vue +93 -0
  320. package/components/message-multi-form/component-pc/label-pc.vue +33 -0
  321. package/components/message-multi-form/component-pc/radio-pc.vue +98 -0
  322. package/components/message-multi-form/form-mobile.vue +385 -0
  323. package/components/message-multi-form/form-pc.vue +184 -0
  324. package/components/message-multi-form/index.vue +61 -0
  325. package/components/message-product-card.vue +129 -0
  326. package/components/message-rating/index.vue +56 -0
  327. package/components/message-rating/message-rating-number.vue +247 -0
  328. package/components/message-rating/message-rating-star.vue +237 -0
  329. package/components/message-rich-text.vue +155 -0
  330. package/components/message-robot-welcome.vue +181 -0
  331. package/components/message-stream.vue +109 -0
  332. package/constant.ts +122 -0
  333. package/excluded-list.txt +6 -0
  334. package/index.ts +30 -0
  335. package/index.vue +60 -0
  336. package/interface.ts +176 -0
  337. package/logger/index.ts +12 -0
  338. package/logger/main.ts +120 -0
  339. package/package.json +62 -0
  340. package/script/fileCopy.js +60 -0
  341. package/script/syncVersion.js +35 -0
  342. package/server.ts +128 -0
  343. package/styles/common.scss +116 -0
  344. package/tsconfig.json +34 -0
  345. package/typings.d.ts +20 -0
  346. package/utils/chatStorage.ts +70 -0
  347. package/utils/copy-web.ts +141 -0
  348. package/utils/enableSampleTaskStatus.ts +8 -0
  349. package/utils/env.ts +15 -0
  350. package/utils/index.ts +59 -0
  351. package/utils/utils.ts +162 -0
@@ -0,0 +1,884 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ 'message-input-editor-container',
5
+ isH5 && 'message-input-editor-container-h5',
6
+ ]"
7
+ >
8
+ <div
9
+ v-if="isMuted"
10
+ class="message-input-mute"
11
+ >
12
+ {{ muteText }}
13
+ </div>
14
+ <div
15
+ v-if="!isMuted && enableInput"
16
+ ref="editorDom"
17
+ class="message-input-editor-area"
18
+ :contenteditable="isH5"
19
+ @keydown.enter="handleEnter"
20
+ @drop="handlePCFileDrop"
21
+ @paste="handlePaste"
22
+ @input="handleH5Input"
23
+ @blur="handleH5Blur"
24
+ @focus="handleH5Focus"
25
+ />
26
+ </div>
27
+ </template>
28
+ <script setup lang="ts">
29
+ import vue from '../../../adapter-vue';
30
+ import {
31
+ TUIStore,
32
+ StoreName,
33
+ IMessageModel,
34
+ } from '@tencentcloud/chat-uikit-engine';
35
+ import { Editor, JSONContent } from '@tiptap/core';
36
+ import Document from '@tiptap/extension-document';
37
+ import Paragraph from '@tiptap/extension-paragraph';
38
+ import Placeholder from '@tiptap/extension-placeholder';
39
+ import Text from '@tiptap/extension-text';
40
+ import Mention from '@tiptap/extension-mention';
41
+ import CustomImage from './message-input-file-web';
42
+ import { ITipTapEditorContent } from '../../../interface';
43
+ import { parseTextToRenderArray } from '../emoji-config';
44
+ import { isH5, isPC } from '../../../utils/env';
45
+ import DraftManager from '../utils/conversationDraft';
46
+ const { toRefs, ref, onMounted, watch, onUnmounted } = vue;
47
+
48
+ const props = defineProps({
49
+ placeholder: {
50
+ type: String,
51
+ default: 'this is placeholder',
52
+ },
53
+ replayOrReferenceMessage: {
54
+ type: Object,
55
+ default: () => ({}),
56
+ },
57
+ isMuted: {
58
+ type: Boolean,
59
+ default: true,
60
+ },
61
+ muteText: {
62
+ type: String,
63
+ default: '',
64
+ },
65
+ enableInput: {
66
+ type: Boolean,
67
+ default: true,
68
+ },
69
+ enableDragUpload: {
70
+ type: Boolean,
71
+ default: true,
72
+ },
73
+ enableTyping: {
74
+ type: Boolean,
75
+ default: true,
76
+ },
77
+ });
78
+
79
+ const emits = defineEmits(['sendMessage', 'onTyping','blurToolAndEmojiH5']);
80
+ const { placeholder, enableDragUpload, enableTyping } = toRefs(props);
81
+ const isEditorEmpty = ref<boolean>(true);
82
+ const isEditorBlur = ref<boolean>(true);
83
+ const isC2C = ref<boolean>(false);
84
+ const currentConversationID = ref<string>('');
85
+ const currentQuoteMessage = ref<{ message: IMessageModel; type: string }>();
86
+ const editorDom = ref();
87
+ let editor: Editor | null = null;
88
+ const fileMap = new Map<string, any>();
89
+
90
+ function onCurrentConversationIDUpdated(conversationID: string) {
91
+ if (currentConversationID.value !== conversationID) {
92
+ if (currentConversationID.value) {
93
+ DraftManager.setStore(
94
+ currentConversationID.value,
95
+ getEditorHTML(),
96
+ DraftManager.generateAbstract(getEditorContent()),
97
+ currentQuoteMessage.value,
98
+ );
99
+ }
100
+ resetEditor();
101
+ if (conversationID) {
102
+ DraftManager.getStore(conversationID, setEditorContent);
103
+ }
104
+ }
105
+ currentConversationID.value = conversationID;
106
+ }
107
+
108
+ function onQuoteMessageUpdated(options?: {
109
+ message: IMessageModel;
110
+ type: string;
111
+ }) {
112
+ currentQuoteMessage.value = options;
113
+ }
114
+
115
+ onMounted(() => {
116
+ editor = isPC
117
+ ? new Editor({
118
+ element: editorDom.value,
119
+ extensions: [
120
+ Document,
121
+ Paragraph,
122
+ Text,
123
+ Placeholder.configure({
124
+ emptyEditorClass: 'is-editor-empty',
125
+ placeholder: placeholder.value,
126
+ }),
127
+ Mention.configure({
128
+ HTMLAttributes: {
129
+ class: 'mention',
130
+ },
131
+ }),
132
+ CustomImage.configure({
133
+ inline: true,
134
+ allowBase64: true,
135
+ }),
136
+ ],
137
+ autofocus: !isH5,
138
+ editable: true,
139
+ injectCSS: false,
140
+ editorProps: {
141
+ transformPastedText() {
142
+ // prevent editor's default paste for resolve emoji
143
+ return '';
144
+ },
145
+ },
146
+ // handle input editor typing (only in C2C and enable typing)
147
+ onUpdate({ editor, transaction }) {
148
+ if (!enableTyping.value || !isC2C.value) return;
149
+ isEditorBlur.value = !editor.isFocused;
150
+ if (transaction?.doc?.content?.size > 2) {
151
+ isEditorEmpty.value = false;
152
+ } else {
153
+ isEditorEmpty.value = true;
154
+ }
155
+ },
156
+ onFocus() {
157
+ if (isH5 && document?.getElementById('app')?.style) {
158
+ // set app height when keyboard popup
159
+ const keyboardHeight
160
+ = document.body.scrollHeight - window.innerHeight;
161
+ (
162
+ document.getElementById('app') as any
163
+ ).style.marginBottom = `${keyboardHeight}px`;
164
+ (
165
+ document.getElementById('app') as any
166
+ ).style.height = `calc(100% - ${keyboardHeight}px)`;
167
+ }
168
+ if (!enableTyping.value || !isC2C.value) return;
169
+ isEditorBlur.value = true;
170
+ },
171
+ onBlur() {
172
+ if (isH5 && document?.getElementById('app')?.style) {
173
+ // reset app height to normal
174
+ (document.getElementById('app') as any).style.marginBottom = ``;
175
+ (document.getElementById('app') as any).style.height = `100%`;
176
+ }
177
+ if (!enableTyping.value || !isC2C.value) return;
178
+ isEditorBlur.value = true;
179
+ },
180
+ })
181
+ : null;
182
+
183
+ TUIStore.watch(StoreName.CONV, {
184
+ currentConversationID: onCurrentConversationIDUpdated,
185
+ });
186
+
187
+ TUIStore.watch(StoreName.CHAT, {
188
+ quoteMessage: onQuoteMessageUpdated,
189
+ });
190
+ });
191
+
192
+ onUnmounted(() => {
193
+ TUIStore.unwatch(StoreName.CONV, {
194
+ currentConversationID: onCurrentConversationIDUpdated,
195
+ });
196
+
197
+ TUIStore.unwatch(StoreName.CHAT, {
198
+ quoteMessage: onQuoteMessageUpdated,
199
+ });
200
+
201
+ // clear map store
202
+ fileMap.clear();
203
+ });
204
+
205
+ function handleEnter(e: any) {
206
+ if (isH5) {
207
+ return;
208
+ }
209
+ e?.preventDefault();
210
+ e?.stopPropagation();
211
+ if (e.keyCode === 13 && e.ctrlKey) {
212
+ // ctrl + enter: warp
213
+ editor?.commands?.insertContent('<p></p>');
214
+ } else if (e.keyCode === 13) {
215
+ // enter only: send message
216
+ emits('sendMessage');
217
+ }
218
+ }
219
+
220
+ function handleH5Input() {
221
+ if (isH5) {
222
+ isEditorEmpty.value = editorDom.value?.childNodes ? false : true;
223
+ }
224
+ }
225
+
226
+ function handleH5Blur() {
227
+ emits('blurToolAndEmojiH5');
228
+ isH5 && (isEditorBlur.value = true);
229
+ }
230
+
231
+ async function handleH5Focus() {
232
+ emits('blurToolAndEmojiH5');
233
+ isH5 && (isEditorBlur.value = false);
234
+ }
235
+
236
+ function handlePCFileDrop(e: any) {
237
+ // Only the PC version supports drag and drop upload of rich text
238
+ isPC && handleFileDropOrPaste(e, 'drop');
239
+ }
240
+
241
+ function handlePaste(e: ClipboardEvent) {
242
+ // In the PC version, disable native copy and support rich text copy, and go through rich text copy upload parsing
243
+ // In the mobile version, only text copy is supported, and default copy parsing is used
244
+ if (!e.clipboardData) {
245
+ return;
246
+ }
247
+ if (isPC && e.clipboardData.files.length) {
248
+ handleFileDropOrPaste(e, 'paste');
249
+ } else {
250
+ handlePasteText(e);
251
+ // Caret: https://developer.mozilla.org/en-US/docs/Web/API/CaretPosition
252
+ scrollToCaret(editorDom.value);
253
+ }
254
+ }
255
+
256
+ function handlePasteText(e: ClipboardEvent) {
257
+ e.preventDefault();
258
+ const html = e.clipboardData?.getData('text/html');
259
+ const text = e.clipboardData?.getData('text/plain') || '';
260
+ // if paste html in pc, paste by tiptap editor default
261
+ // if paste text in pc or mobile, parse text to html to render emoji
262
+ if (!html) {
263
+ const renderArray = parseTextToRenderArray(text);
264
+ insertEditorContent(renderArray);
265
+ }
266
+ }
267
+
268
+ async function handleFileDropOrPaste(e: any, type: string) {
269
+ e.preventDefault();
270
+ e.stopPropagation();
271
+ if (!enableDragUpload.value && type === 'drop') {
272
+ return;
273
+ }
274
+ if (
275
+ (type === 'drop' && e.dataTransfer)
276
+ || (type === 'paste' && e.clipboardData)
277
+ ) {
278
+ const files
279
+ = type === 'drop' ? e?.dataTransfer?.files : e?.clipboardData?.files;
280
+ for (let i = 0; i < files.length; i++) {
281
+ const file = files[i];
282
+ const isImage = file.type.startsWith('image/');
283
+ const fileSrc = isImage
284
+ ? URL.createObjectURL(file)
285
+ : await drawFileCanvasToImageUrl(file);
286
+ editor?.commands?.insertContent({
287
+ type: 'custom-image',
288
+ attrs: {
289
+ src: fileSrc,
290
+ alt: file?.name,
291
+ class: isImage ? 'normal' : 'file',
292
+ },
293
+ });
294
+ fileMap.set(fileSrc, file);
295
+ if (i === files.length - 1) {
296
+ setTimeout(() => {
297
+ editor?.commands?.focus('end');
298
+ editor?.commands?.scrollIntoView();
299
+ }, 10);
300
+ }
301
+ }
302
+ }
303
+ }
304
+
305
+ /**
306
+ * create file icon image
307
+ * To avoid creating img dom with the same icon repeatedly, record the previous type of icon that has been created.
308
+ * The format of the record is map<icon type, img dom>.
309
+ */
310
+ const fileIconDomMap = new Map<string, HTMLImageElement>();
311
+ const addImageProcess = (src: string, type: string) => {
312
+ return new Promise((resolve, reject) => {
313
+ if (fileIconDomMap.has(type)) {
314
+ resolve(fileIconDomMap.get(type));
315
+ } else {
316
+ const img = new Image();
317
+ img.crossOrigin = 'anonymous';
318
+ img.onload = () => {
319
+ fileIconDomMap.set(type, img);
320
+ resolve(img);
321
+ };
322
+ img.onerror = reject;
323
+ img.src = src;
324
+ }
325
+ });
326
+ };
327
+
328
+ // draw file tag canvas
329
+ const drawFileCanvasToImageUrl = async (file: any) => {
330
+ const { name, type } = file;
331
+ const canvas = document.createElement('canvas');
332
+ const width = 160;
333
+ const height = 50;
334
+ canvas.style.width = width + 'px';
335
+ canvas.style.height = height + 'px';
336
+ // Set the actual size in memory (scaled to account for additional pixel density)
337
+ const scale = window.devicePixelRatio; // Change to 1 to view blurry on a retina screen
338
+ canvas.width = Math.floor(width * scale);
339
+ canvas.height = Math.floor(height * scale);
340
+ const ctx = canvas.getContext('2d');
341
+ if (!ctx) {
342
+ return '';
343
+ }
344
+ // To use CSS pixels, normalize the coordinate system
345
+ ctx.scale(scale, scale);
346
+ // draw icon
347
+ const { iconSrc, iconType } = handleFileIconForShow(type);
348
+ const img = await addImageProcess(iconSrc, iconType);
349
+ ctx?.drawImage(img as any, 10, 10, 30, 30);
350
+ // draw font
351
+ const nameForShow = handleNameForShow(name);
352
+ ctx.fillText(nameForShow, 45, 22);
353
+ // canvas to url
354
+ const dataURL = canvas.toDataURL();
355
+ return dataURL;
356
+ };
357
+
358
+ const handleFileIconForShow = (type: string) => {
359
+ const urlBase = 'https://web.sdk.qcloud.com/component/TUIKit/assets/file-';
360
+ const fileTypes = [
361
+ 'image',
362
+ 'pdf',
363
+ 'text',
364
+ 'ppt',
365
+ 'presentation',
366
+ 'sheet',
367
+ 'zip',
368
+ 'word',
369
+ 'video',
370
+ 'unknown',
371
+ ];
372
+ let url = '';
373
+ let iconType = '';
374
+ fileTypes.forEach((typeName: string) => {
375
+ if (type.includes(typeName)) {
376
+ url = urlBase + typeName + '.svg';
377
+ iconType = typeName;
378
+ }
379
+ });
380
+ return {
381
+ iconSrc: url ? url : urlBase + 'unknown.svg',
382
+ iconType: iconType ? iconType : 'unknown',
383
+ };
384
+ };
385
+
386
+ const handleNameForShow = (value: string): string => {
387
+ if (!value) {
388
+ return value;
389
+ }
390
+ let res = '';
391
+ let length = 0;
392
+ for (let i = 0; i < value?.length; i++) {
393
+ if (length > 16) {
394
+ res += '...';
395
+ break;
396
+ }
397
+ res += value[i];
398
+ if (/[a-z]|[0-9]|[,;.!@#-+/\\$%^*()<>?:"'{}~]/i.test(value[i])) {
399
+ length += 1;
400
+ } else {
401
+ length += 2;
402
+ }
403
+ }
404
+ return res;
405
+ };
406
+
407
+ function getEditorContent() {
408
+ return isPC ? parsePCEditorContent() : parseH5EditorContent();
409
+ }
410
+
411
+ function parsePCEditorContent(): ITipTapEditorContent[] {
412
+ const editorJSON = editor?.getJSON();
413
+ const content: ITipTapEditorContent[] = [];
414
+ handleEditorContent(editorJSON, content);
415
+ if (
416
+ content.length > 0
417
+ && content[content.length - 1]
418
+ && content[content.length - 1].type === 'text'
419
+ && content[content.length - 1].payload?.text?.endsWith('\n')
420
+ ) {
421
+ const text = content[content.length - 1].payload.text || '';
422
+ content[content.length - 1].payload.text = text?.substring(
423
+ 0,
424
+ text.lastIndexOf('\n'),
425
+ );
426
+ }
427
+ return content;
428
+ }
429
+
430
+ function handleEditorContent(
431
+ root: JSONContent,
432
+ content: ITipTapEditorContent[],
433
+ ) {
434
+ if (!root || !root.type) {
435
+ return;
436
+ }
437
+ if (
438
+ root.type !== 'text'
439
+ && root.type !== 'custom-image'
440
+ && root.type !== 'mention'
441
+ ) {
442
+ if (root.type === 'paragraph') {
443
+ handleEditorNode(root, content);
444
+ }
445
+ if (root.content?.length) {
446
+ root.content.forEach((item: JSONContent) => {
447
+ handleEditorContent(item, content);
448
+ });
449
+ }
450
+ return;
451
+ } else {
452
+ handleEditorNode(root, content);
453
+ }
454
+ }
455
+
456
+ function handleEditorNode(node: JSONContent, content: ITipTapEditorContent[]) {
457
+ // handle enter
458
+ if (node.type === 'paragraph') {
459
+ if (
460
+ content.length > 0
461
+ && content[content.length - 1]
462
+ && content[content.length - 1]?.type === 'text'
463
+ ) {
464
+ content[content.length - 1].payload.text += '\n';
465
+ }
466
+ } else if (
467
+ node.type === 'text'
468
+ || (node.type === 'custom-image' && node?.attrs?.class?.includes('emoji'))
469
+ ) {
470
+ // Process text and emojis
471
+ const text = node.type === 'text' ? node?.text : node?.attrs?.alt;
472
+ if (
473
+ content.length > 0
474
+ && content[content.length - 1]
475
+ && content[content.length - 1]?.type === 'text'
476
+ ) {
477
+ content[content.length - 1].payload.text += text;
478
+ } else {
479
+ content.push({
480
+ type: 'text',
481
+ payload: { text: text },
482
+ });
483
+ }
484
+ } else if (
485
+ node.type === 'custom-image'
486
+ && node?.attrs?.class?.includes('normal')
487
+ ) {
488
+ // Process rich text images
489
+ content.push({
490
+ type: 'image',
491
+ payload: { file: fileMap?.get(node?.attrs?.src) },
492
+ });
493
+ } else if (
494
+ node.type === 'custom-image'
495
+ && node?.attrs?.class?.includes('file')
496
+ ) {
497
+ const file = fileMap?.get(node?.attrs?.src);
498
+ content.push({
499
+ type: file?.type?.includes('video') ? 'video' : 'file',
500
+ payload: { file },
501
+ });
502
+ } else if (node.type === 'mention') {
503
+ const text = '@' + node?.attrs?.label + ' ';
504
+ if (
505
+ content.length > 0
506
+ && content[content.length - 1]
507
+ && content[content.length - 1]?.type === 'text'
508
+ ) {
509
+ content[content.length - 1].payload.text += text;
510
+ } else {
511
+ content.push({
512
+ type: 'text',
513
+ payload: { text: text },
514
+ });
515
+ }
516
+ if (content[content.length - 1]?.payload?.atUserList) {
517
+ content[content.length - 1]?.payload?.atUserList?.push(node?.attrs?.id);
518
+ } else {
519
+ content[content.length - 1].payload.atUserList = [node?.attrs?.id];
520
+ }
521
+ }
522
+ }
523
+
524
+ function parseH5EditorContent() {
525
+ const root = editorDom.value;
526
+ let text: string = '';
527
+ const atUserList: string[] = [];
528
+ try {
529
+ for (const child of root.childNodes) {
530
+ if (
531
+ child.nodeName === '#text'
532
+ || child.nodeName === 'SPAN'
533
+ || (child as HTMLElement).classList?.contains('custom-image-emoji')
534
+ || (child as HTMLElement).classList?.contains('mention')
535
+ ) {
536
+ text += child.nodeValue || (child as any).alt || child.innerHTML || '';
537
+ if (
538
+ child.classList?.contains('mention')
539
+ && child.id
540
+ && !atUserList?.includes(child.id)
541
+ ) {
542
+ atUserList.push(child.id);
543
+ }
544
+ }
545
+ }
546
+ } catch (error) {
547
+ if (error instanceof Error) {
548
+ throw error;
549
+ }
550
+ }
551
+ return [
552
+ {
553
+ type: 'text',
554
+ payload: {
555
+ text,
556
+ atUserList,
557
+ },
558
+ },
559
+ ];
560
+ }
561
+
562
+ function addEmoji(emojiData: any) {
563
+ if (isPC) {
564
+ editor?.commands?.insertContent({
565
+ type: 'custom-image',
566
+ attrs: {
567
+ src: emojiData?.url,
568
+ alt: emojiData?.emoji.key,
569
+ title: emojiData?.emoji.key,
570
+ class: 'emoji',
571
+ },
572
+ });
573
+ } else {
574
+ const emojiImgNode = document.createElement('img');
575
+ emojiImgNode?.setAttribute('src', emojiData?.url);
576
+ emojiImgNode?.setAttribute('class', 'custom-image custom-image-emoji');
577
+ emojiImgNode?.setAttribute('alt', emojiData?.emoji.key);
578
+ emojiImgNode?.setAttribute('title', emojiData?.emoji.key);
579
+ emojiImgNode?.setAttribute('width', '20px');
580
+ emojiImgNode?.setAttribute('height', '20px');
581
+ editorDom.value?.appendChild(emojiImgNode);
582
+ const spanNode = document.createElement('span');
583
+ spanNode.contentEditable = 'true';
584
+ editorDom.value?.appendChild(spanNode);
585
+ }
586
+ if (!isH5) {
587
+ editor?.commands?.focus();
588
+ editor?.commands?.scrollIntoView();
589
+ }
590
+ }
591
+
592
+ function blur() {
593
+ isPC ? editor?.commands?.blur() : editorDom.value?.blur();
594
+ }
595
+
596
+ function resetEditor() {
597
+ editor?.commands?.clearContent(true);
598
+ isEditorBlur.value = true;
599
+ isEditorEmpty.value = true;
600
+ isH5 && (editorDom.value.innerHTML = '');
601
+ }
602
+
603
+ function getEditorHTML(): string {
604
+ if (isPC) {
605
+ return editor?.getHTML();
606
+ }
607
+ return editorDom.value.innerHTML;
608
+ }
609
+
610
+ function setEditorContent(content: any) {
611
+ if (isPC) {
612
+ editor?.commands?.setContent(content);
613
+ } else {
614
+ editorDom.value!.innerHTML = content;
615
+ }
616
+ }
617
+
618
+ function insertEditorContent(
619
+ content: Array<{ type: 'text' | 'image'; content: string; emojiKey?: string }>,
620
+ ) {
621
+ const selection = window.getSelection();
622
+ if (selection && selection.rangeCount) {
623
+ const currentRange = selection.getRangeAt(0);
624
+ content.forEach((item) => {
625
+ const newNode
626
+ = item.type === 'image'
627
+ ? createEmojiNode(item.emojiKey || '', item.content)
628
+ : createTextNode(item.content);
629
+ currentRange.insertNode(newNode);
630
+ currentRange.setStartAfter(newNode);
631
+ if (item.type === 'image' && isH5) {
632
+ // insert empty span instead of caret after emoji
633
+ const textNode = document.createElement('span');
634
+ textNode.contentEditable = 'true';
635
+ currentRange.insertNode(textNode);
636
+ currentRange.setStartAfter(textNode);
637
+ }
638
+ });
639
+ // update caret to current range and scroll to caret
640
+ currentRange.collapse(false);
641
+ selection.removeAllRanges();
642
+ selection.addRange(currentRange);
643
+ }
644
+ }
645
+
646
+ function createTextNode(text: string) {
647
+ return document.createTextNode(text);
648
+ }
649
+
650
+ function createEmojiNode(key: string, url: string) {
651
+ const imgNode = document.createElement('img');
652
+ imgNode.src = url;
653
+ imgNode.alt = key || '';
654
+ imgNode.classList.add('custom-image', 'custom-image-emoji');
655
+ imgNode.width = 20;
656
+ imgNode.height = 20;
657
+ return imgNode;
658
+ }
659
+
660
+ function scrollToCaret(el: HTMLElement) {
661
+ const selection = window.getSelection();
662
+ if (selection && selection.rangeCount > 0) {
663
+ const range = selection.getRangeAt(0);
664
+ // create a new range with zero width space text node in current caret
665
+ const newRange = document.createRange();
666
+ const emptyPlaceholder = '\u200B';
667
+ const textNode = document.createTextNode(emptyPlaceholder);
668
+ newRange.setStart(range.startContainer, range.startOffset);
669
+ newRange.insertNode(textNode);
670
+ // get new range bounding rect for caret position information
671
+ const rect = newRange.getBoundingClientRect();
672
+ // remove text node
673
+ if (textNode.parentNode) {
674
+ textNode.parentNode.removeChild(textNode);
675
+ }
676
+ // scroll to caret
677
+ el.scrollTop = rect.top - el.getBoundingClientRect().top;
678
+ }
679
+ }
680
+
681
+ watch(
682
+ () => [isEditorEmpty.value, isEditorBlur.value],
683
+ (newVal: boolean[], oldVal: boolean[]) => {
684
+ if (newVal !== oldVal) {
685
+ emits('onTyping', isEditorEmpty.value, isEditorBlur.value);
686
+ }
687
+ },
688
+ {
689
+ immediate: true,
690
+ deep: true,
691
+ },
692
+ );
693
+
694
+ defineExpose({
695
+ getEditorContent,
696
+ addEmoji,
697
+ resetEditor,
698
+ setEditorContent,
699
+ getEditorHTML,
700
+ insertEditorContent,
701
+ blur,
702
+ });
703
+ </script>
704
+
705
+ <style scoped lang="scss">
706
+ @import "../style/common";
707
+
708
+ .message-input-editor {
709
+ &-container {
710
+ box-sizing: border-box;
711
+ height: 100%;
712
+ display: flex;
713
+ flex-direction: column;
714
+ flex: 1;
715
+ padding: 3px 10px 10px;
716
+ }
717
+
718
+ &-area {
719
+ box-sizing: border-box;
720
+ font-family: PingFangSC-Regular;
721
+ height: 100%;
722
+ flex: 1;
723
+ display: flex;
724
+ outline: none;
725
+ ::-webkit-scrollbar {
726
+ width: 6px;
727
+ height: 140px;
728
+ background-color: transparent;
729
+ }
730
+
731
+ ::-webkit-scrollbar-track {
732
+ border-radius: 10px;
733
+ }
734
+
735
+ ::-webkit-scrollbar-thumb {
736
+ border-radius: 10px;
737
+ background-color: #9a999c;
738
+ }
739
+ }
740
+
741
+ &-mute {
742
+ box-sizing: border-box;
743
+ flex: 1;
744
+ display: flex;
745
+ color: #999;
746
+ font-size: 14px;
747
+ justify-content: center;
748
+ align-items: center;
749
+ }
750
+ }
751
+
752
+ .message-input-editor-container-h5 {
753
+ box-sizing: border-box;
754
+ flex: 1;
755
+ height: auto;
756
+ background: #fff;
757
+ border-radius: 9.4px 0 0 9.4px;
758
+ padding: 8px 0 8px 10px;
759
+ font-size: 16px !important;
760
+ max-height: 86px;
761
+ margin-right: 0px;
762
+ overflow: hidden;
763
+
764
+ .message-input-editor-area {
765
+ overflow: auto;
766
+ user-select: text;
767
+ hyphens: auto;
768
+ word-break: keep-all;
769
+ overflow-wrap: break-word;
770
+ flex-wrap: wrap;
771
+ .custom-image,
772
+ .custom-image-emoji {
773
+ display: inline;
774
+ }
775
+ ::-webkit-scrollbar {
776
+ width: 6px;
777
+ height: 140px;
778
+ background-color: transparent;
779
+ }
780
+
781
+ ::-webkit-scrollbar-track {
782
+ border-radius: 10px;
783
+ }
784
+
785
+ ::-webkit-scrollbar-thumb {
786
+ border-radius: 10px;
787
+ background-color: #9a999c;
788
+ }
789
+ }
790
+ }
791
+ </style>
792
+ <style lang="scss">
793
+ /* stylelint-disable-next-line selector-class-pattern */
794
+ .ProseMirror {
795
+ min-height: 100%;
796
+ flex: 1;
797
+ font-size: 14px;
798
+ word-wrap: break-word;
799
+ word-break: keep-all;
800
+ white-space: pre-wrap;
801
+ overflow: auto;
802
+
803
+ div,
804
+ ul,
805
+ ol,
806
+ dt,
807
+ dd,
808
+ li,
809
+ dl,
810
+ h1,
811
+ h2,
812
+ h3,
813
+ h4,
814
+ p {
815
+ margin: 0;
816
+ padding: 0;
817
+ font-style: normal;
818
+ }
819
+
820
+ p {
821
+ * {
822
+ vertical-align: bottom;
823
+ }
824
+ }
825
+
826
+ user-select: text;
827
+ height: 160px;
828
+
829
+ &-focused {
830
+ border: none;
831
+ outline: none;
832
+ }
833
+
834
+ img {
835
+ /* stylelint-disable-next-line selector-class-pattern */
836
+ &.ProseMirror-selectednode {
837
+ outline: 2px solid #68cef8;
838
+ }
839
+ }
840
+
841
+ .custom-image {
842
+ &-normal {
843
+ max-height: 120px;
844
+ max-width: 200px;
845
+ }
846
+
847
+ &-file {
848
+ height: 50px;
849
+ width: 160px;
850
+ border: 1px solid #e8e8e9;
851
+ border-radius: 5px;
852
+ }
853
+
854
+ &-emoji {
855
+ height: 20px;
856
+ width: 20px;
857
+ }
858
+
859
+ &-image {
860
+ display: none;
861
+ }
862
+ }
863
+
864
+ /* stylelint-disable-next-line selector-class-pattern */
865
+ .ProseMirror-selectednode {
866
+ outline: 2px solid #68cef8;
867
+ cursor: none;
868
+ }
869
+
870
+ p,
871
+ [contenteditable] {
872
+ user-select: text;
873
+ }
874
+
875
+ // placeholder style
876
+ p.is-editor-empty:first-child::before {
877
+ color: #adb5bd;
878
+ content: attr(data-placeholder);
879
+ float: left;
880
+ height: 0;
881
+ pointer-events: none;
882
+ }
883
+ }
884
+ </style>