-
@@ -504,26 +515,7 @@ const triggerDownload = (blob, filename) => {
position: relative;
}
-.edit-toggle-btn {
- position: absolute;
- top: 0;
- right: 0;
- z-index: 20;
- color: var(--text-secondary);
- opacity: 0.6;
- background: var(--panel-bg);
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
-}
-.edit-toggle-btn:hover {
- opacity: 1;
- color: var(--text-strong);
-}
-
-.edit-toggle-btn.active {
- color: var(--primary-accent);
- opacity: 0.9;
-}
:root[data-theme="light"] .preview-section {
background: rgba(255, 255, 255, 0.3);
@@ -619,5 +611,23 @@ const triggerDownload = (blob, filename) => {
min-width: 100px !important;
}
+@media (max-width: 600px) {
+ .preview-section {
+ padding: 1rem 0.5rem;
+ gap: 1rem;
+ border-radius: 8px;
+ }
+
+ .qr-container {
+ width: 100%;
+ aspect-ratio: 1;
+ min-height: unset;
+ }
+
+ .qr-frame {
+ padding: 0.5rem;
+ }
+}
+
diff --git a/src/components/tools/QrScanner.vue b/src/components/tools/QrScanner.vue
index 8f171c8..19946cd 100644
--- a/src/components/tools/QrScanner.vue
+++ b/src/components/tools/QrScanner.vue
@@ -492,9 +492,11 @@ const isUrl = (string) => {
}
.switch-camera-btn {
- position: absolute;
- top: 1rem;
- right: 1rem;
+ position: absolute !important;
+ top: auto !important;
+ left: auto !important;
+ bottom: 0.75rem !important;
+ right: 0.75rem !important;
background: rgba(0, 0, 0, 0.4);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #fff;
diff --git a/src/directives/tooltip.js b/src/directives/tooltip.js
index 1afbc03..82dae46 100644
--- a/src/directives/tooltip.js
+++ b/src/directives/tooltip.js
@@ -3,11 +3,60 @@ import { showTooltip, hideTooltip, tooltipState } from '../composables/useToolti
export const tooltipDirective = {
mounted(el, binding) {
el._tooltipText = binding.value;
+ let touchTimeout = null;
+ let isTouch = false;
- el.addEventListener('mouseenter', () => showTooltip(el, el._tooltipText));
- el.addEventListener('mouseleave', hideTooltip);
- el.addEventListener('focus', () => showTooltip(el, el._tooltipText));
- el.addEventListener('blur', hideTooltip);
+ el._handleMouseEnter = () => {
+ if (!isTouch) showTooltip(el, el._tooltipText);
+ };
+ el._handleMouseLeave = () => {
+ if (!isTouch) hideTooltip();
+ };
+ el._handleFocus = () => {
+ if (!isTouch) showTooltip(el, el._tooltipText);
+ };
+ el._handleBlur = () => {
+ if (!isTouch) hideTooltip();
+ };
+
+ el._handleTouchStart = () => {
+ isTouch = true;
+ if (touchTimeout) clearTimeout(touchTimeout);
+ touchTimeout = setTimeout(() => {
+ showTooltip(el, el._tooltipText);
+ }, 400); // 400ms long press threshold
+ };
+
+ el._handleTouchEnd = () => {
+ if (touchTimeout) clearTimeout(touchTimeout);
+ hideTooltip();
+ // Block ensuing simulated mouseenter events
+ setTimeout(() => { isTouch = false; }, 500);
+ };
+
+ el._handleTouchCancel = () => {
+ if (touchTimeout) clearTimeout(touchTimeout);
+ hideTooltip();
+ setTimeout(() => { isTouch = false; }, 500);
+ };
+
+ el._handleContextMenu = (e) => {
+ // Prevent the OS context menu if we're showing a tooltip via long press
+ if (isTouch && tooltipState.isVisible && tooltipState.text === el._tooltipText) {
+ e.preventDefault();
+ }
+ };
+
+ el.addEventListener('mouseenter', el._handleMouseEnter);
+ el.addEventListener('mouseleave', el._handleMouseLeave);
+ el.addEventListener('focus', el._handleFocus);
+ el.addEventListener('blur', el._handleBlur);
+
+ el.addEventListener('touchstart', el._handleTouchStart, { passive: true });
+ el.addEventListener('touchend', el._handleTouchEnd);
+ el.addEventListener('touchmove', el._handleTouchCancel, { passive: true });
+ el.addEventListener('touchcancel', el._handleTouchCancel);
+ el.addEventListener('contextmenu', el._handleContextMenu);
},
updated(el, binding) {
el._tooltipText = binding.value;
@@ -19,10 +68,17 @@ export const tooltipDirective = {
}
},
unmounted(el) {
- el.removeEventListener('mouseenter', () => showTooltip(el, el._tooltipText));
- el.removeEventListener('mouseleave', hideTooltip);
- el.removeEventListener('focus', () => showTooltip(el, el._tooltipText));
- el.removeEventListener('blur', hideTooltip);
+ if (el._handleMouseEnter) {
+ el.removeEventListener('mouseenter', el._handleMouseEnter);
+ el.removeEventListener('mouseleave', el._handleMouseLeave);
+ el.removeEventListener('focus', el._handleFocus);
+ el.removeEventListener('blur', el._handleBlur);
+ el.removeEventListener('touchstart', el._handleTouchStart);
+ el.removeEventListener('touchend', el._handleTouchEnd);
+ el.removeEventListener('touchmove', el._handleTouchCancel);
+ el.removeEventListener('touchcancel', el._handleTouchCancel);
+ el.removeEventListener('contextmenu', el._handleContextMenu);
+ }
hideTooltip();
}
};