remove reset button, move auto save indicator in velxio
parent
998472f996
commit
65c12bc716
|
|
@ -27,7 +27,8 @@
|
||||||
const LONG_PRESS_MS = 400;
|
const LONG_PRESS_MS = 400;
|
||||||
const DOUBLE_TAP_MS = 300;
|
const DOUBLE_TAP_MS = 300;
|
||||||
const HOLDING_TIMEOUT_MS = 5000;
|
const HOLDING_TIMEOUT_MS = 5000;
|
||||||
const CURSOR_OFFSET_Y = -(parseInt(env.PUBLIC_CURSOR_OFFSET_Y || '50', 10));
|
const BASE_OFFSET_Y = -(parseInt(env.PUBLIC_CURSOR_OFFSET_Y || '50', 10));
|
||||||
|
let currentOffset = $derived(isTouchDevice ? BASE_OFFSET_Y : 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State machine:
|
* State machine:
|
||||||
|
|
@ -46,12 +47,18 @@
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (typeof window === 'undefined') return;
|
if (typeof window === 'undefined') return;
|
||||||
const mql = window.matchMedia('(hover: none) and (pointer: coarse)');
|
const mql = window.matchMedia('(hover: none) and (pointer: coarse)');
|
||||||
isTouchDevice = mql.matches;
|
const checkTouch = () => {
|
||||||
const handler = (e: MediaQueryListEvent) => {
|
isTouchDevice = mql.matches && window.innerWidth < 768;
|
||||||
isTouchDevice = e.matches;
|
};
|
||||||
|
|
||||||
|
checkTouch();
|
||||||
|
mql.addEventListener('change', checkTouch);
|
||||||
|
window.addEventListener('resize', checkTouch);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
mql.removeEventListener('change', checkTouch);
|
||||||
|
window.removeEventListener('resize', checkTouch);
|
||||||
};
|
};
|
||||||
mql.addEventListener('change', handler);
|
|
||||||
return () => mql.removeEventListener('change', handler);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function getIframeTarget(x: number, y: number): Element | null {
|
function getIframeTarget(x: number, y: number): Element | null {
|
||||||
|
|
@ -142,7 +149,7 @@
|
||||||
if (!overlayEl) return;
|
if (!overlayEl) return;
|
||||||
const rect = overlayEl.getBoundingClientRect();
|
const rect = overlayEl.getBoundingClientRect();
|
||||||
crosshairX = viewportX - rect.left;
|
crosshairX = viewportX - rect.left;
|
||||||
crosshairY = viewportY - rect.top + CURSOR_OFFSET_Y;
|
crosshairY = viewportY - rect.top + currentOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCrosshairViewport(): { x: number; y: number } {
|
function getCrosshairViewport(): { x: number; y: number } {
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@
|
||||||
|
|
||||||
// Auto-save Velxio state periodically
|
// Auto-save Velxio state periodically
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (velxioReady && auth.isLoggedIn && !showSolution) {
|
if (velxioReady && $authLoggedIn && !showSolution) {
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
const state = getVelxioState();
|
const state = getVelxioState();
|
||||||
if (!state) return;
|
if (!state) return;
|
||||||
|
|
@ -921,9 +921,7 @@
|
||||||
Hubungi guru jika masalah berlanjut.
|
Hubungi guru jika masalah berlanjut.
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="velxio-toolbar">
|
{#if $authLoggedIn}
|
||||||
<button type="button" class="btn btn-secondary btn-sm" onclick={handleReset}>Reset</button>
|
|
||||||
{#if auth.isLoggedIn}
|
|
||||||
<div class="storage-indicator-inline" title={velxioSaving ? "Menyimpan draf..." : "Draf tersimpan di browser"}>
|
<div class="storage-indicator-inline" title={velxioSaving ? "Menyimpan draf..." : "Draf tersimpan di browser"}>
|
||||||
<span class="indicator-icon" class:saving={velxioSaving}>
|
<span class="indicator-icon" class:saving={velxioSaving}>
|
||||||
{velxioSaving ? '●' : '☁'}
|
{velxioSaving ? '●' : '☁'}
|
||||||
|
|
@ -931,7 +929,6 @@
|
||||||
<span class="indicator-text">Auto-save</span>
|
<span class="indicator-text">Auto-save</span>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
|
||||||
<!-- svelte-ignore a11y_missing_attribute -->
|
<!-- svelte-ignore a11y_missing_attribute -->
|
||||||
<iframe
|
<iframe
|
||||||
class="velxio-iframe"
|
class="velxio-iframe"
|
||||||
|
|
@ -1243,22 +1240,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Velxio (Arduino simulator) ─────────────────────── */
|
/* ── Velxio (Arduino simulator) ─────────────────────── */
|
||||||
.velxio-toolbar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
|
||||||
padding: 0.4rem 0.5rem;
|
|
||||||
border-bottom: 1px solid var(--color-border);
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
.storage-indicator-inline {
|
.storage-indicator-inline {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: 0.7rem;
|
font-size: 0.75rem;
|
||||||
color: var(--color-text-muted);
|
color: var(--color-text-muted);
|
||||||
|
background: var(--color-bg-secondary);
|
||||||
|
padding: 3px 10px;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 1rem;
|
||||||
|
right: 1.5rem;
|
||||||
|
z-index: 10;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
margin-left: auto;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
.storage-indicator-inline .indicator-icon {
|
.storage-indicator-inline .indicator-icon {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|
@ -1278,6 +1276,7 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.velxio-panel.tab-hidden {
|
.velxio-panel.tab-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue