fix(ui): modal drag + removed startDrag func (#2430)
* fixed * removed legacy startDrag fc, unified modal dragging * fixes post feedback
This commit is contained in:
@@ -13,6 +13,7 @@ import chatModule from './js/chat.js';
|
||||
import compareModule from './js/compare/index.js';
|
||||
import documentModule from './js/document.js';
|
||||
import searchChatModule from './js/search-chat.js';
|
||||
import { makeWindowDraggable } from './js/windowDrag.js';
|
||||
import markdownModule from './js/markdown.js';
|
||||
import chatRenderer from './js/chatRenderer.js';
|
||||
import sessionModule from './js/sessions.js';
|
||||
@@ -2683,18 +2684,27 @@ function initializeEventListeners() {
|
||||
// Apply saved visibility on load
|
||||
applyUIVis(loadUIVis());
|
||||
|
||||
// Generic draggable for all .modal elements
|
||||
const _sharedDragModalIds = new Set(['settings-modal']);
|
||||
try { document.querySelectorAll('.modal').forEach(m => {
|
||||
if (_sharedDragModalIds.has(m.id)) return;
|
||||
// The only two modals without a per-module makeWindowDraggable call. Wire
|
||||
// them onto the shared helper, drag-only, to match their old behavior.
|
||||
try {
|
||||
['custom-preset-modal', 'rename-session-modal'].forEach((id) => {
|
||||
const m = document.getElementById(id);
|
||||
if (!m) return;
|
||||
const content = m.querySelector('.modal-content');
|
||||
const header = m.querySelector('.modal-header');
|
||||
if (!content || !header) return;
|
||||
let dragX, dragY, startLeft, startTop, dragging = false;
|
||||
|
||||
// Reset to flex-centered position each time modal opens
|
||||
makeWindowDraggable(m, {
|
||||
content, header,
|
||||
skipSelector: '.close-btn',
|
||||
enableDock: false,
|
||||
enableResize: false,
|
||||
});
|
||||
// Re-center on open (these persist in the DOM). Guard on the
|
||||
// hidden→visible edge so it never fires mid-drag.
|
||||
let wasHidden = m.classList.contains('hidden');
|
||||
new MutationObserver(() => {
|
||||
if (!m.classList.contains('hidden')) {
|
||||
const isHidden = m.classList.contains('hidden');
|
||||
if (wasHidden && !isHidden) {
|
||||
content.style.position = '';
|
||||
content.style.left = '';
|
||||
content.style.top = '';
|
||||
@@ -2702,63 +2712,10 @@ function initializeEventListeners() {
|
||||
content.style.bottom = '';
|
||||
content.style.margin = '';
|
||||
}
|
||||
wasHidden = isHidden;
|
||||
}).observe(m, { attributes: true, attributeFilter: ['class'] });
|
||||
|
||||
function startDrag(clientX, clientY) {
|
||||
dragging = true;
|
||||
const rect = content.getBoundingClientRect();
|
||||
dragX = clientX; dragY = clientY;
|
||||
startLeft = rect.left; startTop = rect.top;
|
||||
// Switch to fixed so it can be freely positioned
|
||||
content.style.position = 'fixed';
|
||||
content.style.left = startLeft + 'px';
|
||||
content.style.top = startTop + 'px';
|
||||
content.style.margin = '0';
|
||||
}
|
||||
|
||||
header.addEventListener('mousedown', (e) => {
|
||||
if (e.target.closest('.close-btn')) return;
|
||||
e.preventDefault();
|
||||
startDrag(e.clientX, e.clientY);
|
||||
document.addEventListener('mousemove', onDrag);
|
||||
document.addEventListener('mouseup', stopDrag);
|
||||
});
|
||||
function onDrag(e) {
|
||||
if (!dragging) return;
|
||||
content.style.left = (startLeft + e.clientX - dragX) + 'px';
|
||||
content.style.top = (startTop + e.clientY - dragY) + 'px';
|
||||
}
|
||||
function stopDrag() {
|
||||
dragging = false;
|
||||
document.removeEventListener('mousemove', onDrag);
|
||||
document.removeEventListener('mouseup', stopDrag);
|
||||
}
|
||||
|
||||
// Touch drag is desktop-only — on mobile, modals are bottom sheets and
|
||||
// ui.js handles swipe-down-to-dismiss. Attaching this listener fights
|
||||
// the swipe-dismiss gesture.
|
||||
if (window.innerWidth > 768) {
|
||||
header.addEventListener('touchstart', (e) => {
|
||||
if (e.target.closest('.close-btn')) return;
|
||||
const t = e.touches[0];
|
||||
startDrag(t.clientX, t.clientY);
|
||||
document.addEventListener('touchmove', onTouchDrag, { passive: false });
|
||||
document.addEventListener('touchend', stopTouchDrag);
|
||||
});
|
||||
}
|
||||
function onTouchDrag(e) {
|
||||
if (!dragging) return;
|
||||
e.preventDefault();
|
||||
const t = e.touches[0];
|
||||
content.style.left = (startLeft + t.clientX - dragX) + 'px';
|
||||
content.style.top = (startTop + t.clientY - dragY) + 'px';
|
||||
}
|
||||
function stopTouchDrag() {
|
||||
dragging = false;
|
||||
document.removeEventListener('touchmove', onTouchDrag);
|
||||
document.removeEventListener('touchend', stopTouchDrag);
|
||||
}
|
||||
}); } catch(e) { console.error('Modal drag init error:', e); }
|
||||
} catch (e) { console.error('Dialog drag init error:', e); }
|
||||
})();
|
||||
|
||||
// ── Modal minimize → dock ──
|
||||
|
||||
@@ -149,6 +149,13 @@ export function makeWindowDraggable(modal, options = {}) {
|
||||
const _startDrag = (cx, cy) => {
|
||||
dragging = true;
|
||||
if (modal) modal.classList.add('modal-dragging');
|
||||
// Cancel any in-flight open animation so we don't pin a mid-animation
|
||||
// rect and then jump once the animation settles.
|
||||
try {
|
||||
content.getAnimations()
|
||||
.filter(a => a.playState !== 'finished')
|
||||
.forEach(a => a.cancel());
|
||||
} catch (_) {}
|
||||
const rect = content.getBoundingClientRect();
|
||||
if (onDragStart) {
|
||||
try { onDragStart({ rect, cx, cy }); } catch (_) {}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// - Other static assets (images/fonts/libs): cache-first with bg refresh.
|
||||
// - API / non-GET: never cached.
|
||||
// Bump CACHE_NAME whenever the precache list or SW logic changes.
|
||||
const CACHE_NAME = 'odysseus-v326';
|
||||
const CACHE_NAME = 'odysseus-v327';
|
||||
|
||||
// Core shell precached on install so repeat opens are instant without any
|
||||
// network wait. Keep this list in sync with the <script type="module"> tags
|
||||
|
||||
Reference in New Issue
Block a user