547 lines
18 KiB
Svelte
547 lines
18 KiB
Svelte
<script lang="ts">
|
|
/** @type {import('./$types').LayoutData} */
|
|
export let data: any;
|
|
let log_lvl = 0;
|
|
// console.log(`ae_ Svelte root +layout data:`, data);
|
|
|
|
import { onMount } from 'svelte';
|
|
import '../app.postcss';
|
|
|
|
import { AppShell, AppBar, initializeStores } from '@skeletonlabs/skeleton';
|
|
// Initialize the stores for Drawer, Modal, and Toast so they work throughout the app.
|
|
initializeStores();
|
|
import { Modal } from '@skeletonlabs/skeleton';
|
|
import type {
|
|
// DrawerSettings, DrawerComponent, DrawerStore,
|
|
ModalSettings, ModalComponent, ModalStore
|
|
} from '@skeletonlabs/skeleton';
|
|
// const drawerStore = getDrawerStore();
|
|
|
|
// import ModalComponentEditSponsorshipObj from './sponsorships/10_edit_modal__sponsorship_obj.svelte';
|
|
|
|
const modalRegistry: Record<string, ModalComponent> = {
|
|
// Set a unique modal ID, then pass the component reference
|
|
// modalComponentEditSponsorshipObj: { ref: ModalComponentEditSponsorshipObj },
|
|
// modalComponentTwo: { ref: ModalComponentTwo },
|
|
// ...
|
|
};
|
|
|
|
|
|
// Highlight JS
|
|
import hljs from 'highlight.js/lib/core';
|
|
import 'highlight.js/styles/github-dark.css';
|
|
// import type { Writable } from 'svelte/store';
|
|
// import { get } from 'svelte/store';
|
|
import { browser } from '$app/environment';
|
|
// import { goto } from '$app/navigation';
|
|
// import { page } from "$app/stores";
|
|
import { localStorageStore, storeHighlightJs } from '@skeletonlabs/skeleton';
|
|
import xml from 'highlight.js/lib/languages/xml'; // for HTML
|
|
import css from 'highlight.js/lib/languages/css';
|
|
import javascript from 'highlight.js/lib/languages/javascript';
|
|
import typescript from 'highlight.js/lib/languages/typescript';
|
|
|
|
hljs.registerLanguage('xml', xml); // for HTML
|
|
hljs.registerLanguage('css', css);
|
|
hljs.registerLanguage('javascript', javascript);
|
|
hljs.registerLanguage('typescript', typescript);
|
|
storeHighlightJs.set(hljs);
|
|
|
|
// Floating UI for Popups
|
|
import { computePosition, autoUpdate, flip, shift, offset, arrow } from '@floating-ui/dom';
|
|
import { storePopup } from '@skeletonlabs/skeleton';
|
|
storePopup.set({ computePosition, autoUpdate, flip, shift, offset, arrow });
|
|
|
|
|
|
// import { api } from '$lib/api';
|
|
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/ae_stores';
|
|
import { events_loc, events_slct } from '$lib/ae_events_stores';
|
|
import type { key_val } from '$lib/ae_stores';
|
|
// console.log($ae_loc, $ae_sess, $ae_api);
|
|
|
|
import Element_access_type from '$lib/element_access_type.svelte';
|
|
import Element_app_cfg from '$lib/element_app_cfg.svelte';
|
|
import Element_data_store from '$lib/element_data_store_v2.svelte';
|
|
|
|
// let account_id = localStorage.getItem('ae_account_id');
|
|
// console.log(`account_id = `, account_id);
|
|
|
|
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other. This should catch anything that is a child of this layout.svelte file.
|
|
$slct.account_id = data.account_id;
|
|
console.log(`*ae_root +layout.svelte* $slct.account_id = `, $slct.account_id);
|
|
let ae_acct = data[$slct.account_id];
|
|
// console.log(`*ae_root +layout.svelte* ae_acct = `, ae_acct);
|
|
// let ae_acct = data.ae_acct;
|
|
// $ae_api = ae_acct.api;
|
|
// $ae_loc = ae_acct.loc;
|
|
|
|
$ae_api = {
|
|
...$ae_api,
|
|
...ae_acct.api,
|
|
}
|
|
// console.log(`$ae_api = `, $ae_api);
|
|
|
|
$ae_loc = {
|
|
...$ae_loc,
|
|
...ae_acct.loc,
|
|
}
|
|
// console.log(`$ae_loc = `, $ae_loc);
|
|
|
|
$slct = {
|
|
...$slct,
|
|
...ae_acct.slct,
|
|
}
|
|
// console.log(`$slct = `, $slct);
|
|
|
|
// There should almost always be an event_id set.
|
|
if ($ae_loc?.site_cfg_json.slct__event_id) {
|
|
$events_slct.event_id = $ae_loc.site_cfg_json.slct__event_id;
|
|
$events_loc.event_id = $ae_loc.site_cfg_json.slct__event_id;
|
|
} else if ($events_slct.event_id) {
|
|
// console.log(`Event ID already set:`, $events_slct.event_id);
|
|
$events_loc.event_id = $events_slct.event_id;
|
|
} else {
|
|
console.log(`No Event ID set!`);
|
|
}
|
|
|
|
// This is mainly for Precon CHOW
|
|
if ($ae_loc.site_cfg_json.slct__sponsorship_cfg_id) {
|
|
$slct.sponsorship_cfg_id = $ae_loc.site_cfg_json.slct__sponsorship_cfg_id;
|
|
$ae_loc.mod.sponsorships.cfg_id = $ae_loc.site_cfg_json.slct__sponsorship_cfg_id;
|
|
} else if ($ae_loc.sponsorship_cfg_id) {
|
|
$slct.sponsorship_cfg_id = $ae_loc.sponsorship_cfg_id;
|
|
$ae_loc.mod.sponsorships.cfg_id = $ae_loc.sponsorship_cfg_id;
|
|
} else {
|
|
console.log(`No Sponsorship Config ID set.`);
|
|
}
|
|
|
|
|
|
if ($ae_loc.allow_access && !$ae_loc.key_checked) {
|
|
console.log(`PASS: The access key was checked earlier.`);
|
|
|
|
// allow_access should equal true or the access key.
|
|
if ($ae_loc.site_access_key || $ae_loc.site_domain_access_key) {
|
|
console.log(`We need to do a current check against the allow_access value.`);
|
|
if ($ae_loc.site_access_key == $ae_loc.allow_access || $ae_loc.site_domain_access_key == $ae_loc.allow_access) {
|
|
console.log(`PASS: The access key was checked earlier and we just now checked the key.`);
|
|
} else {
|
|
console.log(`FAIL: The access key was checked earlier, but just now failed.`);
|
|
if ($ae_loc.trusted_access) {
|
|
console.log(`FAIL: The access key was checked earlier and failed, but we have trusted access.`);
|
|
$ae_loc.allow_access = true;
|
|
} else {
|
|
$ae_loc.allow_access = false;
|
|
}
|
|
}
|
|
} else {
|
|
// This means this site and domain do not require an access key.
|
|
// Do nothing to change the allow_access here at this time.
|
|
}
|
|
} else if ($ae_loc.allow_access && $ae_loc.key_checked) {
|
|
console.log(`PASS: The access key was checked earlier and we just now checked the key.`);
|
|
} else if (!$ae_loc.allow_access && $ae_loc.key_checked) {
|
|
console.log(`FAIL: The access key was checked earlier and failed.`);
|
|
if ($ae_loc.trusted_access) {
|
|
console.log(`FAIL: The access key was checked earlier and failed, but we have trusted access.`);
|
|
$ae_loc.allow_access = true;
|
|
}
|
|
} else {
|
|
console.log(`FAIL: The access key was not checked earlier.`);
|
|
// $ae_loc.key_checked = true;
|
|
}
|
|
|
|
// $: access_key = data.url.searchParams.get('key');
|
|
// console.log(`access_key = `, access_key);
|
|
|
|
if (browser) {
|
|
// Waiting until the browser exists.
|
|
if ($ae_loc && $ae_sess && $ae_loc.ver_idb != $ae_sess.ver_idb) {
|
|
console.log('New version of the IDB available!!!');
|
|
console.log(`$ae_loc.ver_idb: ${$ae_loc.ver_idb} != $ae_sess.ver_idb: ${$ae_sess.ver_idb}`);
|
|
|
|
// Clear Indexed DB as well
|
|
indexedDB.deleteDatabase('ae_core_db');
|
|
indexedDB.deleteDatabase('ae_events_db');
|
|
|
|
$ae_loc.ver_idb = $ae_sess.ver_idb;
|
|
|
|
window.location.reload();
|
|
}
|
|
|
|
if ($ae_loc && $ae_sess && ($ae_loc.ver != $ae_sess.ver)) {
|
|
console.log('New version of the data store available!!!');
|
|
console.log(`$ae_loc.ver: ${$ae_loc.ver} != $ae_sess.ver: ${$ae_sess.ver}`);
|
|
|
|
// alert('New version available!!!');
|
|
|
|
$ae_loc.ver = $ae_sess.ver;
|
|
|
|
// $ae_loc = {};
|
|
localStorage.removeItem('ae_loc');
|
|
localStorage.removeItem('events_loc');
|
|
// localStorage.clear();
|
|
|
|
// sessionStorage.removeItem('ae_sess');
|
|
// sessionStorage.removeItem('events_sess');
|
|
// sessionStorage.clear();
|
|
|
|
|
|
// This does not seem to work fast enough or something?
|
|
// goto('/', {replaceState: true, invalidateAll: true});
|
|
|
|
// localStorage.removeItem('ae_loc');
|
|
// localStorage.removeItem('events_loc');
|
|
localStorage.clear();
|
|
|
|
sessionStorage.clear();
|
|
|
|
window.location.reload();
|
|
|
|
// localStorage.removeItem('ae_loc');
|
|
// localStorage.removeItem('events_loc');
|
|
// localStorage.clear();
|
|
}
|
|
|
|
|
|
// save_ds_to_local(ae_acct.ds);
|
|
let ae_ds = ae_acct.ds;
|
|
console.log(`ae_ds__ data:`, ae_ds)
|
|
for (let [key, value] of Object.entries(ae_ds)) {
|
|
console.log(`ae_ds__ key: ${key}, value:`, value);
|
|
localStorage.setItem(`ae_ds__${key}`, JSON.stringify(value));
|
|
|
|
// This should not be needed here anymore.
|
|
// if (key == 'hub__site__appshell_header') {
|
|
// $ae_sess.site_appshell_header = value;
|
|
// console.log(`$ae_sess.site_appshell_header = `, $ae_sess.site_appshell_header);
|
|
// }
|
|
}
|
|
|
|
// $ae_sess.site_appshell_header = JSON.parse(localStorage.getItem('ae_ds__hub__site__appshell_header'));
|
|
// console.log(`$ae_sess.site_appshell_header = `, $ae_sess.site_appshell_header);
|
|
}
|
|
|
|
// We want to loop through all of the data store (ds) key value pairs and set them to localStorage
|
|
// $: if (ae_acct.ds) {
|
|
// console.log(`ae_ds__ data:`, ae_acct.ds)
|
|
// for (let [key, value] of Object.entries(ae_acct.ds)) {
|
|
// console.log(`ae_ds__ key: ${key}, value:`, value);
|
|
// localStorageStore(`ae_ds__${key}`, value);
|
|
// }
|
|
// }
|
|
|
|
|
|
|
|
onMount(() => {
|
|
console.log('Root: +layout.svelte');
|
|
|
|
// Waiting until the browser exists.
|
|
// save_ds_to_local(ae_acct.ds);
|
|
|
|
// $ae_sess.site_appshell_header = JSON.parse(localStorage.getItem('ae_ds__hub__site__appshell_header'));
|
|
// console.log(`$ae_sess.site_appshell_header = `, $ae_sess.site_appshell_header);
|
|
// $ae_sess = $ae_sess;
|
|
|
|
let iframe = data.url.searchParams.get('iframe');
|
|
if (iframe == 'true') {
|
|
console.log('Use iframe layout!');
|
|
// data_struct['iframe'] = iframe;
|
|
$ae_loc.iframe = true;
|
|
|
|
document.getElementsByTagName('html')[0].classList.add('iframe');
|
|
document.getElementsByTagName('html')[0].classList.remove('dark');
|
|
document.getElementsByTagName('html')[0].classList.remove('light');
|
|
|
|
$ae_loc.hub.show_element__access_type = false;
|
|
$ae_loc.hub.show_element__cfg = false;
|
|
} else if (iframe == 'false') {
|
|
// data_struct['iframe'] = false;
|
|
$ae_loc.iframe = false;
|
|
|
|
document.getElementsByTagName('html')[0].classList.remove('iframe');
|
|
document.getElementsByTagName('html')[0].classList.add('light');
|
|
}
|
|
|
|
if (!$ae_loc.iframe && $ae_loc.trusted_access) {
|
|
$ae_loc.hub.show_element__access_type = true;
|
|
$ae_loc.hub.show_element__cfg = true;
|
|
} else if ($ae_loc.iframe && $ae_loc.manager_access) {
|
|
$ae_loc.hub.show_element__access_type = true;
|
|
$ae_loc.hub.show_element__cfg = true;
|
|
} else {
|
|
$ae_loc.hub.show_element__access_type = true;
|
|
$ae_loc.hub.show_element__cfg = false;
|
|
}
|
|
|
|
if (data.url.searchParams.get('event_id')) {
|
|
$events_slct.event_id = data.url.searchParams.get('event_id');
|
|
$events_loc.event_id = data.url.searchParams.get('event_id');
|
|
}
|
|
|
|
if (data.url.searchParams.get('sponsorship_cfg_id')) {
|
|
$slct.sponsorship_cfg_id = data.url.searchParams.get('sponsorship_cfg_id');
|
|
$ae_loc.mod.sponsorships.cfg_id = data.url.searchParams.get('sponsorship_cfg_id');
|
|
}
|
|
|
|
|
|
// TESTING TESTING TESTING
|
|
// WARNING: This needs to be tied to an object type and ID. This is a temporary solution.
|
|
// $ae_sess.download = {
|
|
// 'endpoint': '/event/file/abc123/download',
|
|
// 'filename': 'example.txt',
|
|
// 'size_total': 0,
|
|
// 'size_loaded': 0,
|
|
// 'percent_completed': 0,
|
|
// };
|
|
|
|
|
|
// This is how the download and upload progress is tracked.
|
|
window.addEventListener('message', function(event) {
|
|
if (log_lvl) {
|
|
console.log('Message received in root +layout.svelte:');
|
|
console.log(event);
|
|
}
|
|
|
|
if (event.data.type == 'api_download_blob') {
|
|
if (log_lvl) {
|
|
console.log('Download blob (file) message received:', event.data);
|
|
}
|
|
|
|
let task_id = event.data.task_id;
|
|
|
|
// $ae_sess.download[event.data.endpoint] = {
|
|
// 'status': event.data.status,
|
|
// 'task_id': task_id,
|
|
// 'endpoint': event.data.endpoint,
|
|
// 'filename': event.data.filename,
|
|
// 'size_total': event.data.size_total,
|
|
// 'size_loaded': event.data.size_loaded,
|
|
// 'percent_completed': event.data.percent_completed,
|
|
// };
|
|
|
|
$ae_sess.api_download_kv[task_id] =
|
|
{
|
|
'status': event.data.status,
|
|
'task_id': task_id,
|
|
'endpoint': event.data.endpoint,
|
|
'filename': event.data.filename,
|
|
'size_total': event.data.size_total,
|
|
'size_loaded': event.data.size_loaded,
|
|
'percent_completed': event.data.percent_completed,
|
|
};
|
|
} else if (event.data.type == 'api_post_json_form') {
|
|
if (log_lvl) {
|
|
console.log('Post JSON form message received:', event.data);
|
|
}
|
|
|
|
let task_id = event.data.task_id;
|
|
|
|
$ae_sess.api_upload_kv[task_id] =
|
|
{
|
|
'status': event.data.status,
|
|
'task_id': task_id,
|
|
'endpoint': event.data.endpoint,
|
|
'filename': event.data.filename,
|
|
'size_total': event.data.size_total,
|
|
'size_loaded': event.data.size_loaded,
|
|
'percent_completed': event.data.percent_completed,
|
|
'progress': event.data.progress,
|
|
'rate': event.data.rate,
|
|
};
|
|
}
|
|
});
|
|
|
|
// console.log(`access_key = `, access_key);
|
|
|
|
});
|
|
</script>
|
|
|
|
|
|
<svelte:head>
|
|
<title>{$ae_loc.title ?? 'Æ loading...'}</title>
|
|
<link rel="stylesheet" href="{ae_acct.loc.site_style_href}">
|
|
<!-- <link rel="manifest" href="/manifest.json"> -->
|
|
</svelte:head>
|
|
|
|
|
|
<!-- regionFooter="flex justify-end space-x-2" -->
|
|
|
|
<Modal components={modalRegistry}
|
|
regionBackdrop=''
|
|
regionBody=''
|
|
regionHeader='modal-header card-header text-2xl font-bold'
|
|
regionFooter='modal-footer flex justify-between space-x-2'
|
|
/>
|
|
|
|
<!-- App Shell -->
|
|
<AppShell
|
|
regionPage={($ae_loc.iframe ? 'iframe' : '')}
|
|
slotHeader={($ae_loc.iframe ? 'iframe' : '')}
|
|
slotFooter={($ae_loc.iframe ? 'iframe' : '')}
|
|
>
|
|
|
|
<svelte:fragment slot="header">
|
|
<!-- App Bar -->
|
|
<AppBar
|
|
gridColumns="grid-cols-3"
|
|
slotDefault="place-self-center"
|
|
slotTrail="place-content-end"
|
|
padding="px-4"
|
|
>
|
|
<svelte:fragment slot="lead">
|
|
<Element_data_store
|
|
ds_code="hub__page__appshell_header_lead"
|
|
ds_type="html"
|
|
display="block"
|
|
/>
|
|
|
|
</svelte:fragment>
|
|
<!-- OSIT's Aether App -->
|
|
<!-- {@html (browser ? JSON.parse(localStorage.getItem('ae_ds__hub__site__appshell_header')).html : '-- not found --')} -->
|
|
<!-- {@html $ae_sess.site_appshell_header} -->
|
|
<Element_data_store
|
|
ds_code="hub__site__appshell_header"
|
|
ds_type="html"
|
|
display="block"
|
|
/>
|
|
<svelte:fragment slot="trail">
|
|
<Element_data_store
|
|
ds_code="hub__page__appshell_header_trail"
|
|
ds_type="html"
|
|
display="block"
|
|
/>
|
|
</svelte:fragment>
|
|
</AppBar>
|
|
|
|
</svelte:fragment>
|
|
|
|
|
|
<!-- !($ae_loc.site_access_key && $ae_loc.site_domain_access_key)
|
|
|| ($ae_loc.site_access_key == access_key || $ae_loc.site_domain_access_key == access_key)} -->
|
|
{#if
|
|
$ae_loc.allow_access}
|
|
|
|
<!-- {$ae_loc?.site_access_key ?? '-- site access key not set --'} -->
|
|
<!-- {$ae_loc?.site_domain_access_key ?? '-- site domain access key not set --'} -->
|
|
<!-- {access_key ?? '-- param key not set --'} -->
|
|
|
|
<!-- Page Route Content -->
|
|
<slot />
|
|
|
|
{:else}
|
|
<div class="flex flex-col items-center justify-center h-screen">
|
|
<h1 class="text-4xl font-bold text-red-500">Access Denied</h1>
|
|
<p class="text-lg text-gray-500">You do not have access to this site.</p>
|
|
</div>
|
|
{/if}
|
|
|
|
|
|
<svelte:fragment slot="footer">
|
|
<div
|
|
class="flex text-sm sm:text-sm md:text-md lg:text-md xl:text-md 2xl:text-lg text-slate-400 hover:text-slate-800 transition px-1"
|
|
class:ae_debug={$ae_loc.debug}
|
|
>
|
|
<Element_data_store
|
|
ds_code="hub__site__appshell_footer"
|
|
ds_type="html"
|
|
display="block"
|
|
class_li="grow flex flex-row justify-between"
|
|
/>
|
|
|
|
<button
|
|
on:click={() => {
|
|
console.log('Debug ae_loc:', $ae_loc);
|
|
$ae_loc.debug = !$ae_loc?.debug;
|
|
}}
|
|
id="AE-Quick-Debug"
|
|
class="ae_quick_debug btn btn-sm variant-glass-surface"
|
|
title="Turn debug content and styles off and on"
|
|
>
|
|
π
|
|
</button>
|
|
</div>
|
|
</svelte:fragment>
|
|
|
|
|
|
</AppShell>
|
|
|
|
|
|
{#if $ae_loc.hub?.show_element__access_type}
|
|
<Element_access_type />
|
|
{/if}
|
|
|
|
|
|
<span
|
|
class:hidden={!$ae_loc?.hub?.show_element__cfg}
|
|
>
|
|
<!-- {#if $ae_loc?.hub?.show_element__cfg} -->
|
|
<Element_app_cfg set_theme_mode={true} set_theme_name={true} />
|
|
<!-- {/if} -->
|
|
</span>
|
|
|
|
|
|
<style lang="postcss">
|
|
/* BEGIN: AE's Svelte Quick Debug component */
|
|
#AE-Quick-Debug {
|
|
/* position: absolute; */
|
|
position: fixed;
|
|
/* position: relative; */
|
|
/* position: static; */
|
|
/* position: sticky; */
|
|
/* top: 1em; */
|
|
bottom: 0rem;
|
|
right: 0rem;
|
|
|
|
padding: .0rem;
|
|
|
|
/* lightyellow */
|
|
/* background-color: hsla(60,100%,90%,.30); */
|
|
/* background-color: rgba(var(--color-surface-500) / .5); */
|
|
|
|
border: none;
|
|
|
|
border-top: solid thin hsla(0,0%,0%,.25);
|
|
border-left: solid thin hsla(0,0%,0%,.25);
|
|
border-bottom: solid thin hsla(0,0%,0%,.25);
|
|
/* border-top-left-radius: .5em; */
|
|
/* border-bottom-left-radius: .5em; */
|
|
|
|
opacity: .15;
|
|
/* opacity: 1; */
|
|
|
|
font-size: .75rem;
|
|
|
|
z-index: 5;
|
|
|
|
/* NOTE: transition when no longer hovering */
|
|
transition-property: opacity, background-color;
|
|
transition-delay: 1.25s;
|
|
transition-duration: .5s;
|
|
transition-timing-function: ease-out;
|
|
}
|
|
|
|
#AE-Quick-Debug:hover {
|
|
/* lightyellow */
|
|
/* background-color: hsla(60,100%,90%,.95); */
|
|
/* background-color: rgba(var(--color-surface-500) / 1); */
|
|
|
|
border-top: solid thin hsla(0,0%,0%,.95);
|
|
border-left: solid thin hsla(0,0%,0%,.95);
|
|
border-bottom: solid thin hsla(0,0%,0%,.95);
|
|
|
|
opacity: 1;
|
|
|
|
padding: .5rem;
|
|
|
|
font-size: 1.75rem;
|
|
/* Need to zoom 3.5 when hovering */
|
|
/* transform: scale(3.5); */
|
|
|
|
/* NOTE: transition when hover starts */
|
|
transition-property: opacity, background-color;
|
|
transition-delay: .5s;
|
|
transition-duration: .10s;
|
|
transition-timing-function: ease-in;
|
|
}
|
|
</style>
|