generated from nhcarrigan/template
feat: add snippet library for prompt templates
- Add Rust backend with persistent storage for snippets - Include 8 default snippets across categories (Code Review, Debugging, Testing, etc.) - Create SnippetLibraryPanel component with category filtering - Support create/edit/delete operations for custom snippets - Default snippets can be edited but not deleted - Add snippet button to InputBar for quick access Closes #22
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
type SlashCommand,
|
||||
} from "$lib/commands/slashCommands";
|
||||
import AttachmentPreview from "$lib/components/AttachmentPreview.svelte";
|
||||
import SnippetLibraryPanel from "$lib/components/SnippetLibraryPanel.svelte";
|
||||
import type { Attachment } from "$lib/types/messages";
|
||||
|
||||
const INPUT_HISTORY_KEY = "hikari-input-history";
|
||||
@@ -39,6 +40,7 @@
|
||||
let selectedCommandIndex = $state(0);
|
||||
let attachments = $state<Attachment[]>([]);
|
||||
let isDragging = $state(false);
|
||||
let showSnippetLibrary = $state(false);
|
||||
|
||||
// Input history state
|
||||
let inputHistory = $state<string[]>([]);
|
||||
@@ -617,6 +619,16 @@ User: ${formattedMessage}`;
|
||||
}
|
||||
}
|
||||
|
||||
function handleSnippetInsert(content: string): void {
|
||||
// Insert snippet at cursor position or append to input
|
||||
if (inputValue.trim()) {
|
||||
inputValue = inputValue + "\n\n" + content;
|
||||
} else {
|
||||
inputValue = content;
|
||||
}
|
||||
userHasTyped = true;
|
||||
}
|
||||
|
||||
function handleKeyDown(event: KeyboardEvent) {
|
||||
// Handle command menu navigation
|
||||
if (showCommandMenu && matchingCommands.length > 0) {
|
||||
@@ -723,6 +735,29 @@ User: ${formattedMessage}`;
|
||||
</div>
|
||||
|
||||
<div class="button-wrapper">
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (showSnippetLibrary = true)}
|
||||
class="attach-button"
|
||||
title="Snippet Library"
|
||||
>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" />
|
||||
<polyline points="14,2 14,8 20,8" />
|
||||
<line x1="16" y1="13" x2="8" y2="13" />
|
||||
<line x1="16" y1="17" x2="8" y2="17" />
|
||||
<line x1="10" y1="9" x2="8" y2="9" />
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onclick={handleFilePicker} class="attach-button" title="Attach files">
|
||||
<svg
|
||||
width="20"
|
||||
@@ -769,6 +804,13 @@ User: ${formattedMessage}`;
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{#if showSnippetLibrary}
|
||||
<SnippetLibraryPanel
|
||||
onClose={() => (showSnippetLibrary = false)}
|
||||
onInsert={handleSnippetInsert}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.input-bar {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user