koishi-plugin-chat-patch 5.1.0 → 5.3.1
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.
- package/client/web/dist/assets/Chat-Bo5JdcNg.js +28 -0
- package/client/web/dist/assets/{Chat-CTdyeaX2.css → Chat-C-rmzMIw.css} +1 -1
- package/client/web/dist/assets/{MsgBody-DLeOklIb.js → MsgBody-h4C1nnBQ.js} +1 -1
- package/client/web/dist/assets/MsgBody.vue_vue_type_script_setup_true_lang-a902ps2r.js +67 -0
- package/client/web/dist/assets/{index-Cz89G4we.js → index-CdTmWcO4.js} +121 -129
- package/client/web/dist/assets/index-wjp_A4n1.css +1 -0
- package/client/web/dist/assets/pinyin-Dsq98249.js +157657 -0
- package/client/web/dist/index.html +2 -2
- package/client/web/dist/notice_local.json +1 -0
- package/client/web/package-lock.json +49 -0
- package/client/web/package.json +1 -0
- package/client/web/public/notice_local.json +1 -0
- package/client/web/src/components/AboutPan.vue +2 -1
- package/client/web/src/components/BulletinBody.vue +1 -1
- package/client/web/src/components/EmojiFace.vue +0 -6
- package/client/web/src/components/FacePan.vue +0 -12
- package/client/web/src/components/FriendBody.vue +1 -0
- package/client/web/src/components/MsgBody.vue +4 -4
- package/client/web/src/components/SettingsTab.vue +133 -0
- package/client/web/src/components/TinySessionBody.vue +1 -0
- package/client/web/src/components/UpdatePan.vue +2 -2
- package/client/web/src/components/tooltip/UserInfoTooltip.vue +1 -1
- package/client/web/src/function/connect.ts +81 -28
- package/client/web/src/function/model/emoji.ts +7 -67
- package/client/web/src/function/msg.ts +68 -26
- package/client/web/src/function/satori-model.ts +8 -0
- package/client/web/src/function/satori.ts +31 -1
- package/client/web/src/function/utils/appUtil.ts +1 -4
- package/client/web/src/function/utils/avatarUtil.ts +18 -3
- package/client/web/src/function/utils/msgUtil.ts +86 -52
- package/client/web/src/function/utils/pinyin.ts +25 -65
- package/client/web/src/function/utils/sessionUtil.ts +90 -14
- package/client/web/src/main.ts +5 -0
- package/client/web/src/pages/Chat.vue +3 -4
- package/client/web/src/pages/Friends.vue +72 -30
- package/client/web/src/pages/Info.vue +3 -3
- package/client/web/src/pages/Messages.vue +59 -26
- package/client/web/src/pages/Options.vue +4 -4
- package/client/web/src/pages/Qzone.vue +2 -2
- package/client/web/src/pages/chat-view/SystemNotice.vue +3 -3
- package/client/web/src/pages/options/OptAccount.vue +6 -4
- package/client/web/src/pages/options/OptDev.vue +1 -14
- package/lib/index.js +14 -14
- package/lib/types.d.ts +115 -0
- package/package.json +1 -1
- package/src/bootstrap.ts +1 -0
- package/src/config.ts +1 -1
- package/src/recorder.ts +7 -7
- package/src/types.ts +4 -0
- package/src/web.ts +8 -9
- package/client/web/dist/assets/Chat-BoNiWGxb.js +0 -28
- package/client/web/dist/assets/MsgBody.vue_vue_type_script_setup_true_lang-CGjy4Jzz.js +0 -67
- package/client/web/dist/assets/index-BgOX_tNa.css +0 -1
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
<link rel="stylesheet" href="./bcui/css/style.css">
|
|
12
12
|
<link rel="stylesheet" href="./bcui/css/color-light.css">
|
|
13
13
|
<link rel="stylesheet" href="./css/append-light.css">
|
|
14
|
-
<script type="module" crossorigin src="./assets/index-
|
|
15
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
14
|
+
<script type="module" crossorigin src="./assets/index-CdTmWcO4.js"></script>
|
|
15
|
+
<link rel="stylesheet" crossorigin href="./assets/index-wjp_A4n1.css">
|
|
16
16
|
</head>
|
|
17
17
|
|
|
18
18
|
<body>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[]
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"jsonpath": "^1.1.1",
|
|
31
31
|
"markdown-it": "^14.1.1",
|
|
32
32
|
"pinia": "^3.0.3",
|
|
33
|
+
"pinyin": "^4.0.0",
|
|
33
34
|
"pofile": "^1.1.4",
|
|
34
35
|
"querystring": "^0.2.1",
|
|
35
36
|
"spacingjs": "^1.0.8",
|
|
@@ -2422,6 +2423,12 @@
|
|
|
2422
2423
|
"underscore": "1.13.6"
|
|
2423
2424
|
}
|
|
2424
2425
|
},
|
|
2426
|
+
"node_modules/keypress": {
|
|
2427
|
+
"version": "0.1.0",
|
|
2428
|
+
"resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz",
|
|
2429
|
+
"integrity": "sha512-x0yf9PL/nx9Nw9oLL8ZVErFAk85/lslwEP7Vz7s5SI1ODXZIgit3C5qyWjw4DxOuO/3Hb4866SQh28a1V1d+WA==",
|
|
2430
|
+
"license": "MIT"
|
|
2431
|
+
},
|
|
2425
2432
|
"node_modules/klona": {
|
|
2426
2433
|
"version": "2.0.6",
|
|
2427
2434
|
"resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz",
|
|
@@ -2645,6 +2652,48 @@
|
|
|
2645
2652
|
}
|
|
2646
2653
|
}
|
|
2647
2654
|
},
|
|
2655
|
+
"node_modules/pinyin": {
|
|
2656
|
+
"version": "4.0.0",
|
|
2657
|
+
"resolved": "https://registry.npmjs.org/pinyin/-/pinyin-4.0.0.tgz",
|
|
2658
|
+
"integrity": "sha512-vHpV5K+vpp6XUUpZNGRDuHoN+1xcmieM3EWlH4QjSX2kkpG/gVOwpqwV9EOJ9x9c9UERFKeLml5XVSukE/PLgQ==",
|
|
2659
|
+
"license": "MIT",
|
|
2660
|
+
"dependencies": {
|
|
2661
|
+
"commander": "~1.1.1"
|
|
2662
|
+
},
|
|
2663
|
+
"bin": {
|
|
2664
|
+
"pinyin": "bin/pinyin"
|
|
2665
|
+
},
|
|
2666
|
+
"engines": {
|
|
2667
|
+
"install-node": "^18.0.0"
|
|
2668
|
+
},
|
|
2669
|
+
"peerDependencies": {
|
|
2670
|
+
"@node-rs/jieba": "^1.6.0",
|
|
2671
|
+
"nodejieba": "^3.4.4",
|
|
2672
|
+
"segmentit": "^2.0.3"
|
|
2673
|
+
},
|
|
2674
|
+
"peerDependenciesMeta": {
|
|
2675
|
+
"@node-rs/jieba": {
|
|
2676
|
+
"optional": true
|
|
2677
|
+
},
|
|
2678
|
+
"nodejieba": {
|
|
2679
|
+
"optional": true
|
|
2680
|
+
},
|
|
2681
|
+
"segmentit": {
|
|
2682
|
+
"optional": true
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
},
|
|
2686
|
+
"node_modules/pinyin/node_modules/commander": {
|
|
2687
|
+
"version": "1.1.1",
|
|
2688
|
+
"resolved": "https://registry.npmjs.org/commander/-/commander-1.1.1.tgz",
|
|
2689
|
+
"integrity": "sha512-71Rod2AhcH3JhkBikVpNd0pA+fWsmAaVoti6OR38T76chA7vE3pSerS0Jor4wDw+tOueD2zLVvFOw5H0Rcj7rA==",
|
|
2690
|
+
"dependencies": {
|
|
2691
|
+
"keypress": "0.1.x"
|
|
2692
|
+
},
|
|
2693
|
+
"engines": {
|
|
2694
|
+
"node": ">= 0.6.x"
|
|
2695
|
+
}
|
|
2696
|
+
},
|
|
2648
2697
|
"node_modules/pofile": {
|
|
2649
2698
|
"version": "1.1.4",
|
|
2650
2699
|
"resolved": "https://registry.npmjs.org/pofile/-/pofile-1.1.4.tgz",
|
package/client/web/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[]
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<span> {{ $t('赞助者') }} </span>
|
|
23
23
|
<div class="contributors">
|
|
24
24
|
<div v-for="info in sponsorList.slice(0, 3)" :key="info.user.name">
|
|
25
|
-
<img lazy :src="info.user.avatar">
|
|
25
|
+
<img lazy data-avatar :src="info.user.avatar">
|
|
26
26
|
<div>
|
|
27
27
|
<span>{{ info.user.name }}</span>
|
|
28
28
|
<span>{{ Intl.DateTimeFormat(trueLang, {
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
<img v-for="info in sponsorList.slice(3)"
|
|
38
38
|
:key="info.user.name"
|
|
39
39
|
lazy
|
|
40
|
+
data-avatar
|
|
40
41
|
:src="info.user.avatar">
|
|
41
42
|
</div>
|
|
42
43
|
</div>
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
</div>
|
|
36
36
|
<span v-show="needShow && !showAll">{{ $t('点击展开') }}</span>
|
|
37
37
|
<div class="info">
|
|
38
|
-
<img :src="data.avatar || '/img/icons/icon.svg'">
|
|
38
|
+
<img data-avatar :src="data.avatar || '/img/icons/icon.svg'">
|
|
39
39
|
<a>{{
|
|
40
40
|
chatStore.chatInfo.info.group_members.filter((item) => {
|
|
41
41
|
return Number(item.user_id) === Number(data.sender)
|
|
@@ -10,12 +10,6 @@
|
|
|
10
10
|
:icon="['fas', 'face-grin-wide']"
|
|
11
11
|
:title="$t('表情')"
|
|
12
12
|
class="emoji-face" />
|
|
13
|
-
<img v-else-if="emoji.type === 'apng'"
|
|
14
|
-
class="emoji-face"
|
|
15
|
-
loading="lazy"
|
|
16
|
-
:alt="emoji.description"
|
|
17
|
-
:title="emoji.description"
|
|
18
|
-
:src="emoji.value">
|
|
19
13
|
<span v-else
|
|
20
14
|
:title="emoji.description"
|
|
21
15
|
class="emoji-face">
|
|
@@ -26,18 +26,6 @@
|
|
|
26
26
|
</template>
|
|
27
27
|
</div>
|
|
28
28
|
</template>
|
|
29
|
-
<div class="title">
|
|
30
|
-
<span>{{ $t('小黄脸表情') }}</span>
|
|
31
|
-
</div>
|
|
32
|
-
<div class="face">
|
|
33
|
-
<template v-for="num in Emoji.normalList" :key="num">
|
|
34
|
-
<div>
|
|
35
|
-
<EmojiFace
|
|
36
|
-
:emoji="Emoji.get(num)"
|
|
37
|
-
@click="addBaseFace(num)" />
|
|
38
|
-
</div>
|
|
39
|
-
</template>
|
|
40
|
-
</div>
|
|
41
29
|
<div class="title">
|
|
42
30
|
<span>{{ $t('emoji 表情') }}</span>
|
|
43
31
|
</div>
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
<font-awesome-icon v-if="data.user_id == -10000" :icon="['fas', 'bell']" />
|
|
16
16
|
<font-awesome-icon v-else-if="data.user_id == -10001" :icon="['fas', 'user-group']" />
|
|
17
17
|
<img v-else loading="lazy" :title="getShowName(data.group_name || data.nickname, data.remark)"
|
|
18
|
+
data-avatar
|
|
18
19
|
:src="data.avatar || '/img/icons/icon.svg'" @error="avatarError">
|
|
19
20
|
<div>
|
|
20
21
|
<div>
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
<template v-if="type != 'body'">
|
|
32
32
|
<img v-menu.prevent="event => $emit('showMenu', event, data)"
|
|
33
33
|
v-user-tooltip="() => getUserById(data.sender.user_id)"
|
|
34
|
+
data-avatar
|
|
34
35
|
name="avatar"
|
|
35
36
|
:src="data.sender.avatar || '/img/icons/icon.svg'"
|
|
36
37
|
:alt="data.sender.card ? data.sender.card : data.sender.nickname"
|
|
@@ -81,9 +82,9 @@
|
|
|
81
82
|
<!-- 超级表情 -->
|
|
82
83
|
<template v-else-if="isSuperFaceMsg()">
|
|
83
84
|
<div class="msg-img face lottie-face alone">
|
|
84
|
-
<
|
|
85
|
-
:
|
|
86
|
-
|
|
85
|
+
<EmojiFace
|
|
86
|
+
:emoji="Emoji.get(Number(data.message[0].id))!"
|
|
87
|
+
class="msg-face" />
|
|
87
88
|
</div>
|
|
88
89
|
</template>
|
|
89
90
|
<template v-else-if="!hasCard()">
|
|
@@ -436,7 +437,6 @@ const chatStore = useChatStore()
|
|
|
436
437
|
const settingsStore = useSettingsStore()
|
|
437
438
|
import Emoji from '../function/model/emoji'
|
|
438
439
|
import EmojiFace from './EmojiFace.vue'
|
|
439
|
-
import LazyLottie from './LazyLottie.vue'
|
|
440
440
|
import { Img } from '../function/model/img'
|
|
441
441
|
import { dbGetImage, hashUrl } from '../function/utils/localHistoryUtil'
|
|
442
442
|
import JsonSegComp from './msg-component/JsonSegComp.vue'
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 设置页专用选项卡,避免 BcTab 在多实例/HMR 下取错 tab body -->
|
|
3
|
+
<div class="tab-main">
|
|
4
|
+
<Card>
|
|
5
|
+
<ul v-if="tabs.length" class="tab-bar">
|
|
6
|
+
<span v-if="title">{{ title }}</span>
|
|
7
|
+
<li
|
|
8
|
+
v-for="(tab, index) in tabs"
|
|
9
|
+
:key="tab.name"
|
|
10
|
+
:class="{ select: activeIndex === index }"
|
|
11
|
+
@click="selectTab(index)">
|
|
12
|
+
<span>{{ tab.name }}</span>
|
|
13
|
+
<div
|
|
14
|
+
v-if="index === tabs.length - 1"
|
|
15
|
+
:style="getTabLineStyle(index)" />
|
|
16
|
+
</li>
|
|
17
|
+
</ul>
|
|
18
|
+
</Card>
|
|
19
|
+
<div ref="bodyRef" class="tab-body">
|
|
20
|
+
<slot />
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup lang="ts">
|
|
26
|
+
import { computed, nextTick, onMounted, ref, useSlots, watch } from 'vue'
|
|
27
|
+
import Card from 'vue3-bcui/packages/ss-card'
|
|
28
|
+
|
|
29
|
+
const props = defineProps<{
|
|
30
|
+
title?: string
|
|
31
|
+
}>()
|
|
32
|
+
|
|
33
|
+
const slots = useSlots()
|
|
34
|
+
const bodyRef = ref<HTMLElement>()
|
|
35
|
+
const activeIndex = ref(0)
|
|
36
|
+
|
|
37
|
+
const tabs = computed(() => {
|
|
38
|
+
const nodes = slots.default?.() ?? []
|
|
39
|
+
return nodes.filter((node) => {
|
|
40
|
+
const props = node.props as Record<string, unknown> | undefined
|
|
41
|
+
return Boolean(props?.name)
|
|
42
|
+
}).map((node) => {
|
|
43
|
+
const props = node.props as Record<string, unknown>
|
|
44
|
+
return {
|
|
45
|
+
name: String(props.name ?? ''),
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
function selectTab(index: number) {
|
|
51
|
+
activeIndex.value = index
|
|
52
|
+
nextTick(() => {
|
|
53
|
+
const children = bodyRef.value?.children
|
|
54
|
+
if (!children) return
|
|
55
|
+
const activeName = tabs.value[index]?.name
|
|
56
|
+
for (let i = 0; i < children.length; i++) {
|
|
57
|
+
const child = children[i] as HTMLElement
|
|
58
|
+
if (child.nodeName === 'DIV' && child.hasAttribute('name')) {
|
|
59
|
+
child.style.display = child.getAttribute('name') === activeName
|
|
60
|
+
? 'block'
|
|
61
|
+
: 'none'
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function getTabLineStyle(maxIndex: number) {
|
|
68
|
+
const offset = maxIndex - activeIndex.value
|
|
69
|
+
return `transform: translateX(calc(-${offset}00% - (var(--bc-tab-margin) * 2 + 10px) * ${offset}))`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
onMounted(() => {
|
|
73
|
+
selectTab(0)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
watch(tabs, () => {
|
|
77
|
+
nextTick(() => selectTab(activeIndex.value))
|
|
78
|
+
})
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<style scoped>
|
|
82
|
+
.tab-main > div:first-child {
|
|
83
|
+
margin-bottom: 10px;
|
|
84
|
+
}
|
|
85
|
+
.tab-bar {
|
|
86
|
+
--bc-tab-margin: 20px;
|
|
87
|
+
|
|
88
|
+
margin: -17px -20px -17px -40px;
|
|
89
|
+
justify-content: center;
|
|
90
|
+
align-items: center;
|
|
91
|
+
position: relative;
|
|
92
|
+
display: flex;
|
|
93
|
+
}
|
|
94
|
+
.tab-bar > span {
|
|
95
|
+
font-weight: bold;
|
|
96
|
+
flex: 0 0 auto;
|
|
97
|
+
margin-right: 20px;
|
|
98
|
+
}
|
|
99
|
+
.tab-bar > li {
|
|
100
|
+
margin: 0 var(--bc-tab-margin);
|
|
101
|
+
justify-content: center;
|
|
102
|
+
flex-direction: column;
|
|
103
|
+
list-style-type: none;
|
|
104
|
+
align-items: center;
|
|
105
|
+
border-radius: 3px;
|
|
106
|
+
min-width: 30px;
|
|
107
|
+
cursor: pointer;
|
|
108
|
+
padding: 10px;
|
|
109
|
+
display: flex;
|
|
110
|
+
}
|
|
111
|
+
.tab-bar > li span,
|
|
112
|
+
.tab-bar > li svg {
|
|
113
|
+
color: var(--color-font);
|
|
114
|
+
transition: color 0.3s;
|
|
115
|
+
font-size: 0.9rem;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.tab-bar > li > div {
|
|
119
|
+
width: calc(100% + 10px);
|
|
120
|
+
margin-bottom: -10px;
|
|
121
|
+
transition: all .35s;
|
|
122
|
+
border-radius: 7px;
|
|
123
|
+
margin-top: 6px;
|
|
124
|
+
height: 3px;
|
|
125
|
+
}
|
|
126
|
+
.tab-bar > li:last-child > div {
|
|
127
|
+
background: var(--color-main);
|
|
128
|
+
}
|
|
129
|
+
.tab-bar > li.select span,
|
|
130
|
+
.tab-bar > li.select svg {
|
|
131
|
+
color: var(--color-main);
|
|
132
|
+
}
|
|
133
|
+
</style>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<span>{{ updated ? $t('更新记录') : $t('新版本') }}</span>
|
|
5
5
|
<a>{{ version }}</a>
|
|
6
6
|
<div class="title">
|
|
7
|
-
<img :src="user?.avatar || ''">
|
|
7
|
+
<img data-avatar :src="user?.avatar || ''">
|
|
8
8
|
<a :href="user?.url || ''">{{ user?.name || '' }}</a>
|
|
9
9
|
<span>
|
|
10
10
|
{{
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<div class="release-header">
|
|
38
38
|
<a class="release-version">{{ release.version }} - {{ release.info.title.replace('Release', '') }}</a>
|
|
39
39
|
<div class="release-meta">
|
|
40
|
-
<img :src="release.user.avatar">
|
|
40
|
+
<img data-avatar :src="release.user.avatar">
|
|
41
41
|
<a :href="release.user.url" target="_blank">{{ release.user.name }}</a>
|
|
42
42
|
<span>
|
|
43
43
|
{{
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
import { reactive } from 'vue'
|
|
4
4
|
import { dispatch, msgPreprocess } from './msg'
|
|
5
5
|
import {
|
|
6
|
+
botKey,
|
|
6
7
|
connect as connectSatori,
|
|
7
8
|
getActiveBot,
|
|
9
|
+
getBlockedPlatforms,
|
|
8
10
|
getBootstrap,
|
|
9
11
|
getLogins,
|
|
10
12
|
request,
|
|
@@ -25,7 +27,11 @@ import { useChatStore } from '../state/chat'
|
|
|
25
27
|
import { useContactStore } from '../state/contact'
|
|
26
28
|
import { useSettingsStore } from '../state/settings'
|
|
27
29
|
import { getMsgRawTxt, hasAtMe, updateBaseOnMsgList } from './utils/msgUtil'
|
|
28
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
getSessionDedupKey,
|
|
32
|
+
normalizeSessionId,
|
|
33
|
+
setSessionContact,
|
|
34
|
+
} from './utils/sessionUtil'
|
|
29
35
|
import { buildQqGroupAvatar } from './utils/avatarUtil'
|
|
30
36
|
import type { ConnectionHistoryItem, LoginCacheElem } from './elements/system'
|
|
31
37
|
import type { UserFriendElem, UserGroupElem } from './elements/information'
|
|
@@ -38,6 +44,14 @@ function encodeKeyPart(value: string): string {
|
|
|
38
44
|
return encodeURIComponent(value)
|
|
39
45
|
}
|
|
40
46
|
|
|
47
|
+
function isBlockedPlatform(platform: string): boolean {
|
|
48
|
+
return getBlockedPlatforms().some((item) => {
|
|
49
|
+
return item.exactMatch
|
|
50
|
+
? platform === item.platformName
|
|
51
|
+
: platform.includes(item.platformName)
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
41
55
|
function getChannelKind(value: unknown): 'group' | 'direct' | 'unknown' {
|
|
42
56
|
if (typeof value === 'number') {
|
|
43
57
|
if (value === 0) return 'group'
|
|
@@ -346,20 +360,20 @@ function updateBotStateGroup(
|
|
|
346
360
|
apply: (target: Record<string, unknown>) => void,
|
|
347
361
|
) {
|
|
348
362
|
const contactStore = useContactStore()
|
|
349
|
-
const state = contactStore.botStates.get(selfId)
|
|
363
|
+
const state = contactStore.botStates.get(botKey(platform, selfId))
|
|
350
364
|
const session = state?.onMsgList.find((item) => String(item.group_id) === sessionId)
|
|
351
365
|
if (!state || !session) return
|
|
352
366
|
apply(session as unknown as Record<string, unknown>)
|
|
353
|
-
const key = normalizeSessionId(String(session.channel_id
|
|
367
|
+
const key = normalizeSessionId(String(session.channel_id || session.channelId || sessionId))
|
|
354
368
|
const baseList = [...state.baseList]
|
|
355
|
-
const baseIndex = baseList.findIndex(([
|
|
369
|
+
const baseIndex = baseList.findIndex(([, value]) => value === session)
|
|
356
370
|
const typedSession = session as unknown as UserFriendElem & UserGroupElem
|
|
357
371
|
if (baseIndex >= 0) {
|
|
358
372
|
baseList[baseIndex] = [key, typedSession]
|
|
359
373
|
} else {
|
|
360
374
|
baseList.push([key, typedSession])
|
|
361
375
|
}
|
|
362
|
-
contactStore.botStates.set(selfId, {
|
|
376
|
+
contactStore.botStates.set(botKey(platform, selfId), {
|
|
363
377
|
userList: [...state.userList],
|
|
364
378
|
baseList,
|
|
365
379
|
onMsgList: [...state.onMsgList],
|
|
@@ -574,7 +588,7 @@ function recordBotMessage(platform: string, selfId: string, msg: Record<string,
|
|
|
574
588
|
? (eventGroupAvatar || cachedGroupInfo?.avatar || buildQqGroupAvatar(platform, sessionId) || undefined)
|
|
575
589
|
: undefined
|
|
576
590
|
const contactStore = useContactStore()
|
|
577
|
-
const state = contactStore.botStates.get(selfId) ?? {
|
|
591
|
+
const state = contactStore.botStates.get(botKey(platform, selfId)) ?? {
|
|
578
592
|
userList: [],
|
|
579
593
|
baseList: [],
|
|
580
594
|
onMsgList: [],
|
|
@@ -598,6 +612,14 @@ function recordBotMessage(platform: string, selfId: string, msg: Record<string,
|
|
|
598
612
|
guild_id: typeof msg.guild_id === 'string' ? msg.guild_id : undefined,
|
|
599
613
|
}
|
|
600
614
|
const existing = state.onMsgList.find((item) => {
|
|
615
|
+
const itemChannelId = String(item.channel_id || item.channelId || '')
|
|
616
|
+
if (itemChannelId) {
|
|
617
|
+
if (isGroup) {
|
|
618
|
+
return normalizeGroupId(itemChannelId) === normalizeGroupId(channelId || sessionId)
|
|
619
|
+
}
|
|
620
|
+
return itemChannelId.replace(/^(?:private|direct):/i, '')
|
|
621
|
+
=== String(sessionId).replace(/^(?:private|direct):/i, '')
|
|
622
|
+
}
|
|
601
623
|
return isGroup
|
|
602
624
|
? String(item.group_id) === sessionId
|
|
603
625
|
: String(item.user_id) === sessionId
|
|
@@ -631,14 +653,14 @@ function recordBotMessage(platform: string, selfId: string, msg: Record<string,
|
|
|
631
653
|
}
|
|
632
654
|
const baseKey = normalizeSessionId(sessionKey)
|
|
633
655
|
const baseList = [...state.baseList]
|
|
634
|
-
const baseIndex = baseList.findIndex(([
|
|
656
|
+
const baseIndex = baseList.findIndex(([, value]) => value === session)
|
|
635
657
|
const typedSession = session as unknown as UserFriendElem & UserGroupElem
|
|
636
658
|
if (baseIndex >= 0) {
|
|
637
659
|
baseList[baseIndex] = [baseKey, typedSession]
|
|
638
660
|
} else {
|
|
639
661
|
baseList.push([baseKey, typedSession])
|
|
640
662
|
}
|
|
641
|
-
contactStore.botStates.set(selfId, {
|
|
663
|
+
contactStore.botStates.set(botKey(platform, selfId), {
|
|
642
664
|
userList: [...state.userList],
|
|
643
665
|
baseList,
|
|
644
666
|
onMsgList: [...state.onMsgList],
|
|
@@ -714,6 +736,26 @@ function recordBotMessage(platform: string, selfId: string, msg: Record<string,
|
|
|
714
736
|
)
|
|
715
737
|
if (senderId && senderId !== '0') {
|
|
716
738
|
void fetchUserIdentity(platform, selfId, senderId, null, msg)
|
|
739
|
+
if (isCurrentChat) {
|
|
740
|
+
const members = chatStore.chatInfo.info.group_members
|
|
741
|
+
const member = {
|
|
742
|
+
user_id: senderId,
|
|
743
|
+
nickname: String(sender.nickname || sender.card || senderName || senderId),
|
|
744
|
+
card: String(sender.card || ''),
|
|
745
|
+
role: String(sender.role || ''),
|
|
746
|
+
avatar: hasUsableAvatar(sender.avatar) ? getString(sender.avatar) : undefined,
|
|
747
|
+
title: '',
|
|
748
|
+
join_time: 0,
|
|
749
|
+
last_sent_time: Math.floor(sessionTime),
|
|
750
|
+
level: 0,
|
|
751
|
+
rank: '',
|
|
752
|
+
sex: '',
|
|
753
|
+
shutup_time: 0,
|
|
754
|
+
}
|
|
755
|
+
const index = members.findIndex((item) => String(item.user_id) === senderId)
|
|
756
|
+
if (index >= 0) Object.assign(members[index], member)
|
|
757
|
+
else members.push(member)
|
|
758
|
+
}
|
|
717
759
|
}
|
|
718
760
|
} else if (senderId && senderId !== '0') {
|
|
719
761
|
identityDebug('recordBotMessage: private identity branch', {
|
|
@@ -768,28 +810,36 @@ export function restoreBotStateFromMessageCache(platform: string, selfId: string
|
|
|
768
810
|
}
|
|
769
811
|
if (!sessions.length) return
|
|
770
812
|
|
|
771
|
-
const state = contactStore.botStates.get(selfId) ?? {
|
|
813
|
+
const state = contactStore.botStates.get(botKey(platform, selfId)) ?? {
|
|
772
814
|
userList: [],
|
|
773
815
|
baseList: [],
|
|
774
816
|
onMsgList: [],
|
|
775
817
|
}
|
|
776
|
-
const
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
}
|
|
818
|
+
const baseMap = new Map<string, UserFriendElem & UserGroupElem>()
|
|
819
|
+
for (const [, value] of state.baseList) {
|
|
820
|
+
const id = getSessionDedupKey(value)
|
|
821
|
+
if (!id.endsWith(':0') && !id.endsWith(':')) baseMap.set(id, value)
|
|
822
|
+
}
|
|
823
|
+
const baseList = [...baseMap.entries()]
|
|
824
|
+
const baseKeys = new Set(baseList.map(([key]) => key))
|
|
825
|
+
const existing = new Set(
|
|
826
|
+
state.onMsgList.map((item) => {
|
|
827
|
+
const id = getSessionDedupKey(item)
|
|
828
|
+
return !id.endsWith(':0') && !id.endsWith(':') ? id : ''
|
|
829
|
+
}).filter(Boolean),
|
|
830
|
+
)
|
|
781
831
|
for (const session of sessions) {
|
|
782
|
-
const id =
|
|
783
|
-
if (id && !existing.has(id)) {
|
|
832
|
+
const id = getSessionDedupKey(session)
|
|
833
|
+
if (!id.endsWith(':0') && !id.endsWith(':') && !existing.has(id)) {
|
|
784
834
|
state.onMsgList.unshift(session)
|
|
785
835
|
existing.add(id)
|
|
786
836
|
}
|
|
787
|
-
if (id && !baseKeys.has(
|
|
788
|
-
baseList.push([normalizeSessionId(
|
|
789
|
-
baseKeys.add(
|
|
837
|
+
if (!id.endsWith(':0') && !id.endsWith(':') && !baseKeys.has(id)) {
|
|
838
|
+
baseList.push([normalizeSessionId(String(session.channel_id || session.channelId || session.user_id || session.group_id || '')), session])
|
|
839
|
+
baseKeys.add(id)
|
|
790
840
|
}
|
|
791
841
|
}
|
|
792
|
-
contactStore.botStates.set(selfId, {
|
|
842
|
+
contactStore.botStates.set(botKey(platform, selfId), {
|
|
793
843
|
userList: [...state.userList],
|
|
794
844
|
baseList,
|
|
795
845
|
onMsgList: [...state.onMsgList],
|
|
@@ -797,6 +847,7 @@ export function restoreBotStateFromMessageCache(platform: string, selfId: string
|
|
|
797
847
|
}
|
|
798
848
|
|
|
799
849
|
function onSatoriEvent(event: SatoriEvent) {
|
|
850
|
+
if (isBlockedPlatform(event.platform)) return
|
|
800
851
|
const oneBot = satoriEventToOneBot(event.body, String(event.platform || ''))
|
|
801
852
|
if (oneBot) {
|
|
802
853
|
oneBot._rawSatori = {
|
|
@@ -845,6 +896,7 @@ export function flushPendingBotEvents(platform: string, selfId: string) {
|
|
|
845
896
|
if (!events?.length) return
|
|
846
897
|
pendingBotEvents.delete(key)
|
|
847
898
|
for (const event of events) {
|
|
899
|
+
if (isBlockedPlatform(event.platform)) continue
|
|
848
900
|
const oneBot = satoriEventToOneBot(event.body, String(event.platform || ''))
|
|
849
901
|
if (oneBot) {
|
|
850
902
|
oneBot._rawSatori = {
|
|
@@ -873,7 +925,8 @@ function onSatoriReady(logins: Array<{ platform: string; selfId: string; name: s
|
|
|
873
925
|
login.creating = false
|
|
874
926
|
login.status = true
|
|
875
927
|
const authStore = useAuthStore()
|
|
876
|
-
|
|
928
|
+
const visibleLogins = logins.filter((item) => !isBlockedPlatform(item.platform))
|
|
929
|
+
for (const item of visibleLogins) {
|
|
877
930
|
if (!item.platform || !item.selfId) continue
|
|
878
931
|
identityInfoCache.set(identityCacheKey('user', item.platform, item.selfId, item.selfId), {
|
|
879
932
|
name: item.name || item.selfId,
|
|
@@ -887,7 +940,7 @@ function onSatoriReady(logins: Array<{ platform: string; selfId: string; name: s
|
|
|
887
940
|
},
|
|
888
941
|
})
|
|
889
942
|
}
|
|
890
|
-
const first =
|
|
943
|
+
const first = visibleLogins[0]
|
|
891
944
|
if (!first) return
|
|
892
945
|
|
|
893
946
|
setActiveBot(first.platform, first.selfId)
|
|
@@ -895,16 +948,16 @@ function onSatoriReady(logins: Array<{ platform: string; selfId: string; name: s
|
|
|
895
948
|
login.uin = first.selfId
|
|
896
949
|
login.nickname = first.name
|
|
897
950
|
login.platform = first.platform
|
|
898
|
-
login.satoriLogins =
|
|
899
|
-
login.selectedSatoriBot = first.selfId
|
|
951
|
+
login.satoriLogins = visibleLogins
|
|
952
|
+
login.selectedSatoriBot = botKey(first.platform, first.selfId)
|
|
900
953
|
authStore.loginInfo = {
|
|
901
954
|
uin: first.selfId,
|
|
902
955
|
user_id: first.selfId,
|
|
903
956
|
nickname: first.name,
|
|
904
957
|
platform: first.platform,
|
|
905
958
|
avatar: first.avatar,
|
|
906
|
-
satoriLogins:
|
|
907
|
-
selectedSatoriBot: first.selfId,
|
|
959
|
+
satoriLogins: visibleLogins,
|
|
960
|
+
selectedSatoriBot: botKey(first.platform, first.selfId),
|
|
908
961
|
}
|
|
909
962
|
authStore.botInfo = {
|
|
910
963
|
app_name: 'Satori',
|
|
@@ -1386,9 +1439,9 @@ async function loadAllBotsCache() {
|
|
|
1386
1439
|
}
|
|
1387
1440
|
const userList = [...groupRaws, ...friendRaws] as unknown as (UserFriendElem & UserGroupElem)[]
|
|
1388
1441
|
|
|
1389
|
-
const state = contactStore.botStates.get(selfId)
|
|
1442
|
+
const state = contactStore.botStates.get(botKey(platform, selfId))
|
|
1390
1443
|
if (!state || state.userList.length === 0) {
|
|
1391
|
-
contactStore.botStates.set(selfId, {
|
|
1444
|
+
contactStore.botStates.set(botKey(platform, selfId), {
|
|
1392
1445
|
userList,
|
|
1393
1446
|
baseList: state?.baseList ?? [],
|
|
1394
1447
|
onMsgList: state?.onMsgList ?? [],
|