Major new version #2
@ -167,6 +167,24 @@ function startLocalDrag(init, evt) {
|
||||
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 = {
|
||||
...init,
|
||||
anchorOffset,
|
||||
@ -174,6 +192,9 @@ function startLocalDrag(init, evt) {
|
||||
eventMoved: false,
|
||||
tentativeStart: init.startDate,
|
||||
tentativeEnd: init.endDate,
|
||||
originalWeekday,
|
||||
originalPattern,
|
||||
realizedId: null, // for virtual occurrence converted to real during drag
|
||||
}
|
||||
|
||||
// Begin compound history session (single snapshot after drag completes)
|
||||
@ -238,8 +259,41 @@ function onDragPointerMove(e) {
|
||||
if (ns === st.tentativeStart && ne === st.tentativeEnd) return
|
||||
st.tentativeStart = ns
|
||||
st.tentativeEnd = ne
|
||||
// Real-time update only for non-virtual events (avoid repeated split operations)
|
||||
if (!st.isVirtual) {
|
||||
if (st.mode === 'move') {
|
||||
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(
|
||||
{ id: st.id, isVirtual: st.isVirtual, mode: st.mode, startDate: ns, endDate: ne },
|
||||
ns,
|
||||
|
@ -37,6 +37,10 @@ export const useCalendarStore = defineStore('calendar', {
|
||||
},
|
||||
}),
|
||||
actions: {
|
||||
_rotateWeekdayPattern(pattern, shift) {
|
||||
const k = (7 - (shift % 7)) % 7
|
||||
return pattern.slice(k).concat(pattern.slice(0, k))
|
||||
},
|
||||
_resolveCountry(code) {
|
||||
if (!code || code !== 'auto') return code
|
||||
const locale = navigator.language || navigator.languages?.[0]
|
||||
@ -264,7 +268,7 @@ export const useCalendarStore = defineStore('calendar', {
|
||||
this.notifyEventsChanged()
|
||||
},
|
||||
|
||||
setEventRange(eventId, newStartStr, newEndStr, { mode = 'auto' } = {}) {
|
||||
setEventRange(eventId, newStartStr, newEndStr, { mode = 'auto', rotatePattern = true } = {}) {
|
||||
const snapshot = this.events.get(eventId)
|
||||
if (!snapshot) return
|
||||
const prevStart = fromLocalString(snapshot.startDate, DEFAULT_TZ)
|
||||
@ -283,6 +287,7 @@ export const useCalendarStore = defineStore('calendar', {
|
||||
)
|
||||
if (
|
||||
mode === 'move' &&
|
||||
rotatePattern &&
|
||||
snapshot.isRepeating &&
|
||||
snapshot.repeat === 'weeks' &&
|
||||
Array.isArray(snapshot.repeatWeekdays)
|
||||
@ -291,15 +296,7 @@ export const useCalendarStore = defineStore('calendar', {
|
||||
const newDow = newStart.getDay()
|
||||
const shift = newDow - oldDow
|
||||
if (shift !== 0) {
|
||||
const rotated = [false, false, false, false, false, false, false]
|
||||
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
|
||||
snapshot.repeatWeekdays = this._rotateWeekdayPattern(snapshot.repeatWeekdays, shift)
|
||||
}
|
||||
}
|
||||
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)
|
||||
if (occurrenceDate <= baseStart) {
|
||||
this.setEventRange(baseId, newStartStr, newEndStr, { mode: 'move' })
|
||||
return
|
||||
return baseId
|
||||
}
|
||||
let keptOccurrences = 0
|
||||
if (base.repeat === 'weeks') {
|
||||
@ -359,18 +356,10 @@ export const useCalendarStore = defineStore('calendar', {
|
||||
const newWeekday = fromLocalString(newStartStr, DEFAULT_TZ).getDay()
|
||||
const shift = newWeekday - origWeekday
|
||||
if (shift !== 0) {
|
||||
const rotated = [false, false, false, false, false, false, false]
|
||||
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
|
||||
repeatWeekdays = this._rotateWeekdayPattern(base.repeatWeekdays, shift)
|
||||
}
|
||||
}
|
||||
this.createEvent({
|
||||
const newId = this.createEvent({
|
||||
title: base.title,
|
||||
startDate: newStartStr,
|
||||
endDate: newEndStr,
|
||||
@ -381,6 +370,7 @@ export const useCalendarStore = defineStore('calendar', {
|
||||
repeatWeekdays,
|
||||
})
|
||||
this.notifyEventsChanged()
|
||||
return newId
|
||||
},
|
||||
|
||||
splitRepeatSeries(baseId, occurrenceIndex, newStartStr, newEndStr) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user