From 9fa996f9bf37930339fb4cc99c6ff62456f4157e Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Wed, 9 Jun 2021 19:15:58 +0200 Subject: [PATCH 01/29] Introduce initial types --- src/quickAddSettingsTab.ts | 4 +++- src/types/choices/captureChoice.ts | 10 ++++++++++ src/types/choices/choice.ts | 3 +++ src/types/choices/macroChoice.ts | 6 ++++++ src/types/choices/multiChoice.ts | 5 +++++ src/types/choices/templateChoice.ts | 12 ++++++++++++ src/types/macros/command.ts | 3 +++ src/types/macros/macro.ts | 5 +++++ src/types/macros/obsidianCommand.ts | 5 +++++ src/types/macros/userCommand.ts | 5 +++++ 10 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/types/choices/captureChoice.ts create mode 100644 src/types/choices/choice.ts create mode 100644 src/types/choices/macroChoice.ts create mode 100644 src/types/choices/multiChoice.ts create mode 100644 src/types/choices/templateChoice.ts create mode 100644 src/types/macros/command.ts create mode 100644 src/types/macros/macro.ts create mode 100644 src/types/macros/obsidianCommand.ts create mode 100644 src/types/macros/userCommand.ts diff --git a/src/quickAddSettingsTab.ts b/src/quickAddSettingsTab.ts index 17cd35c..4e84c8b 100644 --- a/src/quickAddSettingsTab.ts +++ b/src/quickAddSettingsTab.ts @@ -1,11 +1,13 @@ import {App, PluginSettingTab, Setting} from "obsidian"; import type QuickAdd from "./main"; +import type {Choice} from "./types/choices/choice"; export interface QuickAddSettings { - + choices: Choice[]; } export const DEFAULT_SETTINGS: QuickAddSettings = { + choices: [] } export class QuickAddSettingsTab extends PluginSettingTab { diff --git a/src/types/choices/captureChoice.ts b/src/types/choices/captureChoice.ts new file mode 100644 index 0000000..ef418a1 --- /dev/null +++ b/src/types/choices/captureChoice.ts @@ -0,0 +1,10 @@ +import type {Choice} from "./choice"; + +export interface CaptureChoice extends Choice { + captureTo: string; + format: { enabled: boolean, format: string }; + prepend: boolean; + appendLink: boolean; + task: boolean; + insertAfter: { enabled: boolean, after: string }; +} \ No newline at end of file diff --git a/src/types/choices/choice.ts b/src/types/choices/choice.ts new file mode 100644 index 0000000..76f6427 --- /dev/null +++ b/src/types/choices/choice.ts @@ -0,0 +1,3 @@ +export interface Choice { + name: string; +} \ No newline at end of file diff --git a/src/types/choices/macroChoice.ts b/src/types/choices/macroChoice.ts new file mode 100644 index 0000000..56ac06c --- /dev/null +++ b/src/types/choices/macroChoice.ts @@ -0,0 +1,6 @@ +import type {Choice} from "./choice"; +import type {Macro} from "../macros/macro"; + +export interface MacroChoice extends Choice { + macro: Macro; +} \ No newline at end of file diff --git a/src/types/choices/multiChoice.ts b/src/types/choices/multiChoice.ts new file mode 100644 index 0000000..f5279a9 --- /dev/null +++ b/src/types/choices/multiChoice.ts @@ -0,0 +1,5 @@ +import type {Choice} from "./choice"; + +export interface MultiChoice extends Choice { + choices: Choice[]; +} \ No newline at end of file diff --git a/src/types/choices/templateChoice.ts b/src/types/choices/templateChoice.ts new file mode 100644 index 0000000..3b37a49 --- /dev/null +++ b/src/types/choices/templateChoice.ts @@ -0,0 +1,12 @@ +import type {Choice} from "./choice"; + +export interface TemplateChoice extends Choice { + templatePath: string; + startSymbol: { enabled: boolean, symbol: string }; + folder: { enabled: boolean, folders: string[] } + fileNameFormat: { enabled: boolean, format: string }; + appendLink: boolean; + incrementFileName: boolean; + noOpen: boolean; + newTab: "vertical" | "horizontal"; +} \ No newline at end of file diff --git a/src/types/macros/command.ts b/src/types/macros/command.ts new file mode 100644 index 0000000..0072741 --- /dev/null +++ b/src/types/macros/command.ts @@ -0,0 +1,3 @@ +export interface Command { + +} \ No newline at end of file diff --git a/src/types/macros/macro.ts b/src/types/macros/macro.ts new file mode 100644 index 0000000..78e74ef --- /dev/null +++ b/src/types/macros/macro.ts @@ -0,0 +1,5 @@ +import type {Command} from "./command"; + +export interface Macro { + commands: Command[]; +} \ No newline at end of file diff --git a/src/types/macros/obsidianCommand.ts b/src/types/macros/obsidianCommand.ts new file mode 100644 index 0000000..5016170 --- /dev/null +++ b/src/types/macros/obsidianCommand.ts @@ -0,0 +1,5 @@ +import type {Command} from "./command"; + +export interface ObsidianCommand extends Command { + +} \ No newline at end of file diff --git a/src/types/macros/userCommand.ts b/src/types/macros/userCommand.ts new file mode 100644 index 0000000..4c5194a --- /dev/null +++ b/src/types/macros/userCommand.ts @@ -0,0 +1,5 @@ +import type {Command} from "./command"; + +export interface UserCommand extends Command { + +} \ No newline at end of file From 11ddb8491af80c1c11f3a9aaf5e74bf3fe1b5f31 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Wed, 9 Jun 2021 21:13:52 +0200 Subject: [PATCH 02/29] Basic choice dropdowns --- package.json | 5 +- src/gui/choiceList/ChoiceList.svelte | 18 +++++++ src/gui/choiceList/ChoiceListItem.svelte | 29 ++++++++++ src/gui/choiceList/ChoiceView.svelte | 22 ++++++++ src/gui/choiceList/MultiChoiceListItem.svelte | 53 +++++++++++++++++++ src/quickAddSettingsTab.ts | 17 +++++- src/types/choices/captureChoice.ts | 4 +- src/types/choices/choice.ts | 8 ++- src/types/choices/choiceType.ts | 3 ++ src/types/choices/macroChoice.ts | 4 +- src/types/choices/multiChoice.ts | 4 +- src/types/choices/templateChoice.ts | 4 +- 12 files changed, 158 insertions(+), 13 deletions(-) create mode 100644 src/gui/choiceList/ChoiceList.svelte create mode 100644 src/gui/choiceList/ChoiceListItem.svelte create mode 100644 src/gui/choiceList/ChoiceView.svelte create mode 100644 src/gui/choiceList/MultiChoiceListItem.svelte create mode 100644 src/types/choices/choiceType.ts diff --git a/package.json b/package.json index a3247ac..b4292e6 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,9 @@ "typescript": "^4.2.4" }, "dependencies": { - "@popperjs/core": "^2.9.2" + "@fortawesome/free-regular-svg-icons": "5.15.3", + "@fortawesome/free-solid-svg-icons": "5.15.3", + "@popperjs/core": "^2.9.2", + "svelte-awesome": "2.3.2" } } diff --git a/src/gui/choiceList/ChoiceList.svelte b/src/gui/choiceList/ChoiceList.svelte new file mode 100644 index 0000000..25c9214 --- /dev/null +++ b/src/gui/choiceList/ChoiceList.svelte @@ -0,0 +1,18 @@ + + +
+ {#each choices as choice, i} + {#if choice.type !== ChoiceType.Multi} + + {:else} + + {/if} + {/each} +
diff --git a/src/gui/choiceList/ChoiceListItem.svelte b/src/gui/choiceList/ChoiceListItem.svelte new file mode 100644 index 0000000..4972c9c --- /dev/null +++ b/src/gui/choiceList/ChoiceListItem.svelte @@ -0,0 +1,29 @@ + + +
+ {choice.name} + + ❌ +
+ + diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte new file mode 100644 index 0000000..f6c076c --- /dev/null +++ b/src/gui/choiceList/ChoiceView.svelte @@ -0,0 +1,22 @@ + + +
+

Choices

+ +
diff --git a/src/gui/choiceList/MultiChoiceListItem.svelte b/src/gui/choiceList/MultiChoiceListItem.svelte new file mode 100644 index 0000000..a5974d9 --- /dev/null +++ b/src/gui/choiceList/MultiChoiceListItem.svelte @@ -0,0 +1,53 @@ + + +
+
+
collapse = !collapse}> + + {choice.name} +
+ + + ❌ +
+ + {#if !collapse} +
+ +
+ {/if} +
+ + diff --git a/src/quickAddSettingsTab.ts b/src/quickAddSettingsTab.ts index 4e84c8b..bd778d8 100644 --- a/src/quickAddSettingsTab.ts +++ b/src/quickAddSettingsTab.ts @@ -1,6 +1,7 @@ import {App, PluginSettingTab, Setting} from "obsidian"; import type QuickAdd from "./main"; -import type {Choice} from "./types/choices/choice"; +import type Choice from "./types/choices/choice"; +import ChoiceList from "./gui/choiceList/ChoiceView.svelte" export interface QuickAddSettings { choices: Choice[]; @@ -11,7 +12,8 @@ export const DEFAULT_SETTINGS: QuickAddSettings = { } export class QuickAddSettingsTab extends PluginSettingTab { - plugin: QuickAdd; + public plugin: QuickAdd; + private choiceList: ChoiceList; constructor(app: App, plugin: QuickAdd) { super(app, plugin); @@ -23,5 +25,16 @@ export class QuickAddSettingsTab extends PluginSettingTab { containerEl.empty(); containerEl.createEl('h2', {text: 'QuickAdd Settings'}); + const choicesDiv = containerEl.createDiv('choices'); + + + this.choiceList = new ChoiceList({ + target: choicesDiv, + // props: {} + }) + } + + hide(): any { + this.choiceList.$destroy(); } } \ No newline at end of file diff --git a/src/types/choices/captureChoice.ts b/src/types/choices/captureChoice.ts index ef418a1..eb5708c 100644 --- a/src/types/choices/captureChoice.ts +++ b/src/types/choices/captureChoice.ts @@ -1,6 +1,6 @@ -import type {Choice} from "./choice"; +import type Choice from "./choice"; -export interface CaptureChoice extends Choice { +export default interface CaptureChoice extends Choice { captureTo: string; format: { enabled: boolean, format: string }; prepend: boolean; diff --git a/src/types/choices/choice.ts b/src/types/choices/choice.ts index 76f6427..d81134b 100644 --- a/src/types/choices/choice.ts +++ b/src/types/choices/choice.ts @@ -1,3 +1,7 @@ -export interface Choice { +import type {ChoiceType} from "./choiceType"; + +export default interface Choice { name: string; -} \ No newline at end of file + type: ChoiceType; +} + diff --git a/src/types/choices/choiceType.ts b/src/types/choices/choiceType.ts new file mode 100644 index 0000000..03c9fd9 --- /dev/null +++ b/src/types/choices/choiceType.ts @@ -0,0 +1,3 @@ +export enum ChoiceType { + Capture, Macro, Multi, Template +} \ No newline at end of file diff --git a/src/types/choices/macroChoice.ts b/src/types/choices/macroChoice.ts index 56ac06c..1498852 100644 --- a/src/types/choices/macroChoice.ts +++ b/src/types/choices/macroChoice.ts @@ -1,6 +1,6 @@ -import type {Choice} from "./choice"; +import type Choice from "./choice"; import type {Macro} from "../macros/macro"; -export interface MacroChoice extends Choice { +export default interface MacroChoice extends Choice { macro: Macro; } \ No newline at end of file diff --git a/src/types/choices/multiChoice.ts b/src/types/choices/multiChoice.ts index f5279a9..d54b938 100644 --- a/src/types/choices/multiChoice.ts +++ b/src/types/choices/multiChoice.ts @@ -1,5 +1,5 @@ -import type {Choice} from "./choice"; +import type Choice from "./choice"; -export interface MultiChoice extends Choice { +export default interface MultiChoice extends Choice { choices: Choice[]; } \ No newline at end of file diff --git a/src/types/choices/templateChoice.ts b/src/types/choices/templateChoice.ts index 3b37a49..d40a10a 100644 --- a/src/types/choices/templateChoice.ts +++ b/src/types/choices/templateChoice.ts @@ -1,6 +1,6 @@ -import type {Choice} from "./choice"; +import type Choice from "./choice"; -export interface TemplateChoice extends Choice { +export default interface TemplateChoice extends Choice { templatePath: string; startSymbol: { enabled: boolean, symbol: string }; folder: { enabled: boolean, folders: string[] } From 6c1bfd734a8ec32b5c15550816a5e9a98fa900f5 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Wed, 9 Jun 2021 22:31:00 +0200 Subject: [PATCH 03/29] Reorder choices --- package.json | 5 +++- src/gui/choiceList/ChoiceList.svelte | 24 ++++++++++++++++--- src/gui/choiceList/ChoiceView.svelte | 13 +++++----- src/gui/choiceList/MultiChoiceListItem.svelte | 3 ++- src/types/choices/choice.ts | 1 + 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index b4292e6..f16317f 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@tsconfig/svelte": "1.0.10", "@types/jest": "26.0.23", "@types/node": "14.17.1", + "@types/uuid": "8.3.0", "babel-core": "6.26.3", "babel-jest": "27.0.1", "jest": "27.0.1", @@ -31,6 +32,7 @@ "rollup-plugin-svelte": "^7.1.0", "svelte": "^3.37.0", "svelte-check": "^1.3.0", + "svelte-dnd-action": "0.9.8", "svelte-preprocess": "^4.7.0", "ts-jest": "27.0.0", "tslib": "^2.2.0", @@ -40,6 +42,7 @@ "@fortawesome/free-regular-svg-icons": "5.15.3", "@fortawesome/free-solid-svg-icons": "5.15.3", "@popperjs/core": "^2.9.2", - "svelte-awesome": "2.3.2" + "svelte-awesome": "2.3.2", + "uuid": "8.3.2" } } diff --git a/src/gui/choiceList/ChoiceList.svelte b/src/gui/choiceList/ChoiceList.svelte index 25c9214..ceac251 100644 --- a/src/gui/choiceList/ChoiceList.svelte +++ b/src/gui/choiceList/ChoiceList.svelte @@ -3,16 +3,34 @@ import ChoiceListItem from "./ChoiceListItem.svelte"; import MultiChoiceListItem from "./MultiChoiceListItem.svelte"; import {ChoiceType} from "../../types/choices/choiceType"; + import {DndEvent, dndzone} from "svelte-dnd-action"; export let choices: Choice[]; + export let type: string; + + function handleSort(e: CustomEvent) { + choices = e.detail.items as Choice[]; + } + -
- {#each choices as choice, i} +
+ {#each choices as choice(choice.id)} {#if choice.type !== ChoiceType.Multi} {:else} - + {/if} {/each}
+ + \ No newline at end of file diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte index f6c076c..0120e36 100644 --- a/src/gui/choiceList/ChoiceView.svelte +++ b/src/gui/choiceList/ChoiceView.svelte @@ -3,13 +3,14 @@ import {ChoiceType} from "../../types/choices/choiceType"; import ChoiceList from "./ChoiceList.svelte"; import MultiChoice from "../../types/choices/multiChoice"; + import {v4 as uuidv4} from "uuid"; export let choices: Choice[] = [ - {name: 'templateChoice', type: ChoiceType.Template}, - {name: 'multiChoice', type: ChoiceType.Multi, choices: [ - {name: 'captureChoice', type: ChoiceType.Capture}, - {name: 'nestedMultiChoice', type: ChoiceType.Multi, choices: [ - {name: 'macroChoice', type: ChoiceType.Macro} + {name: 'templateChoice', type: ChoiceType.Template, id: uuidv4()}, + {name: 'multiChoice', type: ChoiceType.Multi, id: uuidv4(), choices: [ + {name: 'captureChoice', type: ChoiceType.Capture, id: uuidv4()}, + {name: 'nestedMultiChoice', type: ChoiceType.Multi, id: uuidv4(), choices: [ + {name: 'macroChoice', type: ChoiceType.Macro, id: uuidv4()} ]} ]} ]; @@ -18,5 +19,5 @@

Choices

- +
diff --git a/src/gui/choiceList/MultiChoiceListItem.svelte b/src/gui/choiceList/MultiChoiceListItem.svelte index a5974d9..c297333 100644 --- a/src/gui/choiceList/MultiChoiceListItem.svelte +++ b/src/gui/choiceList/MultiChoiceListItem.svelte @@ -5,6 +5,7 @@ import MultiChoice from "../../types/choices/multiChoice"; export let choice: MultiChoice; + export let id: string; let collapse: boolean = false; @@ -21,7 +22,7 @@ {#if !collapse}
- +
{/if}
diff --git a/src/types/choices/choice.ts b/src/types/choices/choice.ts index d81134b..727d943 100644 --- a/src/types/choices/choice.ts +++ b/src/types/choices/choice.ts @@ -2,6 +2,7 @@ import type {ChoiceType} from "./choiceType"; export default interface Choice { name: string; + id: string; type: ChoiceType; } From 9b96e450e9dc3856d00003d4c28dc703e5c4c2f6 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Thu, 10 Jun 2021 10:03:00 +0200 Subject: [PATCH 04/29] Proper handling for reordering choices --- src/gui/choiceList/ChoiceList.svelte | 20 ++++++++++++---- src/gui/choiceList/ChoiceListItem.svelte | 12 +++++----- src/gui/choiceList/ChoiceView.svelte | 22 ++++++++++++------ src/gui/choiceList/MultiChoiceListItem.svelte | 23 +++++++++---------- src/types/choices/multiChoice.ts | 1 + 5 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/gui/choiceList/ChoiceList.svelte b/src/gui/choiceList/ChoiceList.svelte index ceac251..7d96918 100644 --- a/src/gui/choiceList/ChoiceList.svelte +++ b/src/gui/choiceList/ChoiceList.svelte @@ -6,20 +6,30 @@ import {DndEvent, dndzone} from "svelte-dnd-action"; export let choices: Choice[]; - export let type: string; + let collapseId: string; + + function handleConsider(e: CustomEvent) { + let {items: newItems, info: {id}} = e.detail; + collapseId = id; + + choices = newItems as Choice[]; + } function handleSort(e: CustomEvent) { - choices = e.detail.items as Choice[]; + let {items: newItems} = e.detail; + collapseId = ""; + + choices = newItems as Choice[]; } -
+
{#each choices as choice(choice.id)} {#if choice.type !== ChoiceType.Multi} {:else} - + {/if} {/each}
@@ -27,7 +37,7 @@ diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte index 0120e36..6024625 100644 --- a/src/gui/choiceList/ChoiceView.svelte +++ b/src/gui/choiceList/ChoiceView.svelte @@ -6,13 +6,21 @@ import {v4 as uuidv4} from "uuid"; export let choices: Choice[] = [ - {name: 'templateChoice', type: ChoiceType.Template, id: uuidv4()}, - {name: 'multiChoice', type: ChoiceType.Multi, id: uuidv4(), choices: [ - {name: 'captureChoice', type: ChoiceType.Capture, id: uuidv4()}, - {name: 'nestedMultiChoice', type: ChoiceType.Multi, id: uuidv4(), choices: [ - {name: 'macroChoice', type: ChoiceType.Macro, id: uuidv4()} - ]} - ]} + {name: 'πŸšΆβ€β™‚οΈ Journal', type: ChoiceType.Template, id: uuidv4()}, + {name: 'πŸ“– Log Book to Daily Journal', type: ChoiceType.Template, id: uuidv4()}, + {name: 'πŸ“₯ Add...', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ + {name: 'πŸ’­ Add a Thought', type: ChoiceType.Capture, id: uuidv4()}, + {name: 'πŸ“₯ Add an Inbox Item', type: ChoiceType.Template, id: uuidv4()}, + {name: 'πŸ“• Add Book Notes', type: ChoiceType.Template, id: uuidv4()}, + ]}, + {name: "✍ Quick Capture", type: ChoiceType.Capture, id: uuidv4()}, + {name: 'πŸ’¬ Add Quote Page', type: ChoiceType.Template, id: uuidv4()}, + {name: 'πŸŒ€ Task Manager', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ + {name: 'βœ” Add a Task', type: ChoiceType.Macro, id: uuidv4()}, + {name: 'βœ” Quick Capture Task', type: ChoiceType.Capture, id: uuidv4()}, + {name: 'βœ” Add MetaEdit Backlog Task', type: ChoiceType.Capture, id: uuidv4()}, + ]}, + {name: 'πŸ’Έ Add Purchase', type: ChoiceType.Capture, id: uuidv4()} ]; export let saveChoices: (choices: Choice[]) => void; diff --git a/src/gui/choiceList/MultiChoiceListItem.svelte b/src/gui/choiceList/MultiChoiceListItem.svelte index c297333..a359e3b 100644 --- a/src/gui/choiceList/MultiChoiceListItem.svelte +++ b/src/gui/choiceList/MultiChoiceListItem.svelte @@ -5,46 +5,45 @@ import MultiChoice from "../../types/choices/multiChoice"; export let choice: MultiChoice; - export let id: string; - let collapse: boolean = false; + export let collapseId: string;
-
-
collapse = !collapse}> - +
+
choice.collapsed = !choice.collapsed}> + {choice.name}
- ❌ + ❌
- {#if !collapse} + {#if (!collapseId && choice.id !== collapseId) && !choice.collapsed}
- +
{/if}
\ No newline at end of file diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte index 6024625..d991af0 100644 --- a/src/gui/choiceList/ChoiceView.svelte +++ b/src/gui/choiceList/ChoiceView.svelte @@ -4,28 +4,35 @@ import ChoiceList from "./ChoiceList.svelte"; import MultiChoice from "../../types/choices/multiChoice"; import {v4 as uuidv4} from "uuid"; + import AddChoiceBox from "./AddChoiceBox.svelte"; export let choices: Choice[] = [ {name: 'πŸšΆβ€β™‚οΈ Journal', type: ChoiceType.Template, id: uuidv4()}, {name: 'πŸ“– Log Book to Daily Journal', type: ChoiceType.Template, id: uuidv4()}, - {name: 'πŸ“₯ Add...', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ - {name: 'πŸ’­ Add a Thought', type: ChoiceType.Capture, id: uuidv4()}, - {name: 'πŸ“₯ Add an Inbox Item', type: ChoiceType.Template, id: uuidv4()}, - {name: 'πŸ“• Add Book Notes', type: ChoiceType.Template, id: uuidv4()}, - ]}, + { + name: 'πŸ“₯ Add...', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ + {name: 'πŸ’­ Add a Thought', type: ChoiceType.Capture, id: uuidv4()}, + {name: 'πŸ“₯ Add an Inbox Item', type: ChoiceType.Template, id: uuidv4()}, + {name: 'πŸ“• Add Book Notes', type: ChoiceType.Template, id: uuidv4()}, + ] + }, {name: "✍ Quick Capture", type: ChoiceType.Capture, id: uuidv4()}, {name: 'πŸ’¬ Add Quote Page', type: ChoiceType.Template, id: uuidv4()}, - {name: 'πŸŒ€ Task Manager', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ - {name: 'βœ” Add a Task', type: ChoiceType.Macro, id: uuidv4()}, - {name: 'βœ” Quick Capture Task', type: ChoiceType.Capture, id: uuidv4()}, - {name: 'βœ” Add MetaEdit Backlog Task', type: ChoiceType.Capture, id: uuidv4()}, - ]}, + { + name: 'πŸŒ€ Task Manager', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ + {name: 'βœ” Add a Task', type: ChoiceType.Macro, id: uuidv4()}, + {name: 'βœ” Quick Capture Task', type: ChoiceType.Capture, id: uuidv4()}, + {name: 'βœ” Add MetaEdit Backlog Task', type: ChoiceType.Capture, id: uuidv4()}, + ] + }, {name: 'πŸ’Έ Add Purchase', type: ChoiceType.Capture, id: uuidv4()} ]; + export let saveChoices: (choices: Choice[]) => void;

Choices

+
diff --git a/src/types/choices/choiceType.ts b/src/types/choices/choiceType.ts index 03c9fd9..1f29eaa 100644 --- a/src/types/choices/choiceType.ts +++ b/src/types/choices/choiceType.ts @@ -1,3 +1,3 @@ export enum ChoiceType { - Capture, Macro, Multi, Template + Capture = "Capture", Macro = "Macro", Multi = "Multi", Template = "Template" } \ No newline at end of file From ef58779d7628ec70dec9af79997ecee067b801e7 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Thu, 10 Jun 2021 11:55:06 +0200 Subject: [PATCH 07/29] Remove excessive spacing in choice list --- src/gui/choiceList/ChoiceList.svelte | 8 ++++++-- src/gui/choiceList/ChoiceListItem.svelte | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gui/choiceList/ChoiceList.svelte b/src/gui/choiceList/ChoiceList.svelte index 5966f39..0c12433 100644 --- a/src/gui/choiceList/ChoiceList.svelte +++ b/src/gui/choiceList/ChoiceList.svelte @@ -24,7 +24,12 @@ -
+
{#each choices.filter(c => c.id !== SHADOW_PLACEHOLDER_ITEM_ID) as choice(choice.id)} {#if choice.type !== ChoiceType.Multi} @@ -39,7 +44,6 @@ width: auto; border: 0 solid black; overflow-y: auto; - padding-bottom: 0.5rem; height: auto; background-color: rgba(100, 100, 100, 0.01); } diff --git a/src/gui/choiceList/ChoiceListItem.svelte b/src/gui/choiceList/ChoiceListItem.svelte index 300a1e4..e4ec3f8 100644 --- a/src/gui/choiceList/ChoiceListItem.svelte +++ b/src/gui/choiceList/ChoiceListItem.svelte @@ -15,7 +15,7 @@ display: flex; font-size: 16px; align-items: center; - margin: 12px 0; + margin: 12px 0 0 0; transition: 1000ms ease-in-out; } From 790c5e058a5ebe1577525379be66c6164be81d8f Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Thu, 10 Jun 2021 12:59:17 +0200 Subject: [PATCH 08/29] Add choices --- src/gui/choiceList/AddChoiceBox.svelte | 16 ++++++- src/gui/choiceList/ChoiceList.svelte | 8 ++-- src/gui/choiceList/ChoiceListItem.svelte | 4 +- src/gui/choiceList/ChoiceView.svelte | 44 ++++++++++++++++--- src/gui/choiceList/MultiChoiceListItem.svelte | 4 +- src/quickAddSettingsTab.ts | 4 +- src/types/choices/CaptureChoice.ts | 16 +++++++ src/types/choices/Choice.ts | 15 +++++++ .../{captureChoice.ts => ICaptureChoice.ts} | 7 +-- src/types/choices/{choice.ts => IChoice.ts} | 2 +- src/types/choices/IMacroChoice.ts | 7 +++ src/types/choices/IMultiChoice.ts | 7 +++ .../{templateChoice.ts => ITemplateChoice.ts} | 6 +-- src/types/choices/MacroChoice.ts | 12 +++++ src/types/choices/MultiChoice.ts | 13 ++++++ src/types/choices/TemplateChoice.ts | 18 ++++++++ src/types/choices/macroChoice.ts | 6 --- src/types/choices/multiChoice.ts | 6 --- 18 files changed, 158 insertions(+), 37 deletions(-) create mode 100644 src/types/choices/CaptureChoice.ts create mode 100644 src/types/choices/Choice.ts rename src/types/choices/{captureChoice.ts => ICaptureChoice.ts} (66%) rename src/types/choices/{choice.ts => IChoice.ts} (75%) create mode 100644 src/types/choices/IMacroChoice.ts create mode 100644 src/types/choices/IMultiChoice.ts rename src/types/choices/{templateChoice.ts => ITemplateChoice.ts} (61%) create mode 100644 src/types/choices/MacroChoice.ts create mode 100644 src/types/choices/MultiChoice.ts create mode 100644 src/types/choices/TemplateChoice.ts delete mode 100644 src/types/choices/macroChoice.ts delete mode 100644 src/types/choices/multiChoice.ts diff --git a/src/gui/choiceList/AddChoiceBox.svelte b/src/gui/choiceList/AddChoiceBox.svelte index ddbf66c..85ab8fd 100644 --- a/src/gui/choiceList/AddChoiceBox.svelte +++ b/src/gui/choiceList/AddChoiceBox.svelte @@ -1,8 +1,22 @@
@@ -13,7 +27,7 @@ - +
\ No newline at end of file diff --git a/src/gui/choiceList/ChoiceListItem.svelte b/src/gui/choiceList/ChoiceListItem.svelte index 89278eb..d7d80e5 100644 --- a/src/gui/choiceList/ChoiceListItem.svelte +++ b/src/gui/choiceList/ChoiceListItem.svelte @@ -1,17 +1,23 @@ -
- {choice.name} - - ❌ +
+ {choice.name} + +
diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte index b4e994f..576c923 100644 --- a/src/gui/choiceList/ChoiceView.svelte +++ b/src/gui/choiceList/ChoiceView.svelte @@ -37,7 +37,7 @@ export let saveChoices: (choices: IChoice[]) => void; - const addChoiceToList: (event: any) => void = (event: any) => { + function addChoiceToList(event: any): void { const {name, type} = event.detail; switch (type) { @@ -58,7 +58,23 @@ choices = [...choices, multiChoice]; break; } - }; + } + + function deleteChoice(id: string) { + choices = choices.filter((value, index, array) => deleteChoiceHelper(id, value, index, array)); + } + + function deleteChoiceHelper(id: string, value: IChoice, index: number, array: IChoice[]): boolean { + if (value instanceof MultiChoice) { + value.choices = value.choices.filter(this); + + return true; + } + + return value.id !== id; + + + }
diff --git a/src/gui/choiceList/MultiChoiceListItem.svelte b/src/gui/choiceList/MultiChoiceListItem.svelte index 98c9104..c2c233a 100644 --- a/src/gui/choiceList/MultiChoiceListItem.svelte +++ b/src/gui/choiceList/MultiChoiceListItem.svelte @@ -3,9 +3,11 @@ import {faChevronDown} from "@fortawesome/free-solid-svg-icons"; import ChoiceList from "./ChoiceList.svelte"; import IMultiChoice from "../../types/choices/IMultiChoice"; + import RightButtons from "./RightButtons.svelte"; export let choice: IMultiChoice; export let collapseId: string; + export let dragDisabled: boolean;
@@ -15,8 +17,11 @@ {choice.name}
- - ❌ +
{#if !collapseId || (collapseId && choice.id !== collapseId)} @@ -45,10 +50,6 @@ margin-left: 5px; } - .multiChoiceListItemDelete:hover { - cursor: pointer; - } - .nestedChoiceList { padding-left: 25px; } diff --git a/src/gui/choiceList/RightButtons.svelte b/src/gui/choiceList/RightButtons.svelte new file mode 100644 index 0000000..946d8f4 --- /dev/null +++ b/src/gui/choiceList/RightButtons.svelte @@ -0,0 +1,36 @@ + + +
+ + +
+ +
+ +
+ +
+
+ + \ No newline at end of file From 7a190bcd7ae55fab63e2c172fcbe24eb6f0cc4f5 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Thu, 10 Jun 2021 15:12:16 +0200 Subject: [PATCH 10/29] Finish adding choices --- .../GenericYesNoPrompt/GenericYesNoPrompt.ts | 51 +++++++++++++++++++ .../GenericYesNoPromptContent.svelte | 39 ++++++++++++++ src/gui/choiceList/AddChoiceBox.svelte | 1 + ...s.svelte => ChoiceItemRightButtons.svelte} | 19 +++++-- src/gui/choiceList/ChoiceList.svelte | 2 + src/gui/choiceList/ChoiceListItem.svelte | 11 +++- src/gui/choiceList/ChoiceView.svelte | 42 ++++++--------- src/gui/choiceList/MultiChoiceListItem.svelte | 13 ++++- src/main.ts | 41 +++++++++++++-- src/quickAddSettingsTab.ts | 10 +++- 10 files changed, 192 insertions(+), 37 deletions(-) create mode 100644 src/gui/GenericYesNoPrompt/GenericYesNoPrompt.ts create mode 100644 src/gui/GenericYesNoPrompt/GenericYesNoPromptContent.svelte rename src/gui/choiceList/{RightButtons.svelte => ChoiceItemRightButtons.svelte} (63%) diff --git a/src/gui/GenericYesNoPrompt/GenericYesNoPrompt.ts b/src/gui/GenericYesNoPrompt/GenericYesNoPrompt.ts new file mode 100644 index 0000000..74d11ec --- /dev/null +++ b/src/gui/GenericYesNoPrompt/GenericYesNoPrompt.ts @@ -0,0 +1,51 @@ +import {App, Modal} from "obsidian"; +import GenericYesNoPromptContent from "./GenericYesNoPromptContent.svelte" + +export default class GenericYesNoPrompt extends Modal { + private modalContent: GenericYesNoPromptContent ; + private resolvePromise: (input: boolean) => void; + private rejectPromise: (reason?: any) => void; + private input: boolean; + public waitForClose: Promise; + private didSubmit: boolean = false; + + public static Prompt(app: App, header: string, text?: string): Promise { + const newPromptModal = new GenericYesNoPrompt(app, header, text); + return newPromptModal.waitForClose; + } + + private constructor(app: App, header: string, text?: string) { + super(app); + + this.modalContent = new GenericYesNoPromptContent({ + target: this.contentEl, + props: { + app, + header, + text, + onSubmit: (input: boolean) => { + this.input = input; + this.didSubmit = true; + this.close(); + } + } + }); + + this.waitForClose = new Promise( + (resolve, reject) => { + this.resolvePromise = resolve; + this.rejectPromise = reject; + } + ); + + this.open(); + } + + onClose() { + super.onClose(); + this.modalContent.$destroy(); + + if(!this.didSubmit) this.rejectPromise("No answer given."); + else this.resolvePromise(this.input); + } +} \ No newline at end of file diff --git a/src/gui/GenericYesNoPrompt/GenericYesNoPromptContent.svelte b/src/gui/GenericYesNoPrompt/GenericYesNoPromptContent.svelte new file mode 100644 index 0000000..84f6813 --- /dev/null +++ b/src/gui/GenericYesNoPrompt/GenericYesNoPromptContent.svelte @@ -0,0 +1,39 @@ + + +
+

{header}

+ +

{text}

+ +
+ + +
+
+ + \ No newline at end of file diff --git a/src/gui/choiceList/AddChoiceBox.svelte b/src/gui/choiceList/AddChoiceBox.svelte index 85ab8fd..ef7d5a4 100644 --- a/src/gui/choiceList/AddChoiceBox.svelte +++ b/src/gui/choiceList/AddChoiceBox.svelte @@ -7,6 +7,7 @@ let type: ChoiceType; const dispatch = createEventDispatcher(); + function addChoice() { if (!name) { new Notice("Choice name is invalid."); diff --git a/src/gui/choiceList/RightButtons.svelte b/src/gui/choiceList/ChoiceItemRightButtons.svelte similarity index 63% rename from src/gui/choiceList/RightButtons.svelte rename to src/gui/choiceList/ChoiceItemRightButtons.svelte index 946d8f4..4aedb19 100644 --- a/src/gui/choiceList/RightButtons.svelte +++ b/src/gui/choiceList/ChoiceItemRightButtons.svelte @@ -1,14 +1,23 @@
- + {#if showConfigureButton} + + {/if} -
+
@@ -29,6 +38,10 @@ align-items: center; } +.deleteChoiceButton:hover { + cursor: pointer; +} + .alignIconInDivInMiddle { display: flex; align-items: center; diff --git a/src/gui/choiceList/ChoiceList.svelte b/src/gui/choiceList/ChoiceList.svelte index 1f21336..1dd42c5 100644 --- a/src/gui/choiceList/ChoiceList.svelte +++ b/src/gui/choiceList/ChoiceList.svelte @@ -45,6 +45,7 @@ bind:dragDisabled={dragDisabled} on:mousedown={startDrag} on:touchstart={startDrag} + on:deleteChoice bind:choice /> {:else} @@ -52,6 +53,7 @@ bind:dragDisabled={dragDisabled} on:mousedown={startDrag} on:touchstart={startDrag} + on:deleteChoice bind:collapseId bind:choice /> diff --git a/src/gui/choiceList/ChoiceListItem.svelte b/src/gui/choiceList/ChoiceListItem.svelte index d7d80e5..47d2986 100644 --- a/src/gui/choiceList/ChoiceListItem.svelte +++ b/src/gui/choiceList/ChoiceListItem.svelte @@ -1,9 +1,16 @@
@@ -12,6 +19,8 @@
diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte index 576c923..b072ca8 100644 --- a/src/gui/choiceList/ChoiceView.svelte +++ b/src/gui/choiceList/ChoiceView.svelte @@ -3,7 +3,6 @@ import {ChoiceType} from "../../types/choices/choiceType"; import ChoiceList from "./ChoiceList.svelte"; import IMultiChoice from "../../types/choices/IMultiChoice"; - import {v4 as uuidv4} from "uuid"; import AddChoiceBox from "./AddChoiceBox.svelte"; import type ITemplateChoice from "../../types/choices/ITemplateChoice"; import {TemplateChoice} from "../../types/choices/TemplateChoice"; @@ -12,30 +11,13 @@ import type ICaptureChoice from "../../types/choices/ICaptureChoice"; import {CaptureChoice} from "../../types/choices/CaptureChoice"; import {MultiChoice} from "../../types/choices/MultiChoice"; + import GenericYesNoPrompt from "../GenericYesNoPrompt/GenericYesNoPrompt"; + import {App} from "obsidian"; - export let choices: IChoice[] = [ - {name: 'πŸšΆβ€β™‚οΈ Journal', type: ChoiceType.Template, id: uuidv4()}, - {name: 'πŸ“– Log Book to Daily Journal', type: ChoiceType.Template, id: uuidv4()}, - { - name: 'πŸ“₯ Add...', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ - {name: 'πŸ’­ Add a Thought', type: ChoiceType.Capture, id: uuidv4()}, - {name: 'πŸ“₯ Add an Inbox Item', type: ChoiceType.Template, id: uuidv4()}, - {name: 'πŸ“• Add Book Notes', type: ChoiceType.Template, id: uuidv4()}, - ] - }, - {name: "✍ Quick Capture", type: ChoiceType.Capture, id: uuidv4()}, - {name: 'πŸ’¬ Add Quote Page', type: ChoiceType.Template, id: uuidv4()}, - { - name: 'πŸŒ€ Task Manager', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ - {name: 'βœ” Add a Task', type: ChoiceType.Macro, id: uuidv4()}, - {name: 'βœ” Quick Capture Task', type: ChoiceType.Capture, id: uuidv4()}, - {name: 'βœ” Add MetaEdit Backlog Task', type: ChoiceType.Capture, id: uuidv4()}, - ] - }, - {name: 'πŸ’Έ Add Purchase', type: ChoiceType.Capture, id: uuidv4()} - ]; + export let choices: IChoice[] = []; export let saveChoices: (choices: IChoice[]) => void; + export let app: App; function addChoiceToList(event: any): void { const {name, type} = event.detail; @@ -58,10 +40,20 @@ choices = [...choices, multiChoice]; break; } + + saveChoices(choices); } - function deleteChoice(id: string) { + async function deleteChoice(e: any) { + const {choiceId: id, choiceName} = e.detail; + + const userConfirmed: boolean = await GenericYesNoPrompt.Prompt(app, + `Confirm deletion of choice`, `Please confirm that you wish to delete '${choiceName}.'`); + + if (userConfirmed) { choices = choices.filter((value, index, array) => deleteChoiceHelper(id, value, index, array)); + saveChoices(choices); + } } function deleteChoiceHelper(id: string, value: IChoice, index: number, array: IChoice[]): boolean { @@ -72,13 +64,11 @@ } return value.id !== id; - - }

Choices

- +
diff --git a/src/gui/choiceList/MultiChoiceListItem.svelte b/src/gui/choiceList/MultiChoiceListItem.svelte index c2c233a..25b7368 100644 --- a/src/gui/choiceList/MultiChoiceListItem.svelte +++ b/src/gui/choiceList/MultiChoiceListItem.svelte @@ -3,11 +3,20 @@ import {faChevronDown} from "@fortawesome/free-solid-svg-icons"; import ChoiceList from "./ChoiceList.svelte"; import IMultiChoice from "../../types/choices/IMultiChoice"; - import RightButtons from "./RightButtons.svelte"; + import RightButtons from "./ChoiceItemRightButtons.svelte"; + import {createEventDispatcher} from "svelte"; export let choice: IMultiChoice; export let collapseId: string; export let dragDisabled: boolean; + let showConfigureButton: boolean = false; + + const dispatcher = createEventDispatcher(); + + function deleteChoice(e: any) { + dispatcher('deleteChoice', {choiceId: choice.id, choiceName: choice.name}); + } +
@@ -20,6 +29,8 @@
diff --git a/src/main.ts b/src/main.ts index f0cf621..36d0ac8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,10 @@ import {Plugin} from 'obsidian'; -import {DEFAULT_SETTINGS, QuickAddSettingsTab} from "./quickAddSettingsTab"; - - +import {DEFAULT_SETTINGS, QuickAddSettings, QuickAddSettingsTab} from "./quickAddSettingsTab"; +import {ChoiceType} from "./types/choices/choiceType"; +import type IMultiChoice from "./types/choices/IMultiChoice"; +import {v4 as uuidv4} from "uuid"; export default class QuickAdd extends Plugin { - settings: QuickAddSettingsTab; + settings: QuickAddSettings; async onload() { console.log('Loading QuickAdd'); @@ -29,6 +30,38 @@ export default class QuickAdd extends Plugin { }); /*END.DEVCMD*/ + /*START.DEVCMD*/ + this.addCommand({ + id: 'giveDivChoices', + name: 'Give Dev Choices', + callback: () => { + this.settings.choices = [ + {name: 'πŸšΆβ€β™‚οΈ Journal', type: ChoiceType.Template, id: uuidv4()}, + {name: 'πŸ“– Log Book to Daily Journal', type: ChoiceType.Template, id: uuidv4()}, + { + name: 'πŸ“₯ Add...', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ + {name: 'πŸ’­ Add a Thought', type: ChoiceType.Capture, id: uuidv4()}, + {name: 'πŸ“₯ Add an Inbox Item', type: ChoiceType.Template, id: uuidv4()}, + {name: 'πŸ“• Add Book Notes', type: ChoiceType.Template, id: uuidv4()}, + ] + }, + {name: "✍ Quick Capture", type: ChoiceType.Capture, id: uuidv4()}, + {name: 'πŸ’¬ Add Quote Page', type: ChoiceType.Template, id: uuidv4()}, + { + name: 'πŸŒ€ Task Manager', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ + {name: 'βœ” Add a Task', type: ChoiceType.Macro, id: uuidv4()}, + {name: 'βœ” Quick Capture Task', type: ChoiceType.Capture, id: uuidv4()}, + {name: 'βœ” Add MetaEdit Backlog Task', type: ChoiceType.Capture, id: uuidv4()}, + ] + }, + {name: 'πŸ’Έ Add Purchase', type: ChoiceType.Capture, id: uuidv4()} + ]; + + this.saveSettings(); + } + }) + /*END.DEVCMD*/ + this.addSettingTab(new QuickAddSettingsTab(this.app, this)); } diff --git a/src/quickAddSettingsTab.ts b/src/quickAddSettingsTab.ts index c7bae5a..c03dc1a 100644 --- a/src/quickAddSettingsTab.ts +++ b/src/quickAddSettingsTab.ts @@ -27,10 +27,16 @@ export class QuickAddSettingsTab extends PluginSettingTab { containerEl.createEl('h2', {text: 'QuickAdd Settings'}); const choicesDiv = containerEl.createDiv('choices'); - this.choiceList = new ChoiceList({ target: choicesDiv, - // props: {} + props: { + app: this.app, + choices: this.plugin.settings.choices, + saveChoices: async (choices: IChoice[]) => { + this.plugin.settings.choices = choices; + await this.plugin.saveSettings(); + } + } }) } From d1578fee35295401318b6c4691207296088f7f62 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Thu, 10 Jun 2021 17:17:25 +0200 Subject: [PATCH 11/29] Choice suggester, add choices & Fix deletion --- src/gui/choiceList/ChoiceView.svelte | 12 ++-- src/gui/choiceList/MultiChoiceListItem.svelte | 6 +- src/gui/choiceSuggester.ts | 71 +++++++++++++++++++ src/main.ts | 42 +++++------ src/quickAddSettingsTab.ts | 21 ++++-- src/types/choices/MultiChoice.ts | 12 +++- 6 files changed, 125 insertions(+), 39 deletions(-) create mode 100644 src/gui/choiceSuggester.ts diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte index b072ca8..1aaf1a4 100644 --- a/src/gui/choiceList/ChoiceView.svelte +++ b/src/gui/choiceList/ChoiceView.svelte @@ -51,16 +51,15 @@ `Confirm deletion of choice`, `Please confirm that you wish to delete '${choiceName}.'`); if (userConfirmed) { - choices = choices.filter((value, index, array) => deleteChoiceHelper(id, value, index, array)); + choices = choices.filter((value, index, array) => deleteChoiceHelper(id, value)); saveChoices(choices); } } - function deleteChoiceHelper(id: string, value: IChoice, index: number, array: IChoice[]): boolean { - if (value instanceof MultiChoice) { - value.choices = value.choices.filter(this); - - return true; + function deleteChoiceHelper(id: string, value: IChoice): boolean { + if (value.type === ChoiceType.Multi) { + (value as IMultiChoice).choices = (value as IMultiChoice).choices + .filter((value) => deleteChoiceHelper(id, value)); } return value.id !== id; @@ -68,7 +67,6 @@
-

Choices

diff --git a/src/gui/choiceList/MultiChoiceListItem.svelte b/src/gui/choiceList/MultiChoiceListItem.svelte index 25b7368..fa218ca 100644 --- a/src/gui/choiceList/MultiChoiceListItem.svelte +++ b/src/gui/choiceList/MultiChoiceListItem.svelte @@ -38,7 +38,11 @@ {#if !collapseId || (collapseId && choice.id !== collapseId)} {#if !choice.collapsed}
- +
{/if} {/if} diff --git a/src/gui/choiceSuggester.ts b/src/gui/choiceSuggester.ts new file mode 100644 index 0000000..1ee3cb0 --- /dev/null +++ b/src/gui/choiceSuggester.ts @@ -0,0 +1,71 @@ +import {FuzzySuggestModal} from "obsidian"; +import type IChoice from "../types/choices/IChoice"; +import type QuickAdd from "../main"; +import {ChoiceType} from "../types/choices/choiceType"; +import type IMultiChoice from "../types/choices/IMultiChoice"; +import {MultiChoice} from "../types/choices/MultiChoice"; +import type ITemplateChoice from "../types/choices/ITemplateChoice"; +import type ICaptureChoice from "../types/choices/ICaptureChoice"; +import type IMacroChoice from "../types/choices/IMacroChoice"; + +export default class ChoiceSuggester extends FuzzySuggestModal { + public static Open(plugin: QuickAdd, choices: IChoice[]) { + new ChoiceSuggester(plugin, choices).open(); + } + + constructor(private plugin: QuickAdd, private choices: IChoice[]) { + super(plugin.app); + } + + getItemText(item: IChoice): string { + return item.name; + } + + getItems(): IChoice[] { + return this.choices; + } + + onChooseItem(item: IChoice, evt: MouseEvent | KeyboardEvent): void { + switch (item.type) { + case ChoiceType.Multi: + const multiChoice: IMultiChoice = item as IMultiChoice; + this.chooseMultiType(multiChoice); + break; + case ChoiceType.Template: + const templateChoice: ITemplateChoice = item as ITemplateChoice; + this.chooseTemplateType(templateChoice); + break; + case ChoiceType.Capture: + const captureChoice: ICaptureChoice = item as ICaptureChoice; + this.chooseCaptureType(captureChoice); + break; + case ChoiceType.Macro: + const macroChoice: IMacroChoice = item as IMacroChoice; + this.chooseMacroType(macroChoice); + break; + default: + break; + } + } + + private chooseMultiType(multi: IMultiChoice) { + const choices = [...multi.choices]; + + if (multi.name != "← Back") + choices.push(new MultiChoice("← Back").addChoices(this.choices)) + + ChoiceSuggester.Open(this.plugin, choices); + } + + private chooseTemplateType(templateChoice: ITemplateChoice) { + if (!templateChoice.templatePath) return; + } + + private chooseCaptureType(captureChoice: ICaptureChoice) { + if (!captureChoice.captureTo) return; + } + + private chooseMacroType(macroChoice: IMacroChoice) { + if (macroChoice.macro.commands.length === 0) return; + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 36d0ac8..8e938e9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,10 @@ import {Plugin} from 'obsidian'; import {DEFAULT_SETTINGS, QuickAddSettings, QuickAddSettingsTab} from "./quickAddSettingsTab"; -import {ChoiceType} from "./types/choices/choiceType"; -import type IMultiChoice from "./types/choices/IMultiChoice"; -import {v4 as uuidv4} from "uuid"; +import {TemplateChoice} from "./types/choices/TemplateChoice"; +import {MultiChoice} from "./types/choices/MultiChoice"; +import {CaptureChoice} from "./types/choices/CaptureChoice"; +import {MacroChoice} from "./types/choices/MacroChoice"; +import ChoiceSuggester from "./gui/choiceSuggester"; export default class QuickAdd extends Plugin { settings: QuickAddSettings; @@ -15,7 +17,7 @@ export default class QuickAdd extends Plugin { id: 'runQuickAdd', name: 'Run QuickAdd', callback: () => { - + ChoiceSuggester.Open(this, this.settings.choices); } }) @@ -36,25 +38,19 @@ export default class QuickAdd extends Plugin { name: 'Give Dev Choices', callback: () => { this.settings.choices = [ - {name: 'πŸšΆβ€β™‚οΈ Journal', type: ChoiceType.Template, id: uuidv4()}, - {name: 'πŸ“– Log Book to Daily Journal', type: ChoiceType.Template, id: uuidv4()}, - { - name: 'πŸ“₯ Add...', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ - {name: 'πŸ’­ Add a Thought', type: ChoiceType.Capture, id: uuidv4()}, - {name: 'πŸ“₯ Add an Inbox Item', type: ChoiceType.Template, id: uuidv4()}, - {name: 'πŸ“• Add Book Notes', type: ChoiceType.Template, id: uuidv4()}, - ] - }, - {name: "✍ Quick Capture", type: ChoiceType.Capture, id: uuidv4()}, - {name: 'πŸ’¬ Add Quote Page', type: ChoiceType.Template, id: uuidv4()}, - { - name: 'πŸŒ€ Task Manager', type: ChoiceType.Multi, id: uuidv4(), collapsed: false, choices: [ - {name: 'βœ” Add a Task', type: ChoiceType.Macro, id: uuidv4()}, - {name: 'βœ” Quick Capture Task', type: ChoiceType.Capture, id: uuidv4()}, - {name: 'βœ” Add MetaEdit Backlog Task', type: ChoiceType.Capture, id: uuidv4()}, - ] - }, - {name: 'πŸ’Έ Add Purchase', type: ChoiceType.Capture, id: uuidv4()} + new TemplateChoice("πŸšΆβ€β™‚οΈ Journal"), + new TemplateChoice('πŸ“– Log Book to Daily Journal'), + new MultiChoice('πŸ“₯ Add...') + .addChoice(new CaptureChoice('πŸ’­ Add a Thought')) + .addChoice(new CaptureChoice('πŸ“₯ Add an Inbox Item')) + .addChoice(new TemplateChoice('πŸ“• Add Book Notes')), + new CaptureChoice("✍ Quick Capture"), + new TemplateChoice('πŸ’¬ Add Quote Page'), + new MultiChoice('πŸŒ€ Task Manager') + .addChoice(new MacroChoice('βœ” Add a Task')) + .addChoice(new CaptureChoice('βœ” Quick Capture Task')) + .addChoice(new CaptureChoice('βœ” Add MetaEdit Backlog Task')), + new CaptureChoice('πŸ’Έ Add Purchase'), ]; this.saveSettings(); diff --git a/src/quickAddSettingsTab.ts b/src/quickAddSettingsTab.ts index c03dc1a..6b96c37 100644 --- a/src/quickAddSettingsTab.ts +++ b/src/quickAddSettingsTab.ts @@ -23,12 +23,23 @@ export class QuickAddSettingsTab extends PluginSettingTab { display(): void { let {containerEl} = this; containerEl.empty(); - containerEl.createEl('h2', {text: 'QuickAdd Settings'}); - const choicesDiv = containerEl.createDiv('choices'); + + this.addChoicesSetting(); + } + + hide(): any { + if (this.choiceList) + this.choiceList.$destroy(); + } + + private addChoicesSetting(): void { + const setting = new Setting(this.containerEl); + setting.infoEl.remove(); + setting.settingEl.style.display = ""; this.choiceList = new ChoiceList({ - target: choicesDiv, + target: setting.settingEl, props: { app: this.app, choices: this.plugin.settings.choices, @@ -39,8 +50,4 @@ export class QuickAddSettingsTab extends PluginSettingTab { } }) } - - hide(): any { - this.choiceList.$destroy(); - } } \ No newline at end of file diff --git a/src/types/choices/MultiChoice.ts b/src/types/choices/MultiChoice.ts index cd9b6f1..1a78954 100644 --- a/src/types/choices/MultiChoice.ts +++ b/src/types/choices/MultiChoice.ts @@ -4,10 +4,20 @@ import {ChoiceType} from "./choiceType"; import type IMultiChoice from "./IMultiChoice"; export class MultiChoice extends Choice implements IMultiChoice { - choices: IChoice[]; + choices: IChoice[] = []; collapsed: boolean; constructor(name: string) { super(name, ChoiceType.Multi); } + + public addChoice(choice: IChoice): MultiChoice { + this.choices.push(choice); + return this; + } + + public addChoices(choices: IChoice[]): MultiChoice { + this.choices.push(...choices); + return this; + } } \ No newline at end of file From d7dd77cab47e7b12199e514964e313aeb4ad7924 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Thu, 10 Jun 2021 17:18:42 +0200 Subject: [PATCH 12/29] Update ChoiceView.svelte --- src/gui/choiceList/ChoiceView.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte index 1aaf1a4..6410db8 100644 --- a/src/gui/choiceList/ChoiceView.svelte +++ b/src/gui/choiceList/ChoiceView.svelte @@ -51,7 +51,7 @@ `Confirm deletion of choice`, `Please confirm that you wish to delete '${choiceName}.'`); if (userConfirmed) { - choices = choices.filter((value, index, array) => deleteChoiceHelper(id, value)); + choices = choices.filter((value) => deleteChoiceHelper(id, value)); saveChoices(choices); } } From df8ee4cbe295cff84c0e52ff5cbfbeec152329a4 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Thu, 10 Jun 2021 21:05:38 +0200 Subject: [PATCH 13/29] Basic choice builder GUI --- package.json | 12 +- src/gui/ChoiceBuilder/choiceBuilder.ts | 34 +++ .../ChoiceBuilder/templateChoiceBuilder.ts | 37 ++++ .../choiceList/ChoiceItemRightButtons.svelte | 6 +- src/gui/choiceList/ChoiceList.svelte | 2 + src/gui/choiceList/ChoiceListItem.svelte | 5 + src/gui/choiceList/ChoiceView.svelte | 42 +++- src/gui/choiceList/MultiChoiceListItem.svelte | 5 + src/gui/choiceSuggester.ts | 24 ++- src/gui/genericTextSuggester.ts | 31 +++ src/gui/suggest.ts | 197 ++++++++++++++++++ src/quickAddSettingsTab.ts | 2 +- 12 files changed, 377 insertions(+), 20 deletions(-) create mode 100644 src/gui/ChoiceBuilder/choiceBuilder.ts create mode 100644 src/gui/ChoiceBuilder/templateChoiceBuilder.ts create mode 100644 src/gui/genericTextSuggester.ts create mode 100644 src/gui/suggest.ts diff --git a/package.json b/package.json index f16317f..400031d 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,9 @@ "@babel/core": "7.14.3", "@babel/preset-env": "7.14.2", "@babel/preset-typescript": "7.13.0", + "@fortawesome/free-regular-svg-icons": "5.15.3", + "@fortawesome/free-solid-svg-icons": "5.15.3", + "@popperjs/core": "^2.9.2", "@rollup/plugin-commonjs": "^18.0.0", "@rollup/plugin-node-resolve": "^11.2.1", "@rollup/plugin-typescript": "^8.2.1", @@ -31,18 +34,13 @@ "rollup-plugin-strip-code": "0.2.7", "rollup-plugin-svelte": "^7.1.0", "svelte": "^3.37.0", + "svelte-awesome": "2.3.2", "svelte-check": "^1.3.0", "svelte-dnd-action": "0.9.8", "svelte-preprocess": "^4.7.0", "ts-jest": "27.0.0", "tslib": "^2.2.0", - "typescript": "^4.2.4" - }, - "dependencies": { - "@fortawesome/free-regular-svg-icons": "5.15.3", - "@fortawesome/free-solid-svg-icons": "5.15.3", - "@popperjs/core": "^2.9.2", - "svelte-awesome": "2.3.2", + "typescript": "^4.2.4", "uuid": "8.3.2" } } diff --git a/src/gui/ChoiceBuilder/choiceBuilder.ts b/src/gui/ChoiceBuilder/choiceBuilder.ts new file mode 100644 index 0000000..81dddd6 --- /dev/null +++ b/src/gui/ChoiceBuilder/choiceBuilder.ts @@ -0,0 +1,34 @@ +import {App, Modal} from "obsidian"; +import type IChoice from "../../types/choices/IChoice"; + +export abstract class ChoiceBuilder extends Modal { + private resolvePromise: (input: IChoice) => void; + private rejectPromise: (reason?: any) => void; + private input: IChoice; + public waitForClose: Promise; + abstract choice: IChoice; + private didSubmit: boolean = false; + + protected constructor(app: App) { + super(app); + + this.waitForClose = new Promise( + (resolve, reject) => { + this.resolvePromise = resolve; + this.rejectPromise = reject; + } + ); + + this.open(); + } + + protected abstract display(); + + onClose() { + super.onClose(); + this.resolvePromise(this.choice); + + if(!this.didSubmit) this.rejectPromise("No answer given."); + else this.resolvePromise(this.input); + } +} \ No newline at end of file diff --git a/src/gui/ChoiceBuilder/templateChoiceBuilder.ts b/src/gui/ChoiceBuilder/templateChoiceBuilder.ts new file mode 100644 index 0000000..045cae6 --- /dev/null +++ b/src/gui/ChoiceBuilder/templateChoiceBuilder.ts @@ -0,0 +1,37 @@ +import {ChoiceBuilder} from "./choiceBuilder"; +import {App, Setting} from "obsidian"; +import type ITemplateChoice from "../../types/choices/ITemplateChoice"; +import {GenericTextSuggester} from "../genericTextSuggester"; + +export class TemplateChoiceBuilder extends ChoiceBuilder { + choice: ITemplateChoice; + + constructor(app: App, choice: ITemplateChoice) { + super(app); + this.choice = choice; + + this.display(); + } + + protected display() { + this.addTemplatePathSetting(); + } + + private addTemplatePathSetting(): void { + new Setting(this.contentEl) + .setName('Template Path') + .setDesc('Path to the Template.') + .addSearch(searchComponent => { + console.log() + searchComponent.setValue(this.choice.templatePath); + + const markdownFiles = this.app.vault.getMarkdownFiles().map(f => f.path) + const suggester = new GenericTextSuggester(this.app, searchComponent.inputEl, markdownFiles); + + searchComponent.onChange(value => { + this.choice.templatePath = value; + }) + }); + } + +} \ No newline at end of file diff --git a/src/gui/choiceList/ChoiceItemRightButtons.svelte b/src/gui/choiceList/ChoiceItemRightButtons.svelte index 4aedb19..9b12aab 100644 --- a/src/gui/choiceList/ChoiceItemRightButtons.svelte +++ b/src/gui/choiceList/ChoiceItemRightButtons.svelte @@ -10,11 +10,15 @@ function emitDeleteChoice() { dispatcher('deleteChoice'); } + + function emitConfigureChoice() { + dispatcher('configureChoice'); + }
{#if showConfigureButton} - + {/if}
diff --git a/src/gui/choiceList/ChoiceList.svelte b/src/gui/choiceList/ChoiceList.svelte index 1dd42c5..4b017b2 100644 --- a/src/gui/choiceList/ChoiceList.svelte +++ b/src/gui/choiceList/ChoiceList.svelte @@ -46,6 +46,7 @@ on:mousedown={startDrag} on:touchstart={startDrag} on:deleteChoice + on:configureChoice bind:choice /> {:else} @@ -54,6 +55,7 @@ on:mousedown={startDrag} on:touchstart={startDrag} on:deleteChoice + on:configureChoice bind:collapseId bind:choice /> diff --git a/src/gui/choiceList/ChoiceListItem.svelte b/src/gui/choiceList/ChoiceListItem.svelte index 47d2986..fb7115d 100644 --- a/src/gui/choiceList/ChoiceListItem.svelte +++ b/src/gui/choiceList/ChoiceListItem.svelte @@ -11,6 +11,10 @@ function deleteChoice() { dispatcher('deleteChoice', {choiceId: choice.id, choiceName: choice.name}); } + + function configureChoice() { + dispatcher('configureChoice', {choice}); + }
@@ -20,6 +24,7 @@ on:mousedown on:touchstart on:deleteChoice={deleteChoice} + on:configureChoice={configureChoice} bind:showConfigureButton bind:dragDisabled /> diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte index 6410db8..32b6cfd 100644 --- a/src/gui/choiceList/ChoiceView.svelte +++ b/src/gui/choiceList/ChoiceView.svelte @@ -13,6 +13,7 @@ import {MultiChoice} from "../../types/choices/MultiChoice"; import GenericYesNoPrompt from "../GenericYesNoPrompt/GenericYesNoPrompt"; import {App} from "obsidian"; + import {TemplateChoiceBuilder} from "../ChoiceBuilder/templateChoiceBuilder"; export let choices: IChoice[] = []; @@ -59,14 +60,51 @@ function deleteChoiceHelper(id: string, value: IChoice): boolean { if (value.type === ChoiceType.Multi) { (value as IMultiChoice).choices = (value as IMultiChoice).choices - .filter((value) => deleteChoiceHelper(id, value)); + .filter((v) => deleteChoiceHelper(id, v)); } return value.id !== id; } + + async function configureChoice(e: any) { + const {choice: oldChoice} = e.detail; + const updatedChoice = await getChoiceBuilder(oldChoice).waitForClose; + if (!updatedChoice) return; + + choices = choices.map(choice => updateChoiceHelper(choice, updatedChoice)); + saveChoices(choices); + } + + function updateChoiceHelper(oldChoice: IChoice, newChoice: IChoice) { + if (oldChoice.id === newChoice.id) + return newChoice; + + if (oldChoice.type === ChoiceType.Multi) { + (oldChoice as IMultiChoice).choices.map(c => updateChoiceHelper(c, newChoice)) + } + + return oldChoice; + } + + function getChoiceBuilder(choice: IChoice) { + switch (choice.type) { + case ChoiceType.Template: + return new TemplateChoiceBuilder(app, choice as ITemplateChoice); + case ChoiceType.Capture: + case ChoiceType.Macro: + case ChoiceType.Multi: + break; + default: + break; + } + }
- +
diff --git a/src/gui/choiceList/MultiChoiceListItem.svelte b/src/gui/choiceList/MultiChoiceListItem.svelte index fa218ca..de7bb5b 100644 --- a/src/gui/choiceList/MultiChoiceListItem.svelte +++ b/src/gui/choiceList/MultiChoiceListItem.svelte @@ -17,6 +17,9 @@ dispatcher('deleteChoice', {choiceId: choice.id, choiceName: choice.name}); } + function configureChoice() { + dispatcher('configureChoice', {choice}); + }
@@ -30,6 +33,7 @@ on:mousedown on:touchstart on:deleteChoice={deleteChoice} + on:configureChoice={configureChoice} bind:showConfigureButton bind:dragDisabled /> @@ -40,6 +44,7 @@
diff --git a/src/gui/choiceSuggester.ts b/src/gui/choiceSuggester.ts index 1ee3cb0..9e1f207 100644 --- a/src/gui/choiceSuggester.ts +++ b/src/gui/choiceSuggester.ts @@ -29,26 +29,26 @@ export default class ChoiceSuggester extends FuzzySuggestModal { switch (item.type) { case ChoiceType.Multi: const multiChoice: IMultiChoice = item as IMultiChoice; - this.chooseMultiType(multiChoice); + this.onChooseMultiType(multiChoice); break; case ChoiceType.Template: const templateChoice: ITemplateChoice = item as ITemplateChoice; - this.chooseTemplateType(templateChoice); + this.onChooseTemplateType(templateChoice); break; case ChoiceType.Capture: const captureChoice: ICaptureChoice = item as ICaptureChoice; - this.chooseCaptureType(captureChoice); + this.onChooseCaptureType(captureChoice); break; case ChoiceType.Macro: const macroChoice: IMacroChoice = item as IMacroChoice; - this.chooseMacroType(macroChoice); + this.onChooseMacroType(macroChoice); break; default: break; } } - private chooseMultiType(multi: IMultiChoice) { + private onChooseMultiType(multi: IMultiChoice) { const choices = [...multi.choices]; if (multi.name != "← Back") @@ -57,15 +57,21 @@ export default class ChoiceSuggester extends FuzzySuggestModal { ChoiceSuggester.Open(this.plugin, choices); } - private chooseTemplateType(templateChoice: ITemplateChoice) { - if (!templateChoice.templatePath) return; + private onChooseTemplateType(templateChoice: ITemplateChoice) { + // if (!templateChoice.templatePath) return; + + // @ts-ignore + const useTemplater: boolean = this.app.plugins.plugins["templater-obsidian"]; + + // @ts-ignore + console.log(useTemplater.templater.create_new_note_from_template); } - private chooseCaptureType(captureChoice: ICaptureChoice) { + private onChooseCaptureType(captureChoice: ICaptureChoice) { if (!captureChoice.captureTo) return; } - private chooseMacroType(macroChoice: IMacroChoice) { + private onChooseMacroType(macroChoice: IMacroChoice) { if (macroChoice.macro.commands.length === 0) return; } } \ No newline at end of file diff --git a/src/gui/genericTextSuggester.ts b/src/gui/genericTextSuggester.ts new file mode 100644 index 0000000..45a4c3f --- /dev/null +++ b/src/gui/genericTextSuggester.ts @@ -0,0 +1,31 @@ +import {TextInputSuggest} from "./suggest"; +import type {App} from "obsidian"; + +export class GenericTextSuggester extends TextInputSuggest { + + constructor(public app: App, public inputEl: HTMLInputElement, private items: string[]) { + super(app, inputEl); + } + + getSuggestions(inputStr: string): string[] { + const inputLowerCase: string = inputStr.toLowerCase(); + const filtered = this.items.filter(item => { + if (item.toLowerCase().contains(inputLowerCase)) + return item; + }); + + if (!filtered) this.close(); + if (filtered?.length > 0) return filtered; + } + + selectSuggestion(item: string): void { + this.inputEl.value = item; + this.inputEl.trigger("input"); + this.close(); + } + + renderSuggestion(value: string, el: HTMLElement): void { + if (value) + el.setText(value); + } +} \ No newline at end of file diff --git a/src/gui/suggest.ts b/src/gui/suggest.ts new file mode 100644 index 0000000..1e0c10e --- /dev/null +++ b/src/gui/suggest.ts @@ -0,0 +1,197 @@ +// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes + +import { App, ISuggestOwner, Scope} from "obsidian"; +import { createPopper, Instance as PopperInstance } from "@popperjs/core"; + +const wrapAround = (value: number, size: number): number => { + return ((value % size) + size) % size; +}; + +class Suggest { + private owner: ISuggestOwner; + private values: T[]; + private suggestions: HTMLDivElement[]; + private selectedItem: number; + private containerEl: HTMLElement; + + constructor(owner: ISuggestOwner, containerEl: HTMLElement, scope: Scope) { + this.owner = owner; + this.containerEl = containerEl; + + containerEl.on( + "click", + ".suggestion-item", + this.onSuggestionClick.bind(this) + ); + containerEl.on( + "mousemove", + ".suggestion-item", + this.onSuggestionMouseover.bind(this) + ); + + scope.register([], "ArrowUp", (event) => { + if (!event.isComposing) { + this.setSelectedItem(this.selectedItem - 1, true); + return false; + } + }); + + scope.register([], "ArrowDown", (event) => { + if (!event.isComposing) { + this.setSelectedItem(this.selectedItem + 1, true); + return false; + } + }); + + scope.register([], "Enter", (event) => { + if (!event.isComposing) { + this.useSelectedItem(event); + return false; + } + }); + } + + onSuggestionClick(event: MouseEvent, el: HTMLDivElement): void { + event.preventDefault(); + + const item = this.suggestions.indexOf(el); + this.setSelectedItem(item, false); + this.useSelectedItem(event); + } + + onSuggestionMouseover(_event: MouseEvent, el: HTMLDivElement): void { + const item = this.suggestions.indexOf(el); + this.setSelectedItem(item, false); + } + + setSuggestions(values: T[]) { + this.containerEl.empty(); + const suggestionEls: HTMLDivElement[] = []; + + values.forEach((value) => { + const suggestionEl = this.containerEl.createDiv("suggestion-item"); + this.owner.renderSuggestion(value, suggestionEl); + suggestionEls.push(suggestionEl); + }); + + this.values = values; + this.suggestions = suggestionEls; + this.setSelectedItem(0, false); + } + + useSelectedItem(event: MouseEvent | KeyboardEvent) { + const currentValue = this.values[this.selectedItem]; + if (currentValue) { + this.owner.selectSuggestion(currentValue, event); + } + } + + setSelectedItem(selectedIndex: number, scrollIntoView: boolean) { + const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length); + const prevSelectedSuggestion = this.suggestions[this.selectedItem]; + const selectedSuggestion = this.suggestions[normalizedIndex]; + + prevSelectedSuggestion?.removeClass("is-selected"); + selectedSuggestion?.addClass("is-selected"); + + this.selectedItem = normalizedIndex; + + if (scrollIntoView) { + selectedSuggestion.scrollIntoView(false); + } + } +} + +export abstract class TextInputSuggest implements ISuggestOwner { + protected app: App; + protected inputEl: HTMLInputElement; + + private popper: PopperInstance; + private scope: Scope; + private suggestEl: HTMLElement; + private suggest: Suggest; + + constructor(app: App, inputEl: HTMLInputElement) { + this.app = app; + this.inputEl = inputEl; + this.scope = new Scope(); + + this.suggestEl = createDiv("suggestion-container"); + const suggestion = this.suggestEl.createDiv("suggestion"); + this.suggest = new Suggest(this, suggestion, this.scope); + + this.scope.register([], "Escape", this.close.bind(this)); + + this.inputEl.addEventListener("input", this.onInputChanged.bind(this)); + this.inputEl.addEventListener("focus", this.onInputChanged.bind(this)); + this.inputEl.addEventListener("blur", this.close.bind(this)); + this.suggestEl.on( + "mousedown", + ".suggestion-container", + (event: MouseEvent) => { + event.preventDefault(); + } + ); + } + + onInputChanged(): void { + const inputStr = this.inputEl.value; + const suggestions = this.getSuggestions(inputStr); + + if (!suggestions) { + this.close(); + return; + } + + if (suggestions.length > 0) { + this.suggest.setSuggestions(suggestions); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + this.open((this.app).dom.appContainerEl, this.inputEl); + } else { + this.close() + } + } + + open(container: HTMLElement, inputEl: HTMLElement): void { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (this.app).keymap.pushScope(this.scope); + + container.appendChild(this.suggestEl); + this.popper = createPopper(inputEl, this.suggestEl, { + placement: "bottom-start", + modifiers: [ + { + name: "sameWidth", + enabled: true, + fn: ({ state, instance }) => { + // Note: positioning needs to be calculated twice - + // first pass - positioning it according to the width of the popper + // second pass - position it with the width bound to the reference element + // we need to early exit to avoid an infinite loop + const targetWidth = `${state.rects.reference.width}px`; + if (state.styles.popper.width === targetWidth) { + return; + } + state.styles.popper.width = targetWidth; + instance.update(); + }, + phase: "beforeWrite", + requires: ["computeStyles"], + }, + ], + }); + } + + close(): void { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (this.app).keymap.popScope(this.scope); + + this.suggest.setSuggestions([]); + this.popper.destroy(); + this.suggestEl.detach(); + } + + abstract getSuggestions(inputStr: string): T[]; + abstract renderSuggestion(item: T, el: HTMLElement): void; + abstract selectSuggestion(item: T): void; +} \ No newline at end of file diff --git a/src/quickAddSettingsTab.ts b/src/quickAddSettingsTab.ts index 6b96c37..52ebcdc 100644 --- a/src/quickAddSettingsTab.ts +++ b/src/quickAddSettingsTab.ts @@ -36,7 +36,7 @@ export class QuickAddSettingsTab extends PluginSettingTab { private addChoicesSetting(): void { const setting = new Setting(this.containerEl); setting.infoEl.remove(); - setting.settingEl.style.display = ""; + setting.settingEl.style.display = "block"; this.choiceList = new ChoiceList({ target: setting.settingEl, From d6f8de739bbafb229dda3b9763e1f26258f90669 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Fri, 11 Jun 2021 09:51:46 +0200 Subject: [PATCH 14/29] Template Choice Builder progress --- src/constants.ts | 9 ++++ src/gui/ChoiceBuilder/choiceBuilder.ts | 6 +++ .../ChoiceBuilder/templateChoiceBuilder.ts | 47 +++++++++++++++++-- src/gui/formatSyntaxSuggester.ts | 23 +++++++++ src/gui/genericTextSuggester.ts | 1 - src/gui/suggest.ts | 4 +- src/types/choices/ITemplateChoice.ts | 1 - src/types/choices/TemplateChoice.ts | 12 ++++- 8 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 src/constants.ts create mode 100644 src/gui/formatSyntaxSuggester.ts diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..92dfca4 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,9 @@ +export const FORMAT_SYNTAX: string[] = [ + "{{DATE}}", "{{DATE:}}", "{{VDATE:, }}", + "{{VALUE}}", "{{NAME}}", "{{VALUE:}}", "{{LINKCURRENT}}" +]; + +export const FILE_NAME_FORMAT_SYNTAX: string[] = [ + "{{DATE}}", "{{DATE:}}", "{{VDATE:, }}", + "{{VALUE}}", "{{NAME}}", "{{VALUE:}}", +] \ No newline at end of file diff --git a/src/gui/ChoiceBuilder/choiceBuilder.ts b/src/gui/ChoiceBuilder/choiceBuilder.ts index 81dddd6..4077fa6 100644 --- a/src/gui/ChoiceBuilder/choiceBuilder.ts +++ b/src/gui/ChoiceBuilder/choiceBuilder.ts @@ -24,6 +24,12 @@ export abstract class ChoiceBuilder extends Modal { protected abstract display(); + protected addCenteredHeader(header: string): void { + const headerEl = this.contentEl.createEl('h2'); + headerEl.style.textAlign = "center"; + headerEl.setText(header); + } + onClose() { super.onClose(); this.resolvePromise(this.choice); diff --git a/src/gui/ChoiceBuilder/templateChoiceBuilder.ts b/src/gui/ChoiceBuilder/templateChoiceBuilder.ts index 045cae6..5a577ea 100644 --- a/src/gui/ChoiceBuilder/templateChoiceBuilder.ts +++ b/src/gui/ChoiceBuilder/templateChoiceBuilder.ts @@ -1,7 +1,9 @@ import {ChoiceBuilder} from "./choiceBuilder"; -import {App, Setting} from "obsidian"; +import {App, Setting, TextAreaComponent, TextComponent} from "obsidian"; import type ITemplateChoice from "../../types/choices/ITemplateChoice"; import {GenericTextSuggester} from "../genericTextSuggester"; +import {FormatSyntaxSuggester} from "../formatSyntaxSuggester"; +import {FILE_NAME_FORMAT_SYNTAX} from "../../constants"; export class TemplateChoiceBuilder extends ChoiceBuilder { choice: ITemplateChoice; @@ -14,7 +16,15 @@ export class TemplateChoiceBuilder extends ChoiceBuilder { } protected display() { + this.contentEl.style.width = "3/3"; + this.addCenteredHeader(this.choice.name); this.addTemplatePathSetting(); + this.addFileNameFormatSetting(); + this.addFolderSetting(); + this.addAppendLinkSetting(); + this.addIncrementFileNameSetting(); + this.addNoOpenSetting(); + this.addNewTabSetting(); } private addTemplatePathSetting(): void { @@ -22,11 +32,10 @@ export class TemplateChoiceBuilder extends ChoiceBuilder { .setName('Template Path') .setDesc('Path to the Template.') .addSearch(searchComponent => { - console.log() searchComponent.setValue(this.choice.templatePath); const markdownFiles = this.app.vault.getMarkdownFiles().map(f => f.path) - const suggester = new GenericTextSuggester(this.app, searchComponent.inputEl, markdownFiles); + new GenericTextSuggester(this.app, searchComponent.inputEl, markdownFiles); searchComponent.onChange(value => { this.choice.templatePath = value; @@ -34,4 +43,36 @@ export class TemplateChoiceBuilder extends ChoiceBuilder { }); } + private addFileNameFormatSetting(): void { + let textField: TextComponent; + const enableSetting = new Setting(this.contentEl); + enableSetting.setName("File Name Format") + .setDesc("Set the file name format.") + .addToggle(toggleComponent => { + toggleComponent.setValue(this.choice.fileNameFormat.enabled) + .onChange(value => { + this.choice.fileNameFormat.enabled = value; + textField.setDisabled(!value); + }) + }); + + const formatInput = new TextComponent(this.contentEl); + textField = formatInput; + formatInput.inputEl.style.width = "100%"; + formatInput.setValue(this.choice.fileNameFormat.format) + .setDisabled(!this.choice.fileNameFormat.enabled) + .onChange(value => this.choice.fileNameFormat.format = value); + + new FormatSyntaxSuggester(this.app, textField.inputEl, FILE_NAME_FORMAT_SYNTAX); + } + + private addFolderSetting(): void {} + + private addAppendLinkSetting(): void {} + + private addIncrementFileNameSetting(): void {} + + private addNoOpenSetting(): void {} + + private addNewTabSetting(): void {} } \ No newline at end of file diff --git a/src/gui/formatSyntaxSuggester.ts b/src/gui/formatSyntaxSuggester.ts new file mode 100644 index 0000000..197c552 --- /dev/null +++ b/src/gui/formatSyntaxSuggester.ts @@ -0,0 +1,23 @@ +import {TextInputSuggest} from "./suggest"; +import type {App} from "obsidian"; + +export class FormatSyntaxSuggester extends TextInputSuggest { + constructor(public app: App, public inputEl: HTMLInputElement | HTMLTextAreaElement, private items: string[]) { + super(app, inputEl); + } + + getSuggestions(inputStr: string): string[] { + return this.items; + } + + selectSuggestion(item: string): void { + this.inputEl.value += item; + this.inputEl.trigger("input"); + this.close(); + } + + renderSuggestion(value: string, el: HTMLElement): void { + if (value) + el.setText(value); + } +} \ No newline at end of file diff --git a/src/gui/genericTextSuggester.ts b/src/gui/genericTextSuggester.ts index 45a4c3f..1e073b4 100644 --- a/src/gui/genericTextSuggester.ts +++ b/src/gui/genericTextSuggester.ts @@ -2,7 +2,6 @@ import {TextInputSuggest} from "./suggest"; import type {App} from "obsidian"; export class GenericTextSuggester extends TextInputSuggest { - constructor(public app: App, public inputEl: HTMLInputElement, private items: string[]) { super(app, inputEl); } diff --git a/src/gui/suggest.ts b/src/gui/suggest.ts index 1e0c10e..60d0292 100644 --- a/src/gui/suggest.ts +++ b/src/gui/suggest.ts @@ -104,14 +104,14 @@ class Suggest { export abstract class TextInputSuggest implements ISuggestOwner { protected app: App; - protected inputEl: HTMLInputElement; + protected inputEl: HTMLInputElement | HTMLTextAreaElement; private popper: PopperInstance; private scope: Scope; private suggestEl: HTMLElement; private suggest: Suggest; - constructor(app: App, inputEl: HTMLInputElement) { + constructor(app: App, inputEl: HTMLInputElement | HTMLTextAreaElement) { this.app = app; this.inputEl = inputEl; this.scope = new Scope(); diff --git a/src/types/choices/ITemplateChoice.ts b/src/types/choices/ITemplateChoice.ts index 8c3c486..e33a357 100644 --- a/src/types/choices/ITemplateChoice.ts +++ b/src/types/choices/ITemplateChoice.ts @@ -2,7 +2,6 @@ import type IChoice from "./IChoice"; export default interface ITemplateChoice extends IChoice { templatePath: string; - startSymbol: { enabled: boolean, symbol: string }; folder: { enabled: boolean, folders: string[] } fileNameFormat: { enabled: boolean, format: string }; appendLink: boolean; diff --git a/src/types/choices/TemplateChoice.ts b/src/types/choices/TemplateChoice.ts index 05e8036..6200176 100644 --- a/src/types/choices/TemplateChoice.ts +++ b/src/types/choices/TemplateChoice.ts @@ -9,10 +9,20 @@ export class TemplateChoice extends Choice implements ITemplateChoice { incrementFileName: boolean; newTab: { enabled: boolean; direction: "vertical" | "horizontal" }; noOpen: boolean; - startSymbol: { enabled: boolean; symbol: string }; templatePath: string; constructor(name: string) { super(name, ChoiceType.Template); + + this.fileNameFormat = {enabled: false, format: ""}; + this.folder = {enabled: false, folders: []}; + this.newTab = {enabled: false, direction: "vertical"}; + this.appendLink = false; + this.incrementFileName = false; + this.noOpen = false; + } + + public static Load(choice: ITemplateChoice): TemplateChoice { + return choice as TemplateChoice; } } \ No newline at end of file From bf47a021a626bc644d27c1deb4734fe328598752 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Fri, 11 Jun 2021 09:51:58 +0200 Subject: [PATCH 15/29] Update templateChoiceBuilder.ts --- src/gui/ChoiceBuilder/templateChoiceBuilder.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/ChoiceBuilder/templateChoiceBuilder.ts b/src/gui/ChoiceBuilder/templateChoiceBuilder.ts index 5a577ea..5e6edf1 100644 --- a/src/gui/ChoiceBuilder/templateChoiceBuilder.ts +++ b/src/gui/ChoiceBuilder/templateChoiceBuilder.ts @@ -16,7 +16,6 @@ export class TemplateChoiceBuilder extends ChoiceBuilder { } protected display() { - this.contentEl.style.width = "3/3"; this.addCenteredHeader(this.choice.name); this.addTemplatePathSetting(); this.addFileNameFormatSetting(); From c01cea5e8a578f9bb323dacaff2aadbf33cba45f Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Fri, 11 Jun 2021 11:56:31 +0200 Subject: [PATCH 16/29] Template Choice Builder --- src/gui/ChoiceBuilder/FolderList.svelte | 38 +++++++ src/gui/ChoiceBuilder/choiceBuilder.ts | 9 ++ .../ChoiceBuilder/templateChoiceBuilder.ts | 105 ++++++++++++++++-- src/gui/choiceList/ChoiceList.svelte | 9 ++ src/gui/choiceList/ChoiceView.svelte | 4 +- src/gui/suggest.ts | 3 +- src/types/choices/ITemplateChoice.ts | 5 +- src/types/choices/TemplateChoice.ts | 9 +- src/types/newTabDirection.ts | 3 + 9 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 src/gui/ChoiceBuilder/FolderList.svelte create mode 100644 src/types/newTabDirection.ts diff --git a/src/gui/ChoiceBuilder/FolderList.svelte b/src/gui/ChoiceBuilder/FolderList.svelte new file mode 100644 index 0000000..814a251 --- /dev/null +++ b/src/gui/ChoiceBuilder/FolderList.svelte @@ -0,0 +1,38 @@ + + +
+ {#each folders as folder, i} +
+ {folder} + deleteFolder(folder)} class="clickable"> + + +
+ {/each} +
+ + \ No newline at end of file diff --git a/src/gui/ChoiceBuilder/choiceBuilder.ts b/src/gui/ChoiceBuilder/choiceBuilder.ts index 4077fa6..bbe07b4 100644 --- a/src/gui/ChoiceBuilder/choiceBuilder.ts +++ b/src/gui/ChoiceBuilder/choiceBuilder.ts @@ -1,5 +1,6 @@ import {App, Modal} from "obsidian"; import type IChoice from "../../types/choices/IChoice"; +import type {SvelteComponent} from "svelte"; export abstract class ChoiceBuilder extends Modal { private resolvePromise: (input: IChoice) => void; @@ -8,6 +9,7 @@ export abstract class ChoiceBuilder extends Modal { public waitForClose: Promise; abstract choice: IChoice; private didSubmit: boolean = false; + protected svelteElements: SvelteComponent[] = []; protected constructor(app: App) { super(app); @@ -23,6 +25,10 @@ export abstract class ChoiceBuilder extends Modal { } protected abstract display(); + protected reload() { + this.contentEl.empty(); + this.display(); + } protected addCenteredHeader(header: string): void { const headerEl = this.contentEl.createEl('h2'); @@ -33,6 +39,9 @@ export abstract class ChoiceBuilder extends Modal { onClose() { super.onClose(); this.resolvePromise(this.choice); + this.svelteElements.forEach(el => { + if (el && el.$destroy) el.$destroy(); + }) if(!this.didSubmit) this.rejectPromise("No answer given."); else this.resolvePromise(this.input); diff --git a/src/gui/ChoiceBuilder/templateChoiceBuilder.ts b/src/gui/ChoiceBuilder/templateChoiceBuilder.ts index 5e6edf1..5a0f4a9 100644 --- a/src/gui/ChoiceBuilder/templateChoiceBuilder.ts +++ b/src/gui/ChoiceBuilder/templateChoiceBuilder.ts @@ -1,9 +1,11 @@ import {ChoiceBuilder} from "./choiceBuilder"; -import {App, Setting, TextAreaComponent, TextComponent} from "obsidian"; +import {App, SearchComponent, Setting, TextComponent, TFolder} from "obsidian"; import type ITemplateChoice from "../../types/choices/ITemplateChoice"; import {GenericTextSuggester} from "../genericTextSuggester"; import {FormatSyntaxSuggester} from "../formatSyntaxSuggester"; import {FILE_NAME_FORMAT_SYNTAX} from "../../constants"; +import {NewTabDirection} from "../../types/newTabDirection"; +import FolderList from "./FolderList.svelte"; export class TemplateChoiceBuilder extends ChoiceBuilder { choice: ITemplateChoice; @@ -22,8 +24,9 @@ export class TemplateChoiceBuilder extends ChoiceBuilder { this.addFolderSetting(); this.addAppendLinkSetting(); this.addIncrementFileNameSetting(); - this.addNoOpenSetting(); - this.addNewTabSetting(); + this.addOpenFileSetting(); + if (this.choice.openFile) + this.addOpenFileInNewTabSetting(); } private addTemplatePathSetting(): void { @@ -56,8 +59,10 @@ export class TemplateChoiceBuilder extends ChoiceBuilder { }); const formatInput = new TextComponent(this.contentEl); + formatInput.setPlaceholder("File name format"); textField = formatInput; formatInput.inputEl.style.width = "100%"; + formatInput.inputEl.style.marginBottom = "8px"; formatInput.setValue(this.choice.fileNameFormat.format) .setDisabled(!this.choice.fileNameFormat.enabled) .onChange(value => this.choice.fileNameFormat.format = value); @@ -65,13 +70,97 @@ export class TemplateChoiceBuilder extends ChoiceBuilder { new FormatSyntaxSuggester(this.app, textField.inputEl, FILE_NAME_FORMAT_SYNTAX); } - private addFolderSetting(): void {} + private addFolderSetting(): void { + const folderSetting: Setting = new Setting(this.contentEl); + folderSetting.setName("Create in folder") + .setDesc("Create the file in the specified folder. If multiple folders are specified, you will be prompted for which folder to create the file in.") + .addToggle(toggle => { + toggle.setValue(this.choice.folder.enabled); + toggle.onChange(value => this.choice.folder.enabled = value); + }); + + const folderList: HTMLDivElement = this.contentEl.createDiv('folderList'); + + const folderListEl = new FolderList({ + target: folderList, + props: { + folders: this.choice.folder.folders, + deleteFolder: (folder: string) => { + this.choice.folder.folders = this.choice.folder.folders.filter(f => f !== folder); + folderListEl.updateFolders(this.choice.folder.folders); + } + } + }); + + this.svelteElements.push(folderListEl); - private addAppendLinkSetting(): void {} + const folderInput = new TextComponent(this.contentEl); + folderInput.setPlaceholder("Folder path"); + folderInput.inputEl.style.width = "100%"; + folderInput.inputEl.style.marginBottom = "8px"; + const folders: string[] = this.app.vault.getAllLoadedFiles() + .filter(f => f instanceof TFolder) + .map(folder => folder.path); - private addIncrementFileNameSetting(): void {} + new GenericTextSuggester(this.app, folderInput.inputEl, folders); - private addNoOpenSetting(): void {} + folderInput.inputEl.addEventListener('keypress', (e: KeyboardEvent) => { + const input = folderInput.inputEl.value.trim(); + if (e.key === 'Enter' && !this.choice.folder.folders.some(folder => folder === input)) { + this.choice.folder.folders.push(input); + folderListEl.updateFolders(this.choice.folder.folders); + folderInput.inputEl.value = ""; + } + }) + } + + private addAppendLinkSetting(): void { + const appendLinkSetting: Setting = new Setting(this.contentEl); + appendLinkSetting.setName("Append link") + .setDesc("Append link to created file to current file.") + .addToggle(toggle => { + toggle.setValue(this.choice.appendLink); + toggle.onChange(value => this.choice.appendLink = value); + }) + } - private addNewTabSetting(): void {} + private addIncrementFileNameSetting(): void { + const incrementFileNameSetting: Setting = new Setting(this.contentEl); + incrementFileNameSetting.setName("Increment file name") + .setDesc("If the file already exists, increment the file name.") + .addToggle(toggle => { + toggle.setValue(this.choice.incrementFileName); + toggle.onChange(value => this.choice.incrementFileName = value); + }) + } + + private addOpenFileSetting(): void { + const noOpenSetting: Setting = new Setting(this.contentEl); + noOpenSetting.setName("Open") + .setDesc("Open the created file.") + .addToggle(toggle => { + toggle.setValue(this.choice.openFile); + toggle.onChange(value => { + this.choice.openFile = value; + this.reload(); + }); + }) + } + + private addOpenFileInNewTabSetting(): void { + const newTabSetting = new Setting(this.contentEl); + newTabSetting.setName("New Tab") + .setDesc("Open created file in a new tab.") + .addToggle(toggle => { + toggle.setValue(this.choice.openFileInNewTab.enabled); + toggle.onChange(value => this.choice.openFileInNewTab.enabled = value); + }) + .addDropdown(dropdown => { + dropdown.selectEl.style.marginLeft = "10px"; + dropdown.addOption(NewTabDirection.vertical, "Vertical"); + dropdown.addOption(NewTabDirection.horizontal, "Horizontal"); + dropdown.setValue(this.choice.openFileInNewTab.direction); + dropdown.onChange(value => this.choice.openFileInNewTab.direction = value); + }); + } } \ No newline at end of file diff --git a/src/gui/choiceList/ChoiceList.svelte b/src/gui/choiceList/ChoiceList.svelte index 4b017b2..5ec878c 100644 --- a/src/gui/choiceList/ChoiceList.svelte +++ b/src/gui/choiceList/ChoiceList.svelte @@ -4,11 +4,18 @@ import MultiChoiceListItem from "./MultiChoiceListItem.svelte"; import {ChoiceType} from "../../types/choices/choiceType"; import {DndEvent, dndzone, SHADOW_PLACEHOLDER_ITEM_ID, SOURCES} from "svelte-dnd-action"; + import {createEventDispatcher} from "svelte"; export let choices: IChoice[] = []; let collapseId: string; let dragDisabled: boolean = true; + const dispatcher = createEventDispatcher(); + + function emitChoicesReordered() { + dispatcher('reorderChoices', {choices}); + } + function handleConsider(e: CustomEvent) { let {items: newItems, info: {id}} = e.detail; collapseId = id; @@ -25,6 +32,8 @@ if (source === SOURCES.POINTER) { dragDisabled = true; } + + emitChoicesReordered(); } function startDrag(e: CustomEvent) { diff --git a/src/gui/choiceList/ChoiceView.svelte b/src/gui/choiceList/ChoiceView.svelte index 32b6cfd..9dd1b79 100644 --- a/src/gui/choiceList/ChoiceView.svelte +++ b/src/gui/choiceList/ChoiceView.svelte @@ -105,6 +105,8 @@ type="main" bind:choices on:deleteChoice={deleteChoice} - on:configureChoice={configureChoice}/> + on:configureChoice={configureChoice} + on:reorderChoices={e => saveChoices(e.detail.choices)} + />
diff --git a/src/gui/suggest.ts b/src/gui/suggest.ts index 60d0292..072d6d0 100644 --- a/src/gui/suggest.ts +++ b/src/gui/suggest.ts @@ -187,7 +187,8 @@ export abstract class TextInputSuggest implements ISuggestOwner { (this.app).keymap.popScope(this.scope); this.suggest.setSuggestions([]); - this.popper.destroy(); + if (this.popper) + this.popper.destroy(); this.suggestEl.detach(); } diff --git a/src/types/choices/ITemplateChoice.ts b/src/types/choices/ITemplateChoice.ts index e33a357..4878d69 100644 --- a/src/types/choices/ITemplateChoice.ts +++ b/src/types/choices/ITemplateChoice.ts @@ -1,4 +1,5 @@ import type IChoice from "./IChoice"; +import type {NewTabDirection} from "../newTabDirection"; export default interface ITemplateChoice extends IChoice { templatePath: string; @@ -6,6 +7,6 @@ export default interface ITemplateChoice extends IChoice { fileNameFormat: { enabled: boolean, format: string }; appendLink: boolean; incrementFileName: boolean; - noOpen: boolean; - newTab: {enabled: boolean, direction: "vertical" | "horizontal"}; + openFile: boolean; + openFileInNewTab: {enabled: boolean, direction: NewTabDirection}; } \ No newline at end of file diff --git a/src/types/choices/TemplateChoice.ts b/src/types/choices/TemplateChoice.ts index 6200176..5e15cfd 100644 --- a/src/types/choices/TemplateChoice.ts +++ b/src/types/choices/TemplateChoice.ts @@ -1,14 +1,15 @@ import {ChoiceType} from "./choiceType"; import type ITemplateChoice from "./ITemplateChoice"; import {Choice} from "./Choice"; +import {NewTabDirection} from "../newTabDirection"; export class TemplateChoice extends Choice implements ITemplateChoice { appendLink: boolean; fileNameFormat: { enabled: boolean; format: string }; folder: { enabled: boolean; folders: string[] }; incrementFileName: boolean; - newTab: { enabled: boolean; direction: "vertical" | "horizontal" }; - noOpen: boolean; + openFileInNewTab: { enabled: boolean; direction: NewTabDirection }; + openFile: boolean; templatePath: string; constructor(name: string) { @@ -16,10 +17,10 @@ export class TemplateChoice extends Choice implements ITemplateChoice { this.fileNameFormat = {enabled: false, format: ""}; this.folder = {enabled: false, folders: []}; - this.newTab = {enabled: false, direction: "vertical"}; + this.openFileInNewTab = {enabled: false, direction: NewTabDirection.vertical}; this.appendLink = false; this.incrementFileName = false; - this.noOpen = false; + this.openFile = false; } public static Load(choice: ITemplateChoice): TemplateChoice { diff --git a/src/types/newTabDirection.ts b/src/types/newTabDirection.ts new file mode 100644 index 0000000..62367b4 --- /dev/null +++ b/src/types/newTabDirection.ts @@ -0,0 +1,3 @@ +export enum NewTabDirection { + vertical = "vertical", horizontal = "horizontal" +} \ No newline at end of file From 0cebb8edef6336dba7b45391e2ff8ced41788f54 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Fri, 11 Jun 2021 12:26:09 +0200 Subject: [PATCH 17/29] TemplateBuilder: Folder list grid --- src/gui/ChoiceBuilder/FolderList.svelte | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/ChoiceBuilder/FolderList.svelte b/src/gui/ChoiceBuilder/FolderList.svelte index 814a251..0884e7e 100644 --- a/src/gui/ChoiceBuilder/FolderList.svelte +++ b/src/gui/ChoiceBuilder/FolderList.svelte @@ -9,7 +9,7 @@ } -
+
{#each folders as folder, i}
{folder} @@ -27,11 +27,20 @@ justify-content: space-between; } +@media (min-width: 768px) { + .quickAddFolderListGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + column-gap: 20px; + } +} + .quickAddFolderList { max-width: 50%; margin: 12px auto; } + .clickable { cursor: pointer; } From 973eed910de6de4916f1e792c86e58a9ae98305a Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Fri, 11 Jun 2021 12:29:50 +0200 Subject: [PATCH 18/29] Update AddChoiceBox.svelte --- src/gui/choiceList/AddChoiceBox.svelte | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/choiceList/AddChoiceBox.svelte b/src/gui/choiceList/AddChoiceBox.svelte index ef7d5a4..85529ad 100644 --- a/src/gui/choiceList/AddChoiceBox.svelte +++ b/src/gui/choiceList/AddChoiceBox.svelte @@ -28,7 +28,7 @@ - +
\ No newline at end of file From 21129c45165bc82e8553dac953e645979eca9bb4 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Fri, 11 Jun 2021 12:34:10 +0200 Subject: [PATCH 19/29] Change configure button to cog icon --- src/gui/choiceList/ChoiceItemRightButtons.svelte | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/gui/choiceList/ChoiceItemRightButtons.svelte b/src/gui/choiceList/ChoiceItemRightButtons.svelte index 9b12aab..058f14f 100644 --- a/src/gui/choiceList/ChoiceItemRightButtons.svelte +++ b/src/gui/choiceList/ChoiceItemRightButtons.svelte @@ -1,5 +1,5 @@ + +
+ {#each commands as command, i} +
+ {i+1}. {command.name} + deleteCommand(command)} class="clickable"> + + +
+ {/each} +
+ + diff --git a/src/gui/ChoiceBuilder/FolderList.svelte b/src/gui/ChoiceBuilder/FolderList.svelte index 0884e7e..22825b6 100644 --- a/src/gui/ChoiceBuilder/FolderList.svelte +++ b/src/gui/ChoiceBuilder/FolderList.svelte @@ -9,9 +9,9 @@ } -
+
{#each folders as folder, i} -
+
{folder} deleteFolder(folder)} class="clickable"> @@ -21,7 +21,7 @@
\ No newline at end of file diff --git a/src/gui/choiceSuggester.ts b/src/gui/choiceSuggester.ts index 6a4c716..693111e 100644 --- a/src/gui/choiceSuggester.ts +++ b/src/gui/choiceSuggester.ts @@ -10,6 +10,7 @@ import type IMacroChoice from "../types/choices/IMacroChoice"; import {TemplateChoiceEngine} from "../engine/TemplateChoiceEngine"; import {log} from "../logger/logManager"; import {CaptureChoiceEngine} from "../engine/CaptureChoiceEngine"; +import {MacroChoiceEngine} from "../engine/MacroChoiceEngine"; export default class ChoiceSuggester extends FuzzySuggestModal { public static Open(plugin: QuickAdd, choices: IChoice[]) { @@ -44,7 +45,7 @@ export default class ChoiceSuggester extends FuzzySuggestModal { break; case ChoiceType.Macro: const macroChoice: IMacroChoice = item as IMacroChoice; - this.onChooseMacroType(macroChoice); + await this.onChooseMacroType(macroChoice); break; default: break; @@ -78,7 +79,9 @@ export default class ChoiceSuggester extends FuzzySuggestModal { await new CaptureChoiceEngine(this.app, captureChoice).run(); } - private onChooseMacroType(macroChoice: IMacroChoice) { + private async onChooseMacroType(macroChoice: IMacroChoice) { if (macroChoice.macro.commands.length === 0) return; + + await new MacroChoiceEngine(this.app, macroChoice, this.plugin).run(); } } \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 7c1cd91..da82146 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,7 +6,6 @@ import {CaptureChoice} from "./types/choices/CaptureChoice"; import {MacroChoice} from "./types/choices/MacroChoice"; import ChoiceSuggester from "./gui/choiceSuggester"; import {log} from "./logger/logManager"; -import {QuickAddLogger} from "./logger/quickAddLogger"; import {ConsoleErrorLogger} from "./logger/consoleErrorLogger"; import {GuiLogger} from "./logger/guiLogger"; diff --git a/src/quickAddApi.ts b/src/quickAddApi.ts new file mode 100644 index 0000000..421dfd9 --- /dev/null +++ b/src/quickAddApi.ts @@ -0,0 +1,26 @@ +import GenericInputPrompt from "./gui/GenericInputPrompt/genericInputPrompt"; +import GenericYesNoPrompt from "./gui/GenericYesNoPrompt/GenericYesNoPrompt"; +import GenericSuggester from "./gui/GenericSuggester/genericSuggester"; +import type {App} from "obsidian"; + +export class QuickAddApi { + public static GetApi(app: App) { + return { + inputPrompt: (header: string, placeholder?: string, value?: string) => {return this.inputPrompt(app, header, placeholder, value)}, + yesNoPrompt: (header: string, text?: string) => {return this.yesNoPrompt(app, header, text)}, + suggester: (displayItems: string[], actualItems: string[]) => {return this.suggester(app, displayItems, actualItems)} + }; + } + + public static async inputPrompt(app: App, header: string, placeholder?: string, value?: string) { + return await GenericInputPrompt.Prompt(app, header, placeholder, value); + } + + public static async yesNoPrompt(app: App, header: string, text?: string) { + return await GenericYesNoPrompt.Prompt(app, header, text); + } + + public static async suggester(app: App, displayItems: string[], actualItems: string[]) { + return await GenericSuggester.Suggest(app, displayItems, actualItems); + } +} \ No newline at end of file diff --git a/src/quickAddSettingsTab.ts b/src/quickAddSettingsTab.ts index 52ebcdc..2eee471 100644 --- a/src/quickAddSettingsTab.ts +++ b/src/quickAddSettingsTab.ts @@ -1,19 +1,22 @@ import {App, PluginSettingTab, Setting} from "obsidian"; import type QuickAdd from "./main"; import type IChoice from "./types/choices/IChoice"; -import ChoiceList from "./gui/choiceList/ChoiceView.svelte" +import ChoiceView from "./gui/choiceList/ChoiceView.svelte" +import type {IMacro} from "./types/macros/IMacro"; export interface QuickAddSettings { choices: IChoice[]; + macros: IMacro[]; } export const DEFAULT_SETTINGS: QuickAddSettings = { - choices: [] + choices: [], + macros: [] } export class QuickAddSettingsTab extends PluginSettingTab { public plugin: QuickAdd; - private choiceList: ChoiceList; + private choiceView: ChoiceView; constructor(app: App, plugin: QuickAdd) { super(app, plugin); @@ -29,8 +32,8 @@ export class QuickAddSettingsTab extends PluginSettingTab { } hide(): any { - if (this.choiceList) - this.choiceList.$destroy(); + if (this.choiceView) + this.choiceView.$destroy(); } private addChoicesSetting(): void { @@ -38,7 +41,7 @@ export class QuickAddSettingsTab extends PluginSettingTab { setting.infoEl.remove(); setting.settingEl.style.display = "block"; - this.choiceList = new ChoiceList({ + this.choiceView = new ChoiceView({ target: setting.settingEl, props: { app: this.app, @@ -46,8 +49,14 @@ export class QuickAddSettingsTab extends PluginSettingTab { saveChoices: async (choices: IChoice[]) => { this.plugin.settings.choices = choices; await this.plugin.saveSettings(); + }, + macros: this.plugin.settings.macros, + saveMacros: async (macros: IMacro[]) => { + this.plugin.settings.macros = macros; + console.log(1); + await this.plugin.saveSettings(); } } - }) + }); } } \ No newline at end of file diff --git a/src/types/choices/MacroChoice.ts b/src/types/choices/MacroChoice.ts index 9d58f72..5eadc12 100644 --- a/src/types/choices/MacroChoice.ts +++ b/src/types/choices/MacroChoice.ts @@ -9,6 +9,6 @@ export class MacroChoice extends Choice implements IMacroChoice { constructor(name: string) { super(name, ChoiceType.Macro); - this.macro = { commands: [] }; + this.macro = null; } } \ No newline at end of file diff --git a/src/types/macros/Command.ts b/src/types/macros/Command.ts index bb6fdf0..bcdf524 100644 --- a/src/types/macros/Command.ts +++ b/src/types/macros/Command.ts @@ -1,12 +1,15 @@ import type {CommandType} from "./CommandType"; import type {ICommand} from "./ICommand"; +import {v4 as uuidv4} from "uuid"; export abstract class Command implements ICommand { name: string; type: CommandType; + id: string; protected constructor(name: string, type: CommandType) { this.name = name; this.type = type; + this.id = uuidv4(); } } \ No newline at end of file diff --git a/src/types/macros/ICommand.ts b/src/types/macros/ICommand.ts index bdce0f9..962b441 100644 --- a/src/types/macros/ICommand.ts +++ b/src/types/macros/ICommand.ts @@ -3,5 +3,6 @@ import type {CommandType} from "./CommandType"; export interface ICommand { name: string; type: CommandType + id: string; } diff --git a/src/types/macros/IMacro.ts b/src/types/macros/IMacro.ts index acec2ea..8e15d14 100644 --- a/src/types/macros/IMacro.ts +++ b/src/types/macros/IMacro.ts @@ -1,5 +1,9 @@ import type {ICommand} from "./ICommand"; export interface IMacro { + name: string; + id: string; commands: ICommand[]; -} \ No newline at end of file + runOnStartup: boolean; +} + diff --git a/src/types/macros/IObsidianCommand.ts b/src/types/macros/IObsidianCommand.ts index 4d1a8cf..ca81d94 100644 --- a/src/types/macros/IObsidianCommand.ts +++ b/src/types/macros/IObsidianCommand.ts @@ -1,6 +1,6 @@ import type {ICommand} from "./ICommand"; export interface IObsidianCommand extends ICommand { - id: string; + commandId: string; } diff --git a/src/types/macros/ObsidianCommand.ts b/src/types/macros/ObsidianCommand.ts index a7148d7..902fc59 100644 --- a/src/types/macros/ObsidianCommand.ts +++ b/src/types/macros/ObsidianCommand.ts @@ -5,10 +5,11 @@ import type {IObsidianCommand} from "./IObsidianCommand"; export class ObsidianCommand extends Command implements IObsidianCommand { name: string; id: string; + commandId: string; type: CommandType; - constructor(name: string, id: string) { + constructor(name: string, commandId: string) { super(name, CommandType.Obsidian); - this.id = id; + this.commandId = commandId; } } \ No newline at end of file diff --git a/src/types/macros/QuickAddMacro.ts b/src/types/macros/QuickAddMacro.ts new file mode 100644 index 0000000..aad213c --- /dev/null +++ b/src/types/macros/QuickAddMacro.ts @@ -0,0 +1,17 @@ +import type {ICommand} from "./ICommand"; +import type {IMacro} from "./IMacro"; +import {v4 as uuidv4} from "uuid"; + +export class QuickAddMacro implements IMacro { + id: string; + name: string; + commands: ICommand[]; + runOnStartup: boolean; + + constructor(name: string) { + this.name = name; + this.id = uuidv4(); + this.commands = []; + this.runOnStartup = false; + } +} \ No newline at end of file diff --git a/styles.css b/styles.css index e69de29..80e95e7 100644 --- a/styles.css +++ b/styles.css @@ -0,0 +1,31 @@ +.configureMacroDiv { + display: grid; + grid-template-rows: 1fr; +} + +.configureMacroDivItem { + display: flex; + align-content: center; + justify-content: space-between; + margin-bottom: 10px; +} + +.configureMacroDivItemButton { + display: flex; + align-content: center; + justify-content: center; + margin-bottom: 10px; +} + +.macroContainer { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-gap: 40px; +} + +.addMacroBarContainer { + display: flex; + align-content: center; + justify-content: space-around; + margin-top: 20px; +} \ No newline at end of file From 68592a546151d1315b8a6a09fb79767f9c842b70 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Sat, 12 Jun 2021 03:25:05 +0200 Subject: [PATCH 26/29] Startup macro execution --- src/engine/MacroChoiceEngine.ts | 14 +++++++++----- src/engine/StartupMacroEngine.ts | 17 +++++++++++++++++ src/gui/choiceSuggester.ts | 2 +- src/main.ts | 3 +++ 4 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 src/engine/StartupMacroEngine.ts diff --git a/src/engine/MacroChoiceEngine.ts b/src/engine/MacroChoiceEngine.ts index b9068d6..c6de9df 100644 --- a/src/engine/MacroChoiceEngine.ts +++ b/src/engine/MacroChoiceEngine.ts @@ -6,19 +6,23 @@ import type {IUserScript} from "../types/macros/IUserScript"; import type {IObsidianCommand} from "../types/macros/IObsidianCommand"; import {log} from "../logger/logManager"; import {CommandType} from "../types/macros/CommandType"; -import type QuickAdd from "../main"; import {QuickAddApi} from "../quickAddApi"; +import type {ICommand} from "../types/macros/ICommand"; export class MacroChoiceEngine extends QuickAddEngine { choice: IMacroChoice; - constructor(app: App, choice: IMacroChoice, private quickAdd: QuickAdd) { + constructor(app: App, choice: IMacroChoice) { super(app); this.choice = choice; } async run(): Promise { - for (const command of this.choice.macro.commands) { + await this.executeCommands(this.choice.macro.commands); + } + + protected async executeCommands(commands: ICommand[]) { + for (const command of commands) { if (command.type === CommandType.Obsidian) await this.executeObsidianCommand(command as IObsidianCommand); if (command.type === CommandType.UserScript) @@ -28,7 +32,7 @@ export class MacroChoiceEngine extends QuickAddEngine { // Slightly modified from Templater's user script engine: // https://github.com/SilentVoid13/Templater/blob/master/src/UserTemplates/UserTemplateParser.ts - private async executeUserScript(command: IUserScript) { + protected async executeUserScript(command: IUserScript) { // @ts-ignore const vaultPath = this.app.vault.adapter.getBasePath(); const file: TAbstractFile = this.app.vault.getAbstractFileByPath(command.path); @@ -55,7 +59,7 @@ export class MacroChoiceEngine extends QuickAddEngine { } } - private executeObsidianCommand(command: IObsidianCommand) { + protected executeObsidianCommand(command: IObsidianCommand) { // @ts-ignore this.app.commands.executeCommandById(command.id); } diff --git a/src/engine/StartupMacroEngine.ts b/src/engine/StartupMacroEngine.ts new file mode 100644 index 0000000..b7b82c2 --- /dev/null +++ b/src/engine/StartupMacroEngine.ts @@ -0,0 +1,17 @@ +import type {App} from "obsidian"; +import type {IMacro} from "../types/macros/IMacro"; +import {MacroChoiceEngine} from "./MacroChoiceEngine"; + +export class StartupMacroEngine extends MacroChoiceEngine { + constructor(app: App, private macros: IMacro[]) { + super(app, null); + } + + async run(): Promise { + this.macros.forEach(macro => { + if (macro.runOnStartup) { + this.executeCommands(macro.commands); + } + }) + } +} \ No newline at end of file diff --git a/src/gui/choiceSuggester.ts b/src/gui/choiceSuggester.ts index 693111e..988adf4 100644 --- a/src/gui/choiceSuggester.ts +++ b/src/gui/choiceSuggester.ts @@ -82,6 +82,6 @@ export default class ChoiceSuggester extends FuzzySuggestModal { private async onChooseMacroType(macroChoice: IMacroChoice) { if (macroChoice.macro.commands.length === 0) return; - await new MacroChoiceEngine(this.app, macroChoice, this.plugin).run(); + await new MacroChoiceEngine(this.app, macroChoice).run(); } } \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index da82146..2eb87ce 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,6 +8,7 @@ import ChoiceSuggester from "./gui/choiceSuggester"; import {log} from "./logger/logManager"; import {ConsoleErrorLogger} from "./logger/consoleErrorLogger"; import {GuiLogger} from "./logger/guiLogger"; +import {StartupMacroEngine} from "./engine/StartupMacroEngine"; export default class QuickAdd extends Plugin { settings: QuickAddSettings; @@ -66,6 +67,8 @@ export default class QuickAdd extends Plugin { .register(new GuiLogger(this)); this.addSettingTab(new QuickAddSettingsTab(this.app, this)); + + await new StartupMacroEngine(this.app, this.settings.macros).run(); } onunload() { From f2e9019539776a218fb1cfef4d9e2e258902692c Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Sat, 12 Jun 2021 03:51:11 +0200 Subject: [PATCH 27/29] Finishing touches --- src/MacrosManager.ts | 37 ++++++++++++++++++++++++++----------- src/quickAddSettingsTab.ts | 1 - styles.css | 15 ++++++++++++++- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/MacrosManager.ts b/src/MacrosManager.ts index 3153b64..a293c7f 100644 --- a/src/MacrosManager.ts +++ b/src/MacrosManager.ts @@ -7,6 +7,7 @@ export class MacrosManager extends Modal { public waitForClose: Promise; private resolvePromise: (macros: IMacro[]) => void; private rejectPromise: (reason?: any) => void; + private updateMacroContainer: () => void; constructor(public app: App, private macros: IMacro[]) { super(app) @@ -30,8 +31,18 @@ export class MacrosManager extends Modal { private addMacroSettings() { const macroContainer: HTMLDivElement = this.contentEl.createDiv(); - macroContainer.addClass('macroContainer'); + this.updateMacroContainer = () => { + if (this.macros.length <= 1) + macroContainer.className = "macroContainer macroContainer1"; + if (this.macros.length === 2) + macroContainer.className = "macroContainer macroContainer2"; + if (this.macros.length > 2) + macroContainer.className = "macroContainer macroContainer3"; + } + this.macros.forEach(macro => this.addMacroSetting(macro, macroContainer)); + + this.updateMacroContainer(); } private addMacroSetting(macro: IMacro, container: HTMLDivElement) { @@ -42,7 +53,7 @@ export class MacrosManager extends Modal { macroSetting.infoEl.style.fontWeight = "bold"; this.addMacroConfigurationItem(configureMacroContainer, itemContainerEl => { - this.addSpanWithText(itemContainerEl, "Run on Startup"); + this.addSpanWithText(itemContainerEl, "Run on plugin load"); const toggle: ToggleComponent = new ToggleComponent(itemContainerEl); toggle.setValue(macro.runOnStartup); @@ -56,6 +67,15 @@ export class MacrosManager extends Modal { configureMacroContainer.addClass("configureMacroDiv"); this.addMacroConfigurationItem(configureMacroContainer, itemContainerEl => { + const deleteButton: ButtonComponent = new ButtonComponent(itemContainerEl); + deleteButton.setClass('mod-warning'); + deleteButton.buttonEl.style.marginRight = "0"; + + deleteButton.setButtonText("Delete").onClick(evt => { + this.macros = this.macros.filter(m => m.id !== macro.id); + this.reload(); + }); + const configureButton: ButtonComponent = new ButtonComponent(itemContainerEl); configureButton.setClass('mod-cta'); configureButton.buttonEl.style.marginRight = "0"; @@ -68,15 +88,6 @@ export class MacrosManager extends Modal { this.reload(); } }); - - const deleteButton: ButtonComponent = new ButtonComponent(itemContainerEl); - deleteButton.setClass('mod-danger'); - deleteButton.buttonEl.style.marginRight = "0"; - - deleteButton.setButtonText("Delete").onClick(evt => { - this.macros = this.macros.filter(m => m.id !== macro.id); - this.reload(); - }); }); } @@ -96,6 +107,10 @@ export class MacrosManager extends Modal { private updateMacro(macro: IMacro) { const index = this.macros.findIndex(v => v.id === macro.id); this.macros[index] = macro; + + if (this.updateMacroContainer) + this.updateMacroContainer(); + this.reload(); } diff --git a/src/quickAddSettingsTab.ts b/src/quickAddSettingsTab.ts index 2eee471..54f3bad 100644 --- a/src/quickAddSettingsTab.ts +++ b/src/quickAddSettingsTab.ts @@ -53,7 +53,6 @@ export class QuickAddSettingsTab extends PluginSettingTab { macros: this.plugin.settings.macros, saveMacros: async (macros: IMacro[]) => { this.plugin.settings.macros = macros; - console.log(1); await this.plugin.saveSettings(); } } diff --git a/styles.css b/styles.css index 80e95e7..9ca72bd 100644 --- a/styles.css +++ b/styles.css @@ -1,6 +1,7 @@ .configureMacroDiv { display: grid; grid-template-rows: 1fr; + min-width: 12rem; } .configureMacroDivItem { @@ -19,10 +20,22 @@ .macroContainer { display: grid; - grid-template-columns: 1fr 1fr 1fr; + grid-template-rows: repeat(auto-fill, 120px); grid-gap: 40px; } +.macroContainer1 { + grid-template-columns: repeat(1, 1fr); +} + +.macroContainer2 { + grid-template-columns: repeat(2, 1fr); +} + +.macroContainer3 { + grid-template-columns: repeat(3, 1fr); +} + .addMacroBarContainer { display: flex; align-content: center; From cd5705b184f30a656283bdd37b06a8d1a22e140f Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Sat, 12 Jun 2021 03:53:03 +0200 Subject: [PATCH 28/29] Github --- .github/FUNDING.yml | 2 + .github/workflows/release.yml | 84 +++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 .github/FUNDING.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..e6050ce --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: chhoumann +custom: https://www.buymeacoffee.com/chhoumann \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6b01cd4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,84 @@ +# From https://github.com/st3v3nmw/obsidian-spaced-repetition/blob/master/.github/workflows/release.yml +name: Build obsidian plugin + +on: + push: + # Sequence of patterns matched against refs/tags + tags: + - '*' # Push events to matching any tag format, i.e. 1.0, 20.15.10 + +env: + PLUGIN_NAME: quickadd # plugin id + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js + uses: actions/setup-node@v1 + with: + node-version: '14.x' # You might need to adjust this value to your own version + - name: Build + id: build + run: | + npm install + npm run build --if-present + mkdir ${{ env.PLUGIN_NAME }} + cp main.js manifest.json styles.css ${{ env.PLUGIN_NAME }} + zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }} + ls + echo "::set-output name=tag_name::$(git tag --sort version:refname | tail -n 1)" + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ github.ref }} + with: + tag_name: ${{ github.ref }} + release_name: ${{ github.ref }} + draft: false + prerelease: false + - name: Upload zip file + id: upload-zip + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./${{ env.PLUGIN_NAME }}.zip + asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip + asset_content_type: application/zip + - name: Upload main.js + id: upload-main + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./main.js + asset_name: main.js + asset_content_type: text/javascript + - name: Upload manifest.json + id: upload-manifest + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./manifest.json + asset_name: manifest.json + asset_content_type: application/json + - name: Upload styles.css + id: upload-css + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./styles.css + asset_name: styles.css + asset_content_type: text/css \ No newline at end of file From bcd17edcd0aed1f10875bd7c6eb7afb18565e174 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Sat, 12 Jun 2021 03:53:54 +0200 Subject: [PATCH 29/29] Bump versions --- manifest.json | 2 +- package.json | 2 +- versions.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/manifest.json b/manifest.json index 094a87f..1495830 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "quickadd", "name": "QuickAdd", - "version": "0.0.0", + "version": "0.1.0", "minAppVersion": "0.12.00", "description": "Quickly add new pages or content to your vault.", "author": "Christian B. B. Houmann", diff --git a/package.json b/package.json index 400031d..389f572 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "quickadd", - "version": "0.0.0", + "version": "0.1.0", "description": "Quickly add new pages or content to your vault.", "main": "main.js", "scripts": { diff --git a/versions.json b/versions.json index 01436ec..9ccc0e8 100644 --- a/versions.json +++ b/versions.json @@ -1,3 +1,3 @@ { - "0.0.1": "0.12.4" + "0.1.0": "0.12.4" }