mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
- Add AssetsService to manage plugin icon and banner assets - Update sidebar, ribbon, and quick actions to use new icon - Add plugin banner to help modal welcome section - Update help text to reference "plugin icon" instead of "sparkles icon"
215 lines
No EOL
8.9 KiB
TypeScript
215 lines
No EOL
8.9 KiB
TypeScript
import type VaultkeeperAIPlugin from "main";
|
|
import { MarkdownView, Menu, setIcon, type EventRef } from "obsidian";
|
|
import { Resolve } from "Services/DependencyService";
|
|
import { Services } from "Services/Services";
|
|
import type { SettingsService } from "Services/SettingsService";
|
|
import { WorkSpaceService } from "Services/WorkSpaceService";
|
|
import type { QuickActionsDefinitionsService } from "./QuickActionsDefinitionsService";
|
|
import type { HelpModal } from "Modals/HelpModal";
|
|
import { AssetsService } from "Services/AssetsService";
|
|
|
|
export class QuickActionsService {
|
|
|
|
private readonly plugin: VaultkeeperAIPlugin;
|
|
private readonly assetsService: AssetsService;
|
|
private readonly settingsService: SettingsService;
|
|
private readonly workSpaceService: WorkSpaceService;
|
|
private readonly quickActionsDefinitionsService: QuickActionsDefinitionsService;
|
|
|
|
private editorMenuEventRef: EventRef | null = null;
|
|
private layoutChangeEventRef: EventRef | null = null;
|
|
|
|
private readonly settingsSubscription: object;
|
|
|
|
public constructor() {
|
|
this.plugin = Resolve<VaultkeeperAIPlugin>(Services.VaultkeeperAIPlugin);
|
|
this.assetsService = Resolve<AssetsService>(Services.AssetsService);
|
|
this.settingsService = Resolve<SettingsService>(Services.SettingsService);
|
|
this.workSpaceService = Resolve<WorkSpaceService>(Services.WorkSpaceService);
|
|
this.quickActionsDefinitionsService = Resolve<QuickActionsDefinitionsService>(Services.QuickActionsDefinitionsService);
|
|
|
|
this.settingsSubscription = this.settingsService.subscribeToSettingsChanged(changed => {
|
|
if (changed.includes("enableToolbarActions") || changed.includes("enableContextMenuActions")) {
|
|
this.updateRegistrations();
|
|
}
|
|
});
|
|
|
|
this.registerEditorMenuActions();
|
|
this.registerViewActions();
|
|
}
|
|
|
|
public dispose() {
|
|
this.settingsService.unsubscribe(this.settingsSubscription);
|
|
this.unregisterEditorMenuActions();
|
|
this.unregisterViewActions();
|
|
}
|
|
|
|
/* Action Registration */
|
|
|
|
private registerEditorMenuActions() {
|
|
if (!this.settingsService.settings.enableContextMenuActions) {
|
|
this.unregisterEditorMenuActions();
|
|
return;
|
|
}
|
|
if (this.editorMenuEventRef) {
|
|
return;
|
|
}
|
|
|
|
this.editorMenuEventRef = this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => {
|
|
menu.addItem((item) => {
|
|
item.setTitle("Proofread")
|
|
.setIcon("scan-text")
|
|
.onClick(async () => this.quickActionsDefinitionsService.proofread(menu, editor, view));
|
|
});
|
|
menu.addItem((item) => {
|
|
item.setTitle("Beautify")
|
|
.setIcon("palette")
|
|
.onClick(async () => this.quickActionsDefinitionsService.beautify(menu, editor, view));
|
|
});
|
|
menu.addItem((item) => {
|
|
item.setTitle("Apply template")
|
|
.setIcon("notepad-text-dashed")
|
|
.onClick(async () => this.quickActionsDefinitionsService.applyTemplate(menu, editor, view));
|
|
});
|
|
menu.addItem((item) => {
|
|
item.setTitle("Apply links")
|
|
.setIcon("link")
|
|
.onClick(async () => this.quickActionsDefinitionsService.applyLinks(menu, editor, view));
|
|
});
|
|
menu.addItem((item) => {
|
|
item.setTitle("Apply tags")
|
|
.setIcon("tag")
|
|
.onClick(async () => this.quickActionsDefinitionsService.applyTags(menu, editor, view));
|
|
});
|
|
menu.addItem((item) => {
|
|
item.setTitle("Suggest tags")
|
|
.setIcon("tags")
|
|
.onClick(async () => this.quickActionsDefinitionsService.suggestTags(menu, editor, view));
|
|
});
|
|
menu.addItem((item) => {
|
|
item.setTitle("Generate frontmatter")
|
|
.setIcon("list-plus")
|
|
.onClick(async () => this.quickActionsDefinitionsService.generateFrontmatter(menu, editor, view));
|
|
});
|
|
menu.addSeparator();
|
|
menu.addItem((item) =>
|
|
item.setTitle("Quick actions")
|
|
.setIcon("circle-question-mark")
|
|
.onClick(() => {
|
|
const modal = Resolve<HelpModal>(Services.HelpModal);
|
|
modal.open(6);
|
|
})
|
|
);
|
|
});
|
|
this.plugin.registerEvent(this.editorMenuEventRef);
|
|
}
|
|
|
|
private registerViewActions() {
|
|
if (!this.settingsService.settings.enableToolbarActions) {
|
|
this.unregisterViewActions();
|
|
return;
|
|
}
|
|
if (this.layoutChangeEventRef) {
|
|
return;
|
|
}
|
|
|
|
this.layoutChangeEventRef = this.plugin.app.workspace.on("layout-change", () => {
|
|
this.injectToolbarButton();
|
|
});
|
|
this.plugin.registerEvent(this.layoutChangeEventRef);
|
|
this.injectToolbarButton();
|
|
}
|
|
|
|
private injectToolbarButton() {
|
|
const leaves = this.workSpaceService.getLeavesOfType("markdown");
|
|
for (const leaf of leaves) {
|
|
const view = leaf.view;
|
|
if (!(view instanceof MarkdownView)) {
|
|
continue;
|
|
}
|
|
|
|
const actionsEl = view.containerEl.querySelector(".view-actions");
|
|
if (!actionsEl || actionsEl.querySelector(".vault-keeper-ai-actions")) {
|
|
continue;
|
|
}
|
|
|
|
const button = createEl("button", { cls: "clickable-icon view-action vault-keeper-ai-actions" });
|
|
button.setAttribute("aria-label", "AI quick actions");
|
|
button.addEventListener("click", (evt) => {
|
|
const { editor } = view;
|
|
const menu = new Menu();
|
|
menu.addItem((item) =>
|
|
item.setTitle("Proofread")
|
|
.setIcon("scan-text")
|
|
.onClick(async () => this.quickActionsDefinitionsService.proofread(menu, editor, view))
|
|
);
|
|
menu.addItem((item) =>
|
|
item.setTitle("Beautify")
|
|
.setIcon("palette")
|
|
.onClick(async () => this.quickActionsDefinitionsService.beautify(menu, editor, view))
|
|
);
|
|
menu.addItem((item) =>
|
|
item.setTitle("Apply template")
|
|
.setIcon("notepad-text-dashed")
|
|
.onClick(async () => this.quickActionsDefinitionsService.applyTemplate(menu, editor, view))
|
|
);
|
|
menu.addItem((item) =>
|
|
item.setTitle("Apply links")
|
|
.setIcon("link")
|
|
.onClick(async () => this.quickActionsDefinitionsService.applyLinks(menu, editor, view))
|
|
);
|
|
menu.addItem((item) =>
|
|
item.setTitle("Apply tags")
|
|
.setIcon("tag")
|
|
.onClick(async () => this.quickActionsDefinitionsService.applyTags(menu, editor, view))
|
|
);
|
|
menu.addItem((item) =>
|
|
item.setTitle("Suggest tags")
|
|
.setIcon("tags")
|
|
.onClick(async () => this.quickActionsDefinitionsService.suggestTags(menu, editor, view))
|
|
);
|
|
menu.addItem((item) =>
|
|
item.setTitle("Generate frontmatter")
|
|
.setIcon("list-plus")
|
|
.onClick(async () => this.quickActionsDefinitionsService.generateFrontmatter(menu, editor, view))
|
|
);
|
|
menu.addSeparator();
|
|
menu.addItem((item) =>
|
|
item.setTitle("Quick actions")
|
|
.setIcon("circle-question-mark")
|
|
.onClick(() => {
|
|
const modal = Resolve<HelpModal>(Services.HelpModal);
|
|
modal.open(6);
|
|
})
|
|
);
|
|
menu.showAtMouseEvent(evt);
|
|
});
|
|
setIcon(button, this.assetsService.pluginIcon);
|
|
actionsEl.prepend(button);
|
|
}
|
|
}
|
|
|
|
private updateRegistrations() {
|
|
this.registerEditorMenuActions();
|
|
this.registerViewActions();
|
|
}
|
|
|
|
private unregisterEditorMenuActions() {
|
|
if (this.editorMenuEventRef) {
|
|
this.plugin.app.workspace.offref(this.editorMenuEventRef);
|
|
this.editorMenuEventRef = null;
|
|
}
|
|
}
|
|
|
|
private unregisterViewActions(){
|
|
if (this.layoutChangeEventRef) {
|
|
this.plugin.app.workspace.offref(this.layoutChangeEventRef);
|
|
this.layoutChangeEventRef = null;
|
|
// Remove any existing toolbar buttons
|
|
this.plugin.app.workspace.containerEl
|
|
.querySelectorAll(".vault-keeper-ai-actions")
|
|
.forEach(element => element.remove());
|
|
}
|
|
}
|
|
|
|
} |