-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.jsx
More file actions
98 lines (88 loc) · 3 KB
/
Copy pathapp.jsx
File metadata and controls
98 lines (88 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* eslint-disable */
const { useEffect, useState } = React;
const SITE_DEFAULTS = {
"theme": "system",
"type": "default",
"density": "default",
"texture": "none",
"heroLineA": "Rasmus",
"heroLineB": "Tikkanen,",
"heroAccent": "learning",
"heroLineC": "embedded.",
"lede": "Studying IoT and embedded development in Stockholm. I like working where hardware meets software - mixed-domain signals, analog and digital electronics."
};
function App() {
const [now, setNow] = useState("");
const SHOW_WRITING = true;
useEffect(() => {
const applyTheme = (themeVal) => {
if (themeVal === 'system') {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
document.body.dataset.theme = prefersDark ? 'dark' : 'light';
} else {
document.body.dataset.theme = themeVal;
}
document.body.dataset.type = SITE_DEFAULTS.type;
document.body.dataset.density = SITE_DEFAULTS.density;
document.body.dataset.texture = SITE_DEFAULTS.texture;
};
applyTheme(SITE_DEFAULTS.theme);
let mql;
const onPrefChange = (e) => {
if (SITE_DEFAULTS.theme === 'system') applyTheme('system');
};
if (window.matchMedia) {
mql = window.matchMedia('(prefers-color-scheme: dark)');
if (mql.addEventListener) mql.addEventListener('change', onPrefChange);
else if (mql.addListener) mql.addListener(onPrefChange);
}
return () => {
if (mql) {
if (mql.removeEventListener) mql.removeEventListener('change', onPrefChange);
else if (mql.removeListener) mql.removeListener(onPrefChange);
}
};
}, []);
// The browser resolves the URL fragment before React has rendered any
// section, so a direct link like /#oss lands at the top. Re-apply it once
// the tree is mounted; scroll-margin-top in styles.css keeps the offset.
useEffect(() => {
if (!window.location.hash) return;
const target = document.getElementById(window.location.hash.slice(1));
if (target) requestAnimationFrame(() => target.scrollIntoView());
}, []);
useEffect(() => {
const tick = () => {
const d = new Date();
const hh = String(d.getHours()).padStart(2, "0");
const mm = String(d.getMinutes()).padStart(2, "0");
const ss = String(d.getSeconds()).padStart(2, "0");
setNow(`${hh}:${mm}:${ss} EET`);
};
tick();
const id = setInterval(tick, 1000);
return () => clearInterval(id);
}, []);
return (
<>
<TopBar now={now} />
<main>
<Hero
heroLineA={SITE_DEFAULTS.heroLineA}
heroLineB={SITE_DEFAULTS.heroLineB}
heroAccent={SITE_DEFAULTS.heroAccent}
heroLineC={SITE_DEFAULTS.heroLineC}
lede={SITE_DEFAULTS.lede}
/>
<About />
<Projects />
<OpenSource />
{SHOW_WRITING && <Writing />}
<Experience />
<Contact />
</main>
<Footer />
</>
);
}
ReactDOM.createRoot(document.getElementById("root")).render(<App />);