mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-04-06 07:25:51 +00:00
Compare commits
1 Commits
nightly-pr
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdfea4ccb1 |
9
.github/workflows/dev-daily-fixed.yml
vendored
9
.github/workflows/dev-daily-fixed.yml
vendored
@@ -55,8 +55,6 @@ jobs:
|
||||
gh release delete "$FIXED_DEV_TAG" --repo "$GITHUB_REPOSITORY" --yes --cleanup-tag
|
||||
fi
|
||||
gh release create "$FIXED_DEV_TAG" --repo "$GITHUB_REPOSITORY" --title "Daily Dev Build" --notes "开发版发布页" --prerelease --target "$TARGET_BRANCH"
|
||||
RELEASE_REST_ID="$(gh api "repos/$GITHUB_REPOSITORY/releases/tags/$FIXED_DEV_TAG" --jq '.id')"
|
||||
gh api --method PATCH "repos/$GITHUB_REPOSITORY/releases/$RELEASE_REST_ID" -f draft=false -f prerelease=true >/dev/null
|
||||
|
||||
dev-mac-arm64:
|
||||
needs: prepare
|
||||
@@ -329,9 +327,4 @@ jobs:
|
||||
- 如某个平台资源暂未生成,请进入[发布页]($RELEASE_PAGE)查看最新状态
|
||||
EOF
|
||||
|
||||
RELEASE_REST_ID="$(gh api "repos/$REPO/releases/tags/$TAG" --jq '.id')"
|
||||
jq -n --rawfile body dev_release_notes.md \
|
||||
'{name:"Daily Dev Build", body:$body, draft:false, prerelease:true}' \
|
||||
> release_update_payload.json
|
||||
gh api --method PATCH "repos/$REPO/releases/$RELEASE_REST_ID" --input release_update_payload.json >/dev/null
|
||||
gh release view "$TAG" --repo "$REPO" --json isDraft,isPrerelease,url
|
||||
gh release edit "$TAG" --repo "$REPO" --title "Daily Dev Build" --notes-file dev_release_notes.md --prerelease
|
||||
|
||||
9
.github/workflows/preview-nightly-main.yml
vendored
9
.github/workflows/preview-nightly-main.yml
vendored
@@ -81,8 +81,6 @@ jobs:
|
||||
gh release delete "$FIXED_PREVIEW_TAG" --repo "$GITHUB_REPOSITORY" --yes --cleanup-tag
|
||||
fi
|
||||
gh release create "$FIXED_PREVIEW_TAG" --repo "$GITHUB_REPOSITORY" --title "Preview Nightly Build" --notes "预览版发布页" --prerelease --target "$TARGET_BRANCH"
|
||||
RELEASE_REST_ID="$(gh api "repos/$GITHUB_REPOSITORY/releases/tags/$FIXED_PREVIEW_TAG" --jq '.id')"
|
||||
gh api --method PATCH "repos/$GITHUB_REPOSITORY/releases/$RELEASE_REST_ID" -f draft=false -f prerelease=true >/dev/null
|
||||
|
||||
preview-mac-arm64:
|
||||
needs: prepare
|
||||
@@ -371,9 +369,4 @@ jobs:
|
||||
> 如某个平台链接暂未生成,请前往[发布页]($RELEASE_PAGE)查看最新资源
|
||||
EOF
|
||||
|
||||
RELEASE_REST_ID="$(gh api "repos/$REPO/releases/tags/$TAG" --jq '.id')"
|
||||
jq -n --rawfile body preview_release_notes.md \
|
||||
'{name:"Preview Nightly Build", body:$body, draft:false, prerelease:true}' \
|
||||
> release_update_payload.json
|
||||
gh api --method PATCH "repos/$REPO/releases/$RELEASE_REST_ID" --input release_update_payload.json >/dev/null
|
||||
gh release view "$TAG" --repo "$REPO" --json isDraft,isPrerelease,url
|
||||
gh release edit "$TAG" --repo "$REPO" --title "Preview Nightly Build" --notes-file preview_release_notes.md --prerelease
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -73,4 +73,3 @@ pnpm-lock.yaml
|
||||
wechat-research-site
|
||||
.codex
|
||||
weflow-web-offical
|
||||
Insight
|
||||
@@ -5,9 +5,6 @@ interface ExportWorkerConfig {
|
||||
sessionIds: string[]
|
||||
outputDir: string
|
||||
options: ExportOptions
|
||||
dbPath?: string
|
||||
decryptKey?: string
|
||||
myWxid?: string
|
||||
resourcesPath?: string
|
||||
userDataPath?: string
|
||||
logEnabled?: boolean
|
||||
@@ -32,11 +29,6 @@ async function run() {
|
||||
|
||||
wcdbService.setPaths(config.resourcesPath || '', config.userDataPath || '')
|
||||
wcdbService.setLogEnabled(config.logEnabled === true)
|
||||
exportService.setRuntimeConfig({
|
||||
dbPath: config.dbPath,
|
||||
decryptKey: config.decryptKey,
|
||||
myWxid: config.myWxid
|
||||
})
|
||||
|
||||
const result = await exportService.exportSessions(
|
||||
Array.isArray(config.sessionIds) ? config.sessionIds : [],
|
||||
|
||||
@@ -2362,9 +2362,6 @@ function registerIpcHandlers() {
|
||||
const cfg = configService || new ConfigService()
|
||||
configService = cfg
|
||||
const logEnabled = cfg.get('logEnabled')
|
||||
const dbPath = String(cfg.get('dbPath') || '').trim()
|
||||
const decryptKey = String(cfg.get('decryptKey') || '').trim()
|
||||
const myWxid = String(cfg.get('myWxid') || '').trim()
|
||||
const resourcesPath = app.isPackaged
|
||||
? join(process.resourcesPath, 'resources')
|
||||
: join(app.getAppPath(), 'resources')
|
||||
@@ -2378,9 +2375,6 @@ function registerIpcHandlers() {
|
||||
sessionIds,
|
||||
outputDir,
|
||||
options,
|
||||
dbPath,
|
||||
decryptKey,
|
||||
myWxid,
|
||||
resourcesPath,
|
||||
userDataPath,
|
||||
logEnabled
|
||||
|
||||
@@ -4486,16 +4486,15 @@ class ChatService {
|
||||
*/
|
||||
private parseQuoteMessage(content: string): { content?: string; sender?: string } {
|
||||
try {
|
||||
const normalizedContent = this.decodeHtmlEntities(content || '')
|
||||
// 提取 refermsg 部分
|
||||
const referMsgStart = normalizedContent.indexOf('<refermsg>')
|
||||
const referMsgEnd = normalizedContent.indexOf('</refermsg>')
|
||||
const referMsgStart = content.indexOf('<refermsg>')
|
||||
const referMsgEnd = content.indexOf('</refermsg>')
|
||||
|
||||
if (referMsgStart === -1 || referMsgEnd === -1) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const referMsgXml = normalizedContent.substring(referMsgStart, referMsgEnd + 11)
|
||||
const referMsgXml = content.substring(referMsgStart, referMsgEnd + 11)
|
||||
|
||||
// 提取发送者名称
|
||||
let displayName = this.extractXmlValue(referMsgXml, 'displayname')
|
||||
@@ -4512,8 +4511,8 @@ class ChatService {
|
||||
let displayContent = referContent
|
||||
switch (referType) {
|
||||
case '1':
|
||||
// 文本消息优先取“部分引用”字段,缺失时再回退到完整 content
|
||||
displayContent = this.extractPreferredQuotedText(referMsgXml)
|
||||
// 文本消息,清理可能的 wxid
|
||||
displayContent = this.sanitizeQuotedContent(referContent)
|
||||
break
|
||||
case '3':
|
||||
displayContent = '[图片]'
|
||||
@@ -4553,76 +4552,6 @@ class ChatService {
|
||||
}
|
||||
}
|
||||
|
||||
private extractPreferredQuotedText(referMsgXml: string): string {
|
||||
if (!referMsgXml) return ''
|
||||
|
||||
const sources = [this.decodeHtmlEntities(referMsgXml)]
|
||||
const rawMsgSource = this.extractXmlValue(referMsgXml, 'msgsource')
|
||||
if (rawMsgSource) {
|
||||
const decodedMsgSource = this.decodeHtmlEntities(rawMsgSource)
|
||||
if (decodedMsgSource) {
|
||||
sources.push(decodedMsgSource)
|
||||
}
|
||||
}
|
||||
|
||||
const fullContent = this.sanitizeQuotedContent(this.extractXmlValue(sources[0] || referMsgXml, 'content'))
|
||||
const partialText = this.extractPartialQuotedText(sources[0] || referMsgXml, fullContent)
|
||||
if (partialText) return partialText
|
||||
|
||||
const candidateTags = [
|
||||
'selectedcontent',
|
||||
'selectedtext',
|
||||
'selectcontent',
|
||||
'selecttext',
|
||||
'quotecontent',
|
||||
'quotetext',
|
||||
'partcontent',
|
||||
'parttext',
|
||||
'excerpt',
|
||||
'summary',
|
||||
'preview'
|
||||
]
|
||||
|
||||
for (const source of sources) {
|
||||
for (const tag of candidateTags) {
|
||||
const value = this.sanitizeQuotedContent(this.extractXmlValue(source, tag))
|
||||
if (value) return value
|
||||
}
|
||||
}
|
||||
|
||||
return fullContent
|
||||
}
|
||||
|
||||
private extractPartialQuotedText(xml: string, fullContent: string): string {
|
||||
if (!xml || !fullContent) return ''
|
||||
|
||||
const startChar = this.extractXmlValue(xml, 'start')
|
||||
const endChar = this.extractXmlValue(xml, 'end')
|
||||
const startIndexRaw = this.extractXmlValue(xml, 'startindex')
|
||||
const endIndexRaw = this.extractXmlValue(xml, 'endindex')
|
||||
const startIndex = Number.parseInt(startIndexRaw, 10)
|
||||
const endIndex = Number.parseInt(endIndexRaw, 10)
|
||||
|
||||
if (startChar && endChar) {
|
||||
const startPos = fullContent.indexOf(startChar)
|
||||
if (startPos !== -1) {
|
||||
const endPos = fullContent.indexOf(endChar, startPos + startChar.length - 1)
|
||||
if (endPos !== -1 && endPos >= startPos) {
|
||||
const sliced = fullContent.slice(startPos, endPos + endChar.length).trim()
|
||||
if (sliced) return sliced
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Number.isFinite(startIndex) && Number.isFinite(endIndex) && endIndex >= startIndex) {
|
||||
const chars = Array.from(fullContent)
|
||||
const sliced = chars.slice(startIndex, endIndex + 1).join('').trim()
|
||||
if (sliced) return sliced
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析名片消息
|
||||
* 格式: <msg username="wxid_xxx" nickname="昵称" ... />
|
||||
|
||||
@@ -5,13 +5,6 @@ import Store from 'electron-store'
|
||||
|
||||
// 加密前缀标记
|
||||
const SAFE_PREFIX = 'safe:' // safeStorage 加密(普通模式)
|
||||
const isSafeStorageAvailable = (): boolean => {
|
||||
try {
|
||||
return typeof safeStorage?.isEncryptionAvailable === 'function' && safeStorage.isEncryptionAvailable()
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
const LOCK_PREFIX = 'lock:' // 密码派生密钥加密(锁定模式)
|
||||
|
||||
interface ConfigSchema {
|
||||
@@ -264,7 +257,7 @@ export class ConfigService {
|
||||
private safeEncrypt(plaintext: string): string {
|
||||
if (!plaintext) return ''
|
||||
if (plaintext.startsWith(SAFE_PREFIX)) return plaintext
|
||||
if (!isSafeStorageAvailable()) return plaintext
|
||||
if (!safeStorage.isEncryptionAvailable()) return plaintext
|
||||
const encrypted = safeStorage.encryptString(plaintext)
|
||||
return SAFE_PREFIX + encrypted.toString('base64')
|
||||
}
|
||||
@@ -272,7 +265,7 @@ export class ConfigService {
|
||||
private safeDecrypt(stored: string): string {
|
||||
if (!stored) return ''
|
||||
if (!stored.startsWith(SAFE_PREFIX)) return stored
|
||||
if (!isSafeStorageAvailable()) return ''
|
||||
if (!safeStorage.isEncryptionAvailable()) return ''
|
||||
try {
|
||||
const buf = Buffer.from(stored.slice(SAFE_PREFIX.length), 'base64')
|
||||
return safeStorage.decryptString(buf)
|
||||
|
||||
@@ -254,7 +254,6 @@ async function parallelLimit<T, R>(
|
||||
|
||||
class ExportService {
|
||||
private configService: ConfigService
|
||||
private runtimeConfig: { dbPath?: string; decryptKey?: string; myWxid?: string } | null = null
|
||||
private contactCache: LRUCache<string, { displayName: string; avatarUrl?: string }>
|
||||
private inlineEmojiCache: LRUCache<string, string>
|
||||
private htmlStyleCache: string | null = null
|
||||
@@ -296,10 +295,6 @@ class ExportService {
|
||||
return error
|
||||
}
|
||||
|
||||
setRuntimeConfig(config: { dbPath?: string; decryptKey?: string; myWxid?: string } | null): void {
|
||||
this.runtimeConfig = config
|
||||
}
|
||||
|
||||
private normalizeSessionIds(sessionIds: string[]): string[] {
|
||||
return Array.from(
|
||||
new Set((sessionIds || []).map((id) => String(id || '').trim()).filter(Boolean))
|
||||
@@ -1321,9 +1316,9 @@ class ExportService {
|
||||
}
|
||||
|
||||
private async ensureConnected(): Promise<{ success: boolean; cleanedWxid?: string; error?: string }> {
|
||||
const wxid = String(this.runtimeConfig?.myWxid || this.configService.get('myWxid') || '').trim()
|
||||
const dbPath = String(this.runtimeConfig?.dbPath || this.configService.get('dbPath') || '').trim()
|
||||
const decryptKey = String(this.runtimeConfig?.decryptKey || this.configService.get('decryptKey') || '').trim()
|
||||
const wxid = this.configService.get('myWxid')
|
||||
const dbPath = this.configService.get('dbPath')
|
||||
const decryptKey = this.configService.get('decryptKey')
|
||||
if (!wxid) return { success: false, error: '请先在设置页面配置微信ID' }
|
||||
if (!dbPath) return { success: false, error: '请先在设置页面配置数据库路径' }
|
||||
if (!decryptKey) return { success: false, error: '请先在设置页面配置解密密钥' }
|
||||
@@ -2259,7 +2254,7 @@ class ExportService {
|
||||
const referMsgXml = normalized.substring(referMsgStart, referMsgEnd + 11)
|
||||
const quoteInfo = this.parseQuoteMessage(normalized)
|
||||
const replyText = this.stripSenderPrefix(this.extractXmlValue(normalized, 'title') || '')
|
||||
const quotedPreview = quoteInfo.content || this.formatQuotedReferencePreview(
|
||||
const quotedPreview = this.formatQuotedReferencePreview(
|
||||
this.extractXmlValue(referMsgXml, 'content'),
|
||||
this.extractXmlValue(referMsgXml, 'type')
|
||||
)
|
||||
@@ -2965,7 +2960,7 @@ class ExportService {
|
||||
|
||||
switch (referType) {
|
||||
case '1':
|
||||
displayContent = this.extractPreferredQuotedText(referMsgXml)
|
||||
displayContent = this.sanitizeQuotedContent(referContent)
|
||||
break
|
||||
case '3':
|
||||
displayContent = '[图片]'
|
||||
@@ -3006,76 +3001,6 @@ class ExportService {
|
||||
}
|
||||
}
|
||||
|
||||
private extractPreferredQuotedText(referMsgXml: string): string {
|
||||
if (!referMsgXml) return ''
|
||||
|
||||
const sources = [this.decodeHtmlEntities(referMsgXml)]
|
||||
const rawMsgSource = this.extractXmlValue(referMsgXml, 'msgsource')
|
||||
if (rawMsgSource) {
|
||||
const decodedMsgSource = this.decodeHtmlEntities(rawMsgSource)
|
||||
if (decodedMsgSource) {
|
||||
sources.push(decodedMsgSource)
|
||||
}
|
||||
}
|
||||
|
||||
const fullContent = this.sanitizeQuotedContent(this.extractXmlValue(sources[0] || referMsgXml, 'content'))
|
||||
const partialText = this.extractPartialQuotedText(sources[0] || referMsgXml, fullContent)
|
||||
if (partialText) return partialText
|
||||
|
||||
const candidateTags = [
|
||||
'selectedcontent',
|
||||
'selectedtext',
|
||||
'selectcontent',
|
||||
'selecttext',
|
||||
'quotecontent',
|
||||
'quotetext',
|
||||
'partcontent',
|
||||
'parttext',
|
||||
'excerpt',
|
||||
'summary',
|
||||
'preview'
|
||||
]
|
||||
|
||||
for (const source of sources) {
|
||||
for (const tag of candidateTags) {
|
||||
const value = this.sanitizeQuotedContent(this.extractXmlValue(source, tag))
|
||||
if (value) return value
|
||||
}
|
||||
}
|
||||
|
||||
return fullContent
|
||||
}
|
||||
|
||||
private extractPartialQuotedText(xml: string, fullContent: string): string {
|
||||
if (!xml || !fullContent) return ''
|
||||
|
||||
const startChar = this.extractXmlValue(xml, 'start')
|
||||
const endChar = this.extractXmlValue(xml, 'end')
|
||||
const startIndexRaw = this.extractXmlValue(xml, 'startindex')
|
||||
const endIndexRaw = this.extractXmlValue(xml, 'endindex')
|
||||
const startIndex = Number.parseInt(startIndexRaw, 10)
|
||||
const endIndex = Number.parseInt(endIndexRaw, 10)
|
||||
|
||||
if (startChar && endChar) {
|
||||
const startPos = fullContent.indexOf(startChar)
|
||||
if (startPos !== -1) {
|
||||
const endPos = fullContent.indexOf(endChar, startPos + startChar.length - 1)
|
||||
if (endPos !== -1 && endPos >= startPos) {
|
||||
const sliced = fullContent.slice(startPos, endPos + endChar.length).trim()
|
||||
if (sliced) return sliced
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Number.isFinite(startIndex) && Number.isFinite(endIndex) && endIndex >= startIndex) {
|
||||
const chars = Array.from(fullContent)
|
||||
const sliced = chars.slice(startIndex, endIndex + 1).join('').trim()
|
||||
if (sliced) return sliced
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
private extractChatLabReplyToMessageId(content: string): string | undefined {
|
||||
try {
|
||||
const normalized = this.normalizeAppMessageContent(content || '')
|
||||
|
||||
56
package-lock.json
generated
56
package-lock.json
generated
@@ -27,7 +27,7 @@
|
||||
"react-router-dom": "^7.14.0",
|
||||
"react-virtuoso": "^4.18.1",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"sherpa-onnx-node": "^1.10.38",
|
||||
"sherpa-onnx-node": "^1.12.35",
|
||||
"silk-wasm": "^3.7.1",
|
||||
"sudo-prompt": "^9.2.1",
|
||||
"wechat-emojis": "^1.0.2",
|
||||
@@ -9087,9 +9087,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sherpa-onnx-darwin-arm64": {
|
||||
"version": "1.12.34",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-darwin-arm64/-/sherpa-onnx-darwin-arm64-1.12.34.tgz",
|
||||
"integrity": "sha512-UMUZW+NAto+Na7wOYzAwwPU7wZtWdkYcoTNQ5RgDPkPW6PO6l+AlaUxoJJR6ehNojoEAfSxSOpQz+GYkDTHgJw==",
|
||||
"version": "1.12.35",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-darwin-arm64/-/sherpa-onnx-darwin-arm64-1.12.35.tgz",
|
||||
"integrity": "sha512-WGIABo3ruBXE/7FhAdaVNuM+ZKx0B7jkA+jT22k5TxUcw58nWzgkY6k+CPdM14lfaaXR+jPWdDrM4gXl/bP4RQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -9100,9 +9100,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sherpa-onnx-darwin-x64": {
|
||||
"version": "1.12.34",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-darwin-x64/-/sherpa-onnx-darwin-x64-1.12.34.tgz",
|
||||
"integrity": "sha512-ni9nAkceaUM7X7OglnipiHhFd0XDN6OaQdOBfR7ePVWIj0FOfJgZsHbFeBK8g3erd2Q1O07isOiidMd1rslTJg==",
|
||||
"version": "1.12.35",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-darwin-x64/-/sherpa-onnx-darwin-x64-1.12.35.tgz",
|
||||
"integrity": "sha512-hzWQm4CJhGyf3N9Sd1Oobcdz49FauuSCmhrm5vRqydyNsANjs89wATHAuatPAtinpBkgEqacDPrGz+1A/BWpNA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -9113,9 +9113,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sherpa-onnx-linux-arm64": {
|
||||
"version": "1.12.34",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-linux-arm64/-/sherpa-onnx-linux-arm64-1.12.34.tgz",
|
||||
"integrity": "sha512-0w6x9onElqmDYoIm7+gLHIbNzCZ6+ivKBMkrSMI1iTNVtSV0jLumY5XwW9VgzNeEfnLCK7eqlviMKQPo7M52UA==",
|
||||
"version": "1.12.35",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-linux-arm64/-/sherpa-onnx-linux-arm64-1.12.35.tgz",
|
||||
"integrity": "sha512-9glJ+dRv/rFWz/61tiKfaR9Gj+8B6sXi7NBgwBAnO/+ygu/WAjBfQRz2+S0YIy1dxqu7ng246TBNnx1M2XaNXA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -9126,9 +9126,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sherpa-onnx-linux-x64": {
|
||||
"version": "1.12.34",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-linux-x64/-/sherpa-onnx-linux-x64-1.12.34.tgz",
|
||||
"integrity": "sha512-yIf3A+F/hUwPX/YJ0XSaB+KoS4a+sQa3qdQ1Bai046yfCxCRLC8+mDFnSVPf/Ekp3U3jhKLRv4F+68ZXrV2qHw==",
|
||||
"version": "1.12.35",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-linux-x64/-/sherpa-onnx-linux-x64-1.12.35.tgz",
|
||||
"integrity": "sha512-h+v4Yed8T+k1qLlKX2LTGoXP/11ycz7jbqC2f80kDWgz9J8m46mOBa/H20wVkLyQPy1vG1O5iH5Fe5Wh4QlLhw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -9139,23 +9139,23 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sherpa-onnx-node": {
|
||||
"version": "1.12.34",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-node/-/sherpa-onnx-node-1.12.34.tgz",
|
||||
"integrity": "sha512-Ov3nqqSJBiW45KMfV32smo3NNqYO1oiB9nUR7sbRpRunoZZZrxbFg8YkH+pZ8VlcErDyJVSLk/oKtqwHGc13lQ==",
|
||||
"version": "1.12.35",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-node/-/sherpa-onnx-node-1.12.35.tgz",
|
||||
"integrity": "sha512-RHCgV+9fos/ZxP0MsIL7JPU9K3YHnIDmwtX674ChQZY6DLVaIQaju+J3hDqzRu1R3agnDg9WDf01zsT46NC7SQ==",
|
||||
"license": "Apache-2.0",
|
||||
"optionalDependencies": {
|
||||
"sherpa-onnx-darwin-arm64": "^1.12.34",
|
||||
"sherpa-onnx-darwin-x64": "^1.12.34",
|
||||
"sherpa-onnx-linux-arm64": "^1.12.34",
|
||||
"sherpa-onnx-linux-x64": "^1.12.34",
|
||||
"sherpa-onnx-win-ia32": "^1.12.34",
|
||||
"sherpa-onnx-win-x64": "^1.12.34"
|
||||
"sherpa-onnx-darwin-arm64": "^1.12.35",
|
||||
"sherpa-onnx-darwin-x64": "^1.12.35",
|
||||
"sherpa-onnx-linux-arm64": "^1.12.35",
|
||||
"sherpa-onnx-linux-x64": "^1.12.35",
|
||||
"sherpa-onnx-win-ia32": "^1.12.35",
|
||||
"sherpa-onnx-win-x64": "^1.12.35"
|
||||
}
|
||||
},
|
||||
"node_modules/sherpa-onnx-win-ia32": {
|
||||
"version": "1.12.34",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-win-ia32/-/sherpa-onnx-win-ia32-1.12.34.tgz",
|
||||
"integrity": "sha512-AAhK2dvx1zSYLae7NTmxnXmD8bTWHcd1Rr1MQRnDAAGAFW0rnZ7WSmJwsoZ4uT2K+d4Kf4vlbSxl8k8qzWkq6g==",
|
||||
"version": "1.12.35",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-win-ia32/-/sherpa-onnx-win-ia32-1.12.35.tgz",
|
||||
"integrity": "sha512-6H6BSdXXWtz92AuvOmr4w/QvCofxXbfbNKT7jCxdE7Nd4AvinLJxT02vbnL6T54vuXd9chu0QvQrDl1tuRphAA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -9166,9 +9166,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/sherpa-onnx-win-x64": {
|
||||
"version": "1.12.34",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-win-x64/-/sherpa-onnx-win-x64-1.12.34.tgz",
|
||||
"integrity": "sha512-OjQwOfoKIKL1F/i1hjV8918FYZFVwHxrSnk4/yvG1GLzabzifzGcKcj5SjGnIJSH3Zj233wZStTLTrBH+8+BfA==",
|
||||
"version": "1.12.35",
|
||||
"resolved": "https://registry.npmjs.org/sherpa-onnx-win-x64/-/sherpa-onnx-win-x64-1.12.35.tgz",
|
||||
"integrity": "sha512-+GLrxwaEvpJAO0KZgKulfd4qUR089MD+TjE5jVSugMTq4Eh/R/TpPPqYQGibRZVPHW7Se1ABfHGapZQoFMHH5Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"react-router-dom": "^7.14.0",
|
||||
"react-virtuoso": "^4.18.1",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"sherpa-onnx-node": "^1.10.38",
|
||||
"sherpa-onnx-node": "^1.12.35",
|
||||
"silk-wasm": "^3.7.1",
|
||||
"sudo-prompt": "^9.2.1",
|
||||
"wechat-emojis": "^1.0.2",
|
||||
|
||||
@@ -8695,28 +8695,6 @@ function MessageBubble({
|
||||
appMsgTextCache.set(selector, value)
|
||||
return value
|
||||
}, [appMsgDoc, appMsgTextCache])
|
||||
const queryPreferredQuotedContent = useCallback((): string => {
|
||||
if (message.quotedContent) return message.quotedContent
|
||||
const candidates = [
|
||||
'refermsg > selectedcontent',
|
||||
'refermsg > selectedtext',
|
||||
'refermsg > selectcontent',
|
||||
'refermsg > selecttext',
|
||||
'refermsg > quotecontent',
|
||||
'refermsg > quotetext',
|
||||
'refermsg > partcontent',
|
||||
'refermsg > parttext',
|
||||
'refermsg > excerpt',
|
||||
'refermsg > summary',
|
||||
'refermsg > preview',
|
||||
'refermsg > content'
|
||||
]
|
||||
for (const selector of candidates) {
|
||||
const value = queryAppMsgText(selector)
|
||||
if (value) return value
|
||||
}
|
||||
return ''
|
||||
}, [message.quotedContent, queryAppMsgText])
|
||||
const appMsgThumbRawCandidate = useMemo(() => (
|
||||
message.linkThumb ||
|
||||
message.appMsgThumbUrl ||
|
||||
@@ -8734,7 +8712,7 @@ function MessageBubble({
|
||||
queryAppMsgText('refermsg > fromusr'),
|
||||
queryAppMsgText('refermsg > chatusr')
|
||||
)
|
||||
const quotedContent = queryPreferredQuotedContent()
|
||||
const quotedContent = message.quotedContent || queryAppMsgText('refermsg > content') || ''
|
||||
const quotedSenderFallbackName = useMemo(
|
||||
() => resolveQuotedSenderFallbackDisplayName(
|
||||
session.username,
|
||||
@@ -9284,7 +9262,7 @@ function MessageBubble({
|
||||
// type 57: 引用回复消息,解析 refermsg 渲染为引用样式
|
||||
if (xmlType === '57') {
|
||||
const replyText = q('title') || cleanedParsedContent || ''
|
||||
const referContent = queryPreferredQuotedContent()
|
||||
const referContent = q('refermsg > content') || ''
|
||||
const referType = q('refermsg > type') || ''
|
||||
|
||||
// 根据被引用消息类型渲染对应内容
|
||||
@@ -9407,7 +9385,7 @@ function MessageBubble({
|
||||
if (kind === 'quote') {
|
||||
// 引用回复消息(appMsgKind='quote',xmlType=57)
|
||||
const replyText = message.linkTitle || q('title') || cleanedParsedContent || ''
|
||||
const referContent = queryPreferredQuotedContent()
|
||||
const referContent = message.quotedContent || q('refermsg > content') || ''
|
||||
return (
|
||||
renderBubbleWithQuote(
|
||||
renderQuotedMessageBlock(renderTextWithEmoji(cleanMessageContent(referContent))),
|
||||
@@ -9598,7 +9576,7 @@ function MessageBubble({
|
||||
// 引用回复消息 (type=57),防止被误判为链接
|
||||
if (appMsgType === '57') {
|
||||
const replyText = parsedDoc?.querySelector('title')?.textContent?.trim() || cleanedParsedContent || ''
|
||||
const referContent = queryPreferredQuotedContent()
|
||||
const referContent = parsedDoc?.querySelector('refermsg > content')?.textContent?.trim() || ''
|
||||
const referType = parsedDoc?.querySelector('refermsg > type')?.textContent?.trim() || ''
|
||||
|
||||
const renderReferContent2 = () => {
|
||||
|
||||
Reference in New Issue
Block a user