Skip to content

Commit 2bceff6

Browse files
authored
(MINOR) Merge pull request #27 from jamiefdhurst/feature/existing-folders
Choose folder to watch
2 parents 19c508b + 788ac89 commit 2bceff6

File tree

10 files changed

+87
-14
lines changed

10 files changed

+87
-14
lines changed

src/__mocks__/obsidian.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ export class DropdownComponent extends BaseComponent {
5151
export class ToggleComponent extends BaseComponent {}
5252
export class Setting {
5353
public containerEl: HTMLElement;
54+
public controlEl: HTMLElement;
5455

5556
constructor(el: HTMLElement) {
5657
this.containerEl = el;
58+
this.controlEl = el.createDiv({ cls: 'setting-item-control' });
5759
return this;
5860
}
5961

src/__tests__/inbox.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,29 @@ describe('Inbox', () => {
6868
expect(result.length).toEqual(2);
6969
expect(result[0].path).toEqual('bar');
7070
expect(result[1].path).toEqual('foo');
71+
});
72+
73+
it('gets all folders with root included', () => {
74+
const folders = [
75+
new TFolder(),
76+
new TFolder(),
77+
new TFolder(),
78+
];
7179

80+
folders[0].name = '';
81+
folders[0].path = '/';
82+
folders[1].name = INBOX_FOLDER;
83+
folders[1].path = INBOX_FOLDER;
84+
folders[2].name = 'foo';
85+
folders[2].path = 'foo';
86+
87+
jest.spyOn(vault, 'getAllFolders').mockReturnValue(folders);
88+
89+
const result = sut.getFolders(true);
90+
91+
expect(result.length).toEqual(2);
92+
expect(result[0].path).toEqual('/');
93+
expect(result[1].path).toEqual('foo');
7294
});
7395

7496
it('moves a file', async () => {

src/__tests__/settings/tab.test.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1-
import { App, Setting } from 'obsidian';
1+
import { App, Setting, TFolder } from 'obsidian';
22
import InboxOrganiser from '../..';
3+
import { Inbox } from '../../inbox';
34
import { DEFAULT_SETTINGS } from '../../settings';
45
import { InboxOrganiserTab } from '../../settings/tab';
56

67
describe('Settings Tab', () => {
78

89
let app: App;
910
let plugin: InboxOrganiser;
11+
let inbox: Inbox;
1012

1113
let sut: InboxOrganiserTab;
1214

1315
beforeEach(() => {
1416
app = jest.fn() as unknown as App;
1517
plugin = jest.fn() as unknown as InboxOrganiser;
1618
plugin.getSettings = jest.fn();
19+
inbox = jest.fn() as unknown as Inbox;
20+
inbox.getFolders = jest.fn();
1721

18-
sut = new InboxOrganiserTab(app, plugin);
22+
sut = new InboxOrganiserTab(app, plugin, inbox);
1923
sut.containerEl = createDiv();
2024
});
2125

@@ -26,11 +30,16 @@ describe('Settings Tab', () => {
2630

2731
it('displays correctly', () => {
2832
jest.spyOn(plugin, 'getSettings').mockReturnValue(Object.assign({}, DEFAULT_SETTINGS));
33+
const folders = [new TFolder(), new TFolder()];
34+
folders[0].path = '/';
35+
folders[1].path = 'abc';
36+
const inboxGetFolders = jest.spyOn(inbox, 'getFolders').mockReturnValue(folders);
2937
const settingsSetName = jest.spyOn(Setting.prototype, 'setName');
3038

3139
sut.display();
3240

33-
expect(settingsSetName).toHaveBeenCalledTimes(2);
41+
expect(settingsSetName).toHaveBeenCalledTimes(3);
42+
expect(inboxGetFolders).toHaveBeenCalledWith(true);
3443
});
3544

3645
});

src/__tests__/watcher.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('Watcher', () => {
2020
});
2121

2222
it('should not trigger filemanager when inbox is disabled', () => {
23-
const settings: ISettings = { inbox: false, period: 'disabled' };
23+
const settings: ISettings = { inbox: false, period: 'disabled', watchFolder: '/' };
2424
jest.spyOn(plugin, 'getSettings').mockReturnValue(settings);
2525
const fileManagerRenameFile = jest.spyOn(fileManager, 'renameFile');
2626

@@ -30,7 +30,7 @@ describe('Watcher', () => {
3030
});
3131

3232
it('should trigger filemanager when inbox is enabled', () => {
33-
const settings: ISettings = { inbox: true, period: 'disabled' };
33+
const settings: ISettings = { inbox: true, period: 'disabled', watchFolder: '/' };
3434
jest.spyOn(plugin, 'getSettings').mockReturnValue(settings);
3535
const fileManagerRenameFile = jest.spyOn(fileManager, 'renameFile');
3636

src/inbox.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export class Inbox {
2121
.sort((a, b) => a.name.localeCompare(b.name))
2222
}
2323

24-
getFolders(): TFolder[] {
25-
const folders = this.vault.getAllFolders(false);
24+
getFolders(includeRoot: boolean = false): TFolder[] {
25+
const folders = this.vault.getAllFolders(includeRoot);
2626

2727
return folders
2828
.filter(folder => folder.path !== INBOX_FOLDER)
@@ -32,4 +32,4 @@ export class Inbox {
3232
async move(file: TFile, path: string): Promise<void> {
3333
return this.fileManager.renameFile(file, `${path}/${file.name}`);
3434
}
35-
}
35+
}

src/index.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Plugin, TFile, type App, type PluginManifest } from 'obsidian';
22
import { SETTINGS_UPDATED } from './events';
33
import { Inbox } from './inbox';
4+
import debug from './log';
45
import { OrganiserModal } from './modal';
56
import { OrganiserNotice } from './notice';
67
import { DEFAULT_SETTINGS, ISettings } from './settings';
@@ -32,8 +33,18 @@ export default class InboxOrganiser extends Plugin {
3233

3334
onLayoutReady(): void {
3435
this.registerEvent(this.app.vault.on('create', (file) => {
35-
if (file instanceof TFile && file.path.indexOf('/') === -1) {
36-
this.watcher.notify(file);
36+
if (file instanceof TFile) {
37+
// Root needs a special case as it will not match the start of the file path
38+
if (this.settings.watchFolder === '/' && file.path.indexOf('/') === -1) {
39+
this.watcher.notify(file);
40+
}
41+
// Ensure sub-folders are ignored correctly
42+
if (
43+
file.path.indexOf(this.settings.watchFolder + '/') === 0
44+
&& file.path.split('/').length === this.settings.watchFolder.split('/').length + 1
45+
) {
46+
this.watcher.notify(file);
47+
}
3748
}
3849
}));
3950

@@ -42,7 +53,7 @@ export default class InboxOrganiser extends Plugin {
4253
}, 300000));
4354
(new OrganiserNotice(this, this.modal, this.inbox)).display();
4455

45-
this.addSettingTab(new InboxOrganiserTab(this.app, this));
56+
this.addSettingTab(new InboxOrganiserTab(this.app, this, this.inbox));
4657

4758
this.addCommand({
4859
id: 'inbox-organiser',
@@ -63,17 +74,20 @@ export default class InboxOrganiser extends Plugin {
6374
DEFAULT_SETTINGS,
6475
await this.loadData()
6576
);
77+
debug('Loaded settings: ' + JSON.stringify(this.settings));
6678
}
6779

6880
async updateSettings(settings: ISettings): Promise<void> {
6981
this.settings = settings;
7082
await this.saveData(settings);
7183
this.onSettingsUpdate();
84+
debug('Saved settings: ' + JSON.stringify(this.settings));
7285
}
7386

7487
private onSettingsUpdate(): void {
7588
const inboxFolder = this.app.vault.getFolderByPath(INBOX_FOLDER);
7689
if (this.settings.inbox && !inboxFolder) {
90+
debug('Creating missing inbox folder');
7791
this.app.vault.createFolder(INBOX_FOLDER);
7892
}
7993

src/log.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function debug(msg: string): void {
2+
console.debug(`[JH-IO] ${msg}`);
3+
}

src/settings/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { TFolder } from 'obsidian';
2+
13
export type Period =
24
| 'disabled'
35
| 'daily_9am'
@@ -12,9 +14,11 @@ export type Period =
1214
export interface ISettings {
1315
inbox: boolean;
1416
period: Period;
17+
watchFolder: string;
1518
}
1619

1720
export const DEFAULT_SETTINGS: ISettings = Object.freeze({
1821
inbox: false,
1922
period: 'disabled',
23+
watchFolder: '/',
2024
});

src/settings/tab.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { type App, PluginSettingTab, Setting } from 'obsidian';
22
import { ISettings, type Period } from '.';
33
import InboxOrganiser from '..';
4+
import { Inbox } from '../inbox';
5+
import { FolderSuggest } from '../modal/folder-suggest';
46

57
export class InboxOrganiserTab extends PluginSettingTab {
68
private plugin: InboxOrganiser;
9+
private inbox: Inbox;
710

8-
constructor(app: App, plugin: InboxOrganiser) {
11+
constructor(app: App, plugin: InboxOrganiser, inbox: Inbox) {
912
super(app, plugin);
1013
this.plugin = plugin;
14+
this.inbox = inbox;
1115
}
1216

1317
display(): void {
@@ -37,6 +41,19 @@ export class InboxOrganiserTab extends PluginSettingTab {
3741
await this.plugin.updateSettings(settings);
3842
});
3943
});
44+
45+
const watchFolder = new Setting(this.containerEl);
46+
watchFolder.setName('Watched folder')
47+
.setDesc('Which folder should be monitored for new notes to intercept and add into the inbox (default root).');
48+
const watchFolderEl = watchFolder.controlEl.createEl('input', { type: 'text' });
49+
watchFolderEl.setAttr('value', settings.watchFolder);
50+
new FolderSuggest(this.app, this.inbox.getFolders(true), watchFolderEl);
51+
watchFolderEl.addEventListener('change', (event: MouseEvent) => {
52+
const el = event.target as HTMLSelectElement;
53+
settings.watchFolder = el.value;
54+
this.plugin.updateSettings(settings);
55+
});
56+
4057
new Setting(this.containerEl)
4158
.setName('Reminder period')
4259
.setDesc('How often to send a reminder to organise your inbox.')
@@ -47,7 +64,7 @@ export class InboxOrganiserTab extends PluginSettingTab {
4764
.onChange(async (val) => {
4865
settings.period = val as Period;
4966
await this.plugin.updateSettings(settings);
50-
})
51-
})
67+
});
68+
});
5269
}
5370
}

src/watcher.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { FileManager, TFile } from 'obsidian';
22
import InboxOrganiser, { INBOX_FOLDER } from '.';
3+
import debug from './log';
34

45
export class Watcher {
56
private plugin: InboxOrganiser;
@@ -14,6 +15,7 @@ export class Watcher {
1415
const settings = this.plugin.getSettings();
1516

1617
if (settings.inbox) {
18+
debug('Moving newly created file to inbox');
1719
this.fileManager.renameFile(file, `${INBOX_FOLDER}/${file.name}`);
1820
}
1921
}

0 commit comments

Comments
 (0)