Add feature detection and warnings, run formatter

This commit is contained in:
Fred Boniface 2024-06-23 11:21:45 +01:00
parent 98c9b5cc03
commit 8560d61348
10 changed files with 108 additions and 85 deletions

View File

@ -19,14 +19,11 @@
} }
function save() { function save() {
toast.promise( toast.promise(saveQl(), {
saveQl(), loading: "Saving...",
{
loading: 'Saving...',
success: "Quick Links saved!", success: "Quick Links saved!",
error: "Failed to save." error: "Failed to save.",
} });
);
} }
async function saveQl() { async function saveQl() {
@ -48,7 +45,7 @@
function clearQl() { function clearQl() {
ql.set([]); ql.set([]);
saveButton = "Saved"; saveButton = "Saved";
toast.success("Cleared Quick Links.") toast.success("Cleared Quick Links.");
} }
function addQlBox() { function addQlBox() {

View File

@ -1,27 +0,0 @@
<script lang="ts">
import { stop_propagation } from "svelte/internal";
export let showModal: boolean
let dialog: HTMLDialogElement
$: if (dialog && showModal) dialog.showModal();
</script>
<dialog
bind:this={dialog}
on:close={() => (showModal = false)}
on:click|self={() => dialog.close()}
>
<div on:click|stop_propagation>
<slot name="header" />
<hr />
<slot />
<hr />
<button autofocus on:click{() => dialog.close()}>Close</button>
</div>
</dialog>
<style>
</style>

View File

@ -1,9 +0,0 @@
<script lang="ts">
</script>
<style>
</style>

View File

@ -0,0 +1,64 @@
export interface FeatureDetectionResult {
critical: boolean;
nice: boolean;
missing: string[];
}
export function featureDetect(): FeatureDetectionResult {
console.info("Running feature detection");
// Define critical features
const criticalFeatures = {
fetch: "fetch" in window,
localStorage: "localStorage" in window && window["localStorage"] !== null,
sessionStorage: "sessionStorage" in window && window["sessionStorage"] !== null,
promise: "Promise" in window,
};
// Define nice-to-have features
const niceToHaveFeatures = {
geolocation: "geolocation" in navigator,
serviceWorker: "serviceWorker" in navigator,
dialog: "HTMLDialogElement" in window,
popover: "showPopover" in HTMLElement.prototype, // Note: 'Popover' might need more specific checks based on implementation
};
// Initialize result object
const result = {
critical: true,
nice: true,
missing: [],
};
// Check critical features
for (const [feature, available] of Object.entries(criticalFeatures)) {
if (!available) {
result.critical = false;
result.missing.push(feature);
}
}
// Check nice-to-have features
for (const [feature, available] of Object.entries(niceToHaveFeatures)) {
if (!available) {
result.nice = false;
result.missing.push(feature);
}
}
return result;
}
/*// Example usage
const featureSupport = featureDetect();
console.log(featureSupport);
if (!featureSupport.critical) {
alert('Some critical features required for this application are not supported by your browser.');
// Handle lack of critical features appropriately
} else if (!featureSupport.nice) {
console.warn('Some nice-to-have features are not supported by your browser. The app will still function, but some features may be unavailable.');
// Optionally handle lack of nice-to-have features
} else {
// Proceed with the normal functionality of your app
}
*/

View File

@ -1,3 +1,3 @@
export const version: string = '2024.06.2'; export const version: string = "2024.06.3";
export const versionTag: string = ''; export const versionTag: string = "";
export const showWelcome: boolean = false; export const showWelcome: boolean = false;

View File

@ -4,7 +4,7 @@
import { dev } from "$app/environment"; import { dev } from "$app/environment";
import DevBanner from "$lib/DevBanner.svelte"; import DevBanner from "$lib/DevBanner.svelte";
import { page } from "$app/stores"; import { page } from "$app/stores";
import { Toaster } from 'svelte-french-toast' import { Toaster } from "svelte-french-toast";
</script> </script>
<svelte:head> <svelte:head>
@ -31,8 +31,13 @@
<link rel="manifest" href="/manifest.json" /> <link rel="manifest" href="/manifest.json" />
<title>OwlBoard</title> <title>OwlBoard</title>
</svelte:head> </svelte:head>
<Toaster /> <Toaster />
{#if dev} {#if dev}
<DevBanner /> <DevBanner />
{/if} {/if}
<slot /> <slot />
<style>
</style>

View File

@ -6,6 +6,7 @@
import Welcome from "$lib/overlays/welcome.svelte"; import Welcome from "$lib/overlays/welcome.svelte";
import { welcome } from "$lib/stores/welcome"; import { welcome } from "$lib/stores/welcome";
import { version, showWelcome } from "$lib/stores/version"; import { version, showWelcome } from "$lib/stores/version";
import { featureDetect } from "$lib/scripts/featureDetect";
import { onMount } from "svelte"; import { onMount } from "svelte";
import toast from "svelte-french-toast"; import toast from "svelte-french-toast";
@ -25,15 +26,16 @@
}, },
]; ];
onMount(() => { onMount(async () => {
toast( const featureSupport = featureDetect();
"Registration soon required for some features.\n\nClick 'Register' in the menu.", console.log(featureSupport);
{
duration: 3000,
}
)
})
if (!featureSupport.critical) {
toast.error("Your browser is missing critical features, OwlBoard might not work properly. Consider updating your browser.");
} else if (!featureSupport.nice) {
toast.error("Your browser is missing some features, OwlBoard may run slower or be missing some features.");
}
});
</script> </script>
{#if showWelcome && ($welcome === "null" || !$welcome || parseInt($welcome.replace(/\./g, "")) < parseInt(version.replace(/\./g, "")))} {#if showWelcome && ($welcome === "null" || !$welcome || parseInt($welcome.replace(/\./g, "")) < parseInt(version.replace(/\./g, "")))}

View File

@ -42,14 +42,11 @@
} }
function send() { function send() {
toast.promise( toast.promise(request(), {
request(),
{
loading: "Contacting Server...", loading: "Contacting Server...",
success: "Request Answered.", success: "Request Answered.",
error: "Unable to contact server." error: "Unable to contact server.",
} });
)
} }
onMount(async () => { onMount(async () => {

View File

@ -45,28 +45,28 @@
const res = await fetch(url, options); // Enable Auth const res = await fetch(url, options); // Enable Auth
if (res.status == 401) { if (res.status == 401) {
errMsg = "You must be logged in to the staff version"; errMsg = "You must be logged in to the staff version";
toast.error("You must be registered") toast.error("You must be registered");
error = true; error = true;
return false; return false;
} else if (res.status == 500) { } else if (res.status == 500) {
errMsg = "Server Error, try again later"; errMsg = "Server Error, try again later";
toast.error("Server Error.", {duration: 7500}) toast.error("Server Error.", { duration: 7500 });
error = true; error = true;
return false; return false;
} }
const jsonData = await res.json(); const jsonData = await res.json();
if (jsonData.ERROR == "offline") { if (jsonData.ERROR == "offline") {
errMsg = "Connection error, check your internet connection and try again"; errMsg = "Connection error, check your internet connection and try again";
toast.error("You are offline.") toast.error("You are offline.");
error = true; error = true;
return false; return false;
} }
data = jsonData; data = jsonData;
let count = data.length let count = data.length;
if (!count) { if (!count) {
toast.error("No PIS Codes found.") toast.error("No PIS Codes found.");
} else { } else {
toast.success(`${count} PIS Codes found`) toast.success(`${count} PIS Codes found`);
} }
} }
@ -76,18 +76,15 @@
entryPIS = ""; entryPIS = "";
entryStartCRS = ""; entryStartCRS = "";
entryEndCRS = ""; entryEndCRS = "";
toast.success("Form reset") toast.success("Form reset");
isLoading = false;
} }
onMount(() => { onMount(() => {
toast( toast("Registration soon required for PIS features.\n\nClick 'Register' in the menu.", {
"Registration soon required for PIS features.\n\nClick 'Register' in the menu.",
{
duration: 3000, duration: 3000,
} });
) });
})
</script> </script>
<Header {title} /> <Header {title} />

View File

@ -42,12 +42,9 @@
} }
isLoading = false; isLoading = false;
toast( toast("Registration soon required for timetable features.\n\nClick 'Register' in the menu.", {
"Registration soon required for timetable features.\n\nClick 'Register' in the menu.",
{
duration: 3000, duration: 3000,
} });
)
}); });
async function fetchData(id = "") { async function fetchData(id = "") {