koishi-plugin-chat-patch 3.0.2 → 5.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 (194) hide show
  1. package/client/vue/index.vue +60 -634
  2. package/client/web/env.d.ts +56 -0
  3. package/client/web/index.html +21 -0
  4. package/client/web/package-lock.json +3419 -0
  5. package/client/web/package.json +62 -0
  6. package/client/web/public/bcui/css/color-dark.css +35 -0
  7. package/client/web/public/bcui/css/color-light.css +35 -0
  8. package/client/web/public/bcui/css/style.css +468 -0
  9. package/client/web/public/bcui/js/main.js +193 -0
  10. package/client/web/public/css/append-dark.css +13 -0
  11. package/client/web/public/css/append-light.css +13 -0
  12. package/client/web/public/css/append-napcat-dark.css +14 -0
  13. package/client/web/public/css/append-napcat-light.css +14 -0
  14. package/client/web/public/favicon.ico +0 -0
  15. package/client/web/public/img/icons/icon-for-fuck-apple.png +0 -0
  16. package/client/web/public/img/icons/icon-maskable.png +0 -0
  17. package/client/web/public/img/icons/icon.png +0 -0
  18. package/client/web/public/img/icons/icon.svg +10 -0
  19. package/client/web/public/robots.txt +2 -0
  20. package/client/web/public/sw.js +58 -0
  21. package/client/web/scripts/copy-bcui.mjs +17 -0
  22. package/client/web/src/App.vue +1127 -0
  23. package/client/web/src/assets/css/append/append_darwin.css +68 -0
  24. package/client/web/src/assets/css/append/append_full_vibrancy.css +290 -0
  25. package/client/web/src/assets/css/append/append_linux.css +125 -0
  26. package/client/web/src/assets/css/append/append_linux_vibrancy.css +22 -0
  27. package/client/web/src/assets/css/append/append_napcat.css +35 -0
  28. package/client/web/src/assets/css/append/append_new.css +843 -0
  29. package/client/web/src/assets/css/append/append_vibrancy.css +113 -0
  30. package/client/web/src/assets/css/append/append_win32.css +109 -0
  31. package/client/web/src/assets/css/append/mobile/append_mobile_horizontal.css +349 -0
  32. package/client/web/src/assets/css/append/mobile/append_mobile_vertical.css +96 -0
  33. package/client/web/src/assets/css/chat.css +2104 -0
  34. package/client/web/src/assets/css/msg.css +941 -0
  35. package/client/web/src/assets/css/options.css +811 -0
  36. package/client/web/src/assets/css/sys_notice.css +62 -0
  37. package/client/web/src/assets/css/view.css +2105 -0
  38. package/client/web/src/assets/font//346/226/271/346/255/243/345/226/265/345/221/234/344/275/223.ttf +0 -0
  39. package/client/web/src/assets/img/Vue.png +0 -0
  40. package/client/web/src/assets/img/cakes.svg +189 -0
  41. package/client/web/src/assets/img/icons/AppIcon.png +0 -0
  42. package/client/web/src/assets/img/icons/AppIconDark.png +0 -0
  43. package/client/web/src/assets/img/icons/CapacitorAppIcon.png +0 -0
  44. package/client/web/src/assets/img/icons/CapacitorAppIconDark.png +0 -0
  45. package/client/web/src/assets/img/icons/NapcatAppIcon.png +0 -0
  46. package/client/web/src/assets/img/icons/NapcatAppIconDark.png +0 -0
  47. package/client/web/src/assets/img/icons/exit.png +0 -0
  48. package/client/web/src/assets/img/icons/pen.png +0 -0
  49. package/client/web/src/assets/img/stars.svg +89 -0
  50. package/client/web/src/assets/img//346/234/237/345/276/205.png +0 -0
  51. package/client/web/src/assets/l10n/_About I10n.md +35 -0
  52. package/client/web/src/assets/l10n/_l10nconfig.json +7 -0
  53. package/client/web/src/assets/l10n/zh-CN.po +1941 -0
  54. package/client/web/src/assets/logo.png +0 -0
  55. package/client/web/src/assets/pathMap/LLOneBot.yaml +2 -0
  56. package/client/web/src/assets/pathMap/Lagrange.OneBot.yaml +180 -0
  57. package/client/web/src/assets/pathMap/NapCat.Onebot.yaml +224 -0
  58. package/client/web/src/assets/pathMap/SnowLuma.yaml +80 -0
  59. package/client/web/src/assets/qed.txt +1 -0
  60. package/client/web/src/components/AboutPan.vue +197 -0
  61. package/client/web/src/components/BulletinBody.vue +129 -0
  62. package/client/web/src/components/DepPan.vue +310 -0
  63. package/client/web/src/components/EmojiFace.vue +32 -0
  64. package/client/web/src/components/FacePan.vue +461 -0
  65. package/client/web/src/components/FileBody.vue +129 -0
  66. package/client/web/src/components/FileManager.vue +532 -0
  67. package/client/web/src/components/FriendBody.vue +54 -0
  68. package/client/web/src/components/GlobalSessionSearchBar.vue +301 -0
  69. package/client/web/src/components/History.vue +49 -0
  70. package/client/web/src/components/LazyLottie.vue +82 -0
  71. package/client/web/src/components/MergePan.vue +127 -0
  72. package/client/web/src/components/MsgBody.vue +1478 -0
  73. package/client/web/src/components/MusicPlayer.vue +549 -0
  74. package/client/web/src/components/NoticeBody.vue +168 -0
  75. package/client/web/src/components/QzonePermissionPan.vue +150 -0
  76. package/client/web/src/components/RawMsgRenderPreviewPan.vue +190 -0
  77. package/client/web/src/components/ThemeColorPickerPan.vue +420 -0
  78. package/client/web/src/components/TinySessionBody.vue +51 -0
  79. package/client/web/src/components/UmamiInfoPan.vue +1549 -0
  80. package/client/web/src/components/UpdatePan.vue +263 -0
  81. package/client/web/src/components/ViewerCom.vue +1360 -0
  82. package/client/web/src/components/VoiceMsg.vue +626 -0
  83. package/client/web/src/components/WelPan.vue +894 -0
  84. package/client/web/src/components/msg-body/.gitkeep +0 -0
  85. package/client/web/src/components/msg-component/JsonSegComp.vue +138 -0
  86. package/client/web/src/components/msg-component/XmlSegComp.vue +132 -0
  87. package/client/web/src/components/msg-component/jsonComp/AutoReply.vue +97 -0
  88. package/client/web/src/components/msg-component/jsonComp/Contact.lua.vue +129 -0
  89. package/client/web/src/components/msg-component/jsonComp/Feed.lua.vue +94 -0
  90. package/client/web/src/components/msg-component/jsonComp/Forum.vue +84 -0
  91. package/client/web/src/components/msg-component/jsonComp/Mannounce.vue +111 -0
  92. package/client/web/src/components/msg-component/jsonComp/Map.vue +52 -0
  93. package/client/web/src/components/msg-component/jsonComp/Miniapp.lua.vue +53 -0
  94. package/client/web/src/components/msg-component/jsonComp/Miniapp.vue +69 -0
  95. package/client/web/src/components/msg-component/jsonComp/Music.lua.vue +135 -0
  96. package/client/web/src/components/msg-component/jsonComp/Tuwen.lua.vue +56 -0
  97. package/client/web/src/components/notice-component/.gitkeep +0 -0
  98. package/client/web/src/components/notice-component/MealHungryPan.vue +119 -0
  99. package/client/web/src/components/tooltip/CustomFaceTooltip.vue +22 -0
  100. package/client/web/src/components/tooltip/Tooltip.vue +50 -0
  101. package/client/web/src/components/tooltip/Tooltips.vue +14 -0
  102. package/client/web/src/components/tooltip/UserInfoTooltip.vue +69 -0
  103. package/client/web/src/function/base.ts +238 -0
  104. package/client/web/src/function/connect.ts +2042 -0
  105. package/client/web/src/function/debug.ts +10 -0
  106. package/client/web/src/function/elements/information.ts +141 -0
  107. package/client/web/src/function/elements/system.ts +101 -0
  108. package/client/web/src/function/elements/vueComp.ts +62 -0
  109. package/client/web/src/function/favicon.ts +76 -0
  110. package/client/web/src/function/input.ts +69 -0
  111. package/client/web/src/function/model/emoji.ts +127 -0
  112. package/client/web/src/function/model/img.ts +150 -0
  113. package/client/web/src/function/model/msg-body.ts +51 -0
  114. package/client/web/src/function/msg.ts +2674 -0
  115. package/client/web/src/function/notify.ts +225 -0
  116. package/client/web/src/function/option.ts +749 -0
  117. package/client/web/src/function/satori-model.ts +818 -0
  118. package/client/web/src/function/satori.ts +325 -0
  119. package/client/web/src/function/sender.ts +178 -0
  120. package/client/web/src/function/tooltip.ts +49 -0
  121. package/client/web/src/function/utils/appUtil.ts +2288 -0
  122. package/client/web/src/function/utils/avatarUtil.ts +31 -0
  123. package/client/web/src/function/utils/backgroundUtil.ts +110 -0
  124. package/client/web/src/function/utils/linkViewUtil.ts +101 -0
  125. package/client/web/src/function/utils/localHistoryUtil.ts +517 -0
  126. package/client/web/src/function/utils/msgUtil.ts +1242 -0
  127. package/client/web/src/function/utils/pinyin.ts +141 -0
  128. package/client/web/src/function/utils/recordUtil.ts +187 -0
  129. package/client/web/src/function/utils/sessionUtil.ts +114 -0
  130. package/client/web/src/function/utils/systemUtil.ts +664 -0
  131. package/client/web/src/main.ts +91 -0
  132. package/client/web/src/pages/Chat.vue +3453 -0
  133. package/client/web/src/pages/Friends.vue +636 -0
  134. package/client/web/src/pages/Info.vue +717 -0
  135. package/client/web/src/pages/Messages.vue +875 -0
  136. package/client/web/src/pages/Options.vue +82 -0
  137. package/client/web/src/pages/Qzone.vue +1178 -0
  138. package/client/web/src/pages/chat-view/ChatDanmaku.vue +759 -0
  139. package/client/web/src/pages/chat-view/ChatGlagame.vue +642 -0
  140. package/client/web/src/pages/chat-view/ChatTerminal.vue +1044 -0
  141. package/client/web/src/pages/chat-view/SystemNotice.vue +171 -0
  142. package/client/web/src/pages/options/OptAccount.vue +107 -0
  143. package/client/web/src/pages/options/OptAddon.vue +185 -0
  144. package/client/web/src/pages/options/OptDev.vue +704 -0
  145. package/client/web/src/pages/options/OptFunction.vue +403 -0
  146. package/client/web/src/pages/options/OptInfo.vue +165 -0
  147. package/client/web/src/pages/options/OptView.vue +846 -0
  148. package/client/web/src/runtime/backend.ts +310 -0
  149. package/client/web/src/state/auth.ts +14 -0
  150. package/client/web/src/state/chat.ts +36 -0
  151. package/client/web/src/state/connection.ts +20 -0
  152. package/client/web/src/state/contact.ts +37 -0
  153. package/client/web/src/state/qzone.ts +18 -0
  154. package/client/web/src/state/sessionHistory.ts +25 -0
  155. package/client/web/src/state/settings.ts +18 -0
  156. package/client/web/src/state/sticker.ts +10 -0
  157. package/client/web/src/state/ui.ts +56 -0
  158. package/client/web/tsconfig.json +27 -0
  159. package/client/web/tsconfig.tsbuildinfo +1 -0
  160. package/client/web/vite.config.ts +33 -0
  161. package/dist/index.js +1 -12
  162. package/dist/style.css +1 -1
  163. package/lib/index.js +2070 -2077
  164. package/package.json +15 -2
  165. package/readme.md +0 -22
  166. package/src/bootstrap.ts +71 -0
  167. package/src/cache.ts +319 -0
  168. package/src/config.ts +23 -35
  169. package/src/database.ts +650 -0
  170. package/src/index.ts +27 -59
  171. package/src/media.ts +302 -0
  172. package/src/recorder.ts +175 -0
  173. package/src/self-message.ts +456 -0
  174. package/src/server.d.ts +26 -0
  175. package/src/types.ts +108 -48
  176. package/src/web.ts +712 -0
  177. package/client/vue/chat-logic.ts +0 -683
  178. package/client/vue/composables/useChatActions.ts +0 -61
  179. package/client/vue/composables/useChatData.ts +0 -185
  180. package/client/vue/composables/useImageCache.ts +0 -281
  181. package/client/vue/composables/useVideoCache.ts +0 -125
  182. package/client/vue/types.ts +0 -72
  183. package/lib/api-handlers.d.ts +0 -25
  184. package/lib/config.d.ts +0 -14
  185. package/lib/file-manager.d.ts +0 -124
  186. package/lib/index.d.ts +0 -17
  187. package/lib/logger.d.ts +0 -9
  188. package/lib/message-handler.d.ts +0 -35
  189. package/lib/types.d.ts +0 -57
  190. package/lib/utils.d.ts +0 -18
  191. package/src/api-handlers.ts +0 -646
  192. package/src/file-manager.ts +0 -1436
  193. package/src/message-handler.ts +0 -507
  194. package/src/utils.ts +0 -189
