update at 2026-02-11 19:45:21

This commit is contained in:
douboer
2026-02-11 19:45:21 +08:00
parent 9d8316332b
commit a8f6168433
5 changed files with 118 additions and 10 deletions

View File

@@ -418,9 +418,11 @@ async function loadNextPreviewBatch(generationToken: number) {
activePreviewFonts.value.length,
)
previewItems.value = [...previewItems.value, ...batchItems.items]
const existingIds = new Set(previewItems.value.map(item => item.fontInfo.id))
const uniqueBatchItems = batchItems.items.filter(item => !existingIds.has(item.fontInfo.id))
previewItems.value = [...previewItems.value, ...uniqueBatchItems]
renderedPreviewCount.value = Math.min(
renderedPreviewCount.value + PREVIEW_BATCH_SIZE,
renderedPreviewCount.value + uniqueBatchItems.length,
previewItems.value.length,
)
@@ -440,6 +442,90 @@ async function loadNextPreviewBatch(generationToken: number) {
}
}
async function syncPreviewFontsIncrementally(previousFonts: FontInfo[]) {
const generationToken = ++previewGenerationToken
const nextPreviewFonts = [...previewFonts.value]
const validPreviewFontIds = new Set(nextPreviewFonts.map(font => font.id))
uiStore.retainExportItemsByFontIds(validPreviewFontIds)
activePreviewFonts.value = nextPreviewFonts
previewErrorMessage.value = ''
if (!inputText.value || inputText.value.trim() === '' || nextPreviewFonts.length === 0) {
previewItems.value = []
renderedPreviewCount.value = 0
processedFontCount.value = 0
isGenerating.value = false
isBatchGenerating.value = false
batchOwnerToken = null
return
}
const nextIdSet = new Set(nextPreviewFonts.map(font => font.id))
const previousIdSet = new Set(previousFonts.map(font => font.id))
const addedFonts = nextPreviewFonts.filter(font => !previousIdSet.has(font.id))
previewItems.value = previewItems.value.filter(item => nextIdSet.has(item.fontInfo.id))
renderedPreviewCount.value = Math.min(renderedPreviewCount.value, previewItems.value.length)
processedFontCount.value = Math.min(processedFontCount.value, nextPreviewFonts.length)
if (addedFonts.length > 0) {
if (previewItems.value.length === 0) {
isGenerating.value = true
}
try {
const addedBatch = await generatePreviewBatch(
addedFonts,
0,
addedFonts.length,
generationToken,
)
if (isStaleGeneration(generationToken)) {
return
}
const existingIds = new Set(previewItems.value.map(item => item.fontInfo.id))
const uniqueAddedItems = addedBatch.items.filter(item => !existingIds.has(item.fontInfo.id))
if (uniqueAddedItems.length > 0) {
// 新勾选字体插到顶部,避免全量刷新带来的闪烁。
previewItems.value = [...uniqueAddedItems, ...previewItems.value]
renderedPreviewCount.value = Math.min(
renderedPreviewCount.value + uniqueAddedItems.length,
previewItems.value.length,
)
}
if (addedBatch.errors.length > 0 && previewItems.value.length === 0) {
previewErrorMessage.value = `预览生成失败:${addedBatch.errors[0]}`
}
} catch (error) {
console.error('Failed to incrementally load preview fonts:', error)
previewErrorMessage.value = `预览生成失败:${error instanceof Error ? error.message : String(error)}`
} finally {
if (!isStaleGeneration(generationToken)) {
isGenerating.value = false
}
}
}
if (
!isStaleGeneration(generationToken) &&
previewItems.value.length === 0 &&
processedFontCount.value < activePreviewFonts.value.length &&
!isBatchGenerating.value
) {
isGenerating.value = true
try {
await loadNextPreviewBatch(generationToken)
} finally {
if (!isStaleGeneration(generationToken)) {
isGenerating.value = false
}
}
}
}
async function handleLoadMoreByScroll() {
const generationToken = previewGenerationToken
@@ -511,12 +597,34 @@ async function regeneratePreviews() {
}
watch(
[previewFonts, inputText, () => uiStore.letterSpacing],
previewFonts,
(nextFonts, previousFonts) => {
if (!hasTriggeredInitialGenerate || !previousFonts) {
scheduleGeneratePreviews(false)
hasTriggeredInitialGenerate = true
return
}
const previousIds = new Set(previousFonts.map(font => font.id))
if (
nextFonts.length === previousFonts.length &&
nextFonts.every(font => previousIds.has(font.id))
) {
return
}
void syncPreviewFontsIncrementally(previousFonts)
hasTriggeredInitialGenerate = true
},
{ immediate: true },
)
watch(
[inputText, () => uiStore.letterSpacing],
() => {
scheduleGeneratePreviews(hasTriggeredInitialGenerate)
hasTriggeredInitialGenerate = true
},
{ immediate: true },
)
watch(