v0.8.4 full refresh
This commit is contained in:
@@ -14,25 +14,72 @@ if ('serviceWorker' in navigator) {
|
||||
|
||||
|
||||
|
||||
// Disable pull-to-refresh in PWA standalone mode to prevent viewport shift bug.
|
||||
// The CSS overscroll-behavior-y:none handles most browsers; this catches the rest.
|
||||
// ─── Touch gesture handler ───────────────────────────────────────────────────
|
||||
// Handles two behaviours in one unified listener set to avoid conflicts:
|
||||
//
|
||||
// 1. PINCH → font scale only (not viewport zoom).
|
||||
// viewport has user-scalable=no so the browser never zooms the layout.
|
||||
// We intercept the pinch and adjust --font-scale on <html> instead,
|
||||
// which scales only text (rem-based font sizes). Persisted to localStorage.
|
||||
// On first launch, html { font-size: 100% } inherits the Android system
|
||||
// font size as the 1rem baseline automatically.
|
||||
//
|
||||
// 2. PULL-TO-REFRESH → blocked in PWA standalone mode only.
|
||||
(function () {
|
||||
const LS_KEY = 'jama_font_scale';
|
||||
const MIN_SCALE = 0.8;
|
||||
const MAX_SCALE = 2.0;
|
||||
|
||||
const isStandalone = window.matchMedia('(display-mode: standalone)').matches
|
||||
|| window.navigator.standalone === true;
|
||||
if (!isStandalone) return;
|
||||
|
||||
let startY = 0;
|
||||
document.addEventListener('touchstart', e => {
|
||||
startY = e.touches[0].clientY;
|
||||
// Restore saved font scale on launch
|
||||
const saved = parseFloat(localStorage.getItem(LS_KEY));
|
||||
let currentScale = (saved >= MIN_SCALE && saved <= MAX_SCALE) ? saved : 1.0;
|
||||
document.documentElement.style.setProperty('--font-scale', currentScale);
|
||||
|
||||
let pinchStartDist = null;
|
||||
let pinchStartScale = currentScale;
|
||||
let singleStartY = 0;
|
||||
|
||||
function getTouchDist(e) {
|
||||
const dx = e.touches[0].clientX - e.touches[1].clientX;
|
||||
const dy = e.touches[0].clientY - e.touches[1].clientY;
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
document.addEventListener('touchstart', function (e) {
|
||||
if (e.touches.length === 2) {
|
||||
pinchStartDist = getTouchDist(e);
|
||||
pinchStartScale = currentScale;
|
||||
} else if (e.touches.length === 1) {
|
||||
singleStartY = e.touches[0].clientY;
|
||||
}
|
||||
}, { passive: true });
|
||||
|
||||
document.addEventListener('touchmove', e => {
|
||||
// Only block downward pull at the very top of the document
|
||||
const dy = e.touches[0].clientY - startY;
|
||||
if (dy > 0 && (document.documentElement.scrollTop === 0 || document.body.scrollTop === 0)) {
|
||||
document.addEventListener('touchmove', function (e) {
|
||||
if (e.touches.length === 2 && pinchStartDist !== null) {
|
||||
// Two-finger pinch: scale fonts, not viewport
|
||||
e.preventDefault();
|
||||
const ratio = getTouchDist(e) / pinchStartDist;
|
||||
const newScale = Math.min(MAX_SCALE, Math.max(MIN_SCALE, pinchStartScale * ratio));
|
||||
currentScale = Math.round(newScale * 100) / 100;
|
||||
document.documentElement.style.setProperty('--font-scale', currentScale);
|
||||
} else if (e.touches.length === 1 && isStandalone) {
|
||||
// Single finger: block pull-to-refresh at top of page
|
||||
const dy = e.touches[0].clientY - singleStartY;
|
||||
if (dy > 0 && document.documentElement.scrollTop === 0 && document.body.scrollTop === 0) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
}, { passive: false });
|
||||
|
||||
document.addEventListener('touchend', function (e) {
|
||||
if (e.touches.length < 2 && pinchStartDist !== null) {
|
||||
pinchStartDist = null;
|
||||
localStorage.setItem(LS_KEY, currentScale);
|
||||
}
|
||||
}, { passive: true });
|
||||
})();
|
||||
|
||||
// Clear badge count when user focuses the app
|
||||
|
||||
Reference in New Issue
Block a user