commit 66fcf3a721db53c2424fcd169a90f4e45b18bc99
parent b308e2ee773300d79dffdef3d7f96af32e17dc28
Author: Damian Myrda <damian@prime8.dev>
Date: Wed, 21 Jan 2026 17:15:40 -0600
refactor: extract constants and types, speed up boot animation
- Extract WakaTime types to web/src/lib/types/wakatime.ts
- Move WakaTime API constants to web/src/constants/wakatime.ts
- Add env constant for NODE_ENV detection
- Speed up boot animation timings and change progress bar to white
- Skip boot animation check in dev environment
- Fix Zed tasks.json: working_directory -> cwd
Diffstat:
6 files changed, 43 insertions(+), 36 deletions(-)
diff --git a/.zed/tasks.json b/.zed/tasks.json
@@ -3,6 +3,6 @@
"label": "web: dev",
"command": "bun",
"args": ["run", "dev"],
- "working_directory": "$ZED_WORKTREE_ROOT/web",
+ "cwd": "$ZED_WORKTREE_ROOT/web",
},
]
diff --git a/web/src/constants/env.ts b/web/src/constants/env.ts
@@ -0,0 +1 @@
+export default import.meta.env.NODE_ENV as "dev" | "prod";
diff --git a/web/src/constants/wakatime.ts b/web/src/constants/wakatime.ts
@@ -0,0 +1,2 @@
+export const WAKATIME_API_BASE = "https://wakatime.com/api/v1";
+export const WAKATIME_API_KEY = import.meta.env.WAKATIME_API_KEY;
diff --git a/web/src/lib/types/wakatime.ts b/web/src/lib/types/wakatime.ts
@@ -0,0 +1,21 @@
+export interface WakaTimeData {
+ allTimeStats: AllTimeStats | null;
+ weeklyStats: WeeklyStats | null;
+}
+
+export interface AllTimeStats {
+ totalText: string;
+ dailyAverageText: string;
+}
+
+export interface WeeklyStats {
+ totalText: string;
+ days: DailyEntry[];
+}
+
+export interface DailyEntry {
+ dayText: string; // e.g., "Mon", "Tue"
+ dateText: string; // e.g., "Jan 10"
+ timeText: string; // e.g., "2 hrs 30 mins"
+ barWidthPercent: string; // e.g., "75%"
+}
diff --git a/web/src/lib/wakatime.ts b/web/src/lib/wakatime.ts
@@ -1,15 +1,13 @@
+import type {
+ AllTimeStats,
+ DailyEntry,
+ WakaTimeData,
+ WeeklyStats,
+} from "./types/wakatime";
import { DAY_NAMES, MONTH_NAMES } from "../constants/calendar";
+import { WAKATIME_API_BASE, WAKATIME_API_KEY } from "../constants/wakatime";
import { formatDuration } from "./utils/duration";
-const WAKATIME_API_BASE = "https://wakatime.com/api/v1";
-
-const WAKATIME_API_KEY = import.meta.env.WAKATIME_API_KEY;
-
-export interface WakaTimeData {
- allTimeStats: AllTimeStats | null;
- weeklyStats: WeeklyStats | null;
-}
-
export async function fetchWakaTimeData(): Promise<WakaTimeData | null> {
if (!WAKATIME_API_KEY) {
return null;
@@ -28,11 +26,6 @@ export async function fetchWakaTimeData(): Promise<WakaTimeData | null> {
}
}
-export interface AllTimeStats {
- totalText: string;
- dailyAverageText: string;
-}
-
export async function fetchAllTimeStats(): Promise<AllTimeStats | null> {
try {
const [statsResponse, languagesResponse] = [
@@ -75,18 +68,6 @@ export async function fetchAllTimeStats(): Promise<AllTimeStats | null> {
}
}
-export interface WeeklyStats {
- totalText: string;
- days: DailyEntry[];
-}
-
-export interface DailyEntry {
- dayText: string; // e.g., "Mon", "Tue"
- dateText: string; // e.g., "Jan 10"
- timeText: string; // e.g., "2 hrs 30 mins"
- barWidthPercent: string; // e.g., "75%"
-}
-
export async function fetchWeeklyStats(): Promise<WeeklyStats | null> {
try {
const start = new Date();
diff --git a/web/src/scripts/ui/boot.ts b/web/src/scripts/ui/boot.ts
@@ -1,3 +1,5 @@
+import env from "../../constants/env";
+
interface SystemInfo {
platform: string;
browser: string;
@@ -104,7 +106,7 @@ async function runBootSequence(overlay: HTMLElement): Promise<void> {
const cursor = overlay.querySelector(".boot-cursor") as HTMLElement;
const messages = generateBootMessages();
- await sleep(200);
+ await sleep(150);
for (let i = 0; i < messages.length; i++) {
const line = messages[i];
@@ -113,23 +115,23 @@ async function runBootSequence(overlay: HTMLElement): Promise<void> {
lineEl.innerHTML = line || " ";
content.appendChild(lineEl);
- await sleep(50);
+ await sleep(40);
lineEl.classList.remove("boot-line-hidden");
lineEl.classList.add("boot-line-visible");
}
- await sleep(400);
+ await sleep(300);
const startMsg = document.createElement("div");
startMsg.className = "boot-line boot-line-hidden";
startMsg.innerHTML =
- '<br><span class="ansi-bold-green">Starting prime8dev...</span>';
+ '<br><span class="ansi-bold-white">Starting prime8dev...</span>';
content.appendChild(startMsg);
await sleep(60);
startMsg.classList.remove("boot-line-hidden");
startMsg.classList.add("boot-line-visible");
- await sleep(500);
+ await sleep(400);
cursor.style.display = "none";
@@ -142,11 +144,11 @@ async function runBootSequence(overlay: HTMLElement): Promise<void> {
const filled = "=".repeat(i);
const arrow = i < progressWidth ? ">" : "=";
const empty = " ".repeat(progressWidth - i);
- progressBar.innerHTML = `<span class="ansi-bold-green">[${filled}${arrow}${empty}]</span> ${Math.round((i / progressWidth) * 100)}%`;
- await sleep(25);
+ progressBar.innerHTML = `<span class="ansi-bold-white">[${filled}${arrow}${empty}]</span> ${Math.round((i / progressWidth) * 100)}%`;
+ await sleep(20);
}
- await sleep(250);
+ await sleep(200);
overlay.classList.add("fade-out");
await sleep(400);
@@ -158,7 +160,7 @@ export async function playBootAnimation(): Promise<void> {
const BOOT_KEY = "prime8dev-boot-shown";
const app = document.getElementById("app");
- if (sessionStorage.getItem(BOOT_KEY)) {
+ if (env === "prod" && sessionStorage.getItem(BOOT_KEY)) {
if (app) {
app.classList.add("ready");
}