mirror of
https://github.com/KevinMidboe/brewPi.git
synced 2025-10-28 16:30:12 +00:00
Feat/prerender and state (#8)
* pre-load data behind link elements on hover * Enable SSR and prerendering of pages in 'auto' mode * merge relay & regulator state in /api/state This helps when updating relays and receiving state of relays and regulator state (idle, heating or cooling) after emitting relay change.
This commit is contained in:
@@ -20,7 +20,7 @@ const routes: Array<IRoute> = [{
|
||||
|
||||
<ul class="navigation-cards" on:click>
|
||||
{#each routes as route}
|
||||
<a href={route.path}>
|
||||
<a href={route.path} data-sveltekit-preload-data="hover">
|
||||
<li>
|
||||
<span>{ route.name }</span>
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
export let relays: IRelaysDTO[] = [];
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function toggleRelay(controls: string) {
|
||||
async function toggleRelay(controls: string) {
|
||||
const url = `/api/relay/${controls}`;
|
||||
const options = {
|
||||
method: 'POST'
|
||||
};
|
||||
|
||||
fetch(url, options)
|
||||
await fetch(url, options)
|
||||
.then((resp) => resp.json())
|
||||
.then((response) => {
|
||||
const changedRelay = relays.findIndex((relay) => relay.pin === response.pin);
|
||||
|
||||
16
src/routes/+layout.ts
Normal file
16
src/routes/+layout.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// if you want to generate a static html file
|
||||
// for your page.
|
||||
// Documentation: https://kit.svelte.dev/docs/page-options#prerender
|
||||
export const prerender = 'auto';
|
||||
|
||||
// if you want to Generate a SPA
|
||||
// you have to set ssr to false.
|
||||
// This is not the case (so set as true or comment the line)
|
||||
// Documentation: https://kit.svelte.dev/docs/page-options#ssr
|
||||
export const ssr = true;
|
||||
|
||||
// How to manage the trailing slashes in the URLs
|
||||
// the URL for about page witll be /about with 'ignore' (default)
|
||||
// the URL for about page witll be /about/ with 'always'
|
||||
// https://kit.svelte.dev/docs/page-options#trailingslash
|
||||
export const trailingSlash = 'ignore';
|
||||
@@ -1,28 +1,51 @@
|
||||
import { BREWLOGGER_HOST } from '$env/static/private';
|
||||
import type { PageServerLoad } from './$types';
|
||||
import type { ISensorDTO } from '../lib/interfaces/ISensorDTO'
|
||||
import type { PageServerLoad, RequestEvent } from './$types';
|
||||
import type { ISensorDTO } from '../lib/interfaces/ISensorDTO';
|
||||
import { IRelaysDTO } from '../lib/interfaces/IRelaysDTO';
|
||||
import { IStateDTO } from '../lib/interfaces/IStateDTO';
|
||||
|
||||
const sensorsUrl = `${BREWLOGGER_HOST}/api/sensors`;
|
||||
const relaysUrl = `${BREWLOGGER_HOST}/api/relays`;
|
||||
const stateUrl = `${BREWLOGGER_HOST}/api/regulator`;
|
||||
export const prerender = true; // explicitly pre-render
|
||||
|
||||
async function getFromEndpoint(endpoint: string) {
|
||||
return fetch(endpoint)
|
||||
async function fetchSensors(fetch: Fetch): Promise<ISensorDTO[]> {
|
||||
return fetch(sensorsUrl)
|
||||
.then((resp) => resp.json())
|
||||
.then((data) => data?.sensors || [])
|
||||
.catch((error) => {
|
||||
console.error('Failed to fetch endpoint:', endpoint);
|
||||
console.error('failed to fetch sensors.');
|
||||
console.error(error);
|
||||
return null
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
export const load: PageServerLoad = async () => {
|
||||
const [sensorsResp, relaysResp, stateResp] = await Promise.all([getFromEndpoint(sensorsUrl), getFromEndpoint(relaysUrl), getFromEndpoint(stateUrl)]);
|
||||
const sensors: ISensorDTO[] = sensorsResp?.sensors || []
|
||||
const relays: IRelaysDTO[] = relaysResp?.relays || []
|
||||
const state: IStateDTO = stateResp
|
||||
// calls internal sveltekit api endpoint.
|
||||
// this allows unified response in svelte app, even
|
||||
// though it requires multiple calls to regulator server
|
||||
async function fetchState(fetch: Fetch) {
|
||||
return fetch('/api/state')
|
||||
.then((resp) => resp.json())
|
||||
.catch((error) => {
|
||||
console.error('failed to fetch state');
|
||||
console.error(error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
type Fetch = typeof fetch;
|
||||
type HandleFetch = {
|
||||
event: RequestEvent;
|
||||
request: Request;
|
||||
fetch: Fetch;
|
||||
};
|
||||
|
||||
export const load: PageServerLoad = async (input: HandleFetch) => {
|
||||
const [stateResponse, sensorsResponse] = await Promise.all([
|
||||
fetchState(input.fetch),
|
||||
fetchSensors(input.fetch)
|
||||
]);
|
||||
const sensors: ISensorDTO[] = sensorsResponse || [];
|
||||
const relays: IRelaysDTO[] = stateResponse?.relays || [];
|
||||
const regulator: IStateDTO = stateResponse?.regulator;
|
||||
|
||||
const inside = sensors.find((sensor: ISensorDTO) => sensor.location === 'inside');
|
||||
const outside = sensors.find((sensor: ISensorDTO) => sensor.location === 'outside');
|
||||
@@ -30,7 +53,6 @@ export const load: PageServerLoad = async () => {
|
||||
return {
|
||||
inside: inside || null,
|
||||
outside: outside || null,
|
||||
relays,
|
||||
state
|
||||
state: { regulator, relays }
|
||||
};
|
||||
};
|
||||
|
||||
@@ -8,14 +8,13 @@
|
||||
|
||||
export let data: PageData;
|
||||
const { inside, outside } = data;
|
||||
let { relays, state } = data;
|
||||
let { relays, regulator } = data.state;
|
||||
|
||||
const updateState = () =>
|
||||
setTimeout(() => {
|
||||
fetch('/api/state')
|
||||
.then((resp) => resp.json())
|
||||
.then((response: IStateDTO) => (state = response));
|
||||
}, 100);
|
||||
const updateState = () => {
|
||||
fetch('/api/state')
|
||||
.then((resp) => resp.json())
|
||||
.then((response: IStateDTO) => ({ relays, regulator } = response));
|
||||
}
|
||||
</script>
|
||||
|
||||
<Logo />
|
||||
@@ -23,7 +22,12 @@
|
||||
<div class="vertical-grid">
|
||||
<BrewProgress />
|
||||
|
||||
<VerticalSensorDisplay {inside} {outside} {relays} {state} />
|
||||
<VerticalSensorDisplay
|
||||
inside="{inside}"
|
||||
outside="{outside}"
|
||||
relays="{relays}"
|
||||
state="{regulator}"
|
||||
/>
|
||||
|
||||
<RelayControls bind:relays="{relays}" on:relaySwitched="{updateState}" />
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import { json, RequestEvent } from '@sveltejs/kit';
|
||||
import { BREWLOGGER_HOST } from '$env/static/private';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { IRelaysDTO } from '../../../lib/interfaces/IRelaysDTO';
|
||||
|
||||
export const GET = (async (event: RequestEvent) => {
|
||||
return fetch(BREWLOGGER_HOST + '/api/regulator')
|
||||
async function fetchRegulator(): Promise<Response | IRelaysDTO[]> {
|
||||
return fetch(BREWLOGGER_HOST + '/api/regulator').then((resp) => resp.json());
|
||||
}
|
||||
|
||||
async function fetchRelays(): Promise<Response | IRelaysDTO[]> {
|
||||
return fetch(BREWLOGGER_HOST + '/api/relays')
|
||||
.then((resp) => resp.json())
|
||||
.then((response) => json(response));
|
||||
.then((data) => data?.relays || []);
|
||||
}
|
||||
|
||||
export const GET = (async () => {
|
||||
const [regulatorState, relaysState] = await Promise.all([fetchRegulator(), fetchRelays()]);
|
||||
return json({ regulator: regulatorState, relays: relaysState });
|
||||
}) satisfies RequestHandler;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<ul>
|
||||
{#each brews as brew}
|
||||
<li class="brew">
|
||||
<a href="{path(brew.date)}">
|
||||
<a href="{path(brew.date)}" data-sveltekit-preload-data="hover">
|
||||
<img src="/images/{brew.image}" alt="Beer label of {brew.beer.name}" />
|
||||
|
||||
<div class="details">
|
||||
|
||||
@@ -4,8 +4,9 @@ import { fetchHumidity, fetchTemperature } from '../../../lib/server/graphQueryG
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
async function fetchGraphData(brew) {
|
||||
const start = new Date(brew.date * 1000 - 86400000);
|
||||
const end = new Date(brew.date * 1000 + 4838400000);
|
||||
const { date } = brew;
|
||||
const start = new Date(date * 1000 - 86400000);
|
||||
const end = new Date(date * 1000 + 4838400000);
|
||||
const size = 200;
|
||||
|
||||
const [temperature, humidity] = await Promise.all([
|
||||
@@ -13,10 +14,7 @@ async function fetchGraphData(brew) {
|
||||
fetchHumidity(start, end, size)
|
||||
]);
|
||||
|
||||
return {
|
||||
temperature,
|
||||
humidity
|
||||
};
|
||||
return { temperature, humidity };
|
||||
}
|
||||
|
||||
export const load = (async ({ params }) => {
|
||||
|
||||
Reference in New Issue
Block a user