Restored correct function on event splitting by drag.

This commit is contained in:
Leo Vasanko 2025-08-25 21:09:55 -06:00
parent 2798f4bdcb
commit e15f4aadca
2 changed files with 67 additions and 23 deletions

View File

@ -167,6 +167,24 @@ function startLocalDrag(init, evt) {
else anchorOffset = daysInclusive(init.startDate, init.anchorDate) - 1 else anchorOffset = daysInclusive(init.startDate, init.anchorDate) - 1
} }
// Capture original repeating pattern & weekday (for weekly repeats) so we can rotate relative to original
let originalWeekday = null
let originalPattern = null
if (init.mode === 'move') {
try {
originalWeekday = new Date(init.startDate + 'T00:00:00').getDay()
const baseEv = store.getEventById(init.id)
if (
baseEv &&
baseEv.isRepeating &&
baseEv.repeat === 'weeks' &&
Array.isArray(baseEv.repeatWeekdays)
) {
originalPattern = [...baseEv.repeatWeekdays]
}
} catch {}
}
dragState.value = { dragState.value = {
...init, ...init,
anchorOffset, anchorOffset,
@ -174,6 +192,9 @@ function startLocalDrag(init, evt) {
eventMoved: false, eventMoved: false,
tentativeStart: init.startDate, tentativeStart: init.startDate,
tentativeEnd: init.endDate, tentativeEnd: init.endDate,
originalWeekday,
originalPattern,
realizedId: null, // for virtual occurrence converted to real during drag
} }
// Begin compound history session (single snapshot after drag completes) // Begin compound history session (single snapshot after drag completes)
@ -238,8 +259,41 @@ function onDragPointerMove(e) {
if (ns === st.tentativeStart && ne === st.tentativeEnd) return if (ns === st.tentativeStart && ne === st.tentativeEnd) return
st.tentativeStart = ns st.tentativeStart = ns
st.tentativeEnd = ne st.tentativeEnd = ne
// Real-time update only for non-virtual events (avoid repeated split operations) if (st.mode === 'move') {
if (!st.isVirtual) { if (st.isVirtual) {
// On first movement convert virtual occurrence into a real new event (split series)
if (!st.realizedId) {
const newId = store.splitMoveVirtualOccurrence(st.id, st.startDate, ns, ne)
if (newId) {
st.realizedId = newId
st.id = newId
st.isVirtual = false
} else {
return
}
} else {
// Subsequent moves: update range without rotating pattern automatically
store.setEventRange(st.id, ns, ne, { mode: 'move', rotatePattern: false })
}
} else {
// Normal non-virtual move; rotate handled in setEventRange
store.setEventRange(st.id, ns, ne, { mode: 'move', rotatePattern: false })
}
// Manual rotation relative to original pattern (keeps pattern anchored to initially grabbed weekday)
if (st.originalPattern && st.originalWeekday != null) {
try {
const currentWeekday = new Date(ns + 'T00:00:00').getDay()
const shift = currentWeekday - st.originalWeekday
const rotated = store._rotateWeekdayPattern([...st.originalPattern], shift)
const ev = store.getEventById(st.id)
if (ev && ev.repeat === 'weeks') {
ev.repeatWeekdays = rotated
store.touchEvents()
}
} catch {}
}
} else if (!st.isVirtual) {
// Resizes on real events update immediately
applyRangeDuringDrag( applyRangeDuringDrag(
{ id: st.id, isVirtual: st.isVirtual, mode: st.mode, startDate: ns, endDate: ne }, { id: st.id, isVirtual: st.isVirtual, mode: st.mode, startDate: ns, endDate: ne },
ns, ns,

View File

@ -37,6 +37,10 @@ export const useCalendarStore = defineStore('calendar', {
}, },
}), }),
actions: { actions: {
_rotateWeekdayPattern(pattern, shift) {
const k = (7 - (shift % 7)) % 7
return pattern.slice(k).concat(pattern.slice(0, k))
},
_resolveCountry(code) { _resolveCountry(code) {
if (!code || code !== 'auto') return code if (!code || code !== 'auto') return code
const locale = navigator.language || navigator.languages?.[0] const locale = navigator.language || navigator.languages?.[0]
@ -264,7 +268,7 @@ export const useCalendarStore = defineStore('calendar', {
this.notifyEventsChanged() this.notifyEventsChanged()
}, },
setEventRange(eventId, newStartStr, newEndStr, { mode = 'auto' } = {}) { setEventRange(eventId, newStartStr, newEndStr, { mode = 'auto', rotatePattern = true } = {}) {
const snapshot = this.events.get(eventId) const snapshot = this.events.get(eventId)
if (!snapshot) return if (!snapshot) return
const prevStart = fromLocalString(snapshot.startDate, DEFAULT_TZ) const prevStart = fromLocalString(snapshot.startDate, DEFAULT_TZ)
@ -283,6 +287,7 @@ export const useCalendarStore = defineStore('calendar', {
) )
if ( if (
mode === 'move' && mode === 'move' &&
rotatePattern &&
snapshot.isRepeating && snapshot.isRepeating &&
snapshot.repeat === 'weeks' && snapshot.repeat === 'weeks' &&
Array.isArray(snapshot.repeatWeekdays) Array.isArray(snapshot.repeatWeekdays)
@ -291,15 +296,7 @@ export const useCalendarStore = defineStore('calendar', {
const newDow = newStart.getDay() const newDow = newStart.getDay()
const shift = newDow - oldDow const shift = newDow - oldDow
if (shift !== 0) { if (shift !== 0) {
const rotated = [false, false, false, false, false, false, false] snapshot.repeatWeekdays = this._rotateWeekdayPattern(snapshot.repeatWeekdays, shift)
for (let i = 0; i < 7; i++) {
if (snapshot.repeatWeekdays[i]) {
let ni = (i + shift) % 7
if (ni < 0) ni += 7
rotated[ni] = true
}
}
snapshot.repeatWeekdays = rotated
} }
} }
this.events.set(eventId, { ...snapshot, isSpanning: snapshot.startDate < snapshot.endDate }) this.events.set(eventId, { ...snapshot, isSpanning: snapshot.startDate < snapshot.endDate })
@ -314,7 +311,7 @@ export const useCalendarStore = defineStore('calendar', {
const baseStart = fromLocalString(base.startDate, DEFAULT_TZ) const baseStart = fromLocalString(base.startDate, DEFAULT_TZ)
if (occurrenceDate <= baseStart) { if (occurrenceDate <= baseStart) {
this.setEventRange(baseId, newStartStr, newEndStr, { mode: 'move' }) this.setEventRange(baseId, newStartStr, newEndStr, { mode: 'move' })
return return baseId
} }
let keptOccurrences = 0 let keptOccurrences = 0
if (base.repeat === 'weeks') { if (base.repeat === 'weeks') {
@ -359,18 +356,10 @@ export const useCalendarStore = defineStore('calendar', {
const newWeekday = fromLocalString(newStartStr, DEFAULT_TZ).getDay() const newWeekday = fromLocalString(newStartStr, DEFAULT_TZ).getDay()
const shift = newWeekday - origWeekday const shift = newWeekday - origWeekday
if (shift !== 0) { if (shift !== 0) {
const rotated = [false, false, false, false, false, false, false] repeatWeekdays = this._rotateWeekdayPattern(base.repeatWeekdays, shift)
for (let i = 0; i < 7; i++) {
if (base.repeatWeekdays[i]) {
let ni = (i + shift) % 7
if (ni < 0) ni += 7
rotated[ni] = true
}
}
repeatWeekdays = rotated
} }
} }
this.createEvent({ const newId = this.createEvent({
title: base.title, title: base.title,
startDate: newStartStr, startDate: newStartStr,
endDate: newEndStr, endDate: newEndStr,
@ -381,6 +370,7 @@ export const useCalendarStore = defineStore('calendar', {
repeatWeekdays, repeatWeekdays,
}) })
this.notifyEventsChanged() this.notifyEventsChanged()
return newId
}, },
splitRepeatSeries(baseId, occurrenceIndex, newStartStr, newEndStr) { splitRepeatSeries(baseId, occurrenceIndex, newStartStr, newEndStr) {