feedback on temp buttons

This commit is contained in:
2025-07-13 16:41:35 -04:00
parent 15f74335c7
commit af68e8923c
2 changed files with 41 additions and 42 deletions

View File

@@ -117,6 +117,14 @@ body {
background-color: #ddd;
}
.used-temp {
background-color: #ccc !important;
color: #333;
border: 2px solid #888;
cursor: default;
}
#log-table {
width: 100%;
border-collapse: collapse;

View File

@@ -7,6 +7,7 @@ let targets: number[] = [];
let currentTargetIndex = 0;
let interval: NodeJS.Timeout | null = null;
let firstCrackTime: number | null = null;
let loggedTemps = new Set<number>();
declare global {
interface Window {
@@ -23,7 +24,6 @@ declare global {
}
}
function startTimer(): void {
if (isRunning) {
alert("Timer is already running. Click again to reset.");
@@ -39,7 +39,7 @@ function startTimer(): void {
}
function stopTimer(): void {
if(interval !== null){
if (interval !== null) {
clearInterval(interval);
}
isRunning = false;
@@ -48,7 +48,7 @@ function stopTimer(): void {
function updateTimerDisplay(): void {
const roastTimeEl = document.getElementById("roastTime")!;
const devPercentEl = document.getElementById("devPercent")!;
const minutes = Math.floor(timer / 60);
const seconds = timer % 60;
roastTimeEl.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
@@ -63,11 +63,8 @@ function updateTimerDisplay(): void {
}
const timerEl = document.getElementById("timer")!;
// Reset classes
timerEl.className = "";
// Determine phase
if (!log.some(e => e.event === "Charge")) {
timerEl.classList.add("initial-phase");
} else if (!log.some(e => e.event === "Yellow")) {
@@ -75,26 +72,20 @@ function updateTimerDisplay(): void {
} else if (firstCrackTime === null) {
timerEl.classList.add("yellow-phase");
} else {
// Development phase
timerEl.classList.add("dev-phase");
const devTime = timer - firstCrackTime;
const devRatio = Math.min(devTime / timer, 0.4); // clamp to 00.4
// Interpolate from yellow (255,255,208) to muddy brown (215,195,158)
const devRatio = Math.min(devTime / timer, 0.4);
const r = Math.round(255 - devRatio * 100);
const g = Math.round(255 - devRatio * 150);
const b = Math.round(208 - devRatio * 125);
timerEl.style.backgroundColor = `rgb(${r},${g},${b})`;
}
}
function logEvent(eventName: string): void {
if (eventName === "Charge") {
if (log.length > 0 || isRunning) {
if(isRunning){
if (isRunning) {
stopTimer();
}
log = [];
@@ -111,8 +102,7 @@ function logEvent(eventName: string): void {
log.push({ time: formatTime(timer), event: eventName });
updateLog();
document.getElementById("create-plan")!.classList.remove("hidden");
const tempButtons = document.getElementById("temp-buttons")!;
tempButtons.innerHTML = "";
document.getElementById("temp-buttons")!.innerHTML = "";
updateEventButtons(eventName);
return;
}
@@ -125,19 +115,18 @@ function logEvent(eventName: string): void {
updateEventButtons(eventName);
}
function updateEventButtons(eventName: string){
if (eventName === "Charge" || eventName === "Yellow" || eventName === "First Crack" || eventName === "Second Crack" || eventName === "Drop") {
const eventSequence = ["Charge", "Yellow", "First Crack", "Second Crack", "Drop"];
function updateEventButtons(eventName: string): void {
const eventSequence = ["Charge", "Yellow", "First Crack", "Second Crack", "Drop"];
if (eventSequence.includes(eventName)) {
const pressedIndex = eventSequence.indexOf(eventName);
for (let i = 0; i <= pressedIndex; i++) {
const btn = document.querySelector(`#event-buttons button:nth-child(${i + 1})`) as HTMLButtonElement;
if (btn) btn.classList.add("activated");
}
}
else if (eventName === "Reset") {
const eventButtons = document.querySelectorAll("#event-buttons button");
eventButtons.forEach(btn => btn.classList.remove("activated"));
} else if (eventName === "Reset") {
document.querySelectorAll("#event-buttons button").forEach(btn =>
btn.classList.remove("activated")
);
}
}
@@ -146,6 +135,7 @@ function resetSystem(): void {
log = [];
timer = 0;
firstCrackTime = null;
loggedTemps.clear();
updateLog();
updateTimerDisplay();
@@ -153,12 +143,11 @@ function resetSystem(): void {
devPercentEl.style.display = "none";
const timerEl = document.getElementById("timer")!;
timerEl.className = "initial-phase"; // back to white background
timerEl.style.backgroundColor = ""; // clear inline style
timerEl.className = "initial-phase";
timerEl.style.backgroundColor = "";
document.getElementById("create-plan")!.classList.remove("hidden");
const tempButtons = document.getElementById("temp-buttons")!;
tempButtons.innerHTML = "";
document.getElementById("temp-buttons")!.innerHTML = "";
updateEventButtons("Reset");
}
@@ -181,17 +170,24 @@ function setPlan(): void {
function generateTempButtons(): void {
const container = document.getElementById("temp-buttons")!;
container.innerHTML = "";
if (targets.length === 0) {
container.innerHTML = "<p>No temperature plan set.</p>";
return;
}
const currentTarget = targets[currentTargetIndex];
const buttons: string[] = [];
buttons.push('<button class="nav-btn" onclick="navigateTemp(-1);">&lt;&lt;</button>');
for (let i = -2; i <= 2; i++) {
const temp = currentTarget + i;
buttons.push(`<button onclick="logTemp(${temp})">${temp}</button>`);
const used = loggedTemps.has(temp);
const classStr = used ? 'used-temp' : '';
buttons.push(`<button onclick="logTemp(${temp})" class="${classStr}">${temp}</button>`);
}
buttons.push('<button class="nav-btn" onclick="navigateTemp(1);">&gt;&gt;</button>');
container.innerHTML = buttons.join(" ");
}
@@ -208,6 +204,7 @@ function navigateTemp(direction: number): void {
function logTemp(temp: number): void {
log.push({ time: formatTime(timer), event: "Temp", temp });
loggedTemps.add(temp);
updateLog();
currentTargetIndex++;
if (currentTargetIndex >= targets.length) {
@@ -227,22 +224,16 @@ function updateLog(): void {
`).join("");
}
// src/roast.ts
/**
* Generates an array of CSV strings line by line from log data.
*/
function createCSVData(): string[] {
const header = "Time,Event,Temperature";
const logEntries = log.map(entry => `${entry.time},${entry.event}${entry.temp !== null ? `,${entry.temp}` : ''}`);
return [header].concat(logEntries);
const header = "Time,Event,Temperature";
const logEntries = log.map(entry =>
`${entry.time},${entry.event}${entry.temp !== null ? `,${entry.temp}` : ''}`
);
return [header, ...logEntries];
}
/**
* Creates CSV format content as a single string from the array returned by createCSVData().
*/
function generateCSVContent(): string {
return createCSVData().join("\n");
return createCSVData().join("\n");
}
function exportCSV(): void {
@@ -288,4 +279,4 @@ if (typeof window !== 'undefined') {
window.hideGraph = hideGraph;
}
export {};
export {};