fix: improve mobile scrollbar visibility and resize handling
This commit is contained in:
@@ -82,7 +82,7 @@ define(['./workbox-7a5e81cd'], (function (workbox) { 'use strict';
|
|||||||
*/
|
*/
|
||||||
workbox.precacheAndRoute([{
|
workbox.precacheAndRoute([{
|
||||||
"url": "index.html",
|
"url": "index.html",
|
||||||
"revision": "0.ohmkvc7m8mo"
|
"revision": "0.0dmrmul42fg"
|
||||||
}], {});
|
}], {});
|
||||||
workbox.cleanupOutdatedCaches();
|
workbox.cleanupOutdatedCaches();
|
||||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-nonograms-solid",
|
"name": "vue-nonograms-solid",
|
||||||
"version": "1.11.1",
|
"version": "1.11.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "vue-nonograms-solid",
|
"name": "vue-nonograms-solid",
|
||||||
"version": "1.11.1",
|
"version": "1.11.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fireworks-js": "^2.10.8",
|
"fireworks-js": "^2.10.8",
|
||||||
"flag-icons": "^7.5.0",
|
"flag-icons": "^7.5.0",
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-nonograms-solid",
|
"name": "vue-nonograms-solid",
|
||||||
"version": "1.11.1",
|
"version": "1.11.2",
|
||||||
"homepage": "https://nonograms.7u.pl/",
|
"homepage": "https://nonograms.7u.pl/",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite --host",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test": "vitest"
|
"test": "vitest"
|
||||||
|
|||||||
@@ -43,21 +43,30 @@ const handlePointerDown = (e) => {
|
|||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
if (now - lastTap < 300) {
|
if (now - lastTap < 300) {
|
||||||
// Double tap -> X (Force)
|
// Double tap -> X (Force)
|
||||||
|
clearLongPress();
|
||||||
emit('start-drag', props.r, props.c, true, true);
|
emit('start-drag', props.r, props.c, true, true);
|
||||||
lastTap = 0;
|
lastTap = 0;
|
||||||
} else {
|
} else {
|
||||||
// Single tap / Start drag -> Fill
|
// Single tap / Start drag -> Fill
|
||||||
emit('start-drag', props.r, props.c, false, false);
|
emit('start-drag', props.r, props.c, false, false);
|
||||||
lastTap = now;
|
lastTap = now;
|
||||||
|
|
||||||
|
// Start Long Press Timer
|
||||||
|
clearLongPress();
|
||||||
|
longPressTimer = setTimeout(() => {
|
||||||
|
if (navigator.vibrate) navigator.vibrate(50);
|
||||||
|
// Switch to Cross (Right click logic, force=true to overwrite the just-placed Fill)
|
||||||
|
emit('start-drag', props.r, props.c, true, true);
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePointerUp = (e) => {
|
const handlePointerUp = (e) => {
|
||||||
// Handled in pointerdown
|
clearLongPress();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePointerCancel = (e) => {
|
const handlePointerCancel = (e) => {
|
||||||
// Handled in pointerdown
|
clearLongPress();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -27,17 +27,28 @@ let dragStartLeft = 0;
|
|||||||
const checkScroll = () => {
|
const checkScroll = () => {
|
||||||
const el = scrollWrapper.value;
|
const el = scrollWrapper.value;
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
|
|
||||||
|
const content = el.firstElementChild;
|
||||||
|
const contentWidth = content ? content.offsetWidth : el.scrollWidth;
|
||||||
const sw = el.scrollWidth;
|
const sw = el.scrollWidth;
|
||||||
const cw = el.clientWidth;
|
const cw = el.clientWidth;
|
||||||
|
|
||||||
// Only show custom scrollbar on mobile/tablet (width < 768px) and if content overflows
|
// Only show custom scrollbar on mobile/tablet (width < 768px) and if content overflows
|
||||||
const isMobile = window.innerWidth <= 768;
|
const isMobile = window.innerWidth <= 768;
|
||||||
showScrollbar.value = isMobile && (sw > cw + 1);
|
// Use contentWidth to check for overflow, as scrollWidth might be misleading
|
||||||
|
showScrollbar.value = isMobile && (contentWidth > cw + 1);
|
||||||
|
|
||||||
if (showScrollbar.value) {
|
if (showScrollbar.value) {
|
||||||
// Thumb width percentage = (viewport / total) * 100
|
// Thumb width percentage = (viewport / total) * 100
|
||||||
const ratio = cw / sw;
|
// Use contentWidth for more accurate ratio
|
||||||
|
const ratio = cw / contentWidth;
|
||||||
thumbWidth.value = Math.max(10, ratio * 100);
|
thumbWidth.value = Math.max(10, ratio * 100);
|
||||||
|
|
||||||
|
// Hide if content fits or almost fits (prevent useless scrollbar)
|
||||||
|
// Increased tolerance to 95%
|
||||||
|
if (ratio >= 0.95) {
|
||||||
|
showScrollbar.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -175,21 +186,38 @@ const handleGridLeave = () => {
|
|||||||
activeCol.value = null;
|
activeCol.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleResize = () => {
|
||||||
|
computeCellSize();
|
||||||
|
checkScroll();
|
||||||
|
// Re-check after potential layout animation/transition
|
||||||
|
setTimeout(() => {
|
||||||
|
computeCellSize();
|
||||||
|
checkScroll();
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
computeCellSize();
|
computeCellSize();
|
||||||
|
checkScroll();
|
||||||
|
// Extra check for slow layout/font loading or orientation changes
|
||||||
|
setTimeout(() => {
|
||||||
|
computeCellSize();
|
||||||
|
checkScroll();
|
||||||
|
}, 300);
|
||||||
});
|
});
|
||||||
isFinePointer.value = window.matchMedia('(pointer: fine)').matches;
|
isFinePointer.value = window.matchMedia('(pointer: fine)').matches;
|
||||||
window.addEventListener('resize', computeCellSize);
|
|
||||||
window.addEventListener('resize', checkScroll);
|
window.addEventListener('resize', handleResize);
|
||||||
|
window.addEventListener('orientationchange', handleResize);
|
||||||
window.addEventListener('mouseup', handleGlobalMouseUp);
|
window.addEventListener('mouseup', handleGlobalMouseUp);
|
||||||
window.addEventListener('pointerup', handleGlobalPointerUp);
|
window.addEventListener('pointerup', handleGlobalPointerUp);
|
||||||
window.addEventListener('touchend', handleGlobalPointerUp, { passive: true });
|
window.addEventListener('touchend', handleGlobalPointerUp, { passive: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
window.removeEventListener('resize', computeCellSize);
|
window.removeEventListener('resize', handleResize);
|
||||||
window.removeEventListener('resize', checkScroll);
|
window.removeEventListener('orientationchange', handleResize);
|
||||||
window.removeEventListener('mouseup', handleGlobalMouseUp);
|
window.removeEventListener('mouseup', handleGlobalMouseUp);
|
||||||
window.removeEventListener('pointerup', handleGlobalPointerUp);
|
window.removeEventListener('pointerup', handleGlobalPointerUp);
|
||||||
window.removeEventListener('touchend', handleGlobalPointerUp);
|
window.removeEventListener('touchend', handleGlobalPointerUp);
|
||||||
@@ -199,6 +227,10 @@ watch(() => store.size, async () => {
|
|||||||
await nextTick();
|
await nextTick();
|
||||||
computeCellSize();
|
computeCellSize();
|
||||||
checkScroll();
|
checkScroll();
|
||||||
|
setTimeout(() => {
|
||||||
|
computeCellSize();
|
||||||
|
checkScroll();
|
||||||
|
}, 300);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -48,5 +48,8 @@ export default defineConfig({
|
|||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve(__dirname, './src')
|
'@': path.resolve(__dirname, './src')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
allowedHosts: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user