diff --git a/.prettierrc b/.prettierrc index e5b10e0..e9b145f 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ { - "useTabs": false, + "useTabs": true, "tabWidth": 4, "singleQuote": true, "trailingComma": "none", diff --git a/src/components/PasswordInput.svelte b/src/components/PasswordInput.svelte index e19f211..ae80ddb 100644 --- a/src/components/PasswordInput.svelte +++ b/src/components/PasswordInput.svelte @@ -1,56 +1,56 @@
- - {#if wrongCount > 0} -

- Wrong Password! - {#if wrongCount > 2 && hint} - Hint: {hint} - {/if} -

- {/if} + + {#if wrongCount > 0} +

+ Wrong Password! + {#if wrongCount > 2 && hint} + Hint: {hint} + {/if} +

+ {/if}
diff --git a/src/components/Path.svelte b/src/components/Path.svelte index fcc0473..6face12 100644 --- a/src/components/Path.svelte +++ b/src/components/Path.svelte @@ -1,21 +1,21 @@ diff --git a/src/components/RequirePassword.svelte b/src/components/RequirePassword.svelte index b6ed1b1..c90847b 100644 --- a/src/components/RequirePassword.svelte +++ b/src/components/RequirePassword.svelte @@ -1,36 +1,36 @@

This file is protected, please input your password

{ - e.preventDefault() - e.stopPropagation() + class="sp-container" + onsubmit={(e) => { + e.preventDefault() + e.stopPropagation() - if (passInput.submit(true)) { - onCorrect() - } - }} + if (passInput.submit(true)) { + onCorrect() + } + }} > - + - + diff --git a/src/components/SettingsPassword.svelte b/src/components/SettingsPassword.svelte index 5c956e9..63dfe74 100644 --- a/src/components/SettingsPassword.svelte +++ b/src/components/SettingsPassword.svelte @@ -1,77 +1,83 @@
{ - e.preventDefault() - e.stopPropagation() + class="sp-container sp-container-new-password" + onsubmit={(e) => { + e.preventDefault() + e.stopPropagation() - let happy = true + let happy = true - if (!passInp?.submit(false)) { - happy = false - } + if (!passInp?.submit(false)) { + happy = false + } - if (newPassword != conPassword) { - happy = false - } + if (newPassword != conPassword) { + happy = false + } - if (happy) { - onSubmit(newPassword) - } - }} + if (happy) { + onSubmit(newPassword) + } + }} > - {#if requireOldPassword} - - {/if} + {#if requireOldPassword} + + {/if} - - - {#if displayMismatch} - {#if newPassword.length < 3} -

Password needs to be longer than 3 chracters

- {:else} -

Passwords don't match

- {/if} - {/if} + + + {#if displayMismatch} + {#if newPassword.length < 3} +

Password needs to be longer than 3 chracters

+ {:else} +

Passwords don't match

+ {/if} + {/if} - + diff --git a/src/components/SettingsPaths.svelte b/src/components/SettingsPaths.svelte index b2f02db..bc1395f 100644 --- a/src/components/SettingsPaths.svelte +++ b/src/components/SettingsPaths.svelte @@ -1,29 +1,29 @@
@@ -31,46 +31,46 @@

Protected Paths

- {#each $paths as _, i (i)} -
- - -
- {/each} + $paths = $paths + })} + > + - + +
+ {/each} - + diff --git a/src/main.ts b/src/main.ts index a622595..ce9387f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,235 +12,235 @@ const ICON_RIBBON_UNLOCKED = 'unlock' // So we have a problem when closing tabs: the File is set to null type SafeLeaf = { - leaf: WorkspaceLeaf - file: TFile + leaf: WorkspaceLeaf + file: TFile } export default class SimplePassword extends Plugin { - settings: Settings - ribbonIconEl: HTMLElement - autolockTimeoutID: ReturnType - lastHoveredFile: string + settings: Settings + ribbonIconEl: HTMLElement + autolockTimeoutID: ReturnType + lastHoveredFile: string - isLocked: boolean - isLocking = false + isLocked: boolean + isLocking = false - async onload() { - await this.loadSettings() - this.isLocked = true + async onload() { + await this.loadSettings() + this.isLocked = true - this.ribbonIconEl = this.addRibbonIcon(ICON_RIBBON_LOCKED, STR_RIBBON_LOCKED, () => { - this.onIconClick() - }) + this.ribbonIconEl = this.addRibbonIcon(ICON_RIBBON_LOCKED, STR_RIBBON_LOCKED, () => { + this.onIconClick() + }) - this.addCommand({ - id: 'sp-lock-vault', - name: 'Lock Vault', - callback: () => { - this.lock() - } - }) + this.addCommand({ + id: 'sp-lock-vault', + name: 'Lock Vault', + callback: () => { + this.lock() + } + }) - this.registerObsidianProtocolHandler('lock', () => { - this.lock() - }) + this.registerObsidianProtocolHandler('lock', () => { + this.lock() + }) - this.registerEvent( - this.app.workspace.on('file-open', (f: TFile | null) => { - if (!f || !this.isLocked) return + this.registerEvent( + this.app.workspace.on('file-open', (f: TFile | null) => { + if (!f || !this.isLocked) return - if (this.isPathLocked(f.path)) { - this.lock() - } - }) - ) + if (this.isPathLocked(f.path)) { + this.lock() + } + }) + ) - this.app.workspace.onLayoutReady(() => { - ;['create', 'modify', 'delete', 'rename'].forEach((evName) => { - this.registerEvent( - // @ts-expect-error Overloads + Paramters don't play well - this.app.vault.on(evName, () => { - this.resetAutolock() - }) - ) - }) - }) + this.app.workspace.onLayoutReady(() => { + ;['create', 'modify', 'delete', 'rename'].forEach((evName) => { + this.registerEvent( + // @ts-expect-error Overloads + Paramters don't play well + this.app.vault.on(evName, () => { + this.resetAutolock() + }) + ) + }) + }) - this.register(() => this.removeAutolock()) - this.registerEvent( + this.register(() => this.removeAutolock()) + this.registerEvent( this.app.workspace.on( // @ts-expect-error Undocumented api - 'hover-link', - ({ linktext }: { linktext: string }) => { + 'hover-link', + ({ linktext }: { linktext: string }) => { // Name aside, linktext is always the correct link // Though not always an abs path so this.lastHoveredFile = linktext } - ) - ) + ) + ) - this.watchDom() + this.watchDom() - this.addSettingTab(new SettingsTab(this.app, this)) + this.addSettingTab(new SettingsTab(this.app, this)) - // If there are any unprotected things, lock! - this.lock() - } + // If there are any unprotected things, lock! + this.lock() + } - removeAutolock(): void { - if (this.autolockTimeoutID) { - clearTimeout(this.autolockTimeoutID) - } - } + removeAutolock(): void { + if (this.autolockTimeoutID) { + clearTimeout(this.autolockTimeoutID) + } + } - resetAutolock(): void { - this.removeAutolock() + resetAutolock(): void { + this.removeAutolock() - if (this.settings.autoLockMinutes) { - this.autolockTimeoutID = setTimeout( - () => { - this.lock() - }, - 60 * 1000 * this.settings.autoLockMinutes - ) - } - } + if (this.settings.autoLockMinutes) { + this.autolockTimeoutID = setTimeout( + () => { + this.lock() + }, + 60 * 1000 * this.settings.autoLockMinutes + ) + } + } - isPathLocked(testPath: string): boolean { - for (const _p of this.settings.protectedPaths) { - const p = new URL(_p, 'file://').pathname + isPathLocked(testPath: string): boolean { + for (const _p of this.settings.protectedPaths) { + const p = new URL(_p, 'file://').pathname - if (('/' + testPath).startsWith(p)) { - return true - } - } + if (('/' + testPath).startsWith(p)) { + return true + } + } - return false - } + return false + } - watchDom() { - const domObs = new MutationObserver(() => { - if (!this.isLocked || this.isLocking) { - return - } + watchDom() { + const domObs = new MutationObserver(() => { + if (!this.isLocked || this.isLocking) { + return + } - // I decied to add a dom observer clause here, since a user could embed the thing on the fly - const embedDoc = document.querySelector('.internal-embed[src]') - if (embedDoc) { - const path = embedDoc.attributes.getNamedItem('src')?.value - if (path) { - const realPath = this.app.metadataCache.getFirstLinkpathDest(path, '')?.path - if (realPath) { - const curFile = this.app.workspace.getActiveFile() - const curLeaf = this.app.workspace.getMostRecentLeaf() + // I decied to add a dom observer clause here, since a user could embed the thing on the fly + const embedDoc = document.querySelector('.internal-embed[src]') + if (embedDoc) { + const path = embedDoc.attributes.getNamedItem('src')?.value + if (path) { + const realPath = this.app.metadataCache.getFirstLinkpathDest(path, '')?.path + if (realPath) { + const curFile = this.app.workspace.getActiveFile() + const curLeaf = this.app.workspace.getMostRecentLeaf() - if (curLeaf && curFile) { - this.lock(true, [{ leaf: curLeaf, file: curFile }]) - return - } - } - } - } + if (curLeaf && curFile) { + this.lock(true, [{ leaf: curLeaf, file: curFile }]) + return + } + } + } + } - const popover = document.querySelector('.popover.hover-popover') - if (!popover) return + const popover = document.querySelector('.popover.hover-popover') + if (!popover) return - console.log("hover", this.lastHoveredFile) + console.log('hover', this.lastHoveredFile) if (this.isPathLocked(this.lastHoveredFile)) { - popover.remove() - this.lock(true) - return true - } - }) + popover.remove() + this.lock(true) + return true + } + }) - domObs.observe(document.body, { - childList: true, - subtree: true - }) + domObs.observe(document.body, { + childList: true, + subtree: true + }) - this.register(() => domObs.disconnect()) - } + this.register(() => domObs.disconnect()) + } - /** - * Performs all the needed actions to initiate a lock - */ - async lock(alwaysRequestPassword = false, extraLeaves: SafeLeaf[] = []) { - this.isLocked = true - this.isLocking = true - this.setRibbonIcon(true) - this.removeAutolock() + /** + * Performs all the needed actions to initiate a lock + */ + async lock(alwaysRequestPassword = false, extraLeaves: SafeLeaf[] = []) { + this.isLocked = true + this.isLocking = true + this.setRibbonIcon(true) + this.removeAutolock() - const protectedLeaves: SafeLeaf[] = [...extraLeaves] + const protectedLeaves: SafeLeaf[] = [...extraLeaves] - // We always need to know if theres active files, no matter the privacy mode - this.app.workspace.iterateRootLeaves((l) => { - if (l?.view instanceof FileView && l.view?.file) { - if (this.isPathLocked(l.view.file.path)) { - protectedLeaves.push({ leaf: l, file: l.view.file }) - } - } - }) + // We always need to know if theres active files, no matter the privacy mode + this.app.workspace.iterateRootLeaves((l) => { + if (l?.view instanceof FileView && l.view?.file) { + if (this.isPathLocked(l.view.file.path)) { + protectedLeaves.push({ leaf: l, file: l.view.file }) + } + } + }) - if (!alwaysRequestPassword && protectedLeaves.length == 0) { - this.isLocking = false - return - } + if (!alwaysRequestPassword && protectedLeaves.length == 0) { + this.isLocking = false + return + } - if (this.settings.privacyMode == PrivacyMode.CLOSE) { - protectedLeaves.forEach((v) => { - v.leaf.detach() - }) - } + if (this.settings.privacyMode == PrivacyMode.CLOSE) { + protectedLeaves.forEach((v) => { + v.leaf.detach() + }) + } - this.requestUserToUnlock(protectedLeaves) - } + this.requestUserToUnlock(protectedLeaves) + } - requestUserToUnlock(protectedViews: SafeLeaf[] = []) { - console.log('Password requested') + requestUserToUnlock(protectedViews: SafeLeaf[] = []) { + console.log('Password requested') - new RequirePasswordModal(this.app, this.settings, (success) => { - this.isLocked = !success - this.isLocking = false + new RequirePasswordModal(this.app, this.settings, (success) => { + this.isLocked = !success + this.isLocking = false - if (success) { - this.setRibbonIcon(false) - this.resetAutolock() - new Notice('Vault unlocked') + if (success) { + this.setRibbonIcon(false) + this.resetAutolock() + new Notice('Vault unlocked') - if (this.settings.privacyMode == PrivacyMode.CLOSE) { - protectedViews.forEach((v) => { - this.app.workspace.getLeaf('tab').openFile(v.file) - }) - } - } else { - new Notice('Password prompt cancelled') + if (this.settings.privacyMode == PrivacyMode.CLOSE) { + protectedViews.forEach((v) => { + this.app.workspace.getLeaf('tab').openFile(v.file) + }) + } + } else { + new Notice('Password prompt cancelled') - if (this.settings.privacyMode == PrivacyMode.BLUR) { - protectedViews.forEach((v) => v.leaf.detach()) - } - } - }).open() - } + if (this.settings.privacyMode == PrivacyMode.BLUR) { + protectedViews.forEach((v) => v.leaf.detach()) + } + } + }).open() + } - onIconClick() { - if (this.isLocked) { - this.requestUserToUnlock() - } else { - this.lock() - } - } + onIconClick() { + if (this.isLocked) { + this.requestUserToUnlock() + } else { + this.lock() + } + } - setRibbonIcon(locked: boolean) { - this.ribbonIconEl.ariaLabel = locked ? STR_RIBBON_LOCKED : STR_RIBBON_UNLOCKED - setIcon(this.ribbonIconEl, locked ? ICON_RIBBON_LOCKED : ICON_RIBBON_UNLOCKED) - } + setRibbonIcon(locked: boolean) { + this.ribbonIconEl.ariaLabel = locked ? STR_RIBBON_LOCKED : STR_RIBBON_UNLOCKED + setIcon(this.ribbonIconEl, locked ? ICON_RIBBON_LOCKED : ICON_RIBBON_UNLOCKED) + } - async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()) - } + async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()) + } - async saveSettings() { - await this.saveData(this.settings) - } + async saveSettings() { + await this.saveData(this.settings) + } } diff --git a/src/modals.ts b/src/modals.ts index 7d057c6..1d8ab1d 100644 --- a/src/modals.ts +++ b/src/modals.ts @@ -7,89 +7,89 @@ import SettingsPassword from './components/SettingsPassword.svelte' type PasswordCallback = (success: boolean) => void export class RequirePasswordModal extends Modal { - svelteContent: Record - settings: Settings - succeeded: boolean - callback: PasswordCallback + svelteContent: Record + settings: Settings + succeeded: boolean + callback: PasswordCallback - constructor(app: App, settings: Settings, cb: PasswordCallback) { - super(app) + constructor(app: App, settings: Settings, cb: PasswordCallback) { + super(app) - this.settings = settings - this.callback = cb - this.succeeded = false - } + this.settings = settings + this.callback = cb + this.succeeded = false + } - onOpen(): void { - this.setTitle('Password Required!') - this.shouldRestoreSelection = true - this.containerEl.addClass('sp-modal-container') - this.containerEl.toggleClass('sp-modal-blur', this.settings.privacyMode == PrivacyMode.BLUR) + onOpen(): void { + this.setTitle('Password Required!') + this.shouldRestoreSelection = true + this.containerEl.addClass('sp-modal-container') + this.containerEl.toggleClass('sp-modal-blur', this.settings.privacyMode == PrivacyMode.BLUR) - this.svelteContent = mount(RequirePassword, { - target: this.contentEl, - props: { - correctPassword: this.settings.password, - hint: this.settings.hint, - onCorrect: () => { - this.succeeded = true - this.close() - } - } - }) - } + this.svelteContent = mount(RequirePassword, { + target: this.contentEl, + props: { + correctPassword: this.settings.password, + hint: this.settings.hint, + onCorrect: () => { + this.succeeded = true + this.close() + } + } + }) + } - close(): void { - // This needs to be done BEFORE the actual modal closes - // This is to ensure that everything is clsoed in case of a non-success - this.callback(this.succeeded) + close(): void { + // This needs to be done BEFORE the actual modal closes + // This is to ensure that everything is clsoed in case of a non-success + this.callback(this.succeeded) - super.close() - } + super.close() + } - async onClose() { - unmount(this.svelteContent, { outro: true }) - } + async onClose() { + unmount(this.svelteContent, { outro: true }) + } } type NewPasswordCallback = (password: string) => void export class NewPasswordModal extends Modal { - svelteContent: Record - settings: Settings - callback: NewPasswordCallback - password: string + svelteContent: Record + settings: Settings + callback: NewPasswordCallback + password: string - constructor(app: App, settings: Settings, cb: NewPasswordCallback) { - super(app) + constructor(app: App, settings: Settings, cb: NewPasswordCallback) { + super(app) - this.settings = settings - this.callback = cb - this.password = '' - } + this.settings = settings + this.callback = cb + this.password = '' + } - onOpen(): void { - this.setTitle('Password Required!') - this.shouldRestoreSelection = true - this.containerEl.addClass('sp-modal-container') - this.containerEl.toggleClass('sp-modal-blur', this.settings.privacyMode == PrivacyMode.BLUR) + onOpen(): void { + this.setTitle('Password Required!') + this.shouldRestoreSelection = true + this.containerEl.addClass('sp-modal-container') + this.containerEl.toggleClass('sp-modal-blur', this.settings.privacyMode == PrivacyMode.BLUR) - this.svelteContent = mount(SettingsPassword, { - target: this.contentEl, - props: { - requireOldPassword: this.settings.password != '', - correctPassword: this.settings.password, - hint: this.settings.hint, - onSubmit: (pass) => { - this.password = pass - this.close() - } - } - }) - } + this.svelteContent = mount(SettingsPassword, { + target: this.contentEl, + props: { + requireOldPassword: this.settings.password != '', + correctPassword: this.settings.password, + hint: this.settings.hint, + onSubmit: (pass) => { + this.password = pass + this.close() + } + } + }) + } - async onClose() { - this.callback(this.password) - unmount(this.svelteContent, { outro: true }) - } + async onClose() { + this.callback(this.password) + unmount(this.svelteContent, { outro: true }) + } } diff --git a/src/settings.ts b/src/settings.ts index 8c1046b..ee7d648 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -7,198 +7,198 @@ import { mount, unmount } from 'svelte' import { writable, get } from 'svelte/store' export enum PrivacyMode { - BLUR = 'blur', - CLOSE = 'close', - NONE = '' + BLUR = 'blur', + CLOSE = 'close', + NONE = '' } export interface Settings { - autoLockMinutes: number - privacyMode: PrivacyMode - protectedPaths: string[] - hint: string - password: string + autoLockMinutes: number + privacyMode: PrivacyMode + protectedPaths: string[] + hint: string + password: string } export const DEFAULT_SETTINGS: Settings = { - autoLockMinutes: 15, - privacyMode: PrivacyMode.BLUR, - protectedPaths: ['/'], - hint: '', - password: '' + autoLockMinutes: 15, + privacyMode: PrivacyMode.BLUR, + protectedPaths: ['/'], + hint: '', + password: '' } export class SettingsTab extends PluginSettingTab { - plugin: SimplePassword - lockBtn: ButtonComponent - lockSet: Setting - lockableSettings: Setting[] - svelteComp: SettingsPaths + plugin: SimplePassword + lockBtn: ButtonComponent + lockSet: Setting + lockableSettings: Setting[] + svelteComp: SettingsPaths - locked = writable(true) + locked = writable(true) - constructor(app: App, plugin: SimplePassword) { - super(app, plugin) + constructor(app: App, plugin: SimplePassword) { + super(app, plugin) - this.plugin = plugin + this.plugin = plugin - this.locked.subscribe((v) => { - if (!this.lockableSettings || !this.lockBtn || !this.lockSet) return + this.locked.subscribe((v) => { + if (!this.lockableSettings || !this.lockBtn || !this.lockSet) return - if (v) { - this.lockBtn.setIcon('unlock') - this.lockSet.setName('Unlock settings below') - } else { - this.lockBtn.setIcon('lock') - this.lockSet.setName('Lock settings below') - } + if (v) { + this.lockBtn.setIcon('unlock') + this.lockSet.setName('Unlock settings below') + } else { + this.lockBtn.setIcon('lock') + this.lockSet.setName('Lock settings below') + } - this.lockableSettings.forEach((s) => { - s.setDisabled(v) - }) - }) - } + this.lockableSettings.forEach((s) => { + s.setDisabled(v) + }) + }) + } - display() { - const { containerEl } = this + display() { + const { containerEl } = this - containerEl.empty() - containerEl.addClass('sp-settings') + containerEl.empty() + containerEl.addClass('sp-settings') - new Setting(containerEl) - .setName(this.plugin.settings.password ? 'Change Password' : 'Set Password') - .addButton((btn) => { - btn.setCta() - .setButtonText('Change') - .onClick(() => this.onPasswordChangeButton()) - }) + new Setting(containerEl) + .setName(this.plugin.settings.password ? 'Change Password' : 'Set Password') + .addButton((btn) => { + btn.setCta() + .setButtonText('Change') + .onClick(() => this.onPasswordChangeButton()) + }) - this.lockSet = new Setting(containerEl) - .setName('Unlock settings below') - .setDesc( - 'The following settings are sensetive, and therefore require that you enter your password' - ) - .addButton((btn) => { - btn.setIcon('unlock').onClick(() => this.onLockBtn()) - this.lockBtn = btn - }) - .setDisabled(this.plugin.settings.password == '') + this.lockSet = new Setting(containerEl) + .setName('Unlock settings below') + .setDesc( + 'The following settings are sensetive, and therefore require that you enter your password' + ) + .addButton((btn) => { + btn.setIcon('unlock').onClick(() => this.onLockBtn()) + this.lockBtn = btn + }) + .setDisabled(this.plugin.settings.password == '') - containerEl.createEl('hr') + containerEl.createEl('hr') - this.lockableSettings = [ - new Setting(containerEl) - .setName('Auto Lock Minutes') - .setDesc('After x minutes of inactivity, lock the vault. Set to 0 for no auto lock') - .addText((text) => { - text.setPlaceholder('# of Minutes').setValue( - this.plugin.settings.autoLockMinutes.toString() - ) - text.inputEl.type = 'number' - text.onChange((v) => { - const f = parseFloat(v) - if (!isNaN(f)) { - this.plugin.settings.autoLockMinutes = f - this.plugin.resetAutolock() - this.plugin.saveSettings() - } - }) - }) - .setDisabled(true), - new Setting(containerEl) - .setName('Privacy Mode') - .setDesc('What should we do on lock?') - .addDropdown((drop) => { - drop.addOptions({ - [PrivacyMode.BLUR]: 'Blur Background', - [PrivacyMode.CLOSE]: 'Close Affected Tabs', - [PrivacyMode.NONE]: 'Nothing' - }) - .onChange((v) => { - this.plugin.settings.privacyMode = v as PrivacyMode - this.plugin.saveSettings() - }) - .setValue(this.plugin.settings.privacyMode) - }) - .setDisabled(true), - new Setting(containerEl) - .setName('Hint') - .setDesc('Add a hint for your password (shown in case of > 3 failed attempts)') - .addText((text) => { - text.setPlaceholder('Hint') - .onChange((v) => { - this.plugin.settings.hint = v - this.plugin.saveSettings() - }) - .setValue(this.plugin.settings.hint) - }) - .setDisabled(true) - ] + this.lockableSettings = [ + new Setting(containerEl) + .setName('Auto Lock Minutes') + .setDesc('After x minutes of inactivity, lock the vault. Set to 0 for no auto lock') + .addText((text) => { + text.setPlaceholder('# of Minutes').setValue( + this.plugin.settings.autoLockMinutes.toString() + ) + text.inputEl.type = 'number' + text.onChange((v) => { + const f = parseFloat(v) + if (!isNaN(f)) { + this.plugin.settings.autoLockMinutes = f + this.plugin.resetAutolock() + this.plugin.saveSettings() + } + }) + }) + .setDisabled(true), + new Setting(containerEl) + .setName('Privacy Mode') + .setDesc('What should we do on lock?') + .addDropdown((drop) => { + drop.addOptions({ + [PrivacyMode.BLUR]: 'Blur Background', + [PrivacyMode.CLOSE]: 'Close Affected Tabs', + [PrivacyMode.NONE]: 'Nothing' + }) + .onChange((v) => { + this.plugin.settings.privacyMode = v as PrivacyMode + this.plugin.saveSettings() + }) + .setValue(this.plugin.settings.privacyMode) + }) + .setDisabled(true), + new Setting(containerEl) + .setName('Hint') + .setDesc('Add a hint for your password (shown in case of > 3 failed attempts)') + .addText((text) => { + text.setPlaceholder('Hint') + .onChange((v) => { + this.plugin.settings.hint = v + this.plugin.saveSettings() + }) + .setValue(this.plugin.settings.hint) + }) + .setDisabled(true) + ] - const paths = writable(this.plugin.settings.protectedPaths) - paths.subscribe((v) => { - this.plugin.settings.protectedPaths = v - this.plugin.saveSettings() - }) + const paths = writable(this.plugin.settings.protectedPaths) + paths.subscribe((v) => { + this.plugin.settings.protectedPaths = v + this.plugin.saveSettings() + }) - this.svelteComp = mount(SettingsPaths, { - target: containerEl, - props: { - app: this.app, - disabled: this.locked, - paths - } - }) - } + this.svelteComp = mount(SettingsPaths, { + target: containerEl, + props: { + app: this.app, + disabled: this.locked, + paths + } + }) + } - onLockBtn() { - if (get(this.locked)) { - new RequirePasswordModal(this.app, this.plugin.settings, (success) => { - if (success) { - this.locked.set(false) - } - }).open() - } else { - this.locked.set(true) - } - } + onLockBtn() { + if (get(this.locked)) { + new RequirePasswordModal(this.app, this.plugin.settings, (success) => { + if (success) { + this.locked.set(false) + } + }).open() + } else { + this.locked.set(true) + } + } - onPasswordChangeButton() { - new NewPasswordModal(this.app, this.plugin.settings, (p) => { - if (p) { - new Notice('Changed Password') - this.plugin.settings.password = p - this.plugin.saveSettings() + onPasswordChangeButton() { + new NewPasswordModal(this.app, this.plugin.settings, (p) => { + if (p) { + new Notice('Changed Password') + this.plugin.settings.password = p + this.plugin.saveSettings() - this.lockSet.setDisabled(false) - this.locked.set(true) - } else { - new Notice('Password Change Cancelled') - } - }).open() - } + this.lockSet.setDisabled(false) + this.locked.set(true) + } else { + new Notice('Password Change Cancelled') + } + }).open() + } - hide(): void { - unmount(this.svelteComp) - super.hide() - } + hide(): void { + unmount(this.svelteComp) + super.hide() + } } export class PathSuggestions extends AbstractInputSuggest { - protected getSuggestions(query: string): string[] { - const p = new URL(query, 'file://').pathname + protected getSuggestions(query: string): string[] { + const p = new URL(query, 'file://').pathname - return this.app.vault - .getAllFolders(true) - .filter((v) => { - if (('/' + v.path).startsWith(p)) { - return true - } - }) - .map((v) => v.path) - } + return this.app.vault + .getAllFolders(true) + .filter((v) => { + if (('/' + v.path).startsWith(p)) { + return true + } + }) + .map((v) => v.path) + } - renderSuggestion(value: string, el: HTMLElement): void { - el.setText(value) - } + renderSuggestion(value: string, el: HTMLElement): void { + el.setText(value) + } }