Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,25 @@ body {
text-align: center;
padding: 0.2em;
}
#resetButton {
position: fixed;
bottom: 40px;
left: 50%;
transform: translateX(-50%);
padding: 12px 24px;
font-size: 18px;
font-weight: bold;
border: none;
border-radius: 8px;
background-color: #ff4d4f;
color: white;
cursor: pointer;
opacity: 0;
transition: opacity 0.3s ease, background-color 0.2s ease, transform 0.2s ease;
z-index: 1000;
}

#resetButton:hover {
background-color: #ff7875;
transform: translateX(-50%) scale(1.05);
}
19 changes: 14 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<dialog id="settingsModal" onsubmit="submitSettings()">
<h3>Settings</h3>
<form id="settingsForm" method="dialog" name="settingsForm">
<button id="closeSettings" class="btn" onclick="hideSettings()">╳</button>
<button type="button" id="closeSettings" class="btn" onclick="hideSettings()">╳</button>

<label for="durationMinutes">Duration :</label>
<div>
Expand Down Expand Up @@ -66,16 +66,25 @@ <h3>Settings</h3>
</div>
</form>
<div class="buttons">
<button id="resetBtn" class="action" onclick="resetDefaultSettings()">Restore defaults</button>
<button id="submitBtn" class="action" onclick="submitSettings()">Apply</button>
<button type="button" id="resetBtn" class="action" onclick="resetDefaultSettings()">Restore defaults</button>
<button type="button" id="submitBtn" class="action" onclick="submitSettings()">Apply</button>
</div>

</dialog>
<div id="startMessage">
<button id="startButton" type="button" class="btn" onclick="startAnimation()">Start</button>
</div>

<button id="resetButton" type="button" onclick="resetTimer()"
style="display:none; opacity:0; transition: opacity 0.3s;">
Reset
</button>

</div>

<div id="startMessage"><button class="btn" onclick="startAnimation()">START</button></div>
<div id="timer">00:00</div>
<div id="expandingDiv"></div>
<div id="toggleSettings"><button class="btn" onclick="showSettings()">⚙️</button></div>
<div id="toggleSettings"><button type="button" class="btn" onclick="showSettings()">⚙️</button></div>
<div id="credits">made with ❤️ by Zenika</div>

<script src="js/app.js"></script>
Expand Down
71 changes: 64 additions & 7 deletions js/app.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// fetch params in url for quick settings

const params = new URLSearchParams(globalThis.location.search);
const div = document.getElementById('expandingDiv');
const timer = document.getElementById('timer');
const startMessage = document.getElementById('startMessage');
const settingsModal = document.getElementById("settingsModal");
const settingsForm = document.getElementById("settingsForm");
const totalHeight = window.innerHeight;
// 🔹 Declare global variables at the top
let animationFrameId = null;


const defaultSettings = {
"durationInSeconds" : 600,
Expand Down Expand Up @@ -138,41 +142,94 @@ function getClassByProgress(p) {
return 'ending';
}


function startAnimation() {
requestWakeLock();

// Hide Start button
startMessage.style.opacity = 0;
setTimeout(() => startMessage.style.display = 'none', 600);

const startTime = performance.now();

function animate(time) {
const elapsed = time - startTime;
const progress = Math.min(elapsed / (settings.durationInSeconds * 1000), 1); // 0 → 1
const progress = Math.min(elapsed / (settings.durationInSeconds * 1000), 1);
const currentHeight = Math.floor(totalHeight * progress);
const remaining = settings.durationInSeconds - (elapsed / 1000);
updateTimer(remaining);

updateTimer(remaining);
div.style.height = `${currentHeight}px`;
div.classList = getClassByProgress(progress);

if (progress < 1) {
requestAnimationFrame(animate);
animationFrameId = requestAnimationFrame(animate);
} else {
// Timer finished
timer.textContent = "00:00";
playBeep();
timer.classList.add("blinking"); // démarre le clignotement
timer.classList.add("blinking");

// Arrête le clignotement après 5 secondes
// After 5 seconds of blinking, stop blinking & show Reset button
setTimeout(() => {
timer.classList.remove("blinking");
timer.style.opacity = "1";
showResetButton(); // <--- call function here
}, 5000);
}
}
requestAnimationFrame(animate);

animationFrameId = requestAnimationFrame(animate);
}

// Show Reset button after blinking finishes
// Show the Reset button and keep it visible always
const resetButton = document.getElementById("resetButton");
resetButton.style.display = "inline-block";
setTimeout(() => {
resetButton.style.opacity = 1;
}, 100); // fade-in animation



// Function to reset the timer/animation
function resetTimer() {
console.log("Reset clicked");

// Stop animation if running
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
animationFrameId = null;
}

// Reset visuals
div.style.height = "0px"; // animation bar back to zero

// Reset timer text to full duration in mm:ss
const totalSeconds = settings.durationInSeconds;
const minutes = Math.floor(totalSeconds / 60).toString().padStart(2, "0");
const seconds = (totalSeconds % 60).toString().padStart(2, "0");
timer.textContent = `${minutes}:${seconds}`;
Comment on lines +207 to +211
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already is a method

Suggested change
// Reset timer text to full duration in mm:ss
const totalSeconds = settings.durationInSeconds;
const minutes = Math.floor(totalSeconds / 60).toString().padStart(2, "0");
const seconds = (totalSeconds % 60).toString().padStart(2, "0");
timer.textContent = `${minutes}:${seconds}`;
updateTimer(settings.durationInSeconds);


// Hide Reset button
const resetButton = document.getElementById("resetButton");
resetButton.style.opacity = 0;
setTimeout(() => (resetButton.style.display = "none"), 300);

// Show Start button again
startMessage.style.display = "block";
setTimeout(() => (startMessage.style.opacity = 1), 100);

// Release Wake Lock if active
if (wakeLock) {
wakeLock.release().then(() => {
wakeLock = null;
console.log("Wake Lock relâché");
});
}
}



async function requestWakeLock() {
try {
if ('wakeLock' in navigator) {
Expand Down