feat(training): base training stats on practice, keep race laps separate
Training stats count Open/Free practice by default; laps from qualifying, heats and finals are kept and shown under Based on: Races or All, marked with race, session and series. Races are listed per race session and never split into stints. Same picker in the mobile profile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -87,7 +87,14 @@ function normalizePublicTrainingLayout(value, state) {
|
||||
return layouts.some((item) => String(item?.id || "") === layout) ? layout : "current";
|
||||
}
|
||||
|
||||
function buildPublicTrainingProfile(state, shareToken, updatedAt, sinceTimestamp = 0, windowMs = 0, evenLapsSince = 0, stepTrainingSince = 0, layout = "current") {
|
||||
// Mirrors getTrainingLapSource in src/training_logic.js: race laps (qualifying, heats,
|
||||
// finals, team races) only count when "race" or "all" is chosen; unknown = practice.
|
||||
const PUBLIC_RACE_SESSION_TYPES = new Set(["qualification", "heat", "final", "team_race"]);
|
||||
function normalizePublicTrainingSource(value) {
|
||||
return ["practice", "race", "all"].includes(String(value)) ? String(value) : "practice";
|
||||
}
|
||||
|
||||
function buildPublicTrainingProfile(state, shareToken, updatedAt, sinceTimestamp = 0, windowMs = 0, evenLapsSince = 0, stepTrainingSince = 0, layout = "current", source = "practice") {
|
||||
const share = findPublicTrainingShare(state, shareToken);
|
||||
if (!share) return null;
|
||||
const visibility = normalizePublicTrainingVisibility(share.visibility);
|
||||
@@ -98,7 +105,13 @@ function buildPublicTrainingProfile(state, shareToken, updatedAt, sinceTimestamp
|
||||
const driver = driverProfile.drivers[0];
|
||||
|
||||
const classes = Array.isArray(state?.classes) ? state.classes : [];
|
||||
const ledger = Array.isArray(state?.training?.ledger) ? state.training.ledger : [];
|
||||
const selectedSource = normalizePublicTrainingSource(source);
|
||||
const sessionTypes = new Map((Array.isArray(state?.sessions) ? state.sessions : []).map((session) => [String(session?.id || ""), String(session?.type || "")]));
|
||||
const ledger = (Array.isArray(state?.training?.ledger) ? state.training.ledger : []).filter((entry) => {
|
||||
if (selectedSource === "all") return true;
|
||||
const isRace = PUBLIC_RACE_SESSION_TYPES.has(String(entry?.sessionType || sessionTypes.get(String(entry?.sessionId || "")) || ""));
|
||||
return selectedSource === "race" ? isRace : !isRace;
|
||||
});
|
||||
const currentLayoutId = getCurrentTrackLayoutId(state);
|
||||
const selectedLayout = normalizePublicTrainingLayout(layout, state);
|
||||
const layoutFilterId = selectedLayout === "current" ? currentLayoutId : selectedLayout === "none" ? "" : selectedLayout;
|
||||
@@ -188,6 +201,7 @@ function buildPublicTrainingProfile(state, shareToken, updatedAt, sinceTimestamp
|
||||
logoDataUrl: normalizePublicLogoDataUrl(settings.logoDataUrl),
|
||||
},
|
||||
classProfiles,
|
||||
lapSource: selectedSource,
|
||||
trackLayouts: {
|
||||
selected: selectedLayout,
|
||||
currentId: currentLayoutId,
|
||||
|
||||
Reference in New Issue
Block a user