- Best share page: hex + binary hash comparison against network target, per-bit coloring showing exactly which bits prevented a valid block, toggle between network diff at time of finding vs current diff - Capture best share hash from ckpool logs with one-time backfill - Persist network difficulty at time of best share for historical accuracy - Add miner (worker) column to blocks table via coinbase address matching - Truncate block hashes in table with full hash on hover - Increase hashrate chart Y-axis to 7 ticks for better readability
145 lines
3.4 KiB
Svelte
145 lines
3.4 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from "svelte";
|
|
import { connect, snap } from "./stores/snapshot.svelte";
|
|
import { selection } from "./stores/selection.svelte";
|
|
import Header from "./lib/Header.svelte";
|
|
import HealthBanners from "./lib/HealthBanners.svelte";
|
|
import PoolOverview from "./lib/PoolOverview.svelte";
|
|
import HashrateChart from "./lib/HashrateChart.svelte";
|
|
import MinersTable from "./lib/MinersTable.svelte";
|
|
import BlocksTable from "./lib/BlocksTable.svelte";
|
|
import BestShares from "./lib/BestShares.svelte";
|
|
import UserDetailPage from "./lib/UserDetailPage.svelte";
|
|
import WorkerDetailPage from "./lib/WorkerDetailPage.svelte";
|
|
import AcceleratorPage from "./lib/AcceleratorPage.svelte";
|
|
import StatsPage from "./lib/StatsPage.svelte";
|
|
import BestSharePage from "./lib/BestSharePage.svelte";
|
|
import SharesBar from "./lib/SharesBar.svelte";
|
|
import BlockFoundAnimation from "./lib/BlockFoundAnimation.svelte";
|
|
|
|
onMount(() => {
|
|
connect();
|
|
});
|
|
</script>
|
|
|
|
<main class:no-bg={selection.page === "accelerator"}>
|
|
<Header />
|
|
|
|
{#if snap.data}
|
|
<HealthBanners />
|
|
{/if}
|
|
|
|
{#if !snap.data}
|
|
<div class="card placeholder page-enter">
|
|
<div class="stat-label">Status</div>
|
|
<div class="stat-value">Connecting to kamado-api…</div>
|
|
{#if snap.error}
|
|
<div class="stat-sub bad">{snap.error}</div>
|
|
{/if}
|
|
</div>
|
|
{:else if selection.page === "accelerator"}
|
|
{#key 'accelerator'}
|
|
<div class="page-enter">
|
|
<AcceleratorPage />
|
|
</div>
|
|
{/key}
|
|
{:else if selection.page === "stats"}
|
|
{#key 'stats'}
|
|
<div class="page-enter">
|
|
<StatsPage />
|
|
</div>
|
|
{/key}
|
|
{:else if selection.page === "bestshare"}
|
|
{#key 'bestshare'}
|
|
<div class="page-enter">
|
|
<BestSharePage />
|
|
</div>
|
|
{/key}
|
|
{:else if selection.worker}
|
|
{#key selection.worker}
|
|
<div class="page-enter">
|
|
<WorkerDetailPage />
|
|
</div>
|
|
{/key}
|
|
{:else if selection.user}
|
|
{#key selection.user}
|
|
<div class="page-enter">
|
|
<UserDetailPage />
|
|
</div>
|
|
{/key}
|
|
{:else}
|
|
{#key 'dashboard'}
|
|
<div class="page-enter">
|
|
<PoolOverview />
|
|
<SharesBar />
|
|
<HashrateChart />
|
|
<BlocksTable />
|
|
<BestShares />
|
|
<MinersTable />
|
|
</div>
|
|
{/key}
|
|
{/if}
|
|
</main>
|
|
|
|
<BlockFoundAnimation />
|
|
|
|
<style>
|
|
main {
|
|
position: relative;
|
|
max-width: 1280px;
|
|
margin: 0 auto;
|
|
padding: 1.5rem 1.25rem 4rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1.25rem;
|
|
}
|
|
main::before {
|
|
content: '';
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: -1;
|
|
background: url('/tanjiro2.jpg') center center / cover no-repeat;
|
|
opacity: 0.12;
|
|
pointer-events: none;
|
|
transition: opacity 0.4s ease;
|
|
}
|
|
main.no-bg::before {
|
|
opacity: 0;
|
|
}
|
|
main::after {
|
|
content: '';
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: -1;
|
|
background: url('/rengoku1.jpg') center center / cover no-repeat;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 0.4s ease;
|
|
}
|
|
main.no-bg::after {
|
|
opacity: 0.30;
|
|
}
|
|
.placeholder {
|
|
text-align: center;
|
|
}
|
|
.bad {
|
|
color: var(--bad);
|
|
}
|
|
.page-enter {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1.25rem;
|
|
animation: page-fade-in 0.3s ease-out;
|
|
}
|
|
@keyframes page-fade-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(8px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
</style>
|