auto-refresh

Changed files
+44 -8
src
+37 -8
src/App.svelte
··· 1 1 <script lang="ts"> 2 2 import { onMount } from 'svelte'; 3 - import { Progress } from '@skeletonlabs/skeleton-svelte'; 3 + import { formatDistanceToNow, addSeconds, formatDate, formatISO9075 } from 'date-fns'; 4 + import { Progress, Switch } from '@skeletonlabs/skeleton-svelte'; 4 5 import instancesData from './instances.json'; 5 - import { formatDistanceToNow, addSeconds } from 'date-fns'; 6 6 import numeral from 'numeral'; 7 7 8 + const AUTO_REFRESH_INTERVAL = 15 // in seconds 9 + const BUNDLE_OPS = 10_000 8 10 9 11 type Instance = { 10 12 url: string, ··· 20 22 mempoolPercent: 0, 21 23 }) 22 24 25 + let isUpdating = $state(false) 26 + let canRefresh = $state(true) 27 + let lastUpdated = $state(new Date()) 28 + let autoRefreshEnabled = $state(true) 23 29 let instances = $state(instancesData) 24 30 let instancesSorted = $derived(instances.sort((a, b) => a.status?.responseTime > b.status?.responseTime ? 1 : -1)) 25 31 ··· 56 62 } 57 63 58 64 async function doCheck() { 65 + isUpdating = true 66 + canRefresh = false 59 67 for (const i of instances) { 60 68 i.status = undefined 61 69 } ··· 75 83 } 76 84 } 77 85 instance.status = status 86 + lastUpdated = new Date() 78 87 })) 88 + isUpdating = false 89 + setTimeout(() => (canRefresh = false), 1000) 79 90 } 80 91 81 92 onMount(() => { 82 93 doCheck() 94 + 95 + setTimeout(() => { 96 + if (autoRefreshEnabled) { 97 + doCheck() 98 + } 99 + }, AUTO_REFRESH_INTERVAL * 1000) 83 100 }) 84 101 </script> 85 102 86 103 <main class="w-full mt-10"> 87 104 <div class="max-w-4xl mx-auto px-3"> 88 105 89 - <header class="flex items-center gap-2 flex-wrap"> 106 + <header class="flex items-center gap-10 flex-wrap"> 90 107 <div class="grow"> 91 - <h1 class="text-3xl ">plcbundle instances</h1> 108 + <h1 class="text-3xl linear-text-gradient">plcbundle instances</h1> 92 109 </div> 93 - <div class=""> 94 - <button type="button" class="btn btn-sm preset-tonal-primary" onclick={() => doCheck()}>Refresh</button> 110 + <div class="flex items-center gap-6"> 111 + <Switch class="opacity-75" checked={autoRefreshEnabled} onCheckedChange={(x) => autoRefreshEnabled = x.checked} disabled={isUpdating}> 112 + <Switch.Control className="data-[state=checked]:preset-filled-success-500"> 113 + <Switch.Thumb /> 114 + </Switch.Control> 115 + <Switch.Label>Auto-refresh ({AUTO_REFRESH_INTERVAL}s)</Switch.Label> 116 + <Switch.HiddenInput /> 117 + </Switch> 118 + <button type="button" class="btn btn-sm preset-tonal-primary" onclick={() => doCheck()} disabled={canRefresh}>Refresh</button> 95 119 </div> 96 120 </header> 97 121 ··· 125 149 {#if lastKnownBundle.number > 0} 126 150 <div> 127 151 <div class="font-semibold text-2xl animate-pulse">{lastKnownBundle.number + 1}</div> 128 - <div>{formatNumber(lastKnownBundle.mempool)} / 10,000 <span class="opacity-50">({lastKnownBundle.mempoolPercent}%)</span></div> 152 + <div>{formatNumber(lastKnownBundle.mempool)} / {formatNumber(BUNDLE_OPS)} <span class="opacity-50">({lastKnownBundle.mempoolPercent}%)</span></div> 129 153 {#if lastKnownBundle.etaNext} 130 154 <div class="mt-2 opacity-50">ETA: {formatDistanceToNow(lastKnownBundle.etaNext)}</div> 131 155 {/if} ··· 165 189 </table> 166 190 167 191 <div class="mt-12 opacity-50"> 168 - Source: <a href="https://tangled.org/@tree.fail/plcbundle-watch">https://tangled.org/@tree.fail/plcbundle-watch</a> 192 + <div> 193 + Last updated: {formatISO9075(lastUpdated)} 194 + </div> 195 + <div class="mt-4"> 196 + Source: <a href="https://tangled.org/@tree.fail/plcbundle-watch">https://tangled.org/@tree.fail/plcbundle-watch</a> 197 + </div> 169 198 </div> 170 199 </div> 171 200 </main>
+7
src/app.css
··· 22 22 23 23 [data-theme='cerberus'] { 24 24 --text-scaling: 1.3; 25 + } 26 + 27 + .linear-text-gradient { 28 + background: linear-gradient(325deg, var(--color-surface-50), var(--color-primary-500)); 29 + -webkit-background-clip: text; 30 + background-clip: text; 31 + color: transparent; 25 32 }