Now with actual encryption!
This commit is contained in:
@@ -342,10 +342,20 @@ export async function db_save_ae_obj_li__journal_entry(
|
|||||||
|
|
||||||
let content = obj.content ?? '';
|
let content = obj.content ?? '';
|
||||||
// remove the most common zerowidth characters from the start of the file
|
// remove the most common zerowidth characters from the start of the file
|
||||||
let content_cleaned: string = content.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/,"");
|
let content_cleaned: null|string = null;
|
||||||
let content_md_html: null|string = await marked.parse(content_cleaned ?? '') ?? null;
|
let content_md_html: null|string = null; // await marked.parse(content_cleaned ?? '') ?? null;
|
||||||
// let content_md_html_alt: null|string = await marked.parse(content_cleaned ?? '', { gfm: false }) ?? null;
|
// let content_md_html_alt: null|string = await marked.parse(content_cleaned ?? '', { gfm: false }) ?? null;
|
||||||
|
|
||||||
|
if (obj.content_encrypted) {
|
||||||
|
// In theory "content" should be null if "content_encrypted" has a value.
|
||||||
|
content = null; // obj.content_encrypted;
|
||||||
|
content_cleaned = null;
|
||||||
|
content_md_html = null;
|
||||||
|
} else {
|
||||||
|
content_cleaned = content.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/,"");
|
||||||
|
content_md_html = await marked.parse(content_cleaned ?? '') ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
let obj_record = {
|
let obj_record = {
|
||||||
id: obj.journal_entry_id_random,
|
id: obj.journal_entry_id_random,
|
||||||
journal_entry_id: obj.journal_entry_id_random,
|
journal_entry_id: obj.journal_entry_id_random,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
Globe, Group,
|
Globe, Group,
|
||||||
MessageSquareWarning, Minus,
|
MessageSquareWarning, Minus,
|
||||||
NotebookPen, NotebookText, NotepadTextDashed,
|
NotebookPen, NotebookText, NotepadTextDashed,
|
||||||
Pencil, Plus,
|
Pencil, PenLine, Plus,
|
||||||
RemoveFormatting,
|
RemoveFormatting,
|
||||||
Search,
|
Search,
|
||||||
Shapes, Share2, ShieldCheck, ShieldMinus, Siren, Skull,
|
Shapes, Share2, ShieldCheck, ShieldMinus, Siren, Skull,
|
||||||
@@ -127,7 +127,9 @@ $effect(() => {
|
|||||||
console.log('TEST: tmp_entry_obj and orig_entry_obj available; marking tmp_entry_obj as changed');
|
console.log('TEST: tmp_entry_obj and orig_entry_obj available; marking tmp_entry_obj as changed');
|
||||||
// tmp_entry_obj_changed = JSON.stringify(tmp_entry_obj) != JSON.stringify($lq__journal_entry_obj);
|
// tmp_entry_obj_changed = JSON.stringify(tmp_entry_obj) != JSON.stringify($lq__journal_entry_obj);
|
||||||
// tmp_entry_obj_changed = JSON.stringify(tmp_entry_obj) != JSON.stringify(orig_entry_obj);
|
// tmp_entry_obj_changed = JSON.stringify(tmp_entry_obj) != JSON.stringify(orig_entry_obj);
|
||||||
tmp_entry_obj_changed = true;
|
// if (!decrypted_content) {
|
||||||
|
tmp_entry_obj_changed = true;
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
console.log('TEST: tmp_entry_obj == orig_entry_obj');
|
console.log('TEST: tmp_entry_obj == orig_entry_obj');
|
||||||
tmp_entry_obj_changed = false;
|
tmp_entry_obj_changed = false;
|
||||||
@@ -158,6 +160,7 @@ async function update_journal_entry() {
|
|||||||
alert_msg: tmp_entry_obj?.alert_msg,
|
alert_msg: tmp_entry_obj?.alert_msg,
|
||||||
category_code: tmp_entry_obj?.category_code,
|
category_code: tmp_entry_obj?.category_code,
|
||||||
content: tmp_entry_obj?.content,
|
content: tmp_entry_obj?.content,
|
||||||
|
content_encrypted: null, // This should only be generated below.
|
||||||
group: tmp_entry_obj?.group,
|
group: tmp_entry_obj?.group,
|
||||||
archive_on: tmp_entry_obj?.archive_on,
|
archive_on: tmp_entry_obj?.archive_on,
|
||||||
name: tmp_entry_obj?.name,
|
name: tmp_entry_obj?.name,
|
||||||
@@ -165,7 +168,8 @@ async function update_journal_entry() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (tmp_entry_obj?.content && tmp_entry_obj?.private) {
|
if (tmp_entry_obj?.content && tmp_entry_obj?.private) {
|
||||||
content = $lq__journal_entry_obj?.content;
|
console.log('TEST: Saving encrypted content', tmp_entry_obj?.content);
|
||||||
|
content = tmp_entry_obj?.content;
|
||||||
|
|
||||||
// Encrypt the content
|
// Encrypt the content
|
||||||
let encrypted_base64 = await ae_util.encrypt_content(content, test_key);
|
let encrypted_base64 = await ae_util.encrypt_content(content, test_key);
|
||||||
@@ -177,6 +181,24 @@ async function update_journal_entry() {
|
|||||||
const combined_data = Array.from(encryption_iv).map(byte => byte.toString(16).padStart(2, '0')).join('') + ':' + encrypted_base64_content;
|
const combined_data = Array.from(encryption_iv).map(byte => byte.toString(16).padStart(2, '0')).join('') + ':' + encrypted_base64_content;
|
||||||
|
|
||||||
data_kv.content_encrypted = combined_data;
|
data_kv.content_encrypted = combined_data;
|
||||||
|
data_kv.content = null;
|
||||||
|
decrypted_content = '';
|
||||||
|
} else if (decrypted_content && !tmp_entry_obj?.private) {
|
||||||
|
console.log('TEST: Saving decrypted content', decrypted_content);
|
||||||
|
content = decrypted_content;
|
||||||
|
|
||||||
|
data_kv.content = content;
|
||||||
|
decrypted_content = '';
|
||||||
|
} else if (tmp_entry_obj?.content_encrypted && !tmp_entry_obj?.private) {
|
||||||
|
// alert('You must decrypt the content before saving it.');
|
||||||
|
console.log('TEST: You must decrypt the content before saving it.');
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
console.log('TEST: Saving content without encryption', tmp_entry_obj?.content);
|
||||||
|
// Clear content_encrypted again. Just in case.
|
||||||
|
// data_kv.content_encrypted = null;
|
||||||
|
decrypted_content = '';
|
||||||
|
// tmp_entry_obj.content_encrypted = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call API to save the content
|
// Call API to save the content
|
||||||
@@ -252,14 +274,14 @@ async function change_journal_id() {
|
|||||||
// return decodedContent;
|
// return decodedContent;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Example usage
|
// // Example usage
|
||||||
(async () => {
|
// (async () => {
|
||||||
const keyData = "my-secret-key";
|
// const keyData = "my-secret-key";
|
||||||
const content = "This is my test content to encrypt and decrypt.";
|
// const content = "This is my test content to encrypt and decrypt.";
|
||||||
|
|
||||||
const { base64, iv } = await ae_util.encrypt_content(content, keyData);
|
// const { base64, iv } = await ae_util.encrypt_content(content, keyData);
|
||||||
await ae_util.decrypt_content(base64, iv, keyData);
|
// await ae_util.decrypt_content(base64, iv, keyData);
|
||||||
})();
|
// })();
|
||||||
|
|
||||||
const test_key = "my-secret-key";
|
const test_key = "my-secret-key";
|
||||||
let content = "This is my test content to encrypt and decrypt.";
|
let content = "This is my test content to encrypt and decrypt.";
|
||||||
@@ -270,9 +292,9 @@ let trigger_decrypt: boolean = $state(false);
|
|||||||
|
|
||||||
$effect(async () => {
|
$effect(async () => {
|
||||||
if (tmp_entry_obj?.content_encrypted && trigger_decrypt) {
|
if (tmp_entry_obj?.content_encrypted && trigger_decrypt) {
|
||||||
|
trigger_decrypt = false;
|
||||||
log_lvl = 1;
|
log_lvl = 1;
|
||||||
|
|
||||||
trigger_decrypt = false;
|
|
||||||
let combined_data = tmp_entry_obj?.content_encrypted;
|
let combined_data = tmp_entry_obj?.content_encrypted;
|
||||||
let [encryption_iv_hex, encrypted_base64_content] = combined_data.split(':');
|
let [encryption_iv_hex, encrypted_base64_content] = combined_data.split(':');
|
||||||
encryption_iv = new Uint8Array(encryption_iv_hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
|
encryption_iv = new Uint8Array(encryption_iv_hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
|
||||||
@@ -281,10 +303,14 @@ $effect(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let decrypted = await ae_util.decrypt_content(encrypted_base64_content, encryption_iv, test_key);
|
let decrypted = await ae_util.decrypt_content(encrypted_base64_content, encryption_iv, test_key);
|
||||||
|
// decrypted_content = 'XXX '+decrypted+' XXX';
|
||||||
decrypted_content = decrypted;
|
decrypted_content = decrypted;
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log('Decrypted content:', decrypted_content);
|
console.log('Decrypted content:', decrypted_content);
|
||||||
}
|
}
|
||||||
|
tmp_entry_obj.content = decrypted_content;
|
||||||
|
// orig_entry_obj.content = decrypted_content;
|
||||||
|
// tmp_entry_obj_changed = false;
|
||||||
|
|
||||||
// tmp_entry_obj.content_encrypted = null;
|
// tmp_entry_obj.content_encrypted = null;
|
||||||
}
|
}
|
||||||
@@ -332,12 +358,17 @@ $effect(async () => {
|
|||||||
} else {
|
} else {
|
||||||
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = true;
|
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if ($ae_loc.trusted_access && !$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]) {
|
||||||
|
// trigger_decrypt = true;
|
||||||
|
// }
|
||||||
}}
|
}}
|
||||||
class="btn btn-icon-sm inline-block"
|
class="btn btn-icon-sm inline-block"
|
||||||
title="Toggle edit mode for this journal entry"
|
title="Toggle edit mode for this journal entry"
|
||||||
>
|
>
|
||||||
{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
||||||
<Pencil strokeWidth="2.5" color="blue" />
|
<!-- <Pencil strokeWidth="2.5" color="blue" /> -->
|
||||||
|
<PenLine strokeWidth="2.5" color="blue" />
|
||||||
{:else}
|
{:else}
|
||||||
<Pencil strokeWidth="1" color="gray" />
|
<Pencil strokeWidth="1" color="gray" />
|
||||||
{/if}
|
{/if}
|
||||||
@@ -643,13 +674,50 @@ $effect(async () => {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
tmp_entry_obj.private = !$lq__journal_entry_obj?.private;
|
if ($ae_loc.edit_mode) {
|
||||||
update_journal_entry();
|
if (tmp_entry_obj?.content_encrypted && tmp_entry_obj?.private) {
|
||||||
|
alert('You must decrypt the content before saving it!!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_entry_obj.private) {
|
||||||
|
if (confirm('Not private and decrypt?')) {
|
||||||
|
tmp_entry_obj.private = !$lq__journal_entry_obj?.private;
|
||||||
|
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
update_journal_entry();
|
||||||
|
// }
|
||||||
|
// update_journal_entry();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmp_entry_obj.private = !$lq__journal_entry_obj?.private;
|
||||||
|
update_journal_entry();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tmp_entry_obj?.content_encrypted && !decrypted_content) {
|
||||||
|
trigger_decrypt = true;
|
||||||
|
// } else if (tmp_entry_obj?.content_encrypted && decrypted_content && tmp_entry_obj_changed) {
|
||||||
|
// // This is ok because it has not really changed?
|
||||||
|
// // decrypted_content = '';
|
||||||
|
// alert('This journal entry has changed.');
|
||||||
|
|
||||||
|
} else if (tmp_entry_obj?.content_encrypted && decrypted_content) {
|
||||||
|
decrypted_content = '';
|
||||||
|
tmp_entry_obj.content = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
ondblclick={() => {
|
||||||
|
// tmp_entry_obj.private = !$lq__journal_entry_obj?.private;
|
||||||
|
// update_journal_entry();
|
||||||
}}
|
}}
|
||||||
class="btn-icon-sm"
|
class="btn-icon-sm"
|
||||||
title="Toggle private visibility of this journal entry"
|
title="Toggle private visibility of this journal entry"
|
||||||
>
|
>
|
||||||
{#if $lq__journal_entry_obj?.private}
|
{#if $lq__journal_entry_obj?.private && decrypted_content}
|
||||||
|
<Fingerprint strokeWidth="2.5" color="red" />
|
||||||
|
{:else if $lq__journal_entry_obj?.private}
|
||||||
<Fingerprint strokeWidth="2.5" color="green" />
|
<Fingerprint strokeWidth="2.5" color="green" />
|
||||||
{:else}
|
{:else}
|
||||||
<Fingerprint strokeWidth="1" color="gray" />
|
<Fingerprint strokeWidth="1" color="gray" />
|
||||||
@@ -757,6 +825,7 @@ $effect(async () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{#if (!$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id])}
|
||||||
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
||||||
<div
|
<div
|
||||||
ondblclick={() => {
|
ondblclick={() => {
|
||||||
@@ -765,15 +834,10 @@ $effect(async () => {
|
|||||||
$journals_loc.entry.edit = !$journals_loc.entry.edit;
|
$journals_loc.entry.edit = !$journals_loc.entry.edit;
|
||||||
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ae_loc.trusted_access && $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]) {
|
|
||||||
trigger_decrypt = true;
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
role={$ae_loc.edit_mode ? 'button' : 'article'}
|
role={$ae_loc.edit_mode ? 'button' : 'article'}
|
||||||
tabindex={$ae_loc.edit_mode ? 0 : -1}
|
tabindex={$ae_loc.edit_mode ? 0 : -1}
|
||||||
|
|
||||||
class:hidden={!$ae_loc.trusted_access || $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
|
||||||
class="
|
class="
|
||||||
flex-grow
|
flex-grow
|
||||||
flex flex-col items-center justify-center
|
flex flex-col items-center justify-center
|
||||||
@@ -805,7 +869,15 @@ $effect(async () => {
|
|||||||
"
|
"
|
||||||
id="rendered_journal_entry_content_{$lq__journal_entry_obj?.journal_entry_id}"
|
id="rendered_journal_entry_content_{$lq__journal_entry_obj?.journal_entry_id}"
|
||||||
>
|
>
|
||||||
{@html decrypted_content ?? $lq__journal_entry_obj?.content_md_html}
|
{#if decrypted_content?.length}
|
||||||
|
{@html decrypted_content}
|
||||||
|
{:else if $lq__journal_entry_obj?.content_encrypted}
|
||||||
|
<span class="text-sm text-gray-500 break-all">
|
||||||
|
{@html $lq__journal_entry_obj?.content_encrypted}
|
||||||
|
</span>
|
||||||
|
{:else}
|
||||||
|
{@html $lq__journal_entry_obj?.content_md_html}
|
||||||
|
{/if}
|
||||||
</article>
|
</article>
|
||||||
<!-- {@html async () => {
|
<!-- {@html async () => {
|
||||||
const { base64, iv } = await encrypt_content(content, test_key);
|
const { base64, iv } = await encrypt_content(content, test_key);
|
||||||
@@ -820,69 +892,105 @@ $effect(async () => {
|
|||||||
<!-- --{@html encrypted_base64_content}-- -->
|
<!-- --{@html encrypted_base64_content}-- -->
|
||||||
<!-- {@html marked.parse($lq__journal_entry_obj?.content)} -->
|
<!-- {@html marked.parse($lq__journal_entry_obj?.content)} -->
|
||||||
</div>
|
</div>
|
||||||
|
{:else if ($journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id])}
|
||||||
|
<!-- && !($lq__journal_entry_obj?.content_encrypted && decrypted_content)) -->
|
||||||
|
<!-- class="flex flex-row flex-wrap gap-1 items-center justify-center w-full max-w-sm" -->
|
||||||
|
{#if ($lq__journal_entry_obj?.content_encrypted && !decrypted_content)}
|
||||||
|
<div
|
||||||
|
class="
|
||||||
|
flex-grow min-h-48 h-full w-full
|
||||||
|
p-2
|
||||||
|
bg-red-100 text-gray-900
|
||||||
|
dark:bg-red-900 dark:text-gray-100
|
||||||
|
shadow-lg rounded-lg
|
||||||
|
border border-red-200 dark:border-red-700
|
||||||
|
hover:border-red-500 dark:hover:border-red-500
|
||||||
|
"
|
||||||
|
>
|
||||||
|
The entry must be decrypted before it can be edited.
|
||||||
|
<!-- <span class="text-sm text-gray-500">
|
||||||
|
<Lock key={0} strokeWidth="2.5" color="red" />
|
||||||
|
<span class="hidden sm:inline">Encrypted</span>
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => {
|
||||||
|
if ($ae_loc.trusted_access) {
|
||||||
|
trigger_decrypt = true;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
class="btn btn-sm variant-soft-secondary hover:variant-filled-secondary *:hover:inline lg:text-xs"
|
||||||
|
title="Decrypt the content of this journal entry"
|
||||||
|
>
|
||||||
|
<LockOpen key={1} strokeWidth="2.5" color="green" />
|
||||||
|
<span class="hidden sm:inline">Decrypt</span>
|
||||||
|
</button> -->
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div
|
||||||
|
class="
|
||||||
|
flex-grow flex flex-col items-center justify-center
|
||||||
|
w-full max-w-6xl
|
||||||
|
"
|
||||||
|
>
|
||||||
|
|
||||||
<div
|
<textarea
|
||||||
class:hidden={!$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] && $lq__journal_entry_obj?.content?.length}
|
bind:value={tmp_entry_obj.content}
|
||||||
class="
|
ondblclick={() => {
|
||||||
flex-grow flex flex-col items-center justify-center
|
if ($ae_loc.trusted_access && $ae_loc.edit_mode) {
|
||||||
w-full max-w-6xl
|
// Toggle edit mode
|
||||||
"
|
$journals_loc.entry.edit = !$journals_loc.entry.edit;
|
||||||
>
|
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
||||||
|
}
|
||||||
<textarea
|
}}
|
||||||
bind:value={tmp_entry_obj.content}
|
disabled={tmp_entry_obj.content_encrypted && !decrypted_content}
|
||||||
ondblclick={() => {
|
class:border-orange-200={$ae_loc.edit_mode}
|
||||||
if ($ae_loc.trusted_access && $ae_loc.edit_mode) {
|
class:hover:border-orange-500={$ae_loc.edit_mode}
|
||||||
// Toggle edit mode
|
class="
|
||||||
$journals_loc.entry.edit = !$journals_loc.entry.edit;
|
flex-grow min-h-48 h-full w-full
|
||||||
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
p-2
|
||||||
}
|
bg-slate-100 text-gray-900
|
||||||
}}
|
dark:bg-slate-900 dark:text-gray-100
|
||||||
class:border-orange-200={$ae_loc.edit_mode}
|
shadow-lg rounded-lg
|
||||||
class:hover:border-orange-500={$ae_loc.edit_mode}
|
border border-gray-200 dark:border-gray-700
|
||||||
class="
|
hover:border-gray-500 dark:hover:border-gray-500
|
||||||
flex-grow min-h-48 h-full w-full
|
"
|
||||||
p-2
|
|
||||||
bg-slate-100 text-gray-900
|
|
||||||
dark:bg-slate-900 dark:text-gray-100
|
|
||||||
shadow-lg rounded-lg
|
|
||||||
border border-gray-200 dark:border-gray-700
|
|
||||||
hover:border-gray-500 dark:hover:border-gray-500
|
|
||||||
"
|
|
||||||
placeholder="Edit journal entry content here..."
|
placeholder="Edit journal entry content here..."
|
||||||
></textarea>
|
></textarea>
|
||||||
|
|
||||||
<!-- Only enable editing if the user has trusted access -->
|
<!-- Only enable editing if the user has trusted access -->
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
update_journal_entry();
|
update_journal_entry();
|
||||||
}}
|
}}
|
||||||
disabled={!tmp_entry_obj_changed}
|
disabled={!tmp_entry_obj_changed}
|
||||||
class:variant-filled-error={tmp_entry_obj_changed}
|
class:variant-filled-error={tmp_entry_obj_changed}
|
||||||
class="
|
class="
|
||||||
btn btn-sm md:btn-md lg:btn-lg
|
btn btn-sm md:btn-md lg:btn-lg
|
||||||
min-w-72 w-full lg:min-w-96
|
min-w-72 w-full lg:min-w-96
|
||||||
max-w-96
|
max-w-96
|
||||||
hover:variant-outline-success
|
hover:variant-outline-success
|
||||||
hover:variant-filled-success
|
hover:variant-filled-success
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
Save Changes?
|
Save Changes?
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Do a quick check to see if the updated_on timestamp has changed. Specifically, if the entry was updated since the last time it was loaded. -->
|
<!-- Do a quick check to see if the updated_on timestamp has changed. Specifically, if the entry was updated since the last time it was loaded. -->
|
||||||
{#if updated_idb}
|
{#if updated_idb}
|
||||||
<span class="text-sm text-red-500">
|
<span class="text-sm text-red-500">
|
||||||
WARNING: IDB object has been updated since last load.
|
WARNING: IDB object has been updated since last load.
|
||||||
</span>
|
</span>
|
||||||
|
{/if}
|
||||||
|
<!-- Updated: {orig_entry_obj?.updated_on}
|
||||||
|
Updated obj? {updated_obj} -->
|
||||||
|
|
||||||
|
<!-- && $lq__journal_entry_obj?.updated_on !== orig_entry_obj?.updated_on -->
|
||||||
|
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<!-- Updated: {orig_entry_obj?.updated_on}
|
{/if}
|
||||||
Updated obj? {updated_obj} -->
|
|
||||||
|
|
||||||
<!-- && $lq__journal_entry_obj?.updated_on !== orig_entry_obj?.updated_on -->
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <div>
|
<!-- <div>
|
||||||
{@html test_html}
|
{@html test_html}
|
||||||
|
|||||||
Reference in New Issue
Block a user