fix: lora entry selection and strength display issues

- Fix lora entry click-to-select broken after pointer events refactoring
  - Only stopPropagation() after pointer moves beyond 3 pixel threshold
  - This allows click events to fire on lora entries for selection
  - Applied to all drag handlers: initDrag, initHeaderDrag, initReorderDrag

- Fix strength value display to always show 2 decimal places
  - Use toFixed(2) when updating strength input during drag
  - Ensures consistent display (e.g., "1.00" instead of "1", "1.40" instead of "1.4")
This commit is contained in:
Will Miao
2026-01-15 19:04:56 +08:00
parent c5b597dc89
commit bd0dfd4ef5

View File

@@ -116,6 +116,7 @@ export function initDrag(
let initialX = 0; let initialX = 0;
let initialStrength = 0; let initialStrength = 0;
let currentDragElement = null; let currentDragElement = null;
let hasMoved = false;
const { onDragStart, onDragEnd } = dragCallbacks; const { onDragStart, onDragEnd } = dragCallbacks;
// Create a drag handler using pointer events for Vue DOM render mode compatibility // Create a drag handler using pointer events for Vue DOM render mode compatibility
@@ -138,6 +139,7 @@ export function initDrag(
initialX = e.clientX; initialX = e.clientX;
initialStrength = isClipStrength ? loraData.clipStrength : loraData.strength; initialStrength = isClipStrength ? loraData.clipStrength : loraData.strength;
isDragging = true; isDragging = true;
hasMoved = false;
activePointerId = e.pointerId; activePointerId = e.pointerId;
currentDragElement = e.currentTarget; currentDragElement = e.currentTarget;
@@ -145,23 +147,32 @@ export function initDrag(
const target = e.currentTarget; const target = e.currentTarget;
target.setPointerCapture(e.pointerId); target.setPointerCapture(e.pointerId);
// Add class to body to enforce cursor style globally // Prevent text selection
document.body.classList.add('lm-lora-strength-dragging');
if (typeof onDragStart === 'function') {
onDragStart();
}
// Prevent text selection and default behavior
e.preventDefault(); e.preventDefault();
e.stopPropagation();
}); });
dragEl.addEventListener('pointermove', (e) => { dragEl.addEventListener('pointermove', (e) => {
if (!isDragging) return; if (!isDragging) return;
// Stop propagation to prevent canvas from interfering // Track if pointer moved significantly (more than 3 pixels)
if (Math.abs(e.clientX - initialX) > 3) {
hasMoved = true;
}
// Only stop propagation if we've started dragging (moved beyond threshold)
if (hasMoved) {
e.stopPropagation(); e.stopPropagation();
}
// Only process drag if we've moved beyond threshold
if (!hasMoved) return;
// Add class to body to enforce cursor style globally only after drag starts
document.body.classList.add('lm-lora-strength-dragging');
if (typeof onDragStart === 'function') {
onDragStart();
}
// Call the strength adjustment function without updating widget.value during drag // Call the strength adjustment function without updating widget.value during drag
handleStrengthDrag(name, initialStrength, initialX, e, widget, isClipStrength, false); handleStrengthDrag(name, initialStrength, initialX, e, widget, isClipStrength, false);
@@ -173,7 +184,7 @@ export function initDrag(
const loraData = lorasData.find(l => l.name === name); const loraData = lorasData.find(l => l.name === name);
if (loraData) { if (loraData) {
const strengthValue = isClipStrength ? loraData.clipStrength : loraData.strength; const strengthValue = isClipStrength ? loraData.clipStrength : loraData.strength;
strengthInput.value = strengthValue; strengthInput.value = Number(strengthValue).toFixed(2);
} }
} }
@@ -186,7 +197,10 @@ export function initDrag(
const endDrag = (e) => { const endDrag = (e) => {
if (!isDragging) return; if (!isDragging) return;
// Only stop propagation if we actually dragged
if (hasMoved) {
e.stopPropagation(); e.stopPropagation();
}
// Release pointer capture if still have the element // Release pointer capture if still have the element
if (currentDragElement && activePointerId !== null) { if (currentDragElement && activePointerId !== null) {
@@ -197,13 +211,17 @@ export function initDrag(
} }
} }
const wasDragging = hasMoved;
isDragging = false; isDragging = false;
hasMoved = false;
activePointerId = null; activePointerId = null;
currentDragElement = null; currentDragElement = null;
// Remove the class to restore normal cursor behavior // Remove the class to restore normal cursor behavior
document.body.classList.remove('lm-lora-strength-dragging'); document.body.classList.remove('lm-lora-strength-dragging');
// Only call onDragEnd and re-render if we actually dragged
if (wasDragging) {
if (typeof onDragEnd === 'function') { if (typeof onDragEnd === 'function') {
onDragEnd(); onDragEnd();
} }
@@ -212,6 +230,7 @@ export function initDrag(
if (renderFunction) { if (renderFunction) {
renderFunction(widget.value, widget); renderFunction(widget.value, widget);
} }
}
}; };
dragEl.addEventListener('pointerup', endDrag); dragEl.addEventListener('pointerup', endDrag);
@@ -225,6 +244,7 @@ export function initHeaderDrag(headerEl, widget, renderFunction) {
let initialX = 0; let initialX = 0;
let initialStrengths = []; let initialStrengths = [];
let currentHeaderElement = null; let currentHeaderElement = null;
let hasMoved = false;
// Add cursor style to indicate draggable // Add cursor style to indicate draggable
// Create a drag handler using pointer events for Vue DOM render mode compatibility // Create a drag handler using pointer events for Vue DOM render mode compatibility
@@ -246,6 +266,7 @@ export function initHeaderDrag(headerEl, widget, renderFunction) {
})); }));
isDragging = true; isDragging = true;
hasMoved = false;
activePointerId = e.pointerId; activePointerId = e.pointerId;
currentHeaderElement = e.currentTarget; currentHeaderElement = e.currentTarget;
@@ -253,19 +274,29 @@ export function initHeaderDrag(headerEl, widget, renderFunction) {
const target = e.currentTarget; const target = e.currentTarget;
target.setPointerCapture(e.pointerId); target.setPointerCapture(e.pointerId);
// Add class to body to enforce cursor style globally // Prevent text selection
document.body.classList.add('lm-lora-strength-dragging');
// Prevent text selection and default behavior
e.preventDefault(); e.preventDefault();
e.stopPropagation();
}); });
// Handle pointer move for dragging // Handle pointer move for dragging
headerEl.addEventListener('pointermove', (e) => { headerEl.addEventListener('pointermove', (e) => {
if (!isDragging) return; if (!isDragging) return;
// Track if pointer moved significantly (more than 3 pixels)
if (Math.abs(e.clientX - initialX) > 3) {
hasMoved = true;
}
// Only stop propagation if we've started dragging (moved beyond threshold)
if (hasMoved) {
e.stopPropagation(); e.stopPropagation();
}
// Only process drag if we've moved beyond threshold
if (!hasMoved) return;
// Add class to body to enforce cursor style globally only after drag starts
document.body.classList.add('lm-lora-strength-dragging');
// Call the strength adjustment function without updating widget.value during drag // Call the strength adjustment function without updating widget.value during drag
handleAllStrengthsDrag(initialStrengths, initialX, e, widget, false); handleAllStrengthsDrag(initialStrengths, initialX, e, widget, false);
@@ -283,7 +314,10 @@ export function initHeaderDrag(headerEl, widget, renderFunction) {
const endDrag = (e) => { const endDrag = (e) => {
if (!isDragging) return; if (!isDragging) return;
// Only stop propagation if we actually dragged
if (hasMoved) {
e.stopPropagation(); e.stopPropagation();
}
// Release pointer capture if still have the element // Release pointer capture if still have the element
if (currentHeaderElement && activePointerId !== null) { if (currentHeaderElement && activePointerId !== null) {
@@ -294,15 +328,17 @@ export function initHeaderDrag(headerEl, widget, renderFunction) {
} }
} }
const wasDragging = hasMoved;
isDragging = false; isDragging = false;
hasMoved = false;
activePointerId = null; activePointerId = null;
currentHeaderElement = null; currentHeaderElement = null;
// Remove the class to restore normal cursor behavior // Remove the class to restore normal cursor behavior
document.body.classList.remove('lm-lora-strength-dragging'); document.body.classList.remove('lm-lora-strength-dragging');
// Now do a re-render after drag is complete // Only re-render if we actually dragged
if (renderFunction) { if (wasDragging && renderFunction) {
renderFunction(widget.value, widget); renderFunction(widget.value, widget);
} }
}; };
@@ -322,12 +358,13 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
let dropIndicator = null; let dropIndicator = null;
let container = null; let container = null;
let scale = 1; let scale = 1;
let hasMoved = false;
dragHandle.addEventListener('pointerdown', (e) => { dragHandle.addEventListener('pointerdown', (e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation();
isDragging = true; isDragging = true;
hasMoved = false;
activePointerId = e.pointerId; activePointerId = e.pointerId;
draggedElement = dragHandle.closest('.lm-lora-entry'); draggedElement = dragHandle.closest('.lm-lora-entry');
container = draggedElement.parentElement; container = draggedElement.parentElement;
@@ -335,8 +372,24 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
// Capture pointer to receive all subsequent events regardless of stopPropagation // Capture pointer to receive all subsequent events regardless of stopPropagation
const target = e.currentTarget; const target = e.currentTarget;
target.setPointerCapture(e.pointerId); target.setPointerCapture(e.pointerId);
});
// Add dragging class and visual feedback dragHandle.addEventListener('pointermove', (e) => {
if (!isDragging || !draggedElement) return;
// Track if pointer moved significantly (more than 3 pixels vertically)
if (Math.abs(e.movementY) > 3) {
hasMoved = true;
}
// Only stop propagation and process drag if we've moved beyond threshold
if (!hasMoved) return;
// Stop propagation and start drag visuals
e.stopPropagation();
// Add dragging class and visual feedback only after drag starts
if (!dropIndicator) {
draggedElement.classList.add('lm-lora-entry--dragging'); draggedElement.classList.add('lm-lora-entry--dragging');
// Create single drop indicator with absolute positioning // Create single drop indicator with absolute positioning
@@ -355,12 +408,7 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
// Store workflow scale for accurate positioning // Store workflow scale for accurate positioning
scale = app.canvas.ds.scale; scale = app.canvas.ds.scale;
}); }
dragHandle.addEventListener('pointermove', (e) => {
if (!isDragging || !draggedElement || !dropIndicator) return;
e.stopPropagation();
const targetIndex = getDropTargetIndex(container, e.clientY); const targetIndex = getDropTargetIndex(container, e.clientY);
const entries = container.querySelectorAll('.lm-lora-entry, .lm-lora-clip-entry'); const entries = container.querySelectorAll('.lm-lora-entry, .lm-lora-clip-entry');
@@ -396,12 +444,25 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
}); });
dragHandle.addEventListener('pointerup', (e) => { dragHandle.addEventListener('pointerup', (e) => {
// Only stop propagation if we actually dragged
if (hasMoved) {
e.stopPropagation(); e.stopPropagation();
}
// Always reset cursor regardless of isDragging state // Always reset cursor regardless of isDragging state
document.body.classList.remove('lm-lora-reordering'); document.body.classList.remove('lm-lora-reordering');
if (!isDragging || !draggedElement) return; if (!isDragging || !draggedElement) {
// Release pointer capture even if not dragging
const target = e.currentTarget;
if (activePointerId !== null) {
target.releasePointerCapture(activePointerId);
}
isDragging = false;
hasMoved = false;
activePointerId = null;
return;
}
// Release pointer capture // Release pointer capture
const target = e.currentTarget; const target = e.currentTarget;
@@ -409,6 +470,13 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
target.releasePointerCapture(activePointerId); target.releasePointerCapture(activePointerId);
} }
const wasDragging = hasMoved;
isDragging = false;
hasMoved = false;
activePointerId = null;
// Only process reordering if we actually dragged
if (wasDragging) {
const targetIndex = getDropTargetIndex(container, e.clientY); const targetIndex = getDropTargetIndex(container, e.clientY);
// Get current LoRA data // Get current LoRA data
@@ -441,10 +509,9 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
renderFunction(widget.value, widget); renderFunction(widget.value, widget);
} }
} }
}
// Cleanup // Cleanup
isDragging = false;
activePointerId = null;
if (draggedElement) { if (draggedElement) {
draggedElement.classList.remove('lm-lora-entry--dragging'); draggedElement.classList.remove('lm-lora-entry--dragging');
draggedElement = null; draggedElement = null;
@@ -462,12 +529,25 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
}); });
dragHandle.addEventListener('pointercancel', (e) => { dragHandle.addEventListener('pointercancel', (e) => {
// Only stop propagation if we actually dragged
if (hasMoved) {
e.stopPropagation(); e.stopPropagation();
}
// Always reset cursor regardless of isDragging state // Always reset cursor regardless of isDragging state
document.body.classList.remove('lm-lora-reordering'); document.body.classList.remove('lm-lora-reordering');
if (!isDragging || !draggedElement) return; if (!isDragging || !draggedElement) {
// Release pointer capture even if not dragging
const target = e.currentTarget;
if (activePointerId !== null) {
target.releasePointerCapture(activePointerId);
}
isDragging = false;
hasMoved = false;
activePointerId = null;
return;
}
// Release pointer capture // Release pointer capture
const target = e.currentTarget; const target = e.currentTarget;
@@ -475,9 +555,11 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
target.releasePointerCapture(activePointerId); target.releasePointerCapture(activePointerId);
} }
// Cleanup without reordering
isDragging = false; isDragging = false;
hasMoved = false;
activePointerId = null; activePointerId = null;
// Cleanup without reordering
if (draggedElement) { if (draggedElement) {
draggedElement.classList.remove('lm-lora-entry--dragging'); draggedElement.classList.remove('lm-lora-entry--dragging');
draggedElement = null; draggedElement = null;