Skip to content

Commit

Permalink
add faction influence grid generator (#451)
Browse files Browse the repository at this point in the history
Fixes: #240
  • Loading branch information
zkat authored Jul 23, 2024
1 parent 11e0f55 commit 0a512c1
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from "utils/ui/generic-fuzzy-suggester";
import { PromptModal } from "utils/ui/prompt";
import * as meterCommands from "./characters/meter-commands";
import { createFactionInfluenceGrid } from "factions/commands";

export class IronVaultCommands {
plugin: IronVaultPlugin;
Expand Down Expand Up @@ -214,6 +215,13 @@ export class IronVaultCommands {
},
},

{
id: "faction-grid-gen",
name: "Create faction influence grid",
icon: "table",
callback: () => createFactionInfluenceGrid(this.plugin),
},

/*
* UTILITY
*/
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export enum IronVaultKind {
Clock = "clock",
ProgressTrack = "progress",
Campaign = "campaign",
FactionInfluenceGrid = "faction-influence-grid",
}

// TODO(@cwegrzyn): if Datasworn exports this from core at some point, we should use that.
Expand Down
33 changes: 33 additions & 0 deletions src/factions/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import IronVaultPlugin from "index";
import { FactionInfluenceGridCreateModal } from "./grid-creation-modal";
import { createNewIronVaultEntityFile } from "utils/obsidian";
import { IronVaultKind } from "../constants";

export async function createFactionInfluenceGrid(plugin: IronVaultPlugin) {
const input: {
fileName: string;
targetFolder: string;
} = await new Promise((onAccept, onReject) => {
new FactionInfluenceGridCreateModal(plugin, {}, onAccept, onReject).open();
});

const file = await createNewIronVaultEntityFile(
plugin.app,
input.targetFolder,
input.fileName,
IronVaultKind.FactionInfluenceGrid,
{},
undefined,
`
| Dominant 1-30 | Established 31-45 | Established 46-60 |
|---|---|---|
| | | |
| Subsisting 61-70 | Subsisting 71-80 | Subsisting 81-90 |
| | | |
| Diminished 91-94 | Diminished 95-98 | Obscure 99-100 |
| | | |
`,
);

plugin.app.workspace.getLeaf(false).openFile(file);
}
139 changes: 139 additions & 0 deletions src/factions/grid-creation-modal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { CampaignFile } from "campaigns/entity";
import IronVaultPlugin from "index";
import { ButtonComponent, Modal, Setting, debounce } from "obsidian";
import { CampaignSelectComponent } from "utils/ui/settings/campaign-suggest";
import { RelativeFolderSearchComponent } from "utils/ui/settings/relative-folder-search";

export type FactionInfluenceGridCreateResultType = {
fileName: string;
targetFolder: string;
};

export class FactionInfluenceGridCreateModal extends Modal {
public result: FactionInfluenceGridCreateResultType = {
fileName: "",
targetFolder: "",
};

public accepted: boolean = false;

constructor(
readonly plugin: IronVaultPlugin,
defaults: Partial<FactionInfluenceGridCreateResultType> = {},
protected readonly onAccept: (arg: {
targetFolder: string;
fileName: string;
}) => void,
protected readonly onCancel: () => void,
) {
super(plugin.app);
Object.assign(this.result, defaults);
}

onOpen(): void {
this.accepted = false;

const { contentEl } = this;
new Setting(contentEl).setName("New faction influence grid").setHeading();

let campaign!: CampaignFile;

const onChangeCampaign = () => {
//TODO(@cwegrzyn): this should update to use the campaign-specific folder
folderComponent
.setBaseFolder(campaign.file.parent!)
// TODO(@zkat): Make this a setting.
.setValue("Factions")
.onChanged();
};

const validate = debounce(() => {
const valid = this.result.fileName.trim().length > 0;
createButton.setDisabled(!valid);
}, 0);

CampaignSelectComponent.addToSetting(
new Setting(contentEl)
.setName("Campaign")
.setDesc(
"New faction influence grid will be created in this campaign.",
),
this.plugin,
(dropdown) => {
dropdown.onChange((val) => {
campaign = val;
onChangeCampaign();
validate();
});
campaign = dropdown.getValue();
},
);

this.result.fileName = "Faction Influence Grid";
new Setting(contentEl).setName("File name").addText((text) =>
text.setValue(this.result.fileName).onChange((value) => {
this.result.fileName = value;
validate();
}),
);

let folderComponent!: RelativeFolderSearchComponent;
const folderSetting = RelativeFolderSearchComponent.addToSetting(
new Setting(contentEl).setName("Target folder"),
this.plugin.app,
(search) => {
folderComponent = search
.setPlaceholder("Choose a folder")
.setValue(this.result.targetFolder)
.onChange((_relPath, newPath, folder) => {
this.result.targetFolder = newPath;
if (folder) {
folderSetting.setDesc(
`Creating faction influence grid in existing folder '${newPath}'`,
);
} else {
folderSetting.setDesc(
`Creating faction influence grid in new folder '${newPath}'`,
);
}
});
},
);

onChangeCampaign();
validate();

let createButton!: ButtonComponent;
new Setting(contentEl)
.addButton((btn) =>
(createButton = btn)
.setButtonText("Create")
.setCta()
.onClick(() => {
this.accept();
}),
)
.addButton((btn) =>
btn.setButtonText("Cancel").onClick(() => {
this.accepted = false;
this.close();
}),
);
}

accept(): void {
this.accepted = true;
this.close();
this.onAccept({
fileName: this.result.fileName,
targetFolder: this.result.targetFolder,
});
}

onClose(): void {
this.contentEl.empty();
if (!this.accepted) {
this.onCancel();
}
}
}

0 comments on commit 0a512c1

Please sign in to comment.