Faster event updates (avoid full re-render)
This commit is contained in:
parent
895bc96899
commit
e50f90f277
@ -87,7 +87,7 @@ const vwm = createVirtualWeekManager({
|
|||||||
contentHeight,
|
contentHeight,
|
||||||
})
|
})
|
||||||
const visibleWeeks = vwm.visibleWeeks
|
const visibleWeeks = vwm.visibleWeeks
|
||||||
const { scheduleWindowUpdate, resetWeeks } = vwm
|
const { scheduleWindowUpdate, resetWeeks, refreshEvents } = vwm
|
||||||
|
|
||||||
// Scroll managers (after scheduleWindowUpdate available)
|
// Scroll managers (after scheduleWindowUpdate available)
|
||||||
const scrollManager = createScrollManager({ viewport, scheduleRebuild: scheduleWindowUpdate })
|
const scrollManager = createScrollManager({ viewport, scheduleRebuild: scheduleWindowUpdate })
|
||||||
@ -395,11 +395,17 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => calendarStore.events,
|
() => calendarStore.events,
|
||||||
() => {
|
() => {
|
||||||
resetWeeks('events')
|
refreshEvents('events')
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Reflect selection & events by rebuilding day objects in-place
|
||||||
|
watch(
|
||||||
|
() => [selection.value.startDate, selection.value.dayCount],
|
||||||
|
() => refreshEvents('selection'),
|
||||||
|
)
|
||||||
|
|
||||||
// Rebuild if viewport height changes (e.g., resize)
|
// Rebuild if viewport height changes (e.g., resize)
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
if (viewport.value) viewportHeight.value = viewport.value.clientHeight
|
if (viewport.value) viewportHeight.value = viewport.value.clientHeight
|
||||||
|
@ -69,17 +69,14 @@ export function createVirtualWeekManager({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < 7; i++) {
|
const collectEventsForDate = (dateStr, curDateObj) => {
|
||||||
const dateStr = toLocalString(cur, DEFAULT_TZ)
|
|
||||||
const storedEvents = []
|
const storedEvents = []
|
||||||
|
|
||||||
for (const ev of calendarStore.events.values()) {
|
for (const ev of calendarStore.events.values()) {
|
||||||
if (!ev.isRepeating && dateStr >= ev.startDate && dateStr <= ev.endDate) {
|
if (!ev.isRepeating && dateStr >= ev.startDate && dateStr <= ev.endDate) {
|
||||||
storedEvents.push(ev)
|
storedEvents.push(ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const dayEvents = [...storedEvents]
|
const dayEvents = [...storedEvents]
|
||||||
// Expand repeating events
|
|
||||||
for (const base of repeatingBases) {
|
for (const base of repeatingBases) {
|
||||||
if (dateStr >= base.startDate && dateStr <= base.endDate) {
|
if (dateStr >= base.startDate && dateStr <= base.endDate) {
|
||||||
dayEvents.push({ ...base, _recurrenceIndex: 0, _baseId: base.id })
|
dayEvents.push({ ...base, _recurrenceIndex: 0, _baseId: base.id })
|
||||||
@ -88,7 +85,7 @@ export function createVirtualWeekManager({
|
|||||||
const baseStart = fromLocalString(base.startDate, DEFAULT_TZ)
|
const baseStart = fromLocalString(base.startDate, DEFAULT_TZ)
|
||||||
const baseEnd = fromLocalString(base.endDate, DEFAULT_TZ)
|
const baseEnd = fromLocalString(base.endDate, DEFAULT_TZ)
|
||||||
const spanDays = Math.max(0, differenceInCalendarDays(baseEnd, baseStart))
|
const spanDays = Math.max(0, differenceInCalendarDays(baseEnd, baseStart))
|
||||||
const currentDate = fromLocalString(dateStr, DEFAULT_TZ)
|
const currentDate = curDateObj
|
||||||
let occurrenceFound = false
|
let occurrenceFound = false
|
||||||
for (let offset = 0; offset <= spanDays && !occurrenceFound; offset++) {
|
for (let offset = 0; offset <= spanDays && !occurrenceFound; offset++) {
|
||||||
const candidateStart = addDays(currentDate, -offset)
|
const candidateStart = addDays(currentDate, -offset)
|
||||||
@ -114,6 +111,12 @@ export function createVirtualWeekManager({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return dayEvents
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
const dateStr = toLocalString(cur, DEFAULT_TZ)
|
||||||
|
const dayEvents = collectEventsForDate(dateStr, fromLocalString(dateStr, DEFAULT_TZ))
|
||||||
const dow = cur.getDay()
|
const dow = cur.getDay()
|
||||||
const isFirst = cur.getDate() === 1
|
const isFirst = cur.getDate() === 1
|
||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
@ -281,6 +284,77 @@ export function createVirtualWeekManager({
|
|||||||
scheduleWindowUpdate(reason)
|
scheduleWindowUpdate(reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reflective update of only events inside currently visible weeks (keeps week objects stable)
|
||||||
|
function refreshEvents(reason = 'events-refresh') {
|
||||||
|
if (!visibleWeeks.value.length) return
|
||||||
|
const repeatingBases = []
|
||||||
|
if (calendarStore.events) {
|
||||||
|
for (const ev of calendarStore.events.values()) if (ev.isRepeating) repeatingBases.push(ev)
|
||||||
|
}
|
||||||
|
const selStart = selection.value.startDate
|
||||||
|
const selCount = selection.value.dayCount
|
||||||
|
const selEnd = selStart && selCount > 0 ? addDaysStr(selStart, selCount - 1) : null
|
||||||
|
for (const week of visibleWeeks.value) {
|
||||||
|
for (const day of week.days) {
|
||||||
|
const dateStr = day.date
|
||||||
|
// Update selection flag
|
||||||
|
if (selStart && selEnd) day.isSelected = dateStr >= selStart && dateStr <= selEnd
|
||||||
|
else day.isSelected = false
|
||||||
|
// Rebuild events list for this day
|
||||||
|
const storedEvents = []
|
||||||
|
for (const ev of calendarStore.events.values()) {
|
||||||
|
if (!ev.isRepeating && dateStr >= ev.startDate && dateStr <= ev.endDate) {
|
||||||
|
storedEvents.push(ev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const dayEvents = [...storedEvents]
|
||||||
|
for (const base of repeatingBases) {
|
||||||
|
if (dateStr >= base.startDate && dateStr <= base.endDate) {
|
||||||
|
dayEvents.push({ ...base, _recurrenceIndex: 0, _baseId: base.id })
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const baseStart = fromLocalString(base.startDate, DEFAULT_TZ)
|
||||||
|
const baseEnd = fromLocalString(base.endDate, DEFAULT_TZ)
|
||||||
|
const spanDays = Math.max(0, differenceInCalendarDays(baseEnd, baseStart))
|
||||||
|
const currentDate = fromLocalString(dateStr, DEFAULT_TZ)
|
||||||
|
let occurrenceFound = false
|
||||||
|
for (let offset = 0; offset <= spanDays && !occurrenceFound; offset++) {
|
||||||
|
const candidateStart = addDays(currentDate, -offset)
|
||||||
|
const candidateStartStr = toLocalString(candidateStart, DEFAULT_TZ)
|
||||||
|
const occurrenceIndex = getOccurrenceIndex(base, candidateStartStr, DEFAULT_TZ)
|
||||||
|
if (occurrenceIndex !== null) {
|
||||||
|
const virtualEndDate = getVirtualOccurrenceEndDate(
|
||||||
|
base,
|
||||||
|
candidateStartStr,
|
||||||
|
DEFAULT_TZ,
|
||||||
|
)
|
||||||
|
if (dateStr >= candidateStartStr && dateStr <= virtualEndDate) {
|
||||||
|
const virtualId = base.id + '_v_' + candidateStartStr
|
||||||
|
const alreadyExists = dayEvents.some((ev) => ev.id === virtualId)
|
||||||
|
if (!alreadyExists) {
|
||||||
|
dayEvents.push({
|
||||||
|
...base,
|
||||||
|
id: virtualId,
|
||||||
|
startDate: candidateStartStr,
|
||||||
|
endDate: virtualEndDate,
|
||||||
|
_recurrenceIndex: occurrenceIndex,
|
||||||
|
_baseId: base.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
occurrenceFound = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
day.events = dayEvents
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.debug('[VirtualWeeks] refreshEvents', reason, { weeks: visibleWeeks.value.length })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function goToToday() {
|
function goToToday() {
|
||||||
const top = addDays(new Date(calendarStore.now), -21)
|
const top = addDays(new Date(calendarStore.now), -21)
|
||||||
const targetWeekIndex = getWeekIndex(top)
|
const targetWeekIndex = getWeekIndex(top)
|
||||||
@ -300,6 +374,7 @@ export function createVirtualWeekManager({
|
|||||||
scheduleWindowUpdate,
|
scheduleWindowUpdate,
|
||||||
resetWeeks,
|
resetWeeks,
|
||||||
updateVisibleWeeks,
|
updateVisibleWeeks,
|
||||||
|
refreshEvents,
|
||||||
getWeekIndex,
|
getWeekIndex,
|
||||||
getFirstDayForVirtualWeek,
|
getFirstDayForVirtualWeek,
|
||||||
goToToday,
|
goToToday,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user