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,403 @@
1
+ <!--
2
+ * @FileDescription: 设置页面(功能子页面)
3
+ * @Author: Stapxs
4
+ * @Date: 2022/11/07
5
+ * @Version: 1.0
6
+ -->
7
+ <!-- eslint-disable max-len -->
8
+
9
+ <template>
10
+ <div class="opt-page">
11
+ <div class="ss-card">
12
+ <header>{{ $t('会话选项') }}</header>
13
+ <div class="opt-item">
14
+ <div :class="checkDefault('bubble_sort_user')" />
15
+ <font-awesome-icon :icon="['fas', 'box-open']" />
16
+ <div>
17
+ <label for="opt-function-bubble-sort-user">{{ $t('群收纳盒') }}</label>
18
+ <span>{{ $t('全都放出来!全都放出来!') }}</span>
19
+ </div>
20
+ <label class="ss-switch">
21
+ <input id="opt-function-bubble-sort-user" v-model="settingsStore.sysConfig.bubble_sort_user"
22
+ type="checkbox" name="bubble_sort_user" @change="save">
23
+ <div>
24
+ <div />
25
+ </div>
26
+ </label>
27
+ </div>
28
+ <div class="opt-item">
29
+ <div :class="checkDefault('session_display_mode')" />
30
+ <font-awesome-icon :icon="['fas', 'address-book']" />
31
+ <div>
32
+ <label for="opt-function-session-display-mode">{{ $t('会话显示') }}</label>
33
+ <span>{{ $t('关闭时仅显示最近会话,开启后显示全部会话') }}</span>
34
+ </div>
35
+ <label class="ss-switch">
36
+ <input id="opt-function-session-display-mode" :checked="settingsStore.sysConfig.session_display_mode === 'all'"
37
+ type="checkbox" name="session_display_mode" @change="toggleSessionDisplay">
38
+ <div>
39
+ <div />
40
+ </div>
41
+ </label>
42
+ </div>
43
+ </div>
44
+ <div class="ss-card">
45
+ <header>{{ $t('通知选项') }}</header>
46
+ <div class="opt-item">
47
+ <div :class="checkDefault('group_notice_type')" />
48
+ <font-awesome-icon :icon="['fas', 'user-group']" />
49
+ <div>
50
+ <label for="opt-function-group-notice-type">{{ $t('群消息通知方式') }}</label>
51
+ <span>{{ $t('重要消息将始终发起应用内通知和系统通知') }}</span>
52
+ </div>
53
+ <div class="select-wrapper">
54
+ <select id="opt-function-group-notice-type"
55
+ v-model="settingsStore.sysConfig.group_notice_type"
56
+ name="group_notice_type" title="group_notice_type" @change="save">
57
+ <option value="none">
58
+ {{ $t('不通知(默认)') }}
59
+ </option>
60
+ <option value="inner">
61
+ {{ $t('仅应用内通知') }}
62
+ </option>
63
+ <option value="all">
64
+ {{ $t('应用内通知和系统通知') }}
65
+ </option>
66
+ </select>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ <div class="ss-card">
71
+ <header>{{ $t('聊天选项') }}</header>
72
+ <div class="opt-item">
73
+ <div :class="checkDefault('opt_no_auto_load_image')" />
74
+ <font-awesome-icon :icon="['fas', 'image']" />
75
+ <div>
76
+ <label for="opt-function-no-auto-load-image">{{ $t('不自动加载图片') }}</label>
77
+ <span>{{ $t('图片消息默认显示占位符,点击后再加载') }}</span>
78
+ </div>
79
+ <label class="ss-switch">
80
+ <input id="opt-function-no-auto-load-image" v-model="settingsStore.sysConfig.opt_no_auto_load_image"
81
+ type="checkbox" name="opt_no_auto_load_image" @change="save">
82
+ <div>
83
+ <div />
84
+ </div>
85
+ </label>
86
+ </div>
87
+ <div class="opt-item">
88
+ <div :class="checkDefault('send_key')" />
89
+ <font-awesome-icon :icon="['fas', 'keyboard']" />
90
+ <div>
91
+ <label for="opt-function-send-key">{{ $t('发送键') }}</label>
92
+ <span>{{ $t('你可以使用其他组合键来换行') }}</span>
93
+ </div>
94
+ <div class="select-wrapper">
95
+ <select v-if="backend.platform === 'darwin' || backend.platform === 'ios'" id="opt-function-send-key" v-model="settingsStore.sysConfig.send_key"
96
+ name="send_key" title="send_key" @change="save">
97
+ <option value="none">
98
+ Enter
99
+ </option>
100
+ <option value="shift">
101
+ Shift + Enter (⇧)
102
+ </option>
103
+ <option value="ctrl">
104
+ Control + Enter (⌃)
105
+ </option>
106
+ <option value="alt">
107
+ Option + Enter (⌥)
108
+ </option>
109
+ <option value="meta">
110
+ Command + Enter (⌘)
111
+ </option>
112
+ </select>
113
+ <select v-else id="opt-function-send-key" v-model="settingsStore.sysConfig.send_key"
114
+ name="send_key" title="send_key" @change="save">
115
+ <option value="none">
116
+ Enter
117
+ </option>
118
+ <option value="shift">
119
+ Shift + Enter
120
+ </option>
121
+ <option value="ctrl">
122
+ Ctrl + Enter
123
+ </option>
124
+ <option value="alt">
125
+ Alt + Enter
126
+ </option>
127
+ <option value="meta">
128
+ Meta + Enter
129
+ </option>
130
+ </select>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ <div v-if="backend.type === 'tauri'" class="ss-card">
135
+ <header>{{ $t('消息存储') }}</header>
136
+ <div
137
+ class="opt-item"
138
+ :style="{ 'background': settingsStore.sysConfig.enable_local_history ? 'var(--color-card-1)' : 'none' }">
139
+ <div :class="checkDefault('enable_local_history')" />
140
+ <font-awesome-icon :icon="['fas', 'database']" />
141
+ <div>
142
+ <label for="opt-function-enable-local-history">{{ $t('启用消息存储') }}</label>
143
+ <span>{{ $t('保存消息记录何尝不是一种囤囤鼠') }}</span>
144
+ </div>
145
+ <label class="ss-switch">
146
+ <input id="opt-function-enable-local-history" v-model="settingsStore.sysConfig.enable_local_history"
147
+ type="checkbox" name="enable_local_history" @change="save">
148
+ <div>
149
+ <div />
150
+ </div>
151
+ </label>
152
+ </div>
153
+ <div v-if="settingsStore.sysConfig.enable_local_history" class="tip">
154
+ {{
155
+ $t('Stapxs QQ Lite 支持将消息缓存至本地,消息将以加密数据库的方式安全的保存。')
156
+ }}
157
+ </div>
158
+ <div v-if="settingsStore.sysConfig.enable_local_history" class="opt-item">
159
+ <div :class="checkDefault('mixed_load_messages')" />
160
+ <font-awesome-icon :icon="['fas', 'shuffle']" />
161
+ <div>
162
+ <label for="opt-function-mixed-load-messages">{{ $t('混合加载消息(实验性)') }}</label>
163
+ <span>{{ $t('优先加载本地缓存的消息以取得更快的加载速度') }}</span>
164
+ </div>
165
+ <label class="ss-switch">
166
+ <input id="opt-function-mixed-load-messages" v-model="settingsStore.sysConfig.mixed_load_messages"
167
+ type="checkbox"
168
+ name="mixed_load_messages"
169
+ @change="save">
170
+ <div>
171
+ <div />
172
+ </div>
173
+ </label>
174
+ </div>
175
+ <div v-if="settingsStore.sysConfig.enable_local_history" class="opt-item">
176
+ <div :class="checkDefault('disable_local_history_image_cache')" />
177
+ <font-awesome-icon :icon="['fas', 'image']" />
178
+ <div>
179
+ <label for="opt-function-disable-local-history-image-cache">{{ $t('不缓存图片') }}</label>
180
+ <span>{{ $t('开启后将删除已缓存图片,仅保留消息文本') }}</span>
181
+ </div>
182
+ <label class="ss-switch">
183
+ <input id="opt-function-disable-local-history-image-cache" v-model="settingsStore.sysConfig.disable_local_history_image_cache"
184
+ type="checkbox"
185
+ name="disable_local_history_image_cache"
186
+ @change="toggleLocalHistoryImageCache">
187
+ <div>
188
+ <div />
189
+ </div>
190
+ </label>
191
+ </div>
192
+ <div v-if="settingsStore.sysConfig.enable_local_history && dbStats != null" class="db-stats-cards">
193
+ <div class="db-stat-card">
194
+ <font-awesome-icon :icon="['fas', 'message']" />
195
+ <span class="db-stat-value">{{ dbStats.totalMessages.toLocaleString() }}</span>
196
+ <span class="db-stat-label">{{ $t('已存消息') }}</span>
197
+ </div>
198
+ <div class="db-stat-card">
199
+ <font-awesome-icon :icon="['fas', 'database']" />
200
+ <span class="db-stat-value">{{ formatDbSize(dbStats.dbSizeBytes) }}</span>
201
+ <span class="db-stat-label">{{ $t('数据库大小') }}</span>
202
+ </div>
203
+ <div class="db-stat-card">
204
+ <font-awesome-icon :icon="['fas', 'image']" />
205
+ <span class="db-stat-value">{{ dbStats.imageCount > 0 ? formatDbSize(dbStats.imageCacheBytes) : '-' }}</span>
206
+ <span class="db-stat-label">{{ $t('图片缓存') }}{{ dbStats.imageCount > 0 ? '\u00a0(' + dbStats.imageCount.toLocaleString() + ')' : '' }}</span>
207
+ </div>
208
+ </div>
209
+ </div>
210
+ </div>
211
+ </template>
212
+
213
+ <script lang="ts" setup>
214
+ import { ref, watch } from 'vue'
215
+ import { PopInfo, PopType } from '../../function/base'
216
+ import { runASWEvent as save, checkDefault, runAS } from '../../function/option'
217
+ import { i18n } from '../../main'
218
+
219
+ import { backend } from '../../runtime/backend'
220
+ import { dbClearImages, dbGetStats } from '../../function/utils/localHistoryUtil'
221
+ import { useSettingsStore } from '../../state/settings'
222
+ import { useAuthStore } from '../../state/auth'
223
+ import { useUIStore } from '../../state/ui'
224
+
225
+ const settingsStore = useSettingsStore()
226
+ const authStore = useAuthStore()
227
+ const uiStore = useUIStore()
228
+ const $t = i18n.global.t
229
+
230
+ defineOptions({ name: 'ViewOptFunction' })
231
+
232
+ const dbStats = ref<{ totalMessages: number; imageCount: number; imageCacheBytes: number; dbSizeBytes: number } | null>(null)
233
+ const clearImageProgressText = ref('')
234
+
235
+ watch(() => authStore.loginInfo.uin, (uin) => {
236
+ if (uin && settingsStore.sysConfig.enable_local_history) {
237
+ loadDbStats()
238
+ }
239
+ }, { immediate: true })
240
+
241
+ watch(() => settingsStore.sysConfig.enable_local_history, (enabled) => {
242
+ if (enabled && authStore.loginInfo.uin) {
243
+ loadDbStats()
244
+ }
245
+ }, { immediate: true })
246
+
247
+ async function loadDbStats() {
248
+ if (authStore.loginInfo?.uin) {
249
+ dbStats.value = await dbGetStats(authStore.loginInfo.uin)
250
+ }
251
+ }
252
+
253
+ function formatDbSize(bytes: number): string {
254
+ if (bytes < 1024) return `${bytes} B`
255
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
256
+ if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
257
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`
258
+ }
259
+
260
+ function toggleSessionDisplay(event: Event) {
261
+ const sender = event.target as HTMLInputElement
262
+ runAS('session_display_mode', sender.checked ? 'all' : 'recent')
263
+ }
264
+
265
+ function toggleLocalHistoryImageCache(event: Event) {
266
+ save(event)
267
+
268
+ const sender = event.target as HTMLInputElement
269
+ if (!sender.checked) return
270
+
271
+ const selfId = authStore.loginInfo?.uin
272
+ if (!selfId) {
273
+ new PopInfo().add(PopType.INFO, $t('请连接后在进行操作'))
274
+ return
275
+ }
276
+
277
+ const popInfo = {
278
+ title: $t('提醒'),
279
+ html: `<span>${$t('确认要关闭图片缓存吗?所有已缓存图片都将被清除!')}</span>`,
280
+ button: [
281
+ {
282
+ text: $t('确认'),
283
+ fun: async() => {
284
+ uiStore.popBoxList.shift()
285
+
286
+ const progressPop = {
287
+ title: $t('提醒'),
288
+ html: `<span>${$t('正在清理图片缓存 0/0(0%)')}</span>`,
289
+ allowClose: false
290
+ }
291
+
292
+ clearImageProgressText.value = $t('正在清理图片缓存 0/0(0%)')
293
+ uiStore.popBoxList.push(progressPop)
294
+
295
+ const result = await dbClearImages(selfId, (progress) => {
296
+ const text = $t('正在清理图片缓存 {deleted}/{total}({percent}%)', {
297
+ deleted: progress.deleted,
298
+ total: progress.total,
299
+ percent: progress.progress.toFixed(1),
300
+ })
301
+ clearImageProgressText.value = text
302
+ progressPop.html = `<span>${text}</span>`
303
+ })
304
+
305
+ if (uiStore.popBoxList.length > 0) {
306
+ uiStore.popBoxList.shift()
307
+ }
308
+
309
+ new PopInfo().add(
310
+ PopType.INFO,
311
+ $t('图片缓存清理完成,共删除 {count} 项({batches} 批)。', {
312
+ count: result.deleted,
313
+ batches: result.batches,
314
+ }),
315
+ )
316
+ clearImageProgressText.value = ''
317
+ loadDbStats()
318
+ },
319
+ },
320
+ {
321
+ text: $t('取消'),
322
+ master: true,
323
+ fun: () => {
324
+ runAS('disable_local_history_image_cache', false)
325
+ uiStore.popBoxList.shift()
326
+ },
327
+ }
328
+ ],
329
+ }
330
+ uiStore.popBoxList.push(popInfo)
331
+ }
332
+ </script>
333
+ <style>
334
+ .ss-switch input:checked ~ div {
335
+ background: var(--color-main) !important;
336
+ }
337
+
338
+ .ga-share {
339
+ background: var(--color-card-2);
340
+ border-radius: 7px;
341
+ align-items: center;
342
+ margin-top: 10px;
343
+ cursor: pointer;
344
+ display: flex;
345
+ padding: 10px 20px;
346
+ }
347
+
348
+ .ga-share > svg {
349
+ fill: var(--color-font);
350
+ margin-right: 10px;
351
+ width: 20px;
352
+ }
353
+
354
+ .ga-share > a {
355
+ text-decoration: underline;
356
+ color: var(--color-font-1);
357
+ font-size: 0.8rem;
358
+ }
359
+
360
+ .db-stats-cards {
361
+ display: grid;
362
+ grid-template-columns: repeat(3, 1fr);
363
+ gap: 8px;
364
+ margin: 4px 0 8px;
365
+ }
366
+
367
+ .db-stat-card {
368
+ display: flex;
369
+ flex-direction: column;
370
+ align-items: center;
371
+ justify-content: center;
372
+ gap: 4px;
373
+ padding: 12px 8px;
374
+ border-radius: 7px;
375
+ min-width: 0;
376
+ }
377
+
378
+ .db-stat-card > svg {
379
+ width: 16px;
380
+ height: 16px;
381
+ opacity: 0.5;
382
+ flex-shrink: 0;
383
+ }
384
+
385
+ .db-stat-value {
386
+ font-size: 1rem;
387
+ font-weight: 600;
388
+ color: var(--color-font);
389
+ white-space: nowrap;
390
+ overflow: hidden;
391
+ text-overflow: ellipsis;
392
+ max-width: 100%;
393
+ }
394
+
395
+ .db-stat-label {
396
+ font-size: 0.72rem;
397
+ color: var(--color-font-2);
398
+ white-space: nowrap;
399
+ overflow: hidden;
400
+ text-overflow: ellipsis;
401
+ max-width: 100%;
402
+ }
403
+ </style>
@@ -0,0 +1,165 @@
1
+ <!--
2
+ - @FileDescription: 设置页面(群/好友设置页面)
3
+ - @Author: Stapxs
4
+ - @Date: 2023/2/7
5
+ - @Version: 1.0 - 初始版本
6
+ -->
7
+
8
+ <template>
9
+ <div
10
+ class="info-pan-set"
11
+ style="padding: 0">
12
+ <!-- 公用设置 -->
13
+ <!-- 群设置 -->
14
+ <template v-if="type == 'group'">
15
+ <div v-if="chatStore.chatInfo.info.me_info.role == 'owner' ||
16
+ chatStore.chatInfo.info.me_info.role == 'admin'"
17
+ class="opt-item">
18
+ <font-awesome-icon :icon="['fas', 'pen']" />
19
+ <div>
20
+ <label for="opt-info-group-name">{{ $t('群聊名称') }}</label>
21
+ <span>{{ $t('"你们真是害人不浅呐你们这个群"') }}</span>
22
+ </div>
23
+ <input id="opt-info-group-name" v-model="chatStore.chatInfo.show.name" class="ss-input"
24
+ style="width: 150px" type="text" @keyup="setGroupName">
25
+ </div>
26
+ <div class="opt-item">
27
+ <font-awesome-icon :icon="['fas', 'note-sticky']" />
28
+ <div>
29
+ <label for="opt-info-group-card">{{ $t('我的群昵称') }}</label>
30
+ <span>{{ $t('£爺↘僞ηι慹著彡') }}</span>
31
+ </div>
32
+ <input id="opt-info-group-card" v-model="chatStore.chatInfo.info.me_info.card" class="ss-input"
33
+ style="width: 150px" type="text" @change="setGroupCard">
34
+ </div>
35
+ <div class="opt-item">
36
+ <font-awesome-icon :icon="['fas', 'bell']" />
37
+ <div>
38
+ <span>{{ $t('通知群消息') }}</span>
39
+ <span>{{ $t('快来水群快来水群!') }}</span>
40
+ </div>
41
+ <label class="ss-switch">
42
+ <input v-model="canGroupNotice" type="checkbox"
43
+ name="opt_dark" @change="setGroupNotice">
44
+ <div>
45
+ <div />
46
+ </div>
47
+ </label>
48
+ </div>
49
+
50
+ <button class="ss-button"
51
+ style="width: calc(100% - 60px); margin: 10px 30px 0 30px"
52
+ @click="leaveGroup()">
53
+ {{ $t('退出群聊') }}
54
+ </button>
55
+ </template>
56
+ </div>
57
+ </template>
58
+
59
+ <script lang="ts" setup>
60
+ import { useUIStore } from '../../state/ui'
61
+ import { useAuthStore } from '../../state/auth'
62
+ import { useContactStore } from '../../state/contact'
63
+ import { useChatStore } from '../../state/chat'
64
+ import { Connector } from '../../function/connect'
65
+ import { changeGroupNotice, reloadUsers } from '../../function/utils/appUtil'
66
+ import { canGroupNotice } from '../../function/utils/msgUtil'
67
+ import { i18n } from '../../main'
68
+
69
+ defineOptions({ name: 'ViewOptInfo' })
70
+
71
+ const authStore = useAuthStore()
72
+ const contactStore = useContactStore()
73
+ const chatStore = useChatStore()
74
+ const uiStore = useUIStore()
75
+ const $t = i18n.global.t
76
+
77
+ const props = defineProps<{
78
+ type: string
79
+ chat: any
80
+ }>()
81
+
82
+ const emit = defineEmits<{
83
+ 'update_mumber_card': [event: Event, info: any]
84
+ }>()
85
+
86
+ /**
87
+ * 设置群消息通知
88
+ * @param event 输入事件
89
+ */
90
+ function setGroupNotice(event: Event) {
91
+ const status = (event.target as HTMLInputElement).checked
92
+ changeGroupNotice(props.chat.show.id, status)
93
+ }
94
+
95
+ /**
96
+ * 设置群名片
97
+ * @param event 按键事件
98
+ */
99
+ function setGroupCard(event: Event) {
100
+ emit('update_mumber_card', event, chatStore.chatInfo.info.me_info)
101
+ }
102
+
103
+ /**
104
+ * 设置群名
105
+ * @param event 按键事件
106
+ */
107
+ function setGroupName(event: KeyboardEvent) {
108
+ if (
109
+ event.key === 'Enter' &&
110
+ chatStore.chatInfo.show.name != ''
111
+ ) {
112
+ Connector.send(
113
+ 'set_group_name',
114
+ {
115
+ group_id: props.chat.show.id,
116
+ group_name: chatStore.chatInfo.show.name,
117
+ },
118
+ 'setGroupName',
119
+ )
120
+ }
121
+ }
122
+
123
+ /**
124
+ * 退出群聊
125
+ */
126
+ function leaveGroup() {
127
+ const popInfo = {
128
+ html: '<span>' + $t('确定要退出群聊吗?') + '</span>',
129
+ button: [
130
+ {
131
+ text: $t('确定'),
132
+ fun: () => {
133
+ if (authStore.jsonMap.leave_group?.name) {
134
+ Connector.send(authStore.jsonMap.leave_group?.name,
135
+ { group_id: props.chat.show.id },
136
+ 'leaveGroup')
137
+ }
138
+ // 从消息列表中删除该群聊
139
+ contactStore.baseOnMsgList.delete(String(props.chat.show.id))
140
+ // 关闭群聊窗口
141
+ chatStore.chatInfo.show.id = 0
142
+ // 刷新好友/群列表
143
+ reloadUsers()
144
+ uiStore.popBoxList.shift()
145
+ },
146
+ },
147
+ {
148
+ text: $t('取消'),
149
+ master: true,
150
+ fun: () => {
151
+ uiStore.popBoxList.shift()
152
+ },
153
+ },
154
+ ],
155
+ }
156
+ uiStore.popBoxList.push(popInfo)
157
+ }
158
+ </script>
159
+
160
+ <style scoped>
161
+ .opt-item:hover input[type='text'] {
162
+ background: var(--color-card-2);
163
+ transition: background 0.2s;
164
+ }
165
+ </style>