Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a978023
feat: add developer page available if user developer
foreA-adoxid Jan 31, 2026
03d03cd
feat: add modal for asar path select on linux
foreA-adoxid Jan 31, 2026
cdc376c
chore: update patchnotes
foreA-adoxid Jan 31, 2026
39c1c63
chore: update patchnotes
foreA-adoxid Jan 31, 2026
519fb5a
chore: change default build branch
foreA-adoxid Jan 31, 2026
661199a
feat: add build windows+macos option to workflow
foreA-adoxid Jan 31, 2026
0f8299b
fix: mod manager error
foreA-adoxid Jan 31, 2026
c7aada1
fix: try to fix linux launch error
foreA-adoxid Jan 31, 2026
4d4bc8b
fix: revert last commit
foreA-adoxid Jan 31, 2026
bb55521
fix: revert last commit
foreA-adoxid Jan 31, 2026
a84e3f3
Update forge.config.ts
foreA-adoxid Jan 31, 2026
1a2f9a6
fix: linux mod install
foreA-adoxid Feb 1, 2026
1bfc37c
fix: try to fix linux install again
foreA-adoxid Feb 1, 2026
a9a6258
Update postinstall.sh
foreA-adoxid Feb 1, 2026
12c5bd8
fix: very very best fix
foreA-adoxid Feb 1, 2026
e2abd42
Update electron-builder.yml
foreA-adoxid Feb 1, 2026
77ab2cc
fix: enable auto updater on linux
foreA-adoxid Feb 1, 2026
0d83926
fix: linux pext association
foreA-adoxid Feb 1, 2026
d5d28e1
fix: pext icon on linux
foreA-adoxid Feb 1, 2026
b1887ef
fix: icon cache on linux
foreA-adoxid Feb 1, 2026
7b99715
chore: bump version
foreA-adoxid Feb 1, 2026
b6e0ef8
Revert "chore: bump version"
foreA-adoxid Feb 1, 2026
00f4535
fix: postinstall script for linux
foreA-adoxid Feb 1, 2026
ba97b36
fix: change set custom path on linux
foreA-adoxid Feb 1, 2026
68a26cb
fix: update modal events
foreA-adoxid Feb 1, 2026
d88b7d5
fix: try to fix sandbox error on linux
foreA-adoxid Feb 1, 2026
afa7269
fix: main window events not work on linux
foreA-adoxid Feb 1, 2026
72d6e12
fix: custom path select in modal
foreA-adoxid Feb 1, 2026
3fe5a3d
fix: custom path select in modal
foreA-adoxid Feb 1, 2026
4ab4773
feat: optimize mod manager
foreA-adoxid Feb 1, 2026
4f01552
update: auth callback URL to include source parameter
Maks1mio Feb 2, 2026
e47abda
feat: update mod manager
foreA-adoxid Feb 4, 2026
2e2652c
fix: PulseSyncDialog modal text
foreA-adoxid Feb 6, 2026
d74c354
feat: make fonts load from file instead of url
foreA-adoxid Feb 6, 2026
c688d9e
feat: enhance authentication page with default theme and space backgr…
Maks1mio Feb 7, 2026
dbcd747
feat: improve layout component with updated styling and alert informa…
Maks1mio Feb 8, 2026
4dbe428
fix: yandex music autolaunch after mod install
foreA-adoxid Feb 8, 2026
c4ec96a
chore: update patchnotes
foreA-adoxid Feb 9, 2026
3a8d4ee
chore: bump dependencies
foreA-adoxid Feb 9, 2026
8fb33ab
feat: add select status language in rpc
foreA-adoxid Feb 9, 2026
1aa98bb
fix: encoding in pkexec on linux
foreA-adoxid Feb 9, 2026
90fb1f1
feat: move config.json and web_config into appConfig
foreA-adoxid Feb 9, 2026
e93570a
feat: Update client avatar banner variants
foreA-adoxid Feb 10, 2026
3228d00
fix: Make some toast more clear
TheKing-OfTime Feb 10, 2026
509b202
fix: Make banners and avatars lazy load and add variable attachment s…
TheKing-OfTime Feb 10, 2026
a91ccac
fix: Make some toast more clear
TheKing-OfTime Feb 10, 2026
cc850ff
chore: Prepare to release
TheKing-OfTime Feb 10, 2026
632fb54
fix: pull request actions runs
foreA-adoxid Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/build-manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
target:
description: "Choose build branch"
required: true
default: "2.10.0"
default: "dev"
build_os:
description: "Choose OS to build"
required: true
Expand All @@ -16,6 +16,7 @@ on:
- ubuntu-latest
- windows-latest
- macos-latest
- windows+macos
default: all
upload_to_s3:
description: "Upload release/ to S3 after build"
Expand Down Expand Up @@ -59,7 +60,7 @@ jobs:
environment: BUILD_PRODUCTION
strategy:
matrix:
os: ${{ fromJson(inputs.build_os == 'all' && '["ubuntu-latest","windows-latest","macos-latest","macos-15-intel"]' || (inputs.build_os == 'macos-latest' && '["macos-latest","macos-15-intel"]' || format('["{0}"]', inputs.build_os))) }}
os: ${{ fromJson(inputs.build_os == 'all' && '["ubuntu-latest","windows-latest","macos-latest","macos-15-intel"]' || (inputs.build_os == 'macos-latest' && '["macos-latest","macos-15-intel"]' || (inputs.build_os == 'windows+macos' && '["windows-latest","macos-latest","macos-15-intel"]' || format('["{0}"]', inputs.build_os)))) }}

