Skip to content

Commit

Permalink
Merge pull request #425 from chhoumann/macros-qol-18-03-23
Browse files Browse the repository at this point in the history
Macros QoL upgrade 18/03/23 - easier configure & adding macros from choices
  • Loading branch information
chhoumann authored Mar 18, 2023
2 parents 152cb81 + acc5ebb commit 1edb215
Show file tree
Hide file tree
Showing 11 changed files with 291 additions and 57 deletions.
2 changes: 1 addition & 1 deletion esbuild.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ esbuild
],
format: "cjs",
watch: !prod,
target: "es2018",
target: "ES2020",
logLevel: "info",
sourcemap: prod ? false : "inline",
treeShaking: true,
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
},
"dependencies": {
"builtin-modules": "^3.3.0",
"fuse.js": "6.6.2"
"fuse.js": "6.6.2",
"zustand": "^4.3.6"
},
"repository": {
"type": "git",
Expand Down
23 changes: 23 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 14 additions & 12 deletions src/MacrosManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ import {
ToggleComponent,
} from "obsidian";
import { MacroBuilder } from "./gui/MacroGUIs/MacroBuilder";
import { QuickAddMacro } from "./types/macros/QuickAddMacro";
import { log } from "./logger/logManager";
import type IChoice from "./types/choices/IChoice";
import { ChoiceType } from "./types/choices/choiceType";
import type IMultiChoice from "./types/choices/IMultiChoice";
import type QuickAdd from "./main";
import { settingsStore } from "./settingsStore";

export class MacrosManager extends Modal {
public waitForClose: Promise<IMacro[]>;
private resolvePromise: (macros: IMacro[]) => void;
private rejectPromise: (reason?: unknown) => void;
private updateMacroContainer: () => void;
private unsubscribe: () => void;

private macroContainer: HTMLDivElement;
private plugin: QuickAdd;
Expand All @@ -38,6 +39,13 @@ export class MacrosManager extends Modal {
this.resolvePromise = resolve;
});

this.unsubscribe = settingsStore.subscribe((newSettings) => {
this.macros = newSettings.macros;
this.choices = newSettings.choices;

this.reload();
});

this.open();
this.display();
}
Expand Down Expand Up @@ -207,28 +215,22 @@ export class MacrosManager extends Modal {
.onClick(() => {
const inputValue = nameInput.getValue();

if (
inputValue !== "" &&
!this.macros.find((m) => m.name === inputValue)
) {
const macro = new QuickAddMacro(inputValue);
if (!macro) {
log.logError("macro invalid - will not be added");
return;
}

this.macros.push(macro);
try {
settingsStore.createMacro(inputValue);
this.reload();
this.macroContainer.scrollTo(
0,
this.macroContainer.scrollHeight
);
} catch (error) {
log.logError(error);
}
});
}

onClose() {
super.onClose();
this.unsubscribe();
this.resolvePromise(this.macros);
}
}
99 changes: 94 additions & 5 deletions src/gui/ChoiceBuilder/macroChoiceBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,117 @@
import { ChoiceBuilder } from "./choiceBuilder";
import type IMacroChoice from "../../types/choices/IMacroChoice";
import type { App } from "obsidian";
import { App, ButtonComponent } from "obsidian";
import { DropdownComponent } from "obsidian";
import type { IMacro } from "../../types/macros/IMacro";
import { MacroBuilder } from "../MacroGUIs/MacroBuilder";
import QuickAdd from "src/main";
import { settingsStore } from "src/settingsStore";
import IChoice from "src/types/choices/IChoice";
import { log } from "src/logger/logManager";

