Major new version #2
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user