From b1bc22c320e1761127ef59f1d5bbb67f376008e6 Mon Sep 17 00:00:00 2001 From: idanlib Date: Sun, 27 Jul 2025 00:51:16 +0300 Subject: [PATCH 1/4] code review 2 - refactor redirect() --- main.ts | 204 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 136 insertions(+), 68 deletions(-) diff --git a/main.ts b/main.ts index bedf515..6828fdf 100644 --- a/main.ts +++ b/main.ts @@ -17,77 +17,33 @@ export default class RedirectPlugin extends Plugin { isMovingNote = false; isBypassRedirect = false; - handleFileOpen = async (file: TFile) => { - if (this.isMovingNote) return; - - if (this.isBypassRedirect) { - this.isBypassRedirect = false; - return; - } - - await this.redirect(); - }; - async changeSettings(newTab: boolean, switchToTab: boolean): Promise { - this.settings.openInNewTab = newTab; - this.settings.switchToNewTab = switchToTab; - await this.saveSettings(); - } - - private async createRedirectsFolder() { + private async createRedirectsFolder(): Promise { try { this.redirectsFolder = await this.app.vault.createFolder( "/_forwards" ); } catch (error) { - new Notice("Failed to create the `_forwards` folder."); - console.error(error); + console.warn( + "`_forwards` folder not created or already exists.", + error + ); } } - private async redirect() { + private async getCurrentFile(): Promise<{ + currentFile: TFile; + content: string; + } | null> { const currentFile = this.app.workspace.getActiveFile(); if (!currentFile) { - return; - } - - const currentFileContent = (await this.getCurrentFileContent( - currentFile - )) as string; - - const targetNoteFile = this.getTargetFile(currentFileContent); - - if (!targetNoteFile) { - return; - } - - if (currentFile.path !== `_forwards/${currentFile.name}`) { - new Notice( - `Moving ${currentFile.name} to the _forwards folder.`, - 2000 - ); - await this.moveRedirectNote(currentFile); - } - - await this.app.workspace.openLinkText( - targetNoteFile.name, - targetNoteFile.path, - this.settings.openInNewTab, - { active: this.settings.switchToNewTab } - ); - } - - private async getCurrentFileContent( - currentFile: TFile - ): Promise { - try { - return await this.app.vault.read(currentFile); - } catch (error) { - new Notice(`Cannot read ${currentFile}.`); - console.error(`Failed to read ${currentFile} content: `, error); - return null; } + + return { + currentFile: currentFile, + content: (await this.getCurrentFileContent(currentFile)) || "", + }; } private getTargetFile(currentFileContent: string): TFile | null { @@ -116,13 +72,107 @@ export default class RedirectPlugin extends Plugin { return targetNoteFile; } + private async redirect(): Promise { + // 1. Get the current file content + const fileAndContent = await this.getCurrentFile(); + if (!fileAndContent) return; + + const { currentFile, content } = fileAndContent; + + // 2. Checks if this is a redirecting note and get the target file + const targetNoteFile = this.getTargetFile(content); + + if (!targetNoteFile) return; + + // 3. If the redirecting file is not in the _forwards folder, move it there + // if (currentFile.path !== `_forwards/${currentFile.name}`) { + // new Notice( + // `Moving ${currentFile.name} to the _forwards folder.`, + // 2000 + // ); + // await this.moveRedirectNote(currentFile); + // } + + await this.moveRedirectNote(currentFile); + + // 4. Open the target note + await this.openTargetNote(targetNoteFile); + // await this.app.workspace.openLinkText( + // targetNoteFile.name, + // targetNoteFile.path, + // this.settings.openInNewTab, + // { active: this.settings.switchToNewTab } + // ); + } + + private async openTargetNote(targetNoteFile: TFile) { + await this.app.workspace.openLinkText( + targetNoteFile.name, + targetNoteFile.path, + this.settings.openInNewTab, + { active: this.settings.switchToNewTab } + ); + } + + private async getCurrentFileContent( + currentFile: TFile + ): Promise { + try { + return await this.app.vault.read(currentFile); + } catch (error) { + new Notice(`Cannot read ${currentFile}.`); + console.error(`Failed to read ${currentFile} content: `, error); + + return null; + } + } + + // private getTargetFile(currentFileContent: string): TFile | null { + // const linkTextRegex = /::>\[\[(.*?)\]\]/i; + // const targetNoteName = currentFileContent.match(linkTextRegex)?.at(1); + + // if (!targetNoteName) { + // return null; + // } + // const targetNoteFile = this.app.metadataCache.getFirstLinkpathDest( + // getLinkpath(targetNoteName), + // "" + // ); + + // if (!targetNoteFile) { + // new Notice( + // "Target note not found. Create one and try again.", + // 3500 + // ); + // console.error( + // `No target note file found for target: ${targetNoteName}. You can create one manually and try again.` + // ); + // return null; + // } + + // return targetNoteFile; + // } + private async moveRedirectNote( redirectingNote: TFile | null - ): Promise { - if (!redirectingNote) { + ): Promise { + if ( + !redirectingNote || + redirectingNote.path === `_forwards/${redirectingNote.name}` + ) { return; } + // if (redirectingNote.path === `_forwards/${redirectingNote.name}`) { + // return; + // } + + new Notice( + `Moving ${redirectingNote.name} to the _forwards folder.`, + 2000 + ); + + // If necessary, create _forwards folder if (!this.redirectsFolder) { await this.createRedirectsFolder(); } @@ -135,14 +185,15 @@ export default class RedirectPlugin extends Plugin { ); if (this.settings.openInNewTab) { - await this.app.workspace.openLinkText( - redirectingNoteInFolder.name, - redirectingNoteInFolder.path, - this.settings.openInNewTab, - { - active: this.settings.switchToNewTab, - } - ); + await this.openTargetNote(redirectingNoteInFolder); + // await this.app.workspace.openLinkText( + // redirectingNoteInFolder.name, + // redirectingNoteInFolder.path, + // this.settings.openInNewTab, + // { + // active: this.settings.switchToNewTab, + // } + // ); } // Delay deletion to avoid race condition where the original note is deleted before the new note is fully opened in the UI. @@ -168,6 +219,23 @@ export default class RedirectPlugin extends Plugin { } } + handleFileOpen = async (file: TFile): Promise => { + if (this.isMovingNote) return; + + if (this.isBypassRedirect) { + this.isBypassRedirect = false; + return; + } + + await this.redirect(); + }; + + async changeSettings(newTab: boolean, switchToTab: boolean): Promise { + this.settings.openInNewTab = newTab; + this.settings.switchToNewTab = switchToTab; + await this.saveSettings(); + } + async onload() { await this.loadSettings(); From 4a297bc369b5ea59d3f6c562494d797422c9428f Mon Sep 17 00:00:00 2001 From: idanlib Date: Sun, 27 Jul 2025 01:07:20 +0300 Subject: [PATCH 2/4] code review 2 - reorg file --- main-org.ts | 300 +++++++++++++++++++++++++++++++++++++++++ main.ts | 382 ++++++++++++++++++++++------------------------------ 2 files changed, 463 insertions(+), 219 deletions(-) create mode 100644 main-org.ts diff --git a/main-org.ts b/main-org.ts new file mode 100644 index 0000000..d2d66c2 --- /dev/null +++ b/main-org.ts @@ -0,0 +1,300 @@ +// import { getLinkpath, Plugin, Notice, TFolder, TFile } from "obsidian"; +// import RedirectSettingsTab from "components/Settings"; + +// interface RedirectSettings { +// openInNewTab: boolean; +// switchToNewTab: boolean; +// } + +// const DEFAULT_SETTINGS: RedirectSettings = { +// openInNewTab: false, +// switchToNewTab: false, +// }; + +// export default class RedirectPlugin extends Plugin { +// settings: RedirectSettings; +// redirectsFolder: TFolder | null = null; +// isMovingNote = false; +// isBypassRedirect = false; + +// private async createRedirectsFolder(): Promise { +// try { +// this.redirectsFolder = await this.app.vault.createFolder( +// "/_forwards" +// ); +// } catch (error) { +// console.warn( +// "`_forwards` folder not created or already exists.", +// error +// ); +// } +// } + +// private async getCurrentFile(): Promise<{ +// currentFile: TFile; +// content: string; +// } | null> { +// const currentFile = this.app.workspace.getActiveFile(); + +// if (!currentFile) { +// return null; +// } + +// return { +// currentFile: currentFile, +// content: (await this.getCurrentFileContent(currentFile)) || "", +// }; +// } + +// private getTargetFile(currentFileContent: string): TFile | null { +// const linkTextRegex = /::>\[\[(.*?)\]\]/i; +// const targetNoteName = currentFileContent.match(linkTextRegex)?.at(1); + +// if (!targetNoteName) { +// return null; +// } +// const targetNoteFile = this.app.metadataCache.getFirstLinkpathDest( +// getLinkpath(targetNoteName), +// "" +// ); + +// if (!targetNoteFile) { +// new Notice( +// "Target note not found. Create one and try again.", +// 3500 +// ); +// console.error( +// `No target note file found for target: ${targetNoteName}. You can create one manually and try again.` +// ); +// return null; +// } + +// return targetNoteFile; +// } + +// private async redirect(): Promise { +// // 1. Get the current file content +// const fileAndContent = await this.getCurrentFile(); +// if (!fileAndContent) return; + +// const { currentFile, content } = fileAndContent; + +// // 2. Checks if this is a redirecting note and get the target file +// const targetNoteFile = this.getTargetFile(content); + +// if (!targetNoteFile) return; + +// // 3. If the redirecting file is not in the _forwards folder, move it there +// // if (currentFile.path !== `_forwards/${currentFile.name}`) { +// // new Notice( +// // `Moving ${currentFile.name} to the _forwards folder.`, +// // 2000 +// // ); +// // await this.moveRedirectNote(currentFile); +// // } + +// await this.moveRedirectNote(currentFile); + +// // 4. Open the target note +// await this.openTargetNote(targetNoteFile); +// // await this.app.workspace.openLinkText( +// // targetNoteFile.name, +// // targetNoteFile.path, +// // this.settings.openInNewTab, +// // { active: this.settings.switchToNewTab } +// // ); +// } + +// private async openTargetNote(targetNoteFile: TFile) { +// await this.app.workspace.openLinkText( +// targetNoteFile.name, +// targetNoteFile.path, +// this.settings.openInNewTab, +// { active: this.settings.switchToNewTab } +// ); +// } + +// private async getCurrentFileContent( +// currentFile: TFile +// ): Promise { +// try { +// return await this.app.vault.read(currentFile); +// } catch (error) { +// new Notice(`Cannot read ${currentFile}.`); +// console.error(`Failed to read ${currentFile} content: `, error); + +// return null; +// } +// } + +// // private getTargetFile(currentFileContent: string): TFile | null { +// // const linkTextRegex = /::>\[\[(.*?)\]\]/i; +// // const targetNoteName = currentFileContent.match(linkTextRegex)?.at(1); + +// // if (!targetNoteName) { +// // return null; +// // } +// // const targetNoteFile = this.app.metadataCache.getFirstLinkpathDest( +// // getLinkpath(targetNoteName), +// // "" +// // ); + +// // if (!targetNoteFile) { +// // new Notice( +// // "Target note not found. Create one and try again.", +// // 3500 +// // ); +// // console.error( +// // `No target note file found for target: ${targetNoteName}. You can create one manually and try again.` +// // ); +// // return null; +// // } + +// // return targetNoteFile; +// // } + +// private async moveRedirectNote( +// redirectingNote: TFile | null +// ): Promise { +// if ( +// !redirectingNote || +// redirectingNote.path === `_forwards/${redirectingNote.name}` +// ) { +// return; +// } + +// // if (redirectingNote.path === `_forwards/${redirectingNote.name}`) { +// // return; +// // } + +// new Notice( +// `Moving ${redirectingNote.name} to the _forwards folder.`, +// 2000 +// ); + +// // If necessary, create _forwards folder +// if (!this.redirectsFolder) { +// await this.createRedirectsFolder(); +// } + +// try { +// this.isMovingNote = true; +// const redirectingNoteInFolder = await this.app.vault.copy( +// redirectingNote, +// `/_forwards/${redirectingNote.name}` +// ); + +// if (this.settings.openInNewTab) { +// await this.openTargetNote(redirectingNoteInFolder); +// // await this.app.workspace.openLinkText( +// // redirectingNoteInFolder.name, +// // redirectingNoteInFolder.path, +// // this.settings.openInNewTab, +// // { +// // active: this.settings.switchToNewTab, +// // } +// // ); +// } + +// // Delay deletion to avoid race condition where the original note is deleted before the new note is fully opened in the UI. +// setTimeout(async () => { +// await this.deleteNote(redirectingNote); +// this.isMovingNote = false; +// }, 500); +// } catch (error) { +// this.isMovingNote = false; +// console.error(error); +// } +// } + +// private async deleteNote(orgRedirectingNote: TFile): Promise { +// try { +// await this.app.fileManager.trashFile(orgRedirectingNote); +// } catch (error) { +// new Notice( +// "Failed to delete directing note from original location. Please delete manually.", +// 4500 +// ); +// console.error(error); +// } +// } + +// handleFileOpen = async (file: TFile): Promise => { +// if (this.isMovingNote) return; + +// if (this.isBypassRedirect) { +// this.isBypassRedirect = false; +// return; +// } + +// await this.redirect(); +// }; + +// async changeSettings(newTab: boolean, switchToTab: boolean): Promise { +// this.settings.openInNewTab = newTab; +// this.settings.switchToNewTab = switchToTab; +// await this.saveSettings(); +// } + +// async onload() { +// await this.loadSettings(); + +// this.addSettingTab(new RedirectSettingsTab(this.app, this)); + +// this.app.workspace.onLayoutReady(async () => { +// await this.createRedirectsFolder(); +// await this.redirect(); +// }); + +// this.app.workspace.on("file-open", this.handleFileOpen); + +// this.addCommand({ +// id: "paste-redirect-syntax", +// name: "Paste redirect syntax onto selection", +// editorCallback: (editor, view) => { +// const selection = editor.getSelection(); +// editor.replaceSelection(`::>[[${selection}]]`); +// const { ch, line } = editor.getCursor(); +// if (!selection) { +// editor.setCursor({ +// ch: ch - 2, +// line: line, +// }); +// } +// }, +// }); + +// this.addCommand({ +// id: "bypass-redirect", +// name: "Bypass redirect to target note", +// callback: () => { +// this.isBypassRedirect = true; +// new Notice("Bypassing redirects."); +// }, +// }); +// } + +// onunload() { +// this.app.workspace.off("file-open", this.handleFileOpen); +// } + +// async loadSettings() { +// try { +// this.settings = Object.assign( +// {}, +// DEFAULT_SETTINGS, +// await this.loadData() +// ); +// } catch (error) { +// console.error("Failed to load settings: ", error); +// } +// } + +// async saveSettings() { +// try { +// await this.saveData(this.settings); +// } catch (error) { +// console.error("Failed to save settings: ", error); +// } +// } +// } diff --git a/main.ts b/main.ts index 6828fdf..9fbfae7 100644 --- a/main.ts +++ b/main.ts @@ -1,6 +1,7 @@ import { getLinkpath, Plugin, Notice, TFolder, TFile } from "obsidian"; import RedirectSettingsTab from "components/Settings"; +// --- Setup --- interface RedirectSettings { openInNewTab: boolean; switchToNewTab: boolean; @@ -11,231 +12,15 @@ const DEFAULT_SETTINGS: RedirectSettings = { switchToNewTab: false, }; +// --- Main Plugin Class --- export default class RedirectPlugin extends Plugin { + // --- Properties --- settings: RedirectSettings; redirectsFolder: TFolder | null = null; isMovingNote = false; isBypassRedirect = false; - private async createRedirectsFolder(): Promise { - try { - this.redirectsFolder = await this.app.vault.createFolder( - "/_forwards" - ); - } catch (error) { - console.warn( - "`_forwards` folder not created or already exists.", - error - ); - } - } - - private async getCurrentFile(): Promise<{ - currentFile: TFile; - content: string; - } | null> { - const currentFile = this.app.workspace.getActiveFile(); - - if (!currentFile) { - return null; - } - - return { - currentFile: currentFile, - content: (await this.getCurrentFileContent(currentFile)) || "", - }; - } - - private getTargetFile(currentFileContent: string): TFile | null { - const linkTextRegex = /::>\[\[(.*?)\]\]/i; - const targetNoteName = currentFileContent.match(linkTextRegex)?.at(1); - - if (!targetNoteName) { - return null; - } - const targetNoteFile = this.app.metadataCache.getFirstLinkpathDest( - getLinkpath(targetNoteName), - "" - ); - - if (!targetNoteFile) { - new Notice( - "Target note not found. Create one and try again.", - 3500 - ); - console.error( - `No target note file found for target: ${targetNoteName}. You can create one manually and try again.` - ); - return null; - } - - return targetNoteFile; - } - - private async redirect(): Promise { - // 1. Get the current file content - const fileAndContent = await this.getCurrentFile(); - if (!fileAndContent) return; - - const { currentFile, content } = fileAndContent; - - // 2. Checks if this is a redirecting note and get the target file - const targetNoteFile = this.getTargetFile(content); - - if (!targetNoteFile) return; - - // 3. If the redirecting file is not in the _forwards folder, move it there - // if (currentFile.path !== `_forwards/${currentFile.name}`) { - // new Notice( - // `Moving ${currentFile.name} to the _forwards folder.`, - // 2000 - // ); - // await this.moveRedirectNote(currentFile); - // } - - await this.moveRedirectNote(currentFile); - - // 4. Open the target note - await this.openTargetNote(targetNoteFile); - // await this.app.workspace.openLinkText( - // targetNoteFile.name, - // targetNoteFile.path, - // this.settings.openInNewTab, - // { active: this.settings.switchToNewTab } - // ); - } - - private async openTargetNote(targetNoteFile: TFile) { - await this.app.workspace.openLinkText( - targetNoteFile.name, - targetNoteFile.path, - this.settings.openInNewTab, - { active: this.settings.switchToNewTab } - ); - } - - private async getCurrentFileContent( - currentFile: TFile - ): Promise { - try { - return await this.app.vault.read(currentFile); - } catch (error) { - new Notice(`Cannot read ${currentFile}.`); - console.error(`Failed to read ${currentFile} content: `, error); - - return null; - } - } - - // private getTargetFile(currentFileContent: string): TFile | null { - // const linkTextRegex = /::>\[\[(.*?)\]\]/i; - // const targetNoteName = currentFileContent.match(linkTextRegex)?.at(1); - - // if (!targetNoteName) { - // return null; - // } - // const targetNoteFile = this.app.metadataCache.getFirstLinkpathDest( - // getLinkpath(targetNoteName), - // "" - // ); - - // if (!targetNoteFile) { - // new Notice( - // "Target note not found. Create one and try again.", - // 3500 - // ); - // console.error( - // `No target note file found for target: ${targetNoteName}. You can create one manually and try again.` - // ); - // return null; - // } - - // return targetNoteFile; - // } - - private async moveRedirectNote( - redirectingNote: TFile | null - ): Promise { - if ( - !redirectingNote || - redirectingNote.path === `_forwards/${redirectingNote.name}` - ) { - return; - } - - // if (redirectingNote.path === `_forwards/${redirectingNote.name}`) { - // return; - // } - - new Notice( - `Moving ${redirectingNote.name} to the _forwards folder.`, - 2000 - ); - - // If necessary, create _forwards folder - if (!this.redirectsFolder) { - await this.createRedirectsFolder(); - } - - try { - this.isMovingNote = true; - const redirectingNoteInFolder = await this.app.vault.copy( - redirectingNote, - `/_forwards/${redirectingNote.name}` - ); - - if (this.settings.openInNewTab) { - await this.openTargetNote(redirectingNoteInFolder); - // await this.app.workspace.openLinkText( - // redirectingNoteInFolder.name, - // redirectingNoteInFolder.path, - // this.settings.openInNewTab, - // { - // active: this.settings.switchToNewTab, - // } - // ); - } - - // Delay deletion to avoid race condition where the original note is deleted before the new note is fully opened in the UI. - setTimeout(async () => { - await this.deleteNote(redirectingNote); - this.isMovingNote = false; - }, 500); - } catch (error) { - this.isMovingNote = false; - console.error(error); - } - } - - private async deleteNote(orgRedirectingNote: TFile): Promise { - try { - await this.app.fileManager.trashFile(orgRedirectingNote); - } catch (error) { - new Notice( - "Failed to delete directing note from original location. Please delete manually.", - 4500 - ); - console.error(error); - } - } - - handleFileOpen = async (file: TFile): Promise => { - if (this.isMovingNote) return; - - if (this.isBypassRedirect) { - this.isBypassRedirect = false; - return; - } - - await this.redirect(); - }; - - async changeSettings(newTab: boolean, switchToTab: boolean): Promise { - this.settings.openInNewTab = newTab; - this.settings.switchToNewTab = switchToTab; - await this.saveSettings(); - } - + // --- Lifecycle methods and commands--- async onload() { await this.loadSettings(); @@ -278,6 +63,165 @@ export default class RedirectPlugin extends Plugin { this.app.workspace.off("file-open", this.handleFileOpen); } + // --- Event Handlers --- + handleFileOpen = async (file: TFile) => { + if (this.isMovingNote) return; + if (this.isBypassRedirect) { + this.isBypassRedirect = false; + return; + } + await this.redirect(); + }; + + async changeSettings(newTab: boolean, switchToTab: boolean): Promise { + this.settings.openInNewTab = newTab; + this.settings.switchToNewTab = switchToTab; + await this.saveSettings(); + } + + // --- Core Logic --- + private async redirect(): Promise { + const fileAndContent = await this.getCurrentFile(); + if (!fileAndContent) return; + + const { currentFile, content } = fileAndContent; + const targetNoteFile = this.getTargetFile(content); + if (!targetNoteFile) return; + + await this.moveRedirectNote(currentFile); + await this.openTargetNote(targetNoteFile); + } + + // --- Helper functions --- + + private async moveRedirectNote( + redirectingNote: TFile | null + ): Promise { + if ( + !redirectingNote || + redirectingNote.path === `_forwards/${redirectingNote.name}` + ) { + return; + } + + new Notice( + `Moving ${redirectingNote.name} to the _forwards folder.`, + 2000 + ); + + if (!this.redirectsFolder) { + await this.createRedirectsFolder(); + } + + try { + this.isMovingNote = true; + const redirectingNoteInFolder = await this.app.vault.copy( + redirectingNote, + `/_forwards/${redirectingNote.name}` + ); + + if (this.settings.openInNewTab) { + await this.openTargetNote(redirectingNoteInFolder); + } + + // Delay deletion to avoid race condition where the original note is deleted before the new note is fully opened in the UI. + setTimeout(async () => { + await this.deleteNote(redirectingNote); + this.isMovingNote = false; + }, 500); + } catch (error) { + this.isMovingNote = false; + console.error(error); + } + } + + private async openTargetNote(targetNoteFile: TFile) { + await this.app.workspace.openLinkText( + targetNoteFile.name, + targetNoteFile.path, + this.settings.openInNewTab, + { active: this.settings.switchToNewTab } + ); + } + + private async createRedirectsFolder() { + try { + this.redirectsFolder = await this.app.vault.createFolder( + "/_forwards" + ); + } catch (error) { + console.warn( + "`_forwards` folder not created or already exists.", + error + ); + } + } + + private async getCurrentFile(): Promise<{ + currentFile: TFile; + content: string; + } | null> { + const currentFile = this.app.workspace.getActiveFile(); + if (!currentFile) { + return null; + } + return { + currentFile: currentFile, + content: (await this.getCurrentFileContent(currentFile)) || "", + }; + } + + private async getCurrentFileContent( + currentFile: TFile + ): Promise { + try { + return await this.app.vault.read(currentFile); + } catch (error) { + new Notice(`Cannot read ${currentFile}.`); + console.error(`Failed to read ${currentFile} content: `, error); + return null; + } + } + + private getTargetFile(currentFileContent: string): TFile | null { + const linkTextRegex = /::>\[\[(.*?)\]\]/i; + const targetNoteName = currentFileContent.match(linkTextRegex)?.at(1); + + if (!targetNoteName) { + return null; + } + const targetNoteFile = this.app.metadataCache.getFirstLinkpathDest( + getLinkpath(targetNoteName), + "" + ); + + if (!targetNoteFile) { + new Notice( + "Target note not found. Create one and try again.", + 3500 + ); + console.error( + `No target note file found for target: ${targetNoteName}. You can create one manually and try again.` + ); + return null; + } + + return targetNoteFile; + } + + private async deleteNote(orgRedirectingNote: TFile): Promise { + try { + await this.app.fileManager.trashFile(orgRedirectingNote); + } catch (error) { + new Notice( + "Failed to delete directing note from original location. Please delete manually.", + 4500 + ); + console.error(error); + } + } + + // --- Settings Persistence --- async loadSettings() { try { this.settings = Object.assign( From 198807bfbc4a6f19318d5ca45f0f9547752a2801 Mon Sep 17 00:00:00 2001 From: idanlib Date: Sun, 3 Aug 2025 01:12:48 +0300 Subject: [PATCH 3/4] code review 2b - reorg, version 1.1 --- main-org.ts | 300 -------------------------------------------------- manifest.json | 4 +- package.json | 2 +- versions.json | 3 +- 4 files changed, 5 insertions(+), 304 deletions(-) delete mode 100644 main-org.ts diff --git a/main-org.ts b/main-org.ts deleted file mode 100644 index d2d66c2..0000000 --- a/main-org.ts +++ /dev/null @@ -1,300 +0,0 @@ -// import { getLinkpath, Plugin, Notice, TFolder, TFile } from "obsidian"; -// import RedirectSettingsTab from "components/Settings"; - -// interface RedirectSettings { -// openInNewTab: boolean; -// switchToNewTab: boolean; -// } - -// const DEFAULT_SETTINGS: RedirectSettings = { -// openInNewTab: false, -// switchToNewTab: false, -// }; - -// export default class RedirectPlugin extends Plugin { -// settings: RedirectSettings; -// redirectsFolder: TFolder | null = null; -// isMovingNote = false; -// isBypassRedirect = false; - -// private async createRedirectsFolder(): Promise { -// try { -// this.redirectsFolder = await this.app.vault.createFolder( -// "/_forwards" -// ); -// } catch (error) { -// console.warn( -// "`_forwards` folder not created or already exists.", -// error -// ); -// } -// } - -// private async getCurrentFile(): Promise<{ -// currentFile: TFile; -// content: string; -// } | null> { -// const currentFile = this.app.workspace.getActiveFile(); - -// if (!currentFile) { -// return null; -// } - -// return { -// currentFile: currentFile, -// content: (await this.getCurrentFileContent(currentFile)) || "", -// }; -// } - -// private getTargetFile(currentFileContent: string): TFile | null { -// const linkTextRegex = /::>\[\[(.*?)\]\]/i; -// const targetNoteName = currentFileContent.match(linkTextRegex)?.at(1); - -// if (!targetNoteName) { -// return null; -// } -// const targetNoteFile = this.app.metadataCache.getFirstLinkpathDest( -// getLinkpath(targetNoteName), -// "" -// ); - -// if (!targetNoteFile) { -// new Notice( -// "Target note not found. Create one and try again.", -// 3500 -// ); -// console.error( -// `No target note file found for target: ${targetNoteName}. You can create one manually and try again.` -// ); -// return null; -// } - -// return targetNoteFile; -// } - -// private async redirect(): Promise { -// // 1. Get the current file content -// const fileAndContent = await this.getCurrentFile(); -// if (!fileAndContent) return; - -// const { currentFile, content } = fileAndContent; - -// // 2. Checks if this is a redirecting note and get the target file -// const targetNoteFile = this.getTargetFile(content); - -// if (!targetNoteFile) return; - -// // 3. If the redirecting file is not in the _forwards folder, move it there -// // if (currentFile.path !== `_forwards/${currentFile.name}`) { -// // new Notice( -// // `Moving ${currentFile.name} to the _forwards folder.`, -// // 2000 -// // ); -// // await this.moveRedirectNote(currentFile); -// // } - -// await this.moveRedirectNote(currentFile); - -// // 4. Open the target note -// await this.openTargetNote(targetNoteFile); -// // await this.app.workspace.openLinkText( -// // targetNoteFile.name, -// // targetNoteFile.path, -// // this.settings.openInNewTab, -// // { active: this.settings.switchToNewTab } -// // ); -// } - -// private async openTargetNote(targetNoteFile: TFile) { -// await this.app.workspace.openLinkText( -// targetNoteFile.name, -// targetNoteFile.path, -// this.settings.openInNewTab, -// { active: this.settings.switchToNewTab } -// ); -// } - -// private async getCurrentFileContent( -// currentFile: TFile -// ): Promise { -// try { -// return await this.app.vault.read(currentFile); -// } catch (error) { -// new Notice(`Cannot read ${currentFile}.`); -// console.error(`Failed to read ${currentFile} content: `, error); - -// return null; -// } -// } - -// // private getTargetFile(currentFileContent: string): TFile | null { -// // const linkTextRegex = /::>\[\[(.*?)\]\]/i; -// // const targetNoteName = currentFileContent.match(linkTextRegex)?.at(1); - -// // if (!targetNoteName) { -// // return null; -// // } -// // const targetNoteFile = this.app.metadataCache.getFirstLinkpathDest( -// // getLinkpath(targetNoteName), -// // "" -// // ); - -// // if (!targetNoteFile) { -// // new Notice( -// // "Target note not found. Create one and try again.", -// // 3500 -// // ); -// // console.error( -// // `No target note file found for target: ${targetNoteName}. You can create one manually and try again.` -// // ); -// // return null; -// // } - -// // return targetNoteFile; -// // } - -// private async moveRedirectNote( -// redirectingNote: TFile | null -// ): Promise { -// if ( -// !redirectingNote || -// redirectingNote.path === `_forwards/${redirectingNote.name}` -// ) { -// return; -// } - -// // if (redirectingNote.path === `_forwards/${redirectingNote.name}`) { -// // return; -// // } - -// new Notice( -// `Moving ${redirectingNote.name} to the _forwards folder.`, -// 2000 -// ); - -// // If necessary, create _forwards folder -// if (!this.redirectsFolder) { -// await this.createRedirectsFolder(); -// } - -// try { -// this.isMovingNote = true; -// const redirectingNoteInFolder = await this.app.vault.copy( -// redirectingNote, -// `/_forwards/${redirectingNote.name}` -// ); - -// if (this.settings.openInNewTab) { -// await this.openTargetNote(redirectingNoteInFolder); -// // await this.app.workspace.openLinkText( -// // redirectingNoteInFolder.name, -// // redirectingNoteInFolder.path, -// // this.settings.openInNewTab, -// // { -// // active: this.settings.switchToNewTab, -// // } -// // ); -// } - -// // Delay deletion to avoid race condition where the original note is deleted before the new note is fully opened in the UI. -// setTimeout(async () => { -// await this.deleteNote(redirectingNote); -// this.isMovingNote = false; -// }, 500); -// } catch (error) { -// this.isMovingNote = false; -// console.error(error); -// } -// } - -// private async deleteNote(orgRedirectingNote: TFile): Promise { -// try { -// await this.app.fileManager.trashFile(orgRedirectingNote); -// } catch (error) { -// new Notice( -// "Failed to delete directing note from original location. Please delete manually.", -// 4500 -// ); -// console.error(error); -// } -// } - -// handleFileOpen = async (file: TFile): Promise => { -// if (this.isMovingNote) return; - -// if (this.isBypassRedirect) { -// this.isBypassRedirect = false; -// return; -// } - -// await this.redirect(); -// }; - -// async changeSettings(newTab: boolean, switchToTab: boolean): Promise { -// this.settings.openInNewTab = newTab; -// this.settings.switchToNewTab = switchToTab; -// await this.saveSettings(); -// } - -// async onload() { -// await this.loadSettings(); - -// this.addSettingTab(new RedirectSettingsTab(this.app, this)); - -// this.app.workspace.onLayoutReady(async () => { -// await this.createRedirectsFolder(); -// await this.redirect(); -// }); - -// this.app.workspace.on("file-open", this.handleFileOpen); - -// this.addCommand({ -// id: "paste-redirect-syntax", -// name: "Paste redirect syntax onto selection", -// editorCallback: (editor, view) => { -// const selection = editor.getSelection(); -// editor.replaceSelection(`::>[[${selection}]]`); -// const { ch, line } = editor.getCursor(); -// if (!selection) { -// editor.setCursor({ -// ch: ch - 2, -// line: line, -// }); -// } -// }, -// }); - -// this.addCommand({ -// id: "bypass-redirect", -// name: "Bypass redirect to target note", -// callback: () => { -// this.isBypassRedirect = true; -// new Notice("Bypassing redirects."); -// }, -// }); -// } - -// onunload() { -// this.app.workspace.off("file-open", this.handleFileOpen); -// } - -// async loadSettings() { -// try { -// this.settings = Object.assign( -// {}, -// DEFAULT_SETTINGS, -// await this.loadData() -// ); -// } catch (error) { -// console.error("Failed to load settings: ", error); -// } -// } - -// async saveSettings() { -// try { -// await this.saveData(this.settings); -// } catch (error) { -// console.error("Failed to save settings: ", error); -// } -// } -// } diff --git a/manifest.json b/manifest.json index 785cc5d..743786b 100644 --- a/manifest.json +++ b/manifest.json @@ -1,10 +1,10 @@ { "id": "fast-forward-link", "name": "FastForwardLink", - "version": "1.0.1", + "version": "1.1.0", "minAppVersion": "0.15.0", "description": "Fast-forward multiple links to a single target note. Create custom link shorthands (like `ps` > `photoshop`) to create synonyms, streamline navigation, and keep your vault organized.", "author": "Idan Liberman", "isDesktopOnly": false, "fundingUrl": "https://buymeacoffee.com/idanlib" -} +} \ No newline at end of file diff --git a/package.json b/package.json index 9f6a4bf..df80a4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fast-forward-link", - "version": "1.0.0", + "version": "1.1.0", "description": "Forward multiple links to a single note with ease.", "main": "main.js", "scripts": { diff --git a/versions.json b/versions.json index df3d877..908e85c 100644 --- a/versions.json +++ b/versions.json @@ -1,3 +1,4 @@ { + "1.0.0": "0.15.0", "1.1.0": "0.15.0" -} +} \ No newline at end of file From 789c1a830ec847e6a63665863493ac5512c813a1 Mon Sep 17 00:00:00 2001 From: idanlib Date: Sun, 3 Aug 2025 01:17:53 +0300 Subject: [PATCH 4/4] code review 2b - reorg, version 1.1 + update readme --- README.md | 10 ++++++++++ main.ts | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index aa8b1f2..827c9f6 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,16 @@ Here are some examples of how you might set up FastForwardLink: ![demo](./plugin_demo.gif) +## Version Updates + +### Version 1.1 + +Some improvements include: + +- You can now temporarily by pass forwarding with a designated command! +- Source code refactored and better organized for future conributors. +- Better robust event and error handling and messaging. + ## Features - **Multiple Links, One Target**: Set multiple links to redirect to a single target note for quick navigation between related topics or abbreviations. Organize synonyms or alternate spellings for easier access. diff --git a/main.ts b/main.ts index 9fbfae7..d5dd691 100644 --- a/main.ts +++ b/main.ts @@ -50,8 +50,8 @@ export default class RedirectPlugin extends Plugin { }); this.addCommand({ - id: "bypass-redirect", - name: "Bypass redirect to target note", + id: "bypass-forwarding", + name: "Bypass forwarding to target note", callback: () => { this.isBypassRedirect = true; new Notice("Bypassing redirects.");