Skip to content

Commit e0cf304

Browse files
committed
button builder improvements
1 parent 83b3ac7 commit e0cf304

10 files changed

+112
-17
lines changed

packages/core/src/api/InternalAPI.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,21 @@ export interface TextPromptModalOptions extends ModalOptions {
5757
onCancel: () => void;
5858
}
5959

60+
export const IMAGE_FILE_EXTENSIONS = [
61+
'apng',
62+
'avif',
63+
'gif',
64+
'jpg',
65+
'jpeg',
66+
'jfif',
67+
'pjpeg',
68+
'pjp',
69+
'png',
70+
'svg',
71+
'webp',
72+
];
73+
export const IMAGE_FILE_EXTENSIONS_WITH_DOTS = IMAGE_FILE_EXTENSIONS.map(ext => `.${ext}`);
74+
6075
export abstract class InternalAPI<Plugin extends IPlugin> {
6176
readonly plugin: Plugin;
6277
readonly file: FileAPI<Plugin>;
@@ -220,6 +235,23 @@ export abstract class InternalAPI<Plugin extends IPlugin> {
220235
this.createSearchModal(new FileSelectModal(this.plugin, selectCallback)).open();
221236
}
222237

238+
openFilteredFileSelectModal(
239+
selectCallback: (selected: string) => void,
240+
filterFunction: (filePath: string) => boolean,
241+
): void {
242+
this.createSearchModal(new FileSelectModal(this.plugin, selectCallback, filterFunction)).open();
243+
}
244+
245+
openMarkdownFileSelectModal(selectCallback: (selected: string) => void): void {
246+
this.openFilteredFileSelectModal(selectCallback, filePath => filePath.endsWith('.md'));
247+
}
248+
249+
openImageFileSelectModal(selectCallback: (selected: string) => void): void {
250+
this.openFilteredFileSelectModal(selectCallback, filePath =>
251+
IMAGE_FILE_EXTENSIONS_WITH_DOTS.some(ext => filePath.endsWith(ext)),
252+
);
253+
}
254+
223255
openFolderSelectModal(selectCallback: (selected: string) => void): void {
224256
this.createSearchModal(new FolderSelectModal(this.plugin, selectCallback)).open();
225257
}

packages/core/src/modals/modalContents/buttonBuilder/ButtonBuilderModalComponent.svelte

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@
126126
127127
plugin.internal.createContextMenu(menuActions).showWithEvent(e);
128128
}
129+
130+
function changeBackgroundImage(): void {
131+
plugin.internal.openImageFileSelectModal((file: string) => {
132+
buttonConfig.backgroundImage = file;
133+
});
134+
}
129135
</script>
130136

131137
<SettingComponent name="Label" description="The label shown on the button.">
@@ -156,8 +162,10 @@
156162
</SettingComponent>
157163

158164
<SettingComponent name="Background image" description="A background image to use in the button.">
159-
<!-- TODO: make this a file selector with modal and so on -->
160-
<input type="text" bind:value={buttonConfig.backgroundImage} />
165+
<span>{buttonConfig.backgroundImage ?? 'none'}</span>
166+
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeBackgroundImage()} tooltip="Select from vault"
167+
>Select</Button
168+
>
161169
</SettingComponent>
162170

163171
<SettingComponent

packages/core/src/modals/modalContents/buttonBuilder/CommandActionSettings.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
action: CommandButtonAction;
1515
} = $props();
1616
17-
function changeCommand(action: CommandButtonAction): void {
17+
function changeCommand(): void {
1818
plugin.internal.openCommandSelectModal((command: Command) => {
1919
action.command = command.id;
2020
});
@@ -25,5 +25,5 @@
2525
name="Command: {action.command || 'none'}"
2626
description="The command to execute when this action runs."
2727
>
28-
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeCommand(action)}>Change</Button>
28+
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeCommand()}>Change</Button>
2929
</SettingComponent>

packages/core/src/modals/modalContents/buttonBuilder/CreateNoteActionSettings.svelte

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
</script>
2323

