learn and share notes on atproto (wip) 馃
malfestio.stormlightlabs.org/
readability
solid
axum
atproto
srs
1import { syncStore } from "$lib/sync-store";
2import { Show } from "solid-js";
3
4export function SyncIndicator() {
5 const stateClasses = () => {
6 const state = syncStore.syncState();
7 switch (state) {
8 case "syncing":
9 return "text-blue-500";
10 case "error":
11 return "text-red-500";
12 case "offline":
13 return "text-amber-500";
14 default:
15 return "text-green-500";
16 }
17 };
18
19 const stateIcon = () => {
20 const state = syncStore.syncState();
21 switch (state) {
22 case "syncing":
23 return "i-ri-loader-4-line animate-spin";
24 case "error":
25 return "i-ri-error-warning-line";
26 case "offline":
27 return "i-ri-wifi-off-line";
28 default:
29 return "i-ri-cloud-line";
30 }
31 };
32
33 const stateLabel = () => {
34 const state = syncStore.syncState();
35 switch (state) {
36 case "syncing":
37 return "Syncing...";
38 case "error":
39 return "Sync error";
40 case "offline":
41 return "Offline";
42 default:
43 return "Synced";
44 }
45 };
46
47 return (
48 <div class="flex items-center gap-2 text-sm">
49 <span class={`${stateIcon()} ${stateClasses()}`} />
50 <span class={stateClasses()}>{stateLabel()}</span>
51 <Show when={syncStore.pendingCount() > 0}>
52 <span class="rounded-full bg-blue-100 px-2 py-0.5 text-xs text-blue-700">
53 {syncStore.pendingCount()} pending
54 </span>
55 </Show>
56 <Show when={syncStore.conflictCount() > 0}>
57 <span class="rounded-full bg-red-100 px-2 py-0.5 text-xs text-red-700">
58 {syncStore.conflictCount()} conflicts
59 </span>
60 </Show>
61 </div>
62 );
63}