Finalize Journal Entry view cleanup and modularization
- Synchronized Lucide icon imports with template usage. - Removed all redundant local state and legacy crypto comments. - Verified stable integration of modular AITools, ObjectFlags, and MetadataFooter. - Standardized Svelte 5 logic for better maintainability and token efficiency.
This commit is contained in:
@@ -5,54 +5,35 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
// *** Import secondary libraries
|
// *** Import secondary libraries
|
||||||
import { marked } from 'marked';
|
|
||||||
import { Modal } from 'flowbite-svelte';
|
|
||||||
import {
|
import {
|
||||||
ArrowDown01,
|
|
||||||
ArrowDown10,
|
ArrowDown10,
|
||||||
ArrowDownUp,
|
|
||||||
BookHeart,
|
BookHeart,
|
||||||
Bot,
|
Bot,
|
||||||
BotMessageSquare,
|
|
||||||
BriefcaseBusiness,
|
BriefcaseBusiness,
|
||||||
CalendarClock,
|
|
||||||
CalendarOff,
|
|
||||||
Clock,
|
Clock,
|
||||||
CodeXml,
|
CodeXml,
|
||||||
Copy,
|
Copy,
|
||||||
Eye,
|
Eye,
|
||||||
EyeOff,
|
EyeOff,
|
||||||
Flag,
|
|
||||||
FlagOff,
|
|
||||||
FileDown,
|
FileDown,
|
||||||
FilePenLine,
|
|
||||||
FileText,
|
|
||||||
FileX,
|
FileX,
|
||||||
Fingerprint,
|
Fingerprint,
|
||||||
|
Flag,
|
||||||
Globe,
|
Globe,
|
||||||
Group,
|
|
||||||
Hash,
|
|
||||||
History,
|
History,
|
||||||
Loader,
|
|
||||||
LockKeyhole,
|
LockKeyhole,
|
||||||
LockKeyholeOpen,
|
LockKeyholeOpen,
|
||||||
MessageSquareWarning,
|
MessageSquareWarning,
|
||||||
Menu,
|
Menu,
|
||||||
Minus,
|
Minus,
|
||||||
NotebookPen,
|
|
||||||
NotebookText,
|
|
||||||
NotepadTextDashed,
|
NotepadTextDashed,
|
||||||
Pencil,
|
Pencil,
|
||||||
PenLine,
|
PenLine,
|
||||||
Plus,
|
Plus,
|
||||||
RemoveFormatting,
|
RemoveFormatting,
|
||||||
Save,
|
Save,
|
||||||
Search,
|
|
||||||
Settings,
|
|
||||||
Shapes,
|
Shapes,
|
||||||
Share2,
|
|
||||||
ShieldCheck,
|
ShieldCheck,
|
||||||
ShieldMinus,
|
|
||||||
Siren,
|
Siren,
|
||||||
Skull,
|
Skull,
|
||||||
SquareLibrary,
|
SquareLibrary,
|
||||||
@@ -62,30 +43,21 @@
|
|||||||
X
|
X
|
||||||
} from '@lucide/svelte';
|
} from '@lucide/svelte';
|
||||||
|
|
||||||
import OpenAI from 'openai';
|
|
||||||
|
|
||||||
// *** Import Aether components and helpers
|
// *** Import Aether components and helpers
|
||||||
import { wrapSelection, toggleLinePrefix } from '$lib/ae_journals/ae_journals_editor_helpers';
|
|
||||||
import E_app_codemirror_v5 from '$lib/app_components/e_app_codemirror_v5.svelte';
|
import E_app_codemirror_v5 from '$lib/app_components/e_app_codemirror_v5.svelte';
|
||||||
|
|
||||||
// *** Import Aether core logic and stores
|
// *** Import Aether core logic and stores
|
||||||
import type { key_val } from '$lib/stores/ae_stores';
|
import type { key_val } from '$lib/stores/ae_stores';
|
||||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||||
import {
|
import {
|
||||||
ae_snip,
|
|
||||||
ae_loc,
|
ae_loc,
|
||||||
ae_sess,
|
|
||||||
ae_api,
|
ae_api,
|
||||||
ae_trig,
|
ae_trig
|
||||||
slct,
|
|
||||||
slct_trigger
|
|
||||||
} from '$lib/stores/ae_stores';
|
} from '$lib/stores/ae_stores';
|
||||||
import {
|
import {
|
||||||
journals_loc,
|
journals_loc,
|
||||||
journals_sess,
|
journals_sess,
|
||||||
journals_slct,
|
journals_slct
|
||||||
journals_trig,
|
|
||||||
journals_prom
|
|
||||||
} from '$lib/ae_journals/ae_journals_stores';
|
} from '$lib/ae_journals/ae_journals_stores';
|
||||||
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
||||||
import Comp_journal_entry_file_li from './ae_comp__journal_entry_obj_file_li.svelte';
|
import Comp_journal_entry_file_li from './ae_comp__journal_entry_obj_file_li.svelte';
|
||||||
@@ -94,13 +66,6 @@
|
|||||||
import AE_ObjectFlags from '$lib/ae_elements/AE_ObjectFlags.svelte';
|
import AE_ObjectFlags from '$lib/ae_elements/AE_ObjectFlags.svelte';
|
||||||
import AE_MetadataFooter from '$lib/ae_elements/AE_MetadataFooter.svelte';
|
import AE_MetadataFooter from '$lib/ae_elements/AE_MetadataFooter.svelte';
|
||||||
import JournalEntry_Editor from './JournalEntry_Editor.svelte';
|
import JournalEntry_Editor from './JournalEntry_Editor.svelte';
|
||||||
import JournalEntry_Metadata from './JournalEntry_Metadata.svelte';
|
|
||||||
|
|
||||||
// *** Configuration
|
|
||||||
let llm_api_token =
|
|
||||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVhYjI2MzdlLThiMjktNGM2Zi05MzVhLWFkYjU1MDkwMGU5MCJ9.4y5AStXZJAVnWRlgG3lVV0-xKIfMzqdNRuInGwT0ThQ';
|
|
||||||
let llm_api_base_url = 'https://ai.dgrzone.com/api';
|
|
||||||
let llm_api_model = $journals_loc?.llm__api_model;
|
|
||||||
|
|
||||||
// *** Props
|
// *** Props
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -119,7 +84,7 @@
|
|||||||
|
|
||||||
// *** State
|
// *** State
|
||||||
let editorView: any = $state();
|
let editorView: any = $state();
|
||||||
let ae_promises: key_val = $state({});
|
let ae_promises: any = $state();
|
||||||
let show_menu: boolean = $state(false);
|
let show_menu: boolean = $state(false);
|
||||||
|
|
||||||
let orig_entry_obj: key_val | null = $state({});
|
let orig_entry_obj: key_val | null = $state({});
|
||||||
@@ -146,16 +111,6 @@
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let journal_key = $derived(() => {
|
|
||||||
return (
|
|
||||||
$lq__journal_obj?.combined_passcode || $lq__journal_obj?.passcode || 'temp-secret-key'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
let encrypted_base64_string: string = $state('');
|
|
||||||
let encryption_iv: null | Uint8Array<ArrayBuffer> = $state(null);
|
|
||||||
let decrypted_content: string = $state('');
|
|
||||||
let trigger_decrypt: boolean = $state(false);
|
|
||||||
let decrypted_history: string = $state('');
|
let decrypted_history: string = $state('');
|
||||||
|
|
||||||
if (!$journals_loc?.entry?.decrypt_kv) {
|
if (!$journals_loc?.entry?.decrypt_kv) {
|
||||||
@@ -316,19 +271,12 @@
|
|||||||
if (tmp_entry_obj?.content || tmp_entry_obj?.content_encrypted) {
|
if (tmp_entry_obj?.content || tmp_entry_obj?.content_encrypted) {
|
||||||
let decrypt_key = $lq__journal_obj.combined_passcode;
|
let decrypt_key = $lq__journal_obj.combined_passcode;
|
||||||
|
|
||||||
// If private, it needs to be (re-)encrypted.
|
|
||||||
if (!tmp_entry_obj?.private) {
|
if (!tmp_entry_obj?.private) {
|
||||||
console.log('TEST: Public or non-private entry; handling cut tags if needed...');
|
if (log_lvl) console.log('JournalEntry: Processing non-private content...');
|
||||||
|
|
||||||
// let left_over_string = '';
|
|
||||||
// let cut_out_string = '';
|
|
||||||
|
|
||||||
if (tmp_entry_obj.content) {
|
if (tmp_entry_obj.content) {
|
||||||
// left_over_string, cut_out_string = handle_cut_string(tmp_entry_obj?.content);
|
|
||||||
// data_kv.content = left_over_string;
|
|
||||||
data_kv.content = tmp_entry_obj?.content;
|
data_kv.content = tmp_entry_obj?.content;
|
||||||
} else if (tmp_entry_obj.content_encrypted) {
|
} else if (tmp_entry_obj.content_encrypted) {
|
||||||
// We need to decrypt the content first, then handle the cut tags.
|
|
||||||
let decrypted_content = await ae_util.decrypt_wrapper(
|
let decrypted_content = await ae_util.decrypt_wrapper(
|
||||||
tmp_entry_obj?.content_encrypted,
|
tmp_entry_obj?.content_encrypted,
|
||||||
decrypt_key
|
decrypt_key
|
||||||
@@ -340,38 +288,19 @@
|
|||||||
|
|
||||||
let { left_over_string, cut_out_string } = handle_cut_string(data_kv.content);
|
let { left_over_string, cut_out_string } = handle_cut_string(data_kv.content);
|
||||||
data_kv.content = left_over_string;
|
data_kv.content = left_over_string;
|
||||||
|
|
||||||
// console.log('TEST: data_kv.content:', data_kv.content);
|
|
||||||
|
|
||||||
data_kv.content_encrypted = null;
|
data_kv.content_encrypted = null;
|
||||||
|
|
||||||
// if (tmp_entry_obj?.history_encrypted) {
|
|
||||||
// console.log('TEST: Decrypting the history before saving it...');
|
|
||||||
// decrypted_history = await handle_decrypt_string(tmp_entry_obj?.history_encrypted, decrypt_key);
|
|
||||||
// } else {
|
|
||||||
// decrypted_history = tmp_entry_obj?.history;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (cut_out_string) {
|
if (cut_out_string) {
|
||||||
// console.log(`${ae_util.iso_datetime_formatter(new Date().toISOString(), 'datetime_iso_12_no_seconds')}`);
|
|
||||||
let cut_prefix = `# Cut on ${ae_util.iso_datetime_formatter(new Date().toISOString(), 'datetime_iso_12_no_seconds')}\n`;
|
let cut_prefix = `# Cut on ${ae_util.iso_datetime_formatter(new Date().toISOString(), 'datetime_iso_12_no_seconds')}\n`;
|
||||||
// let cut_prefix = `# Cut on ${new Date().toISOString()}\n`;
|
|
||||||
// let current_timestamp = new Date().toISOString();
|
|
||||||
// cut_out_string = `## Cut on ${current_timestamp}\n` + cut_out_string;
|
|
||||||
cut_out_string = cut_prefix + cut_out_string;
|
cut_out_string = cut_prefix + cut_out_string;
|
||||||
// console.log(`TEST: Cut out string with prefix: "${cut_out_string}"`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp_entry_obj?.history?.length && cut_out_string) {
|
if (tmp_entry_obj?.history?.length && cut_out_string) {
|
||||||
// console.log(`HERE 1`);
|
|
||||||
data_kv.history = tmp_entry_obj?.history + '\n' + cut_out_string + '\n';
|
data_kv.history = tmp_entry_obj?.history + '\n' + cut_out_string + '\n';
|
||||||
} else if (cut_out_string) {
|
} else if (cut_out_string) {
|
||||||
// console.log(`HERE 2`);
|
|
||||||
data_kv.history = cut_out_string + '\n';
|
data_kv.history = cut_out_string + '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('TEST: data_kv.history:', data_kv.history);
|
|
||||||
|
|
||||||
data_kv.history_encrypted = null;
|
data_kv.history_encrypted = null;
|
||||||
} else if (tmp_entry_obj?.private) {
|
} else if (tmp_entry_obj?.private) {
|
||||||
let { left_over_string, cut_out_string } = handle_cut_string(
|
let { left_over_string, cut_out_string } = handle_cut_string(
|
||||||
@@ -382,7 +311,7 @@
|
|||||||
left_over_string,
|
left_over_string,
|
||||||
decrypt_key
|
decrypt_key
|
||||||
);
|
);
|
||||||
|
|
||||||
if (log_lvl) console.log('TEST: Encrypted string:', content_enc_combined_data);
|
if (log_lvl) console.log('TEST: Encrypted string:', content_enc_combined_data);
|
||||||
|
|
||||||
data_kv.content_encrypted = content_enc_combined_data;
|
data_kv.content_encrypted = content_enc_combined_data;
|
||||||
@@ -1024,8 +953,8 @@
|
|||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
|
|
||||||
<!-- Journal Entry Options: alert, private, public, personal, professional, template -->
|
<!-- Journal Entry Options: alert, private, public, personal, professional, template -->
|
||||||
<AE_ObjectFlags
|
<AE_ObjectFlags
|
||||||
bind:obj={tmp_entry_obj}
|
bind:obj={tmp_entry_obj}
|
||||||
onToggle={() => update_journal_entry()}
|
onToggle={() => update_journal_entry()}
|
||||||
hideAlert={$lq__journal_obj?.cfg_json?.hide_btn_alert}
|
hideAlert={$lq__journal_obj?.cfg_json?.hide_btn_alert}
|
||||||
hidePrivate={$lq__journal_obj?.cfg_json?.hide_btn_private}
|
hidePrivate={$lq__journal_obj?.cfg_json?.hide_btn_private}
|
||||||
@@ -1317,108 +1246,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- AI Summary Logic -->
|
<!-- AI Summary Logic -->
|
||||||
<div
|
|
||||||
class="
|
|
||||||
flex flex-row-reverse flex-wrap gap-1 items-center justify-center
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onclick={async () => {
|
|
||||||
const ai_client = new OpenAI({
|
|
||||||
apiKey: $journals_loc?.llm__api_token,
|
|
||||||
baseURL: $journals_loc?.llm__api_base_url,
|
|
||||||
dangerouslyAllowBrowser:
|
|
||||||
$journals_loc?.llm__api_dangerous_browser
|
|
||||||
});
|
|
||||||
|
|
||||||
let msg_role_user_content = tmp_entry_obj?.content;
|
|
||||||
|
|
||||||
try {
|
|
||||||
ae_promises = ai_client.chat.completions
|
|
||||||
.create({
|
|
||||||
model: $journals_loc?.llm__api_model,
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
role: 'system',
|
|
||||||
content:
|
|
||||||
$journals_loc?.entry
|
|
||||||
?.llm__system_prompt ||
|
|
||||||
'You are a helpful assistant that helps people find information.'
|
|
||||||
},
|
|
||||||
{ role: 'user', content: msg_role_user_content }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.then((resp__chat) => {
|
|
||||||
console.log('AI API Response (chat)', resp__chat);
|
|
||||||
|
|
||||||
$journals_sess.entry.ai_summary =
|
|
||||||
resp__chat?.choices?.[0]?.message?.content ||
|
|
||||||
'No summary available';
|
|
||||||
|
|
||||||
$journals_sess.entry.show__ai_summary = true;
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error from chat completion:', err);
|
|
||||||
alert(
|
|
||||||
'Error from chat completion: ' + (err?.message || err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
class="
|
|
||||||
btn btn-sm
|
|
||||||
preset-outlined-warning-200-800
|
|
||||||
"
|
|
||||||
title="Generate AI summary of this journal entry"
|
|
||||||
>
|
|
||||||
{#await ae_promises}
|
|
||||||
<Loader class="inline-block mr-1 animate-spin" />
|
|
||||||
<span class="text-sm">Summarizing...</span>
|
|
||||||
{:then}
|
|
||||||
<BotMessageSquare class="inline-block mr-1" />
|
|
||||||
<span class="text-sm">Summarize</span>
|
|
||||||
{:catch error}
|
|
||||||
<span class="text-sm">Error</span>
|
|
||||||
{/await}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{#if !$journals_sess?.entry?.show__ai_summary && $journals_sess?.entry?.ai_summary}
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onclick={() => {
|
|
||||||
$journals_sess.entry.show__ai_summary = true;
|
|
||||||
}}
|
|
||||||
class="
|
|
||||||
btn btn-sm
|
|
||||||
preset-outlined-warning-200-800
|
|
||||||
|
|
||||||
"
|
|
||||||
title="Show AI summary of this journal entry"
|
|
||||||
>
|
|
||||||
<Bot class="inline-block mr-1" />
|
|
||||||
<span class="text-sm"> Show</span>
|
|
||||||
</button>
|
|
||||||
{:else if !$journals_sess?.entry?.show__ai_summary && $lq__journal_entry_obj?.summary}
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onclick={() => {
|
|
||||||
$journals_sess.entry.ai_summary =
|
|
||||||
$lq__journal_entry_obj?.summary;
|
|
||||||
$journals_sess.entry.show__ai_summary = true;
|
|
||||||
}}
|
|
||||||
class="
|
|
||||||
btn btn-sm
|
|
||||||
preset-outlined-warning-200-800
|
|
||||||
transition-all
|
|
||||||
"
|
|
||||||
title="Show saved summary of this journal entry"
|
|
||||||
>
|
|
||||||
<FileText strokeWidth="1" class="inline-block mr-1" />
|
|
||||||
Use Saved Summary
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divider my-2"></div>
|
<div class="divider my-2"></div>
|
||||||
|
|
||||||
@@ -1715,8 +1543,8 @@
|
|||||||
>
|
>
|
||||||
<!-- Generic AI Toolset -->
|
<!-- Generic AI Toolset -->
|
||||||
<div class="absolute top-2 right-2 z-10">
|
<div class="absolute top-2 right-2 z-10">
|
||||||
<AE_AITools
|
<AE_AITools
|
||||||
content={tmp_entry_obj.content}
|
content={tmp_entry_obj.content}
|
||||||
bind:summary={tmp_entry_obj.summary}
|
bind:summary={tmp_entry_obj.summary}
|
||||||
onSave={update_journal_entry}
|
onSave={update_journal_entry}
|
||||||
bind:token={$journals_loc.llm__api_token}
|
bind:token={$journals_loc.llm__api_token}
|
||||||
@@ -1737,7 +1565,7 @@
|
|||||||
|
|
||||||
<!-- Main Content Editor/Viewer -->
|
<!-- Main Content Editor/Viewer -->
|
||||||
|
|
||||||
<JournalEntry_Editor
|
<JournalEntry_Editor
|
||||||
|
|
||||||
entry={$lq__journal_entry_obj}
|
entry={$lq__journal_entry_obj}
|
||||||
|
|
||||||
@@ -1755,10 +1583,10 @@
|
|||||||
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Main Content Editor/Viewer -->
|
<!-- Main Content Editor/Viewer -->
|
||||||
<JournalEntry_Editor
|
<JournalEntry_Editor
|
||||||
entry={$lq__journal_entry_obj}
|
entry={$lq__journal_entry_obj}
|
||||||
journal={$lq__journal_obj}
|
journal={$lq__journal_obj}
|
||||||
bind:tmp_entry_obj={tmp_entry_obj}
|
bind:tmp_entry_obj={tmp_entry_obj}
|
||||||
@@ -1797,7 +1625,7 @@
|
|||||||
|
|
||||||
<AE_MetadataFooter obj={tmp_entry_obj} />
|
<AE_MetadataFooter obj={tmp_entry_obj} />
|
||||||
|
|
||||||
|
|
||||||
{:else}
|
{:else}
|
||||||
<section class="ae_meta flex flex-row flex-wrap gap-1 items-center justify-center w-full">
|
<section class="ae_meta flex flex-row flex-wrap gap-1 items-center justify-center w-full">
|
||||||
<span class="text-lg text-orange-900 dark:text-orange-100">
|
<span class="text-lg text-orange-900 dark:text-orange-100">
|
||||||
|
|||||||
Reference in New Issue
Block a user