2424
<SettingComponent name="Folder: {action.folderPath || 'none'}" description="The folder to create a new note in.">
25-
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeFolderPath()}>Change</Button>
25+
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeFolderPath()} tooltip="Select from vault"
26+
>Change</Button
27+
>
2628
</SettingComponent>
2729

2830
<SettingComponent name="File name: {action.fileName || 'default'}" description="The file name of the new note.">
@@ -34,7 +36,7 @@
3436
</SettingComponent>
3537

3638
<SettingComponent
37-
name="Open if note already xxists"
39+
name="Open if note already exists"
3840
description="Whether to open the note instead of creating a new one if the note already exists."
3941
>
4042
<Toggle bind:checked={action.openIfAlreadyExists}></Toggle>
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script lang="ts">
2-
import type { JSButtonAction } from 'packages/core/src/config/ButtonConfig';
2+
import { ButtonStyleType, type JSButtonAction } from 'packages/core/src/config/ButtonConfig';
33
import type { IPlugin } from 'packages/core/src/IPlugin';
4+
import Button from 'packages/core/src/utils/components/Button.svelte';
45
import SettingComponent from 'packages/core/src/utils/components/SettingComponent.svelte';
56
67
const {
@@ -10,8 +11,19 @@
1011
plugin: IPlugin;
1112
action: JSButtonAction;
1213
} = $props();
14+
15+
function changeFilePath(): void {
16+
plugin.internal.openFilteredFileSelectModal(
17+
(file: string) => {
18+
action.file = file;
19+
},
20+
(file: string) => file.endsWith('.js'),
21+
);
22+
}
1323
</script>
1424

1525
<SettingComponent name="JS file" description="The JavaScript file to run.">
16-
<input type="text" bind:value={action.file} placeholder="someJsFile.js" />
26+
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeFilePath()} tooltip="Select from vault"
27+
>Change</Button
28+
>
1729
</SettingComponent>

packages/core/src/modals/modalContents/buttonBuilder/OpenActionSettings.svelte

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script lang="ts">
2-
import type { OpenButtonAction } from 'packages/core/src/config/ButtonConfig';
2+
import { ButtonStyleType, type OpenButtonAction } from 'packages/core/src/config/ButtonConfig';
33
import type { IPlugin } from 'packages/core/src/IPlugin';
4+
import Button from 'packages/core/src/utils/components/Button.svelte';
5+
import Icon from 'packages/core/src/utils/components/Icon.svelte';
46
import SettingComponent from 'packages/core/src/utils/components/SettingComponent.svelte';
57
import Toggle from 'packages/core/src/utils/components/Toggle.svelte';
68
@@ -11,10 +13,19 @@
1113
plugin: IPlugin;
1214
action: OpenButtonAction;
1315
} = $props();
16+
17+
function changeFilePath(): void {
18+
plugin.internal.openMarkdownFileSelectModal((file: string) => {
19+
action.link = file;
20+
});
21+
}
1422
</script>
1523

1624
<SettingComponent name="Link" description="The link to open.">
1725
<input type="text" bind:value={action.link} placeholder="[[Some Note]] or https://www.example.com" />
26+
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeFilePath()} tooltip="Select from vault"
27+
><Icon iconName="list" plugin={plugin}></Icon></Button
28+
>
1829
</SettingComponent>
1930

2031
<SettingComponent name="New tab" description="Whether to open the link in a new tab.">
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script lang="ts">
2-
import type { RunTemplaterFileButtonAction } from 'packages/core/src/config/ButtonConfig';
2+
import { ButtonStyleType, type RunTemplaterFileButtonAction } from 'packages/core/src/config/ButtonConfig';
33
import type { IPlugin } from 'packages/core/src/IPlugin';
4+
import Button from 'packages/core/src/utils/components/Button.svelte';
5+
import Icon from 'packages/core/src/utils/components/Icon.svelte';
46
import SettingComponent from 'packages/core/src/utils/components/SettingComponent.svelte';
57
68
const {
@@ -10,11 +12,19 @@
1012
plugin: IPlugin;
1113
action: RunTemplaterFileButtonAction;
1214
} = $props();
15+
16+
function changeFilePath(): void {
17+
plugin.internal.openMarkdownFileSelectModal((file: string) => {
18+
action.templateFile = file;
19+
});
20+
}
1321
</script>
1422

