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..fc6b255485 --- /dev/null +++ b/src/plugins/taskbar-progress/index.ts @@ -0,0 +1,79 @@ +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 }, + + 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); + }; + }, +});