206 lines
5.7 KiB
TypeScript
206 lines
5.7 KiB
TypeScript
import { contextBridge, ipcRenderer } from "electron";
|
|
|
|
interface SetupState {
|
|
needsSetup: boolean;
|
|
sourceDir: string | null;
|
|
sourceRepoUrl: string;
|
|
imageRepoUrl: string;
|
|
imageBaseUrl: string;
|
|
}
|
|
|
|
interface SetupRunInput {
|
|
mode: "url" | "zip";
|
|
sourceRepoUrl?: string;
|
|
sourceZipPath?: string;
|
|
imageRepoUrl?: string;
|
|
imageBaseUrl?: string;
|
|
downloadImages?: boolean;
|
|
}
|
|
|
|
interface SetupRunResult {
|
|
ok: boolean;
|
|
error?: string;
|
|
}
|
|
|
|
type CharacterEntityType = "class" | "background" | "species";
|
|
type CharacterSourceBucket = "homebrew" | "core2024" | "expanded2024" | "core2014" | "expanded2014";
|
|
|
|
interface CharacterSelectionOption {
|
|
entityType: CharacterEntityType;
|
|
name: string;
|
|
source: string;
|
|
hash: string;
|
|
entityRef: string;
|
|
details: string;
|
|
sourceName: string;
|
|
sourceGroup: string | null;
|
|
sourcePublished: string | null;
|
|
sourceBucket: CharacterSourceBucket;
|
|
sourceEdition: "2014" | "2024" | null;
|
|
imagePath: string | null;
|
|
summary: string;
|
|
}
|
|
|
|
interface CharacterFeatureOption {
|
|
name: string;
|
|
source: string;
|
|
hash: string;
|
|
entityRef: string;
|
|
details: string;
|
|
}
|
|
|
|
interface CharacterFeatureCard {
|
|
id: string;
|
|
title: string;
|
|
level: number | null;
|
|
summary: string;
|
|
options?: CharacterFeatureOption[];
|
|
}
|
|
|
|
interface CharacterSelectionDetail extends CharacterSelectionOption {
|
|
featureCards: CharacterFeatureCard[];
|
|
rawJson: string;
|
|
}
|
|
|
|
interface CharacterSelectionOptionSets {
|
|
classes: CharacterSelectionOption[];
|
|
backgrounds: CharacterSelectionOption[];
|
|
species: CharacterSelectionOption[];
|
|
}
|
|
|
|
interface CharacterEntityRef {
|
|
entityType: "class" | "subclass" | "background" | "species" | "item" | "feat" | "spell";
|
|
name: string;
|
|
source: string;
|
|
hash: string;
|
|
entityRef: string;
|
|
}
|
|
|
|
interface CharacterProfile {
|
|
name: string;
|
|
level: number;
|
|
alignment: string;
|
|
faith: string;
|
|
lifestyle: string;
|
|
age: string;
|
|
gender: string;
|
|
height: string;
|
|
weight: string;
|
|
eyes: string;
|
|
skin: string;
|
|
hair: string;
|
|
}
|
|
|
|
interface CharacterPreferencesStep {
|
|
sourceBuckets: string[];
|
|
useOptionalClassFeatures: boolean;
|
|
customizeOrigin: boolean;
|
|
advancementType: "milestone" | "xp";
|
|
hpMode: "average" | "maximum" | "rolled";
|
|
usePrerequisitesFeats: boolean;
|
|
usePrerequisitesMulticlass: boolean;
|
|
}
|
|
|
|
interface CharacterAbilityScoresStep {
|
|
method: "standardArray" | "pointBuy" | "manual" | "rolled";
|
|
scores: Record<"str" | "dex" | "con" | "int" | "wis" | "cha", number>;
|
|
rolledValues: [number, number, number, number, number, number];
|
|
assignments: Record<"str" | "dex" | "con" | "int" | "wis" | "cha", number>;
|
|
backgroundBonusModeIndex: number;
|
|
backgroundBonusSelections: Array<"str" | "dex" | "con" | "int" | "wis" | "cha">;
|
|
}
|
|
|
|
interface CharacterFeatsStep {
|
|
selected: string[];
|
|
notes: string;
|
|
}
|
|
|
|
interface CharacterSkillsStep {
|
|
selected: string[];
|
|
notes: string;
|
|
}
|
|
|
|
interface CharacterSpellsStep {
|
|
selected: string[];
|
|
notes: string;
|
|
}
|
|
|
|
interface CharacterEquipmentStep {
|
|
startingEquipmentText: string;
|
|
inventoryText: string;
|
|
possessionsText: string;
|
|
currency: Record<"cp" | "sp" | "ep" | "gp" | "pp", number>;
|
|
}
|
|
|
|
interface CharacterAboutStep {
|
|
personality: string;
|
|
ideals: string;
|
|
bonds: string;
|
|
flaws: string;
|
|
backstory: string;
|
|
notes: string;
|
|
}
|
|
|
|
interface CharacterDocument {
|
|
schema: "5etd.character";
|
|
version: 1;
|
|
id: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
profile: CharacterProfile;
|
|
selections: {
|
|
class: CharacterEntityRef | null;
|
|
subclass: CharacterEntityRef | null;
|
|
background: CharacterEntityRef | null;
|
|
species: CharacterEntityRef | null;
|
|
};
|
|
steps: {
|
|
preferences: CharacterPreferencesStep;
|
|
abilityScores: CharacterAbilityScoresStep;
|
|
feats: CharacterFeatsStep;
|
|
skills: CharacterSkillsStep;
|
|
spells: CharacterSpellsStep;
|
|
equipment: CharacterEquipmentStep;
|
|
about: CharacterAboutStep;
|
|
};
|
|
notes: string;
|
|
}
|
|
|
|
interface CharacterSummary {
|
|
id: string;
|
|
name: string;
|
|
level: number;
|
|
className: string | null;
|
|
backgroundName: string | null;
|
|
speciesName: string | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
interface CharacterUpsertInput {
|
|
id?: string;
|
|
profile?: Partial<CharacterProfile>;
|
|
selections?: Partial<CharacterDocument["selections"]>;
|
|
steps?: Partial<CharacterDocument["steps"]>;
|
|
notes?: string;
|
|
createdAt?: string;
|
|
}
|
|
|
|
contextBridge.exposeInMainWorld("desktopApi", {
|
|
getWikiUrl: () => ipcRenderer.invoke("wiki:get-url") as Promise<string>,
|
|
getSetupState: () => ipcRenderer.invoke("setup:get-state") as Promise<SetupState>,
|
|
pickSourceZip: () => ipcRenderer.invoke("setup:pick-source-zip") as Promise<string | null>,
|
|
runSetup: (input: SetupRunInput) => ipcRenderer.invoke("setup:run", input) as Promise<SetupRunResult>,
|
|
resetOnboarding: () => ipcRenderer.invoke("setup:reset-onboarding") as Promise<SetupRunResult>,
|
|
listCharacters: () => ipcRenderer.invoke("characters:list") as Promise<CharacterSummary[]>,
|
|
getCharacter: (id: string) => ipcRenderer.invoke("characters:get", id) as Promise<CharacterDocument | null>,
|
|
saveCharacter: (input: CharacterUpsertInput) => ipcRenderer.invoke("characters:save", input) as Promise<CharacterDocument>,
|
|
deleteCharacter: (id: string) => ipcRenderer.invoke("characters:delete", id) as Promise<boolean>,
|
|
getCharacterOptions: () => ipcRenderer.invoke("characters:get-options") as Promise<CharacterSelectionOptionSets>,
|
|
getCharacterOptionDetail: (entityRef: string) =>
|
|
ipcRenderer.invoke("characters:get-option-detail", entityRef) as Promise<CharacterSelectionDetail | null>,
|
|
pickCharacterJson: () => ipcRenderer.invoke("characters:pick-json") as Promise<string | null>,
|
|
importCharacterJson: (filePath: string) =>
|
|
ipcRenderer.invoke("characters:import-json", filePath) as Promise<CharacterDocument>
|
|
});
|