diff --git a/src/lib/ae_journals/ae_journals_editor_helpers.ts b/src/lib/ae_journals/ae_journals_editor_helpers.ts new file mode 100644 index 00000000..1766af26 --- /dev/null +++ b/src/lib/ae_journals/ae_journals_editor_helpers.ts @@ -0,0 +1,60 @@ +import type { EditorView } from '@codemirror/view'; + +/** + * Wraps the current selection in CodeMirror with the given prefix and suffix. + */ +export function wrapSelection(view: EditorView, prefix: string, suffix: string = prefix) { + if (!view) return; + const { state, dispatch } = view; + const changes = state.changeByRange((range) => { + const selectedText = state.doc.sliceString(range.from, range.to); + return { + changes: [ + { from: range.from, insert: prefix }, + { from: range.to, insert: suffix } + ], + range: { + from: range.from + prefix.length, + to: range.to + prefix.length + } + }; + }); + dispatch(state.update(changes, { scrollIntoView: true, userEvent: 'input' })); + view.focus(); +} + +/** + * Inserts a prefix at the start of each line in the selection (e.g., for lists or blockquotes). + */ +export function toggleLinePrefix(view: EditorView, prefix: string) { + if (!view) return; + const { state, dispatch } = view; + const changes = state.changeByRange((range) => { + const lines = []; + for (let pos = range.from; pos <= range.to; ) { + const line = state.doc.lineAt(pos); + lines.push(line); + pos = line.to + 1; + } + + const isAlreadyPrefixed = lines.every(l => l.text.startsWith(prefix)); + + const lineChanges = lines.map(l => { + if (isAlreadyPrefixed) { + return { from: l.from, to: l.from + prefix.length, insert: '' }; + } else { + return { from: l.from, insert: prefix }; + } + }); + + return { + changes: lineChanges, + range: { + from: range.from + (isAlreadyPrefixed ? -prefix.length : prefix.length), + to: range.to + (isAlreadyPrefixed ? -prefix.length * lines.length : prefix.length * lines.length) + } + }; + }); + dispatch(state.update(changes, { scrollIntoView: true, userEvent: 'input' })); + view.focus(); +} diff --git a/src/lib/app_components/e_app_codemirror_v5.svelte b/src/lib/app_components/e_app_codemirror_v5.svelte index 0589a724..0582b42c 100644 --- a/src/lib/app_components/e_app_codemirror_v5.svelte +++ b/src/lib/app_components/e_app_codemirror_v5.svelte @@ -29,6 +29,7 @@ let { content = 'test test test test', new_content = $bindable(''), + editorView = $bindable(), // Exposed for external control theme_mode = 'light', extensions = [], editable = true, diff --git a/src/routes/journals/+layout.svelte b/src/routes/journals/+layout.svelte index ac19ee23..9b905942 100644 --- a/src/routes/journals/+layout.svelte +++ b/src/routes/journals/+layout.svelte @@ -7,7 +7,7 @@ import { goto } from '$app/navigation'; // *** Import other supporting libraries - import { House, RefreshCw, Satellite } from '@lucide/svelte'; + import { ArrowDownUp, House, RefreshCw, Satellite } from '@lucide/svelte'; // *** Import Aether specific variables and functions import { ae_loc, ae_sess, ae_api, slct } from '$lib/stores/ae_stores'; @@ -271,10 +271,6 @@ `Scroll to top button clicked. yScroll: ${yScroll} scrollTop: ${scroll_container().scrollTop}`, scroll_container() ); - // document.getElementById('ae_idaa')?.scrollTo(0, 0); - // document.documentElement?.scrollTo(0, 0); - // document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera - // document.body.scrollTop = 0; // For Safari } }); @@ -284,11 +280,11 @@ behavior: 'smooth' }); - window.parent.postMessage({ scroll_to: 0 }, '*'); // This should be + window.parent.postMessage({ scroll_to: 0 }, '*'); }} title="Scroll to top" > - + Scroll to Top @@ -345,10 +341,6 @@ `Scroll to bottom button clicked. yScroll: ${yScroll} scrollTop: ${scroll_container().scrollTop}`, scroll_container() ); - // document.getElementById('ae_idaa')?.scrollTo(0, 0); - // document.documentElement?.scrollTo(0, 0); - // document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera - // document.body.scrollTop = 0; // For Safari } }); @@ -358,13 +350,12 @@ behavior: 'smooth' }); - window.parent.postMessage({ scroll_to: yScroll }, '*'); // This should be + window.parent.postMessage({ scroll_to: yScroll }, '*'); }} title="Scroll to bottom" > - + Scroll to Bottom - diff --git a/src/routes/journals/+page.svelte b/src/routes/journals/+page.svelte index e0306c72..2823527f 100644 --- a/src/routes/journals/+page.svelte +++ b/src/routes/journals/+page.svelte @@ -8,7 +8,7 @@ import { goto } from '$app/navigation'; // *** Import other supporting libraries - import { BookPlus, FolderPlus, Library, SquareLibrary, Wrench } from '@lucide/svelte'; + import { BookPlus, FolderPlus, Library, Loader, SquareLibrary, Wrench } from '@lucide/svelte'; import { liveQuery } from 'dexie'; import { Modal } from 'flowbite-svelte'; @@ -243,7 +243,7 @@ {#await ae_acct.slct.journal_obj_li}
- + Loading journals...
{:then} diff --git a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte index c024c635..1288727b 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte @@ -9,6 +9,7 @@ ArrowDown01, ArrowDown10, ArrowDownUp, + Bold, BookHeart, Bot, BotMessageSquare, @@ -31,6 +32,10 @@ Group, Hash, History, + Italic, + Link, + List, + ListOrdered, Loader, LockKeyhole, LockKeyholeOpen, @@ -43,6 +48,7 @@ Pencil, PenLine, Plus, + Quote, RemoveFormatting, Save, Search, @@ -54,6 +60,7 @@ Siren, Skull, SquareLibrary, + Strikethrough, Tags, Trash2, TypeOutline, @@ -64,6 +71,8 @@ import OpenAI from 'openai'; // import { Configuration, OpenAIApi } from 'openai'; + import { wrapSelection, toggleLinePrefix } from '$lib/ae_journals/ae_journals_editor_helpers'; + let llm_api_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVhYjI2MzdlLThiMjktNGM2Zi05MzVhLWFkYjU1MDkwMGU5MCJ9.4y5AStXZJAVnWRlgG3lVV0-xKIfMzqdNRuInGwT0ThQ'; @@ -128,6 +137,8 @@ lq__journal_entry_obj }: Props = $props(); + let editorView: any = $state(); + if (log_lvl) { console.log( `ae_comp__journal_entry_obj_id_view.svelte`, @@ -2651,19 +2662,56 @@ tabindex={$ae_loc.edit_mode ? 0 : -1} --> {#if $lq__journal_obj?.cfg_json?.pref_editor == 'codemirror'} - + +
+ + + + + + + + + + + + + + +
+

- {@html journals_journal_obj.name} + {journals_journal_obj.name}