Skip to content

Commit ca4be68

Browse files
committed
Component (AppShell): Add connectivity loss Banner. | Component (Banner): Add animation onMount
1 parent c285c20 commit ca4be68

File tree

3 files changed

+55
-37
lines changed

3 files changed

+55
-37
lines changed

src/lib/components/messaging/Banner/Banner.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<script lang="ts">
22
import type { Snippet } from "svelte";
3+
import { quintOut } from "svelte/easing";
4+
import { slide } from "svelte/transition";
35
46
import Flex from "$lib/components/primitives/Flex/Flex.svelte";
57
import Icon from "$lib/components/primitives/Icon/Icon.svelte";
8+
import type { iconType } from "$lib/types/Icon.ts";
69
7-
import type { iconType } from "../../../types/Icon.ts";
810
import { styles } from "./Banner.css.ts";
911
1012
interface Props {
@@ -15,7 +17,9 @@
1517
let { appearance, children, icon }: Props = $props();
1618
</script>
1719

18-
<div class="{styles.baseBanner} {styles.appearance[appearance]}">
20+
<div
21+
class="{styles.baseBanner} {styles.appearance[appearance]}"
22+
transition:slide={{ duration: 500, easing: quintOut }}>
1923
<Flex width="100%" height="3rem" direction="row" alignItems="center" gap="small">
2024
{#if icon}
2125
<Icon {icon} size="large" />

src/lib/components/primitives/AppShell/AppShell.svelte

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
import IconLinkButton from "$lib/components/input/IconLinkButton/IconLinkButton.svelte";
1010
import Toaster from "$lib/components/messaging/Toaster/Toaster.svelte";
1111
import Blanket from "$lib/components/overlays/Blanket/Blanket.svelte";
12+
import { appState, initTrackers } from "$lib/engines/appStateEngine.svelte.ts";
13+
import { useShortcut } from "$lib/engines/shortcutEngine.svelte.ts";
14+
import { currentTheme, setTheme } from "$lib/engines/themeEngine.svelte.ts";
15+
import { createTranslationEngine } from "$lib/engines/translationEngine.svelte.ts";
1216
import { token } from "$lib/styles/designTokens.ts";
1317
14-
import { useShortcut } from "../../../../lib/engines/shortcutEngine.svelte.ts";
15-
import { appState } from "../../../engines/appStateEngine.svelte.ts";
16-
import { currentTheme, setTheme } from "../../../engines/themeEngine.svelte.ts";
17-
import { createTranslationEngine } from "../../../engines/translationEngine.svelte.ts";
1818
import Anchor from "../Anchor/Anchor.svelte";
1919
import Flex from "../Flex/Flex.svelte";
2020
import Icon from "../Icon/Icon.svelte";
@@ -64,9 +64,12 @@
6464
console.log("buildTime: " + __DDS_INFO__.buildTime);
6565
console.groupEnd();
6666
67-
// Some notes:
68-
// Read caches first of engines after rerun after auth completed???
69-
// Keep lastcommunicated value or smth that you dont refresh if newer then 10m
67+
// Multi-Account Auth:
68+
// - Storage: HttpOnly cookies named `token_${accountId}`.
69+
// - Request: Frontend sends `x-active-account: ${accountId}` header.
70+
// - Backend: Reads header, pulls the matching cookie, and validates that specific JWT.
71+
72+
// We dont need cache bcs we can just use the JWT and after refresh it.
7073
7174
try {
7275
console.debug("[AppShell] Configuring translationEngine.");
@@ -79,31 +82,8 @@
7982
console.debug("[AppShell] Configuring theme engine.");
8083
setTheme("dark");
8184
82-
// Vite connection
83-
if (import.meta.hot) {
84-
import.meta.hot.on("vite:ws:disconnect", () => {
85-
appState.viteConnected = false;
86-
});
87-
88-
import.meta.hot.on("vite:ws:connect", () => {
89-
appState.viteConnected = true;
90-
});
91-
} else {
92-
appState.viteConnected = false;
93-
}
94-
95-
// Is mobile
96-
const mediaQuery = window.matchMedia("(max-width: 768px)");
97-
appState.isMobile = mediaQuery.matches;
98-
99-
const handler = (e: MediaQueryListEvent) => {
100-
appState.isMobile = e.matches;
101-
};
102-
mediaQuery.addEventListener("change", handler);
103-
104-
return () => {
105-
mediaQuery.removeEventListener("change", handler);
106-
};
85+
// AppStateEngine trackers
86+
initTrackers();
10787
});
10888
10989
const toggleSidebar = useShortcut(
@@ -135,12 +115,18 @@
135115
<div class="appshell {currentTheme.themeObject} {styles.base}" id="appshell">
136116
<div class={styles.container}>
137117
<div class={styles.maincontainer}>
138-
{#if appState.isDevelopmentBuild && !appState.viteConnected}
118+
{#if import.meta.env.DEV && !appState.viteConnected}
139119
<Banner icon="sync_problem" appearance="danger">
140120
<b>Vite connection lost.</b>
141121
Hot Module Reloading will be unavailable until reconnected.
142122
</Banner>
143123
{/if}
124+
{#if appState.isOffline}
125+
<Banner icon="cloud_alert" appearance="danger">
126+
<b>Connection lost.</b>
127+
We have lost the connection with Davidnet. Please check your internet connection.
128+
</Banner>
129+
{/if}
144130
{@render banners?.()}
145131

146132
<Flex height="100%" width="100%" direction="column">

src/lib/engines/appStateEngine.svelte.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,40 @@ interface sidebarOpen {
22
sidebarOpen: boolean;
33
isMobile: boolean;
44
viteConnected: boolean;
5-
isDevelopmentBuild: boolean;
5+
isOffline: boolean;
66
}
77

88
export const appState: sidebarOpen = $state({
99
sidebarOpen: false,
1010
isMobile: false,
1111
viteConnected: true,
12-
isDevelopmentBuild: import.meta.env.DEV
12+
isOffline: false
1313
});
14+
15+
export function initTrackers() {
16+
// Vite connection
17+
if (import.meta.hot) {
18+
import.meta.hot.on("vite:ws:disconnect", () => {
19+
appState.viteConnected = false;
20+
});
21+
22+
import.meta.hot.on("vite:ws:connect", () => {
23+
appState.viteConnected = true;
24+
});
25+
} else {
26+
appState.viteConnected = false;
27+
}
28+
29+
// Is mobile
30+
const mediaQuery = window.matchMedia("(max-width: 768px)");
31+
mediaQuery.onchange = (event) => (appState.isMobile = event.matches);
32+
appState.isMobile = mediaQuery.matches;
33+
34+
// Network Status
35+
window.addEventListener("online", () => {
36+
appState.isOffline = false;
37+
});
38+
window.addEventListener("offline", () => {
39+
appState.isOffline = true;
40+
});
41+
}

0 commit comments

Comments
 (0)