mirror of
https://github.com/got-feedBack/feedBack-desktop.git
synced 2026-08-16 13:43:16 +00:00
fix(preload): expose desktop bridge as window.feedBackDesktop (#40)
* fix(preload): expose desktop bridge as window.feedBackDesktop The core feedback app reads window.feedBackDesktop, but the desktop preload exposed the bridge as window.slopsmithDesktop. On the desktop build window.feedBackDesktop was therefore undefined: the DLC-folder Browse button stayed hidden in both the first-run wizard (#v3-ob-songdir-browse) and Settings (#btn-pick-dlc), and the rest of the bridge silently fell back to browser mode. Finish the rebrand: rename the exposed global slopsmithDesktop -> feedBackDesktop, plus the internal api object, the renderer + plugin-manager consumers, the private __feedBackDesktopAudioHooks scratch namespace, and the comments/migration doc. No compatibility alias — the ecosystem moves to the new name (TARGET-CURRENT). Plugins that still read window.slopsmithDesktop are renamed in their own PRs; nothing ships until the next desktop build bundles them together, so there is no broken shipped artifact. Fixes the "Select DLC Songs Folder — No Browse" report (wizard + Settings, Mac + Windows). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QbexxfTt8q2tAn436MqGWF * fix(preload): also expose bridge under legacy slopsmithDesktop name Keep plugins/community code built against the pre-rename bridge working after the rename. Same isMainFrame gating. See got-feedback/feedBack-desktop#41. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: ChrisBeWithYou <chris@rifflarr.local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: byrongamatos <xasiklas@gmail.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
ChrisBeWithYou
byrongamatos
parent
5188aab938
commit
59e1c1cb0e
@@ -66,7 +66,7 @@ under both the old filename key and the new `settings-v1-...` key after the
|
|||||||
Core `audio-effects` owns provider selection, policy, safe diagnostics, and the
|
Core `audio-effects` owns provider selection, policy, safe diagnostics, and the
|
||||||
`slopsmith.audio_effects.chain_plan.v1` schema. Desktop owns the trusted physical
|
`slopsmith.audio_effects.chain_plan.v1` schema. Desktop owns the trusted physical
|
||||||
executor. Renderer plugins may pass a core-resolved chain plan plus a private
|
executor. Renderer plugins may pass a core-resolved chain plan plus a private
|
||||||
trusted asset map to `window.slopsmithDesktop.audioEffects.loadChainPlan(...)`;
|
trusted asset map to `window.feedBackDesktop.audioEffects.loadChainPlan(...)`;
|
||||||
desktop validates the schema, authorization, stage kinds, stage counts, opaque
|
desktop validates the schema, authorization, stage kinds, stage counts, opaque
|
||||||
asset references, local asset paths, and extension/kind compatibility before it
|
asset references, local asset paths, and extension/kind compatibility before it
|
||||||
builds the native preset JSON and calls the existing native `loadPreset` path.
|
builds the native preset JSON and calls the existing native `loadPreset` path.
|
||||||
@@ -100,7 +100,7 @@ When migrating more desktop integrations to capabilities:
|
|||||||
- Use `target.settingsKey` for local per-song plugin settings.
|
- Use `target.settingsKey` for local per-song plugin settings.
|
||||||
- Use `targetId` only for arrangement/session correlation, not persistent
|
- Use `targetId` only for arrangement/session correlation, not persistent
|
||||||
per-song settings.
|
per-song settings.
|
||||||
- Route effect-chain execution through `window.slopsmithDesktop.audioEffects`
|
- Route effect-chain execution through `window.feedBackDesktop.audioEffects`
|
||||||
rather than passing raw native preset JSON through plugin-visible capability
|
rather than passing raw native preset JSON through plugin-visible capability
|
||||||
state.
|
state.
|
||||||
- Keep raw filename fallback code behind a capability-version check.
|
- Keep raw filename fallback code behind a capability-version check.
|
||||||
|
|||||||
+2
-2
@@ -372,7 +372,7 @@ const rendererWebPreferences: Electron.WebPreferences = {
|
|||||||
// a remote iframe can't ride the privileged preload, but the tutorials plugin
|
// a remote iframe can't ride the privileged preload, but the tutorials plugin
|
||||||
// legitimately embeds YouTube. This is safe only because preload.ts now gates
|
// legitimately embeds YouTube. This is safe only because preload.ts now gates
|
||||||
// its IPC bridge to the main frame — an allow-listed embed frame loads with no
|
// its IPC bridge to the main frame — an allow-listed embed frame loads with no
|
||||||
// slopsmithDesktop surface. Host-suffix match (exact host or `.`-prefixed
|
// feedBackDesktop surface. Host-suffix match (exact host or `.`-prefixed
|
||||||
// sub-domain) so `evil-youtube.com` / `youtube.com.evil.com` don't slip past.
|
// sub-domain) so `evil-youtube.com` / `youtube.com.evil.com` don't slip past.
|
||||||
const EMBED_ALLOWED_HOSTS = ['youtube.com', 'youtube-nocookie.com'];
|
const EMBED_ALLOWED_HOSTS = ['youtube.com', 'youtube-nocookie.com'];
|
||||||
function isAllowedEmbedUrl(url: string): boolean {
|
function isAllowedEmbedUrl(url: string): boolean {
|
||||||
@@ -1094,7 +1094,7 @@ async function startup(): Promise<void> {
|
|||||||
ipcMain.handle(IPC_UPDATE_APPLY, () => updateManager.applyAndRestart());
|
ipcMain.handle(IPC_UPDATE_APPLY, () => updateManager.applyAndRestart());
|
||||||
|
|
||||||
// Keep the display awake while a song plays (got-feedback/feedback#686). The
|
// Keep the display awake while a song plays (got-feedback/feedback#686). The
|
||||||
// renderer toggles this via window.slopsmithDesktop.power.setScreenAwake on
|
// renderer toggles this via window.feedBackDesktop.power.setScreenAwake on
|
||||||
// play/pause; the single OS blocker is refcounted across renderers below.
|
// play/pause; the single OS blocker is refcounted across renderers below.
|
||||||
ipcMain.handle(IPC_POWER_SET_SCREEN_AWAKE, (event, keep: unknown) => {
|
ipcMain.handle(IPC_POWER_SET_SCREEN_AWAKE, (event, keep: unknown) => {
|
||||||
setRendererScreenAwake(event.sender, keep === true);
|
setRendererScreenAwake(event.sender, keep === true);
|
||||||
|
|||||||
+9
-3
@@ -1,6 +1,6 @@
|
|||||||
// Preload script — exposes safe APIs to the Slopsmith webview.
|
// Preload script — exposes safe APIs to the Slopsmith webview.
|
||||||
// The existing Slopsmith frontend runs unchanged; this adds
|
// The existing Slopsmith frontend runs unchanged; this adds
|
||||||
// window.slopsmithDesktop for audio engine and desktop features.
|
// window.feedBackDesktop for audio engine and desktop features.
|
||||||
|
|
||||||
const { contextBridge, ipcRenderer } = require('electron');
|
const { contextBridge, ipcRenderer } = require('electron');
|
||||||
import type { StartupStatus } from './python';
|
import type { StartupStatus } from './python';
|
||||||
@@ -190,7 +190,7 @@ const isMainFrame = (() => {
|
|||||||
try { return w === w.top; } catch { return false; }
|
try { return w === w.top; } catch { return false; }
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const slopsmithDesktopApi = {
|
const feedBackDesktopApi = {
|
||||||
// Platform detection
|
// Platform detection
|
||||||
isDesktop: true,
|
isDesktop: true,
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
@@ -533,7 +533,13 @@ const slopsmithDesktopApi = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (isMainFrame) {
|
if (isMainFrame) {
|
||||||
contextBridge.exposeInMainWorld('slopsmithDesktop', slopsmithDesktopApi);
|
contextBridge.exposeInMainWorld('feedBackDesktop', feedBackDesktopApi);
|
||||||
|
// Legacy alias — plugins and external/community code built against the
|
||||||
|
// pre-rename bridge still read window.slopsmithDesktop. Expose the same
|
||||||
|
// object under the old name so they keep working after the rename
|
||||||
|
// (got-feedback/feedBack-desktop#40). Same isMainFrame gating, so an
|
||||||
|
// allow-listed embed frame still gets no desktop surface under either name.
|
||||||
|
contextBridge.exposeInMainWorld('slopsmithDesktop', feedBackDesktopApi);
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const plugins = window.slopsmithDesktop?.plugins;
|
const plugins = window.feedBackDesktop?.plugins;
|
||||||
if (!plugins) {
|
if (!plugins) {
|
||||||
const panel = document.getElementById('plugin-manager-panel');
|
const panel = document.getElementById('plugin-manager-panel');
|
||||||
if (panel) panel.innerHTML = '<div class="p-8 text-center text-slate-400">Plugin manager is only available in the Slopsmith Desktop app.</div>';
|
if (panel) panel.innerHTML = '<div class="p-8 text-center text-slate-400">Plugin manager is only available in the Slopsmith Desktop app.</div>';
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
refreshBtn.addEventListener('click', refreshList);
|
refreshBtn.addEventListener('click', refreshList);
|
||||||
|
|
||||||
// ── LAN access toggle ───────────────────────────────────────────────
|
// ── LAN access toggle ───────────────────────────────────────────────
|
||||||
const network = window.slopsmithDesktop?.network;
|
const network = window.feedBackDesktop?.network;
|
||||||
const lanToggle = $('pm-lan-toggle');
|
const lanToggle = $('pm-lan-toggle');
|
||||||
const lanStatus = $('pm-lan-status');
|
const lanStatus = $('pm-lan-status');
|
||||||
|
|
||||||
|
|||||||
+27
-27
@@ -1,13 +1,13 @@
|
|||||||
// Slopsmith Audio Engine Plugin — Frontend
|
// Slopsmith Audio Engine Plugin — Frontend
|
||||||
// Communicates with the JUCE audio engine via window.slopsmithDesktop.audio
|
// Communicates with the JUCE audio engine via window.feedBackDesktop.audio
|
||||||
// Desktop audio engine plugin
|
// Desktop audio engine plugin
|
||||||
|
|
||||||
window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
window.__feedBackDesktopAudioHooks = window.__feedBackDesktopAudioHooks || {};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const api = window.slopsmithDesktop?.audio;
|
const api = window.feedBackDesktop?.audio;
|
||||||
if (!api) {
|
if (!api) {
|
||||||
console.error('[audio-engine] Desktop audio API not available — running in browser mode');
|
console.error('[audio-engine] Desktop audio API not available — running in browser mode');
|
||||||
const panel = document.getElementById('audio-engine-panel');
|
const panel = document.getElementById('audio-engine-panel');
|
||||||
@@ -21,7 +21,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
// clear here — letting the prior interval keep running preserves mid-song
|
// clear here — letting the prior interval keep running preserves mid-song
|
||||||
// tone polling, since its closure refs (toneSwitcher, autoSwitchEnabled)
|
// tone polling, since its closure refs (toneSwitcher, autoSwitchEnabled)
|
||||||
// are still valid until the next playSong rotates to the new closure.
|
// are still valid until the next playSong rotates to the new closure.
|
||||||
const hookState = window.__slopsmithDesktopAudioHooks;
|
const hookState = window.__feedBackDesktopAudioHooks;
|
||||||
|
|
||||||
// ── State ─────────────────────────────────────────────────────────────────
|
// ── State ─────────────────────────────────────────────────────────────────
|
||||||
let audioRunning = false;
|
let audioRunning = false;
|
||||||
@@ -364,7 +364,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
audioSession.recordBridgeHit({
|
audioSession.recordBridgeHit({
|
||||||
domain: 'audio-input',
|
domain: 'audio-input',
|
||||||
bridgeId: 'audio-input.legacy-source',
|
bridgeId: 'audio-input.legacy-source',
|
||||||
legacySurface: 'window.slopsmithDesktop.audio',
|
legacySurface: 'window.feedBackDesktop.audio',
|
||||||
participantId: 'audio_engine',
|
participantId: 'audio_engine',
|
||||||
logicalSourceKey: currentAudioDeviceSnapshot().inputDevice ? 'desktop-audio:selected-input' : '',
|
logicalSourceKey: currentAudioDeviceSnapshot().inputDevice ? 'desktop-audio:selected-input' : '',
|
||||||
outcome: 'handled',
|
outcome: 'handled',
|
||||||
@@ -709,7 +709,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
}
|
}
|
||||||
|
|
||||||
function aeApplyNoiseGateToEngine() {
|
function aeApplyNoiseGateToEngine() {
|
||||||
const bridge = window.slopsmithDesktop?.audio;
|
const bridge = window.feedBackDesktop?.audio;
|
||||||
if (!bridge || typeof bridge.setNoiseGate !== 'function') {
|
if (!bridge || typeof bridge.setNoiseGate !== 'function') {
|
||||||
if (bridge && !window._aeNoiseGateBridgeWarned) {
|
if (bridge && !window._aeNoiseGateBridgeWarned) {
|
||||||
window._aeNoiseGateBridgeWarned = true;
|
window._aeNoiseGateBridgeWarned = true;
|
||||||
@@ -762,7 +762,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
}
|
}
|
||||||
|
|
||||||
function aeApplyTonePolishToEngine() {
|
function aeApplyTonePolishToEngine() {
|
||||||
const bridge = window.slopsmithDesktop?.audio;
|
const bridge = window.feedBackDesktop?.audio;
|
||||||
if (!bridge || typeof bridge.setTonePolish !== 'function') {
|
if (!bridge || typeof bridge.setTonePolish !== 'function') {
|
||||||
if (bridge && !window._aeTonePolishBridgeWarned) {
|
if (bridge && !window._aeTonePolishBridgeWarned) {
|
||||||
window._aeTonePolishBridgeWarned = true;
|
window._aeTonePolishBridgeWarned = true;
|
||||||
@@ -1351,7 +1351,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
|
|
||||||
// Add NAM model
|
// Add NAM model
|
||||||
addNamBtn.addEventListener('click', async () => {
|
addNamBtn.addEventListener('click', async () => {
|
||||||
const filePath = await window.slopsmithDesktop.pickFile([
|
const filePath = await window.feedBackDesktop.pickFile([
|
||||||
{ name: 'NAM Models', extensions: ['nam'] }
|
{ name: 'NAM Models', extensions: ['nam'] }
|
||||||
]);
|
]);
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
@@ -1363,7 +1363,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
// Add IR
|
// Add IR
|
||||||
addIrBtn.addEventListener('click', async () => {
|
addIrBtn.addEventListener('click', async () => {
|
||||||
console.error('[audio-engine] IR button clicked, opening picker...');
|
console.error('[audio-engine] IR button clicked, opening picker...');
|
||||||
const filePath = await window.slopsmithDesktop.pickFile([
|
const filePath = await window.feedBackDesktop.pickFile([
|
||||||
{ name: 'Impulse Responses', extensions: ['wav', 'aif', 'ir'] },
|
{ name: 'Impulse Responses', extensions: ['wav', 'aif', 'ir'] },
|
||||||
{ name: 'All Files', extensions: ['*'] }
|
{ name: 'All Files', extensions: ['*'] }
|
||||||
]);
|
]);
|
||||||
@@ -1478,7 +1478,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
|
|
||||||
// ── Updater (Velopack) settings UI ────────────────────────────────────────
|
// ── Updater (Velopack) settings UI ────────────────────────────────────────
|
||||||
// Reads/writes the persisted channel in localStorage and talks to the main
|
// Reads/writes the persisted channel in localStorage and talks to the main
|
||||||
// process via window.slopsmithDesktop.update (added by the main-process slice).
|
// process via window.feedBackDesktop.update (added by the main-process slice).
|
||||||
// Designed to degrade gracefully when the updater IPC namespace is missing
|
// Designed to degrade gracefully when the updater IPC namespace is missing
|
||||||
// (dev builds before the main slice lands) or when running on Linux.
|
// (dev builds before the main slice lands) or when running on Linux.
|
||||||
function setupUpdateChannelControls() {
|
function setupUpdateChannelControls() {
|
||||||
@@ -1493,8 +1493,8 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
const storedChannel = VALID_CHANNELS.includes(storedChannelRaw) ? storedChannelRaw : 'stable';
|
const storedChannel = VALID_CHANNELS.includes(storedChannelRaw) ? storedChannelRaw : 'stable';
|
||||||
channelSelect.value = storedChannel;
|
channelSelect.value = storedChannel;
|
||||||
|
|
||||||
const updateApi = window.slopsmithDesktop?.update;
|
const updateApi = window.feedBackDesktop?.update;
|
||||||
const isLinux = window.slopsmithDesktop?.platform === 'linux';
|
const isLinux = window.feedBackDesktop?.platform === 'linux';
|
||||||
|
|
||||||
function showLinuxFallback(message) {
|
function showLinuxFallback(message) {
|
||||||
if (linuxNote) linuxNote.classList.remove('hidden');
|
if (linuxNote) linuxNote.classList.remove('hidden');
|
||||||
@@ -1647,13 +1647,13 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
|
|
||||||
// ── Reset / repair configuration (Maintenance) ────────────────────────────
|
// ── Reset / repair configuration (Maintenance) ────────────────────────────
|
||||||
// Replaces the old "delete the config folder before upgrading" instruction.
|
// Replaces the old "delete the config folder before upgrading" instruction.
|
||||||
// Talks to the main process via window.slopsmithDesktop.maintenance, which
|
// Talks to the main process via window.feedBackDesktop.maintenance, which
|
||||||
// enumerates the correct per-OS paths and performs the delete. Binds fresh on
|
// enumerates the correct per-OS paths and performs the delete. Binds fresh on
|
||||||
// each settings render (the panel is injected via innerHTML, recreating the
|
// each settings render (the panel is injected via innerHTML, recreating the
|
||||||
// DOM), mirroring setupAudioQualityControls. Degrades gracefully when the
|
// DOM), mirroring setupAudioQualityControls. Degrades gracefully when the
|
||||||
// maintenance IPC namespace is absent (browser / older build).
|
// maintenance IPC namespace is absent (browser / older build).
|
||||||
function setupMaintenanceControls() {
|
function setupMaintenanceControls() {
|
||||||
const api = window.slopsmithDesktop?.maintenance;
|
const api = window.feedBackDesktop?.maintenance;
|
||||||
const section = document.getElementById('maint-section');
|
const section = document.getElementById('maint-section');
|
||||||
if (!section) return;
|
if (!section) return;
|
||||||
|
|
||||||
@@ -1751,7 +1751,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
|
|
||||||
// ── Audio Quality (soundfont) ─────────────────────────────────────────────
|
// ── Audio Quality (soundfont) ─────────────────────────────────────────────
|
||||||
function setupAudioQualityControls() {
|
function setupAudioQualityControls() {
|
||||||
const api = window.slopsmithDesktop?.soundfont;
|
const api = window.feedBackDesktop?.soundfont;
|
||||||
const defaultRadio = document.getElementById('ae-sf-default');
|
const defaultRadio = document.getElementById('ae-sf-default');
|
||||||
const highRadio = document.getElementById('ae-sf-high');
|
const highRadio = document.getElementById('ae-sf-high');
|
||||||
const highStatus = document.getElementById('ae-sf-high-status');
|
const highStatus = document.getElementById('ae-sf-high-status');
|
||||||
@@ -1863,7 +1863,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
if (saved) inputEl.value = saved;
|
if (saved) inputEl.value = saved;
|
||||||
|
|
||||||
btnEl.addEventListener('click', async () => {
|
btnEl.addEventListener('click', async () => {
|
||||||
const dir = await window.slopsmithDesktop.pickDirectory();
|
const dir = await window.feedBackDesktop.pickDirectory();
|
||||||
if (dir) {
|
if (dir) {
|
||||||
inputEl.value = dir;
|
inputEl.value = dir;
|
||||||
localStorage.setItem('slopsmith-' + key, dir);
|
localStorage.setItem('slopsmith-' + key, dir);
|
||||||
@@ -3406,7 +3406,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
});
|
});
|
||||||
// Apply MIDI mode immediately
|
// Apply MIDI mode immediately
|
||||||
window._toneMappingsDirty = true;
|
window._toneMappingsDirty = true;
|
||||||
const _liveApi = window.slopsmithDesktop?.audio;
|
const _liveApi = window.feedBackDesktop?.audio;
|
||||||
const _midiMappings = mappingsObj;
|
const _midiMappings = mappingsObj;
|
||||||
const _midiVstSlot = vstSelect ? parseInt(vstSelect.value) : -1;
|
const _midiVstSlot = vstSelect ? parseInt(vstSelect.value) : -1;
|
||||||
const _midiCh = chInput ? parseInt(chInput.value) : 1;
|
const _midiCh = chInput ? parseInt(chInput.value) : 1;
|
||||||
@@ -3445,7 +3445,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
const vstSelect = root.querySelector('#ae-midi-vst');
|
const vstSelect = root.querySelector('#ae-midi-vst');
|
||||||
const hint = root.querySelector('#ae-midi-vst-hint');
|
const hint = root.querySelector('#ae-midi-vst-hint');
|
||||||
if (!vstSelect) return;
|
if (!vstSelect) return;
|
||||||
const apiLocal = window.slopsmithDesktop?.audio;
|
const apiLocal = window.feedBackDesktop?.audio;
|
||||||
if (!apiLocal || typeof apiLocal.getChainState !== 'function') {
|
if (!apiLocal || typeof apiLocal.getChainState !== 'function') {
|
||||||
vstSelect.innerHTML = '<option value="">(no audio bridge)</option>';
|
vstSelect.innerHTML = '<option value="">(no audio bridge)</option>';
|
||||||
return;
|
return;
|
||||||
@@ -3900,7 +3900,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
(function() {
|
(function() {
|
||||||
// Hook registry shared across re-evaluations; see the IIFE 1 comment for
|
// Hook registry shared across re-evaluations; see the IIFE 1 comment for
|
||||||
// why we don't preemptively clear toneAutoMonitor here.
|
// why we don't preemptively clear toneAutoMonitor here.
|
||||||
const hookState = window.__slopsmithDesktopAudioHooks;
|
const hookState = window.__feedBackDesktopAudioHooks;
|
||||||
let _lastTone = null;
|
let _lastTone = null;
|
||||||
// Throttle the "_toneSwitcher not ready" warning — the tone monitor polls
|
// Throttle the "_toneSwitcher not ready" warning — the tone monitor polls
|
||||||
// at 50ms, so without this it would log every tick while the switcher is
|
// at 50ms, so without this it would log every tick while the switcher is
|
||||||
@@ -3940,7 +3940,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
// mute would silence the dry guitar. Suppress the mute for the rebuild
|
// mute would silence the dry guitar. Suppress the mute for the rebuild
|
||||||
// window so the guitar keeps sounding; resolve it once the chain settles.
|
// window so the guitar keeps sounding; resolve it once the chain settles.
|
||||||
function aeSetMonitorMuteSuppressed(suppressed) {
|
function aeSetMonitorMuteSuppressed(suppressed) {
|
||||||
const api = window.slopsmithDesktop?.audio;
|
const api = window.feedBackDesktop?.audio;
|
||||||
// Optional-chained: a downlevel native addon simply ignores this.
|
// Optional-chained: a downlevel native addon simply ignores this.
|
||||||
// setMonitorMuteSuppressed is async (ipcRenderer.invoke) — the sync
|
// setMonitorMuteSuppressed is async (ipcRenderer.invoke) — the sync
|
||||||
// try/catch only covers a missing method, so also swallow the
|
// try/catch only covers a missing method, so also swallow the
|
||||||
@@ -4003,7 +4003,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
// monitor-mute behaviour; if not, keep the dry guitar audible (leave the
|
// monitor-mute behaviour; if not, keep the dry guitar audible (leave the
|
||||||
// suppression on) rather than silencing it, and tell the user why.
|
// suppression on) rather than silencing it, and tell the user why.
|
||||||
async function resolveChainRebuildGuard() {
|
async function resolveChainRebuildGuard() {
|
||||||
const api = window.slopsmithDesktop?.audio;
|
const api = window.feedBackDesktop?.audio;
|
||||||
if (!api) return;
|
if (!api) return;
|
||||||
const providerRoute = window._aeInspectProviderManagedChain && window._aeInspectProviderManagedChain();
|
const providerRoute = window._aeInspectProviderManagedChain && window._aeInspectProviderManagedChain();
|
||||||
if (providerRoute) {
|
if (providerRoute) {
|
||||||
@@ -4197,7 +4197,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Preload presets for tone switching
|
// Preload presets for tone switching
|
||||||
const api = window.slopsmithDesktop?.audio;
|
const api = window.feedBackDesktop?.audio;
|
||||||
const hw = window.highway || window._slopsmithHighway;
|
const hw = window.highway || window._slopsmithHighway;
|
||||||
if (!api || !hw) return;
|
if (!api || !hw) return;
|
||||||
|
|
||||||
@@ -4369,7 +4369,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
console.log('[tone-switcher] switchToTone called:', name, 'current:', this.activeTone, 'midiMode:', this.midiMode);
|
console.log('[tone-switcher] switchToTone called:', name, 'current:', this.activeTone, 'midiMode:', this.midiMode);
|
||||||
if (name === this.activeTone) return;
|
if (name === this.activeTone) return;
|
||||||
const program = midiMappings[name];
|
const program = midiMappings[name];
|
||||||
const _api = window.slopsmithDesktop?.audio;
|
const _api = window.feedBackDesktop?.audio;
|
||||||
console.log('[tone-switcher] program:', program, 'api:', !!_api, 'sendMidi:', !!_api?.sendMidiToSlot, 'slotId:', midiConfig.vstSlotId);
|
console.log('[tone-switcher] program:', program, 'api:', !!_api, 'sendMidi:', !!_api?.sendMidiToSlot, 'slotId:', midiConfig.vstSlotId);
|
||||||
if (program !== undefined && _api?.sendMidiToSlot) {
|
if (program !== undefined && _api?.sendMidiToSlot) {
|
||||||
_api.sendMidiToSlot(midiConfig.vstSlotId, 0, midiConfig.channel || 1, program);
|
_api.sendMidiToSlot(midiConfig.vstSlotId, 0, midiConfig.channel || 1, program);
|
||||||
@@ -4379,7 +4379,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Send initial PC for base tone
|
// Send initial PC for base tone
|
||||||
const _apiInit = window.slopsmithDesktop?.audio;
|
const _apiInit = window.feedBackDesktop?.audio;
|
||||||
if (midiMappings[toneBase] !== undefined && _apiInit?.sendMidiToSlot) {
|
if (midiMappings[toneBase] !== undefined && _apiInit?.sendMidiToSlot) {
|
||||||
_apiInit.sendMidiToSlot(midiConfig.vstSlotId, 0, midiConfig.channel || 1, midiMappings[toneBase]);
|
_apiInit.sendMidiToSlot(midiConfig.vstSlotId, 0, midiConfig.channel || 1, midiMappings[toneBase]);
|
||||||
}
|
}
|
||||||
@@ -4617,13 +4617,13 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
// ── Update-downloaded restart banner (top-level, runs even without audio API) ──
|
// ── Update-downloaded restart banner (top-level, runs even without audio API) ──
|
||||||
// Subscribes to window.slopsmithDesktop.update.onDownloaded and renders a
|
// Subscribes to window.feedBackDesktop.update.onDownloaded and renders a
|
||||||
// persistent banner with a "Restart now" button. Degrades silently when the
|
// persistent banner with a "Restart now" button. Degrades silently when the
|
||||||
// updater IPC namespace is unavailable (e.g. dev builds before the main slice
|
// updater IPC namespace is unavailable (e.g. dev builds before the main slice
|
||||||
// lands, or unsupported platforms).
|
// lands, or unsupported platforms).
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
const updateApi = window.slopsmithDesktop?.update;
|
const updateApi = window.feedBackDesktop?.update;
|
||||||
if (!updateApi || typeof updateApi.onDownloaded !== 'function') return;
|
if (!updateApi || typeof updateApi.onDownloaded !== 'function') return;
|
||||||
|
|
||||||
const BANNER_ID = 'slopsmith-update-banner';
|
const BANNER_ID = 'slopsmith-update-banner';
|
||||||
@@ -4632,7 +4632,7 @@ window.__slopsmithDesktopAudioHooks = window.__slopsmithDesktopAudioHooks || {};
|
|||||||
// unsubscribe fn — drop the listener a previous evaluation registered so
|
// unsubscribe fn — drop the listener a previous evaluation registered so
|
||||||
// they don't pile up (renderUpdateBanner() de-dupes the DOM node, but the
|
// they don't pile up (renderUpdateBanner() de-dupes the DOM node, but the
|
||||||
// listeners themselves would still leak).
|
// listeners themselves would still leak).
|
||||||
const hookState = window.__slopsmithDesktopAudioHooks;
|
const hookState = window.__feedBackDesktopAudioHooks;
|
||||||
if (typeof hookState.updateBannerUnsub === 'function') {
|
if (typeof hookState.updateBannerUnsub === 'function') {
|
||||||
try { hookState.updateBannerUnsub(); } catch (_) { /* defensive */ }
|
try { hookState.updateBannerUnsub(); } catch (_) { /* defensive */ }
|
||||||
hookState.updateBannerUnsub = null;
|
hookState.updateBannerUnsub = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user