From 6432d8953424a00096364d4c1ecf06f93204efdd Mon Sep 17 00:00:00 2001 From: ImMALWARE Date: Sat, 1 Nov 2025 17:24:39 +0300 Subject: [PATCH 1/2] New plugin: Taskbar Progress --- src/i18n/resources/en.json | 4 ++ src/i18n/resources/ru.json | 4 ++ src/plugins/taskbar-progress/index.ts | 67 +++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 src/plugins/taskbar-progress/index.ts diff --git a/src/i18n/resources/en.json b/src/i18n/resources/en.json index 4cf482aa3b..69b334f835 100644 --- a/src/i18n/resources/en.json +++ b/src/i18n/resources/en.json @@ -879,6 +879,10 @@ "description": "Control playback from your Windows taskbar", "name": "Taskbar Media Control" }, + "taskbar-progress": { + "name": "Taskbar Progress", + "description": "Shows the current track playback progress on the taskbar" + }, "touchbar": { "description": "Adds a TouchBar widget for macOS users", "name": "TouchBar" diff --git a/src/i18n/resources/ru.json b/src/i18n/resources/ru.json index a443dda1ce..6cdd90fe58 100644 --- a/src/i18n/resources/ru.json +++ b/src/i18n/resources/ru.json @@ -879,6 +879,10 @@ "description": "Управляйте воспроизведением с панели задач Windows", "name": "Управление мультимедиа на панели задач" }, + "taskbar-progress": { + "name": "Прогресс на панели задач", + "description": "Отображает прогресс воспроизведения текущего трека на панели задач" + }, "touchbar": { "description": "Добавляет виджет тачбара для пользователей macOS", "name": "Тачбар" diff --git a/src/plugins/taskbar-progress/index.ts b/src/plugins/taskbar-progress/index.ts new file mode 100644 index 0000000000..86c0d14c31 --- /dev/null +++ b/src/plugins/taskbar-progress/index.ts @@ -0,0 +1,67 @@ +import { createPlugin } from '@/utils'; +import { registerCallback, type SongInfo } from '@/providers/song-info'; +import { t } from '@/i18n'; + +export default createPlugin({ + name: () => t('plugins.taskbar-progress.name'), + description: () => t('plugins.taskbar-progress.description'), + restartNeeded: true, + config: { enabled: false }, + + async backend({ window }) { + let lastSongInfo: SongInfo | null = null; + let progressInterval: ReturnType | null = null; + + const updateProgressBar = (songInfo: SongInfo) => { + if (!songInfo?.title || typeof songInfo.elapsedSeconds !== 'number' || !songInfo.songDuration) { + return; + } + + if (!lastSongInfo || + songInfo.title !== lastSongInfo.title || + songInfo.elapsedSeconds !== lastSongInfo.elapsedSeconds || + songInfo.isPaused !== lastSongInfo.isPaused) { + lastSongInfo = songInfo; + } + + const progress = songInfo.elapsedSeconds / songInfo.songDuration; + window.setProgressBar(progress, { mode: songInfo.isPaused ? 'paused' : 'normal' }); + }; + + const startProgressInterval = (songInfo: SongInfo) => { + stopProgressInterval(); + if (!songInfo.isPaused) { + progressInterval = setInterval(() => { + if (lastSongInfo && !lastSongInfo.isPaused && typeof lastSongInfo.elapsedSeconds === 'number') { + updateProgressBar({ + ...lastSongInfo, + elapsedSeconds: lastSongInfo.elapsedSeconds + 1 + }); + } + }, 1000); + } + }; + + const stopProgressInterval = () => { + if (progressInterval) { + clearInterval(progressInterval); + progressInterval = null; + } + }; + + registerCallback((songInfo) => { + if (!songInfo?.title) return; + updateProgressBar(songInfo); + if (songInfo.isPaused) { + stopProgressInterval(); + } else { + startProgressInterval(songInfo); + } + }); + + return () => { + stopProgressInterval(); + window.setProgressBar(-1); + }; + } +}); \ No newline at end of file From 9d82fb94d79d913c03278392bd437a7a6c9e2b33 Mon Sep 17 00:00:00 2001 From: ImMALWARE Date: Sat, 1 Nov 2025 17:43:30 +0300 Subject: [PATCH 2/2] Taskbar Progress: review fixes --- src/plugins/taskbar-progress/index.ts | 34 ++++++++++++++++++--------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/plugins/taskbar-progress/index.ts b/src/plugins/taskbar-progress/index.ts index 86c0d14c31..fc6b255485 100644 --- a/src/plugins/taskbar-progress/index.ts +++ b/src/plugins/taskbar-progress/index.ts @@ -8,34 +8,46 @@ export default createPlugin({ restartNeeded: true, config: { enabled: false }, - async backend({ window }) { + backend({ window }) { let lastSongInfo: SongInfo | null = null; let progressInterval: ReturnType | null = null; const updateProgressBar = (songInfo: SongInfo) => { - if (!songInfo?.title || typeof songInfo.elapsedSeconds !== 'number' || !songInfo.songDuration) { + if ( + !songInfo?.title || + typeof songInfo.elapsedSeconds !== 'number' || + !songInfo.songDuration + ) { return; } - if (!lastSongInfo || - songInfo.title !== lastSongInfo.title || - songInfo.elapsedSeconds !== lastSongInfo.elapsedSeconds || - songInfo.isPaused !== lastSongInfo.isPaused) { + if ( + !lastSongInfo || + songInfo.title !== lastSongInfo.title || + songInfo.elapsedSeconds !== lastSongInfo.elapsedSeconds || + songInfo.isPaused !== lastSongInfo.isPaused + ) { lastSongInfo = songInfo; } const progress = songInfo.elapsedSeconds / songInfo.songDuration; - window.setProgressBar(progress, { mode: songInfo.isPaused ? 'paused' : 'normal' }); + window.setProgressBar(progress, { + mode: songInfo.isPaused ? 'paused' : 'normal', + }); }; const startProgressInterval = (songInfo: SongInfo) => { stopProgressInterval(); if (!songInfo.isPaused) { progressInterval = setInterval(() => { - if (lastSongInfo && !lastSongInfo.isPaused && typeof lastSongInfo.elapsedSeconds === 'number') { + if ( + lastSongInfo && + !lastSongInfo.isPaused && + typeof lastSongInfo.elapsedSeconds === 'number' + ) { updateProgressBar({ ...lastSongInfo, - elapsedSeconds: lastSongInfo.elapsedSeconds + 1 + elapsedSeconds: lastSongInfo.elapsedSeconds + 1, }); } }, 1000); @@ -63,5 +75,5 @@ export default createPlugin({ stopProgressInterval(); window.setProgressBar(-1); }; - } -}); \ No newline at end of file + }, +});