apps/legacy/static/legacy/js/pages/play.js (Line 381:20 - Line 440:8), apps/legacy/static/legacy/js/pages/play.js (Line 320:17 - Line 380:8)
(e) {
var btn = e.currentTarget;
var duration = parseInt(btn.getAttribute('data-duration'), 10);
var label = btn.getAttribute('data-label');
var instruction = instructions[currentStep] || '';
// If AI is available, try to get an AI-generated name
if (typeof AI_AVAILABLE !== 'undefined' && AI_AVAILABLE && instruction) {
// Disable button while loading
btn.disabled = true;
btn.classList.add('loading');
// Convert seconds to minutes for the API
var durationMinutes = Math.ceil(duration / 60);
// Call AI API using XMLHttpRequest (ES5 compatible)
var xhr = new XMLHttpRequest();
xhr.open('POST', '/api/ai/timer-name', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
btn.disabled = false;
btn.classList.remove('loading');
if (xhr.status === 200) {
try {
var response = JSON.parse(xhr.responseText);
if (response.label) {
addTimer(response.label, duration);
return;
}
} catch (parseError) {
// JSON parse error, fall through to default
}
}
// AI failed, use default label
addTimer(label, duration);
}
};
xhr.onerror = function() {
btn.disabled = false;
btn.classList.remove('loading');
addTimer(label, duration);
};
xhr.send(JSON.stringify({
step_text: instruction,
duration_minutes: durationMinutes
}));
} else {
// No AI available, use default label
addTimer(label, duration);
}
}
/**
* Add a new timer
*/
apps/legacy/static/legacy/js/pages/play.js (Line 572:10 - Line 583:5), apps/legacy/static/legacy/js/pages/profile-selector.js (Line 222:2 - Line 599:7)
apps/legacy/static/legacy/js/pages/favorites.js (Line 31:5 - Line 38:15), apps/legacy/static/legacy/js/pages/home.js (Line 283:5 - Line 289:4)
function handleFavoriteClick(e) {
e.preventDefault();
e.stopPropagation();
var btn = e.currentTarget;
var recipeId = btn.getAttribute('data-recipe-id');
removeFavorite
apps/legacy/static/legacy/js/pages/favorites.js (Line 38:4 - Line 51:31), apps/legacy/static/legacy/js/pages/home.js (Line 316:2 - Line 328:4)
);
}
/**
* Remove recipe from favorites
*/
function removeFavorite(recipeId, btn) {
Cookie.ajax.delete('/api/favorites/' + recipeId + '/', function(err) {
if (err) {
Cookie.toast.error('Failed to remove from favorites');
return;
}
// Animate and remove the card
apps/legacy/static/legacy/js/pages/favorites.js (Line 52:13 - Line 56:5), apps/legacy/static/legacy/js/pages/home.js (Line 337:13 - Line 341:11)
var card = btn.closest('.recipe-card');
if (card) {
card.style.opacity = '0';
card.style.transform = 'scale(0.9)';
card
apps/legacy/static/legacy/js/pages/favorites.js (Line 86:13 - Line 98:10), apps/legacy/static/legacy/js/pages/home.js (Line 360:13 - Line 599:7)
apps/legacy/static/legacy/js/time-detect.js (Line 63:7 - Line 89:8), apps/legacy/static/legacy/js/timer.js (Line 365:15 - Line 385:14)
(seconds) {
if (seconds >= 3600) {
var hrs = Math.floor(seconds / 3600);
var mins = Math.floor((seconds % 3600) / 60);
if (mins > 0) {
return hrs + 'h ' + mins + 'm';
}
return hrs + 'h';
}
var mins = Math.floor(seconds / 60);
var secs = seconds % 60;
if (mins === 0) {
return secs + ' sec';
}
if (secs === 0) {
return mins + ' min';
}
return mins + 'm ' + secs + 's';
}
/**
* Check if text contains any time mentions
* @param {string} text - Text to check
* @returns {boolean} - True if time mentions found
*/
apps/legacy/static/legacy/js/polyfills.js (Line 55:56 - Line 68:2), apps/legacy/static/legacy/js/polyfills.js (Line 31:51 - Line 44:6)
);
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return i
apps/legacy/static/legacy/js/ajax.js (Line 22:8 - Line 27:3), apps/legacy/static/legacy/js/pages/play.js (Line 337:21 - Line 342:4)
, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if