Add HAOS scene preset buttons and smooth tutorial scrolling
Expose scene presets as button entities in the HA integration under a dedicated "Scenes" device. Each button activates its scene via the API. The coordinator now fetches scene presets alongside other data, and the integration reloads when the scene list changes. Also animate tutorial autoscroll with smooth behavior and wait for scrollend before positioning the spotlight overlay. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -226,35 +226,7 @@ export function tutorialPrev() {
|
||||
}
|
||||
}
|
||||
|
||||
function showTutorialStep(index, direction = 1) {
|
||||
if (!activeTutorial) return;
|
||||
activeTutorial.step = index;
|
||||
const step = activeTutorial.steps[index];
|
||||
const overlay = activeTutorial.overlay;
|
||||
const isFixed = activeTutorial.mode === 'fixed';
|
||||
|
||||
document.querySelectorAll('.tutorial-target').forEach(el => {
|
||||
el.classList.remove('tutorial-target');
|
||||
el.style.zIndex = '';
|
||||
});
|
||||
|
||||
const target = activeTutorial.resolveTarget(step);
|
||||
if (!target) {
|
||||
// Auto-skip hidden/missing targets in the current direction
|
||||
const next = index + direction;
|
||||
if (next >= 0 && next < activeTutorial.steps.length) showTutorialStep(next, direction);
|
||||
else closeTutorial();
|
||||
return;
|
||||
}
|
||||
target.classList.add('tutorial-target');
|
||||
if (isFixed) target.style.zIndex = '10001';
|
||||
|
||||
// Scroll target into view if off-screen
|
||||
const preRect = target.getBoundingClientRect();
|
||||
if (preRect.bottom > window.innerHeight || preRect.top < 0) {
|
||||
target.scrollIntoView({ behavior: 'instant', block: 'center' });
|
||||
}
|
||||
|
||||
function _positionSpotlight(target, overlay, step, index, isFixed) {
|
||||
const targetRect = target.getBoundingClientRect();
|
||||
const pad = 6;
|
||||
let x, y, w, h;
|
||||
@@ -306,6 +278,58 @@ function showTutorialStep(index, direction = 1) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Wait for smooth scroll to finish, then resolve. */
|
||||
function _waitForScrollEnd(scrollTarget) {
|
||||
return new Promise(resolve => {
|
||||
let timer = setTimeout(resolve, 500); // fallback
|
||||
const onEnd = () => {
|
||||
clearTimeout(timer);
|
||||
scrollTarget.removeEventListener('scrollend', onEnd);
|
||||
resolve();
|
||||
};
|
||||
scrollTarget.addEventListener('scrollend', onEnd, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
function showTutorialStep(index, direction = 1) {
|
||||
if (!activeTutorial) return;
|
||||
activeTutorial.step = index;
|
||||
const step = activeTutorial.steps[index];
|
||||
const overlay = activeTutorial.overlay;
|
||||
const isFixed = activeTutorial.mode === 'fixed';
|
||||
|
||||
document.querySelectorAll('.tutorial-target').forEach(el => {
|
||||
el.classList.remove('tutorial-target');
|
||||
el.style.zIndex = '';
|
||||
});
|
||||
|
||||
const target = activeTutorial.resolveTarget(step);
|
||||
if (!target) {
|
||||
// Auto-skip hidden/missing targets in the current direction
|
||||
const next = index + direction;
|
||||
if (next >= 0 && next < activeTutorial.steps.length) showTutorialStep(next, direction);
|
||||
else closeTutorial();
|
||||
return;
|
||||
}
|
||||
target.classList.add('tutorial-target');
|
||||
if (isFixed) target.style.zIndex = '10001';
|
||||
|
||||
// Scroll target into view if off-screen (smooth animation)
|
||||
const preRect = target.getBoundingClientRect();
|
||||
const needsScroll = preRect.bottom > window.innerHeight || preRect.top < 0;
|
||||
|
||||
if (needsScroll) {
|
||||
target.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
_waitForScrollEnd(isFixed ? document.scrollingElement || document.documentElement : activeTutorial.container).then(() => {
|
||||
if (activeTutorial && activeTutorial.step === index) {
|
||||
_positionSpotlight(target, overlay, step, index, isFixed);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_positionSpotlight(target, overlay, step, index, isFixed);
|
||||
}
|
||||
}
|
||||
|
||||
function positionTutorialTooltip(tooltip, sx, sy, sw, sh, preferred, isFixed) {
|
||||
const gap = 12;
|
||||
const tooltipW = 260;
|
||||
|
||||
Reference in New Issue
Block a user