Skip to content

Pomodoro timer solution - #5

Open
yoo-12236 wants to merge 1 commit into
AkongaLabs:mainfrom
yoo-12236:my-contribution
Open

Pomodoro timer solution #5
yoo-12236 wants to merge 1 commit into
AkongaLabs:mainfrom
yoo-12236:my-contribution

Conversation

@yoo-12236

@yoo-12236 yoo-12236 commented Jun 24, 2025

Copy link
Copy Markdown

Bounty Solution Submission

Problem Statement

Built a minimal Pomodoro timer web app with reliable background audio notifications in Chrome, featuring a configurable timer, MM:SS display, and start/pause controls.

### Solution Approach
Single HTML file with embedded CSS/JS for simplicity and no external dependencies.
Used AudioContext for background audio, initialized on user interaction to comply with Chrome restrictions.
Timestamp-based setInterval for accurate timing in background tabs.
Input validation for 1-999 minutes with user-friendly error messages.
Accessibility features: ARIA labels, keyboard navigation, high contrast.

### Technical Implementation
Package Manager: None used (single HTML file, no dependencies).
Database Setup: Not applicable (no database required).
Environment Variables: None required.
Build Process: No build process; run pomodoro.html directly in Chrome.

Testing Evidence

Test Coverage: Tested all required scenarios (see pomodoro/TESTING.md).
Critical Flows Tested:
Background audio: 30s timer, tab switch, chime played.
Permissions: Handled blocked/denied/granted cases.
Tab inactive: Timer accurate after 5min.
Input validation: Rejects -1, 0, non-numeric inputs.
Accessibility: Keyboard navigation, NVDA screen reader compatibility.
Test Results: Detailed in pomodoro/TESTING.md.

Demo Evidence

  • Video [Demo:]
Pomodoro.Timer.-.Google.Chrome.2025-06-24.15-59-14.mp4

Setup Instructions

  1. Clone the repository: git clone https://github.com/yoo-12236/OSS-bounties.git.
  2. Navigate to pomodoro/.
  3. Open pomodoro.html in Chrome.
  4. Enter minutes (1-999), click Start, and test functionality.

Database Setup

Not applicable (no database used).

Architectural Decisions

  • Used AudioContext to avoid external sound files.
  • Timestamp-based timing for background accuracy.
  • Minimal CSS for clean, accessible UI.
  • ARIA labels and keyboard support for accessibility.

Bun/Yarn Justification

Not applicable (no package manager needed; single HTML file).


Pre-submission Checklist:
All bounty requirements met
Tests written and passing
Working demo available
Code is self-explanatory
Setup instructions complete
@adrianmurage tagged for review

I confirm this submission meets all requirements and is ready for review.
Fixes #1

Summary by CodeRabbit

  • New Features

    • Introduced a standalone Pomodoro timer web page with a retro-futuristic design.
    • Added interactive timer controls, including start/pause, reset, and numeric input for custom durations.
    • Implemented accurate countdown, audio notifications, and dynamic document title updates.
    • Enhanced accessibility with keyboard navigation and screen reader support.
  • Documentation

    • Added comprehensive testing documentation covering timer functionality, audio behavior, input validation, and accessibility features.

@coderabbitai

coderabbitai Bot commented Jun 24, 2025

Copy link
Copy Markdown

Walkthrough

A new Pomodoro timer web page was added, featuring a retro-futuristic design, interactive timer controls, audio notifications, and accessibility enhancements. Accompanying documentation outlines comprehensive testing scenarios, including audio permission handling, timer accuracy, input validation, and accessibility support.

Changes

File(s) Change Summary
pomodoro/pomodoro.html Added a standalone Pomodoro timer web page with timer logic, audio notifications, accessibility, and UI.
pomodoro/TESTING.md Added detailed testing documentation covering scenarios for audio, input validation, and accessibility.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI
    participant PomodoroTimer
    participant AudioContext

    User->>UI: Sets duration and clicks Start
    UI->>PomodoroTimer: toggleTimer()
    PomodoroTimer->>PomodoroTimer: Validate input
    PomodoroTimer->>PomodoroTimer: Start countdown
    PomodoroTimer->>AudioContext: Initialize/resume if needed
    PomodoroTimer->>UI: Update timer display
    loop Every tick
        PomodoroTimer->>UI: Update display
    end
    PomodoroTimer->>AudioContext: Play beep on completion
    PomodoroTimer->>UI: Show completion state
Loading

Possibly related issues

Poem

In neon glow, the minutes flow,
A timer ticks, with beeps aglow.
Retro-future, pause or play,
Accessible for all today.
With every chime, a task begun—
Pomodoro joy for everyone!
🥕⏰


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
pomodoro/pomodoro.html (2)

217-220: The <label> is missing the declared .label styling class

You define .label in CSS but the actual <label for="minutesInput"> omits this class, so it inherits default styling instead of the intended neon look.

