图片解密优化

This commit is contained in:
xuncha
2026-03-17 23:11:37 +08:00
parent 61eef27740
commit ee684021db
2 changed files with 48 additions and 24 deletions

View File

@@ -154,11 +154,40 @@ export class ImageDecryptService {
async decryptImage(payload: { sessionId?: string; imageMd5?: string; imageDatName?: string; force?: boolean }): Promise<DecryptResult> {
await this.ensureCacheIndexed()
const cacheKey = payload.imageMd5 || payload.imageDatName
const cacheKeys = this.getCacheKeys(payload)
const cacheKey = cacheKeys[0]
if (!cacheKey) {
return { success: false, error: '缺少图片标识' }
}
if (payload.force) {
for (const key of cacheKeys) {
const cached = this.resolvedCache.get(key)
if (cached && existsSync(cached) && this.isImageFile(cached) && !this.isThumbnailPath(cached)) {
this.cacheResolvedPaths(cacheKey, payload.imageMd5, payload.imageDatName, cached)
this.clearUpdateFlags(cacheKey, payload.imageMd5, payload.imageDatName)
const dataUrl = this.fileToDataUrl(cached)
const localPath = dataUrl || this.filePathToUrl(cached)
this.emitCacheResolved(payload, cacheKey, localPath)
return { success: true, localPath }
}
if (cached && !this.isImageFile(cached)) {
this.resolvedCache.delete(key)
}
}
for (const key of cacheKeys) {
const existingHd = this.findCachedOutput(key, true, payload.sessionId)
if (!existingHd || this.isThumbnailPath(existingHd)) continue
this.cacheResolvedPaths(cacheKey, payload.imageMd5, payload.imageDatName, existingHd)
this.clearUpdateFlags(cacheKey, payload.imageMd5, payload.imageDatName)
const dataUrl = this.fileToDataUrl(existingHd)
const localPath = dataUrl || this.filePathToUrl(existingHd)
this.emitCacheResolved(payload, cacheKey, localPath)
return { success: true, localPath }
}
}
if (!payload.force) {
const cached = this.resolvedCache.get(cacheKey)
if (cached && existsSync(cached) && this.isImageFile(cached)) {

View File

@@ -6489,6 +6489,10 @@ function MessageBubble({
return 'image/jpeg'
}, [])
const getImageObserverRoot = useCallback((): Element | null => {
return imageContainerRef.current?.closest('.message-list') ?? null
}, [])
// 获取头像首字母
const getAvatarLetter = (name: string): string => {
if (!name) return '?'
@@ -6793,34 +6797,25 @@ function MessageBubble({
const observer = new IntersectionObserver(
(entries) => {
const entry = entries[0]
// rootMargin 设置为 200px提前触发解密
if (entry.isIntersecting && !imageAutoDecryptTriggered.current) {
imageAutoDecryptTriggered.current = true
void requestImageDecrypt()
}
},
{ rootMargin: '200px', threshold: 0 }
)
observer.observe(container)
return () => observer.disconnect()
}, [isImage, imageLocalPath, message.imageMd5, message.imageDatName, requestImageDecrypt])
// 进入视野时自动尝试切换高清图
useEffect(() => {
if (!isImage) return
const container = imageContainerRef.current
if (!container) return
const observer = new IntersectionObserver(
(entries) => {
const entry = entries[0]
// rootMargin 设置为 200px提前感知即将进入视野的图片
setImageInView(entry.isIntersecting)
},
{ rootMargin: '120px', threshold: 0 }
{ root: getImageObserverRoot(), rootMargin: '200px', threshold: 0 }
)
observer.observe(container)
return () => observer.disconnect()
}, [isImage])
}, [getImageObserverRoot, isImage])
// 进入视野后自动触发一次普通解密
useEffect(() => {
if (!isImage || !imageInView) return
if (imageLocalPath || imageLoading) return
if (!message.imageMd5 && !message.imageDatName) return
if (imageAutoDecryptTriggered.current) return
imageAutoDecryptTriggered.current = true
void requestImageDecrypt()
}, [isImage, imageInView, imageLocalPath, imageLoading, message.imageMd5, message.imageDatName, requestImageDecrypt])
useEffect(() => {
if (!isImage || !imageHasUpdate || !imageInView) return