Skip to content

Commit d294264

Browse files
committed
feat: improved cache statuses
Signed-off-by: Matt Gleich <git@mattglei.ch>
1 parent fe38870 commit d294264

File tree

4 files changed

+137
-64
lines changed

4 files changed

+137
-64
lines changed

src/lib/icons/refresh-icon.svelte

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<svg
2+
xmlns="http://www.w3.org/2000/svg"
3+
viewBox="0 0 24 24"
4+
fill="none"
5+
stroke="currentColor"
6+
stroke-width="2"
7+
stroke-linecap="round"
8+
stroke-linejoin="round"
9+
><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path
10+
d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"
11+
></path></svg
12+
>

src/lib/time/formatted-date.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
dayjs.extend(utc);
99
dayjs.extend(timezonePlugin);
1010
11-
const { time }: { time: Date } = $props();
11+
const { time, lowercase = false }: { time: Date; lowercase?: boolean } = $props();
1212
1313
let dayjsTime = dayjs(time);
1414
let now = $state(dayjs());
@@ -23,4 +23,8 @@
2323
});
2424
</script>
2525

26-
{renderDate(dayjsTime, now)} [{fromNow(dayjsTime, now)}]
26+
{#if lowercase}
27+
{renderDate(dayjsTime, now).toLowerCase()} [{fromNow(dayjsTime, now).toLowerCase()}]
28+
{:else}
29+
{renderDate(dayjsTime, now)} [{fromNow(dayjsTime, now)}]
30+
{/if}

src/routes/writing/lcp/+page.svelte

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,38 @@
2121
{#await data.projects}
2222
<p>Loading projects cache...</p>
2323
{:then projects}
24-
<CacheStatus name="Projects" updated={projects?.updated} />
24+
<CacheStatus
25+
name="Projects"
26+
updated={projects?.updated}
27+
updateFrequency="Refreshed data every 60 seconds"
28+
/>
2529
{/await}
2630
{#await data.workouts}
2731
<p>Loading workouts cache...</p>
2832
{:then workouts}
29-
<CacheStatus name="Workouts" updated={workouts?.updated} />
33+
<CacheStatus
34+
name="Workouts"
35+
updated={workouts?.updated}
36+
updateFrequency="Refreshing when data changes"
37+
/>
3038
{/await}
3139
{#await data.music}
3240
<p>Loading music cache...</p>
3341
{:then music}
34-
<CacheStatus name="Music" updated={music?.updated} />
42+
<CacheStatus
43+
name="Music"
44+
updated={music?.updated}
45+
updateFrequency="Refreshing every 30 seconds"
46+
/>
3547
{/await}
3648
{#await data.games}
3749
<p>Loading games cache...</p>
3850
{:then games}
39-
<CacheStatus name="Games" updated={games?.updated} />
51+
<CacheStatus
52+
name="Games"
53+
updated={games?.updated}
54+
updateFrequency="Refreshing every 5 minutes"
55+
/>
4056
{/await}
4157
</div>
4258
</WritingSection>
@@ -229,7 +245,7 @@
229245
.statuses {
230246
display: grid;
231247
grid-template-columns: 1fr 1fr;
232-
gap: 5px;
248+
gap: 10px;
233249
align-items: center;
234250
width: 100%;
235251
}
@@ -251,7 +267,7 @@
251267
margin: 10px 0;
252268
}
253269
254-
@media (max-width: 860px) {
270+
@media (max-width: 830px) {
255271
.statuses {
256272
grid-template-columns: 1fr;
257273
}
Lines changed: 97 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,123 @@
11
<script lang="ts">
2-
import Since from '$lib/time/since.svelte';
3-
import { onMount } from 'svelte';
2+
import RefreshIcon from '$lib/icons/refresh-icon.svelte';
3+
import FormattedDate from '$lib/time/formatted-date.svelte';
4+
import { Card } from '@gleich/ui';
45
5-
const loadingFrames = [
6-
'[    ]', // 0%
7-
'[⋅   ]', // 6.25%
8-
'[⋅⋅  ]', // 12.5%
9-
'[⋅⋅⋅ ]', // 18.75%
10-
'[ ⋅⋅⋅]', // 25%
11-
'[  ⋅⋅]', // 31.25%
12-
'[   ⋅]', // 37.5%
13-
'[    ]', // 43.75%
14-
'[   ⋅]', // 50%
15-
'[  ⋅⋅]', // 56.25%
16-
'[ ⋅⋅⋅]', // 62.5%
17-
'[⋅⋅⋅⋅]', // 68.75%
18-
'[⋅⋅⋅ ]', // 75%
19-
'[⋅⋅  ]', // 81.25%
20-
'[⋅   ]', // 87.5%
21-
'[    ]', // 93.75%
22-
'[    ]' // 100%
23-
];
24-
let frameIndex = $state(0);
25-
let frame = $derived(loadingFrames[frameIndex]);
26-
27-
onMount(() => {
28-
const interval = setInterval(() => {
29-
frameIndex = (frameIndex + 1) % loadingFrames.length;
30-
}, 30);
31-
return () => clearInterval(interval);
32-
});
33-
34-
const { name, updated }: { name: string; updated?: Date } = $props();
6+
const {
7+
name,
8+
updated,
9+
updateFrequency
10+
}: { name: string; updated?: Date; updateFrequency: string } = $props();
3511
</script>
3612

37-
<div class="container">
38-
<p class="frame">{frame}</p>
39-
<p class="online">ONLINE</p>
40-
<p class="name">{name} <span class="cache-text"> cache</span></p>
41-
<p class="updated"><Since time={updated ?? new Date()} /></p>
42-
</div>
13+
<Card padding="0">
14+
<div class="container">
15+
<div class="header">
16+
<p class="cache-name">{name} Cache</p>
17+
{#if updated}
18+
<p class="online">ONLINE</p>
19+
{:else}
20+
<p class="offline">OFFLINE</p>
21+
{/if}
22+
</div>
23+
</div>
24+
<div class="refresh">
25+
<div class="refresh-icon">
26+
<RefreshIcon />
27+
</div>
28+
<p>{updateFrequency}</p>
29+
</div>
30+
<div class="updated">
31+
{#if updated}
32+
Updated <FormattedDate lowercase time={updated} />
33+
{:else}
34+
Cache is currently offline
35+
{/if}
36+
</div>
37+
</Card>
4338

4439
<style>
45-
.container {
46-
display: flex;
47-
gap: 5px;
40+
.cache-name {
41+
font-size: 19px;
42+
padding-left: 10px;
43+
padding-top: 6px;
44+
font-family: 'Inter';
45+
font-weight: 700;
46+
background-color: #343537;
47+
box-shadow: inset 0px 0px 6px var(--box-shadow-color);
48+
border: 1px solid var(--border);
49+
border-top: 0;
50+
border-left: 0;
51+
border-bottom-right-radius: var(--border-radius);
52+
padding-bottom: 5px;
53+
padding-right: 10px;
4854
}
4955
50-
.frame {
51-
white-space: pre;
52-
display: inline-block;
53-
font-family: 'IBM Plex Mono';
56+
.header {
57+
display: flex;
58+
justify-content: space-between;
5459
}
5560
56-
.name {
57-
width: 120px;
61+
.online,
62+
.offline {
63+
font-family: 'IBM Plex Mono';
64+
display: flex;
65+
align-items: center;
66+
padding: 4px 10px;
67+
border-top: 0 !important;
68+
border-right: 0 !important;
69+
font-size: 14px;
70+
border-bottom-left-radius: var(--border-radius);
5871
}
5972
6073
.online {
6174
color: var(--green-foreground);
6275
background-color: var(--green-background);
63-
padding: 0 5px;
64-
margin: 0 5px;
65-
border-radius: 2px;
76+
border: 1px solid var(--green-border);
77+
}
78+
79+
.offline {
80+
color: var(--red-foreground);
81+
background-color: var(--red-background);
82+
border: 1px solid var(--red-border);
83+
}
84+
85+
.refresh {
86+
padding: 20px 10px;
87+
display: flex;
88+
gap: 10px;
89+
align-items: center;
90+
justify-content: center;
91+
}
92+
93+
.refresh-icon :global(svg) {
94+
position: relative;
95+
top: 1px;
96+
width: 14px;
97+
height: 14px;
98+
animation: spin 3s linear infinite;
99+
transform-origin: center;
66100
}
67101
68102
.updated {
69-
margin-left: 5px;
70103
color: grey;
104+
border-top: 1px solid var(--border);
105+
padding: 5px;
106+
display: flex;
107+
align-items: center;
108+
justify-content: center;
109+
font-size: 14px;
71110
}
72111
73-
@media (max-width: 450px) {
74-
.cache-text {
75-
display: none;
112+
@keyframes spin {
113+
to {
114+
transform: rotate(360deg);
76115
}
116+
}
77117
78-
.name {
79-
width: 80px;
118+
@media (max-width: 500px) {
119+
.cache-name {
120+
font-size: 15px;
80121
}
81122
}
82123
</style>

0 commit comments

Comments
 (0)