Polish player chrome: left back, right menu, swipe-down dismiss.
build-and-deploy / deploy (push) Successful in 4m32s

Unify square icon buttons and close the expanded sheet with a real downward drag instead of a chevron control.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
masoodafar-web
2026-10-10 03:29:50 +03:30
parent 0cddd0f59a
commit 27a47a545e
4 changed files with 160 additions and 32 deletions
+102
View File
@@ -80,3 +80,105 @@ window.tqAudio = {
};
}
};
window.tqSheet = {
_handlers: new WeakMap(),
_ignored: (target) => {
if (!target || !target.closest) return false;
return !!target.closest('.seek, input, .player-main-controls, .sheet-actions, .sheet-icon-btn, button, a');
},
bindDismiss: (el, dotnet, methodName) => {
if (!el || !dotnet) return;
window.tqSheet.unbindDismiss(el);
const state = { startY: 0, startX: 0, active: false, dragging: false };
const threshold = 80;
const method = methodName || 'OnSwipeDismiss';
const resetTransform = () => {
el.style.transition = 'transform 0.22s ease, opacity 0.22s ease';
el.style.transform = '';
el.style.opacity = '';
window.setTimeout(() => { el.style.transition = ''; }, 240);
};
const onStart = (e) => {
if (window.tqSheet._ignored(e.target)) return;
const point = e.touches ? e.touches[0] : e;
if (!point) return;
state.startY = point.clientY;
state.startX = point.clientX;
state.active = true;
state.dragging = false;
el.style.transition = 'none';
};
const onMove = (e) => {
if (!state.active) return;
const point = e.touches ? e.touches[0] : e;
if (!point) return;
const dy = point.clientY - state.startY;
const dx = point.clientX - state.startX;
if (!state.dragging) {
if (Math.abs(dy) < 8 && Math.abs(dx) < 8) return;
if (Math.abs(dx) > Math.abs(dy) || dy < 0) {
state.active = false;
return;
}
state.dragging = true;
}
if (e.cancelable) e.preventDefault();
const y = Math.max(0, dy);
el.style.transform = `translateY(${y}px)`;
el.style.opacity = String(Math.max(0.45, 1 - y / 420));
};
const onEnd = (e) => {
if (!state.active && !state.dragging) return;
const point = (e.changedTouches && e.changedTouches[0]) || e;
const dy = point ? (point.clientY - state.startY) : 0;
const dx = point ? (point.clientX - state.startX) : 0;
const shouldDismiss = state.dragging && dy >= threshold && Math.abs(dx) < dy;
state.active = false;
state.dragging = false;
if (shouldDismiss) {
el.style.transition = 'transform 0.2s ease, opacity 0.2s ease';
el.style.transform = 'translateY(100%)';
el.style.opacity = '0';
dotnet.invokeMethodAsync(method);
} else {
resetTransform();
}
};
el.addEventListener('touchstart', onStart, { passive: true });
el.addEventListener('touchmove', onMove, { passive: false });
el.addEventListener('touchend', onEnd, { passive: true });
el.addEventListener('touchcancel', onEnd, { passive: true });
el.addEventListener('pointerdown', onStart);
el.addEventListener('pointermove', onMove);
el.addEventListener('pointerup', onEnd);
el.addEventListener('pointercancel', onEnd);
window.tqSheet._handlers.set(el, { onStart, onMove, onEnd });
},
unbindDismiss: (el) => {
const h = window.tqSheet._handlers.get(el);
if (!h || !el) return;
el.removeEventListener('touchstart', h.onStart);
el.removeEventListener('touchmove', h.onMove);
el.removeEventListener('touchend', h.onEnd);
el.removeEventListener('touchcancel', h.onEnd);
el.removeEventListener('pointerdown', h.onStart);
el.removeEventListener('pointermove', h.onMove);
el.removeEventListener('pointerup', h.onEnd);
el.removeEventListener('pointercancel', h.onEnd);
el.style.transform = '';
el.style.opacity = '';
el.style.transition = '';
window.tqSheet._handlers.delete(el);
}
};