Implement event/date search bar
This commit is contained in:
1 parent
367072a8a2
commit
825e3e2b73
5 files changed
+616
-312
No files matched your search
@@ -139,6 +139,68 @@ export function getDate(event, n, timeZone = DEFAULT_TZ) {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Return nearest occurrence (past or future) relative to a reference date (date-string yyyy-MM-dd).
|
||||
* Falls back to first/last when reference lies before first or after last (bounded by cap).
|
||||
* Returns { n, dateStr } or null if no recurrence / invalid.
|
||||
*/
|
||||
export function getNearestOccurrence(event, referenceDateStr, timeZone = DEFAULT_TZ, cap = 5000) {
|
||||
if (!event) return null
|
||||
if (!event.recur) return { n: 0, dateStr: event.startDate }
|
||||
const { recur } = event
|
||||
if (!recur || !['weeks', 'months'].includes(recur.freq)) return { n: 0, dateStr: event.startDate }
|
||||
const refDate = fromLocalString(referenceDateStr, timeZone)
|
||||
const baseDate = fromLocalString(event.startDate, timeZone)
|
||||
if (refDate <= baseDate) return { n: 0, dateStr: event.startDate }
|
||||
const maxCount = recur.count === 'unlimited' ? cap : Math.min(parseInt(recur.count, 10) || 0, cap)
|
||||
if (maxCount <= 0) return null
|
||||
let low = 0
|
||||
let high = maxCount - 1
|
||||
let candidateGE = null
|
||||
while (low <= high) {
|
||||
const mid = (low + high) >> 1
|
||||
const midStr = getDate(event, mid, timeZone)
|
||||
if (!midStr) {
|
||||
// invalid mid (should rarely happen) shrink high
|
||||
high = mid - 1
|
||||
continue
|
||||
}
|
||||
const midDate = fromLocalString(midStr, timeZone)
|
||||
if (midDate >= refDate) {
|
||||
candidateGE = { n: mid, dateStr: midStr, date: midDate }
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
let candidateLT = null
|
||||
if (candidateGE) {
|
||||
const prevN = candidateGE.n - 1
|
||||
if (prevN >= 0) {
|
||||
const prevStr = getDate(event, prevN, timeZone)
|
||||
if (prevStr) {
|
||||
candidateLT = { n: prevN, dateStr: prevStr, date: fromLocalString(prevStr, timeZone) }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// All occurrences earlier than ref
|
||||
const lastN = maxCount - 1
|
||||
const lastStr = getDate(event, lastN, timeZone)
|
||||
if (lastStr)
|
||||
candidateLT = { n: lastN, dateStr: lastStr, date: fromLocalString(lastStr, timeZone) }
|
||||
}
|
||||
if (candidateGE && candidateLT) {
|
||||
const diffGE = candidateGE.date - refDate
|
||||
const diffLT = refDate - candidateLT.date
|
||||
return diffLT <= diffGE
|
||||
? { n: candidateLT.n, dateStr: candidateLT.dateStr }
|
||||
: { n: candidateGE.n, dateStr: candidateGE.dateStr }
|
||||
}
|
||||
if (candidateGE) return { n: candidateGE.n, dateStr: candidateGE.dateStr }
|
||||
if (candidateLT) return { n: candidateLT.n, dateStr: candidateLT.dateStr }
|
||||
return null
|
||||
}
|
||||
|
||||
export function buildDayEvents(events, dateStr, timeZone = DEFAULT_TZ) {
|
||||
const date = fromLocalString(dateStr, timeZone)
|
||||
const out = []
|
||||
|
||||
Reference in new issue
Block a user