steps:
- uses: actions/checkout@v5
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/build-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ jobs:
- name: Build (package)
run: yarn build:package --nativeModules ${{ matrix.os == 'macos-15-intel' && '--mac-x64' || '' }}
env:
CONFIG_JSON: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) && secrets.CONFIG_JSON || '' }}
RENDERER_CONFIG: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) && secrets.RENDERER_CONFIG || '' }}
APP_CONFIG: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) && secrets.APP_CONFIG || '' }}

- name: Show release contents (debug)
shell: bash
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ out/
.idea
yarn.lock

web_config.ts
config.json
appConfig.ts
release


Expand Down
2 changes: 1 addition & 1 deletion .yarnrc.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nodeLinker: "node-modules"
nodeLinker: 'node-modules'
20 changes: 6 additions & 14 deletions PATCHNOTES.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
### Добавлено
- Настройка отключающая брендинг PulseSync в RPC, доступна, если имеется подписка на Boosty
- Переключение языка интерфейса: Русский и Английский
- Аддоны теперь показывают совместимость с версиями приложения
- Если аддон устарел, приложение предупреждает об этом
- Установка мода стала удобнее
- появился кэш, загрузка теперь быстрее
- кэш можно очистить
- добавили проверку файлов, чтобы ловить повреждённые файлы
### Изменено
- Улучшили работу с ресурсами приложения
- Улучшили скорость загрузки страницы с аддонами
- Изменен дизайн у модального окна установки/обновления мода
- Изменен дизайн страницы авторизации
- Улучшены сообщения в некоторых тостаx.
- Теперь баннеры и аватары загружаются на фоне, а также под занимаемый размер на экране. (Раньше ваш ултра 4к баннер мог загружаться в картинку 200x300px)
### Исправлено
- Починили импорт аддонов при запуске, когда он иногда не срабатывал
- Починили кнопку "Директория аддонов" в опциях на странице аддонов
- Подправили интерфейс в нескольких местах: авторизация, контекстное меню, модалки, выбор цвета на странице аддонов
- Теперь автозапуск яндекс музыки работает корректно
- Из прогресс бара уровней убраны лишние элементы. Теперь он выглядит не перегружено
4 changes: 2 additions & 2 deletions declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ declare module '*.wav' {
}

declare module '*.gif' {
const src: string;
export default src;
const src: string
export default src
}

declare module '*.md'
12 changes: 9 additions & 3 deletions electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ directories:
files:
- package.json

electronLanguages:
- ru
- en-US

fileAssociations:
- ext: pext
name: PulseSync extension
Expand Down Expand Up @@ -67,9 +71,9 @@ nsis:

linux:
target:
- AppImage
- deb
- rpm
# - AppImage
- deb
# - rpm
category: AudioVideo
icon: ./icons/icon.png
executableName: pulsesync
Expand Down Expand Up @@ -109,6 +113,7 @@ rpm:
- libXtst
- nss
- xdg-utils
afterInstall: scriptsInstaller/linux/postinstall.sh

