Skip to content

Commit 5dbc192

Browse files
Merge pull request #47 from sebastiankrll/performance/web
Performance/web
2 parents 207188b + eafa719 commit 5dbc192

File tree

13 files changed

+168
-192
lines changed

13 files changed

+168
-192
lines changed

apps/web/app/globals.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ html {
3535
--color-magenta: rgb(222, 89, 234);
3636
--color-glass-bg: rgba(255, 255, 255, 0.5);
3737
--color-hover: rgb(77, 95, 131);
38+
--box-shadow: 1px 1px 5px 1px var(--color-box-shadow);
3839
}
3940

4041
[data-theme="dark"] {

apps/web/components/Header/Header.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ import { signIn, useSession } from "next-auth/react";
77
import { useEffect, useRef, useState } from "react";
88
import simradar24Logo from "@/assets/images/logos/Simradar21_Logo.svg";
99
import VatsimLogo from "@/assets/images/logos/VATSIM_Logo_Only.png";
10+
import useSettings from "@/hooks/useSettings";
1011
import Navigation from "./Navigation";
1112

1213
export default function Header() {
1314
const [open, setOpen] = useState(false);
1415
const headerRef = useRef<HTMLElement>(null);
16+
1517
const { data: session } = useSession();
1618

19+
useSettings();
20+
1721
useEffect(() => {
1822
function handleClickOutside(event: MouseEvent) {
1923
if (headerRef.current && !headerRef.current.contains(event.target as Node)) {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#initializer {
2+
position: absolute;
3+
top: -5rem;
4+
left: 50%;
5+
transform: translateX(-50%);
6+
background-color: var(--color-blue);
7+
width: 20rem;
8+
z-index: 1000;
9+
box-shadow: var(--box-shadow);
10+
padding: 0.5rem 1rem;
11+
transition: all 0.5s ease;
12+
opacity: 0;
13+
}
14+
15+
#initializer.open {
16+
top: 4.5rem;
17+
opacity: 1;
18+
}
19+
20+
#initializer p {
21+
color: white;
22+
}
23+
24+
#initializer-title {
25+
font-weight: 700;
26+
}
27+
28+
#initializer-disclaimer {
29+
font-size: 14px;
30+
}
31+
32+
#initializer-text {
33+
margin-top: 10px;
34+
font-size: 12px;
35+
}
36+
37+
#initializer-progress {
38+
position: absolute;
39+
left: 0;
40+
top: 0;
41+
background: var(--color-green);
42+
width: 0%;
43+
height: 100%;
44+
z-index: -1;
45+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"use client";
2+
3+
import { useEffect, useState } from "react";
4+
import { initCache } from "@/storage/cache";
5+
import "./Initializer.css";
6+
import { usePathname } from "next/navigation";
7+
import type { StatusMap } from "@/types/initializer";
8+
9+
function getInitializerText(status: StatusMap): string {
10+
if (!status.airports) {
11+
return "Downloading airport data ...";
12+
} else if (!status.firs) {
13+
return "Downloading VAT-Spy data ...";
14+
} else if (!status.tracons) {
15+
return "Downloading SimAware data ...";
16+
} else if (!status.airlines) {
17+
return "Downloading airline data ...";
18+
} else if (!status.cache) {
19+
return "Initializing local cache ...";
20+
} else if (!status.map) {
21+
return "Setting up map ...";
22+
} else {
23+
return "Initialization complete!";
24+
}
25+
}
26+
27+
export default function Initializer() {
28+
const [open, setOpen] = useState(true);
29+
const [visible, setVisible] = useState(true);
30+
const [status, setStatus] = useState<StatusMap>({});
31+
const pathname = usePathname();
32+
33+
useEffect(() => {
34+
initCache(setStatus, pathname);
35+
return () => {};
36+
}, [pathname]);
37+
38+
useEffect(() => {
39+
if (status.airports && status.firs && status.tracons && status.airlines && status.cache && status.map) {
40+
setOpen(false);
41+
setTimeout(() => setVisible(false), 500);
42+
}
43+
}, [status]);
44+
45+
if (!visible) {
46+
return null;
47+
}
48+
49+
return (
50+
<div id="initializer" className={open ? "open" : ""}>
51+
<span id="initializer-progress" style={{ width: `${(Object.keys(status).length / 6) * 100}%` }}></span>
52+
<p id="initializer-title">Initializing data ...</p>
53+
<p id="initializer-disclaimer">This can take up to a minute during the first load.</p>
54+
<p id="initializer-text">{getInitializerText(status)}</p>
55+
</div>
56+
);
57+
}

apps/web/components/Loader/Loader.css

Lines changed: 0 additions & 88 deletions
This file was deleted.

apps/web/components/Loader/Loader.tsx

Lines changed: 0 additions & 86 deletions
This file was deleted.

apps/web/components/Map/Map.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useRouter } from "next/navigation";
66
import { useTheme } from "next-themes";
77
import { ToastContainer } from "react-toastify";
88
import { useSettingsStore } from "@/storage/zustand";
9-
import Loader from "../Loader/Loader";
9+
import Initializer from "../Initializer/Initializer";
1010
import { MessageBoxCloseButton } from "../MessageBox/MessageBox";
1111
import BasePanel from "../Panels/BasePanel";
1212
import MapControls from "./components/MapControls";
@@ -18,6 +18,7 @@ import { setSunLayerSettings } from "./utils/sunLayer";
1818

1919
export default function OMap({ children }: { children?: React.ReactNode }) {
2020
const router = useRouter();
21+
2122
const { theme } = useTheme();
2223
const {
2324
dayNightLayer,
@@ -99,7 +100,7 @@ export default function OMap({ children }: { children?: React.ReactNode }) {
99100
return (
100101
<>
101102
<ToastContainer closeButton={MessageBoxCloseButton} icon={false} theme="colored" />
102-
<Loader />
103+
<Initializer />
103104
<BasePanel>{children}</BasePanel>
104105
<MapControls />
105106
<div id="map" />

apps/web/components/Map/utils/pilotFeatures.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ export function animatePilotFeatures(map: OlMap) {
220220
feature.set("latitude", newLat, true);
221221
feature.set("longitude", newLon, true);
222222
});
223-
map.render();
223+
224224
animateOverlays();
225225
animateTrackFeatures();
226226

apps/web/hooks/useSettings.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"use client";
2+
3+
import { useSession } from "next-auth/react";
4+
import { useTheme } from "next-themes";
5+
import { useEffect } from "react";
6+
import { useSettingsStore } from "@/storage/zustand";
7+
8+
export default function useSettings() {
9+
const { setTheme } = useTheme();
10+
const { theme: settingsTheme, setSettings } = useSettingsStore();
11+
const { data: session } = useSession();
12+
13+
useEffect(() => {
14+
setTheme(settingsTheme);
15+
}, [settingsTheme, setTheme]);
16+
17+
useEffect(() => {
18+
if (!session) return;
19+
20+
const fetchUserSettings = async () => {
21+
try {
22+
const res = await fetch("/user/settings", { cache: "no-store" });
23+
if (!res.ok) {
24+
return;
25+
}
26+
27+
const data = await res.json();
28+
setSettings(data.settings);
29+
} catch (err) {
30+
console.error("Failed to load settings:", err);
31+
}
32+
};
33+
34+
fetchUserSettings();
35+
}, [setSettings, session]);
36+
}

0 commit comments

Comments
 (0)