// Panel bootstrap. Wires DOM events to API / Library / Import handlers and // restores the connection from localStorage on mount. (function () { // Avoid running twice if UXP reloads the panel. if (window.__df_uxp_started) return; window.__df_uxp_started = true; function syncConnectBtn() { const u = UI.$('#server-url').value.trim(); const t = UI.$('#api-token').value.trim(); UI.$('#connect-btn').disabled = !u || !t; } async function tryConnect(serverUrl, apiToken) { UI.setStatus('#connect-status', 'Connecting…', 'muted'); try { const me = await API.connect(serverUrl, apiToken); // /auth/me returns the user fields directly (no `user:` wrapper). const who = (me && (me.display_name || me.username)) || serverUrl; UI.$('#connected-host').textContent = who + (who === serverUrl ? '' : ' @ ' + serverUrl); UI.setStatus('#connect-status', '', 'muted'); UI.showPane('library'); await Library.refresh(''); } catch (e) { API.state.connected = false; UI.setStatus('#connect-status', 'Connect failed: ' + e.message, 'error'); UI.showPane('connect'); } } function wireConnectPane() { UI.$('#server-url').value = API.state.serverUrl; UI.$('#api-token').value = API.state.apiToken; syncConnectBtn(); ['input', 'change'].forEach(ev => { UI.$('#server-url').addEventListener(ev, syncConnectBtn); UI.$('#api-token').addEventListener(ev, syncConnectBtn); }); UI.$('#connect-btn').addEventListener('click', async () => { const u = UI.$('#server-url').value.trim(); const t = UI.$('#api-token').value.trim(); await tryConnect(u, t); }); } function wireLibraryPane() { UI.$('#disconnect-btn').addEventListener('click', () => { API.disconnect(); UI.$('#server-url').value = ''; UI.$('#api-token').value = ''; syncConnectBtn(); UI.showPane('connect'); UI.setStatus('#connect-status', 'Disconnected.', 'muted'); }); let searchTimer = null; UI.$('#search-input').addEventListener('input', (e) => { clearTimeout(searchTimer); const q = e.target.value; searchTimer = setTimeout(() => Library.refresh(q), 250); }); UI.$('#refresh-btn').addEventListener('click', () => Library.refresh(UI.$('#search-input').value)); UI.$('#import-proxy-btn').addEventListener('click', async () => { const a = Library.selectedAsset(); if (!a) return; UI.$('#import-proxy-btn').disabled = true; UI.$('#import-hires-btn').disabled = true; try { await Import.proxy(a); } catch (e) { UI.hideProgress(); UI.toast('Proxy import failed: ' + e.message, 'error'); } finally { Library.syncActions(); } }); UI.$('#import-hires-btn').addEventListener('click', async () => { const a = Library.selectedAsset(); if (!a) return; UI.$('#import-proxy-btn').disabled = true; UI.$('#import-hires-btn').disabled = true; try { await Import.hires(a); } catch (e) { UI.hideProgress(); UI.toast('Hi-res import failed: ' + e.message, 'error'); } finally { Library.syncActions(); } }); } function init() { wireConnectPane(); wireLibraryPane(); // If we have stored creds, try to reconnect silently. On failure fall // back to the connect pane so the user can retype. if (API.state.serverUrl && API.state.apiToken) { tryConnect(API.state.serverUrl, API.state.apiToken); } else { UI.showPane('connect'); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();