The v2.0.0 grid stayed empty in Premiere 26 because UXP's CSS engine
doesn't support `grid-template-columns: repeat(auto-fill, minmax(...))`
or `aspect-ratio`. Cards rendered with 0 height and the flex column
collapsed, so the actions row stuck to the top of the pane.
Switch to flex-wrap with fixed-width (140px) cards and explicit 80px
thumb heights — both work in UXP's stripped CSS.
Also fix the /auth/me response shape — it returns the user fields
directly, not wrapped in `{ user: ... }`. Header now shows
"display_name @ host" instead of falling back to bare host.
Add a toast on each library load reporting "Loaded N assets (total M)"
so we can tell empty-grid (zero assets) from CSS-broken-grid (cards
exist but invisible) at a glance.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
103 lines
3.6 KiB
JavaScript
103 lines
3.6 KiB
JavaScript
// 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();
|
|
}
|
|
})();
|