106 lines
2.5 KiB
Svelte
106 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from 'svelte';
|
|
import type { BtopData } from '#lib/btop/types';
|
|
import { randomWalk, usageTone } from '#lib/btop/simulate';
|
|
import BtopBox from './BtopBox.svelte';
|
|
|
|
let { data }: { data: BtopData | null } = $props();
|
|
|
|
const updateInterval = 2000;
|
|
|
|
let meters = $state([
|
|
{ label: 'Caffeine', value: 82 },
|
|
{ label: 'Sleep debt', value: 64 },
|
|
{ label: 'Side projects', value: 91 },
|
|
{ label: 'Free time', value: 12 }
|
|
]);
|
|
|
|
const disks = $derived(
|
|
data
|
|
? [
|
|
{ label: 'Public repos', value: `${data.github.publicRepos}` },
|
|
{ label: 'Followers', value: `${data.github.followers}` },
|
|
{ label: 'Total stars', value: `${data.repos.reduce((sum, repo) => sum + repo.stars, 0)}` },
|
|
{ label: 'Total forks', value: `${data.repos.reduce((sum, repo) => sum + repo.forks, 0)}` }
|
|
]
|
|
: []
|
|
);
|
|
|
|
onMount(() => {
|
|
const timer = setInterval(() => {
|
|
meters = meters.map((meter) => ({ ...meter, value: randomWalk(meter.value, 4, 2, 99) }));
|
|
}, updateInterval);
|
|
return () => clearInterval(timer);
|
|
});
|
|
</script>
|
|
|
|
<BtopBox title="mem" number={2} color="yellow">
|
|
<div class="meters">
|
|
{#each meters as meter (meter.label)}
|
|
<div class="meter">
|
|
<div class="meter-label">
|
|
<span>{meter.label}</span>
|
|
<span style:color="var(--{usageTone(meter.value)})">{Math.round(meter.value)}%</span>
|
|
</div>
|
|
<span class="meter-track"><span style:width="{meter.value}%" style:background="var(--{usageTone(meter.value)})"></span></span>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
|
|
{#if disks.length}
|
|
<div class="disks">
|
|
<span class="disks-title">disks</span>
|
|
{#each disks as disk (disk.label)}
|
|
<div class="disk"><span class="muted">{disk.label}</span><span>{disk.value}</span></div>
|
|
{/each}
|
|
</div>
|
|
{/if}
|
|
</BtopBox>
|
|
|
|
<style>
|
|
.meters {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.45rem;
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.meter-label {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 0.15rem;
|
|
}
|
|
|
|
.meter-track {
|
|
display: block;
|
|
height: 6px;
|
|
background: color-mix(in srgb, var(--foreground) 10%, transparent);
|
|
}
|
|
|
|
.meter-track span {
|
|
display: block;
|
|
height: 100%;
|
|
transition: width 0.6s ease;
|
|
}
|
|
|
|
.disks {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.2rem;
|
|
margin-top: 0.7rem;
|
|
padding-top: 0.5rem;
|
|
border-top: 1px dashed color-mix(in srgb, var(--foreground) 20%, transparent);
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.disks-title {
|
|
color: var(--yellow);
|
|
font-weight: 700;
|
|
}
|
|
|
|
.disk {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
</style>
|