front: исправлен баг перемещения блоков
build-and-deploy / build-and-deploy (push) Successful in 20m21s

This commit is contained in:
Kayashov.SM
2026-09-08 16:05:42 +04:00
parent 12dc0a4725
commit 46a5cebd54
2 changed files with 31 additions and 9 deletions
+17 -1
View File
@@ -153,7 +153,23 @@ export default function Timeline({
dragRef.current = null
setDragPreview(null)
if (drag && preview && preview.size > 0) {
onCommit(preview, drag.mode)
// Простой клик (pointerdown+pointerup без реального перетаскивания, либо
// движение мыши, округлившееся до 0 минут) не должен попадать в
// несохранённые изменения - beginDrag заранее кладёт в preview сам
// редактируемый блок с ЕГО ЖЕ текущими start/end (нужно для подсветки
// "тянущегося" блока с первого кадра), и если движения так и не было,
// preview долетает до сюда без единого реального изменения. Коммитим
// только те записи, где start/end реально отличаются от исходных.
const changed = new Map()
for (const [id, { start, end }] of preview) {
const original = itemsRef.current.find((it) => it.id === id)
if (!original || original.start !== start || original.end !== end) {
changed.set(id, { start, end })
}
}
if (changed.size > 0) {
onCommit(changed, drag.mode)
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [onCommit])
+14 -8
View File
@@ -133,12 +133,16 @@ export function computeCascade(items, id, mode, proposedStart, proposedEnd, { ca
let start = proposedStart
let end = proposedEnd
if (startChanged && prev) {
// Без каскада (или если предыдущий блок locked) предыдущий никто не
// подвинет/не растянет - значит, нельзя залезать поверх его занятого времени.
// С каскадом ограничение мягче: только не раньше НАЧАЛА предыдущего блока -
// его конец мы всё равно сейчас подтянем следующим шагом.
const prevIsAnchor = !cascadeEnabled || prev.locked
if (startChanged && prev && !prev.locked) {
// FIXED-блоки НЕ считаются "стеной" для редактируемого блока - с ними
// разрешено визуально пересекаться (раскладка по колонкам), поэтому
// ограничение по предыдущему блоку действует только когда сам предыдущий
// блок не locked. Без каскада предыдущий (не locked) блок никто не
// подвинет/не растянет - значит, нельзя залезать поверх его занятого
// времени. С каскадом ограничение мягче: только не раньше НАЧАЛА
// предыдущего блока - его конец мы всё равно сейчас подтянем следующим
// шагом.
const prevIsAnchor = !cascadeEnabled
const floor = prevIsAnchor ? prev.end : prev.start
if (start < floor) {
const delta = floor - start
@@ -164,8 +168,10 @@ export function computeCascade(items, id, mode, proposedStart, proposedEnd, { ca
result.set(it.id, { start: it.start + delta, end: it.end + delta })
}
}
} else if (next && end > next.start) {
// Без каскада не подвигаем следующий блок, но и не даём на него залезть.
} else if (next && !next.locked && end > next.start) {
// Без каскада не подвигаем следующий блок, но и не даём на него залезть -
// если только следующий блок сам не FIXED: с FIXED пересечение допустимо
// (раскладка по колонкам), он тут не "стена".
end = next.start
result.set(id, { start, end })
}