1523
<SettingComponent
1624
name="File path: {action.templateFile || 'default'}"
17-
description="The path from the vault to the templater file."
25+
description="The path to the templater file, relative to the vault root."
1826
>
19-
<input type="text" bind:value={action.templateFile} placeholder="some path" />
27+
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeFilePath()} tooltip="Select from vault"
28+
>Change</Button
29+
>
2030
</SettingComponent>

packages/core/src/modals/modalContents/buttonBuilder/TemplaterCreateNoteActionSettings.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@
3131
name="Template file: {action.templateFile || 'none'}"
3232
description="The template file to create a new note of."
3333
>
34-
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeTemplateFile(action)}>Change</Button>
34+
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeTemplateFile(action)} tooltip="Select from vault"
35+
>Change</Button
36+
>
3537
</SettingComponent>
3638

3739
<SettingComponent name="Folder: {action.folderPath || 'none'}" description="The folder to create a new note in.">
38-
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeFolderPath(action)}>Change</Button>
40+
<Button variant={ButtonStyleType.PRIMARY} onclick={() => changeFolderPath(action)} tooltip="Select from vault"
41+
>Change</Button
42+
>
3943
</SettingComponent>
4044

4145
<SettingComponent name="File name: {action.fileName || 'default'}" description="The file name of the new note.">
Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
1+
import type { IPlugin } from 'packages/core/src/IPlugin';
12
import { SelectModalContent } from 'packages/core/src/modals/SelectModalContent';
23

34
export class FileSelectModal extends SelectModalContent<string> {
5+
readonly filterFunction?: (filePath: string) => boolean;
6+
7+
constructor(
8+
plugin: IPlugin,
9+
selectCallback: (value: string) => void,
10+
filterFunction?: (filePath: string) => boolean,
11+
) {
12+
super(plugin, selectCallback);
13+
this.filterFunction = filterFunction;
14+
}
15+
416
public getItemText(item: string): string {
517
return item;
618
}
719

820
public getItems(): string[] {
9-
return this.plugin.internal.file.getAllFiles();
21+
if (this.filterFunction !== undefined) {
22+
return this.plugin.internal.file.getAllFiles().filter(f => this.filterFunction!(f));
23+
} else {
24+
return this.plugin.internal.file.getAllFiles();
25+
}
1026
}
1127
}

packages/obsidian/src/modals/ImageSuggesterModalHelper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { TAbstractFile } from 'obsidian';
22
import { Notice, TFile, TFolder } from 'obsidian';
3+
import { IMAGE_FILE_EXTENSIONS } from 'packages/core/src/api/InternalAPI';
34
import { InputFieldArgumentType } from 'packages/core/src/config/FieldConfigs';
45
import type { OptionInputFieldArgument } from 'packages/core/src/fields/fieldArguments/inputFieldArguments/arguments/OptionInputFieldArgument';
56
import type { OptionQueryInputFieldArgument } from 'packages/core/src/fields/fieldArguments/inputFieldArguments/arguments/OptionQueryInputFieldArgument';
@@ -132,8 +133,7 @@ export function getImageSuggesterOptions(
132133
}
133134

134135
function isImageExtension(extension: string): boolean {
135-
const extensions = ['apng', 'avif', 'gif', 'jpg', 'jpeg', 'jfif', 'pjpeg', 'pjp', 'png', 'svg', 'webp'];
136-
return extensions.contains(extension);
136+
return IMAGE_FILE_EXTENSIONS.contains(extension);
137137
}
138138

139139
export function getImageSuggesterOptionsForInputField(

0 commit comments

Comments
 (0)