refactor(desktop): separate js for neutralino from the js used on the website
This commit is contained in:
parent
0213132606
commit
cafa97cb0f
6 changed files with 79 additions and 78 deletions
|
|
@ -4561,7 +4561,6 @@
|
|||
</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>
|
||||
|
|
|
|||
68
js/app.js
68
js/app.js
|
|
@ -21,15 +21,8 @@ import { sidePanelManager } from './side-panel.js';
|
|||
import { db } from './db.js';
|
||||
import { syncManager } from './accounts/pocketbase.js';
|
||||
import { registerSW } from 'virtual:pwa-register';
|
||||
import { initializeDiscordRPC } from './discord-rpc.js';
|
||||
import * as Neutralino from '@neutralinojs/lib';
|
||||
import './smooth-scrolling.js';
|
||||
|
||||
// Assign Neutralino to window for global access
|
||||
if (typeof window !== 'undefined' && window.NL_MODE) {
|
||||
window.Neutralino = Neutralino;
|
||||
}
|
||||
|
||||
import { initTracker } from './tracker.js';
|
||||
|
||||
// Lazy-loaded modules
|
||||
|
|
@ -238,46 +231,7 @@ async function disablePwaForAuthGate() {
|
|||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
// Initialize desktop environment (Neutralino)
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const hasNLParams = urlParams.has('NL_PORT') || urlParams.has('NL_TOKEN');
|
||||
const isDesktop =
|
||||
typeof window !== 'undefined' && (window.NL_MODE || window.location.port === '5050' || hasNLParams);
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
const nlGlobals = Object.keys(window).filter((k) => k.startsWith('NL_'));
|
||||
console.log('[App] Environment Check:', {
|
||||
isDesktop,
|
||||
port: window.location.port,
|
||||
hasNLParams,
|
||||
nlGlobals,
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined' && window.Neutralino) {
|
||||
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 MusicAPI(apiSettings);
|
||||
|
||||
const audioPlayer = document.getElementById('audio-player');
|
||||
|
||||
// i love ios and macos!!!! webkit fucking SUCKS BULLSHIT sorry ios/macos heads yall getting lossless only
|
||||
|
|
@ -308,6 +262,17 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
const currentQuality = localStorage.getItem('playback-quality') || 'HI_RES_LOSSLESS';
|
||||
const player = new Player(audioPlayer, api, currentQuality);
|
||||
|
||||
// Initialize tracker
|
||||
initTracker(player);
|
||||
|
||||
// Initialize desktop features if in Neutralino mode
|
||||
if (typeof window !== 'undefined' && (window.NL_MODE || window.location.search.includes('mode=neutralino'))) {
|
||||
import('./desktop/desktop.js').then((m) => m.initDesktop(player));
|
||||
}
|
||||
|
||||
const castBtn = document.getElementById('cast-btn');
|
||||
initializeCasting(audioPlayer, castBtn);
|
||||
|
||||
const ui = new UIRenderer(api, player);
|
||||
const scrobbler = new MultiScrobbler();
|
||||
const lyricsManager = new LyricsManager(api);
|
||||
|
|
@ -421,17 +386,6 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
initializeUIInteractions(player, api, ui);
|
||||
initializeKeyboardShortcuts(player, audioPlayer);
|
||||
|
||||
// Initialize tracker
|
||||
initTracker(player);
|
||||
|
||||
if (typeof window !== 'undefined' && window.Neutralino && isDesktop) {
|
||||
console.log('[App] Starting Discord RPC...');
|
||||
initializeDiscordRPC(player);
|
||||
}
|
||||
|
||||
const castBtn = document.getElementById('cast-btn');
|
||||
initializeCasting(audioPlayer, castBtn);
|
||||
|
||||
// Restore UI state for the current track (like button, theme)
|
||||
if (player.currentTrack) {
|
||||
ui.setCurrentTrack(player.currentTrack);
|
||||
|
|
|
|||
22
js/desktop/desktop.js
Normal file
22
js/desktop/desktop.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// js/desktop/desktop.js
|
||||
import Neutralino from './neutralino-bridge.js';
|
||||
import { initializeDiscordRPC } from './discord-rpc.js';
|
||||
|
||||
export async function initDesktop(player) {
|
||||
console.log('[Desktop] Initializing desktop features...');
|
||||
|
||||
// Assign to window for modules that use global Neutralino (like Player.js)
|
||||
window.Neutralino = Neutralino;
|
||||
|
||||
try {
|
||||
await Neutralino.init();
|
||||
console.log('[Desktop] Neutralino initialized.');
|
||||
|
||||
if (player) {
|
||||
console.log('[Desktop] Starting Discord RPC...');
|
||||
initializeDiscordRPC(player);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Desktop] Failed to initialize desktop environment:', error);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import { getTrackTitle, getTrackArtists } from './utils.js';
|
||||
// js/desktop/discord-rpc.js
|
||||
import { getTrackTitle, getTrackArtists } from '../utils.js';
|
||||
|
||||
export function initializeDiscordRPC(player) {
|
||||
const EXTENSION_ID = 'js.neutralino.discordrpc';
|
||||
|
|
@ -1,69 +1,94 @@
|
|||
// js/neutralino-bridge.js
|
||||
// js/desktop/neutralino-bridge.js
|
||||
|
||||
const isNeutralino = typeof window !== 'undefined' && (
|
||||
window.NL_MODE ||
|
||||
window.location.search.includes('mode=neutralino') ||
|
||||
(window.parent !== window)
|
||||
);
|
||||
|
||||
const listeners = new Map();
|
||||
|
||||
// Listen for events from the Shell (Parent)
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data?.type === 'NL_EVENT') {
|
||||
const { eventName, detail } = event.data;
|
||||
if (listeners.has(eventName)) {
|
||||
listeners.get(eventName).forEach((handler) => {
|
||||
try {
|
||||
handler(detail);
|
||||
} catch (e) {
|
||||
console.error('[Bridge] Error in event handler:', e);
|
||||
}
|
||||
});
|
||||
if (isNeutralino) {
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data?.type === 'NL_EVENT') {
|
||||
const { eventName, detail } = event.data;
|
||||
if (listeners.has(eventName)) {
|
||||
listeners.get(eventName).forEach((handler) => {
|
||||
try {
|
||||
handler(detail);
|
||||
} catch (e) {
|
||||
console.error('[Bridge] Error in event handler:', e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const init = async () => {
|
||||
if (!isNeutralino) return;
|
||||
// Notify Shell we are ready
|
||||
window.parent.postMessage({ type: 'NL_INIT' }, '*');
|
||||
};
|
||||
|
||||
export const events = {
|
||||
on: (eventName, handler) => {
|
||||
if (!isNeutralino) return;
|
||||
if (!listeners.has(eventName)) {
|
||||
listeners.set(eventName, []);
|
||||
}
|
||||
listeners.get(eventName).push(handler);
|
||||
},
|
||||
off: (eventName, handler) => {
|
||||
if (!isNeutralino) return;
|
||||
if (!listeners.has(eventName)) return;
|
||||
const handlers = listeners.get(eventName);
|
||||
const index = handlers.indexOf(handler);
|
||||
if (index > -1) handlers.splice(index, 1);
|
||||
},
|
||||
broadcast: async (eventName, data) => {
|
||||
if (!isNeutralino) return;
|
||||
window.parent.postMessage({ type: 'NL_BROADCAST', eventName, data }, '*');
|
||||
},
|
||||
};
|
||||
|
||||
export const extensions = {
|
||||
dispatch: async (extensionId, eventName, data) => {
|
||||
if (!isNeutralino) return;
|
||||
window.parent.postMessage({ type: 'NL_EXTENSION', extensionId, eventName, data }, '*');
|
||||
},
|
||||
};
|
||||
|
||||
export const app = {
|
||||
exit: async () => {
|
||||
if (!isNeutralino) return;
|
||||
window.parent.postMessage({ type: 'NL_APP_EXIT' }, '*');
|
||||
},
|
||||
};
|
||||
|
||||
const _window = {
|
||||
export const _window = {
|
||||
minimize: async () => {
|
||||
if (!isNeutralino) return;
|
||||
window.parent.postMessage({ type: 'NL_WINDOW_MIN' }, '*');
|
||||
},
|
||||
maximize: async () => {
|
||||
if (!isNeutralino) return;
|
||||
window.parent.postMessage({ type: 'NL_WINDOW_MAX' }, '*');
|
||||
},
|
||||
show: async () => {
|
||||
if (!isNeutralino) return;
|
||||
window.parent.postMessage({ type: 'NL_WINDOW_SHOW' }, '*');
|
||||
},
|
||||
hide: async () => {
|
||||
if (!isNeutralino) return;
|
||||
window.parent.postMessage({ type: 'NL_WINDOW_HIDE' }, '*');
|
||||
},
|
||||
isVisible: async () => {
|
||||
return true; // Mock response
|
||||
},
|
||||
setTitle: async (title) => {
|
||||
if (!isNeutralino) return;
|
||||
window.parent.postMessage({ type: 'NL_WINDOW_SET_TITLE', title }, '*');
|
||||
},
|
||||
};
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"applicationId": "com.monochrome.app",
|
||||
"applicationName": "Monochrome",
|
||||
"applicationIcon": "public/assets/512.png",
|
||||
"applicationIcon": "public/assets/appicon.png",
|
||||
"author": "Monochrome",
|
||||
"description": "Lossless music streaming",
|
||||
"description": "Monochrome - Lossless music streaming",
|
||||
"version": "1.0.0",
|
||||
"defaultMode": "window",
|
||||
"documentRoot": "dist/",
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
"modes": {
|
||||
"window": {
|
||||
"title": "Monochrome",
|
||||
"icon": "public/assets/512.png",
|
||||
"icon": "public/assets/appicon.png",
|
||||
"width": 1280,
|
||||
"height": 800,
|
||||
"minWidth": 800,
|
||||
|
|
@ -44,5 +44,5 @@
|
|||
"commandWindows": "powershell.exe -ExecutionPolicy Bypass -File \"${NL_PATH}/extensions/js.neutralino.discordrpc/bridge.ps1\""
|
||||
}
|
||||
],
|
||||
"nativeAllowList": ["app.exit", "window.*", "extensions.*", "events.*"]
|
||||
"nativeAllowList": ["app.exit", "window.*", "extensions.*", "events.*", "os.*"]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue