feedback on temp buttons
This commit is contained in:
@@ -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;
|
||||
|
||||
75
src/roast.ts
75
src/roast.ts
@@ -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 0–0.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);"><<</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);">>></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 {};
|
||||
|
||||
Reference in New Issue
Block a user