Skip to content

Commit

Permalink
Add new functionality to allow users to onboard all notes in their va…
Browse files Browse the repository at this point in the history
…ult (optionally skipping directories via provided list) to the Spaced Everything plugin
  • Loading branch information
zachmueller committed Sep 25, 2024
1 parent e644b6b commit fb85901
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 2 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "spaced-everything",
"name": "Spaced everything",
"version": "1.1.1",
"version": "1.2.0",
"minAppVersion": "1.6.7",
"description": "Apply spaced repetition algorithms to everything in your vault.",
"author": "Zach Mueller",
Expand Down
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const DEFAULT_SETTINGS: SpacedEverythingPluginSettings = {
includeShortThoughtInAlias: true,
shortCapturedThoughtThreshold: 200,
openCapturedThoughtInNewTab: false,
onboardingExcludedFolders: []
}

export default class SpacedEverythingPlugin extends Plugin {
Expand Down
118 changes: 117 additions & 1 deletion src/settings.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { App, Notice, PluginSettingTab, Setting, normalizePath } from 'obsidian';
import { App, Notice, PluginSettingTab, Setting, normalizePath, Modal, TAbstractFile, TFile, TFolder } from 'obsidian';
import { Context, ReviewOption, SpacingMethod } from './types';
import SpacedEverythingPlugin from './main';

Expand All @@ -16,6 +16,7 @@ interface SpacedEverythingPluginSettings {
includeShortThoughtInAlias: boolean;
shortCapturedThoughtThreshold: number;
openCapturedThoughtInNewTab: boolean;
onboardingExcludedFolders: string[];
}

export type { SpacedEverythingPluginSettings };
Expand Down Expand Up @@ -262,8 +263,81 @@ export class SpacedEverythingSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
})
);


// Onboard all notes
new Setting(containerEl).setName('Onboard all notes (beta)')
.setHeading()
.setDesc('This provides an optional means of onboarding every note in your vault to the Spaced Everything system. Importantly, the plugin uses frontmatter properties on notes to track relevant metadata to perform the spacing algorithm actions. So it is recommended to use the "Excluded folders" setting below to filter out subsets of notes that you wish to avoid onboarding. Performing this action will not change any existing Spaced Everything frontmatter if you already have some notes oboarded.\n\nThis is still a beta feature. Currently, it asusmes to only apply the settings from the first Spacing Method (defined above) and assumes to not set any context for notes onboarded in this manner.');

new Setting(containerEl)
.setName('Excluded folders')
.setDesc('Enter the paths of any folders you want to exclude from the onboarding process (one per line). Consider adding folders that contain things like templates or scripts that may not work if frontmatter properties are added to them.')
.addTextArea((textArea) => {
textArea.setValue(this.plugin.settings.onboardingExcludedFolders.join('\n')).onChange(async (value) => {
this.plugin.settings.onboardingExcludedFolders = value.trim().split('\n').filter((v) => v);
await this.plugin.saveSettings();
});
});

new Setting(containerEl)
.setName('Onboard all notes')
.setDesc('Click the button to add the required frontmatter properties to all notes in your vault, excluding the folders specified above.')
.addButton((button) =>
button
.setButtonText('Onboard all notes')
.onClick(async () => this.showConfirmationModal())
);
}


// functions for onboarding all notes
async showConfirmationModal() {
const modal = new ConfirmationModal(this.app, this.plugin);
modal.open();
}

async addFrontMatterPropertiesToAllNotes() {
const files = this.app.vault.getMarkdownFiles();

for (const file of files) {
if (!this.isFileExcluded(file)) {
await this.addFrontMatterPropertiesToNote(file);
}
}
}

isFileExcluded(file: TAbstractFile): boolean {
const excludedFolders = this.plugin.settings.onboardingExcludedFolders;
let parent: TFolder | null = file.parent;

while (parent) {
if (excludedFolders.includes(parent.path)) {
return true;
}
parent = parent.parent;
}

return false;
}

async addFrontMatterPropertiesToNote(file: TFile) {
const frontMatter = this.app.metadataCache.getCache(file.path)?.frontmatter;
const modifiedFrontMatter = {
'se-interval': frontMatter?.['se-interval'] || this.plugin.settings.spacingMethods[0].defaultInterval,
'se-last-reviewed': frontMatter?.['se-last-reviewed'] || new Date().toISOString().split('.')[0],
'se-ease': frontMatter?.['se-ease'] || this.plugin.settings.spacingMethods[0].defaultEaseFactor,
};

await this.app.fileManager.processFrontMatter(file, async (frontmatter: any) => {
frontmatter["se-interval"] = modifiedFrontMatter["se-interval"];
frontmatter["se-last-reviewed"] = modifiedFrontMatter["se-last-reviewed"];
frontmatter["se-ease"] = modifiedFrontMatter["se-ease"];
});
}


// Functions for rendering subsets of the settings
renderSpacingMethodSetting(containerEl: HTMLElement, spacingMethod: SpacingMethod, index: number) {
const settingEl = containerEl.createDiv('spacing-method-settings-items');
const settingHeader = settingEl.createDiv('spacing-method-header');
Expand Down Expand Up @@ -517,3 +591,45 @@ export class SpacedEverythingSettingTab extends PluginSettingTab {
});
}
}

class ConfirmationModal extends Modal {
plugin: SpacedEverythingPlugin;
settingsTab: SpacedEverythingSettingTab;

constructor(app: App, plugin: SpacedEverythingPlugin) {
super(app);
this.plugin = plugin;
this.settingsTab = new SpacedEverythingSettingTab(app, plugin);
}

onOpen() {
const { contentEl } = this;
contentEl.createEl('h2', { text: 'Confirm Action' });
contentEl.createEl('p', { text: 'Are you sure you want to onboard to all notes in your vault? This action cannot be undone. It is highly recommended you create a full backup of your vault prior to running this vault-wide action, in case any unexpected changes result.' });

const confirmButton = new Setting(contentEl)
.addButton((button) => {
button
.setButtonText('Confirm')
.setCta()
.onClick(async () => {
await this.settingsTab.addFrontMatterPropertiesToAllNotes();
this.close();
new Notice('All notes onboarded');
});
});

const cancelButton = new Setting(contentEl)
.addButton((button) => {
button
.setButtonText('Cancel')
.onClick(() => {
this.close();
});
});
}

onClose() {
this.contentEl.empty();
}
}

0 comments on commit fb85901

Please sign in to comment.