mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
refactor: replace sparkles icon with custom plugin icon throughout app
- 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"
This commit is contained in:
parent
72bf43a8ea
commit
a77c5b3339
10 changed files with 79 additions and 5 deletions
12
Assets/vaultkeeper-mono.svg
Normal file
12
Assets/vaultkeeper-mono.svg
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Vaultkeeper AI ribbon icon. Uses currentColor so it adapts to Obsidian themes. -->
|
||||
<circle cx="50" cy="50" r="30" stroke="currentColor" stroke-width="7" fill="none"/>
|
||||
<g stroke="currentColor" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none">
|
||||
<!-- locking bolts -->
|
||||
<path d="M85 50 H92 M50 85 V92 M15 50 H8 M50 15 V8
|
||||
M74.75 74.75 L79.70 79.70 M25.25 74.75 L20.30 79.70
|
||||
M74.75 25.25 L79.70 20.30 M25.25 25.25 L20.30 20.30"/>
|
||||
<!-- central spark -->
|
||||
<path d="M50 33 L54.09 45.91 L67 50 L54.09 54.09 L50 67 L45.91 54.09 L33 50 L45.91 45.91 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 734 B |
BIN
Assets/vaultkeeper-social-1280x330.png
Normal file
BIN
Assets/vaultkeeper-social-1280x330.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 MiB |
|
|
@ -223,7 +223,7 @@ If you find any issues or have a feature request, please feel free to raise them
|
|||
|
||||
1. **Add an API key**: Go to Settings and add at least one API key (Claude, Gemini, OpenAI, or Mistral)
|
||||
2. **Select a model**: Choose your preferred AI model from the dropdown
|
||||
3. **Open the chat**: Click the sparkles icon in the sidebar to start chatting`,
|
||||
3. **Open the chat**: Click the plugin icon in the sidebar to start chatting`,
|
||||
|
||||
HelpModalChatModesTitle = "Chat modes",
|
||||
HelpModalChatModesContent = `#### Chat modes
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@
|
|||
import type { WorkSpaceService } from "Services/WorkSpaceService";
|
||||
import { fade } from "svelte/transition";
|
||||
import { onMount } from "svelte";
|
||||
import type { AssetsService } from "Services/AssetsService";
|
||||
|
||||
export let onClose: () => void;
|
||||
export let initialTopic: number = 1;
|
||||
|
||||
const plugin: VaultkeeperAIPlugin = Resolve<VaultkeeperAIPlugin>(Services.VaultkeeperAIPlugin);
|
||||
const assetsService: AssetsService = Resolve<AssetsService>(Services.AssetsService);
|
||||
const streamingMarkdownService: StreamingMarkdownService = Resolve<StreamingMarkdownService>(Services.StreamingMarkdownService);
|
||||
const workSpaceService: WorkSpaceService = Resolve<WorkSpaceService>(Services.WorkSpaceService);
|
||||
|
||||
|
|
@ -166,6 +168,9 @@
|
|||
</div>
|
||||
<div class="help-modal-content" bind:this={contentContainer}>
|
||||
{#if contentVisible}
|
||||
{#if selectedTopic === 1}
|
||||
<img class="help-modal-banner" src={assetsService.bannerSource} alt="Plugin Banner">
|
||||
{/if}
|
||||
<div transition:fade={{ duration: 100 }} use:helpContentAction={selectedTopic}></div>
|
||||
<div transition:fade={{ duration: 100 }}>
|
||||
{#if selectedTopic === 1}
|
||||
|
|
@ -190,7 +195,7 @@
|
|||
<span>{Copy.CoffeeIcon}</span>
|
||||
<span>{Copy.CoffeeLinkText}</span>
|
||||
</a>
|
||||
<p style="margin-top: 2em; font-style: italic;">{Copy.ThankYouMessage}</p>
|
||||
<p style="margin-top: 1em; font-style: italic;">{Copy.ThankYouMessage}</p>
|
||||
{/if}
|
||||
</div>
|
||||
{#if selectedTopic === 1}
|
||||
|
|
@ -323,6 +328,13 @@
|
|||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.help-modal-banner {
|
||||
margin-top: var(--size-2-2);
|
||||
margin-left: calc(var(--size-4-2) * -1);
|
||||
width: calc(100% + (var(--size-4-2) * 2) - var(--size-2-2));
|
||||
border-radius: var(--radius-s);
|
||||
}
|
||||
|
||||
.help-modal-version-string {
|
||||
/* Absorbs leftover vertical space so the version sits bottom-right on tall
|
||||
screens, but collapses and scrolls naturally when content overflows. */
|
||||
|
|
|
|||
33
Services/AssetsService.ts
Normal file
33
Services/AssetsService.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import type VaultkeeperAIPlugin from "main";
|
||||
import { Resolve } from "./DependencyService";
|
||||
import { Services } from "./Services";
|
||||
import { addIcon } from "obsidian";
|
||||
|
||||
export class AssetsService {
|
||||
|
||||
private readonly plugin: VaultkeeperAIPlugin;
|
||||
|
||||
public pluginIcon: string = "";
|
||||
public bannerSource: string = "";
|
||||
|
||||
public constructor() {
|
||||
this.plugin = Resolve<VaultkeeperAIPlugin>(Services.VaultkeeperAIPlugin);
|
||||
}
|
||||
|
||||
public async loadAssets(): Promise<void> {
|
||||
this.pluginIcon = this.addIcon(
|
||||
await this.plugin.app.vault.adapter.read(`${this.plugin.manifest.dir}/Assets/vaultkeeper-mono.svg`),
|
||||
"vaultkeeper-ai-icon"
|
||||
);
|
||||
|
||||
this.bannerSource = this.plugin.app.vault.adapter.getResourcePath(
|
||||
`${this.plugin.manifest.dir}/Assets/vaultkeeper-social-1280x330.png`
|
||||
);
|
||||
}
|
||||
|
||||
private addIcon(icon: string, name: string): string {
|
||||
addIcon(name, icon);
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,10 +6,12 @@ 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;
|
||||
|
|
@ -21,6 +23,7 @@ export class QuickActionsService {
|
|||
|
||||
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);
|
||||
|
|
@ -181,7 +184,7 @@ export class QuickActionsService {
|
|||
);
|
||||
menu.showAtMouseEvent(evt);
|
||||
});
|
||||
setIcon(button, "sparkles");
|
||||
setIcon(button, this.assetsService.pluginIcon);
|
||||
actionsEl.prepend(button);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { AIProvider, fromModel } from "Enums/ApiProvider";
|
||||
import { Environment } from "Enums/Environment";
|
||||
import type VaultkeeperAIPlugin from "main";
|
||||
import { AssetsService } from "./AssetsService";
|
||||
|
||||
// Services
|
||||
import { RegisterSingleton, RegisterTransient, Resolve } from "./DependencyService";
|
||||
|
|
@ -64,6 +65,7 @@ import { QuickActionsService } from "./QuickActions/QuickActionsService";
|
|||
export async function RegisterPlugin(plugin: VaultkeeperAIPlugin) {
|
||||
RegisterSingleton<VaultkeeperAIPlugin>(Services.VaultkeeperAIPlugin, plugin);
|
||||
RegisterSingleton<SettingsService>(Services.SettingsService, new SettingsService(await plugin.loadData() as Partial<IVaultkeeperAISettings>));
|
||||
RegisterSingleton<AssetsService>(Services.AssetsService, new AssetsService());
|
||||
}
|
||||
|
||||
export function RegisterDependencies() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
export class Services {
|
||||
static VaultkeeperAIPlugin = Symbol("VaultkeeperAIPlugin");
|
||||
static SettingsService = Symbol("SettingsService");
|
||||
static AssetsService = Symbol("AssetsService");
|
||||
static EventService = Symbol("EventService");
|
||||
static AbortService = Symbol("AbortService");
|
||||
static HTMLService = Symbol("HTMLService");
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ import { ItemView, WorkspaceLeaf } from 'obsidian';
|
|||
import { mount, unmount } from 'svelte';
|
||||
import ChatWindow from 'Components/ChatWindow.svelte';
|
||||
import TopBar from 'Components/TopBar.svelte';
|
||||
import { AssetsService } from 'Services/AssetsService';
|
||||
import { Resolve } from 'Services/DependencyService';
|
||||
import { Services } from 'Services/Services';
|
||||
|
||||
export const VIEW_TYPE_MAIN = 'vaultkeeper-ai-main-view';
|
||||
|
||||
|
|
@ -12,8 +15,11 @@ interface ChatWindowComponent {
|
|||
|
||||
export class MainView extends ItemView {
|
||||
|
||||
private readonly assetsService: AssetsService;
|
||||
|
||||
constructor(leaf: WorkspaceLeaf) {
|
||||
super(leaf);
|
||||
this.assetsService = Resolve<AssetsService>(Services.AssetsService);
|
||||
}
|
||||
|
||||
topBar: ReturnType<typeof TopBar> | undefined;
|
||||
|
|
@ -28,7 +34,7 @@ export class MainView extends ItemView {
|
|||
}
|
||||
|
||||
public getIcon(): string {
|
||||
return 'sparkles';
|
||||
return this.assetsService.pluginIcon;
|
||||
}
|
||||
|
||||
protected override onOpen(): Promise<void> {
|
||||
|
|
|
|||
7
main.ts
7
main.ts
|
|
@ -14,11 +14,16 @@ import type { Diff2HtmlUIConfig } from "diff2html/lib/ui/js/diff2html-ui";
|
|||
import "katex/dist/katex.min.css";
|
||||
import 'highlight.js/styles/monokai.min.css';
|
||||
import 'diff2html/bundles/css/diff2html.min.css';
|
||||
import type { AssetsService } from "Services/AssetsService";
|
||||
|
||||
export default class VaultkeeperAIPlugin extends Plugin {
|
||||
|
||||
public async onload() {
|
||||
await RegisterPlugin(this);
|
||||
|
||||
const assetsService = Resolve<AssetsService>(Services.AssetsService);
|
||||
|
||||
await assetsService.loadAssets();
|
||||
RegisterDependencies();
|
||||
|
||||
this.registerView(
|
||||
|
|
@ -38,7 +43,7 @@ export default class VaultkeeperAIPlugin extends Plugin {
|
|||
}
|
||||
});
|
||||
|
||||
this.addRibbonIcon("sparkles", "Vaultkeeper AI", async () => {
|
||||
this.addRibbonIcon(assetsService.pluginIcon, "Vaultkeeper AI", async () => {
|
||||
await this.activateMainView();
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue