Skip to content

Commit 043fc2c

Browse files
committed
fix $darkTheme store
1 parent 253714b commit 043fc2c

File tree

5 files changed

+42
-49
lines changed

5 files changed

+42
-49
lines changed

src/components/loaders/Cards.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<script lang="ts" context="module">
1010
import ContentLoader from 'svelte-content-loader';
11-
import { media } from '@/stores/media';
11+
import { darkTheme } from '@/stores/theme';
1212
</script>
1313

1414
<script lang="ts">
@@ -24,5 +24,5 @@
2424
2525
$: x = (width - cols * w) / cols + cols / 2;
2626
$: y = (height - rows * h) / rows + rows / 2;
27-
$: colors = $media.dark ? { primaryColor: '#303742', secondaryColor: '#252b33' } : {};
27+
$: colors = $darkTheme ? { primaryColor: '#303742', secondaryColor: '#252b33' } : {};
2828
</script>

src/stores/media.ts

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { writable } from 'svelte/store';
1+
import { type Readable, readable } from 'svelte/store';
22

3-
type MediaQuery = {
3+
export type Queries = {
44
[key: string]: boolean | string;
55
};
6-
type BrowserStorage = {
7-
type: string
8-
key: string
6+
7+
type MediaObject = {
8+
[key: string]: MediaQueryList
99
}
1010

11-
const mediaQueries: MediaQuery = {
11+
const queries: Queries = {
1212
xs: '(max-width: 480px)',
1313
sm: '(max-width: 600px)',
1414
md: '(max-width: 840px)',
@@ -23,43 +23,29 @@ const mediaQueries: MediaQuery = {
2323
touch: '(hover: none)',
2424
};
2525

26-
export const media = watchMedia(mediaQueries, { key: 'optimade-media' })
27-
28-
function watchMedia(queries: MediaQuery, storage: Partial<BrowserStorage>) {
29-
const { subscribe, set, update } = writable({});
30-
const base = { type: 'session', key: 'media-query' }
31-
32-
storage = { ...base, ...storage }
33-
34-
if (persist(storage)) {
35-
const match: MediaQuery = JSON.parse(persist(storage).getItem(storage.key as string) as string) || {};
36-
37-
for (const query in queries) {
38-
const media = window.matchMedia(queries[query] as string)
39-
setMatches(media, query)
40-
media.onchange = (e) => setMatches(e, query)
26+
export const media: Readable<Queries> = mediaStore(queries)
27+
28+
function mediaStore(queries: Queries = {}) {
29+
return readable({}, (set) => {
30+
let mqs = Object.entries(queries).reduce((mqs: MediaObject, [key, query]) => {
31+
mqs[key] = window.matchMedia(query as string);
32+
mqs[key].onchange = (mq) => {
33+
mqs[key] = mq;
34+
update();
35+
};
36+
return mqs as MediaObject;
37+
}, {});
38+
39+
function update() {
40+
const matches: Queries = Object.entries(mqs).reduce((matches: Queries, [key, mq]) => {
41+
matches[key] = mq.matches;
42+
return matches;
43+
}, {});
44+
set(matches);
4145
}
4246

43-
subscribe((match): void => persist(storage).setItem(storage.key as string, JSON.stringify(match)));
44-
45-
function setMatches(media: MediaQueryList | MediaQueryListEvent, query: string) {
46-
if ('target' in media) match[query] = media.matches;
47-
else match[query] ??= media.matches;
48-
set(match);
49-
persist(storage).setItem(storage.key as string, JSON.stringify(match));
50-
}
51-
}
52-
53-
function persist(storage: Partial<BrowserStorage>): Storage {
54-
try {
55-
const store = storage.type === 'session' ? sessionStorage : localStorage
56-
store.setItem(storage.key as string, storage.key as string);
57-
store.removeItem(storage.key as string);
58-
return store;
59-
} catch (e) {
60-
console.error(e)
61-
}
62-
}
47+
update();
6348

64-
return { subscribe, set, update }
49+
return () => mqs = {};
50+
});
6551
}

src/stores/theme.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { writable, get } from 'svelte/store';
2+
import { media } from '@/stores/media';
3+
4+
export const darkTheme = writable(
5+
JSON.parse(sessionStorage.getItem('optimade_darkTheme') as string) ?? get(media).dark
6+
);
7+
darkTheme.subscribe((val) => sessionStorage.setItem('optimade_darkTheme', val));

src/views/Footer.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<a href="http://www.optimade.org" target="_blank">OPTIMADE</a> standard &mdash; Open Databases Integration for Materials Design.
88
</Col>
99
<Col col="auto">
10-
<Switch bind:value={$media.dark}>Dark theme</Switch>
10+
<Switch bind:value={$darkTheme}>Dark theme</Switch>
1111
</Col>
1212
</Grid>
1313
</Container>
@@ -18,9 +18,9 @@
1818
1919
import { nodeAttribute } from '@/helpers/dom';
2020
21-
import { media } from '@/stores/media';
21+
import { darkTheme } from '@/stores/theme';
2222
23-
$: nodeAttribute(document.documentElement, 'color-scheme', $media.dark ? 'dark' : 'light');
23+
$: nodeAttribute(document.documentElement, 'color-scheme', $darkTheme ? 'dark' : 'light');
2424
</script>
2525

2626
<style lang="scss">

src/views/Result.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<Col col="5" md="12">
1717
<ModuleSelect bind:selectedValue={module} />
1818
<br />
19-
<Hero size="sm" bg={$media.dark ? 'dark' : 'gray'}>
19+
<Hero size="sm" bg={$darkTheme ? 'dark' : 'gray'}>
2020
<div class="module">
2121
<iframe name="visualisationFrame" bind:this={iframe} src={module} title="Module window" />
2222
</div>
@@ -29,7 +29,7 @@
2929

3030
<script lang="ts" context="module">
3131
import { Col, Divider, Grid, Hero, Input, Steps } from 'svelte-spectre';
32-
import { media } from '@/stores/media';
32+
import { darkTheme } from '@/stores/theme';
3333
3434
import ModuleSelect from '@/views/ModuleSelect/ModuleSelect.svelte';
3535
import * as JSON from '@/components/JSON';

0 commit comments

Comments
 (0)