mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 10:31:47 +00:00
feat: migrate from rollup to electron-vite (#1364)
* feat: electron-vite PoC * fix: fix preload path * remove rollup deps and config * fix: debug mode * fix: build mode, asset path * fix: remove unused dependencies * feat: use `executeJavaScriptInIsolatedWorld` instead of `executeJavaScript` * feat: enable `minify` * fix(actions): update task name * fix: fix dev mode check * fix: remove unused variable
This commit is contained in:
@ -1,4 +1,2 @@
|
|||||||
.eslintrc.js
|
.eslintrc.js
|
||||||
rollup.main.config.ts
|
electron.vite.config.ts
|
||||||
rollup.preload.config.ts
|
|
||||||
rollup.renderer.config.ts
|
|
||||||
|
|||||||
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -42,8 +42,8 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
# Only rollup build without release if it is a fork
|
# Only vite build without release if it is a fork, or it is a pull-request
|
||||||
- name: Rollup Build
|
- name: Vite Build
|
||||||
if: github.repository == 'th-ch/youtube-music' && github.event_name == 'pull_request'
|
if: github.repository == 'th-ch/youtube-music' && github.event_name == 'pull_request'
|
||||||
run: |
|
run: |
|
||||||
pnpm build
|
pnpm build
|
||||||
|
|||||||
103
electron.vite.config.ts
Normal file
103
electron.vite.config.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import { defineConfig, defineViteConfig } from 'electron-vite';
|
||||||
|
import builtinModules from 'builtin-modules';
|
||||||
|
|
||||||
|
import type { UserConfig } from 'vite';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
main: defineViteConfig(({ mode }) => {
|
||||||
|
const commonConfig: UserConfig = {
|
||||||
|
publicDir: 'assets',
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
entry: 'src/index.ts',
|
||||||
|
formats: ['cjs'],
|
||||||
|
},
|
||||||
|
outDir: 'dist/main',
|
||||||
|
commonjsOptions: {
|
||||||
|
ignoreDynamicRequires: true,
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: ['electron', 'custom-electron-prompt', ...builtinModules],
|
||||||
|
input: './src/index.ts',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mode === 'development') {
|
||||||
|
return commonConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...commonConfig,
|
||||||
|
build: {
|
||||||
|
...commonConfig.build,
|
||||||
|
minify: true,
|
||||||
|
cssMinify: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
preload: defineViteConfig(({ mode }) => {
|
||||||
|
const commonConfig: UserConfig = {
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
entry: 'src/preload.ts',
|
||||||
|
formats: ['cjs'],
|
||||||
|
},
|
||||||
|
outDir: 'dist/preload',
|
||||||
|
commonjsOptions: {
|
||||||
|
ignoreDynamicRequires: true,
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: ['electron', 'custom-electron-prompt', ...builtinModules],
|
||||||
|
input: './src/preload.ts',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mode === 'development') {
|
||||||
|
return commonConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...commonConfig,
|
||||||
|
build: {
|
||||||
|
...commonConfig.build,
|
||||||
|
minify: true,
|
||||||
|
cssMinify: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
renderer: defineViteConfig(({ mode }) => {
|
||||||
|
const commonConfig: UserConfig = {
|
||||||
|
root: './src/',
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
entry: 'src/index.html',
|
||||||
|
formats: ['iife'],
|
||||||
|
name: 'renderer',
|
||||||
|
},
|
||||||
|
outDir: 'dist/renderer',
|
||||||
|
commonjsOptions: {
|
||||||
|
ignoreDynamicRequires: true,
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: ['electron', ...builtinModules],
|
||||||
|
input: './src/index.html',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mode === 'development') {
|
||||||
|
return commonConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...commonConfig,
|
||||||
|
build: {
|
||||||
|
...commonConfig.build,
|
||||||
|
minify: true,
|
||||||
|
cssMinify: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
28
package.json
28
package.json
@ -3,7 +3,7 @@
|
|||||||
"productName": "YouTube Music",
|
"productName": "YouTube Music",
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"description": "YouTube Music Desktop App - including custom plugins",
|
"description": "YouTube Music Desktop App - including custom plugins",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/main/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": "th-ch/youtube-music",
|
"repository": "th-ch/youtube-music",
|
||||||
"author": {
|
"author": {
|
||||||
@ -17,6 +17,7 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"!*",
|
"!*",
|
||||||
"dist",
|
"dist",
|
||||||
|
"assets",
|
||||||
"license",
|
"license",
|
||||||
"!node_modules",
|
"!node_modules",
|
||||||
"node_modules/custom-electron-prompt/**",
|
"node_modules/custom-electron-prompt/**",
|
||||||
@ -89,12 +90,11 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "playwright test",
|
"test": "playwright test",
|
||||||
"test:debug": "cross-env DEBUG=pw:*,-pw:test:protocol playwright test",
|
"test:debug": "cross-env DEBUG=pw:*,-pw:test:protocol playwright test",
|
||||||
"rollup:renderer": "rollup -c rollup.renderer.config.ts --configPlugin @rollup/plugin-typescript --bundleConfigAsCjs",
|
"build": "electron-vite build",
|
||||||
"rollup:preload": "rollup -c rollup.preload.config.ts --configPlugin @rollup/plugin-typescript --bundleConfigAsCjs",
|
"start": "electron-vite preview",
|
||||||
"rollup:main": "rollup -c rollup.main.config.ts --configPlugin @rollup/plugin-typescript --bundleConfigAsCjs",
|
|
||||||
"build": "yarpm-pnpm run rollup:renderer && yarpm-pnpm run rollup:preload && yarpm-pnpm run rollup:main",
|
|
||||||
"start": "yarpm-pnpm run build && electron ./dist/index.js",
|
|
||||||
"start:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 yarpm-pnpm run start",
|
"start:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 yarpm-pnpm run start",
|
||||||
|
"dev": "electron-vite dev",
|
||||||
|
"dev:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 yarpm-pnpm run dev",
|
||||||
"clean": "del-cli dist && del-cli pack",
|
"clean": "del-cli dist && del-cli pack",
|
||||||
"dist": "yarpm-pnpm run clean && yarpm-pnpm run build && electron-builder --win --mac --linux -p never",
|
"dist": "yarpm-pnpm run clean && yarpm-pnpm run build && electron-builder --win --mac --linux -p never",
|
||||||
"dist:linux": "yarpm-pnpm run clean && yarpm-pnpm run build && electron-builder --linux -p never",
|
"dist:linux": "yarpm-pnpm run clean && yarpm-pnpm run build && electron-builder --linux -p never",
|
||||||
@ -157,6 +157,7 @@
|
|||||||
"html-to-text": "9.0.5",
|
"html-to-text": "9.0.5",
|
||||||
"keyboardevent-from-electron-accelerator": "2.0.0",
|
"keyboardevent-from-electron-accelerator": "2.0.0",
|
||||||
"keyboardevents-areequal": "0.2.2",
|
"keyboardevents-areequal": "0.2.2",
|
||||||
|
"node-html-parser": "6.1.11",
|
||||||
"node-id3": "0.2.6",
|
"node-id3": "0.2.6",
|
||||||
"simple-youtube-age-restriction-bypass": "git+https://github.com/organization/Simple-YouTube-Age-Restriction-Bypass.git#v2.5.8",
|
"simple-youtube-age-restriction-bypass": "git+https://github.com/organization/Simple-YouTube-Age-Restriction-Bypass.git#v2.5.8",
|
||||||
"vudio": "2.1.1",
|
"vudio": "2.1.1",
|
||||||
@ -165,34 +166,29 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "1.39.0",
|
"@playwright/test": "1.39.0",
|
||||||
"@rollup/plugin-commonjs": "25.0.7",
|
|
||||||
"@rollup/plugin-image": "3.0.3",
|
|
||||||
"@rollup/plugin-json": "6.0.1",
|
|
||||||
"@rollup/plugin-node-resolve": "15.2.3",
|
|
||||||
"@rollup/plugin-terser": "0.4.4",
|
|
||||||
"@rollup/plugin-typescript": "11.1.5",
|
|
||||||
"@rollup/plugin-wasm": "6.2.2",
|
|
||||||
"@total-typescript/ts-reset": "0.5.1",
|
"@total-typescript/ts-reset": "0.5.1",
|
||||||
"@types/electron-localshortcut": "3.1.2",
|
"@types/electron-localshortcut": "3.1.2",
|
||||||
"@types/howler": "2.2.10",
|
"@types/howler": "2.2.10",
|
||||||
"@types/html-to-text": "9.0.3",
|
"@types/html-to-text": "9.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "6.9.1",
|
"@typescript-eslint/eslint-plugin": "6.9.1",
|
||||||
|
"bufferutil": "4.0.8",
|
||||||
"builtin-modules": "^3.3.0",
|
"builtin-modules": "^3.3.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"del-cli": "5.1.0",
|
"del-cli": "5.1.0",
|
||||||
"electron": "27.0.3",
|
"electron": "27.0.3",
|
||||||
"electron-builder": "24.6.4",
|
"electron-builder": "24.6.4",
|
||||||
"electron-devtools-installer": "3.2.0",
|
"electron-devtools-installer": "3.2.0",
|
||||||
|
"electron-vite": "1.0.28",
|
||||||
"eslint": "8.53.0",
|
"eslint": "8.53.0",
|
||||||
"eslint-plugin-import": "2.29.0",
|
"eslint-plugin-import": "2.29.0",
|
||||||
"eslint-plugin-prettier": "5.0.1",
|
"eslint-plugin-prettier": "5.0.1",
|
||||||
"node-gyp": "10.0.1",
|
"node-gyp": "10.0.1",
|
||||||
"playwright": "1.39.0",
|
"playwright": "1.39.0",
|
||||||
"rollup": "4.3.0",
|
"rollup": "4.3.0",
|
||||||
"rollup-plugin-copy": "3.5.0",
|
|
||||||
"rollup-plugin-import-css": "3.3.5",
|
|
||||||
"rollup-plugin-string": "3.0.0",
|
|
||||||
"typescript": "5.2.2",
|
"typescript": "5.2.2",
|
||||||
|
"utf-8-validate": "6.0.3",
|
||||||
|
"vite": "4.5.0",
|
||||||
|
"ws": "8.14.2",
|
||||||
"yarpm": "1.2.0"
|
"yarpm": "1.2.0"
|
||||||
},
|
},
|
||||||
"auto-changelog": {
|
"auto-changelog": {
|
||||||
|
|||||||
977
pnpm-lock.yaml
generated
977
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,60 +0,0 @@
|
|||||||
import { defineConfig } from 'rollup';
|
|
||||||
import builtinModules from 'builtin-modules';
|
|
||||||
import typescript from '@rollup/plugin-typescript';
|
|
||||||
import commonjs from '@rollup/plugin-commonjs';
|
|
||||||
import nodeResolvePlugin from '@rollup/plugin-node-resolve';
|
|
||||||
import json from '@rollup/plugin-json';
|
|
||||||
import terser from '@rollup/plugin-terser';
|
|
||||||
import { string } from 'rollup-plugin-string';
|
|
||||||
import css from 'rollup-plugin-import-css';
|
|
||||||
import wasmPlugin from '@rollup/plugin-wasm';
|
|
||||||
import copy from 'rollup-plugin-copy';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [
|
|
||||||
typescript({
|
|
||||||
module: 'ESNext',
|
|
||||||
}),
|
|
||||||
nodeResolvePlugin({
|
|
||||||
browser: false,
|
|
||||||
preferBuiltins: true,
|
|
||||||
exportConditions: ['node', 'default', 'module', 'import'],
|
|
||||||
}),
|
|
||||||
commonjs({
|
|
||||||
ignoreDynamicRequires: true,
|
|
||||||
}),
|
|
||||||
wasmPlugin({
|
|
||||||
maxFileSize: 0,
|
|
||||||
targetEnv: 'browser',
|
|
||||||
}),
|
|
||||||
json(),
|
|
||||||
string({
|
|
||||||
include: '**/*.html',
|
|
||||||
}),
|
|
||||||
css(),
|
|
||||||
copy({
|
|
||||||
targets: [
|
|
||||||
{ src: 'src/error.html', dest: 'dist/' },
|
|
||||||
{ src: 'assets', dest: 'dist/' },
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
terser({
|
|
||||||
ecma: 2020,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
closeBundle() {
|
|
||||||
if (!process.env.ROLLUP_WATCH) {
|
|
||||||
setTimeout(() => process.exit(0));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: 'force-close',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
input: './src/index.ts',
|
|
||||||
output: {
|
|
||||||
format: 'cjs',
|
|
||||||
name: '[name].js',
|
|
||||||
dir: './dist',
|
|
||||||
},
|
|
||||||
external: ['electron', 'custom-electron-prompt', ...builtinModules],
|
|
||||||
});
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
import { defineConfig } from 'rollup';
|
|
||||||
import builtinModules from 'builtin-modules';
|
|
||||||
import typescript from '@rollup/plugin-typescript';
|
|
||||||
import commonjs from '@rollup/plugin-commonjs';
|
|
||||||
import nodeResolvePlugin from '@rollup/plugin-node-resolve';
|
|
||||||
import json from '@rollup/plugin-json';
|
|
||||||
import terser from '@rollup/plugin-terser';
|
|
||||||
import { string } from 'rollup-plugin-string';
|
|
||||||
import css from 'rollup-plugin-import-css';
|
|
||||||
import wasmPlugin from '@rollup/plugin-wasm';
|
|
||||||
import image from '@rollup/plugin-image';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [
|
|
||||||
typescript({
|
|
||||||
module: 'ESNext',
|
|
||||||
}),
|
|
||||||
nodeResolvePlugin({
|
|
||||||
browser: false,
|
|
||||||
preferBuiltins: true,
|
|
||||||
}),
|
|
||||||
commonjs({
|
|
||||||
ignoreDynamicRequires: true,
|
|
||||||
}),
|
|
||||||
json(),
|
|
||||||
string({
|
|
||||||
include: '**/*.html',
|
|
||||||
}),
|
|
||||||
css(),
|
|
||||||
wasmPlugin({
|
|
||||||
maxFileSize: 0,
|
|
||||||
targetEnv: 'browser',
|
|
||||||
}),
|
|
||||||
image({ dom: true }),
|
|
||||||
terser({
|
|
||||||
ecma: 2020,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
closeBundle() {
|
|
||||||
if (!process.env.ROLLUP_WATCH) {
|
|
||||||
setTimeout(() => process.exit(0));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: 'force-close',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
input: './src/preload.ts',
|
|
||||||
output: {
|
|
||||||
format: 'cjs',
|
|
||||||
name: '[name].js',
|
|
||||||
dir: './dist',
|
|
||||||
},
|
|
||||||
external: ['electron', 'custom-electron-prompt', ...builtinModules],
|
|
||||||
});
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
import { defineConfig } from 'rollup';
|
|
||||||
import builtinModules from 'builtin-modules';
|
|
||||||
import typescript from '@rollup/plugin-typescript';
|
|
||||||
import commonjs from '@rollup/plugin-commonjs';
|
|
||||||
import nodeResolvePlugin from '@rollup/plugin-node-resolve';
|
|
||||||
import json from '@rollup/plugin-json';
|
|
||||||
import terser from '@rollup/plugin-terser';
|
|
||||||
import { string } from 'rollup-plugin-string';
|
|
||||||
import css from 'rollup-plugin-import-css';
|
|
||||||
import wasmPlugin from '@rollup/plugin-wasm';
|
|
||||||
import image from '@rollup/plugin-image';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [
|
|
||||||
typescript({
|
|
||||||
module: 'ESNext',
|
|
||||||
}),
|
|
||||||
nodeResolvePlugin({
|
|
||||||
browser: false,
|
|
||||||
preferBuiltins: true,
|
|
||||||
}),
|
|
||||||
commonjs({
|
|
||||||
ignoreDynamicRequires: true,
|
|
||||||
}),
|
|
||||||
json(),
|
|
||||||
string({
|
|
||||||
include: '**/*.html',
|
|
||||||
}),
|
|
||||||
css(),
|
|
||||||
wasmPlugin({
|
|
||||||
maxFileSize: 0,
|
|
||||||
targetEnv: 'browser',
|
|
||||||
}),
|
|
||||||
image({ dom: true }),
|
|
||||||
terser({
|
|
||||||
ecma: 2020,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
closeBundle() {
|
|
||||||
if (!process.env.ROLLUP_WATCH) {
|
|
||||||
setTimeout(() => process.exit(0));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: 'force-close'
|
|
||||||
},
|
|
||||||
],
|
|
||||||
input: './src/renderer.ts',
|
|
||||||
output: {
|
|
||||||
format: 'cjs',
|
|
||||||
name: '[name].js',
|
|
||||||
dir: './dist',
|
|
||||||
},
|
|
||||||
external: [
|
|
||||||
'electron',
|
|
||||||
...builtinModules,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
1
src/index.html
Normal file
1
src/index.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<script type="module" src="./renderer.ts"></script>
|
||||||
37
src/index.ts
37
src/index.ts
@ -8,6 +8,7 @@ import is from 'electron-is';
|
|||||||
import unhandled from 'electron-unhandled';
|
import unhandled from 'electron-unhandled';
|
||||||
import { autoUpdater } from 'electron-updater';
|
import { autoUpdater } from 'electron-updater';
|
||||||
import electronDebug from 'electron-debug';
|
import electronDebug from 'electron-debug';
|
||||||
|
import { parse } from 'node-html-parser';
|
||||||
|
|
||||||
import config from './config';
|
import config from './config';
|
||||||
import { refreshMenu, setApplicationMenu } from './menu';
|
import { refreshMenu, setApplicationMenu } from './menu';
|
||||||
@ -198,7 +199,7 @@ async function createMainWindow() {
|
|||||||
show: false,
|
show: false,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
preload: path.join(__dirname, 'preload.js'),
|
preload: path.join(__dirname, '..', 'preload', 'preload.js'),
|
||||||
...(isTesting()
|
...(isTesting()
|
||||||
? undefined
|
? undefined
|
||||||
: {
|
: {
|
||||||
@ -334,12 +335,34 @@ async function createMainWindow() {
|
|||||||
|
|
||||||
removeContentSecurityPolicy();
|
removeContentSecurityPolicy();
|
||||||
|
|
||||||
win.webContents.on('dom-ready', () => {
|
win.webContents.on('dom-ready', async () => {
|
||||||
const rendererScriptPath = path.join(__dirname, 'renderer.js');
|
// Inject index.html file as string using insertAdjacentHTML
|
||||||
win.webContents.executeJavaScriptInIsolatedWorld(0, [{
|
// In dev mode, get string from process.env.VITE_DEV_SERVER_URL, else use fs.readFileSync
|
||||||
code: fs.readFileSync(rendererScriptPath, 'utf-8') + ';0',
|
if (is.dev() && process.env.ELECTRON_RENDERER_URL) {
|
||||||
url: url.pathToFileURL(rendererScriptPath).toString(),
|
// HACK: to make vite work with electron renderer (supports hot reload)
|
||||||
}], true);
|
await win.webContents.executeJavaScript(`
|
||||||
|
console.log('Loading vite from dev server');
|
||||||
|
const viteScript = document.createElement('script');
|
||||||
|
viteScript.type = 'module';
|
||||||
|
viteScript.src = '${process.env.ELECTRON_RENDERER_URL}/@vite/client';
|
||||||
|
const rendererScript = document.createElement('script');
|
||||||
|
rendererScript.type = 'module';
|
||||||
|
rendererScript.src = '${process.env.ELECTRON_RENDERER_URL}/renderer.ts';
|
||||||
|
document.body.appendChild(viteScript);
|
||||||
|
document.body.appendChild(rendererScript);
|
||||||
|
0
|
||||||
|
`);
|
||||||
|
} else {
|
||||||
|
const rendererPath = path.join(__dirname, '..', 'renderer');
|
||||||
|
const indexHTML = parse(fs.readFileSync(path.join(rendererPath, 'index.html'), 'utf-8'));
|
||||||
|
const scriptSrc = indexHTML.querySelector('script')!;
|
||||||
|
const scriptPath = path.join(rendererPath, scriptSrc.getAttribute('src')!);
|
||||||
|
const scriptString = fs.readFileSync(scriptPath, 'utf-8');
|
||||||
|
await win.webContents.executeJavaScriptInIsolatedWorld(0, [{
|
||||||
|
code: scriptString + ';0',
|
||||||
|
url: url.pathToFileURL(scriptPath).toString(),
|
||||||
|
}], true);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
win.webContents.loadURL(urlToLoad);
|
win.webContents.loadURL(urlToLoad);
|
||||||
|
|||||||
4
src/plugins/adblocker/inject.d.ts
vendored
4
src/plugins/adblocker/inject.d.ts
vendored
@ -1,3 +1 @@
|
|||||||
const inject: () => void;
|
export const inject: () => void;
|
||||||
|
|
||||||
export default inject;
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
Parts of this code is derived from set-constant.js:
|
Parts of this code is derived from set-constant.js:
|
||||||
https://github.com/gorhill/uBlock/blob/5de0ce975753b7565759ac40983d31978d1f84ca/assets/resources/scriptlets.js#L704
|
https://github.com/gorhill/uBlock/blob/5de0ce975753b7565759ac40983d31978d1f84ca/assets/resources/scriptlets.js#L704
|
||||||
*/
|
*/
|
||||||
module.exports = () => {
|
export const inject = () => {
|
||||||
{
|
{
|
||||||
const pruner = function (o) {
|
const pruner = function (o) {
|
||||||
delete o.playerAds;
|
delete o.playerAds;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import config, { shouldUseBlocklists } from './config';
|
import config, { shouldUseBlocklists } from './config';
|
||||||
import inject from './inject';
|
import { inject } from './inject';
|
||||||
import injectCliqzPreload from './inject-cliqz-preload';
|
import injectCliqzPreload from './inject-cliqz-preload';
|
||||||
|
|
||||||
import { blockers } from './blocker-types';
|
import { blockers } from './blocker-types';
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import configProvider from './config-renderer';
|
import configProvider from './config-renderer';
|
||||||
|
|
||||||
import CaptionsSettingsButtonHTML from './templates/captions-settings-template.html';
|
import CaptionsSettingsButtonHTML from './templates/captions-settings-template.html?raw';
|
||||||
|
|
||||||
import { ElementFromHtml } from '../utils-renderer';
|
import { ElementFromHtml } from '../utils-renderer';
|
||||||
import { YoutubePlayer } from '../../types/youtube-player';
|
import { YoutubePlayer } from '../../types/youtube-player';
|
||||||
|
|||||||
@ -208,8 +208,10 @@ export default (
|
|||||||
// if lastSent is more than 5 seconds ago, send the new time
|
// if lastSent is more than 5 seconds ago, send the new time
|
||||||
if (currentTime - lastSent > 5000) {
|
if (currentTime - lastSent > 5000) {
|
||||||
lastSent = currentTime;
|
lastSent = currentTime;
|
||||||
lastSongInfo.elapsedSeconds = t;
|
if (lastSongInfo) {
|
||||||
updateActivity(lastSongInfo);
|
lastSongInfo.elapsedSeconds = t;
|
||||||
|
updateActivity(lastSongInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import downloadHTML from './templates/download.html';
|
import downloadHTML from './templates/download.html?raw';
|
||||||
|
|
||||||
import defaultConfig from '../../config/defaults';
|
import defaultConfig from '../../config/defaults';
|
||||||
import { getSongMenu } from '../../providers/dom-elements';
|
import { getSongMenu } from '../../providers/dom-elements';
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import { createPanel } from './menu/panel';
|
import { createPanel } from './menu/panel';
|
||||||
|
|
||||||
import logo from './assets/menu.svg';
|
import logoRaw from './assets/menu.svg?inline';
|
||||||
import close from './assets/close.svg';
|
import closeRaw from './assets/close.svg?inline';
|
||||||
import minimize from './assets/minimize.svg';
|
import minimizeRaw from './assets/minimize.svg?inline';
|
||||||
import maximize from './assets/maximize.svg';
|
import maximizeRaw from './assets/maximize.svg?inline';
|
||||||
import unmaximize from './assets/unmaximize.svg';
|
import unmaximizeRaw from './assets/unmaximize.svg?inline';
|
||||||
|
|
||||||
import type { Menu } from 'electron';
|
import type { Menu } from 'electron';
|
||||||
|
import * as electron from 'electron';
|
||||||
|
|
||||||
function $<E extends Element = Element>(selector: string) {
|
function $<E extends Element = Element>(selector: string) {
|
||||||
return document.querySelector<E>(selector);
|
return document.querySelector<E>(selector);
|
||||||
@ -23,6 +24,26 @@ export default async () => {
|
|||||||
let maximizeButton: HTMLButtonElement;
|
let maximizeButton: HTMLButtonElement;
|
||||||
if (isMacOS) titleBar.style.setProperty('--offset-left', '70px');
|
if (isMacOS) titleBar.style.setProperty('--offset-left', '70px');
|
||||||
|
|
||||||
|
const logo = document.createElement('img');
|
||||||
|
const close = document.createElement('img');
|
||||||
|
const minimize = document.createElement('img');
|
||||||
|
const maximize = document.createElement('img');
|
||||||
|
const unmaximize = document.createElement('img');
|
||||||
|
|
||||||
|
if (window.ELECTRON_RENDERER_URL) {
|
||||||
|
logo.src = window.ELECTRON_RENDERER_URL + '/' + logoRaw;
|
||||||
|
close.src = window.ELECTRON_RENDERER_URL + '/' + closeRaw;
|
||||||
|
minimize.src = window.ELECTRON_RENDERER_URL + '/' + minimizeRaw;
|
||||||
|
maximize.src = window.ELECTRON_RENDERER_URL + '/' + maximizeRaw;
|
||||||
|
unmaximize.src = window.ELECTRON_RENDERER_URL + '/' + unmaximizeRaw;
|
||||||
|
} else {
|
||||||
|
logo.src = logoRaw;
|
||||||
|
close.src = closeRaw;
|
||||||
|
minimize.src = minimizeRaw;
|
||||||
|
maximize.src = maximizeRaw;
|
||||||
|
unmaximize.src = unmaximizeRaw;
|
||||||
|
}
|
||||||
|
|
||||||
logo.classList.add('title-bar-icon');
|
logo.classList.add('title-bar-icon');
|
||||||
const logoClick = () => {
|
const logoClick = () => {
|
||||||
hideMenu = !hideMenu;
|
hideMenu = !hideMenu;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import forwardHTML from './templates/forward.html';
|
import forwardHTML from './templates/forward.html?raw';
|
||||||
import backHTML from './templates/back.html';
|
import backHTML from './templates/back.html?raw';
|
||||||
|
|
||||||
import { ElementFromHtml } from '../utils-renderer';
|
import { ElementFromHtml } from '../utils-renderer';
|
||||||
|
|
||||||
|
|||||||
@ -7,9 +7,10 @@ import config from './config';
|
|||||||
|
|
||||||
import { cache } from '../../providers/decorators';
|
import { cache } from '../../providers/decorators';
|
||||||
import { SongInfo } from '../../providers/song-info';
|
import { SongInfo } from '../../providers/song-info';
|
||||||
import { getAssetsDirectoryLocation } from '../utils';
|
|
||||||
|
|
||||||
const defaultIcon = path.join(getAssetsDirectoryLocation(), 'youtube-music.png');
|
import youtubeMusicIcon from '../../../assets/youtube-music.png?asset';
|
||||||
|
|
||||||
|
|
||||||
const userData = app.getPath('userData');
|
const userData = app.getPath('userData');
|
||||||
const temporaryIcon = path.join(userData, 'tempIcon.png');
|
const temporaryIcon = path.join(userData, 'tempIcon.png');
|
||||||
const temporaryBanner = path.join(userData, 'tempBanner.png');
|
const temporaryBanner = path.join(userData, 'tempBanner.png');
|
||||||
@ -45,7 +46,7 @@ const nativeImageToLogo = cache((nativeImage: NativeImage) => {
|
|||||||
|
|
||||||
export const notificationImage = (songInfo: SongInfo) => {
|
export const notificationImage = (songInfo: SongInfo) => {
|
||||||
if (!songInfo.image) {
|
if (!songInfo.image) {
|
||||||
return defaultIcon;
|
return youtubeMusicIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config.get('interactive')) {
|
if (!config.get('interactive')) {
|
||||||
@ -68,8 +69,9 @@ export const saveImage = cache((img: NativeImage, savePath: string) => {
|
|||||||
try {
|
try {
|
||||||
fs.writeFileSync(savePath, img.toPNG());
|
fs.writeFileSync(savePath, img.toPNG());
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
console.log(`Error writing song icon to disk:\n${String(error)}`);
|
console.error('Error writing song icon to disk:');
|
||||||
return defaultIcon;
|
console.trace(error);
|
||||||
|
return youtubeMusicIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
return savePath;
|
return savePath;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { toKeyEvent } from 'keyboardevent-from-electron-accelerator';
|
import { toKeyEvent } from 'keyboardevent-from-electron-accelerator';
|
||||||
import keyEventAreEqual from 'keyboardevents-areequal';
|
import keyEventAreEqual from 'keyboardevents-areequal';
|
||||||
|
|
||||||
import pipHTML from './templates/picture-in-picture.html';
|
import pipHTML from './templates/picture-in-picture.html?raw';
|
||||||
|
|
||||||
import { getSongMenu } from '../../providers/dom-elements';
|
import { getSongMenu } from '../../providers/dom-elements';
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import sliderHTML from './templates/slider.html';
|
import sliderHTML from './templates/slider.html?raw';
|
||||||
|
|
||||||
import { getSongMenu } from '../../providers/dom-elements';
|
import { getSongMenu } from '../../providers/dom-elements';
|
||||||
import { ElementFromHtml } from '../utils-renderer';
|
import { ElementFromHtml } from '../utils-renderer';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import qualitySettingsTemplate from './templates/qualitySettingsTemplate.html';
|
import qualitySettingsTemplate from './templates/qualitySettingsTemplate.html?raw';
|
||||||
|
|
||||||
import { ElementFromHtml } from '../utils-renderer';
|
import { ElementFromHtml } from '../utils-renderer';
|
||||||
import { YoutubePlayer } from '../../types/youtube-player';
|
import { YoutubePlayer } from '../../types/youtube-player';
|
||||||
|
|||||||
@ -4,10 +4,9 @@ import path from 'node:path';
|
|||||||
import { app } from 'electron';
|
import { app } from 'electron';
|
||||||
import is from 'electron-is';
|
import is from 'electron-is';
|
||||||
|
|
||||||
import { ValueOf } from '../utils/type-utils';
|
|
||||||
import defaultConfig from '../config/defaults';
|
import defaultConfig from '../config/defaults';
|
||||||
|
|
||||||
export const getAssetsDirectoryLocation = () => path.resolve(__dirname, 'assets');
|
export const getAssetsDirectoryLocation = () => path.resolve(__dirname, '..', 'assets');
|
||||||
|
|
||||||
export const getMediaIconLocation = () =>
|
export const getMediaIconLocation = () =>
|
||||||
app.isPackaged
|
app.isPackaged
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import buttonTemplate from './templates/button_template.html';
|
import buttonTemplate from './templates/button_template.html?raw';
|
||||||
|
|
||||||
import { ElementFromHtml } from '../utils-renderer';
|
import { ElementFromHtml } from '../utils-renderer';
|
||||||
|
|
||||||
|
|||||||
@ -48,3 +48,4 @@ contextBridge.exposeInMainWorld('ipcRenderer', {
|
|||||||
sendToHost: (channel: string, ...args: unknown[]) => ipcRenderer.sendToHost(channel, ...args),
|
sendToHost: (channel: string, ...args: unknown[]) => ipcRenderer.sendToHost(channel, ...args),
|
||||||
});
|
});
|
||||||
contextBridge.exposeInMainWorld('reload', () => ipcRenderer.send('reload'));
|
contextBridge.exposeInMainWorld('reload', () => ipcRenderer.send('reload'));
|
||||||
|
contextBridge.exposeInMainWorld('ELECTRON_RENDERER_URL', process.env.ELECTRON_RENDERER_URL);
|
||||||
|
|||||||
@ -1,12 +1,8 @@
|
|||||||
import path from 'node:path';
|
import youtubeMusicTrayIcon from '../../assets/youtube-music-tray.png?asset';
|
||||||
|
|
||||||
import { getAssetsDirectoryLocation } from '../plugins/utils';
|
|
||||||
|
|
||||||
const iconPath = path.join(getAssetsDirectoryLocation(), 'youtube-music-tray.png');
|
|
||||||
|
|
||||||
const promptOptions = {
|
const promptOptions = {
|
||||||
customStylesheet: 'dark',
|
customStylesheet: 'dark',
|
||||||
icon: iconPath,
|
icon: youtubeMusicTrayIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => promptOptions;
|
export default () => promptOptions;
|
||||||
|
|||||||
@ -145,7 +145,8 @@ function onApiLoaded() {
|
|||||||
try {
|
try {
|
||||||
await handler?.(options as never);
|
await handler?.(options as never);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in plugin "${pluginName}": ${String(error)}`);
|
console.error(`Error in plugin "${pluginName}"`);
|
||||||
|
console.trace(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
1
src/reset.d.ts
vendored
1
src/reset.d.ts
vendored
@ -21,6 +21,7 @@ declare global {
|
|||||||
ipcRenderer: typeof electronIpcRenderer;
|
ipcRenderer: typeof electronIpcRenderer;
|
||||||
mainConfig: typeof config;
|
mainConfig: typeof config;
|
||||||
electronIs: typeof is;
|
electronIs: typeof is;
|
||||||
|
ELECTRON_RENDERER_URL: string | undefined;
|
||||||
/**
|
/**
|
||||||
* YouTube Music internal variable (Last interaction time)
|
* YouTube Music internal variable (Last interaction time)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import path from 'node:path';
|
|
||||||
|
|
||||||
import { Menu, nativeImage, Tray } from 'electron';
|
import { Menu, nativeImage, Tray } from 'electron';
|
||||||
|
|
||||||
import { restart } from './providers/app-controls';
|
import { restart } from './providers/app-controls';
|
||||||
import config from './config';
|
import config from './config';
|
||||||
import getSongControls from './providers/song-controls';
|
import getSongControls from './providers/song-controls';
|
||||||
|
|
||||||
import { getAssetsDirectoryLocation } from './plugins/utils';
|
import youtubeMusicTrayIcon from '../assets/youtube-music-tray.png?asset';
|
||||||
|
|
||||||
import type { MenuTemplate } from './menu';
|
import type { MenuTemplate } from './menu';
|
||||||
|
|
||||||
@ -41,9 +39,8 @@ export const setUpTray = (app: Electron.App, win: Electron.BrowserWindow) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { playPause, next, previous } = getSongControls(win);
|
const { playPause, next, previous } = getSongControls(win);
|
||||||
const iconPath = path.join(getAssetsDirectoryLocation(), 'youtube-music-tray.png');
|
|
||||||
|
|
||||||
const trayIcon = nativeImage.createFromPath(iconPath).resize({
|
const trayIcon = nativeImage.createFromPath(youtubeMusicTrayIcon).resize({
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
});
|
});
|
||||||
|
|||||||
26
src/youtube-music.d.ts
vendored
26
src/youtube-music.d.ts
vendored
@ -1,12 +1,19 @@
|
|||||||
|
/// <reference types="electron-vite/node" />
|
||||||
|
|
||||||
declare module '*.html' {
|
declare module '*.html' {
|
||||||
const html: string;
|
const html: string;
|
||||||
|
|
||||||
export default html;
|
export default html;
|
||||||
}
|
}
|
||||||
declare module '*.svg' {
|
declare module '*.html?raw' {
|
||||||
const element: SVGAElement;
|
const html: string;
|
||||||
|
|
||||||
export default element;
|
export default html;
|
||||||
|
}
|
||||||
|
declare module '*.svg?inline' {
|
||||||
|
const base64: string;
|
||||||
|
|
||||||
|
export default base64;
|
||||||
}
|
}
|
||||||
declare module '*.png' {
|
declare module '*.png' {
|
||||||
const element: HTMLImageElement;
|
const element: HTMLImageElement;
|
||||||
@ -15,7 +22,6 @@ declare module '*.png' {
|
|||||||
}
|
}
|
||||||
declare module '*.jpg' {
|
declare module '*.jpg' {
|
||||||
const element: HTMLImageElement;
|
const element: HTMLImageElement;
|
||||||
|
|
||||||
export default element;
|
export default element;
|
||||||
}
|
}
|
||||||
declare module '*.css' {
|
declare module '*.css' {
|
||||||
@ -23,15 +29,3 @@ declare module '*.css' {
|
|||||||
|
|
||||||
export default css;
|
export default css;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'rollup-plugin-string' {
|
|
||||||
import type { Plugin } from 'rollup';
|
|
||||||
|
|
||||||
interface PluginOptions {
|
|
||||||
include?: string[] | string;
|
|
||||||
exclude?: string[] | string;
|
|
||||||
minifier?: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function string(options?: PluginOptions): Plugin;
|
|
||||||
}
|
|
||||||
@ -3,6 +3,7 @@
|
|||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"lib": ["dom", "dom.iterable", "es2022"],
|
"lib": ["dom", "dom.iterable", "es2022"],
|
||||||
"module": "CommonJS",
|
"module": "CommonJS",
|
||||||
|
"types": ["electron-vite/node"],
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user