feat: bootstrap walking skeleton
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import type { Content } from '../content/schema';
|
||||
import type { GameState } from '../engine/game';
|
||||
|
||||
/**
|
||||
* Pure mapping from engine state to the view model the React shell renders.
|
||||
* No React, no store — just data shaping, so it can be unit-tested directly.
|
||||
*/
|
||||
|
||||
export interface ResourceView {
|
||||
id: string;
|
||||
name: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export interface GameView {
|
||||
resources: ResourceView[];
|
||||
activeActionId: string | null;
|
||||
actionName: string | null;
|
||||
/** Progress of the active action, clamped to 0..1. */
|
||||
actionProgress: number;
|
||||
}
|
||||
|
||||
export function toView(state: GameState, content: Content): GameView {
|
||||
const resources: ResourceView[] = content.resources.map((resource) => ({
|
||||
id: resource.id,
|
||||
name: resource.name,
|
||||
amount: state.resources[resource.id] ?? 0,
|
||||
}));
|
||||
|
||||
const action = state.activeActionId ? content.actionsById[state.activeActionId] : undefined;
|
||||
const actionProgress = action ? Math.min(1, state.actionElapsedMs / action.durationMs) : 0;
|
||||
|
||||
return {
|
||||
resources,
|
||||
activeActionId: state.activeActionId,
|
||||
actionName: action ? action.name : null,
|
||||
actionProgress,
|
||||
};
|
||||
}
|
||||
|
||||
/** Render an offline gap as `45s`, `1m 30s`, `2m`, `1h 1m`, `2h`. */
|
||||
export function formatOfflineDuration(ms: number): string {
|
||||
const totalSeconds = Math.floor(ms / 1000);
|
||||
if (totalSeconds < 60) {
|
||||
return `${totalSeconds}s`;
|
||||
}
|
||||
const totalMinutes = Math.floor(totalSeconds / 60);
|
||||
if (totalMinutes < 60) {
|
||||
const seconds = totalSeconds % 60;
|
||||
return seconds === 0 ? `${totalMinutes}m` : `${totalMinutes}m ${seconds}s`;
|
||||
}
|
||||
const hours = Math.floor(totalMinutes / 60);
|
||||
const minutes = totalMinutes % 60;
|
||||
return minutes === 0 ? `${hours}h` : `${hours}h ${minutes}m`;
|
||||
}
|
||||
Reference in New Issue
Block a user