Other areas of the AE SvelteKit primary routes.

This commit is contained in:
Scott Idem
2026-03-24 12:18:27 -04:00
parent 6018a94499
commit e1338b1a72
13 changed files with 1607 additions and 1026 deletions

View File

@@ -6,14 +6,17 @@ import type { RequestHandler } from './$types';
* Used by Docker and Nginx to verify the service is running.
*/
export const GET: RequestHandler = async () => {
return json({
status: 'healthy',
timestamp: new Date().toISOString(),
service: 'aether-app-sveltekit',
node_env: process.env.NODE_ENV || 'development'
}, {
headers: {
'Cache-Control': 'no-cache'
return json(
{
status: 'healthy',
timestamp: new Date().toISOString(),
service: 'aether-app-sveltekit',
node_env: process.env.NODE_ENV || 'development'
},
{
headers: {
'Cache-Control': 'no-cache'
}
}
});
);
};

View File

@@ -1,34 +1,34 @@
<script lang="ts">
/** @type {import('./$types').LayoutData} */
let log_lvl: number = 1;
// *** Import Svelte specific
// import { browser } from '$app/environment';
// *** Import other supporting libraries
import { Brain, House, Library, RefreshCw, Satellite } from '@lucide/svelte';
// *** Import Aether specific variables and functions
// import type { key_val } from '$lib/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
import {
ae_snip,
ae_loc,
ae_sess,
ae_api,
ae_trig,
slct,
slct_trigger
} from '$lib/stores/ae_stores';
// import Element_data_store from '$lib/elements/element_data_store.svelte';
interface Props {
/** @type {import('./$types').LayoutData} */
let log_lvl: number = 1;
data: any;
children?: import('svelte').Snippet;
}
// *** Import Svelte specific
// import { browser } from '$app/environment';
// *** Import other supporting libraries
import { Brain, House, Library, RefreshCw, Satellite } from '@lucide/svelte';
// *** Import Aether specific variables and functions
// import type { key_val } from '$lib/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
import {
ae_snip,
ae_loc,
ae_sess,
ae_api,
ae_trig,
slct,
slct_trigger
} from '$lib/stores/ae_stores';
// import Element_data_store from '$lib/elements/element_data_store.svelte';
interface Props {
/** @type {import('./$types').LayoutData} */
data: any;
children?: import('svelte').Snippet;
}
let { data, children }: Props = $props();
let { data, children }: Props = $props();
</script>
<svelte:head>
@@ -40,11 +40,10 @@
class:iframe={$ae_loc?.iframe}
class="
ae_hosted_files
h-full max-h-full max-w-6xl overflow-auto
flex flex-col gap-1
m-auto
"
>
m-auto flex h-full max-h-full
max-w-6xl flex-col gap-1
overflow-auto
">
<nav
class="
submenu
@@ -55,8 +54,7 @@
p-1
px-2
pb-2
"
>
">
<span class="justify-self-start">
<!-- Be sure to explain what &AElig; (Aether) means in the title text or similar! -->
<Satellite size="1.5em" class="mx-1 inline-block text-gray-500" />
@@ -68,14 +66,15 @@
/> -->
<a
href="/"
class="btn btn-sm preset-tonal-surface border border-surface-500 hover:preset-filled-success-500"
>
class="btn btn-sm preset-tonal-surface border-surface-500 hover:preset-filled-success-500 border">
<House />
<span class="hidden md:inline"> Home </span>
</a>
</nav>
<section class:iframe={$ae_loc?.iframe} class="main_content grow px-1 md:px-2 pb-28">
<section
class:iframe={$ae_loc?.iframe}
class="main_content grow px-1 pb-28 md:px-2">
{@render children?.()}
</section>
</div>

View File

@@ -27,7 +27,9 @@ export async function load({ params, parent, url }) {
const qry_limit = parseInt(url.searchParams.get('limit') ?? '19');
if (!qry_limit) {
console.log(`qry_limit +page.ts: The qry_limit was not found in the params!!!`);
console.log(
`qry_limit +page.ts: The qry_limit was not found in the params!!!`
);
}
ae_acct.slct.qry_limit = qry_limit;

View File

@@ -1,90 +1,96 @@
<script lang="ts">
// console.log(`ae_ Svelte Hosted Files +page data:`, data);
// console.log(`ae_ Svelte Hosted Files +page data:`, data);
import { onMount } from 'svelte';
import { onMount } from 'svelte';
// import { api } from '$lib/api.js';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
import type { key_val } from '$lib/stores/ae_stores';
// import { api } from '$lib/api.js';
import {
ae_loc,
ae_sess,
ae_api,
slct,
slct_trigger
} from '$lib/stores/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
import type { key_val } from '$lib/stores/ae_stores';
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
import { Video } from '@lucide/svelte';
let { data } = $props();
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
import { Video } from '@lucide/svelte';
let { data } = $props();
let log_lvl = 0;
let log_lvl = 0;
let ae_promises: key_val = {};
let ae_promises: key_val = {};
// export let container_class_li = [];
// export let container_class_li = [];
let file_uploads_post_promise;
let download_src;
let download_filename;
let file_uploads_post_promise;
let download_src;
let download_filename;
if (!$ae_loc.files) {
$ae_loc.files = {};
$ae_loc.files.processed_file_kv = {};
$ae_loc.files.uploaded_file_kv = {};
$ae_loc.files.video_clip_file_kv = {};
// $ae_loc.files.uploaded_file_list = [];
// $ae_loc.files.video_clip_file_list = [];
}
if (!$ae_loc.files.processed_file_kv) {
$ae_loc.files.processed_file_kv = {};
if (!$ae_loc.files) {
$ae_loc.files = {};
$ae_loc.files.processed_file_kv = {};
$ae_loc.files.uploaded_file_kv = {};
$ae_loc.files.video_clip_file_kv = {};
// $ae_loc.files.uploaded_file_list = [];
// $ae_loc.files.video_clip_file_list = [];
}
if (!$ae_loc.files.processed_file_kv) {
$ae_loc.files.processed_file_kv = {};
}
$effect(() => {
// if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_li) {
// // Append this list to the $ae_loc.files.uploaded_file_li list
// $ae_loc.files.uploaded_file_li = [
// ...$ae_loc.files.uploaded_file_li,
// ...$ae_sess.files.uploaded_file_li
// ];
// }
if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_kv) {
// Add this key-value pair to the $ae_loc.files.uploaded_file_kv object
$ae_loc.files.uploaded_file_kv = {
...$ae_loc.files.uploaded_file_kv,
...$ae_sess.files.uploaded_file_kv
};
$ae_sess.files.upload_complete = false;
}
$effect(() => {
// if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_li) {
// // Append this list to the $ae_loc.files.uploaded_file_li list
// $ae_loc.files.uploaded_file_li = [
// ...$ae_loc.files.uploaded_file_li,
// ...$ae_sess.files.uploaded_file_li
// ];
// }
if ($ae_sess.files.clip_complete && $ae_sess.files.video_clip_file_kv) {
// Add this key-value pair to the $ae_loc.files.video_clip_file_kv object
$ae_loc.files.video_clip_file_kv = {
...$ae_loc.files.video_clip_file_kv,
...$ae_sess.files.video_clip_file_kv
};
$ae_sess.files.clip_complete = false;
}
});
if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_kv) {
// Add this key-value pair to the $ae_loc.files.uploaded_file_kv object
$ae_loc.files.uploaded_file_kv = {
...$ae_loc.files.uploaded_file_kv,
...$ae_sess.files.uploaded_file_kv
};
$ae_sess.files.upload_complete = false;
}
// $effect(() => {
// if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_kv) {
// // Add this key-value pair to the $ae_loc.files.uploaded_file_kv object
// $ae_loc.files.uploaded_file_kv = {
// ...$ae_loc.files.uploaded_file_kv,
// ...$ae_sess.files.uploaded_file_kv
// };
// }
// });
if ($ae_sess.files.clip_complete && $ae_sess.files.video_clip_file_kv) {
// Add this key-value pair to the $ae_loc.files.video_clip_file_kv object
$ae_loc.files.video_clip_file_kv = {
...$ae_loc.files.video_clip_file_kv,
...$ae_sess.files.video_clip_file_kv
};
$ae_sess.files.clip_complete = false;
}
});
// $effect(() => {
// if ($ae_sess.files.clip_complete && $ae_sess.files.video_clip_file_kv) {
// // Add this key-value pair to the $ae_loc.files.video_clip_file_kv object
// $ae_loc.files.video_clip_file_kv = {
// ...$ae_loc.files.video_clip_file_kv,
// ...$ae_sess.files.video_clip_file_kv
// };
// }
// });
// $effect(() => {
// if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_kv) {
// // Add this key-value pair to the $ae_loc.files.uploaded_file_kv object
// $ae_loc.files.uploaded_file_kv = {
// ...$ae_loc.files.uploaded_file_kv,
// ...$ae_sess.files.uploaded_file_kv
// };
// }
// });
// $effect(() => {
// if ($ae_sess.files.clip_complete && $ae_sess.files.video_clip_file_kv) {
// // Add this key-value pair to the $ae_loc.files.video_clip_file_kv object
// $ae_loc.files.video_clip_file_kv = {
// ...$ae_loc.files.video_clip_file_kv,
// ...$ae_sess.files.video_clip_file_kv
// };
// }
// });
onMount(() => {
console.log('Hosted Files: AV Utilities +page.svelte');
});
onMount(() => {
console.log('Hosted Files: AV Utilities +page.svelte');
});
</script>
<!-- <section
@@ -123,8 +129,7 @@
link_to_id={$ae_loc?.account_id}
allow_basic={true}
allow_moderator={true}
class_li={'max-h-full'}
/>
class_li={'max-h-full'} />
<!-- </div> -->

View File

@@ -1,123 +1,129 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { run } from 'svelte/legacy';
// console.log(`ae_ Svelte Hosted Files +page data:`, data);
// console.log(`ae_ Svelte Hosted Files +page data:`, data);
import { onMount } from 'svelte';
import { onMount } from 'svelte';
// import { api } from '$lib/api.js';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
import type { key_val } from '$lib/stores/ae_stores';
// import { api } from '$lib/api.js';
import {
ae_loc,
ae_sess,
ae_api,
slct,
slct_trigger
} from '$lib/stores/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
import type { key_val } from '$lib/stores/ae_stores';
import Comp_hosted_files_upload from '$lib/ae_core/ae_comp__hosted_files_upload.svelte';
import Comp_hosted_files_clip_video from '$lib/ae_core/ae_comp__hosted_files_clip_video.svelte';
import Comp_hosted_files_clip_video_li from '$lib/ae_core/ae_comp__hosted_files_clip_video_li.svelte';
import Comp_hosted_files_upload from '$lib/ae_core/ae_comp__hosted_files_upload.svelte';
import Comp_hosted_files_clip_video from '$lib/ae_core/ae_comp__hosted_files_clip_video.svelte';
import Comp_hosted_files_clip_video_li from '$lib/ae_core/ae_comp__hosted_files_clip_video_li.svelte';
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
import { ArrowLeftRight, Trash2, Upload } from '@lucide/svelte';
let { data } = $props();
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
import { ArrowLeftRight, Trash2, Upload } from '@lucide/svelte';
let { data } = $props();
let log_lvl = 1;
let log_lvl = 1;
let ae_promises: key_val = {};
let ae_promises: key_val = {};
// export let container_class_li = [];
// export let container_class_li = [];
let file_uploads_post_promise;
let download_src;
let download_filename;
let file_uploads_post_promise;
let download_src;
let download_filename;
let file_uploads_clip_post_promise;
let download_clip_src;
let download_clip_filename;
let file_uploads_clip_post_promise;
let download_clip_src;
let download_clip_filename;
let hosted_file_upload: key_val = $state({
// link_to_type: 'account',
// link_to_id: ae_loc.account_id,
hosted_file_id_li: [],
hosted_file_obj_li: [],
clip_complete: false,
upload_complete: false,
submit_status: null
});
let hosted_file_upload: key_val = $state({
// link_to_type: 'account',
// link_to_id: ae_loc.account_id,
hosted_file_id_li: [],
hosted_file_obj_li: [],
clip_complete: false,
upload_complete: false,
submit_status: null
});
let hosted_file_clip: key_val = $state({
video_clip_file_kv: {},
clip_complete: false,
submit_status: null
});
let hosted_file_clip: key_val = $state({
video_clip_file_kv: {},
clip_complete: false,
submit_status: null
});
if (!$ae_loc.files) {
$ae_loc.files = {};
$ae_loc.files.processed_file_kv = {};
$ae_loc.files.uploaded_file_kv = {};
$ae_loc.files.video_clip_file_kv = {};
// $ae_loc.files.uploaded_file_list = [];
// $ae_loc.files.video_clip_file_list = [];
}
if (!$ae_loc.files.processed_file_kv) {
$ae_loc.files.processed_file_kv = {};
}
if (!$ae_loc.files) {
$ae_loc.files = {};
$ae_loc.files.processed_file_kv = {};
$ae_loc.files.uploaded_file_kv = {};
$ae_loc.files.video_clip_file_kv = {};
// $ae_loc.files.uploaded_file_list = [];
// $ae_loc.files.video_clip_file_list = [];
}
if (!$ae_loc.files.processed_file_kv) {
$ae_loc.files.processed_file_kv = {};
}
if (!$ae_sess.files) {
$ae_sess.files = {};
}
if (typeof $ae_sess.files.upload_complete === 'undefined') {
if (!$ae_sess.files) {
$ae_sess.files = {};
}
if (typeof $ae_sess.files.upload_complete === 'undefined') {
$ae_sess.files.upload_complete = false;
}
$effect(() => {
// if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_li) {
// // Append this list to the $ae_loc.files.uploaded_file_li list
// $ae_loc.files.uploaded_file_li = [
// ...$ae_loc.files.uploaded_file_li,
// ...$ae_sess.files.uploaded_file_li
// ];
// }
if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_kv) {
// Add this key-value pair to the $ae_loc.files.uploaded_file_kv object
$ae_loc.files.uploaded_file_kv = {
...$ae_loc.files.uploaded_file_kv,
...$ae_sess.files.uploaded_file_kv
};
$ae_sess.files.upload_complete = false;
}
$effect(() => {
// if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_li) {
// // Append this list to the $ae_loc.files.uploaded_file_li list
// $ae_loc.files.uploaded_file_li = [
// ...$ae_loc.files.uploaded_file_li,
// ...$ae_sess.files.uploaded_file_li
// ];
// }
if ($ae_sess.files.clip_complete && $ae_sess.files.video_clip_file_kv) {
// Add this key-value pair to the $ae_loc.files.video_clip_file_kv object
$ae_loc.files.video_clip_file_kv = {
...$ae_loc.files.video_clip_file_kv,
...$ae_sess.files.video_clip_file_kv
};
$ae_sess.files.clip_complete = false;
}
});
if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_kv) {
// Add this key-value pair to the $ae_loc.files.uploaded_file_kv object
$ae_loc.files.uploaded_file_kv = {
...$ae_loc.files.uploaded_file_kv,
...$ae_sess.files.uploaded_file_kv
};
$ae_sess.files.upload_complete = false;
}
// $effect(() => {
// if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_kv) {
// // Add this key-value pair to the $ae_loc.files.uploaded_file_kv object
// $ae_loc.files.uploaded_file_kv = {
// ...$ae_loc.files.uploaded_file_kv,
// ...$ae_sess.files.uploaded_file_kv
// };
// }
// });
if ($ae_sess.files.clip_complete && $ae_sess.files.video_clip_file_kv) {
// Add this key-value pair to the $ae_loc.files.video_clip_file_kv object
$ae_loc.files.video_clip_file_kv = {
...$ae_loc.files.video_clip_file_kv,
...$ae_sess.files.video_clip_file_kv
};
$ae_sess.files.clip_complete = false;
}
});
// $effect(() => {
// if ($ae_sess.files.clip_complete && $ae_sess.files.video_clip_file_kv) {
// // Add this key-value pair to the $ae_loc.files.video_clip_file_kv object
// $ae_loc.files.video_clip_file_kv = {
// ...$ae_loc.files.video_clip_file_kv,
// ...$ae_sess.files.video_clip_file_kv
// };
// }
// });
// $effect(() => {
// if ($ae_sess.files.upload_complete && $ae_sess.files.uploaded_file_kv) {
// // Add this key-value pair to the $ae_loc.files.uploaded_file_kv object
// $ae_loc.files.uploaded_file_kv = {
// ...$ae_loc.files.uploaded_file_kv,
// ...$ae_sess.files.uploaded_file_kv
// };
// }
// });
// $effect(() => {
// if ($ae_sess.files.clip_complete && $ae_sess.files.video_clip_file_kv) {
// // Add this key-value pair to the $ae_loc.files.video_clip_file_kv object
// $ae_loc.files.video_clip_file_kv = {
// ...$ae_loc.files.video_clip_file_kv,
// ...$ae_sess.files.video_clip_file_kv
// };
// }
// });
onMount(() => {
console.log('Hosted Files: AV Utilities +page.svelte');
});
onMount(() => {
console.log('Hosted Files: AV Utilities +page.svelte');
});
</script>
<!-- <section
@@ -140,10 +146,11 @@
<h1 class="h1">Clip and Scale Video Files</h1>
<p>
This AV utility will take an mp4 video file and create a clipped mp4 video file. By default,
videos will be scaled down to 1920x1080. This process takes at least 30 seconds, but it can
easily take a handful of minutes. The scaling option requires that the video be re-encoded.
Please be patient while it is processing.
This AV utility will take an mp4 video file and create a clipped mp4 video
file. By default, videos will be scaled down to 1920x1080. This process
takes at least 30 seconds, but it can easily take a handful of minutes. The
scaling option requires that the video be re-encoded. Please be patient
while it is processing.
</p>
<h2 class="h2">
@@ -151,7 +158,7 @@
<button
type="button"
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 float-right"
class="btn btn-sm preset-tonal-warning border-warning-500 hover:preset-filled-warning-500 float-right border"
title="Toggle between Upload and Select from Hosted Files"
onclick={() => {
if ($ae_sess.files.add_to_use_files_method == 'upload') {
@@ -159,8 +166,7 @@
} else {
$ae_sess.files.add_to_use_files_method = 'upload';
}
}}
>
}}>
<ArrowLeftRight size="1em" class="m-1" />
Upload/Select
</button>
@@ -175,15 +181,15 @@
bind:hosted_file_obj_li={hosted_file_upload.hosted_file_obj_li}
bind:hosted_file_obj_kv={$ae_sess.files.uploaded_file_kv}
bind:upload_complete={$ae_sess.files.upload_complete}
{log_lvl}
>
{log_lvl}>
{#snippet label()}
<span>
<div class="flex items-center gap-2 mb-1">
<div class="mb-1 flex items-center gap-2">
<Upload size="1em" class="text-primary-500" />
<strong class="preset-tonal-success px-3 py-1 rounded-full">Upload video files</strong>
<strong class="preset-tonal-success rounded-full px-3 py-1"
>Upload video files</strong>
</div>
<span class="text-sm opacity-70 italic">
<span class="text-sm italic opacity-70">
<strong>Aether hosted files only</strong><br />
Recommended: video (mp4, mkv)<br />
</span>
@@ -200,8 +206,7 @@
allow_moderator={true}
class_li={''}
max_file_count={39}
file_type={'video'}
/>
file_type={'video'} />
</div>
<hr />
@@ -214,8 +219,7 @@
onclick={() => {
$ae_loc.files.uploaded_file_kv = {};
}}
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 float-right"
>
class="btn btn-sm preset-tonal-warning border-warning-500 hover:preset-filled-warning-500 float-right border">
<Trash2 size="1em" class="m-1" />
Clear Upload History
</button>
@@ -229,8 +233,7 @@
bind:video_clip_file_kv={$ae_loc.files.video_clip_file_kv}
bind:clip_complete={$ae_sess.files.clip_complete}
bind:submit_status={hosted_file_clip.submit_status}
{log_lvl}
></Comp_hosted_files_clip_video>
{log_lvl}></Comp_hosted_files_clip_video>
{:else}
<p>Upload a video file to clip first.</p>
{/if}
@@ -245,8 +248,7 @@
onclick={() => {
$ae_loc.files.video_clip_file_kv = {};
}}
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 float-right"
>
class="btn btn-sm preset-tonal-warning border-warning-500 hover:preset-filled-warning-500 float-right border">
<Trash2 size="1em" class="m-1" />
Clear Clip History
</button>
@@ -257,8 +259,7 @@
link_to_type="account"
link_to_id={$ae_loc.account_id}
bind:video_clip_file_kv={$ae_loc.files.video_clip_file_kv}
{log_lvl}
></Comp_hosted_files_clip_video_li>
{log_lvl}></Comp_hosted_files_clip_video_li>
{:else}
<p>Clip a video file first.</p>
{/if}

View File

@@ -1,54 +1,61 @@
<script lang="ts">
// import { api } from '$lib/api.js';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
import type { key_val } from '$lib/stores/ae_stores';
// import { api } from '$lib/api.js';
import {
ae_loc,
ae_sess,
ae_api,
slct,
slct_trigger
} from '$lib/stores/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
import type { key_val } from '$lib/stores/ae_stores';
import Comp_hosted_files_upload from '$lib/ae_core/ae_comp__hosted_files_upload.svelte';
import Comp_hosted_files_clip_video from '$lib/ae_core/ae_comp__hosted_files_clip_video.svelte';
import Comp_hosted_files_clip_video_li from '$lib/ae_core/ae_comp__hosted_files_clip_video_li.svelte';
import Comp_hosted_files_upload from '$lib/ae_core/ae_comp__hosted_files_upload.svelte';
import Comp_hosted_files_clip_video from '$lib/ae_core/ae_comp__hosted_files_clip_video.svelte';
import Comp_hosted_files_clip_video_li from '$lib/ae_core/ae_comp__hosted_files_clip_video_li.svelte';
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
import { ArrowLeftRight, Trash2, Upload } from '@lucide/svelte';
let log_lvl = 1;
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
import { ArrowLeftRight, Trash2, Upload } from '@lucide/svelte';
let log_lvl = 1;
let ae_promises: key_val = {};
let ae_promises: key_val = {};
// export let container_class_li = [];
// export let container_class_li = [];
let file_uploads_post_promise;
let download_src;
let download_filename;
let file_uploads_post_promise;
let download_src;
let download_filename;
let file_uploads_clip_post_promise;
let download_clip_src;
let download_clip_filename;
let file_uploads_clip_post_promise;
let download_clip_src;
let download_clip_filename;
let hosted_file_upload: key_val = $state({
// link_to_type: 'account',
// link_to_id: ae_loc.account_id,
hosted_file_id_li: [],
hosted_file_obj_li: [],
clip_complete: false,
upload_complete: false,
submit_status: null
});
let hosted_file_upload: key_val = $state({
// link_to_type: 'account',
// link_to_id: ae_loc.account_id,
hosted_file_id_li: [],
hosted_file_obj_li: [],
clip_complete: false,
upload_complete: false,
submit_status: null
});
let hosted_file_clip: key_val = $state({
video_clip_file_kv: {},
clip_complete: false,
submit_status: null
});
let hosted_file_clip: key_val = $state({
video_clip_file_kv: {},
clip_complete: false,
submit_status: null
});
</script>
<section class="ae__hosted_files__av_util container space-y-4 pb-20">
<div class="border border-gray-200 p-2 rounded-lg">
<div class="rounded-lg border border-gray-200 p-2">
<h1 class="h1">Clip and Scale Video Files</h1>
<p>
This AV utility will take an mp4 video file and create a clipped mp4 video file. By
default, videos will be scaled down to 1920x1080. This process takes at least 30
seconds, but it can easily take a handful of minutes. The scaling option requires that
the video be re-encoded. Please be patient while it is processing.
This AV utility will take an mp4 video file and create a clipped mp4
video file. By default, videos will be scaled down to 1920x1080.
This process takes at least 30 seconds, but it can easily take a
handful of minutes. The scaling option requires that the video be
re-encoded. Please be patient while it is processing.
</p>
<h2 class="h2">
@@ -56,7 +63,7 @@
<button
type="button"
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 float-right"
class="btn btn-sm preset-tonal-warning border-warning-500 hover:preset-filled-warning-500 float-right border"
title="Toggle between Upload and Select from Hosted Files"
onclick={() => {
if ($ae_sess.files.add_to_use_files_method == 'upload') {
@@ -64,8 +71,7 @@
} else {
$ae_sess.files.add_to_use_files_method = 'upload';
}
}}
>
}}>
<ArrowLeftRight size="1em" class="m-1" />
Upload/Select
</button>
@@ -80,15 +86,16 @@
bind:hosted_file_obj_li={hosted_file_upload.hosted_file_obj_li}
bind:hosted_file_obj_kv={$ae_sess.files.uploaded_file_kv}
bind:upload_complete={$ae_sess.files.upload_complete}
{log_lvl}
>
{log_lvl}>
{#snippet label()}
<span>
<div>
<Upload size="1em" />
<strong class="bg-green-100 p-1">Upload video files</strong>
<strong class="bg-green-100 p-1"
>Upload video files</strong>
</div>
<span class="text-sm text-gray-600 dark:text-gray-400 italic">
<span
class="text-sm text-gray-600 italic dark:text-gray-400">
<strong>Aether hosted files only</strong><br />
Recommended: video (mp4, mkv)<br />
</span>
@@ -97,14 +104,15 @@
</Comp_hosted_files_upload>
</div>
<div class:hidden={$ae_sess.files.add_to_use_files_method == 'select'} class="">
<div
class:hidden={$ae_sess.files.add_to_use_files_method == 'select'}
class="">
<Element_manage_hosted_file_li_wrap
link_to_type={'account'}
link_to_id={$ae_loc?.account_id}
allow_basic={true}
allow_moderator={true}
class_li={''}
/>
class_li={''} />
</div>
<hr />
@@ -117,8 +125,7 @@
onclick={() => {
$ae_loc.files.uploaded_file_kv = {};
}}
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 float-right"
>
class="btn btn-sm preset-tonal-warning border-warning-500 hover:preset-filled-warning-500 float-right border">
<Trash2 size="1em" class="m-1" />
Clear Upload History
</button>
@@ -132,8 +139,7 @@
bind:video_clip_file_kv={$ae_loc.files.video_clip_file_kv}
bind:clip_complete={$ae_sess.files.clip_complete}
bind:submit_status={hosted_file_clip.submit_status}
{log_lvl}
></Comp_hosted_files_clip_video>
{log_lvl}></Comp_hosted_files_clip_video>
{:else}
<p>Upload a video file to clip first.</p>
{/if}
@@ -146,8 +152,7 @@
onclick={() => {
$ae_loc.files.video_clip_file_kv = {};
}}
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 float-right"
>
class="btn btn-sm preset-tonal-warning border-warning-500 hover:preset-filled-warning-500 float-right border">
<Trash2 size="1em" class="m-1" />
Clear Clip History
</button>
@@ -158,8 +163,7 @@
link_to_type="account"
link_to_id={$ae_loc.account_id}
bind:video_clip_file_kv={$ae_loc.files.video_clip_file_kv}
{log_lvl}
></Comp_hosted_files_clip_video_li>
{log_lvl}></Comp_hosted_files_clip_video_li>
{:else}
<p>Clip a video file first.</p>
{/if}

View File

@@ -50,64 +50,131 @@ export const GET: RequestHandler = async ({ url, fetch }) => {
}
// Default branding
const branding_name = site_domain?.account_name || site_domain?.name || "Aether";
const branding_name =
site_domain?.account_name || site_domain?.name || 'Aether';
const name = `One Sky IT - ${branding_name} Aether PWA`;
const short_name = `${site_domain?.account_code || site_domain?.code || 'Aether'} PWA`;
const background_color = site_domain?.cfg_json?.pwa_background_color || "hsl(220, 65%, 31%)";
const theme_color = "#3a5997";
const background_color =
site_domain?.cfg_json?.pwa_background_color || 'hsl(220, 65%, 31%)';
const theme_color = '#3a5997';
const manifest = {
"id": `ae-pwa-${fqdn}`, // Unique ID for this installation
"name": name,
"short_name": short_name,
"description": `The ${name} platform for unified event and documentation management.`,
"start_url": "/",
"scope": "/",
"display": "fullscreen",
"background_color": background_color,
"theme_color": theme_color,
"orientation": "any",
"categories": ["business", "productivity", "utilities"],
"icons": [
id: `ae-pwa-${fqdn}`, // Unique ID for this installation
name: name,
short_name: short_name,
description: `The ${name} platform for unified event and documentation management.`,
start_url: '/',
scope: '/',
display: 'fullscreen',
background_color: background_color,
theme_color: theme_color,
orientation: 'any',
categories: ['business', 'productivity', 'utilities'],
icons: [
// Standard Icons (Small/Med)
{ "sizes": "24x24", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_24px.png", "type": "image/png" },
{ "sizes": "48x48", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_48px.png", "type": "image/png" },
{ "sizes": "96x96", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_96px.png", "type": "image/png" },
{ "sizes": "144x144", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_144px.png", "type": "image/png" },
{ "sizes": "180x180", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_180px.png", "type": "image/png" },
{
sizes: '24x24',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_24px.png',
type: 'image/png'
},
{
sizes: '48x48',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_48px.png',
type: 'image/png'
},
{
sizes: '96x96',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_96px.png',
type: 'image/png'
},
{
sizes: '144x144',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_144px.png',
type: 'image/png'
},
{
sizes: '180x180',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_180px.png',
type: 'image/png'
},
// High-res Maskable Icons (WebP preferred for efficiency)
{ "sizes": "192x192", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_192px.webp", "type": "image/webp", "purpose": "any maskable" },
{ "sizes": "192x192", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_192px.png", "type": "image/png", "purpose": "any maskable" },
{ "sizes": "512x512", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_512px.webp", "type": "image/webp", "purpose": "any maskable" },
{ "sizes": "512x512", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_512px.png", "type": "image/png", "purpose": "any maskable" },
{ "sizes": "1024x1024", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_1024px.webp", "type": "image/webp", "purpose": "any maskable" },
{ "sizes": "1024x1024", "src": "https://static.oneskyit.com/images/OSIT_logo_2022_1024px.png", "type": "image/png", "purpose": "any maskable" }
],
// App Shortcuts (Long-press icon features)
"shortcuts": [
{
"name": "Journals",
"short_name": "Journals",
"description": "View and manage journal entries",
"url": "/journals",
"icons": [{ "src": "https://static.oneskyit.com/images/OSIT_logo_2022_192px.png", "sizes": "192x192" }]
sizes: '192x192',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_192px.webp',
type: 'image/webp',
purpose: 'any maskable'
},
{
"name": "Events",
"short_name": "Events",
"description": "Access active event management",
"url": "/events",
"icons": [{ "src": "https://static.oneskyit.com/images/OSIT_logo_2022_192px.png", "sizes": "192x192" }]
sizes: '192x192',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_192px.png',
type: 'image/png',
purpose: 'any maskable'
},
{
"name": "Testing",
"short_name": "Testing",
"description": "System diagnostic dashboard",
"url": "/testing",
"icons": [{ "src": "https://static.oneskyit.com/images/OSIT_logo_2022_192px.png", "sizes": "192x192" }]
sizes: '512x512',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_512px.webp',
type: 'image/webp',
purpose: 'any maskable'
},
{
sizes: '512x512',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_512px.png',
type: 'image/png',
purpose: 'any maskable'
},
{
sizes: '1024x1024',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_1024px.webp',
type: 'image/webp',
purpose: 'any maskable'
},
{
sizes: '1024x1024',
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_1024px.png',
type: 'image/png',
purpose: 'any maskable'
}
],
"testing": "One Sky IT"
// App Shortcuts (Long-press icon features)
shortcuts: [
{
name: 'Journals',
short_name: 'Journals',
description: 'View and manage journal entries',
url: '/journals',
icons: [
{
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_192px.png',
sizes: '192x192'
}
]
},
{
name: 'Events',
short_name: 'Events',
description: 'Access active event management',
url: '/events',
icons: [
{
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_192px.png',
sizes: '192x192'
}
]
},
{
name: 'Testing',
short_name: 'Testing',
description: 'System diagnostic dashboard',
url: '/testing',
icons: [
{
src: 'https://static.oneskyit.com/images/OSIT_logo_2022_192px.png',
sizes: '192x192'
}
]
}
],
testing: 'One Sky IT'
};
return json(manifest, {
@@ -116,4 +183,4 @@ export const GET: RequestHandler = async ({ url, fetch }) => {
'Cache-Control': 'public, max-age=3600'
}
});
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,85 +1,100 @@
<script lang="ts">
import AE_Obj_Field_Editor_V3 from '$lib/elements/element_ae_obj_field_editor.svelte';
import { ae_loc, ae_api } from '$lib/stores/ae_stores';
import { liveQuery } from 'dexie';
import { db_journals } from '$lib/ae_journals/db_journals';
import { load_ae_obj_id__journal } from '$lib/ae_journals/ae_journals__journal';
import { load_ae_obj_id__journal_entry } from '$lib/ae_journals/ae_journals__journal_entry';
import { Database, FileText, LoaderCircle, RefreshCw } from '@lucide/svelte';
import { onMount } from 'svelte';
import AE_Obj_Field_Editor_V3 from '$lib/elements/element_ae_obj_field_editor.svelte';
import { ae_loc, ae_api } from '$lib/stores/ae_stores';
import { liveQuery } from 'dexie';
import { db_journals } from '$lib/ae_journals/db_journals';
import { load_ae_obj_id__journal } from '$lib/ae_journals/ae_journals__journal';
import { load_ae_obj_id__journal_entry } from '$lib/ae_journals/ae_journals__journal_entry';
import { Database, FileText, LoaderCircle, RefreshCw } from '@lucide/svelte';
import { onMount } from 'svelte';
let log_lvl = $state(1);
let log_lvl = $state(1);
// Provided Test IDs
let test_journal_id = $state('SWFK-48-89-90'); // 'BVYE-94-46-29'
let test_journal_entry_id = $state('xRx-Y4-h3-fU');
// Provided Test IDs
let test_journal_id = $state('SWFK-48-89-90'); // 'BVYE-94-46-29'
let test_journal_entry_id = $state('xRx-Y4-h3-fU');
// Fetch objects from API on mount to ensure local DB is populated
onMount(async () => {
if (log_lvl) console.log('Test Page: Initializing data from server...');
try {
await Promise.all([
load_ae_obj_id__journal({
api_cfg: $ae_api,
journal_id: test_journal_id,
log_lvl
}),
load_ae_obj_id__journal_entry({
api_cfg: $ae_api,
journal_entry_id: test_journal_entry_id,
log_lvl
})
]);
} catch (e) {
console.error('Test Page: Error loading initial data', e);
}
});
// Dexie LiveQueries
let lq__test_journal = $derived(
liveQuery(async () => {
return await db_journals.journal.get(test_journal_id);
})
);
let lq__test_journal_entry = $derived(
liveQuery(async () => {
return await db_journals.journal_entry.get(test_journal_entry_id);
})
);
function handle_success(data: any) {
console.log('Test Page: Patch Success!', data);
// Fetch objects from API on mount to ensure local DB is populated
onMount(async () => {
if (log_lvl) console.log('Test Page: Initializing data from server...');
try {
await Promise.all([
load_ae_obj_id__journal({
api_cfg: $ae_api,
journal_id: test_journal_id,
log_lvl
}),
load_ae_obj_id__journal_entry({
api_cfg: $ae_api,
journal_entry_id: test_journal_entry_id,
log_lvl
})
]);
} catch (e) {
console.error('Test Page: Error loading initial data', e);
}
});
// Dexie LiveQueries
let lq__test_journal = $derived(
liveQuery(async () => {
return await db_journals.journal.get(test_journal_id);
})
);
let lq__test_journal_entry = $derived(
liveQuery(async () => {
return await db_journals.journal_entry.get(test_journal_entry_id);
})
);
function handle_success(data: any) {
console.log('Test Page: Patch Success!', data);
}
</script>
<div class="p-8 space-y-8 max-w-6xl mx-auto h-full overflow-y-auto">
<header class="border-b border-surface-500/30 pb-4 flex justify-between items-center">
<div class="mx-auto h-full max-w-6xl space-y-8 overflow-y-auto p-8">
<header
class="border-surface-500/30 flex items-center justify-between border-b pb-4">
<div>
<h1 class="h1">AE Obj Field Editor V3 Test</h1>
<p class="opacity-70 font-mono text-xs">IDs: Journal={test_journal_id} | Entry={test_journal_entry_id}</p>
<p class="font-mono text-xs opacity-70">
IDs: Journal={test_journal_id} | Entry={test_journal_entry_id}
</p>
</div>
<div class="flex items-center gap-4">
<label class="flex items-center gap-2 cursor-pointer bg-surface-200 dark:bg-surface-800 px-3 py-1.5 rounded-full shadow-inner">
<span class="text-xs font-bold uppercase opacity-70">Edit Mode</span>
<input type="checkbox" bind:checked={$ae_loc.edit_mode} class="checkbox" />
<label
class="bg-surface-200 dark:bg-surface-800 flex cursor-pointer items-center gap-2 rounded-full px-3 py-1.5 shadow-inner">
<span class="text-xs font-bold uppercase opacity-70"
>Edit Mode</span>
<input
type="checkbox"
bind:checked={$ae_loc.edit_mode}
class="checkbox" />
</label>
<button class="btn variant-filled-primary" onclick={() => window.location.reload()}>
<button
class="btn variant-filled-primary"
onclick={() => window.location.reload()}>
<RefreshCw size="1em" class="mr-2" /> Reload Page
</button>
</div>
</header>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div class="grid grid-cols-1 gap-8 lg:grid-cols-2">
<!-- COLUMN 1: JOURNAL TEST -->
<div class="space-y-8">
<h2 class="h2 flex items-center gap-2"><Database /> Journal Properties</h2>
<h2 class="h2 flex items-center gap-2">
<Database /> Journal Properties
</h2>
{#if $lq__test_journal}
<section class="card p-6 space-y-6 variant-soft-primary shadow-lg border border-primary-500/20">
<section
class="card variant-soft-primary border-primary-500/20 space-y-6 border p-6 shadow-lg">
<div class="field_group">
<label for="j_name" class="label text-xs font-bold opacity-50 mb-1 uppercase tracking-tighter">Journal Name</label>
<label
for="j_name"
class="label mb-1 text-xs font-bold tracking-tighter uppercase opacity-50"
>Journal Name</label>
<AE_Obj_Field_Editor_V3
id="j_name"
object_type="journal"
@@ -88,12 +103,14 @@
bind:current_value={$lq__test_journal.name}
field_type="text"
{log_lvl}
on_success={handle_success}
/>
on_success={handle_success} />
</div>
<div class="field_group">
<label for="j_type" class="label text-xs font-bold opacity-50 mb-1 uppercase tracking-tighter">Type Code</label>
<label
for="j_type"
class="label mb-1 text-xs font-bold tracking-tighter uppercase opacity-50"
>Type Code</label>
<AE_Obj_Field_Editor_V3
id="j_type"
object_type="journal"
@@ -102,17 +119,19 @@
bind:current_value={$lq__test_journal.type_code}
field_type="select"
select_options={{
'personal': 'Personal Journal',
'work': 'Work Log',
'shared': 'Shared Notes',
'ai_brain': 'AI Context'
personal: 'Personal Journal',
work: 'Work Log',
shared: 'Shared Notes',
ai_brain: 'AI Context'
}}
{log_lvl}
/>
{log_lvl} />
</div>
<div class="field_group">
<label for="j_summary" class="label text-xs font-bold opacity-50 mb-1 uppercase tracking-tighter">Summary</label>
<label
for="j_summary"
class="label mb-1 text-xs font-bold tracking-tighter uppercase opacity-50"
>Summary</label>
<AE_Obj_Field_Editor_V3
id="j_summary"
object_type="journal"
@@ -121,26 +140,34 @@
bind:current_value={$lq__test_journal.summary}
field_type="textarea"
display_block={true}
{log_lvl}
/>
{log_lvl} />
</div>
</section>
{:else}
<div class="card p-10 flex flex-col items-center justify-center opacity-50 gap-4 variant-soft-surface">
<div
class="card variant-soft-surface flex flex-col items-center justify-center gap-4 p-10 opacity-50">
<LoaderCircle size="32" class="animate-spin" />
<p class="text-sm font-bold">Loading Journal {test_journal_id}...</p>
<p class="text-sm font-bold">
Loading Journal {test_journal_id}...
</p>
</div>
{/if}
</div>
<!-- COLUMN 2: JOURNAL ENTRY TEST -->
<div class="space-y-8">
<h2 class="h2 flex items-center gap-2"><FileText /> Journal Entry Properties</h2>
<h2 class="h2 flex items-center gap-2">
<FileText /> Journal Entry Properties
</h2>
{#if $lq__test_journal_entry}
<section class="card p-6 space-y-6 variant-soft-secondary shadow-lg border border-secondary-500/20">
<section
class="card variant-soft-secondary border-secondary-500/20 space-y-6 border p-6 shadow-lg">
<div class="field_group">
<label for="e_name" class="label text-xs font-bold opacity-50 mb-1 uppercase tracking-tighter">Entry Title</label>
<label
for="e_name"
class="label mb-1 text-xs font-bold tracking-tighter uppercase opacity-50"
>Entry Title</label>
<AE_Obj_Field_Editor_V3
id="e_name"
object_type="journal_entry"
@@ -148,39 +175,49 @@
field_name="name"
bind:current_value={$lq__test_journal_entry.name}
field_type="text"
{log_lvl}
/>
{log_lvl} />
</div>
<div class="grid grid-cols-2 gap-4">
<div class="field_group">
<label for="e_enabled" class="label text-xs font-bold opacity-50 mb-1 uppercase tracking-tighter">Status</label>
<label
for="e_enabled"
class="label mb-1 text-xs font-bold tracking-tighter uppercase opacity-50"
>Status</label>
<AE_Obj_Field_Editor_V3
id="e_enabled"
object_type="journal_entry"
object_id={test_journal_entry_id}
field_name="enable"
bind:current_value={$lq__test_journal_entry.enable}
bind:current_value={
$lq__test_journal_entry.enable
}
field_type="checkbox"
{log_lvl}
/>
{log_lvl} />
</div>
<div class="field_group">
<label for="e_priority" class="label text-xs font-bold opacity-50 mb-1 uppercase tracking-tighter">Priority</label>
<label
for="e_priority"
class="label mb-1 text-xs font-bold tracking-tighter uppercase opacity-50"
>Priority</label>
<AE_Obj_Field_Editor_V3
id="e_priority"
object_type="journal_entry"
object_id={test_journal_entry_id}
field_name="priority"
bind:current_value={$lq__test_journal_entry.priority}
bind:current_value={
$lq__test_journal_entry.priority
}
field_type="checkbox"
{log_lvl}
/>
{log_lvl} />
</div>
</div>
<div class="field_group">
<p class="label text-xs font-bold opacity-50 mb-1 uppercase tracking-tighter">Content (TipTap)</p>
<p
class="label mb-1 text-xs font-bold tracking-tighter uppercase opacity-50">
Content (TipTap)
</p>
<AE_Obj_Field_Editor_V3
object_type="journal_entry"
object_id={test_journal_entry_id}
@@ -188,34 +225,40 @@
bind:current_value={$lq__test_journal_entry.content}
field_type="tiptap"
display_block={true}
{log_lvl}
/>
{log_lvl} />
</div>
</section>
{:else}
<div class="card p-10 flex flex-col items-center justify-center opacity-50 gap-4 variant-soft-surface">
<div
class="card variant-soft-surface flex flex-col items-center justify-center gap-4 p-10 opacity-50">
<LoaderCircle size="32" class="animate-spin" />
<p class="text-sm font-bold">Loading Entry {test_journal_entry_id}...</p>
<p class="text-sm font-bold">
Loading Entry {test_journal_entry_id}...
</p>
</div>
{/if}
</div>
</div>
<!-- DEBUG FOOTER -->
<section class="card p-4 space-y-4">
<section class="card space-y-4 p-4">
<h2 class="h3">Debug Context</h2>
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4 text-xs font-mono">
<div class="bg-surface-900 text-success-500 p-2 rounded">
<strong>Edit Mode:</strong> {$ae_loc.edit_mode}
<div class="grid grid-cols-2 gap-4 font-mono text-xs lg:grid-cols-4">
<div class="bg-surface-900 text-success-500 rounded p-2">
<strong>Edit Mode:</strong>
{$ae_loc.edit_mode}
</div>
<div class="bg-surface-900 text-success-500 p-2 rounded">
<strong>Account ID:</strong> {$ae_loc.account_id}
<div class="bg-surface-900 text-success-500 rounded p-2">
<strong>Account ID:</strong>
{$ae_loc.account_id}
</div>
<div class="bg-surface-900 text-success-500 p-2 rounded">
<strong>Journal Status:</strong> {$lq__test_journal ? 'Cached' : 'Pending'}
<div class="bg-surface-900 text-success-500 rounded p-2">
<strong>Journal Status:</strong>
{$lq__test_journal ? 'Cached' : 'Pending'}
</div>
<div class="bg-surface-900 text-success-500 p-2 rounded">
<strong>Entry Status:</strong> {$lq__test_journal_entry ? 'Cached' : 'Pending'}
<div class="bg-surface-900 text-success-500 rounded p-2">
<strong>Entry Status:</strong>
{$lq__test_journal_entry ? 'Cached' : 'Pending'}
</div>
</div>
</section>

View File

@@ -1,122 +1,141 @@
<script lang="ts">
import AE_Element_Data_Store from '$lib/elements/element_data_store.svelte';
import { ae_loc } from '$lib/stores/ae_stores';
import { db_core } from '$lib/ae_core/db_core';
import { RefreshCw, Trash2 } from '@lucide/svelte';
// let test_code_global = 'hub__site__root_page_header'; // Expected to be a global default
// let test_name_global = 'Global Header Test - hub__site__root_page_header';
// let test_code_account = 'hub__site__root_page_header';
// let test_name_account = 'Account Header Test - hub__site__root_page_header';
// let test_code_specific = 'event_launcher_main_info';
// let test_name_specific = 'Event Specific Test - event_launcher_main_info';
import AE_Element_Data_Store from '$lib/elements/element_data_store.svelte';
import { ae_loc } from '$lib/stores/ae_stores';
import { db_core } from '$lib/ae_core/db_core';
import { RefreshCw, Trash2 } from '@lucide/svelte';
// let test_code_global = 'hub__site__root_page_header'; // Expected to be a global default
// let test_name_global = 'Global Header Test - hub__site__root_page_header';
// let test_code_account = 'hub__site__root_page_header';
// let test_name_account = 'Account Header Test - hub__site__root_page_header';
// let test_code_specific = 'event_launcher_main_info';
// let test_name_specific = 'Event Specific Test - event_launcher_main_info';
let test_null_act_and_for = 'events__leads__overview'; // Expecting the Global Default
let test_code_account = 'hub__site__root_page_header'; // Expecting the Account Default
let test_code_and_for = 'event_launcher_main_info'; // Expecting the Specific Record (Event ID)
let testing_event_id = 'pjrcghqwert'; // Per README test data
let test_null_act_and_for = 'events__leads__overview'; // Expecting the Global Default
let test_code_account = 'hub__site__root_page_header'; // Expecting the Account Default
let test_code_and_for = 'event_launcher_main_info'; // Expecting the Specific Record (Event ID)
let testing_event_id = 'pjrcghqwert'; // Per README test data
let log_lvl = $state(0);
let refresh_trigger = $state(0);
async function clear_cache() {
if (log_lvl) console.log('Asking to confirm clearing Data Store cache...');
let log_lvl = $state(0);
let refresh_trigger = $state(0);
async function clear_cache() {
if (log_lvl) console.log('Asking to confirm clearing Data Store cache...');
if (confirm('Are you sure you want to clear the local Data Store cache?')) {
await db_core.data_store.clear();
refresh_trigger++;
alert('Cache cleared.');
}
if (confirm('Are you sure you want to clear the local Data Store cache?')) {
await db_core.data_store.clear();
refresh_trigger++;
alert('Cache cleared.');
}
}
</script>
<div class="p-8 space-y-8 max-w-4xl mx-auto h-full overflow-y-auto">
<header class="border-b border-surface-500/30 pb-4 flex justify-between items-center">
<div class="mx-auto h-full max-w-4xl space-y-8 overflow-y-auto p-8">
<header
class="border-surface-500/30 flex items-center justify-between border-b pb-4">
<div>
<h1 class="h1">Data Store V3 Test Page</h1>
<p class="opacity-70">Testing cascading lookup: Specific &rarr; Account &rarr; Global</p>
<p class="opacity-70">
Testing cascading lookup: Specific &rarr; Account &rarr; Global
</p>
</div>
<div class="flex gap-2">
<button class="btn variant-filled-warning" onclick={clear_cache}>
<Trash2 size="1em" class="mr-2" /> Clear Cache
</button>
<button class="btn variant-filled-primary" onclick={() => refresh_trigger++}>
<button
class="btn variant-filled-primary"
onclick={() => refresh_trigger++}>
<RefreshCw size="1em" class="mr-2" /> Force Refresh
</button>
</div>
</header>
{#key refresh_trigger}
<section class="card p-4 space-y-4 variant-soft-primary">
<h2 class="h3">Scenario 1: Global Default</h2>
<p class="text-sm">Fetching code <code>{test_null_act_and_for}</code>. Should fall back to <code>account_id = NULL</code> if not found for account.</p>
<div class="bg-surface-100 dark:bg-surface-800 p-4 rounded-lg border border-surface-500/20">
<AE_Element_Data_Store
ds_code={test_null_act_and_for}
ds_name={'Global Default Test'}
{log_lvl}
debug={true}
/>
</div>
</section>
<section class="card variant-soft-primary space-y-4 p-4">
<h2 class="h3">Scenario 1: Global Default</h2>
<p class="text-sm">
Fetching code <code>{test_null_act_and_for}</code>. Should fall
back to <code>account_id = NULL</code> if not found for account.
</p>
<div
class="bg-surface-100 dark:bg-surface-800 border-surface-500/20 rounded-lg border p-4">
<AE_Element_Data_Store
ds_code={test_null_act_and_for}
ds_name={'Global Default Test'}
{log_lvl}
debug={true} />
</div>
</section>
<section class="card p-4 space-y-4 variant-soft-secondary">
<h2 class="h3">Scenario 2: Account Default</h2>
<p class="text-sm">Fetching code <code>{test_code_account}</code> for Account ID: <code>{$ae_loc.account_id}</code>.</p>
<div class="bg-surface-100 dark:bg-surface-800 p-4 rounded-lg border border-surface-500/20">
<AE_Element_Data_Store
ds_code={test_code_account}
ds_name={'Account Default Test'}
{log_lvl}
debug={true}
/>
</div>
</section>
<section class="card variant-soft-secondary space-y-4 p-4">
<h2 class="h3">Scenario 2: Account Default</h2>
<p class="text-sm">
Fetching code <code>{test_code_account}</code> for Account ID:
<code>{$ae_loc.account_id}</code>.
</p>
<div
class="bg-surface-100 dark:bg-surface-800 border-surface-500/20 rounded-lg border p-4">
<AE_Element_Data_Store
ds_code={test_code_account}
ds_name={'Account Default Test'}
{log_lvl}
debug={true} />
</div>
</section>
<section class="card p-4 space-y-4 variant-soft-tertiary">
<h2 class="h3">Scenario 3: Specific Record (Event Override)</h2>
<p class="text-sm">Fetching code <code>{test_code_and_for}</code> linked to <code>for_type: event</code> and <code>for_id: {testing_event_id}</code>.</p>
<div class="bg-surface-100 dark:bg-surface-800 p-4 rounded-lg border border-surface-500/20">
<AE_Element_Data_Store
ds_code={test_code_and_for}
ds_name={'Specific Record Test'}
for_type="event"
for_id={testing_event_id}
{log_lvl}
debug={true}
/>
</div>
</section>
<section class="card variant-soft-tertiary space-y-4 p-4">
<h2 class="h3">Scenario 3: Specific Record (Event Override)</h2>
<p class="text-sm">
Fetching code <code>{test_code_and_for}</code> linked to
<code>for_type: event</code>
and <code>for_id: {testing_event_id}</code>.
</p>
<div
class="bg-surface-100 dark:bg-surface-800 border-surface-500/20 rounded-lg border p-4">
<AE_Element_Data_Store
ds_code={test_code_and_for}
ds_name={'Specific Record Test'}
for_type="event"
for_id={testing_event_id}
{log_lvl}
debug={true} />
</div>
</section>
<section class="card p-4 space-y-4 variant-soft-tertiary">
<h2 class="h3">Scenario 4: Change Props Passed</h2>
<p class="text-sm">Fetching code <code>{test_code_and_for}</code> linked to <code>for_type: event</code> and <code>for_id: {testing_event_id}</code>.</p>
<div class="bg-surface-100 dark:bg-surface-800 p-4 rounded-lg border border-surface-500/20">
<AE_Element_Data_Store
ds_code={test_code_and_for}
ds_name={'Specific Record Test'}
ds_type="html"
for_type="event"
for_id={testing_event_id}
class_li="w-fit max-w-(--breakpoint-lg) text-xl text-red-500 font-bold text-center p-1 m-1 border border-red-200 rounded-md bg-red-100"
show_edit={false}
show_edit_btn={true}
{log_lvl}
debug={true}
/>
</div>
</section>
<section class="card variant-soft-tertiary space-y-4 p-4">
<h2 class="h3">Scenario 4: Change Props Passed</h2>
<p class="text-sm">
Fetching code <code>{test_code_and_for}</code> linked to
<code>for_type: event</code>
and <code>for_id: {testing_event_id}</code>.
</p>
<div
class="bg-surface-100 dark:bg-surface-800 border-surface-500/20 rounded-lg border p-4">
<AE_Element_Data_Store
ds_code={test_code_and_for}
ds_name={'Specific Record Test'}
ds_type="html"
for_type="event"
for_id={testing_event_id}
class_li="w-fit max-w-(--breakpoint-lg) text-xl text-red-500 font-bold text-center p-1 m-1 border border-red-200 rounded-md bg-red-100"
show_edit={false}
show_edit_btn={true}
{log_lvl}
debug={true} />
</div>
</section>
{/key}
<section class="card p-4 space-y-4">
<section class="card space-y-4 p-4">
<h2 class="h3">Current Context</h2>
<div class="grid grid-cols-2 gap-4 text-xs font-mono">
<div class="bg-surface-900 text-success-500 p-2 rounded">
<strong>Account ID:</strong> {$ae_loc.account_id || 'NULL'}
<div class="grid grid-cols-2 gap-4 font-mono text-xs">
<div class="bg-surface-900 text-success-500 rounded p-2">
<strong>Account ID:</strong>
{$ae_loc.account_id || 'NULL'}
</div>
<div class="bg-surface-900 text-success-500 p-2 rounded">
<strong>Edit Mode:</strong> {$ae_loc.edit_mode}
<div class="bg-surface-900 text-success-500 rounded p-2">
<strong>Edit Mode:</strong>
{$ae_loc.edit_mode}
</div>
</div>
</section>

View File

@@ -1,20 +1,24 @@
<script lang="ts">
import AE_Comp_Editor_TipTap from '$lib/elements/element_editor_tiptap.svelte';
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';
import { Code, Eye } from '@lucide/svelte';
let test_content = $state('<h2>Welcome to the Visual Editor Test</h2><p>This editor uses <strong>native browser rich text</strong> capabilities.</p><ul><li>No library conflicts</li><li>Uses existing <em>.tiptap</em> styles</li><li>Instant performance</li></ul>');
let log_lvl = 1;
import AE_Comp_Editor_TipTap from '$lib/elements/element_editor_tiptap.svelte';
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';
import { Code, Eye } from '@lucide/svelte';
let test_content = $state(
'<h2>Welcome to the Visual Editor Test</h2><p>This editor uses <strong>native browser rich text</strong> capabilities.</p><ul><li>No library conflicts</li><li>Uses existing <em>.tiptap</em> styles</li><li>Instant performance</li></ul>'
);
let log_lvl = 1;
</script>
<div class="p-8 space-y-8 max-w-5xl mx-auto h-full overflow-y-auto">
<header class="border-b border-surface-500/30 pb-4">
<div class="mx-auto h-full max-w-5xl space-y-8 overflow-y-auto p-8">
<header class="border-surface-500/30 border-b pb-4">
<h1 class="h1">Rich Text Editor Test</h1>
<p class="opacity-70">Testing the Zero-Dependency "TipTap" replacement.</p>
<p class="opacity-70">
Testing the Zero-Dependency "TipTap" replacement.
</p>
</header>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div class="grid grid-cols-1 gap-8 lg:grid-cols-2">
<!-- Visual Editor -->
<section class="card p-4 space-y-4 variant-soft-primary">
<section class="card variant-soft-primary space-y-4 p-4">
<h2 class="h3 flex items-center gap-2">
<Eye size="1em" class="text-primary-500" />
Visual Editor (AE_Comp_Editor_TipTap)
@@ -22,30 +26,33 @@
<div class="bg-surface-100 dark:bg-surface-800 rounded-lg">
<AE_Comp_Editor_TipTap
bind:content={test_content}
placeholder="Try writing something pretty..."
/>
placeholder="Try writing something pretty..." />
</div>
</section>
<!-- Source Code View -->
<section class="card p-4 space-y-4 variant-soft-tertiary">
<section class="card variant-soft-tertiary space-y-4 p-4">
<h2 class="h3 flex items-center gap-2">
<Code size="1em" class="text-tertiary-500" />
Source View (AE_Comp_Editor_CodeMirror)
</h2>
<div class="bg-surface-100 dark:bg-surface-800 rounded-lg h-[250px]">
<div
class="bg-surface-100 dark:bg-surface-800 h-[250px] rounded-lg">
<AE_Comp_Editor_CodeMirror
bind:content={test_content}
language="html"
show_line_numbers={true}
/>
show_line_numbers={true} />
</div>
</section>
</div>
<!-- HTML Preview -->
<section class="card p-4 space-y-4 bg-surface-900 text-green-400 font-mono text-xs overflow-auto max-h-96 shadow-2xl border border-white/10">
<h2 class="text-sm font-bold opacity-50 uppercase tracking-widest border-b border-white/10 pb-2">Raw Bound Content (Saved to DB)</h2>
<section
class="card bg-surface-900 max-h-96 space-y-4 overflow-auto border border-white/10 p-4 font-mono text-xs text-green-400 shadow-2xl">
<h2
class="border-b border-white/10 pb-2 text-sm font-bold tracking-widest uppercase opacity-50">
Raw Bound Content (Saved to DB)
</h2>
<pre class="whitespace-pre">{test_content}</pre>
</section>
</div>

View File

@@ -1,71 +1,76 @@
<script lang="ts">
import { onMount } from 'svelte';
import { onMount } from 'svelte';
let status: string[] = $state([]);
let status: string[] = $state([]);
function log(msg: string) {
status = [...status, `${new Date().toLocaleTimeString()} - ${msg}`];
console.log(`[FIX-SW] ${msg}`);
function log(msg: string) {
status = [...status, `${new Date().toLocaleTimeString()} - ${msg}`];
console.log(`[FIX-SW] ${msg}`);
}
async function nukeServiceWorkers() {
log('Starting Service Worker cleanup...');
if (!('serviceWorker' in navigator)) {
log('Service Workers not supported in this browser.');
return;
}
async function nukeServiceWorkers() {
log('Starting Service Worker cleanup...');
try {
const registrations = await navigator.serviceWorker.getRegistrations();
log(`Found ${registrations.length} registrations.`);
if (!('serviceWorker' in navigator)) {
log('Service Workers not supported in this browser.');
return;
for (const registration of registrations) {
const scope = registration.scope;
log(`Unregistering SW at scope: ${scope}`);
const success = await registration.unregister();
log(`Unregister success: ${success}`);
}
try {
const registrations = await navigator.serviceWorker.getRegistrations();
log(`Found ${registrations.length} registrations.`);
for (const registration of registrations) {
const scope = registration.scope;
log(`Unregistering SW at scope: ${scope}`);
const success = await registration.unregister();
log(`Unregister success: ${success}`);
}
if (registrations.length === 0) {
log('No active Service Workers found.');
}
log('Clearing Cache Storage...');
const cacheKeys = await caches.keys();
for (const key of cacheKeys) {
log(`Deleting cache: ${key}`);
await caches.delete(key);
}
log('Cache storage cleared.');
log('DONE. Please reload the application now.');
} catch (err: any) {
log(`ERROR: ${err.message}`);
console.error(err);
if (registrations.length === 0) {
log('No active Service Workers found.');
}
log('Clearing Cache Storage...');
const cacheKeys = await caches.keys();
for (const key of cacheKeys) {
log(`Deleting cache: ${key}`);
await caches.delete(key);
}
log('Cache storage cleared.');
log('DONE. Please reload the application now.');
} catch (err: any) {
log(`ERROR: ${err.message}`);
console.error(err);
}
}
onMount(() => {
nukeServiceWorkers();
});
onMount(() => {
nukeServiceWorkers();
});
</script>
<div class="p-8 max-w-2xl mx-auto font-mono">
<h1 class="text-2xl font-bold mb-4 text-red-600">Service Worker Reset Tool</h1>
<p class="mb-4">Attempting to unregister all service workers and clear caches to fix the TypeError loop.</p>
<div class="mx-auto max-w-2xl p-8 font-mono">
<h1 class="mb-4 text-2xl font-bold text-red-600">
Service Worker Reset Tool
</h1>
<p class="mb-4">
Attempting to unregister all service workers and clear caches to fix the
TypeError loop.
</p>
<div class="bg-gray-100 p-4 rounded border border-gray-300 min-h-[200px]">
<div class="min-h-[200px] rounded border border-gray-300 bg-gray-100 p-4">
{#each status as line, i (i)}
<div class="border-b border-gray-200 last:border-0 py-1">{line}</div>
<div class="border-b border-gray-200 py-1 last:border-0">
{line}
</div>
{/each}
</div>
<button
class="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
onclick={() => window.location.reload()}
>
class="mt-4 rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
onclick={() => window.location.reload()}>
Reload Page
</button>
</div>

View File

@@ -1,128 +1,151 @@
<script lang="ts">
import { onMount } from 'svelte';
import { ae_api, ae_loc } from '$lib/stores/ae_stores';
import { load_ae_obj_id__hosted_file } from '$lib/ae_core/core__hosted_files';
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
import * as Lucide from 'lucide-svelte';
import { onMount } from 'svelte';
import { ae_api, ae_loc } from '$lib/stores/ae_stores';
import { load_ae_obj_id__hosted_file } from '$lib/ae_core/core__hosted_files';
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
import * as Lucide from 'lucide-svelte';
let hosted_files: any[] = $state([]);
let large_file_obj: any = $state(null);
let loading = $state(true);
let hosted_files: any[] = $state([]);
let large_file_obj: any = $state(null);
let loading = $state(true);
// Testing Toggles
let test_direct_download = $state(false);
// Testing Toggles
let test_direct_download = $state(false);
const LARGE_FILE_ID = 'sPw1he_RGCW';
const test_ids = [
'QpyZNtEb2LQBmNJPQU_aOA', // small.mp4
'ZmMTrrqx8nTTY0Cj0wvA3Q', // Test PowerPoint video.pptx
'e7NcV-275YPLQLoFMWuUZw', // Test PDF.pdf
'INVALID_ID_TEST'
];
const LARGE_FILE_ID = 'sPw1he_RGCW';
const test_ids = [
'QpyZNtEb2LQBmNJPQU_aOA', // small.mp4
'ZmMTrrqx8nTTY0Cj0wvA3Q', // Test PowerPoint video.pptx
'e7NcV-275YPLQLoFMWuUZw', // Test PDF.pdf
'INVALID_ID_TEST'
];
onMount(async () => {
// Load the large file specifically first
large_file_obj = await load_ae_obj_id__hosted_file({
api_cfg: $ae_api,
hosted_file_id: LARGE_FILE_ID,
log_lvl: 1
});
// Fallback for large file if API doesn't have it (for UI testing)
if (!large_file_obj) {
large_file_obj = {
id: LARGE_FILE_ID,
hosted_file_id: LARGE_FILE_ID,
filename: 'Large_Test_File_Fallback.zip',
extension: 'zip',
hash_sha256: 'pending...'
};
}
const promises = test_ids.map(id =>
load_ae_obj_id__hosted_file({
api_cfg: $ae_api,
hosted_file_id: id,
log_lvl: 1
})
);
const results = await Promise.all(promises);
hosted_files = results.filter((f: any) => f !== null) as any[];
// Add a fake object for the invalid ID test
hosted_files.push({
id: 'INVALID_ID_TEST',
hosted_file_id: 'INVALID_ID_TEST',
filename: 'non_existent_file.txt',
extension: 'txt',
hash_sha256: '0000000000'
});
loading = false;
onMount(async () => {
// Load the large file specifically first
large_file_obj = await load_ae_obj_id__hosted_file({
api_cfg: $ae_api,
hosted_file_id: LARGE_FILE_ID,
log_lvl: 1
});
// Fallback for large file if API doesn't have it (for UI testing)
if (!large_file_obj) {
large_file_obj = {
id: LARGE_FILE_ID,
hosted_file_id: LARGE_FILE_ID,
filename: 'Large_Test_File_Fallback.zip',
extension: 'zip',
hash_sha256: 'pending...'
};
}
const promises = test_ids.map((id) =>
load_ae_obj_id__hosted_file({
api_cfg: $ae_api,
hosted_file_id: id,
log_lvl: 1
})
);
const results = await Promise.all(promises);
hosted_files = results.filter((f: any) => f !== null) as any[];
// Add a fake object for the invalid ID test
hosted_files.push({
id: 'INVALID_ID_TEST',
hosted_file_id: 'INVALID_ID_TEST',
filename: 'non_existent_file.txt',
extension: 'txt',
hash_sha256: '0000000000'
});
loading = false;
});
</script>
<!-- Outer wrapper to enable scrolling if parent is overflow-hidden -->
<div class="h-full w-full overflow-y-auto overflow-x-hidden bg-transparent">
<div class="container mx-auto p-4 space-y-8 pb-20">
<header class="flex flex-col md:flex-row justify-between items-start md:items-center bg-surface-50-900-token p-6 rounded-container shadow-xl border border-gray-500 gap-4">
<div class="h-full w-full overflow-x-hidden overflow-y-auto bg-transparent">
<div class="container mx-auto space-y-8 p-4 pb-20">
<header
class="bg-surface-50-900-token rounded-container flex flex-col items-start justify-between gap-4 border border-gray-500 p-6 shadow-xl md:flex-row md:items-center">
<div class="space-y-1">
<h1 class="h1 flex items-center gap-3">
<Lucide.Download class="text-primary-500" /> Hosted Files Testing
</h1>
<p class="opacity-60 text-sm">Testing the AE_Comp_Hosted_Files_Download_Button component</p>
<p class="text-sm opacity-60">
Testing the AE_Comp_Hosted_Files_Download_Button component
</p>
</div>
<div class="flex flex-wrap gap-3 items-center bg-black/20 p-3 rounded-lg border border-white/10">
<div class="flex items-center gap-2 pr-3 border-r border-white/10">
<span class="text-[10px] font-bold uppercase opacity-50">Edit Mode</span>
<span class="badge {$ae_loc.edit_mode ? 'variant-filled-success' : 'variant-filled-surface'}">
<div
class="flex flex-wrap items-center gap-3 rounded-lg border border-white/10 bg-black/20 p-3">
<div
class="flex items-center gap-2 border-r border-white/10 pr-3">
<span class="text-[10px] font-bold uppercase opacity-50"
>Edit Mode</span>
<span
class="badge {$ae_loc.edit_mode
? 'variant-filled-success'
: 'variant-filled-surface'}">
{$ae_loc.edit_mode ? 'ON' : 'OFF'}
</span>
</div>
<div class="flex items-center gap-3">
<span class="text-[10px] font-bold uppercase opacity-50">Direct Download</span>
<span class="text-[10px] font-bold uppercase opacity-50"
>Direct Download</span>
<button
class="btn btn-sm {test_direct_download ? 'variant-filled-primary' : 'variant-soft-surface'}"
onclick={() => test_direct_download = !test_direct_download}
>
{test_direct_download ? 'Anchor Mode (<a>)' : 'Action Mode (<button>)'}
class="btn btn-sm {test_direct_download
? 'variant-filled-primary'
: 'variant-soft-surface'}"
onclick={() =>
(test_direct_download = !test_direct_download)}>
{test_direct_download
? 'Anchor Mode (<a>)'
: 'Action Mode (<button>)'}
</button>
</div>
</div>
</header>
<!-- Dedicated Large File Section -->
<div class="card p-6 variant-soft-primary border-2 border-primary-500 shadow-xl space-y-4">
<header class="flex justify-between items-center border-b border-primary-500/30 pb-2">
<div
class="card variant-soft-primary border-primary-500 space-y-4 border-2 p-6 shadow-xl">
<header
class="border-primary-500/30 flex items-center justify-between border-b pb-2">
<h2 class="h2 flex items-center gap-2">
<Lucide.Zap class="text-warning-500" /> Large File Progress Test
</h2>
<div class="flex gap-2">
<span class="badge variant-filled-warning animate-pulse">Testing Percentage</span>
<span class="badge variant-filled-warning animate-pulse"
>Testing Percentage</span>
{#if test_direct_download}
<span class="badge variant-filled-secondary">Direct Link</span>
<span class="badge variant-filled-secondary"
>Direct Link</span>
{/if}
</div>
</header>
<p class="text-sm opacity-80 italic">
Use this file to verify the <strong>percentage counter</strong> and <strong>loading spinner</strong>.
This file is ~100MB+, which should provide ample time to observe the progress state.
<p class="text-sm italic opacity-80">
Use this file to verify the <strong>percentage counter</strong>
and <strong>loading spinner</strong>. This file is ~100MB+,
which should provide ample time to observe the progress state.
</p>
{#if large_file_obj}
<div class="bg-black/20 p-4 rounded-container border border-primary-500/20 flex flex-col md:flex-row justify-between items-center gap-4">
<div
class="rounded-container border-primary-500/20 flex flex-col items-center justify-between gap-4 border bg-black/20 p-4 md:flex-row">
<div class="flex items-center gap-4">
<div class="p-3 bg-primary-500/20 rounded-lg">
<div class="bg-primary-500/20 rounded-lg p-3">
<Lucide.FileArchive size={32} />
</div>
<div>
<h3 class="font-bold text-lg">{large_file_obj.filename}</h3>
<p class="text-xs font-mono opacity-50">ID: {LARGE_FILE_ID}</p>
<h3 class="text-lg font-bold">
{large_file_obj.filename}
</h3>
<p class="font-mono text-xs opacity-50">
ID: {LARGE_FILE_ID}
</p>
</div>
</div>
@@ -133,95 +156,112 @@
show_direct_download={test_direct_download}
variant="filled"
color="primary"
classes="w-full md:min-w-64 py-4"
/>
classes="w-full md:min-w-64 py-4" />
</div>
</div>
{/if}
</div>
<div class="card p-6 variant-soft-surface space-y-4 border border-gray-500 shadow-lg">
<div
class="card variant-soft-surface space-y-4 border border-gray-500 p-6 shadow-lg">
<h2 class="h2">Style & Variant Trials</h2>
{#if loading}
<div class="flex items-center gap-2 py-10 justify-center">
<div class="flex items-center justify-center gap-2 py-10">
<Lucide.LoaderCircle class="animate-spin" />
<span>Loading test metadata gallery...</span>
</div>
{:else}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
{#each hosted_files as file (file.id)}
<div class="card p-4 variant-soft-secondary space-y-4">
<div class="flex justify-between items-start">
<div class="card variant-soft-secondary space-y-4 p-4">
<div class="flex items-start justify-between">
<div>
<h3 class="font-bold">{file.filename}</h3>
<p class="text-xs opacity-60 font-mono">ID: {file.id}</p>
<p class="font-mono text-xs opacity-60">
ID: {file.id}
</p>
</div>
<span class="badge variant-filled-primary uppercase">{file.extension}</span>
<span
class="badge variant-filled-primary uppercase"
>{file.extension}</span>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 pt-2">
<div
class="grid grid-cols-1 gap-4 pt-2 sm:grid-cols-2">
<div class="space-y-1">
<p class="text-[10px] opacity-50 uppercase font-bold">Variant: Tonal</p>
<p
class="text-[10px] font-bold uppercase opacity-50">
Variant: Tonal
</p>
<AE_Comp_Hosted_Files_Download_Button
hosted_file_id={file.id}
hosted_file_obj={file}
show_direct_download={test_direct_download}
variant="tonal"
color="primary"
classes="w-full"
/>
classes="w-full" />
</div>
<div class="space-y-1">
<p class="text-[10px] opacity-50 uppercase font-bold">Variant: Filled</p>
<p
class="text-[10px] font-bold uppercase opacity-50">
Variant: Filled
</p>
<AE_Comp_Hosted_Files_Download_Button
hosted_file_id={file.id}
hosted_file_obj={file}
show_direct_download={test_direct_download}
variant="filled"
color="secondary"
classes="w-full"
/>
classes="w-full" />
</div>
<div class="space-y-1">
<p class="text-[10px] opacity-50 uppercase font-bold">Variant: Outline</p>
<p
class="text-[10px] font-bold uppercase opacity-50">
Variant: Outline
</p>
<AE_Comp_Hosted_Files_Download_Button
hosted_file_id={file.id}
hosted_file_obj={file}
show_direct_download={test_direct_download}
variant="outline"
color="tertiary"
classes="w-full"
/>
classes="w-full" />
</div>
<div class="space-y-1">
<p class="text-[10px] opacity-50 uppercase font-bold">Variant: Ghost</p>
<p
class="text-[10px] font-bold uppercase opacity-50">
Variant: Ghost
</p>
<AE_Comp_Hosted_Files_Download_Button
hosted_file_id={file.id}
hosted_file_obj={file}
show_direct_download={test_direct_download}
variant="ghost"
color="surface"
classes="w-full"
/>
classes="w-full" />
</div>
</div>
<div class="pt-2 border-t border-surface-500/20">
<p class="text-[10px] opacity-50 uppercase font-bold">Custom Label Snippet:</p>
<div class="border-surface-500/20 border-t pt-2">
<p
class="text-[10px] font-bold uppercase opacity-50">
Custom Label Snippet:
</p>
<AE_Comp_Hosted_Files_Download_Button
hosted_file_id={file.id}
hosted_file_obj={file}
show_direct_download={test_direct_download}
variant="tonal"
color="success"
classes="w-full mt-1"
>
classes="w-full mt-1">
{#snippet label()}
<Lucide.FileArchive size={16} class="mr-2" />
<Lucide.FileArchive
size={16}
class="mr-2" />
<span>Download Source</span>
{/snippet}
</AE_Comp_Hosted_Files_Download_Button>
@@ -232,18 +272,20 @@
{/if}
</div>
<div class="card p-6 variant-soft-warning border border-warning-500 shadow-lg">
<h3 class="h3 font-bold text-warning-700 dark:text-warning-500 flex items-center gap-2">
<div
class="card variant-soft-warning border-warning-500 border p-6 shadow-lg">
<h3
class="h3 text-warning-700 dark:text-warning-500 flex items-center gap-2 font-bold">
<Lucide.AlertTriangle size={20} /> Edge Case: Missing Metadata
</h3>
<p class="text-sm opacity-80 mt-2">
Testing the component when <code>hosted_file_id</code> or <code>hosted_file_obj</code> is missing.
<p class="mt-2 text-sm opacity-80">
Testing the component when <code>hosted_file_id</code> or
<code>hosted_file_obj</code> is missing.
</p>
<div class="flex gap-4 mt-4">
<div class="mt-4 flex gap-4">
<AE_Comp_Hosted_Files_Download_Button
hosted_file_id={null}
hosted_file_obj={null}
/>
hosted_file_obj={null} />
</div>
</div>
</div>