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') {
|
if (baseEvent.repeat === 'weeks') {
|
||||||
const repeatWeekdays = baseEvent.repeatWeekdays
|
const repeatWeekdays = baseEvent.repeatWeekdays
|
||||||
const targetWeekday = targetDate.getDay()
|
|
||||||
if (!repeatWeekdays[targetWeekday]) continue
|
|
||||||
if (targetDate < baseStartDate) continue
|
if (targetDate < baseStartDate) continue
|
||||||
const maxOccurrences =
|
const maxOccurrences = baseEvent.repeatCount === 'unlimited' ? Infinity : parseInt(baseEvent.repeatCount, 10)
|
||||||
baseEvent.repeatCount === 'unlimited' ? Infinity : parseInt(baseEvent.repeatCount, 10)
|
|
||||||
const interval = baseEvent.repeatInterval || 1
|
|
||||||
if (maxOccurrences === 0) continue
|
if (maxOccurrences === 0) continue
|
||||||
// Count occurrences from start up to (and including) target
|
const interval = baseEvent.repeatInterval || 1
|
||||||
let occIdx = 0
|
|
||||||
// Determine the week distance from baseStartDate to targetDate
|
|
||||||
const msPerDay = 24*60*60*1000
|
const msPerDay = 24*60*60*1000
|
||||||
const daysDiff = Math.floor((targetDate - baseStartDate) / msPerDay)
|
|
||||||
|
// 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)
|
const weeksDiff = Math.floor(daysDiff / 7)
|
||||||
if (weeksDiff % interval !== 0) continue
|
if (weeksDiff % interval !== 0) continue
|
||||||
// Count occurrences only among valid weeks and selected weekdays
|
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
|
||||||
const cursor = new Date(baseStartDate)
|
const cursor = new Date(baseStartDate)
|
||||||
while (cursor < targetDate && occIdx < maxOccurrences) {
|
while (cursor < occStart && occIdx < maxOccurrences) {
|
||||||
const cDaysDiff = Math.floor((cursor - baseStartDate)/msPerDay)
|
const cDaysDiff = Math.floor((cursor - baseStartDate)/msPerDay)
|
||||||
const cWeeksDiff = Math.floor(cDaysDiff / 7)
|
const cWeeksDiff = Math.floor(cDaysDiff / 7)
|
||||||
if (cWeeksDiff % interval === 0 && repeatWeekdays[cursor.getDay()]) occIdx++
|
if (cWeeksDiff % interval === 0 && repeatWeekdays[cursor.getDay()]) occIdx++
|
||||||
cursor.setDate(cursor.getDate()+1)
|
cursor.setDate(cursor.getDate()+1)
|
||||||
}
|
}
|
||||||
if (targetDate.getTime() === baseStartDate.getTime()) {
|
|
||||||
// skip base occurrence
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if (occIdx >= maxOccurrences) continue
|
if (occIdx >= maxOccurrences) continue
|
||||||
const occStart = new Date(targetDate)
|
|
||||||
const occEnd = new Date(occStart)
|
const occEnd = new Date(occStart)
|
||||||
occEnd.setDate(occStart.getDate() + spanDays)
|
occEnd.setDate(occStart.getDate() + spanDays)
|
||||||
const occStartStr = toLocalString(occStart)
|
const occStartStr = toLocalString(occStart)
|
||||||
const occEndStr = toLocalString(occEnd)
|
const occEndStr = toLocalString(occEnd)
|
||||||
occurrences.push({
|
occurrences.push({
|
||||||
...baseEvent,
|
...baseEvent,
|
||||||
id: `${baseEvent.id}_repeat_${occIdx}_${targetWeekday}`,
|
id: `${baseEvent.id}_repeat_${occIdx}_${occStart.getDay()}`,
|
||||||
startDate: occStartStr,
|
startDate: occStartStr,
|
||||||
endDate: occEndStr,
|
endDate: occEndStr,
|
||||||
isRepeatOccurrence: true,
|
isRepeatOccurrence: true,
|
||||||
@ -123,12 +133,15 @@ function generateRepeatOccurrencesForDate(targetDateStr) {
|
|||||||
if (maxOccurrences === 0) continue
|
if (maxOccurrences === 0) continue
|
||||||
const i = intervalsPassed
|
const i = intervalsPassed
|
||||||
if (i >= maxOccurrences) continue
|
if (i >= maxOccurrences) continue
|
||||||
// Skip base occurrence
|
|
||||||
if (i === 0) continue
|
|
||||||
const currentStart = new Date(baseStartDate)
|
const currentStart = new Date(baseStartDate)
|
||||||
currentStart.setMonth(baseStartDate.getMonth() + i)
|
currentStart.setMonth(baseStartDate.getMonth() + i)
|
||||||
const currentEnd = new Date(currentStart)
|
const currentEnd = new Date(currentStart)
|
||||||
currentEnd.setDate(currentStart.getDate() + spanDays)
|
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 currentStartStr = toLocalString(currentStart)
|
||||||
const currentEndStr = toLocalString(currentEnd)
|
const currentEndStr = toLocalString(currentEnd)
|
||||||
if (currentStartStr <= targetDateStr && targetDateStr <= currentEndStr) {
|
if (currentStartStr <= targetDateStr && targetDateStr <= currentEndStr) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user