From c6219674de01a928ea6de7d0049f9da77ae6f347 Mon Sep 17 00:00:00 2001 From: Momik Shrestha Date: Fri, 5 Jan 2024 19:41:50 +0545 Subject: [PATCH] feat: converge sync events if overlap --- main.ts | 125 ++++++++++++++-------- manifest.json | 2 +- src/FileCollection/OnlyEverFileManager.ts | 30 +++++- src/interfaces.ts | 4 + 4 files changed, 111 insertions(+), 50 deletions(-) diff --git a/main.ts b/main.ts index ee2ebde..fc54849 100644 --- a/main.ts +++ b/main.ts @@ -1,8 +1,7 @@ -import {Plugin, addIcon, TFile, debounce} from "obsidian"; +import { Plugin, addIcon, TFile, debounce } from "obsidian"; import { OnlyEverFileManager as Manager } from "./src/FileCollection/OnlyEverFileManager"; import { OnlyEverSettingsTab } from "./src/OnlyEverSettingsTab"; -import {OnlyEverSettings} from "./src/interfaces"; - +import { OnlyEverSettings, WasEditedMap } from "./src/interfaces"; const DEFAULT_SETTINGS: OnlyEverSettings = { apiToken: "", @@ -15,9 +14,11 @@ const DEFAULT_SETTINGS: OnlyEverSettings = { export default class OnlyEverPlugin extends Plugin { settings: OnlyEverSettings; oeFileManager: Manager; - activeTab: null | TFile = null; - previousTab: null | TFile = null; - wasEdited: any = {} + + previousTab: TFile; + activeTab: TFile; + wasEdited: WasEditedMap = {} + timeout = 2500; async onload() { this.loadIcons(); @@ -30,7 +31,7 @@ export default class OnlyEverPlugin extends Plugin { this.scheduledSync(); this.addSettingTab(new OnlyEverSettingsTab(this.app, this)); - this.previousTab = this.app.workspace.getActiveFile() + this.setPreviousAndActiveTab(); } async loadSettings() { @@ -46,10 +47,6 @@ export default class OnlyEverPlugin extends Plugin { this.scanVault(); } - getSettingsValue() { - return this.settings.apiToken; - } - private loadHotKeys() { this.addCommand({ id: "add-obsidian-sync-true-in-frontmatter", @@ -104,74 +101,108 @@ export default class OnlyEverPlugin extends Plugin { } /** - * Note by @PG-Momik - * Obsidian's default 'modify' event is 'throttled' not 'debounced'(As per my observation) - * The event delay is 2 to 3 seconds. - * So we set debounce interval to time greater than throttle interval. + * Note by: @PG-Momik + * Obsidian's default 'modify' event is 'throttled' not 'debounced' (I Think) + * The event delay is 2 seconds. + * So we set the debounce interval to time greater than the throttle interval. */ - debouncedSync = debounce(() => { - this.oeFileManager.fileProcessor.processSingleFile(this.settings, this.activeTab) - }, 3000, true) + debouncedSync = debounce(async (file: TFile) => { + console.log('debounce sync vitra'); + if(this.oeFileManager.isSupportedFile(file)){ + console.log('i will sync now'); + await this.oeFileManager.fileProcessor.processSingleFile(this.settings, file); + this.timeout = 2500; + } + }, this.timeout, true) + + debouncedSave = debounce((file: TFile)=>{ + this.timeout = 0 + this.wasEdited[file.path] = false; + this.debouncedSync(file); + }, 500, true); - /* - * Registers event and functionality on event + /** + * Register event and functionality on event */ + private registerAllEvents(): void { + + /** private registerAllEvents() { /* * Registers and handles initial Obsidian open event */ this.registerEvent( - // @ts-ignore - this.app.workspace.on("layout-ready", () => { - this.oeFileManager.fileProcessor.processMarkedFiles(this.settings).then(); - }) + // @ts-ignore ( IDE SHOWING ERROR DESPITE THIS CODE WORKING. ) + this.app.workspace.on("layout-ready", + () => { + this.oeFileManager.fileProcessor.processMarkedFiles(this.settings).then(); + } + ) ); /* * Registers and handles active note edit event */ this.registerEvent( - this.app.vault.on("modify", ()=>{ - this.debouncedSync.cancel() - this.debouncedSync(); - }) + this.app.vault.on("modify", + async (file) => { + if (file instanceof TFile) { + this.debouncedSync(file as TFile); + } + } + ) ); - /* - * Registers and handles vault's note rename event + /** + * Registers and handles vault's note rename event. */ this.registerEvent( - this.app.vault.on("rename", () => { - this.oeFileManager.onActiveFileSaveAction(this.settings).then(); - }) + this.app.vault.on("rename", + () => { + this.oeFileManager.onActiveFileSaveAction(this.settings).then(); + } + ) ); - /* - * Registers and handles note save event + /** + * Registers and handles note save event. */ const saveCommandDefinition = (this.app as any).commands?.commands?.["editor:save-file"]; const save = saveCommandDefinition?.callback; if (typeof save === "function") { saveCommandDefinition.callback = async () => { - this.debouncedSync.cancel(); - this.oeFileManager.onActiveFileSaveAction(this.settings).then(); + this.debouncedSave(this.activeTab); }; } + /** + * Registers and handles tab switch event. + */ this.registerEvent( - this.app.workspace.on('active-leaf-change', () => { - if(this.previousTab){ - const prev = this.previousTab; - if(this.wasEdited[prev.name]){ - this.debouncedSync.cancel() - this.oeFileManager.fileProcessor.processSingleFile(this.settings, this.previousTab) - - this.previousTab = this.app.workspace.getActiveFile() - this.wasEdited[prev.name] = false + this.app.workspace.on('active-leaf-change', + async () => { + if (this.oeFileManager.isActualTabChanged(this.previousTab)) { + if (this.oeFileManager.fileWasEdited(this.wasEdited, this.previousTab) && this.oeFileManager.isSupportedFile(this.previousTab)) { + this.debouncedSync(this.previousTab); + } + + this.setPreviousAndActiveTab(); + this.wasEdited[this.activeTab.path] = false; } } - }) + ) ); } + + /** + * Set previousTab and activeTab to current open file. + */ + private setPreviousAndActiveTab(): void { + const openFileOnAppOpen = this.app.workspace.getActiveFile() + + if(openFileOnAppOpen){ + this.previousTab = this.activeTab = openFileOnAppOpen + } + } } diff --git a/manifest.json b/manifest.json index 6f7e2cf..8d3d421 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "the-only-ever-plugin", "name": "Only Ever", - "version": "1.3.8", + "version": "1.3.8-converge", "minAppVersion": "0.15.0", "description": "This is a sample plugin for Obsidian. This plugin demonstrates some of the capabilities of the Obsidian API.", "author": "Obsidian", diff --git a/src/FileCollection/OnlyEverFileManager.ts b/src/FileCollection/OnlyEverFileManager.ts index ac5e234..c68bdcc 100644 --- a/src/FileCollection/OnlyEverFileManager.ts +++ b/src/FileCollection/OnlyEverFileManager.ts @@ -1,6 +1,6 @@ -import { App, TFile } from "obsidian"; +import {App, TAbstractFile, TFile} from "obsidian"; import { OnlyEverFileProcessor } from "./OnlyEverFileProcessor"; -import {OnlyEverSettings} from "../interfaces"; +import {OnlyEverSettings, WasEditedMap} from "../interfaces"; class OnlyEverFileManager { app: App; @@ -16,6 +16,32 @@ class OnlyEverFileManager { async onActiveFileSaveAction(settings:OnlyEverSettings) { this.fileProcessor.processSingleFile(settings); } + + fileWasEdited(wasEditedMap: WasEditedMap, file: TFile|null) { + return Boolean(file && file.path && wasEditedMap[file.path]); + } + + isSupportedFile(file: TFile | null){ + if( file ){ + return file.extension === 'md' + } + + return false + } + + /* + * Note by @PG-Momik + * Single Clicking item OR drag dropping items from sidebar is considered active-leaf-change. + * So need to check if it's an actual active leaf change event or a false positive. + * So we compare the file path of the supposed new active file and the actual previous file. + * + * @return boolean + */ + isActualTabChanged(previousTab: TFile): boolean { + const newActiveFile = this.app.workspace.getActiveFile(); + + return previousTab?.path !== newActiveFile?.path; + } } export { OnlyEverFileManager }; diff --git a/src/interfaces.ts b/src/interfaces.ts index 7b1d936..e1f1aac 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -94,3 +94,7 @@ export interface SyncImagesResponse extends OeResponse{ export interface Siblings { [key: string]: Stat } + +export interface WasEditedMap{ + [key: string]: boolean +}