deb:
depends:
Expand All @@ -125,3 +130,4 @@ deb:
- libayatana-appindicator3-1 | libappindicator3-1
compression: xz
priority: optional
afterInstall: scriptsInstaller/linux/postinstall.sh
7 changes: 6 additions & 1 deletion forge.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const forgeConfig: ForgeConfig = {
packagerConfig: {
icon: process.platform === 'linux' ? './icons/icon.png' : './icons/icon',
name: 'PulseSync',
executableName: 'PulseSync',
executableName: process.platform === 'linux' ? 'pulsesync' : 'PulseSync',
appCopyright: `Copyright (C) ${new Date().getFullYear()} ИП «Деднев Григорий Дмитриевич»`,
asar: {
unpack: '**/.vite/renderer/**/static/assets/icon/**',
Expand Down Expand Up @@ -78,6 +78,7 @@ const forgeConfig: ForgeConfig = {
case 'author':
case 'devDependencies':
case 'homepage':
case 'buildInfo':
break
default:
delete pkg[key]
Expand All @@ -91,6 +92,10 @@ const forgeConfig: ForgeConfig = {
const iconDestination = path.join(resourcesPath, 'assets', 'icon')
fs.mkdirSync(iconDestination, { recursive: true })
fs.cpSync(iconSource, iconDestination, { recursive: true })
const pextIconSource = path.resolve(__dirname, 'icons', 'pext')
const pextIconDestination = path.join(resourcesPath, 'assets', 'pext')
fs.mkdirSync(pextIconDestination, { recursive: true })
fs.cpSync(pextIconSource, pextIconDestination, { recursive: true })
console.log(`Built app ${platform}-${arch} with Electron ${electronVersion}`)
},
},
Expand Down
52 changes: 26 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"author": "PulseSync <contact@pulsesync.dev>",
"description": "PulseSync app for desktops",
"homepage": "https://pulsesync.dev",
"version": "2.10.1-beta",
"version": "2.10.2-beta",
"main": ".vite/main/index.js",
"scripts": {
"start": "electron-forge start",
"build:package": "ts-node scripts/build.ts --application --debug",
"build:installer": "ts-node scripts/build.ts --installer --debug",
"build:nativeModules": "ts-node scripts/build.ts --application --nativeModules --debug",
"build:nativeModules": "ts-node scripts/build.ts --nativeModules --debug",
"publish:api": "ts-node scripts/changelog-publish.ts --api",
"publish:discord": "ts-node scripts/changelog-publish.ts --discord",
"publish:beta": "ts-node scripts/build.ts --application --publish beta --debug",
Expand All @@ -24,23 +24,23 @@
"keywords": [],
"license": "GPL-3.0+",
"devDependencies": {
"@aws-sdk/client-s3": "^3.978.0",
"@aws-sdk/client-s3": "^3.986.0",
"@electron-forge/cli": "^7.11.1",
"@electron-forge/maker-deb": "^7.11.1",
"@electron-forge/maker-dmg": "^7.11.1",
"@electron-forge/maker-rpm": "^7.11.1",
"@electron-forge/maker-squirrel": "^7.11.1",
"@electron-forge/maker-zip": "^7.11.1",
"@electron-forge/plugin-vite": "^7.11.1",
"@sentry/vite-plugin": "^4.8.0",
"@sentry/vite-plugin": "^4.9.1",
"@types/adm-zip": "^0.5.7",
"@types/electron": "^1.6.12",
"@types/fs-extra": "^11.0.4",
"@types/glob": "^9.0.0",
"@types/lodash.debounce": "^4.0.9",
"@types/node": "^25.1.0",
"@types/node": "^25.2.3",
"@types/plist": "^3.0.5",
"@types/react": "^19.2.10",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"@types/react-modal": "^3.16.3",
"@types/react-transition-group": "^4.4.12",
Expand All @@ -54,12 +54,12 @@
"@types/unzipper": "^0.10.11",
"@types/uuid": "^11.0.0",
"@types/yazl": "^3.3.0",
"@typescript-eslint/eslint-plugin": "^8.54.0",
"@typescript-eslint/parser": "^8.54.0",
"@vitejs/plugin-react-swc": "^4.2.2",
"electron": "40.1.0",
"electron-builder": "^26.6.0",
"eslint": "^9.39.2",
"@typescript-eslint/eslint-plugin": "^8.55.0",
"@typescript-eslint/parser": "^8.55.0",
"@vitejs/plugin-react-swc": "^4.2.3",
"electron": "40.2.1",
"electron-builder": "^26.7.0",
"eslint": "^10.0.0",
"eslint-plugin-import": "^2.32.0",
"iconv-lite": "^0.7.2",
"prettier": "^3.8.1",
Expand All @@ -72,21 +72,21 @@
"vite-plugin-svgr": "^4.5.0"
},
"dependencies": {
"@apollo/client": "^4.1.3",
"@dr.pogodin/react-helmet": "^3.0.5",
"@apollo/client": "^4.1.4",
"@dr.pogodin/react-helmet": "^3.0.6",
"@electron-forge/plugin-fuses": "^7.11.1",
"@electron/fuses": "1.8.0",
"@electron/fuses": "2.0.0",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@mui/joy": "^5.0.0-beta.52",
"@radix-ui/react-tooltip": "^1.2.8",
"@reduxjs/toolkit": "^2.11.2",
"@sentry/electron": "^7.7.0",
"@sentry/electron": "^7.7.1",
"@xhayper/discord-rpc": "^1.3.0",
"acorn": "^8.15.0",
"acorn-walk": "^8.3.4",
"adm-zip": "^0.5.16",
"axios": "^1.13.4",
"axios": "^1.13.5",
"browserify-fs": "^1.0.0",
"browserify-sign": "^4.2.5",
"chart.js": "^4.5.1",
Expand All @@ -96,12 +96,12 @@
"electron-store": "11.0.2",
"electron-updater": "^6.8.1",
"formik": "^2.4.9",
"framer-motion": "^12.29.2",
"framer-motion": "^12.34.0",
"fs-extra": "^11.3.3",
"glob": "^13.0.0",
"glob": "^13.0.1",
"graphql": "^16.12.0",
"graphql-ws": "^6.0.7",
"i18next": "^25.8.0",
"i18next": "^25.8.4",
"lodash.debounce": "^4.0.8",
"log4js": "^6.9.1",
"net": "^1.0.2",
Expand All @@ -121,15 +121,15 @@
"rehype-raw": "^7.0.0",
"remark-breaks": "^4.0.0",
"remark-gfm": "^4.0.1",
"resedit": "^3.0.1",
"resedit": "^3.0.2",
"rxjs": "^7.8.2",
"semver": "^7.7.3",
"semver": "^7.7.4",
"socket.io": "^4.8.3",
"socket.io-client": "^4.8.3",
"source-map-support": "^0.5.21",
"stream-browserify": "^3.0.0",
"string-similarity": "^4.0.4",
"systeminformation": "^5.30.6",
"systeminformation": "^5.30.7",
"tar": "^7.5.7",
"url": "^0.11.4",
"uuid": "^13.0.0",
Expand All @@ -146,9 +146,9 @@
"forge": "./forge.config.ts"
},
"buildInfo": {
"VERSION": "2.10.0-beta",
"BRANCH": "8272fce",
"BUILD_TIME": "31.01.2026, 01:12:30"
"VERSION": "2.10.2-beta",
"BRANCH": "897313a",
"BUILD_TIME": "10.02.2026, 18:09:31"
},
"optionalDependencies": {
"bufferutil": "^4.1.0",
Expand Down
48 changes: 12 additions & 36 deletions scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { exec as _exec, execSync } from 'child_process'
import { performance } from 'perf_hooks'
import chalk from 'chalk'
import yaml from 'js-yaml'
import { publishToS3, generateAndPublishMacDownloadJson } from './s3-upload'
import { generateAndPublishMacDownloadJson, publishToS3 } from './s3-upload'
import { publishChangelogToApi, publishPatchNotesToDiscord } from './changelog-publish'

const exec = promisify(_exec)
Expand Down Expand Up @@ -126,19 +126,11 @@ async function runCommandStep(name: string, command: string): Promise<void> {
}

function applyConfigFromEnv() {
const configJson = process.env.CONFIG_JSON
const rendererConfig = process.env.RENDERER_CONFIG

if (configJson) {
const configJsonPath = path.resolve(__dirname, '../src/config.json')
fs.writeFileSync(configJsonPath, configJson, 'utf-8')
log(LogLevel.SUCCESS, `Wrote ${configJsonPath}`)
}

if (rendererConfig) {
const rendererConfigPath = path.resolve(__dirname, '../src/renderer/api/web_config.ts')
fs.writeFileSync(rendererConfigPath, rendererConfig, 'utf-8')
log(LogLevel.SUCCESS, `Wrote ${rendererConfigPath}`)
const configSource = process.env.APP_CONFIG
if (configSource) {
const appConfigPath = path.resolve(__dirname, '../src/common/appConfig.ts')
fs.writeFileSync(appConfigPath, configSource, 'utf-8')
log(LogLevel.SUCCESS, `Wrote ${appConfigPath}`)
}
}

Expand All @@ -155,24 +147,24 @@ function ensureNodeHeapForMac(): void {
}

function setConfigDevFalse(branch?: string) {
const configPath = path.resolve(__dirname, '../src/renderer/api/web_config.ts')
const configPath = path.resolve(__dirname, '../src/common/appConfig.ts')
let content = fs.readFileSync(configPath, 'utf-8')
content = content.replace(/export const isDev\s*=\s*.*$/m, 'export const isDev = false')
if (branch !== 'dev') {
content = content.replace(/export const isDevmark\s*=\s*.*$/m, 'export const isDevmark = false')
}
fs.writeFileSync(configPath, content, 'utf-8')
const devmarkStatus = branch === 'dev' ? ' (isDevmark kept for dev branch)' : ''
log(LogLevel.SUCCESS, `Set isDev to false in web_config.ts${devmarkStatus}`)
log(LogLevel.SUCCESS, `Set isDev to false in appConfig.ts${devmarkStatus}`)
}

function setConfigBranch(branch: string) {
const configPath = path.resolve(__dirname, '../src/renderer/api/web_config.ts')
const configPath = path.resolve(__dirname, '../src/common/appConfig.ts')
let content = fs.readFileSync(configPath, 'utf-8')
content = content.replace(/export const branch\s*=\s*.*$/m, `export const branch = "${branch}"`)

fs.writeFileSync(configPath, content, 'utf-8')
log(LogLevel.SUCCESS, `Set branch=${branch} in web_config.ts`)
log(LogLevel.SUCCESS, `Set branch=${branch} in appConfig.ts`)
}

async function main(): Promise<void> {
Expand All @@ -181,8 +173,7 @@ async function main(): Promise<void> {
return
}
ensureNodeHeapForMac()
log(LogLevel.INFO, `CONFIG_JSON length: ${process.env.CONFIG_JSON?.length}`)
log(LogLevel.INFO, `RENDERER_CONFIG length: ${process.env.RENDERER_CONFIG?.length}`)
log(LogLevel.INFO, `APP_CONFIG length: ${process.env.APP_CONFIG?.length}`)
applyConfigFromEnv()

log(LogLevel.INFO, `Platform: ${os.platform()}, Arch: ${os.arch()}`)
Expand All @@ -196,7 +187,6 @@ async function main(): Promise<void> {
log(LogLevel.INFO, `Mac target arch: ${macX64Build ? 'x64' : 'arm64'}`)
}

const desiredLinuxExeName = 'pulsesync'
const branchForConfig = publishBranch ?? 'beta'
setConfigBranch(branchForConfig)

Expand Down Expand Up @@ -231,6 +221,7 @@ async function main(): Promise<void> {
const builderBase = path.resolve(__dirname, '../electron-builder.yml')
const baseYml = fs.readFileSync(builderBase, 'utf-8')
const configObj = yaml.load(baseYml) as any

if (os.platform() === 'darwin') {
configObj.dmg = configObj.dmg || {}
configObj.dmg.contents = [
Expand Down Expand Up @@ -293,21 +284,6 @@ async function main(): Promise<void> {
})
}
copyNodes(nativeDir)

if (os.platform() === 'linux') {
const productNameFromYml = getProductNameFromConfig()

const currentBinUpper = path.join(outDir, productNameFromYml)
const targetBinLower = path.join(outDir, desiredLinuxExeName)
try {
if (fs.existsSync(currentBinUpper) && !fs.existsSync(targetBinLower)) {
fs.renameSync(currentBinUpper, targetBinLower)
log(LogLevel.SUCCESS, `Renamed Linux executable → ${desiredLinuxExeName}`)
}
} catch (e: any) {
log(LogLevel.WARN, `Failed to rename executable: ${e.message || e}`)
}
}
}

const outDirX64 = path.join(baseOutDir, `PulseSync-${os.platform()}-x64`)
Expand Down
Loading