diff --git a/vscode/webview-ui/src/codeReader/sharing.test.ts b/vscode/webview-ui/src/codeReader/sharing.test.ts index 9bef0a6..547ce51 100644 --- a/vscode/webview-ui/src/codeReader/sharing.test.ts +++ b/vscode/webview-ui/src/codeReader/sharing.test.ts @@ -27,6 +27,16 @@ describe('新文档里指纹没变的块沿用上一份的对象', () => { expect(shared[1].children[1]).not.toBe(PREV[1].children[1]) }) + it('变了的块里没变的部分(译文、只是长短变了时的整张卡片内容)还是原来的对象:卡片重画,里面没变的文字不重画', () => { + const next = hashed([card('0', 'a'), { ...card('1', 'b', [card('1.0', 'c'), card('1.1', 'D')]), span: { ...NO_SPAN, length: 1 } }, card('2', 'e')]) + const shared = shareBlocks(PREV, next) + expect(shared[1]).toEqual(next[1]) + expect('translation' in shared[1] && shared[1].translation).toBe('translation' in PREV[1] && PREV[1].translation) + expect(shared[1].concepts).toBe(PREV[1].concepts) + const child = shared[1].children[1] + expect('translation' in child && child.translation[0]).not.toBe('translation' in PREV[1].children[1] && PREV[1].children[1].translation[0]) + }) + it('多了、少了块:那一层是新的数组,没变的块照样沿用', () => { const longer = shareBlocks(PREV, hashed([card('0', 'a'), card('1', 'b', [card('1.0', 'c'), card('1.1', 'd')]), card('2', 'e'), card('3', 'f')])) expect(longer).not.toBe(PREV) diff --git a/vscode/webview-ui/src/codeReader/sharing.ts b/vscode/webview-ui/src/codeReader/sharing.ts index 8fb9208..62d96a0 100644 --- a/vscode/webview-ui/src/codeReader/sharing.ts +++ b/vscode/webview-ui/src/codeReader/sharing.ts @@ -48,11 +48,21 @@ export function shareBlocks(prev: BlockView[] | undefined, next: BlockView[]): B } } collect(prev) - const share = (list: BlockView[], before: BlockView[] | undefined): BlockView[] => { - const shared = list.map(block => byHash.get(block.hash) ?? { ...block, children: share(block.children, byId.get(block.id)?.children) }) + return share(next, prev) + + function share(list: BlockView[], before: BlockView[] | undefined): BlockView[] { + const shared = list.map(block => byHash.get(block.hash) ?? changed(block)) return before && before.length === shared.length && shared.every((block, index) => block === before[index]) ? before : shared } - return share(next, prev) + + /** 变了的块(只有几块)里没变的部分和上一份的同一块逐个比着沿用:卡片重画,里面没变的文字不重画 */ + function changed({ children, ...own }: BlockView): BlockView { + const old = byId.get(own.id) + if (!old) + return { ...own, children: share(children, undefined) } + const { children: before, ...was } = old + return { ...shareUnchanged(was, own), children: share(children, before) } + } } function isPlainObject(value: unknown): value is Record {