-<label for="minutesInput">SET TIME (MIN):</label>
+<label for="minutesInput" class="label">SET TIME&nbsp;(MIN):</label>

372-374: Interval granularity is higher than necessary

Updating every 100 ms costs extra wake-ups on mobile devices/battery-saving modes while the display only changes once per second.
Consider 1000 ms or throttling updates to the next integer second.

[performance]

pomodoro/TESTING.md (1)

12-12: Use an en-dash in numeric ranges for readability

“1-999” (U+2013) is the recommended typographic form.

-Rejects -1, 0, non-numeric inputs with 'Enter 1-999 minutes' error.
+Rejects −1, 0, non-numeric inputs with ‘Enter 1–999 minutes’ error.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 086b69e and f24e8f1.

📒 Files selected for processing (2)
  • pomodoro/TESTING.md (1 hunks)
  • pomodoro/pomodoro.html (1 hunks)
🧰 Additional context used
🪛 LanguageTool
pomodoro/TESTING.md

[uncategorized] ~5-~5: Possible missing comma found.
Context: ...ully. AudioContext initialized on start button click to meet Chrome requirements. ## P...

(AI_HYDRA_LEO_MISSING_COMMA)


[typographical] ~12-~12: If specifying a range, consider using an en dash instead of a hyphen.
Context: ...s -1, 0, non-numeric inputs with 'Enter 1-999 minutes' error. ## Accessibility Tab na...

(HYPHEN_TO_EN)

🔇 Additional comments (1)
pomodoro/pomodoro.html (1)

449-451: beforeunload handler needs event.returnValue for cross-browser support

Some browsers ignore a bare return value. Assigning to event.returnValue is still the most reliable way to trigger the confirmation dialog.

-window.addEventListener('beforeunload', () => {
-  if (timer?.isRunning) return 'Timer is running.';
-});
+window.addEventListener('beforeunload', e => {
+  if (timer?.isRunning) {
+    const msg = 'Timer is running.';
+    e.returnValue = msg;
+    return msg;
+  }
+});

Comment thread pomodoro/pomodoro.html
Comment on lines +298 to +304
_showPermissionNotice() {
this.permissionNotice.classList.remove('hidden');
}

_hidePermissionNotice() {
this.permissionNotice.classList.add('hidden');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add aria-hidden when toggling the audio-permission banner

Removing/adding the hidden class hides the element visually but screen-readers will still announce its content.
Consider toggling aria-hidden="true" / false together with the class to avoid confusing, invisible announcements.

[accessibility]

🤖 Prompt for AI Agents
In pomodoro/pomodoro.html around lines 298 to 304, the methods
_showPermissionNotice and _hidePermissionNotice toggle the 'hidden' class to
show or hide the permission notice visually, but do not update the aria-hidden
attribute. To fix this, update _showPermissionNotice to set aria-hidden="false"
on the permissionNotice element and _hidePermissionNotice to set
aria-hidden="true" to ensure screen readers correctly recognize the visibility
state and avoid announcing hidden content.

Comment thread pomodoro/pomodoro.html
Comment on lines +415 to +417
const mins = Math.floor(this.remainingSeconds / 60);
const secs = Math.round(this.remainingSeconds % 60);
this.timerDisplay.textContent = `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Seconds rounding can show an invalid “:60” and skip a second

Math.round pushes 59.5-59.9 s up to 60, so the display can momentarily read MM:60, then jump to MM+1:00, effectively hiding a second from the user.
Replace Math.round with Math.floor (or clamp to 59) to keep the range 0-59.

-const secs = Math.round(this.remainingSeconds % 60);
+const secs = Math.floor(this.remainingSeconds % 60);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const mins = Math.floor(this.remainingSeconds / 60);
const secs = Math.round(this.remainingSeconds % 60);
this.timerDisplay.textContent = `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
const mins = Math.floor(this.remainingSeconds / 60);
- const secs = Math.round(this.remainingSeconds % 60);
+ const secs = Math.floor(this.remainingSeconds % 60);
this.timerDisplay.textContent = `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
🤖 Prompt for AI Agents
In pomodoro/pomodoro.html around lines 415 to 417, the seconds value is
calculated using Math.round, which can cause the display to show an invalid
":60" and skip a second. To fix this, replace Math.round with Math.floor when
calculating the seconds to ensure the value stays within 0-59 and the timer
display remains accurate.

@adrianmurage

Copy link
Copy Markdown
Member

Turns out running a company takes a lot more than I anticipated. I apologize for not reviewing your work in the promised timeline. I assure you I haven't ignored or forgotten you. Founder duties to the company that is making all this possible have simply taken the #1 priority. Because if the company fails, this program cannot exist. Thank you for understanding and I'll get back to you as soon as I possibly can.

@NeshJesse

Copy link
Copy Markdown

Understandable 😂🤝

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pomodoro Timer Prototype - Development Instructions

3 participants