Leaner userscript: edge tab, card-click continue, test harness #7
@@ -1200,6 +1200,71 @@
|
|||||||
setInterval(fire, 1500); // catch routes that bypass history
|
setInterval(fire, 1500); // catch routes that bypass history
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Two-finger long-press — a way in that does not depend on finding a 7px tab
|
||||||
|
//
|
||||||
|
// Deliberately two fingers, not one: Chromium claims the one-finger long
|
||||||
|
// press for image context menus, text selection, and link previews, and on a
|
||||||
|
// manga reader the whole viewport is images. It assigns no two-finger long
|
||||||
|
// press, so these listeners stay passive and never preventDefault.
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
const LONGPRESS_MS = 500;
|
||||||
|
const LONGPRESS_SLOP = 15; // px either finger may drift before it counts as a drag
|
||||||
|
|
||||||
|
function installLongPress() {
|
||||||
|
let timer = null;
|
||||||
|
let start = null; // [{x, y}, {x, y}] — where each finger landed
|
||||||
|
|
||||||
|
const cancel = () => {
|
||||||
|
if (timer) clearTimeout(timer);
|
||||||
|
timer = null;
|
||||||
|
start = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const opts = { passive: true, capture: true };
|
||||||
|
|
||||||
|
// Fires once per finger, so the first touch cancels and the second arms.
|
||||||
|
// A third finger cancels again.
|
||||||
|
document.addEventListener(
|
||||||
|
"touchstart",
|
||||||
|
(e) => {
|
||||||
|
cancel();
|
||||||
|
if (e.touches.length !== 2) return;
|
||||||
|
start = [
|
||||||
|
{ x: e.touches[0].clientX, y: e.touches[0].clientY },
|
||||||
|
{ x: e.touches[1].clientX, y: e.touches[1].clientY },
|
||||||
|
];
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
cancel();
|
||||||
|
togglePanel();
|
||||||
|
}, LONGPRESS_MS);
|
||||||
|
},
|
||||||
|
opts
|
||||||
|
);
|
||||||
|
|
||||||
|
// A pinch-zoom is two fingers held down, so the slop check is what keeps it
|
||||||
|
// from opening the panel mid-gesture.
|
||||||
|
document.addEventListener(
|
||||||
|
"touchmove",
|
||||||
|
(e) => {
|
||||||
|
if (!start || e.touches.length !== 2) return cancel();
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
if (
|
||||||
|
Math.abs(e.touches[i].clientX - start[i].x) > LONGPRESS_SLOP ||
|
||||||
|
Math.abs(e.touches[i].clientY - start[i].y) > LONGPRESS_SLOP
|
||||||
|
) {
|
||||||
|
return cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
opts
|
||||||
|
);
|
||||||
|
|
||||||
|
document.addEventListener("touchend", cancel, opts);
|
||||||
|
document.addEventListener("touchcancel", cancel, opts);
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Boot
|
// Boot
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -1209,6 +1274,7 @@
|
|||||||
state.page = detect();
|
state.page = detect();
|
||||||
render();
|
render();
|
||||||
installNavWatcher();
|
installNavWatcher();
|
||||||
|
installLongPress();
|
||||||
window.addEventListener("online", drain); // signal returned while the page stayed open
|
window.addEventListener("online", drain); // signal returned while the page stayed open
|
||||||
// Sync first: both auto-record and the latest-chapter checks below need to
|
// Sync first: both auto-record and the latest-chapter checks below need to
|
||||||
// know which series are bookmarked and how fresh they are.
|
// know which series are bookmarked and how fresh they are.
|
||||||
|
|||||||
Reference in New Issue
Block a user