Next/back button assignment moves from a frame-level "Button assignments" card into each widget's own gear-icon dialog, prefilled with a sane default at creation (photos/calendar -> advance/back, whiteboard/weather -> check_now, others -> none). At most one binding per (widget, button) now -- cross-widget execution order never mattered since each widget's action only touches its own state. New firmware capability: holding NEXT or BACK past a configurable duration (min 3s, server-side default) triggers a frame-wide action instead of the per-widget short-press one -- cycling saved layouts, refreshing all widgets, or freezing/unfreezing every photo widget (see app/global_actions.py). Firmware next/back checks gain the same hold-duration polling the combo button already had; the threshold comes from the previous wake's /frame/config fetch (persisted in NVS), since this wake's button decision happens before that request. Not done here: firmware/version.txt is intentionally left unbumped -- this hasn't been built or hardware-tested (no ESP-IDF toolchain in this environment), so no firmware release build should be triggered yet.
34 lines
1.4 KiB
JavaScript
34 lines
1.4 KiB
JavaScript
// Shared "Button actions" card (models.FrameButtonAction,
|
|
// _widget_button_fields.html) -- present on every widget type's dialog
|
|
// that supports any actions at all (the card renders nothing for
|
|
// tasks/static/text/battery, whose ACTIONS is empty), so this is one
|
|
// shared init function each widget_dialog_<type>.js's init<Type>Dialog()
|
|
// calls, rather than N copies of the same save wiring -- same pattern as
|
|
// widget_dialog_border.js. Not a page-load script by itself --
|
|
// frame_layout.js loads it unconditionally (like every other
|
|
// widget_dialog_*.js) since which dialog is open varies.
|
|
|
|
function initButtonActionFields() {
|
|
const form = document.getElementById('button-actions-form');
|
|
if (!form) return; // this widget type has no actions -- card didn't render
|
|
|
|
form.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const body = JSON.stringify({
|
|
next_button_action: document.getElementById('next_button_action').value,
|
|
back_button_action: document.getElementById('back_button_action').value,
|
|
});
|
|
try {
|
|
const resp = await fetch(`${window.FRAME_API}/button-actions`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body,
|
|
});
|
|
if (!resp.ok) throw new Error(await apiError(resp));
|
|
showStatus(true, 'Button actions saved.');
|
|
} catch (err) {
|
|
showStatus(false, err.message);
|
|
}
|
|
});
|
|
}
|