51 lines
2.1 KiB
JavaScript
51 lines
2.1 KiB
JavaScript
// Decides what a saved schedule needs after the catalog was read again.
|
||
// Runs in the browser; kept free of DOM code so the rules are testable in Node.
|
||
|
||
const escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||
const time = (value) => Date.parse(value || "") || 0;
|
||
|
||
/** "23-БА" matches "23-ЛГ_23-БА.docx" but not "23-БАз" or "123-БА". */
|
||
export function namesGroup(fileName, group) {
|
||
if (!group) return false;
|
||
const base = fileName.replace(/\.docx?$/i, "");
|
||
return new RegExp(
|
||
`(^|[^0-9A-Za-zА-ЯЁа-яё])${escape(group)}(?![0-9A-Za-zА-ЯЁа-яё])`,
|
||
"iu",
|
||
).test(base);
|
||
}
|
||
|
||
/**
|
||
* changed: the same document was republished, or parsed by an older parser than the server's
|
||
* (`catalog.parserVersion`, from API version 10) — reload it quietly.
|
||
* newer: another document for this group appeared later, e.g. the next semester — offer it.
|
||
* missing: the document left the catalog, e.g. a new academic year began.
|
||
*/
|
||
export function scheduleUpdate(saved, catalog, group, options = {}) {
|
||
// A server without parserVersion never asks for a re-read: comparing with a guess could
|
||
// reload the same document on every check.
|
||
const { dismissed = [], schemaVersion = catalog?.parserVersion ?? 0 } = options;
|
||
const fileId = saved?.source?.fileId;
|
||
if (!fileId || !catalog?.files || catalog.stale) return null;
|
||
const current = catalog.files.find((f) => f.id === fileId) || null;
|
||
const savedTime = time(saved.source.modified) || time(saved.source.importedAt);
|
||
const newer =
|
||
catalog.files
|
||
.filter(
|
||
(f) =>
|
||
f.id !== fileId &&
|
||
!dismissed.includes(f.id) &&
|
||
namesGroup(f.name, group) &&
|
||
time(f.modified) > savedTime &&
|
||
(!saved.source.faculty || f.faculty === saved.source.faculty),
|
||
)
|
||
.sort((a, b) => time(b.modified) - time(a.modified))[0] || null;
|
||
const changed =
|
||
current &&
|
||
(current.modified !== saved.source.modified ||
|
||
(saved.schemaVersion || 0) < schemaVersion)
|
||
? current
|
||
: null;
|
||
if (!changed && !newer && current) return null;
|
||
return { changed, newer, missing: !current };
|
||
}
|