From 1d7950ec4bfbfced8fe0b1001eb41d0afd3a7346 Mon Sep 17 00:00:00 2001 From: vycdev2 Date: Tue, 22 Sep 2026 01:09:04 +0000 Subject: [PATCH] fix: honor theme-specific embedded icon colors --- CHANGELOG.md | 1 + src/utils/view.ts | 39 ++++++++++++++++++++++++++------------- test/view-icons.spec.ts | 20 ++++++++++++++++++++ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6af930d..54a2432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -95,6 +95,7 @@ - Fixed Todo and embedded file grouping so similarly prefixed sibling folders are not treated as workspace roots. - Preserved CRLF line endings when merging tasks into existing archive files. - Fixed embedded todo type icons so changes to `todo.colors.types` apply without restarting VS Code. +- Fixed embedded todo type icons so `todo.colors.dark.types` and `todo.colors.light.types` apply in their matching themes. - Added optional whole-line background colors for configured special tags with `todo.colors.tags.lineBackground`. Fixes: https://github.com/vycdev/vscode-todo-plus-two/issues/93 - Added TextMate syntax scopes so Todo projects, standard statuses, tags, and formatting are visible in the editor minimap. Fixes: https://github.com/vycdev/vscode-todo-plus-two/issues/70 - Added a command to copy the project at the cursor with its rendered statistics included as text. Fixes: https://github.com/vycdev/vscode-todo-plus-two/issues/73 diff --git a/src/utils/view.ts b/src/utils/view.ts index 9e11be4..1ed258a 100644 --- a/src/utils/view.ts +++ b/src/utils/view.ts @@ -26,8 +26,6 @@ const View = { icons: {}, getTypeIcon(type) { - //TODO: Add support for light/dark colors - const color = Consts.colors.types[type]; if (!color) return; @@ -37,23 +35,38 @@ const View = { if (!storagePath) return; - const colorHash = sha1(color), - iconPath = path.join(storagePath, `type-color-${colorHash}.svg`), - iconKey = `${type}:${colorHash}`; + const getIconPath = (iconColor: string) => { + const colorHash = sha1(iconColor), + iconPath = path.join(storagePath, `type-color-${colorHash}.svg`), + iconKey = `${type}:${colorHash}`; + + if (View.icons[iconKey]) return View.icons[iconKey]; + + mkdirp.sync(storagePath); + + if (!fs.existsSync(iconPath)) { + const image = ``; - if (View.icons[iconKey]) return View.icons[iconKey]; + fs.writeFileSync(iconPath, image); + } - mkdirp.sync(storagePath); + View.icons[iconKey] = iconPath; - if (!fs.existsSync(iconPath)) { - const image = ``; + return iconPath; + }; - fs.writeFileSync(iconPath, image); - } + const darkColor = + (Consts.colors.dark && Consts.colors.dark.types && Consts.colors.dark.types[type]) || color, + lightColor = + (Consts.colors.light && Consts.colors.light.types && Consts.colors.light.types[type]) || + color; - View.icons[iconKey] = iconPath; + if (darkColor === color && lightColor === color) return getIconPath(color); - return iconPath; + return { + dark: getIconPath(darkColor), + light: getIconPath(lightColor), + }; }, }; diff --git a/test/view-icons.spec.ts b/test/view-icons.spec.ts index ceac0ce..402ee75 100644 --- a/test/view-icons.spec.ts +++ b/test/view-icons.spec.ts @@ -72,6 +72,26 @@ describe('View type icons', () => { }); }); + it('uses theme-specific type colors for light and dark icons', () => { + withView( + { + types: { TODO: '#ff0000' }, + dark: { types: { TODO: '#00ff00' } }, + light: { types: { TODO: '#0000ff' } }, + }, + (view, writtenPaths) => { + expect(view.getTypeIcon('TODO')).to.deep.equal({ + dark: path.join('/storage', 'type-color-hash-#00ff00.svg'), + light: path.join('/storage', 'type-color-hash-#0000ff.svg'), + }); + expect(writtenPaths).to.deep.equal([ + path.join('/storage', 'type-color-hash-#00ff00.svg'), + path.join('/storage', 'type-color-hash-#0000ff.svg'), + ]); + } + ); + }); + it('uses extension-wide storage when no workspace is open', () => { withView( { types: { TODO: '#ff0000' } },