Add visual separators and confirmation modal for folder history reset

This commit is contained in:
wz 2025-04-30 19:20:45 +02:00
parent eb222d3e52
commit 99e1d036aa
4 changed files with 111 additions and 10 deletions

View file

@ -16,6 +16,8 @@ An [Obsidian](https://obsidian.md) plugin that allows you to quickly navigate to
- Default sorting (alphabetical)
- Recently visited folders displayed at the top
- Frequently visited folders displayed at the top
- Customizable number of recent/frequent folders to show
- Visual separators to distinguish recent/frequent folders
## Why Folder Navigator?

View file

@ -1,4 +1,4 @@
import { App, FuzzySuggestModal, TFolder, WorkspaceLeaf, View } from "obsidian";
import { App, FuzzySuggestModal, TFolder, WorkspaceLeaf, View, FuzzyMatch } from "obsidian";
import type FolderNavigatorPlugin from "./main";
import { FolderSortMode } from "./settings";
@ -97,8 +97,24 @@ export class FolderSuggestModal extends FuzzySuggestModal<TFolder> {
log(`Found ${recentFolders.length} recent folders to display`, this.plugin);
// Combine recent folders with remaining folders
return [...recentFolders, ...remainingFolders];
// Only add separator if we have recent folders to show
if (recentFolders.length > 0) {
// Create a separator "folder" (not a real folder)
const separator = {} as TFolder;
(separator as any)._isSeparator = true;
(separator as any)._separatorText = "— Recently visited folders —";
// Create another separator for the remaining folders
const remainingSeparator = {} as TFolder;
(remainingSeparator as any)._isSeparator = true;
(remainingSeparator as any)._separatorText = "— All folders —";
// Combine recent folders with remaining folders with separators
return [separator, ...recentFolders, remainingSeparator, ...remainingFolders];
}
// If no recent folders, just return all folders
return allFolders;
}
if (sortMode === FolderSortMode.FREQUENCY) {
@ -121,8 +137,24 @@ export class FolderSuggestModal extends FuzzySuggestModal<TFolder> {
log(`Found ${frequentFolders.length} frequent folders to display`, this.plugin);
// Combine frequent folders with remaining folders
return [...frequentFolders, ...remainingFolders];
// Only add separator if we have frequent folders to show
if (frequentFolders.length > 0) {
// Create a separator "folder" (not a real folder)
const separator = {} as TFolder;
(separator as any)._isSeparator = true;
(separator as any)._separatorText = "— Frequently visited folders —";
// Create another separator for the remaining folders
const remainingSeparator = {} as TFolder;
(remainingSeparator as any)._isSeparator = true;
(remainingSeparator as any)._separatorText = "— All folders —";
// Combine frequent folders with remaining folders with separators
return [separator, ...frequentFolders, remainingSeparator, ...remainingFolders];
}
// If no frequent folders, just return all folders
return allFolders;
}
// Fallback to default sorting
@ -158,6 +190,10 @@ export class FolderSuggestModal extends FuzzySuggestModal<TFolder> {
}
getItemText(folder: TFolder): string {
// For separator folders (which will have a special property), return the separator text
if ((folder as any)._isSeparator) {
return (folder as any)._separatorText;
}
return folder.path;
}
@ -225,7 +261,12 @@ export class FolderSuggestModal extends FuzzySuggestModal<TFolder> {
/**
* Event handler for when a folder is chosen from the suggestion list
*/
onChooseItem(folder: TFolder): void {
onChooseItem(folder: TFolder, evt: MouseEvent | KeyboardEvent): void {
// Check if this is a separator and ignore if so
if ((folder as any)._isSeparator) {
return;
}
log(
`Folder selected: "${folder.path}" (name: "${folder.name}")`,
this.plugin,
@ -436,4 +477,20 @@ export class FolderSuggestModal extends FuzzySuggestModal<TFolder> {
logError(`Error highlighting folder: ${error}`);
}
}
// Override the renderSuggestion method to customize how folders are displayed
renderSuggestion(item: FuzzyMatch<TFolder>, el: HTMLElement): void {
// Check if this is a separator
if ((item.item as any)._isSeparator) {
el.empty();
const separatorEl = el.createDiv({
cls: "folder-separator"
});
separatorEl.setText((item.item as any)._separatorText);
return;
}
// Regular folder rendering - use the default rendering
super.renderSuggestion(item, el);
}
}

View file

@ -1,4 +1,4 @@
import { App, PluginSettingTab, Setting, DropdownComponent } from "obsidian";
import { App, PluginSettingTab, Setting, DropdownComponent, Modal, Notice } from "obsidian";
import FolderNavigatorPlugin from "./main";
import { FolderSortMode } from "./settings";
@ -95,13 +95,44 @@ export class SettingsTab extends PluginSettingTab {
// Add reset history button
new Setting(containerEl)
.setName("Reset folder history")
.setDesc("Clear the tracked history of visited folders")
.setDesc("Clear the tracked history of visited folders. Warning: This will remove all recency and frequency data.")
.addButton((button) =>
button
.setButtonText("Reset")
.setWarning()
.onClick(async () => {
this.plugin.settings.folderHistory = {};
await this.plugin.saveSettings();
// Create a confirmation modal
const confirmModal = new Modal(this.app);
confirmModal.titleEl.setText("Reset folder history");
confirmModal.contentEl.createEl("p", {
text: "Are you sure? This will permanently delete all folder navigation history including recently visited and frequently used folder data.",
cls: "mod-warning"
});
const buttonContainer = confirmModal.contentEl.createDiv({
cls: "modal-button-container"
});
// Cancel button
buttonContainer.createEl("button", {
text: "Cancel"
}).addEventListener("click", () => {
confirmModal.close();
});
// Confirm button
const confirmButton = buttonContainer.createEl("button", {
text: "Reset folder history",
cls: "mod-warning"
});
confirmButton.addEventListener("click", async () => {
this.plugin.settings.folderHistory = {};
await this.plugin.saveSettings();
confirmModal.close();
new Notice("Folder history has been reset");
});
confirmModal.open();
}),
);

View file

@ -3,3 +3,14 @@
border-radius: 4px;
transition: background-color 0.3s ease;
}
.folder-separator {
color: var(--text-muted);
font-size: 0.85em;
text-align: center;
padding: 5px 0;
font-style: italic;
border-bottom: 1px solid var(--background-modifier-border);
margin-bottom: 5px;
pointer-events: none;
}