2025-11-07 00:28:22 +00:00
< script lang = "ts" >
2025-11-08 13:31:53 +00:00
import { Copy } from "Enums/Copy";
2025-11-09 19:59:41 +00:00
import { Selector } from "Enums/Selector";
2025-11-08 13:31:53 +00:00
import type AIAgentPlugin from "main";
2025-11-08 17:15:55 +00:00
import { DropdownComponent , setIcon } from "obsidian";
2025-11-08 13:31:53 +00:00
import { Resolve } from "Services/DependencyService";
import { Services } from "Services/Services";
import type { StreamingMarkdownService } from "Services/StreamingMarkdownService";
2025-11-09 19:59:41 +00:00
import type { WorkSpaceService } from "Services/WorkSpaceService";
2025-11-08 13:31:53 +00:00
import { fade } from "svelte/transition";
2025-11-08 17:15:55 +00:00
import { onMount } from "svelte";
2025-11-08 13:31:53 +00:00
export let onClose: () => void;
2025-11-09 19:59:41 +00:00
export let initialTopic: number = 1;
2025-11-08 13:31:53 +00:00
const plugin: AIAgentPlugin = Resolve< AIAgentPlugin > (Services.AIAgentPlugin);
const streamingMarkdownService: StreamingMarkdownService = Resolve< StreamingMarkdownService > (Services.StreamingMarkdownService);
2025-11-09 19:59:41 +00:00
const workSpaceService: WorkSpaceService = Resolve< WorkSpaceService > (Services.WorkSpaceService);
2025-11-08 13:31:53 +00:00
let closeButton: HTMLButtonElement;
2025-11-08 17:15:55 +00:00
let dropdownContainer: HTMLDivElement;
2025-11-09 19:59:41 +00:00
let contentContainer: HTMLDivElement;
2025-11-08 13:31:53 +00:00
const topics: Record< number , { title : string ; content : string } > = {
1: {
title: Copy.HelpModalAboutTitle,
content: Copy.HelpModalAboutContent
},
2: {
title: Copy.HelpModalGuideTitle,
content: Copy.HelpModalGuideContent
},
3: {
title: Copy.HelpModalTroubleshootTitle,
content: Copy.HelpModalTroubleshootContent
},
4: {
title: Copy.HelpModalPrivacyTitle,
content: Copy.HelpModalPrivacyContent
}
};
2025-11-09 19:59:41 +00:00
let selectedTopic: number = initialTopic;
2025-11-08 13:31:53 +00:00
let title: string = topics[selectedTopic].title;
let content: string = streamingMarkdownService.formatText(topics[selectedTopic].content);
function selectTopic(topicNumber: number) {
title = "";
content = "";
selectedTopic = topicNumber;
setTimeout(() => {
title = topics[selectedTopic].title;
content = streamingMarkdownService.formatText(topics[selectedTopic].content);
}, 200);
}
$: if (closeButton) {
setIcon(closeButton, 'circle-x');
}
2025-11-08 17:15:55 +00:00
2025-11-09 19:59:41 +00:00
async function handleLinkClick(evt: MouseEvent) {
const target = evt.target as HTMLElement;
// Check for both internal wikilinks and regular markdown links
const link = target.closest('a') as HTMLAnchorElement | null;
if (!link) {
return;
}
const href = link.getAttribute('href');
if (!href || !href.startsWith('#/page/')) {
return;
}
evt.preventDefault();
evt.stopPropagation();
const encodedPath = href.replace('#/page/', '');
const notePath = decodeURIComponent(encodedPath);
await workSpaceService.openNote(notePath);
onClose();
}
2025-11-08 17:15:55 +00:00
onMount(() => {
if (dropdownContainer) {
const dropdown = new DropdownComponent(dropdownContainer);
// Add all topic options
Object.entries(topics).forEach(([key, topic]) => {
dropdown.addOption(key, topic.title);
});
// Set initial value
dropdown.setValue(selectedTopic.toString());
// Handle changes
dropdown.onChange((value) => {
selectTopic(Number(value));
});
}
2025-11-09 19:59:41 +00:00
if (contentContainer) {
plugin.registerDomEvent(contentContainer, 'click', handleLinkClick);
}
2025-11-08 17:15:55 +00:00
});
2025-11-07 00:28:22 +00:00
< / script >
2025-11-08 13:31:53 +00:00
< div class = "help-modal-container" >
< div class = "help-modal-top-bar" >
< div class = "help-modal-top-bar-content" >
{ #if title !== "" }
< div id = "help-modal-title" transition:fade = {{ duration : 100 }} >
{ title }
< / div >
{ /if }
< button
bind:this={ closeButton }
id="close-button"
class="top-bar-button clickable-icon"
on:click={ onClose }
aria-label="Close Conversation History"
>< / button >
< / div >
< / div >
< div class = "help-modal-body" >
2025-11-08 17:15:55 +00:00
< div class = "help-modal-dropdown" bind:this = { dropdownContainer } > </div >
< div id = "help-modal-version-string-mobile" >
Plugin version: { plugin . manifest . version }
< / div >
2025-11-08 13:31:53 +00:00
< div class = "help-modal-topics" >
< div
class="help-modal-topic-frame"
class:hidden={ selectedTopic !== 1 }
on:click={() => selectTopic ( 1 )}
on:keydown={( e ) => e . key === 'Enter' && selectTopic ( 1 )}
role="button"
tabindex="0">
2025-11-08 13:41:29 +00:00
< div class = "help-modal-topic-item" >
2025-11-08 13:31:53 +00:00
{ topics [ 1 ]. title }
< / div >
< / div >
< div
class="help-modal-topic-frame"
class:hidden={ selectedTopic !== 2 }
on:click={() => selectTopic ( 2 )}
on:keydown={( e ) => e . key === 'Enter' && selectTopic ( 2 )}
role="button"
tabindex="0">
2025-11-08 13:41:29 +00:00
< div class = "help-modal-topic-item" >
2025-11-08 13:31:53 +00:00
{ topics [ 2 ]. title }
< / div >
< / div >
< div
class="help-modal-topic-frame"
class:hidden={ selectedTopic !== 3 }
on:click={() => selectTopic ( 3 )}
on:keydown={( e ) => e . key === 'Enter' && selectTopic ( 3 )}
role="button"
tabindex="0">
2025-11-08 13:41:29 +00:00
< div class = "help-modal-topic-item" >
2025-11-08 13:31:53 +00:00
{ topics [ 3 ]. title }
< / div >
< / div >
< div
class="help-modal-topic-frame"
class:hidden={ selectedTopic !== 4 }
on:click={() => selectTopic ( 4 )}
on:keydown={( e ) => e . key === 'Enter' && selectTopic ( 4 )}
role="button"
tabindex="0">
2025-11-08 13:41:29 +00:00
< div class = "help-modal-topic-item" >
2025-11-08 13:31:53 +00:00
{ topics [ 4 ]. title }
< / div >
< / div >
< div id = "help-modal-version-string" >
Plugin version: { plugin . manifest . version }
< / div >
< / div >
2025-11-09 19:59:41 +00:00
< div class = "help-modal-content" bind:this = { contentContainer } >
2025-11-08 13:31:53 +00:00
{ #if content !== "" }
< div transition:fade = {{ duration : 100 }} >
{ @html content }
2025-11-09 13:57:47 +00:00
{ #if selectedTopic === 1 }
2025-11-09 19:59:41 +00:00
< a
href="https://github.com/Andy-Stack/ai-agent-plugin"
style="text-decoration: none; display: inline-flex; align-items: center; gap: 0.5em; margin: 0 0 1em 0;">
< svg
width="1em"
height="1em"
viewBox="0 0 98 96"
xmlns="http://www.w3.org/2000/svg"
aria-label="GitHub"
style="display: inline-block; vertical-align: middle;">
< path fill-rule = "evenodd" clip-rule = "evenodd" d = { Copy . GitHubIconPath } fill="currentColor"/ >
< / svg >
< span > View on GitHub< / span >
< / a >
< br >
< span style = "display: inline-block; margin-bottom: 1em;" > If you enjoy using the plugin or find it useful and want to contribute, you can buy me a Coffee using the link below:< / span >
< br >
< a href = "a" style = "text-decoration: none; display: inline-flex; align-items: center; gap: 0.5em;" >
< span > ☕< / span >
< span > Buy me a coffee< / span >
< / a >
< p style = "margin-top: 2em; font-style: italic;" > Thanks for using the AI Agent plugin!< / p >
2025-11-09 13:57:47 +00:00
{ /if }
2025-11-08 13:31:53 +00:00
< / div >
{ /if }
< / div >
< / div >
2025-11-07 00:28:22 +00:00
< / div >
< style >
2025-11-08 13:31:53 +00:00
.help-modal-container {
display: grid;
grid-template-rows: auto var(--size-4-1) 1fr var(--size-4-2);
grid-template-columns: var(--size-4-2) 1fr var(--size-4-2);
max-height: 60vh;
min-height: 60vh;
}
.help-modal-top-bar {
grid-row: 1;
grid-column: 2;
height: var(--size-4-16);
display: grid;
grid-template-rows: var(--size-4-2) 1fr var(--size-4-2);
grid-template-columns: 1fr;
}
.help-modal-top-bar-content {
grid-row: 2;
grid-column: 1;
display: grid;
grid-template-rows: auto;
grid-template-columns: var(--size-4-2) 1fr auto var(--size-4-2);
background-color: var(--background-modifier-hover);
border-radius: var(--radius-m);
}
#help-modal-title {
grid-row: 1;
grid-column: 2 / 4;
display: inline-block;
text-align: center;
align-self: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
color: var(--text-muted);
}
#close-button {
grid-row: 1;
grid-column: 3;
z-index: 1;
}
.help-modal-body {
grid-row: 3;
grid-column: 2;
display: grid;
grid-template-rows: auto var(--size-4-3) auto var(--size-4-3) auto var(--size-4-3) auto 1fr;
grid-template-columns: auto var(--size-4-2) 1fr;
height: 100%;
width: 100%;
overflow: auto;
}
2025-11-08 17:15:55 +00:00
.help-modal-dropdown {
display: none;
}
#help-modal-version-string-mobile {
display: none;
}
2025-11-08 13:31:53 +00:00
.help-modal-topic-frame {
grid-column: 1 / 4;
display: grid;
grid-template-rows: auto;
grid-template-columns: auto var(--size-4-2) 1fr;
width: 150%;
padding: var(--size-4-2) var(--size-4-1);
border-radius: var(--radius-m);
cursor: pointer;
background-color: var(--alt-background-primary);
transition: background-color 0.25s ease-in-out;
}
.help-modal-topic-frame.hidden {
background-color: transparent;
}
2025-11-08 13:41:29 +00:00
.help-modal-topic-frame:nth-child(1) {
2025-11-08 13:31:53 +00:00
grid-row: 1;
}
2025-11-08 13:41:29 +00:00
.help-modal-topic-frame:nth-child(2) {
2025-11-08 13:31:53 +00:00
grid-row: 3;
}
2025-11-08 13:41:29 +00:00
.help-modal-topic-frame:nth-child(3) {
2025-11-08 13:31:53 +00:00
grid-row: 5;
}
2025-11-08 13:41:29 +00:00
.help-modal-topic-frame:nth-child(4) {
2025-11-08 13:31:53 +00:00
grid-row: 7;
}
.help-modal-topics {
grid-row: 1 / 9;
grid-column: 1;
display: grid;
2025-11-08 13:48:39 +00:00
max-width: 150px;
2025-11-08 13:31:53 +00:00
grid-template-rows: auto var(--size-4-3) auto var(--size-4-3) auto var(--size-4-3) auto 1fr;
grid-template-columns: auto var(--size-4-2) 1fr;
}
.help-modal-topic-item {
grid-column: 1;
2025-11-08 13:48:39 +00:00
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
2025-11-08 13:31:53 +00:00
padding: var(--size-4-1) var(--size-4-3);
cursor: pointer;
transition: color 0.15s ease-in-out;
}
.help-modal-topic-item:hover {
color: var(--text-normal);
}
2025-11-08 13:41:29 +00:00
.help-modal-topic-item:nth-child(1) {
2025-11-08 13:31:53 +00:00
grid-row: 1;
}
2025-11-08 13:41:29 +00:00
.help-modal-topic-item:nth-child(2) {
2025-11-08 13:31:53 +00:00
grid-row: 3;
}
2025-11-08 13:41:29 +00:00
.help-modal-topic-item:nth-child(3) {
2025-11-08 13:31:53 +00:00
grid-row: 5;
}
2025-11-08 13:41:29 +00:00
.help-modal-topic-item:nth-child(4) {
2025-11-08 13:31:53 +00:00
grid-row: 7;
}
#help-modal-version-string {
grid-row: 8;
grid-column: 1;
align-self: flex-end;
padding: var(--size-4-1) var(--size-4-3);
font-size: var(--font-smallest);
}
2025-11-07 00:28:22 +00:00
2025-11-08 13:31:53 +00:00
.help-modal-content {
grid-row: 1 / 9;
grid-column: 3;
height: 100%;
border-radius: var(--radius-m);
background-color: var(--alt-background-primary);
2025-11-09 19:59:41 +00:00
padding: 0 var(--size-4-2) var(--size-4-2) var(--size-4-3);
2025-11-08 13:31:53 +00:00
overflow-y: auto;
}
2025-11-08 17:15:55 +00:00
/* Mobile styles */
:global(.is-mobile) .help-modal-body {
grid-template-rows: auto var(--size-4-2) 1fr var(--size-4-2) auto;
grid-template-columns: 1fr;
}
:global(.is-mobile) .help-modal-dropdown {
display: block;
grid-row: 1;
grid-column: 1;
width: 100%;
}
.help-modal-dropdown :global(.dropdown) {
width: 100%;
border: solid;
border-width: 1px;
border-color: var(--color-accent) !important;
outline: none;
}
:global(.is-mobile) #help-modal-version-string-mobile {
display: block;
grid-row: 5;
grid-column: 1;
align-self: flex-end;
padding: var(--size-4-1) var(--size-4-2);
font-size: var(--font-smallest);
color: var(--text-muted);
}
:global(.is-mobile) .help-modal-topics {
display: none;
}
:global(.is-mobile) .help-modal-content {
grid-row: 3;
grid-column: 1;
padding: var(--size-4-2);
}
2025-11-08 13:31:53 +00:00
< / style >