export class MacroChoiceBuilder extends ChoiceBuilder {
choice: IMacroChoice;
private macros: IMacro[];
private choices: IChoice[];

constructor(app: App, choice: IMacroChoice, private macros: IMacro[]) {
private unsubscribe: () => void;

constructor(
app: App,
choice: IMacroChoice,
macros: IMacro[],
choices: IChoice[]
) {
super(app);
this.choice = choice;
this.macros = macros;
this.choices = choices;

this.unsubscribe = settingsStore.subscribe((newSettings) => {
this.macros = newSettings.macros;
this.choices = newSettings.choices;

this.reload();
});

this.display();
}

onClose(): void {
this.unsubscribe();
}

protected display() {
this.containerEl.addClass("macroChoiceBuilder");
this.addCenteredChoiceNameHeader(this.choice);
this.addSelectMacroSearch();
const macroDropdownContainer = this.contentEl.createDiv();
macroDropdownContainer.addClass("macroDropdownContainer");

this.addSelectMacroSearch(macroDropdownContainer);

const buttonsContainer = macroDropdownContainer.createDiv();
buttonsContainer.addClass("macro-choice-buttonsContainer");

this.addConfigureMacroButton(buttonsContainer);
this.addCreateMacroButton(buttonsContainer);
}

addCreateMacroButton(container: HTMLElement) {
const hasOwnMacro =
settingsStore.getMacro(this.choice.macroId)?.name ===
this.choice.name;

if (hasOwnMacro) return;

const createMacroButtonContainer = container.createDiv();
const createMacroButton = new ButtonComponent(
createMacroButtonContainer
);
createMacroButton
.setIcon("plus")
.setCta()
.setTooltip("Create Macro")
.onClick(async () => {
try {
const macro = settingsStore.createMacro(this.choice.name);
this.choice.macroId = macro.id;
this.reload();
} catch (error) {
log.logError(error);
}
});
}

private addConfigureMacroButton(container: HTMLElement) {
const configureMacroButtonContainer = container.createDiv();
const configureMacroButton = new ButtonComponent(
configureMacroButtonContainer
);
configureMacroButton
.setIcon("cog")
.setTooltip("Configure Macro")
.onClick(async () => {
const macro = this.macros.find(
(m) => m.id === this.choice.macroId
);
if (!macro)
return log.logError("Could not find macro to configure");

const builder = new MacroBuilder(
app,
QuickAdd.instance,
macro,
this.choices
);
const newMacro = await builder.waitForClose;

settingsStore.setMacro(this.choice.macroId, newMacro);
});
}

private addSelectMacroSearch() {
private addSelectMacroSearch(container: HTMLElement) {
const selectMacroDropdownContainer: HTMLDivElement =
this.contentEl.createDiv("selectMacroDropdownContainer");
container.createDiv("selectMacroDropdownContainer");
const dropdown: DropdownComponent = new DropdownComponent(
selectMacroDropdownContainer
);
Expand Down
45 changes: 37 additions & 8 deletions src/gui/choiceList/ChoiceView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import QuickAdd from "../../main";
import GenericInputPrompt from "../GenericInputPrompt/GenericInputPrompt";
import { excludeKeys, getChoiceType } from "src/utility";
import { settingsStore } from "src/settingsStore";
import { onMount } from "svelte";
export let choices: IChoice[] = [];
export let macros: IMacro[] = [];
Expand All @@ -30,6 +32,17 @@
export let app: App;
export let plugin: QuickAdd;
onMount(() => {
const unsubSettingsStore = settingsStore.subscribe(settings => {
choices = settings.choices;
macros = settings.macros;
});
return () => {
unsubSettingsStore();
}
});
function addChoiceToList(event: any): void {
const {name, type} = event.detail;
Expand Down Expand Up @@ -58,18 +71,29 @@
async function deleteChoice(e: any) {
const choice: IChoice = e.detail.choice;
const hasOwnMacro = choice.type === ChoiceType.Macro && macros.some(macro => macro.name === (choice as MacroChoice).name);
const isMulti = choice.type === ChoiceType.Multi;
const userConfirmed: boolean = await GenericYesNoPrompt.Prompt(app,
`Confirm deletion of choice`, `Please confirm that you wish to delete '${choice.name}'.
${choice.type === ChoiceType.Multi
${isMulti
? "Deleting this choice will delete all (" + (choice as IMultiChoice).choices.length + ") choices inside it!"
: ""}
${hasOwnMacro
? "Deleting this choice will delete the macro associated with it!"
: ""}
`);
if (userConfirmed) {
choices = choices.filter((value) => deleteChoiceHelper(choice.id, value));
plugin.removeCommandForChoice(choice);
saveChoices(choices);
if (!userConfirmed) return;
if (hasOwnMacro) {
macros = macros.filter(macro => macro.id !== (choice as MacroChoice).macroId);
saveMacros(macros);
}
choices = choices.filter((value) => deleteChoiceHelper(choice.id, value));
plugin.removeCommandForChoice(choice);
saveChoices(choices);
}
function deleteChoiceHelper(id: string, value: IChoice): boolean {
Expand All @@ -84,7 +108,7 @@
async function configureChoice(e: any) {
const {choice: oldChoice} = e.detail;
let updatedChoice;
let updatedChoice: MultiChoice | TemplateChoice | CaptureChoice | MacroChoice;
if (oldChoice.type === ChoiceType.Multi) {
updatedChoice = oldChoice;
Expand All @@ -93,7 +117,12 @@
updatedChoice.name = name;
} else {
updatedChoice = await getChoiceBuilder(oldChoice).waitForClose;
const builder = getChoiceBuilder(oldChoice);
if (!builder) {
throw new Error('Invalid choice type');
}
updatedChoice = await builder.waitForClose as typeof updatedChoice;
}
if (!updatedChoice) return;
Expand Down Expand Up @@ -176,7 +205,7 @@
case ChoiceType.Capture:
return new CaptureChoiceBuilder(app, choice as ICaptureChoice, plugin);
case ChoiceType.Macro:
return new MacroChoiceBuilder(app, choice as IMacroChoice, macros);
return new MacroChoiceBuilder(app, choice as IMacroChoice, macros, settingsStore.getState().choices);
case ChoiceType.Multi:
default:
break;
Expand Down
9 changes: 9 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ import { deleteObsidianCommand } from "./utility";
import ChoiceSuggester from "./gui/suggesters/choiceSuggester";
import { QuickAddApi } from "./quickAddApi";
import migrate from "./migrations/migrate";
import { settingsStore } from "./settingsStore";

export default class QuickAdd extends Plugin {
static instance: QuickAdd;
settings: QuickAddSettings;

private unsubscribeSettingsStore: () => void;

get api(): ReturnType<typeof QuickAddApi.GetApi> {
return QuickAddApi.GetApi(app, this, new ChoiceExecutor(app, this));
}
Expand All @@ -27,6 +30,11 @@ export default class QuickAdd extends Plugin {
QuickAdd.instance = this;

await this.loadSettings();
settingsStore.setState(this.settings);
this.unsubscribeSettingsStore = settingsStore.subscribe((settings) => {
this.settings = settings;
this.saveSettings();
});

this.addCommand({
id: "runQuickAdd",
Expand Down Expand Up @@ -94,6 +102,7 @@ export default class QuickAdd extends Plugin {

onunload() {
console.log("Unloading QuickAdd");
this.unsubscribeSettingsStore?.call(this);
}

async loadSettings() {
Expand Down
Loading

1 comment on commit 1edb215

@vercel
Copy link

@vercel vercel bot commented on 1edb215 Mar 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

quickadd – ./

quickadd-chrisbbh.vercel.app
quickadd-git-master-chrisbbh.vercel.app
quickadd.obsidian.guide

Please sign in to comment.