@@ -0,0 +1,759 @@
1
+ <!--
2
+ * @FileDescription: 聊天面板页面(弹幕样式)
3
+ * @Author: Stapxs
4
+ * @Date: 2024/07/17
5
+ * @Version: 1.0 - 初始版本
6
+ * @Description: 这是个弹幕样式的聊天面板
7
+ -->
8
+ <!-- eslint-disable max-len -->
9
+
10
+ <template>
11
+ <div
12
+ id="chat-pan"
13
+ :class="
14
+ 'chat-pan' +
15
+ (uiStore.openSideBar ? ' open' : '') +
16
+ (['linux', 'win32'].includes(backend.platform ?? '') ? ' withBar' : '')
17
+ ">
18
+ <div class="danmu-pan">
19
+ <vue-danmaku
20
+ v-if="containerReady"
21
+ ref="danmakuRef"
22
+ style="height: calc(100vh - 40px); width: 100%"
23
+ :channels="0"
24
+ :danmus="danmus"
25
+ :speeds="opt.speeds"
26
+ random-channel
27
+ :top="2"
28
+ :loop="opt.loop"
29
+ use-slot>
30
+ <div class="controller">
31
+ <div
32
+ class="back"
33
+ @click="openLeftBar">
34
+ <font-awesome-icon :icon="['fas', 'angle-left']" />
35
+ </div>
36
+ <div
37
+ class="back"
38
+ @click="opera">
39
+ <font-awesome-icon
40
+ v-if="parseIndex == -1"
41
+ :icon="['fas', 'pause']" />
42
+ <font-awesome-icon
43
+ v-else
44
+ :icon="['fas', 'play']" />
45
+ </div>
46
+ <div class="loop">
47
+ <font-awesome-icon :icon="['fas', 'arrows-rotate']" />
48
+ <label for="chat-danmu-loop" class="sr-only">{{ $t('循环播放弹幕') }}</label>
49
+ <label class="ss-switch">
50
+ <input
51
+ id="chat-danmu-loop"
52
+ v-model="opt.loop"
53
+ type="checkbox"
54
+ checked>
55
+ <div>
56
+ <div />
57
+ </div>
58
+ </label>
59
+ </div>
60
+ <div class="space" />
61
+ <div class="ss-range">
62
+ <font-awesome-icon
63
+ :class="opt.speeds < 120 ? 'w' : ''"
64
+ :icon="['fas', 'gauge-high']" />
65
+ <label for="chat-danmu-speed" class="sr-only">{{ $t('弹幕速度') }}</label>
66
+ <input
67
+ id="chat-danmu-speed"
68
+ v-model="opt.speeds"
69
+ :style="{ 'background-size': `${opt.speeds / 8}% 100%` }"
70
+ type="range"
71
+ min="20"
72
+ max="800"
73
+ step="20">
74
+ <span
75
+ :style="{ 'color': `var(--color-font${opt.speeds / 8 > 50 ? '-r' : ''})` }">
76
+ {{ opt.speeds }} px/s
77
+ </span>
78
+ </div>
79
+ </div>
80
+ <div class="controller input">
81
+ <label for="chat-danmu-input" class="sr-only">{{ $t('弹幕消息输入框') }}</label>
82
+ <input
83
+ id="chat-danmu-input"
84
+ v-model="msg"
85
+ class="msgInput"
86
+ @keyup="sendMsg"
87
+ @paste="addImg">
88
+ </div>
89
+ <template #dm="{ index, danmu }">
90
+ <div
91
+ :data-id="index"
92
+ :class="
93
+ 'danmu' +
94
+ (index == 0 ? ' new' : '') +
95
+ (authStore.loginInfo.uin == danmu.id
96
+ ? ' me'
97
+ : '') +
98
+ (parseIndex != index && parseIndex != -1
99
+ ? ' opacity'
100
+ : '')
101
+ "
102
+ @mouseenter="pause(index)"
103
+ @mouseleave="play"
104
+ @touchstart="pause(index)"
105
+ @touchend="play">
106
+ <img
107
+ name="avatar"
108
+ :src="
109
+ danmu.avatar || '/img/icons/icon.svg'
110
+ ">
111
+ <a>{{ danmus.length - index + 1 }}</a>
112
+ <span>{{ danmu.text }}</span>
113
+ </div>
114
+ </template>
115
+ <div :class="'danmu-bg' + (parseIndex != -1 ? ' hidden' : '')">
116
+ <svg
117
+ class="bg"
118
+ width="930"
119
+ height="414"
120
+ viewBox="0 0 930 414"
121
+ fill="none"
122
+ xmlns="http://www.w3.org/2000/svg">
123
+ <g clip-path="url(#clip0_810_16)">
124
+ <rect
125
+ width="1.40442"
126
+ height="49"
127
+ rx="0.70221"
128
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 455.05 67.6182)"
129
+ fill="var(--color-main)" />
130
+ <path
131
+ d="M402.229 113.088L407.629 103L413.029 113.088L421 117.867L413.029 122.646L407.629 133L403.514 122.646L394 117.867L402.229 113.088Z"
132
+ stroke="var(--color-main)"
133
+ stroke-linecap="round" />
134
+ <rect
135
+ width="1.40442"
136
+ height="49"
137
+ rx="0.70221"
138
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 516.05 146.936)"
139
+ fill="var(--color-main)" />
140
+ <path
141
+ d="M463.229 192.406L468.629 182.318L474.029 192.406L482 197.185L474.029 201.964L468.629 212.318L464.514 201.964L455 197.185L463.229 192.406Z"
142
+ stroke="var(--color-main)"
143
+ stroke-linecap="round" />
144
+ <rect
145
+ width="1.40442"
146
+ height="49"
147
+ rx="0.70221"
148
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 330.05 197.936)"
149
+ fill="var(--color-main)" />
150
+ <path
151
+ d="M277.229 243.406L282.629 233.318L288.029 243.406L296 248.185L288.029 252.964L282.629 263.318L278.514 252.964L269 248.185L277.229 243.406Z"
152
+ stroke="var(--color-main)"
153
+ stroke-linecap="round" />
154
+ <rect
155
+ width="1.40442"
156
+ height="49"
157
+ rx="0.70221"
158
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 468.05 290.936)"
159
+ fill="var(--color-main)" />
160
+ <path
161
+ d="M415.229 336.406L420.629 326.318L426.029 336.406L434 341.185L426.029 345.964L420.629 356.318L416.514 345.964L407 341.185L415.229 336.406Z"
162
+ stroke="var(--color-main)"
163
+ stroke-linecap="round" />
164
+ <rect
165
+ width="1.40442"
166
+ height="49"
167
+ rx="0.70221"
168
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 656.05 224.936)"
169
+ fill="var(--color-main)" />
170
+ <path
171
+ d="M603.229 270.406L608.629 260.318L614.029 270.406L622 275.185L614.029 279.964L608.629 290.318L604.514 279.964L595 275.185L603.229 270.406Z"
172
+ stroke="var(--color-main)"
173
+ stroke-linecap="round" />
174
+ <rect
175
+ width="1.40442"
176
+ height="49"
177
+ rx="0.70221"
178
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 803.05 70.9359)"
179
+ fill="var(--color-main)" />
180
+ <path
181
+ d="M750.229 116.406L755.629 106.318L761.029 116.406L769 121.185L761.029 125.964L755.629 136.318L751.514 125.964L742 121.185L750.229 116.406Z"
182
+ stroke="var(--color-main)"
183
+ stroke-linecap="round" />
184
+ <rect
185
+ width="1.40442"
186
+ height="49"
187
+ rx="0.70221"
188
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 864.05 276.936)"
189
+ fill="var(--color-main)" />
190
+ <path
191
+ d="M811.229 322.406L816.629 312.318L822.029 322.406L830 327.185L822.029 331.964L816.629 342.318L812.514 331.964L803 327.185L811.229 322.406Z"
192
+ stroke="var(--color-main)"
193
+ stroke-linecap="round" />
194
+ <rect
195
+ width="1.40442"
196
+ height="49"
197
+ rx="0.70221"
198
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 144.05 183.936)"
199
+ fill="var(--color-main)" />
200
+ <path
201
+ d="M91.2286 229.406L96.6286 219.318L102.029 229.406L110 234.185L102.029 238.964L96.6286 249.318L92.5143 238.964L83 234.185L91.2286 229.406Z"
202
+ stroke="var(--color-main)"
203
+ stroke-linecap="round" />
204
+ <rect
205
+ width="1.40442"
206
+ height="49"
207
+ rx="0.70221"
208
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 171.05 34.9359)"
209
+ fill="var(--color-main)" />
210
+ <rect
211
+ width="1.40442"
212
+ height="49"
213
+ rx="0.70221"
214
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 256.699 175.936)"
215
+ fill="var(--color-main)" />
216
+ <rect
217
+ width="1.40442"
218
+ height="49"
219
+ rx="0.70221"
220
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 701.699 132.936)"
221
+ fill="var(--color-main)" />
222
+ <rect
223
+ width="1.40442"
224
+ height="92.07"
225
+ rx="0.70221"
226
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 302.699 16.9359)"
227
+ fill="var(--color-main)" />
228
+ <rect
229
+ width="1.40442"
230
+ height="92.07"
231
+ rx="0.70221"
232
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 344.4 326.936)"
233
+ fill="var(--color-main)" />
234
+ <rect
235
+ width="1.40442"
236
+ height="92.07"
237
+ rx="0.70221"
238
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 657.4 337.936)"
239
+ fill="var(--color-main)" />
240
+ <rect
241
+ width="1.40442"
242
+ height="92.07"
243
+ rx="0.70221"
244
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 847.4 167.936)"
245
+ fill="var(--color-main)" />
246
+ <path
247
+ d="M118.229 80.4062L123.629 70.3177L129.029 80.4062L137 85.185L129.029 89.9638L123.629 100.318L119.514 89.9638L110 85.185L118.229 80.4062Z"
248
+ stroke="var(--color-main)"
249
+ stroke-linecap="round" />
250
+ <rect
251
+ width="1.40442"
252
+ height="49"
253
+ rx="0.70221"
254
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 205.05 372.936)"
255
+ fill="var(--color-main)" />
256
+ <path
257
+ d="M152.229 418.406L157.629 408.318L163.029 418.406L171 423.185L163.029 427.964L157.629 438.318L153.514 427.964L144 423.185L152.229 418.406Z"
258
+ stroke="var(--color-main)"
259
+ stroke-linecap="round" />
260
+ <rect
261
+ width="1.40442"
262
+ height="49"
263
+ rx="0.70221"
264
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 756.05 408.936)"
265
+ fill="var(--color-main)" />
266
+ <rect
267
+ width="1.40442"
268
+ height="49"
269
+ rx="0.70221"
270
+ transform="matrix(-0.745625 -0.666366 -0.666366 0.745625 686.05 5.93591)"
271
+ fill="var(--color-main)" />
272
+ <path
273
+ d="M633.229 51.4062L638.629 41.3177L644.029 51.4062L652 56.185L644.029 60.9638L638.629 71.3177L634.514 60.9638L625 56.185L633.229 51.4062Z"
274
+ stroke="var(--color-main)"
275
+ stroke-linecap="round" />
276
+ <circle
277
+ cx="291.5"
278
+ cy="122.5"
279
+ r="13"
280
+ stroke="var(--color-main)"
281
+ stroke-linecap="round" />
282
+ <circle
283
+ cx="846.5"
284
+ cy="407.5"
285
+ r="13"
286
+ stroke="var(--color-main)"
287
+ stroke-linecap="round" />
288
+ <circle
289
+ cx="910.5"
290
+ cy="64.5"
291
+ r="13"
292
+ stroke="var(--color-main)"
293
+ stroke-linecap="round" />
294
+ </g>
295
+ <defs>
296
+ <clipPath id="clip0_810_16">
297
+ <rect
298
+ width="930"
299
+ height="414"
300
+ rx="7"
301
+ fill="white" />
302
+ </clipPath>
303
+ </defs>
304
+ </svg>
305
+ <span class="name">{{
306
+ chatStore.chatInfo.show.name
307
+ }}</span>
308
+ <div class="info">
309
+ <span class="time">
310
+ {{
311
+ list[list.length - 1]
312
+ ? $t('上次消息 - {time}', {
313
+ time: Intl.DateTimeFormat(trueLang, {
314
+ hour: 'numeric',
315
+ minute: 'numeric',
316
+ second: 'numeric',
317
+ }).format(
318
+ new Date(
319
+ list[list.length - 1].time *
320
+ 1000,
321
+ ),
322
+ ),
323
+ })
324
+ : $t('暂无消息')
325
+ }}
326
+ </span>
327
+ </div>
328
+ </div>
329
+ </vue-danmaku>
330
+ </div>
331
+ </div>
332
+ </template>
333
+
334
+ <script lang="ts" setup>
335
+ import vueDanmaku from 'vue3-danmaku'
336
+
337
+ import { Connector } from '../../function/connect'
338
+ import { ref, onMounted, watch, useTemplateRef, nextTick } from 'vue'
339
+ import { getMsgRawTxt, sendMsgRaw } from '../../function/utils/msgUtil'
340
+ import { parseMsg } from '../../function/sender'
341
+ import {
342
+ MsgItemElem,
343
+ SQCodeElem,
344
+ } from '../../function/elements/information'
345
+ import { PopInfo, PopType } from '../../function/base'
346
+ import { getTrueLang } from '../../function/utils/systemUtil'
347
+ import { backend } from '../../runtime/backend'
348
+ import { i18n } from '../../main'
349
+ import { useUIStore } from '../../state/ui'
350
+ import { useAuthStore } from '../../state/auth'
351
+ import { useChatStore } from '../../state/chat'
352
+
353
+ defineOptions({ name: 'ChatDan' })
354
+
355
+ const uiStore = useUIStore()
356
+ const authStore = useAuthStore()
357
+ const chatStore = useChatStore()
358
+ const $t = i18n.global.t
359
+
360
+ const props = defineProps<{
361
+ chat: any
362
+ list: any
363
+ mumberInfo: any
364
+ }>()
365
+
366
+ const danmakuRef = useTemplateRef<any>('danmakuRef')
367
+
368
+ const opt = ref({
369
+ speeds: 140,
370
+ loop: true,
371
+ })
372
+ const trueLang = getTrueLang()
373
+ const danmus = ref<any[]>([])
374
+ const imgCache = ref<string[]>([])
375
+ const sendCache = ref<MsgItemElem[]>([])
376
+ const msg = ref('')
377
+ const parseIndex = ref(-1)
378
+ const operaParse = ref(false)
379
+ const containerReady = ref(false)
380
+
381
+ onMounted(() => {
382
+ // 监听元素尺寸变化
383
+ const ele = document.getElementById('chat-pan') as Element
384
+ const resizeObserver = new ResizeObserver(() => {
385
+ danmakuRef.value?.resize()
386
+ })
387
+ resizeObserver.observe(ele)
388
+ // 监听消息列表,刷新到弹幕列表中
389
+ watch(() => props.list.length, updateList)
390
+ // 等待容器渲染完成后再初始化弹幕组件
391
+ nextTick(() => {
392
+ containerReady.value = true
393
+ })
394
+ })
395
+
396
+ function openLeftBar() {
397
+ uiStore.openSideBar = !uiStore.openSideBar
398
+ }
399
+
400
+ function pause(index: number) {
401
+ danmakuRef.value?.pause()
402
+ parseIndex.value = index
403
+ }
404
+
405
+ function play() {
406
+ if (!operaParse.value) {
407
+ danmakuRef.value?.play()
408
+ parseIndex.value = -1
409
+ }
410
+ }
411
+
412
+ function opera() {
413
+ if (parseIndex.value == -1) {
414
+ operaParse.value = true
415
+ pause(0)
416
+ } else {
417
+ operaParse.value = false
418
+ play()
419
+ }
420
+ }
421
+
422
+ function sendMsg(event: KeyboardEvent) {
423
+ if (event.keyCode === 13 && msg.value != '') {
424
+ const parsedMsg = parseMsg(
425
+ msg.value, sendCache.value, imgCache.value)
426
+ if (props.chat.show.temp) {
427
+ sendMsgRaw(
428
+ props.chat.show.id + '/' + props.chat.show.temp,
429
+ props.chat.show.type,
430
+ parsedMsg,
431
+ )
432
+ } else {
433
+ sendMsgRaw(props.chat.show.id, props.chat.show.type, parsedMsg)
434
+ }
435
+ // 发送后处理
436
+ sendCache.value = []
437
+ imgCache.value = []
438
+ msg.value = ''
439
+ }
440
+ }
441
+
442
+ function addImg(event: ClipboardEvent) {
443
+ // 判断粘贴类型
444
+ if (!(event.clipboardData && event.clipboardData.items)) {
445
+ return
446
+ }
447
+ for (
448
+ let i = 0, len = event.clipboardData.items.length;
449
+ i < len;
450
+ i++
451
+ ) {
452
+ const item = event.clipboardData.items[i]
453
+ if (item.kind === 'file') {
454
+ setImg(item.getAsFile())
455
+ // 阻止默认行为
456
+ event.preventDefault()
457
+ }
458
+ }
459
+ }
460
+
461
+ function setImg(blob: File | null) {
462
+ const popInfo = new PopInfo()
463
+ if (
464
+ blob !== null &&
465
+ blob.type.indexOf('image/') >= 0 &&
466
+ blob.size !== 0
467
+ ) {
468
+ if (blob.size < 3145728) {
469
+ // 转换为 Base64
470
+ const reader = new FileReader()
471
+ reader.readAsDataURL(blob)
472
+ reader.onloadend = () => {
473
+ const base64data = reader.result as string
474
+ if (base64data !== null) {
475
+ // 记录图片信息
476
+ // 只要你内存够猛,随便 cache 图片,这边就不做限制了
477
+ imgCache.value.push(base64data)
478
+ }
479
+ }
480
+ } else {
481
+ popInfo.add(PopType.INFO, $t('图片过大'))
482
+ }
483
+ }
484
+ }
485
+
486
+ function addSpecialMsg(data: SQCodeElem) {
487
+ if (data !== undefined) {
488
+ const index = sendCache.value.length
489
+ sendCache.value.push(data.msgObj)
490
+ if (data.addText === true) {
491
+ const token = data.msgObj?.type === 'image' ? '[图片]' : '[SQ:' + index + ']'
492
+ if (data.addTop === true) {
493
+ msg.value = token + msg.value
494
+ } else {
495
+ msg.value += token
496
+ }
497
+ }
498
+ return index
499
+ }
500
+ return -1
501
+ }
502
+
503
+ defineExpose({ addSpecialMsg })
504
+
505
+ function updateList() {
506
+ if (opt.value.loop) {
507
+ // 如果弹幕列表长度是 20,请求更多消息
508
+ if (props.list.length == 20) {
509
+ const type = chatStore.chatInfo.show.type
510
+ const id = chatStore.chatInfo.show.id
511
+ const firstMsgId = props.list[0].message_id ?? 0
512
+ let name
513
+ const fullPage =
514
+ authStore.jsonMap.message_list?.pagerType ==
515
+ 'full'
516
+ if (
517
+ authStore.jsonMap.message_list &&
518
+ type != 'group'
519
+ ) {
520
+ name = authStore.jsonMap.message_list.private_name
521
+ } else {
522
+ name = authStore.jsonMap.message_list.name
523
+ }
524
+ Connector.send(
525
+ name ?? 'get_chat_history',
526
+ {
527
+ group_id: type == 'group' ? id : undefined,
528
+ user_id: type != 'group' ? id : undefined,
529
+ message_id: firstMsgId,
530
+ count: fullPage? chatStore.messageList.length + 10: 10,
531
+ },
532
+ 'getChatHistory',
533
+ )
534
+ }
535
+ const list = props.list.map((data: any) => {
536
+ return {
537
+ text: getMsgRawTxt(data),
538
+ id: data.sender.user_id,
539
+ }
540
+ })
541
+ // list 只需要最新的 30 条消息,多余的从前删除
542
+ if (list.length > 30) {
543
+ list.splice(0, list.length - 30)
544
+ }
545
+ // 倒序, 保证最新的消息最现出来
546
+ danmus.value = list.reverse()
547
+ } else {
548
+ // 只添加最后一条
549
+ danmakuRef.value?.push({
550
+ text: getMsgRawTxt(props.list[props.list.length - 1]),
551
+ id: props.list[props.list.length - 1].sender.user_id,
552
+ })
553
+ }
554
+ }
555
+ </script>
556
+
557
+ <style>
558
+ .danmus {
559
+ margin-top: 15px;
560
+ height: calc(100% - 40px) !important;
561
+ }
562
+ </style>
563
+ <style scoped>
564
+ .chat-pan {
565
+ background: var(--color-card-1);
566
+ }
567
+
568
+ .chat-pan > div {
569
+ pointer-events: visible;
570
+ }
571
+ .chat-pan > div:first-child {
572
+ background: var(--color-card);
573
+ }
574
+
575
+ .controller {
576
+ position: absolute;
577
+ z-index: 1;
578
+ width: calc(100% - 10px);
579
+ height: 50px;
580
+ pointer-events: none;
581
+ display: flex;
582
+ flex-direction: row;
583
+ padding: 0 10px;
584
+ align-items: center;
585
+ flex-wrap: wrap;
586
+ }
587
+ .controller svg {
588
+ color: var(--color-font-2);
589
+ }
590
+ .controller > div:not(.space) {
591
+ height: 30px;
592
+ border: 2px solid var(--color-card-2);
593
+ border-radius: 7px;
594
+ backdrop-filter: blur(15px);
595
+ background: rgba(var(--color-card-rgb), 0.3);
596
+ pointer-events: all;
597
+ margin-right: 10px;
598
+ cursor: pointer;
599
+ }
600
+ .controller > div.space {
601
+ flex: 1;
602
+ }
603
+ .controller > div.back {
604
+ width: 30px;
605
+ display: flex;
606
+ justify-content: center;
607
+ align-items: center;
608
+ }
609
+ .controller > div.ss-range {
610
+ padding-right: 5px;
611
+ }
612
+ .controller > div.ss-range > svg {
613
+ padding: 8px 0;
614
+ color: #fff;
615
+ margin-right: -25px;
616
+ z-index: 1;
617
+ margin-left: 12px;
618
+ }
619
+ .controller > div.ss-range > svg.w {
620
+ color: var(--color-font-2);
621
+ }
622
+ .controller > div.ss-range > input {
623
+ background-color: transparent;
624
+ }
625
+ .controller > div.ss-range > span {
626
+ color: var(--color-font-2);
627
+ font-size: 0.7rem;
628
+ margin-top: 2px;
629
+ }
630
+
631
+ .controller > div.loop {
632
+ width: 80px;
633
+ display: flex;
634
+ flex-direction: row;
635
+ align-items: center;
636
+ }
637
+ .controller > div.loop > svg {
638
+ margin: 0 10px;
639
+ }
640
+ .controller > div.loop > label {
641
+ --switch-dot-margin: 6px;
642
+ --switch-height: 20px;
643
+ min-width: 35px;
644
+ }
645
+
646
+ .controller.input {
647
+ bottom: 0;
648
+ }
649
+ .msgInput {
650
+ pointer-events: all;
651
+ width: calc(100% - 35px);
652
+ padding: 0 10px;
653
+ height: 30px;
654
+ border: 2px solid var(--color-card-2);
655
+ outline: 0;
656
+ border-radius: 7px;
657
+ background: rgba(var(--color-card-rgb), 0.3);
658
+ backdrop-filter: blur(15px);
659
+ }
660
+
661
+ .danmu-pan {
662
+ border: 2px solid var(--color-card-2);
663
+ border-radius: 7px;
664
+ margin: 20px;
665
+ }
666
+
667
+ .danmu {
668
+ display: flex;
669
+ align-items: center;
670
+ padding: 5px 10px;
671
+ margin: 10px 0;
672
+ border-radius: 7px;
673
+
674
+ transition:
675
+ background 0.5s,
676
+ color 0.5s,
677
+ opacity 0.5s;
678
+ }
679
+ .danmu.opacity {
680
+ opacity: 0.5;
681
+ }
682
+ .danmu.me {
683
+ background: var(--color-card-1);
684
+ }
685
+ .danmu.me > span {
686
+ color: var(--color-font);
687
+ }
688
+ .danmu.new {
689
+ background: var(--color-main);
690
+ }
691
+ .danmu.new > span {
692
+ color: var(--color-font-r) !important;
693
+ }
694
+ .danmu > img {
695
+ border-radius: 100%;
696
+ width: 1.4rem;
697
+ margin-right: 10px;
698
+ border: 1px solid var(--color-main);
699
+ background: var(--color-card-2);
700
+ }
701
+ .danmu > span {
702
+ color: var(--color-font-2);
703
+ font-size: 0.9rem;
704
+ }
705
+ .danmu > a {
706
+ color: var(--color-font-1);
707
+ background: var(--color-card-2);
708
+ margin-right: 10px;
709
+ padding: 2px;
710
+ border-radius: 7px;
711
+ width: 1.3rem;
712
+ text-align: center;
713
+ font-size: 0.7rem;
714
+ }
715
+ .danmu.new > a {
716
+ display: none;
717
+ }
718
+
719
+ .danmu-bg {
720
+ transition: opacity 0.7s;
721
+ width: 100%;
722
+ height: calc(100% - 60px);
723
+ border-radius: 7px;
724
+ display: flex;
725
+ flex-direction: column-reverse;
726
+ padding: 10px;
727
+ opacity: 0.1;
728
+ position: absolute;
729
+ z-index: -1;
730
+ }
731
+ .danmu-bg.hidden {
732
+ opacity: 0;
733
+ }
734
+ .danmu-bg span {
735
+ color: var(--color-main);
736
+ font-weight: bold;
737
+ }
738
+ .danmu-bg > span.name {
739
+ white-space: nowrap;
740
+ font-size: 50px;
741
+ }
742
+ .danmu-bg > svg.bg {
743
+ width: 210%;
744
+ position: absolute;
745
+ z-index: -2;
746
+ left: -20%;
747
+ top: -15%;
748
+ opacity: 0.9;
749
+ }
750
+ .danmu-bg > div.info {
751
+ background: var(--color-main);
752
+ border-radius: 7px;
753
+ width: fit-content;
754
+ padding: 10px;
755
+ }
756
+ .danmu-bg > div.info span {
757
+ color: var(--color-font-r);
758
+ }
759
+ </style>