Phase 5: campaign management & worldbuilding
- New entities (note/npc/quest/calendar): schemas, Dexie v4 tables, repos, hooks; campaign cascade-delete now covers them all - Dashboard hub: campaign stats, navigation cards, party overview, recent rolls; opening a campaign lands here - Notes/Wiki: tags, [[wiki-links]] with click-to-open/create, backlinks panel, full-text search, autosave - NPC manager (role/location/faction/status) and Quest tracker (status + objectives checklist + reward) - In-world Calendar: integer day counter + events (no real Date -> no timezone bug) - Fix: calendarRepo.get is read-only (creating-on-read crashed inside liveQuery) 8 new unit tests (wikilinks + extended cascade), worldbuilding e2e. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
/** Extract the distinct titles referenced as [[Wiki Links]] in a body of text. */
|
||||
export function extractWikiLinks(text: string): string[] {
|
||||
const set = new Set<string>();
|
||||
for (const m of text.matchAll(/\[\[([^\]]+)\]\]/g)) {
|
||||
const title = m[1]?.trim();
|
||||
if (title) set.add(title);
|
||||
}
|
||||
return [...set];
|
||||
}
|
||||
|
||||
/** Split text into plain segments and [[link]] segments for rendering. */
|
||||
export function splitWikiLinks(text: string): { text: string; link?: string }[] {
|
||||
const parts: { text: string; link?: string }[] = [];
|
||||
let last = 0;
|
||||
for (const m of text.matchAll(/\[\[([^\]]+)\]\]/g)) {
|
||||
const idx = m.index ?? 0;
|
||||
if (idx > last) parts.push({ text: text.slice(last, idx) });
|
||||
parts.push({ text: m[1]!.trim(), link: m[1]!.trim() });
|
||||
last = idx + m[0].length;
|
||||
}
|
||||
if (last < text.length) parts.push({ text: text.slice(last) });
|
||||
return parts;
|
||||
}
|
||||
Reference in New Issue
Block a user