Merge pull request #203 from SebastianMC/202-improve-automatic-initial-application-of-custom-sorting-for-obsidian-deferred-views
202 improve automatic initial application of custom sorting for obsidian deferred views
This commit is contained in:
		
						commit
						5bb04f41a1
					
				
							
								
								
									
										87
									
								
								src/main.ts
								
								
								
								
							
							
						
						
									
										87
									
								
								src/main.ts
								
								
								
								
							| 
						 | 
				
			
			@ -78,11 +78,16 @@ type MonkeyAroundUninstaller = () => void
 | 
			
		|||
 | 
			
		||||
type ContextMenuProvider = (item: MenuItem) => void
 | 
			
		||||
 | 
			
		||||
enum FileExplorerStateError {
 | 
			
		||||
	DoesNotExist,
 | 
			
		||||
enum FileExplorerState {
 | 
			
		||||
	DoesNotExist = 1,
 | 
			
		||||
	DeferredView
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface FileExplorerStateError {
 | 
			
		||||
	state: FileExplorerState
 | 
			
		||||
	fileExplorerInDeferredState?: FileExplorerLeaf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type FileExplorerLeafOrError = ValueOrError<FileExplorerLeaf,FileExplorerStateError>
 | 
			
		||||
 | 
			
		||||
export default class CustomSortPlugin
 | 
			
		||||
| 
						 | 
				
			
			@ -188,20 +193,25 @@ export default class CustomSortPlugin
 | 
			
		|||
 | 
			
		||||
		if (fileExplorer) {
 | 
			
		||||
			if (fileExplorer.isDeferred) {
 | 
			
		||||
				return fileExplorerOrError.setError(FileExplorerStateError.DeferredView)
 | 
			
		||||
				return fileExplorerOrError.setError({
 | 
			
		||||
					state: FileExplorerState.DeferredView,
 | 
			
		||||
					fileExplorerInDeferredState: fileExplorer
 | 
			
		||||
				})
 | 
			
		||||
			} else {
 | 
			
		||||
				return fileExplorerOrError.setValue(fileExplorer)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			return fileExplorerOrError.setError(FileExplorerStateError.DoesNotExist)
 | 
			
		||||
			return fileExplorerOrError.setError({
 | 
			
		||||
				state: FileExplorerState.DoesNotExist
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	checkFileExplorerIsAvailableAndPatchable(logWarning: boolean = true): FileExplorerLeafOrError {
 | 
			
		||||
		let fileExplorerOrError = this.getFileExplorer()
 | 
			
		||||
		if (fileExplorerOrError.e === FileExplorerStateError.DeferredView) {
 | 
			
		||||
		if (fileExplorerOrError.e && fileExplorerOrError.e.state === FileExplorerState.DeferredView) {
 | 
			
		||||
			if (logWarning) {
 | 
			
		||||
				this.logWarningFileExplorerDeferred()
 | 
			
		||||
				this.logDeferredFileExplorerInfo()
 | 
			
		||||
			}
 | 
			
		||||
			return fileExplorerOrError
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -269,12 +279,17 @@ export default class CustomSortPlugin
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logWarningFileExplorerDeferred() {
 | 
			
		||||
		const msg = `${PLUGIN_ID} v${this.manifest.version}: failed to get active File Explorer view.\n`
 | 
			
		||||
	logDeferredFileExplorerInfo() {
 | 
			
		||||
		const msg = `${PLUGIN_ID} v${this.manifest.version}: File Explorer is not displayed yet (Obsidian deferred view detected).\n`
 | 
			
		||||
			+ `Until the File Explorer is visible, the custom-sort plugin cannot apply the custom order.\n`
 | 
			
		||||
		console.warn(msg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logDeferredFileExplorerWatcherSetupInfo() {
 | 
			
		||||
		const msg = `${PLUGIN_ID} v${this.manifest.version}: A watcher was set up to apply custom sort automatically when the File Explorer is displayed.\n`
 | 
			
		||||
		console.warn(msg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logWarningFileExplorerNotAvailable() {
 | 
			
		||||
		const msg = `${PLUGIN_ID} v${this.manifest.version}: failed to locate File Explorer. The 'Files' core plugin can be disabled.\n`
 | 
			
		||||
			+ `Some community plugins can also disable it.\n`
 | 
			
		||||
| 
						 | 
				
			
			@ -583,7 +598,7 @@ export default class CustomSortPlugin
 | 
			
		|||
		const plugin = this
 | 
			
		||||
		this.app.workspace.onLayoutReady(() => {
 | 
			
		||||
			setTimeout(() => {
 | 
			
		||||
				plugin.initialDelayedApplicationOfCustomSorting.apply(this)
 | 
			
		||||
				plugin.delayedApplicationOfCustomSorting.apply(this)
 | 
			
		||||
			},
 | 
			
		||||
			plugin.settings.delayForInitialApplication)
 | 
			
		||||
		})
 | 
			
		||||
| 
						 | 
				
			
			@ -682,7 +697,39 @@ export default class CustomSortPlugin
 | 
			
		|||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initialDelayedApplicationOfCustomSorting() {
 | 
			
		||||
	setWatcherForDelayedFileExplorerView(fileExplorerInDeferredState?: FileExplorerLeaf) {
 | 
			
		||||
		const self = this
 | 
			
		||||
 | 
			
		||||
		let workspaceLeafContentElementParentToObserve: HTMLElement|Element|null|undefined = fileExplorerInDeferredState?.view?.containerEl?.parentElement
 | 
			
		||||
		if (!workspaceLeafContentElementParentToObserve) {
 | 
			
		||||
			// Fallback for the case when DOM is not available for deferred file explorer
 | 
			
		||||
			// (did not happen in practice, but just in case)
 | 
			
		||||
			workspaceLeafContentElementParentToObserve = document.querySelector(".workspace");
 | 
			
		||||
		}
 | 
			
		||||
		if (workspaceLeafContentElementParentToObserve) {
 | 
			
		||||
			const fullyFledgedFileExplorerElementSelector=
 | 
			
		||||
					() => workspaceLeafContentElementParentToObserve.querySelector('[data-type="file-explorer"] .nav-files-container');
 | 
			
		||||
 | 
			
		||||
			const mutationObserver = new MutationObserver((_, observerInstance) => {
 | 
			
		||||
				const fullyFledgedFileExplorerElement = fullyFledgedFileExplorerElementSelector();
 | 
			
		||||
				if (fullyFledgedFileExplorerElement) {
 | 
			
		||||
					observerInstance.disconnect();
 | 
			
		||||
					self.delayedApplicationOfCustomSorting(self.FROM_DOM_WATCHER)
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			mutationObserver.observe(workspaceLeafContentElementParentToObserve, {
 | 
			
		||||
				childList: true,
 | 
			
		||||
				subtree: false
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Entering this method for the first time after initial delay after plugin loaded (via setTimeout()),
 | 
			
		||||
	// and if first attempt is unsuccessful, then entering this method again from DOM watcher, when
 | 
			
		||||
	// the File Explorer view gets transformed from delayed view into fully-fledged active view
 | 
			
		||||
	FROM_DOM_WATCHER: boolean = true
 | 
			
		||||
	delayedApplicationOfCustomSorting(fromDOMwatcher?: boolean) {
 | 
			
		||||
		if (!this?.isThePluginStillInstalledAndEnabled()) {
 | 
			
		||||
			console.log(`${PLUGIN_ID} v${this.manifest.version} - delayed handler skipped, plugin no longer active.`)
 | 
			
		||||
			return
 | 
			
		||||
| 
						 | 
				
			
			@ -695,7 +742,25 @@ export default class CustomSortPlugin
 | 
			
		|||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.switchPluginStateTo(true)
 | 
			
		||||
		if (!fromDOMwatcher) {
 | 
			
		||||
			// Only for the first delayed invocation:
 | 
			
		||||
			// If file explorer is delayed, configure the watcher
 | 
			
		||||
			// NOTE: Do not configure the watcher if the file explorer is not available
 | 
			
		||||
			let fileExplorerOrError: FileExplorerLeafOrError = this.checkFileExplorerIsAvailableAndPatchable()
 | 
			
		||||
			if (fileExplorerOrError.e && fileExplorerOrError.e.state === FileExplorerState.DeferredView) {
 | 
			
		||||
				this.logDeferredFileExplorerWatcherSetupInfo()
 | 
			
		||||
				this.setWatcherForDelayedFileExplorerView(fileExplorerOrError.e.fileExplorerInDeferredState)
 | 
			
		||||
			} else if (fileExplorerOrError.e) {
 | 
			
		||||
				// file explorer other error - does not exist
 | 
			
		||||
				// force the plugin switch state to report error and show the error icon
 | 
			
		||||
				this.switchPluginStateTo(true)
 | 
			
		||||
			}
 | 
			
		||||
			else { // file explorer is available
 | 
			
		||||
				this.switchPluginStateTo(true)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			this.switchPluginStateTo(true)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setRibbonIconToEnabled() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue