learn and share notes on atproto (wip) 馃 malfestio.stormlightlabs.org/
readability solid axum atproto srs
at main 63 lines 1.7 kB view raw
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}