Updated mobile UX

This commit is contained in:
root
2025-05-18 17:14:56 +02:00
parent e3205d500d
commit b33b172644
11 changed files with 785 additions and 562 deletions

View File

@@ -14,8 +14,8 @@
:class="{ 'rounded-none border-0': isFullScreen }"
>
<!-- Header with drag handle -->
<div class="flex justify-between items-center p-4 border-b border-gray-200 dark:border-gray-700" :class="{ 'cursor-move': !isFullScreen }" @mousedown="startDrag" @touchstart.prevent="handleTouchStart">
<h3 class="text-2xl font-semibold text-gray-900 dark:text-gray-100">{{ title }}</h3>
<div class="flex justify-between items-center p-4 border-b border-gray-200 dark:border-gray-700" :class="{ 'cursor-move': !isFullScreen && !isMobile }">
<h3 class="text-xl sm:text-2xl font-semibold text-gray-900 dark:text-gray-100 truncate pr-2" @mousedown="startDrag" @touchstart="handleTouchStart">{{ title }}</h3>
<div class="flex items-center space-x-2">
<button @click="toggleFullScreen" class="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors" data-umami-event="modal-fullscreen">
<img src="@/assets/images/fullscreen-icon.svg" class="w-4 h-4 dark:invert" alt="Fullscreen" :class="{ 'rotate-180': isFullScreen }" />
@@ -27,12 +27,12 @@
</div>
<!-- Body -->
<div class="p-6 flex-1 overflow-auto">
<div class="p-4 sm:p-6 flex-1 overflow-auto">
<slot></slot>
</div>
<!-- Resize handle -->
<div v-if="!isFullScreen" class="absolute bottom-0 right-0 w-8 h-8 cursor-se-resize" @mousedown="startResize" @touchstart="startResize"></div>
<div v-if="!isFullScreen && !isMobile" class="absolute bottom-0 right-0 w-8 h-8 cursor-se-resize" @mousedown="startResize" @touchstart="startResize"></div>
</div>
</Teleport>
</template>
@@ -65,6 +65,7 @@
// Add isFullScreen ref
const isFullScreen = ref(false);
const isMobile = ref(false);
// Add previous state storage for restoring from full screen
const previousState = ref({
@@ -72,6 +73,23 @@
size: { width: 0, height: 0 },
});
// Check if device is mobile
const checkMobile = () => {
isMobile.value = window.innerWidth < 640; // sm breakpoint in Tailwind
// Auto fullscreen on mobile
if (isMobile.value && !isFullScreen.value) {
toggleFullScreen();
} else if (!isMobile.value && isFullScreen.value && autoFullScreened.value) {
// If we're no longer on mobile and were auto-fullscreened, exit fullscreen
toggleFullScreen();
autoFullScreened.value = false;
}
};
// Track if fullscreen was automatic (for mobile)
const autoFullScreened = ref(false);
// Add toggleFullScreen function
const toggleFullScreen = () => {
if (!isFullScreen.value) {
@@ -80,6 +98,11 @@
position: { ...position.value },
size: { ...size.value },
};
// If toggling to fullscreen on mobile automatically, track it
if (isMobile.value) {
autoFullScreened.value = true;
}
} else {
// Restore previous state
position.value = { ...previousState.value.position };
@@ -138,7 +161,7 @@
isDragging.value = false;
isResizing.value = false;
document.removeEventListener('mousemove', handleMove);
document.removeEventListener('touchmove', handleMove);
document.removeEventListener('touchmove', handleTouchMove); // Fix: was handleMove
document.removeEventListener('mouseup', stopAction);
document.removeEventListener('touchend', stopAction);
};
@@ -194,11 +217,8 @@
const handleTouchMove = (event: TouchEvent) => {
if (!isDragging.value && !isResizing.value) return;
event.preventDefault();
if (event.touches.length === 1) {
handleMove(event);
}
event.preventDefault(); // Prevent scrolling while dragging
handleMove(event);
};
// Lifecycle
@@ -212,12 +232,18 @@
onMounted(() => {
document.addEventListener('keydown', handleKeyDown);
window.addEventListener('resize', handleResize);
window.addEventListener('resize', checkMobile);
// Initial check for mobile
checkMobile();
if (props.isOpen) centerModal();
});
onUnmounted(() => {
document.removeEventListener('keydown', handleKeyDown);
window.removeEventListener('resize', handleResize);
window.removeEventListener('resize', checkMobile);
stopAction();
});
</script>