Fix display of repeated multi day events
This commit is contained in:
parent
07b22fa885
commit
1b1a95da1d
@ -62,41 +62,51 @@ function generateRepeatOccurrencesForDate(targetDateStr) {
|
||||
|
||||
if (baseEvent.repeat === 'weeks') {
|
||||
const repeatWeekdays = baseEvent.repeatWeekdays
|
||||
const targetWeekday = targetDate.getDay()
|
||||
if (!repeatWeekdays[targetWeekday]) continue
|
||||
if (targetDate < baseStartDate) continue
|
||||
const maxOccurrences =
|
||||
baseEvent.repeatCount === 'unlimited' ? Infinity : parseInt(baseEvent.repeatCount, 10)
|
||||
const interval = baseEvent.repeatInterval || 1
|
||||
const maxOccurrences = baseEvent.repeatCount === 'unlimited' ? Infinity : parseInt(baseEvent.repeatCount, 10)
|
||||
if (maxOccurrences === 0) continue
|
||||
// Count occurrences from start up to (and including) target
|
||||
const interval = baseEvent.repeatInterval || 1
|
||||
const msPerDay = 24*60*60*1000
|
||||
|
||||
// Determine if targetDate lies within some occurrence span. We look backwards up to spanDays to find a start day.
|
||||
let occStart = null
|
||||
for (let back=0; back<=spanDays; back++) {
|
||||
const cand = new Date(targetDate)
|
||||
cand.setDate(cand.getDate() - back)
|
||||
if (cand < baseStartDate) break
|
||||
const daysDiff = Math.floor((cand - baseStartDate)/msPerDay)
|
||||
const weeksDiff = Math.floor(daysDiff / 7)
|
||||
if (weeksDiff % interval !== 0) continue
|
||||
if (repeatWeekdays[cand.getDay()]) {
|
||||
// candidate start must produce span covering targetDate
|
||||
const candEnd = new Date(cand)
|
||||
candEnd.setDate(candEnd.getDate() + spanDays)
|
||||
if (targetDate <= candEnd) {
|
||||
occStart = cand
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!occStart) continue
|
||||
// Skip base occurrence if this is within its span (base already physically stored)
|
||||
if (occStart.getTime() === baseStartDate.getTime()) continue
|
||||
// Compute occurrence index (number of previous start days)
|
||||
let occIdx = 0
|
||||
// Determine the week distance from baseStartDate to targetDate
|
||||
const msPerDay = 24 * 60 * 60 * 1000
|
||||
const daysDiff = Math.floor((targetDate - baseStartDate) / msPerDay)
|
||||
const weeksDiff = Math.floor(daysDiff / 7)
|
||||
if (weeksDiff % interval !== 0) continue
|
||||
// Count occurrences only among valid weeks and selected weekdays
|
||||
const cursor = new Date(baseStartDate)
|
||||
while (cursor < targetDate && occIdx < maxOccurrences) {
|
||||
const cDaysDiff = Math.floor((cursor - baseStartDate) / msPerDay)
|
||||
while (cursor < occStart && occIdx < maxOccurrences) {
|
||||
const cDaysDiff = Math.floor((cursor - baseStartDate)/msPerDay)
|
||||
const cWeeksDiff = Math.floor(cDaysDiff / 7)
|
||||
if (cWeeksDiff % interval === 0 && repeatWeekdays[cursor.getDay()]) occIdx++
|
||||
cursor.setDate(cursor.getDate() + 1)
|
||||
}
|
||||
if (targetDate.getTime() === baseStartDate.getTime()) {
|
||||
// skip base occurrence
|
||||
continue
|
||||
cursor.setDate(cursor.getDate()+1)
|
||||
}
|
||||
if (occIdx >= maxOccurrences) continue
|
||||
const occStart = new Date(targetDate)
|
||||
const occEnd = new Date(occStart)
|
||||
occEnd.setDate(occStart.getDate() + spanDays)
|
||||
const occStartStr = toLocalString(occStart)
|
||||
const occEndStr = toLocalString(occEnd)
|
||||
occurrences.push({
|
||||
...baseEvent,
|
||||
id: `${baseEvent.id}_repeat_${occIdx}_${targetWeekday}`,
|
||||
id: `${baseEvent.id}_repeat_${occIdx}_${occStart.getDay()}`,
|
||||
startDate: occStartStr,
|
||||
endDate: occEndStr,
|
||||
isRepeatOccurrence: true,
|
||||
@ -123,12 +133,15 @@ function generateRepeatOccurrencesForDate(targetDateStr) {
|
||||
if (maxOccurrences === 0) continue
|
||||
const i = intervalsPassed
|
||||
if (i >= maxOccurrences) continue
|
||||
// Skip base occurrence
|
||||
if (i === 0) continue
|
||||
const currentStart = new Date(baseStartDate)
|
||||
currentStart.setMonth(baseStartDate.getMonth() + i)
|
||||
const currentEnd = new Date(currentStart)
|
||||
currentEnd.setDate(currentStart.getDate() + spanDays)
|
||||
// If target day lies within base (i===0) we skip because base is stored already
|
||||
if (i === 0) {
|
||||
// only skip if targetDate within base span
|
||||
if (targetDate >= baseStartDate && targetDate <= baseEndDate) continue
|
||||
}
|
||||
const currentStartStr = toLocalString(currentStart)
|
||||
const currentEndStr = toLocalString(currentEnd)
|
||||
if (currentStartStr <= targetDateStr && targetDateStr <= currentEndStr) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user