Merge branch 'main' of github.com:SamidyFR/monochrome

This commit is contained in:
Samidy 2026-02-10 15:37:18 +03:00
commit 2d43e2d3cc
7 changed files with 82 additions and 61 deletions

View file

@ -50,7 +50,7 @@ jobs:
run: npx neu update
- name: Build application
run: npm run build
run: npm run build:desktop
- name: Prepare Release
run: |

BIN
.gitignore vendored

Binary file not shown.

View file

@ -4323,6 +4323,7 @@
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/pocketbase@0.21.3/dist/pocketbase.umd.js"></script>
<script src="/neutralino.js"></script>
<script type="module" src="/js/app.js"></script>
</body>
</html>

View file

@ -1,4 +1,5 @@
//js/app.js
console.log('[App] Script loaded');
import { LosslessAPI } from './api.js';
import {
apiSettings,
@ -25,7 +26,7 @@ import * as Neutralino from '@neutralinojs/lib';
import './smooth-scrolling.js';
// Assign Neutralino to window for global access
if (typeof window !== 'undefined') {
if (typeof window !== 'undefined' && window.NL_MODE) {
window.Neutralino = Neutralino;
}
@ -237,6 +238,31 @@ async function disablePwaForAuthGate() {
}
document.addEventListener('DOMContentLoaded', async () => {
// Initialize desktop environment (Neutralino)
const isDesktop = typeof window !== 'undefined' && (window.NL_MODE || window.location.port === '5050');
if (typeof window !== 'undefined' && window.Neutralino) {
console.log('[App] Neutralino object detected. Environment:', isDesktop ? 'Desktop' : 'Web');
if (isDesktop) {
console.log('[App] Initializing Neutralino desktop environment...');
try {
Neutralino.init();
console.log('[App] Neutralino.init() called successfully.');
// Register events immediately
Neutralino.events.on('windowClose', () => {
console.log('[App] Window close event triggered.');
Neutralino.app.exit();
});
} catch (error) {
console.error('[App] Failed to initialize desktop environment:', error);
}
} else {
console.log('[App] Skipping Neutralino.init() on regular web environment.');
}
} else {
console.log('[App] Neutralino object NOT detected.');
}
const api = new LosslessAPI(apiSettings);
const audioPlayer = document.getElementById('audio-player');
@ -385,22 +411,9 @@ document.addEventListener('DOMContentLoaded', async () => {
// Initialize tracker
initTracker(player);
// Initialize desktop environment (Neutralino)
if (window.Neutralino) {
console.log('Initializing Neutralino desktop environment (Lite Mode)...');
try {
Neutralino.init();
// Register events immediately
Neutralino.events.on('windowClose', () => {
Neutralino.app.exit();
});
// Start RPC immediately after init
initializeDiscordRPC(player);
} catch (error) {
console.error('Failed to initialize desktop environment:', error);
}
if (typeof window !== 'undefined' && window.Neutralino && (window.NL_MODE || window.location.port === '5050')) {
console.log('[App] Starting Discord RPC...');
initializeDiscordRPC(player);
}
const castBtn = document.getElementById('cast-btn');

View file

@ -42,6 +42,7 @@ export function initializeDiscordRPC(player) {
if (player.currentTrack) {
sendUpdate(player.currentTrack, player.audio.paused);
} else {
console.log('[DiscordRPC] Sending idling heartbeat...');
const idlingData = {
details: 'Idling',
state: 'Monochrome',

View file

@ -6,7 +6,8 @@
"main": "sw.js",
"scripts": {
"dev": "vite",
"build": "vite build && npx neu build",
"build": "vite build",
"build:desktop": "vite build --mode neutralino && npx neu build && node -e \"const fs = require('fs'); fs.cpSync('extensions', 'dist/Monochrome/extensions', {recursive: true}); fs.copyFileSync('neutralino.config.json', 'dist/Monochrome/neutralino.config.json')\"",
"preview": "vite preview",
"start": "vite preview",
"lint:js": "eslint .",

View file

@ -3,50 +3,55 @@ import { VitePWA } from 'vite-plugin-pwa';
import neutralino from 'vite-plugin-neutralino';
import authGatePlugin from './vite-plugin-auth-gate.js';
export default defineConfig({
base: './',
build: {
outDir: 'www',
emptyOutDir: true,
},
plugins: [
neutralino(),
authGatePlugin(),
VitePWA({
registerType: 'prompt',
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg,json}'],
cleanupOutdatedCaches: true,
maximumFileSizeToCacheInBytes: 3 * 1024 * 1024, // 3 MiB limit
// Define runtime caching strategies
runtimeCaching: [
{
urlPattern: ({ request }) => request.destination === 'image',
handler: 'CacheFirst',
options: {
cacheName: 'images',
expiration: {
maxEntries: 100,
maxAgeSeconds: 60 * 24 * 60 * 60, // 60 Days
export default defineConfig(({ mode }) => {
const IS_NEUTRALINO = mode === 'neutralino';
return {
base: './',
build: {
outDir: IS_NEUTRALINO ? 'www' : 'dist',
emptyOutDir: IS_NEUTRALINO,
},
plugins: [
IS_NEUTRALINO && neutralino(),
authGatePlugin(),
VitePWA({
registerType: 'prompt',
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg,json}'],
cleanupOutdatedCaches: true,
maximumFileSizeToCacheInBytes: 3 * 1024 * 1024, // 3 MiB limit
// Define runtime caching strategies
runtimeCaching: [
{
urlPattern: ({ request }) => request.destination === 'image',
handler: 'CacheFirst',
options: {
cacheName: 'images',
expiration: {
maxEntries: 100,
maxAgeSeconds: 60 * 24 * 60 * 60, // 60 Days
},
},
},
},
{
urlPattern: ({ request }) => request.destination === 'audio' || request.destination === 'video',
handler: 'CacheFirst',
options: {
cacheName: 'media',
expiration: {
maxEntries: 50,
maxAgeSeconds: 60 * 24 * 60 * 60, // 60 Days
{
urlPattern: ({ request }) =>
request.destination === 'audio' || request.destination === 'video',
handler: 'CacheFirst',
options: {
cacheName: 'media',
expiration: {
maxEntries: 50,
maxAgeSeconds: 60 * 24 * 60 * 60, // 60 Days
},
rangeRequests: true, // Support scrubbing
},
rangeRequests: true, // Support scrubbing
},
},
],
},
includeAssets: ['instances.json', 'discord.html'],
manifest: false, // Use existing public/manifest.json
}),
],
],
},
includeAssets: ['instances.json', 'discord.html'],
manifest: false, // Use existing public/manifest.json
}),
],
};
});