-
Notifications
You must be signed in to change notification settings - Fork 328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nazal #10
base: main
Are you sure you want to change the base?
Nazal #10
Conversation
WalkthroughThe pull request introduces a new browser extension named "Useless Projects Extension," which includes several new files. A Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Popup
participant Options
participant Background
participant Content
User->>Popup: Click "Start Annoying"
Popup->>Background: Log "Annoying started!"
User->>Popup: Click "Settings"
Popup->>Options: Open options page
User->>Content: Visit productive site
Content->>Content: Check site type
Content->>User: Show overlay
User->>Content: Click close button
Content->>Content: Remove overlay
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
🧹 Outside diff range and nitpick comments (4)
pinne-cheyyam/popup/popup.js (1)
1-8
: Add JSDoc documentation and initialization checksThe file lacks documentation about its purpose and proper initialization checks for the Chrome extension APIs.
Consider adding documentation and checks:
+/** + * Popup script for the Useless Projects Extension + * Handles user interactions in the extension popup + */ + +// Ensure we're running in a Chrome extension context +if (!chrome?.runtime?.openOptionsPage) { + console.error('This script must be run in a Chrome extension context'); + throw new Error('Chrome extension APIs not available'); +} + const startButton = document.getElementById('start');pinne-cheyyam/manifest.json (1)
2-8
: Consider migrating to Manifest V3.Chrome is deprecating Manifest V2, and it's recommended to use Manifest V3 for new extensions to ensure future compatibility.
Add additional icon sizes.
The extension only includes a 48px icon. Consider adding more sizes (16, 32, 128) for better display across different contexts:
"icons": { + "16": "icons/icon16.png", + "32": "icons/icon32.png", "48": "icons/icon.png", + "128": "icons/icon128.png" }pinne-cheyyam/options/options.html (1)
15-15
: Add ARIA roles to the site lists.The unordered lists should have ARIA roles for better accessibility.
Apply these changes:
- <ul id="productiveList"></ul> + <ul id="productiveList" role="list" aria-label="List of productive sites"></ul> - <ul id="distractingList"></ul> + <ul id="distractingList" role="list" aria-label="List of distracting sites"></ul>Also applies to: 22-22
pinne-cheyyam/options/options.js (1)
1-57
: Consider architectural improvements for better maintainability.
- Separate the storage logic into a dedicated service class to improve testability and reuse.
- Consider using TypeScript for better type safety and developer experience.
- Implement a centralized error handling strategy.
- Add JSDoc comments for better documentation.
Here's a sketch of the suggested architecture:
/** * @typedef {Object} SiteStorageService * @property {function(string): Promise<string[]>} getSites * @property {function(string, string): Promise<void>} addSite * @property {function(string, number): Promise<void>} removeSite */ /** * @typedef {'productiveSites' | 'distractingSites'} SiteType */ class SiteStorageService { async getSites(type) { // Storage logic } async addSite(type, site) { // Add site logic } async removeSite(type, index) { // Remove site logic } } class UIManager { constructor(storageService) { this.storage = storageService; } async updateUI() { // UI update logic } }Would you like me to help implement this improved architecture?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
pinne-cheyyam/icons/icon.png
is excluded by!**/*.png
📒 Files selected for processing (10)
.gitignore
(1 hunks)pinne-cheyyam/background.js
(1 hunks)pinne-cheyyam/content.js
(1 hunks)pinne-cheyyam/manifest.json
(1 hunks)pinne-cheyyam/options/options.css
(1 hunks)pinne-cheyyam/options/options.html
(1 hunks)pinne-cheyyam/options/options.js
(1 hunks)pinne-cheyyam/popup/popup.css
(1 hunks)pinne-cheyyam/popup/popup.html
(1 hunks)pinne-cheyyam/popup/popup.js
(1 hunks)
✅ Files skipped from review due to trivial changes (5)
- .gitignore
- pinne-cheyyam/background.js
- pinne-cheyyam/options/options.css
- pinne-cheyyam/popup/popup.css
- pinne-cheyyam/popup/popup.html
🔇 Additional comments (6)
pinne-cheyyam/manifest.json (4)
9-13
: LGTM! Permissions are appropriate.
The requested permissions align with the extension's functionality:
storage
: Required for saving user preferencestabs
&activeTab
: Needed for monitoring site visits
18-23
:
Consider restricting content script matches.
The "<all_urls>"
match pattern grants the content script access to all websites, which might be broader than necessary. Consider restricting it to only the domains where the extension needs to function.
"content_scripts": [
{
- "matches": ["<all_urls>"],
+ "matches": [
+ "*://*.google.com/*",
+ "*://*.github.com/*"
+ // Add other productive sites as needed
+ ],
"js": ["content.js"]
}
]
Verify content script implementation.
#!/bin/bash
# Verify content.js exists and contains overlay implementation
fd -t f "content.js" --exec rg -l "overlay|break"
24-29
: Verify popup and options pages.
The configuration looks correct, but let's ensure the referenced files exist.
#!/bin/bash
# Verify popup and options pages exist
echo "Checking popup HTML:"
fd -t f "popup.html" -p "popup"
echo "Checking options HTML:"
fd -t f "options.html" -p "options"
14-17
: Verify background.js implementation.
The background script configuration looks good, using non-persistent mode for better performance.
✅ Verification successful
Background script implementation verified and approved
The background script exists at pinne-cheyyam/background.js
and contains the required installation handler. The implementation is minimal and correct, using the non-persistent mode as specified in the manifest.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify background.js exists and contains installation handler
fd -t f "background.js" --exec rg -l "chrome.runtime.onInstalled"
Length of output: 357
Script:
#!/bin/bash
# First verify if background.js exists
fd -t f "background.js"
# If it exists, let's examine its content
fd -t f "background.js" --exec cat {}
Length of output: 198
pinne-cheyyam/options/options.html (2)
1-7
: LGTM! Document structure follows best practices.
The HTML document is well-structured with proper DOCTYPE declaration, language attribute, character encoding, and external resource links.
25-25
: Verify script dependencies.
The options.js file is loaded without any error handling. Consider adding error handling and ensuring all required functionality is available.
Let's verify the script file exists and check its content:
document.getElementById('openOptions').addEventListener('click', () => { | ||
// Opens the options page | ||
chrome.runtime.openOptionsPage(); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for options button
Similar to the start button, this needs proper error handling for the DOM element lookup.
Apply this improvement:
-document.getElementById('openOptions').addEventListener('click', () => {
- // Opens the options page
- chrome.runtime.openOptionsPage();
-});
+const optionsButton = document.getElementById('openOptions');
+if (optionsButton) {
+ optionsButton.addEventListener('click', () => {
+ chrome.runtime.openOptionsPage();
+ });
+} else {
+ console.error('Options button not found in popup');
+}
📝 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.
document.getElementById('openOptions').addEventListener('click', () => { | |
// Opens the options page | |
chrome.runtime.openOptionsPage(); | |
}); | |
const optionsButton = document.getElementById('openOptions'); | |
if (optionsButton) { | |
optionsButton.addEventListener('click', () => { | |
chrome.runtime.openOptionsPage(); | |
}); | |
} else { | |
console.error('Options button not found in popup'); | |
} |
document.getElementById('start').addEventListener('click', () => { | ||
console.log('Annoying started!'); | ||
}); | ||
|
||
document.getElementById('openOptions').addEventListener('click', () => { | ||
// Opens the options page | ||
chrome.runtime.openOptionsPage(); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Missing implementation for 'start' functionality
The background script currently only handles installation events and lacks any implementation for the 'start' functionality referenced in popup.js. The click handler in popup.js only logs a message without any actual integration with the background script.
Required changes:
- Implement message passing between popup and background script for the 'start' functionality
- Add corresponding message handler in background.js to process the 'start' action
🔗 Analysis chain
Verify integration with background script
The 'start' functionality seems to be missing its core implementation. We should verify if there's corresponding handling in the background script.
Let's check for related background script implementations:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Look for background script handling of the 'start' functionality
# Check for background script files
echo "Checking for background script files:"
fd -e js -e ts background
# Look for message handling related to 'start' functionality
echo -e "\nChecking for message handlers:"
rg -l "chrome\.(runtime|extension)\.onMessage"
Length of output: 266
Script:
#!/bin/bash
# Let's examine the content of the background script and look for any start-related functionality
echo "Content of background.js:"
cat pinne-cheyyam/background.js
# Also check for any other potential message passing or start functionality implementations
echo -e "\nChecking for any start-related functionality across the codebase:"
rg -i "start" --type js -C 2
Length of output: 600
document.getElementById('start').addEventListener('click', () => { | ||
console.log('Annoying started!'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling and remove console.log
The current implementation has two issues:
- Missing error handling for the DOM element lookup
- Console.log statement should not be in production code
Consider implementing proper error handling and actual functionality:
-document.getElementById('start').addEventListener('click', () => {
- console.log('Annoying started!');
-});
+const startButton = document.getElementById('start');
+if (startButton) {
+ startButton.addEventListener('click', () => {
+ // TODO: Implement the actual start functionality
+ });
+} else {
+ console.error('Start button not found in popup');
+}
📝 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.
document.getElementById('start').addEventListener('click', () => { | |
console.log('Annoying started!'); | |
}); | |
const startButton = document.getElementById('start'); | |
if (startButton) { | |
startButton.addEventListener('click', () => { | |
// TODO: Implement the actual start functionality | |
}); | |
} else { | |
console.error('Start button not found in popup'); | |
} |
<input type="text" id="productiveInput" placeholder="Add a productive site URL"> | ||
<button id="addProductive">Add</button> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enhance input validation and accessibility.
The input fields and buttons need improvements for better accessibility and user experience:
- Add
aria-label
attributes to inputs for screen readers - Add pattern validation for URL inputs
- Add disabled state handling for the Add buttons
Apply these changes:
- <input type="text" id="productiveInput" placeholder="Add a productive site URL">
- <button id="addProductive">Add</button>
+ <input
+ type="url"
+ id="productiveInput"
+ placeholder="Add a productive site URL"
+ aria-label="Enter productive site URL"
+ pattern="https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)"
+ >
+ <button id="addProductive" aria-label="Add productive site">Add</button>
- <input type="text" id="distractingInput" placeholder="Add a distracting site URL">
- <button id="addDistracting">Add</button>
+ <input
+ type="url"
+ id="distractingInput"
+ placeholder="Add a distracting site URL"
+ aria-label="Enter distracting site URL"
+ pattern="https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)"
+ >
+ <button id="addDistracting" aria-label="Add distracting site">Add</button>
Also applies to: 20-21
<div> | ||
<h2>Productive Sites</h2> | ||
<input type="text" id="productiveInput" placeholder="Add a productive site URL"> | ||
<button id="addProductive">Add</button> | ||
<ul id="productiveList"></ul> | ||
</div> | ||
|
||
<div> | ||
<h2>Distracting Sites</h2> | ||
<input type="text" id="distractingInput" placeholder="Add a distracting site URL"> | ||
<button id="addDistracting">Add</button> | ||
<ul id="distractingList"></ul> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider adding form elements for better user interaction.
Wrap the input sections in <form>
elements to enable submit-on-enter functionality and proper form handling.
Apply these changes:
- <div>
+ <form id="productiveForm">
<h2>Productive Sites</h2>
<!-- ... input and button ... -->
<ul id="productiveList"></ul>
- </div>
+ </form>
- <div>
+ <form id="distractingForm">
<h2>Distracting Sites</h2>
<!-- ... input and button ... -->
<ul id="distractingList"></ul>
- </div>
+ </form>
Committable suggestion skipped: line range outside the PR's diff.
function removeSite(type, index) { | ||
chrome.storage.sync.get([type], (result) => { | ||
const sites = result[type] || []; | ||
sites.splice(index, 1); | ||
chrome.storage.sync.set({ [type]: sites }, () => { | ||
updateSiteList(type, type === 'productiveSites' ? 'productiveList' : 'distractingList'); | ||
}); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve error handling and use constants for list IDs.
The removeSite
function needs improvements:
- Add error handling.
- Use constants for list IDs.
- Validate index before removal.
Here's the suggested implementation:
+const LIST_IDS = {
+ productiveSites: 'productiveList',
+ distractingSites: 'distractingList'
+};
+
function removeSite(type, index) {
+ if (!['productiveSites', 'distractingSites'].includes(type)) {
+ console.error('Invalid site type:', type);
+ return;
+ }
chrome.storage.sync.get([type], (result) => {
+ if (chrome.runtime.lastError) {
+ console.error('Storage error:', chrome.runtime.lastError);
+ return;
+ }
const sites = result[type] || [];
+ if (index < 0 || index >= sites.length) {
+ console.error('Invalid index:', index);
+ return;
+ }
sites.splice(index, 1);
chrome.storage.sync.set({ [type]: sites }, () => {
- updateSiteList(type, type === 'productiveSites' ? 'productiveList' : 'distractingList');
+ if (chrome.runtime.lastError) {
+ console.error('Storage error:', chrome.runtime.lastError);
+ return;
+ }
+ updateSiteList(type, LIST_IDS[type]);
});
});
}
📝 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.
function removeSite(type, index) { | |
chrome.storage.sync.get([type], (result) => { | |
const sites = result[type] || []; | |
sites.splice(index, 1); | |
chrome.storage.sync.set({ [type]: sites }, () => { | |
updateSiteList(type, type === 'productiveSites' ? 'productiveList' : 'distractingList'); | |
}); | |
}); | |
} | |
const LIST_IDS = { | |
productiveSites: 'productiveList', | |
distractingSites: 'distractingList' | |
}; | |
function removeSite(type, index) { | |
if (!['productiveSites', 'distractingSites'].includes(type)) { | |
console.error('Invalid site type:', type); | |
return; | |
} | |
chrome.storage.sync.get([type], (result) => { | |
if (chrome.runtime.lastError) { | |
console.error('Storage error:', chrome.runtime.lastError); | |
return; | |
} | |
const sites = result[type] || []; | |
if (index < 0 || index >= sites.length) { | |
console.error('Invalid index:', index); | |
return; | |
} | |
sites.splice(index, 1); | |
chrome.storage.sync.set({ [type]: sites }, () => { | |
if (chrome.runtime.lastError) { | |
console.error('Storage error:', chrome.runtime.lastError); | |
return; | |
} | |
updateSiteList(type, LIST_IDS[type]); | |
}); | |
}); | |
} |
function addSite(type, inputId, listId) { | ||
const inputElement = document.getElementById(inputId); | ||
const site = inputElement.value.trim(); | ||
if (site) { | ||
chrome.storage.sync.get([type], (result) => { | ||
const sites = result[type] || []; | ||
sites.push(site); | ||
chrome.storage.sync.set({ [type]: sites }, () => { | ||
updateSiteList(type, listId); | ||
inputElement.value = ''; | ||
}); | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enhance input validation and add duplicate checking.
The addSite
function needs improvements:
- Validate URLs before adding.
- Prevent duplicate entries.
- Add a reasonable limit to the number of sites.
- Include error handling.
Here's the suggested implementation:
function addSite(type, inputId, listId) {
const inputElement = document.getElementById(inputId);
const site = inputElement.value.trim();
- if (site) {
+ try {
+ // Validate URL format
+ new URL(site);
+ } catch (e) {
+ alert('Please enter a valid URL');
+ return;
+ }
+
+ if (site) {
chrome.storage.sync.get([type], (result) => {
+ if (chrome.runtime.lastError) {
+ console.error('Storage error:', chrome.runtime.lastError);
+ return;
+ }
const sites = result[type] || [];
+
+ // Check for duplicates
+ if (sites.includes(site)) {
+ alert('This site is already in the list');
+ return;
+ }
+
+ // Limit number of sites
+ if (sites.length >= 50) {
+ alert('Maximum number of sites reached');
+ return;
+ }
sites.push(site);
chrome.storage.sync.set({ [type]: sites }, () => {
+ if (chrome.runtime.lastError) {
+ console.error('Storage error:', chrome.runtime.lastError);
+ return;
+ }
updateSiteList(type, listId);
inputElement.value = '';
});
});
}
}
📝 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.
function addSite(type, inputId, listId) { | |
const inputElement = document.getElementById(inputId); | |
const site = inputElement.value.trim(); | |
if (site) { | |
chrome.storage.sync.get([type], (result) => { | |
const sites = result[type] || []; | |
sites.push(site); | |
chrome.storage.sync.set({ [type]: sites }, () => { | |
updateSiteList(type, listId); | |
inputElement.value = ''; | |
}); | |
}); | |
} | |
} | |
function addSite(type, inputId, listId) { | |
const inputElement = document.getElementById(inputId); | |
const site = inputElement.value.trim(); | |
try { | |
// Validate URL format | |
new URL(site); | |
} catch (e) { | |
alert('Please enter a valid URL'); | |
return; | |
} | |
if (site) { | |
chrome.storage.sync.get([type], (result) => { | |
if (chrome.runtime.lastError) { | |
console.error('Storage error:', chrome.runtime.lastError); | |
return; | |
} | |
const sites = result[type] || []; | |
// Check for duplicates | |
if (sites.includes(site)) { | |
alert('This site is already in the list'); | |
return; | |
} | |
// Limit number of sites | |
if (sites.length >= 50) { | |
alert('Maximum number of sites reached'); | |
return; | |
} | |
sites.push(site); | |
chrome.storage.sync.set({ [type]: sites }, () => { | |
if (chrome.runtime.lastError) { | |
console.error('Storage error:', chrome.runtime.lastError); | |
return; | |
} | |
updateSiteList(type, listId); | |
inputElement.value = ''; | |
}); | |
}); | |
} | |
} |
function createOverlay() { | ||
// Check if the overlay already exists | ||
if (document.getElementById("productive-overlay")) return; | ||
|
||
// Create the overlay div | ||
const overlay = document.createElement("div"); | ||
overlay.id = "productive-overlay"; | ||
overlay.style.position = "fixed"; | ||
overlay.style.top = "0"; | ||
overlay.style.left = "0"; | ||
overlay.style.width = "100%"; | ||
overlay.style.height = "100%"; | ||
overlay.style.backgroundColor = "rgba(0, 0, 0, 0.8)"; | ||
overlay.style.zIndex = "10000"; | ||
overlay.style.display = "flex"; | ||
overlay.style.justifyContent = "center"; | ||
overlay.style.alignItems = "center"; | ||
overlay.style.color = "white"; | ||
overlay.style.fontSize = "24px"; | ||
overlay.style.textAlign = "center"; | ||
|
||
// Message content | ||
overlay.innerHTML = ` | ||
<div> | ||
<p>You are on a productive site! Take a break?</p> | ||
<button id="close-overlay" style=" | ||
margin-top: 20px; | ||
padding: 10px 20px; | ||
font-size: 18px; | ||
background-color: #176B87; | ||
color: white; | ||
border: none; | ||
border-radius: 5px; | ||
cursor: pointer; | ||
">Close</button> | ||
</div> | ||
`; | ||
|
||
// Append overlay to body | ||
document.body.appendChild(overlay); | ||
|
||
// Close overlay button functionality | ||
document.getElementById("close-overlay").addEventListener("click", () => { | ||
overlay.remove(); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor overlay implementation for better maintainability and extensibility.
The overlay implementation has several areas for improvement:
- Move styles to a separate CSS file
- Externalize text for internationalization
- Clean up event listeners properly
Consider refactoring the code as follows:
+const OVERLAY_TEXT = chrome.i18n.getMessage('overlayText') || 'You are on a productive site! Take a break?';
+const CLOSE_BUTTON_TEXT = chrome.i18n.getMessage('closeButton') || 'Close';
function createOverlay() {
if (document.getElementById("productive-overlay")) return;
const overlay = document.createElement("div");
overlay.id = "productive-overlay";
- overlay.style.position = "fixed";
- // ... remove all inline styles
+ overlay.classList.add('productive-overlay');
overlay.innerHTML = `
<div>
- <p>You are on a productive site! Take a break?</p>
- <button id="close-overlay" style="...">Close</button>
+ <p>${OVERLAY_TEXT}</p>
+ <button id="close-overlay" class="overlay-button">${CLOSE_BUTTON_TEXT}</button>
</div>
`;
document.body.appendChild(overlay);
- document.getElementById("close-overlay").addEventListener("click", () => {
+ const closeButton = document.getElementById("close-overlay");
+ const handleClose = () => {
+ closeButton.removeEventListener("click", handleClose);
overlay.remove();
- });
+ };
+ closeButton.addEventListener("click", handleClose);
}
Add a new CSS file:
.productive-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
z-index: var(--overlay-z-index, 10000);
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 24px;
text-align: center;
}
.overlay-button {
margin-top: 20px;
padding: 10px 20px;
font-size: 18px;
background-color: var(--button-bg-color, #176B87);
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
// Run the function when the page loads | ||
window.addEventListener('load', checkSiteType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve event handling for URL checks.
The current implementation might miss URL changes in single-page applications (SPAs) and could potentially run multiple times.
Consider using the following approach:
-window.addEventListener('load', checkSiteType);
+// Check on initial load
+checkSiteType();
+
+// Listen for URL changes (for SPAs)
+const observer = new MutationObserver(() => {
+ if (document.location.href !== lastUrl) {
+ lastUrl = document.location.href;
+ checkSiteType();
+ }
+});
+
+let lastUrl = document.location.href;
+observer.observe(document, { subtree: true, childList: true });
+
+// Cleanup when the content script is unloaded
+window.addEventListener('unload', () => {
+ observer.disconnect();
+});
Committable suggestion skipped: line range outside the PR's diff.
function checkSiteType() { | ||
const currentUrl = window.location.href; | ||
|
||
// Retrieve the site lists from storage | ||
chrome.storage.sync.get(['productiveSites', 'distractingSites'], (data) => { | ||
const productiveSites = data.productiveSites || []; | ||
const distractingSites = data.distractingSites || []; | ||
|
||
// Check if the current URL matches any productive site | ||
if (productiveSites.some(site => currentUrl.includes(site))) { | ||
createOverlay(); // Display the overlay for productive sites | ||
} | ||
|
||
// Check if the current URL matches any distracting site | ||
if (distractingSites.some(site => currentUrl.includes(site))) { | ||
alert("You are on a distracting site!"); | ||
} | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve URL matching and error handling in site type checking.
The current implementation has several potential issues:
- Simple string inclusion for URL matching could lead to false positives
- Missing error handling for storage access
- Alert dialogs can be intrusive
Consider implementing these improvements:
function checkSiteType() {
const currentUrl = window.location.href;
+ const urlObj = new URL(currentUrl);
+ const domain = urlObj.hostname;
// Retrieve the site lists from storage
chrome.storage.sync.get(['productiveSites', 'distractingSites'], (data) => {
+ if (chrome.runtime.lastError) {
+ console.error('Error accessing storage:', chrome.runtime.lastError);
+ return;
+ }
+
const productiveSites = data.productiveSites || [];
const distractingSites = data.distractingSites || [];
// Check if the current URL matches any productive site
- if (productiveSites.some(site => currentUrl.includes(site))) {
+ if (productiveSites.some(site => domain.endsWith(site))) {
createOverlay();
}
// Check if the current URL matches any distracting site
- if (distractingSites.some(site => currentUrl.includes(site))) {
- alert("You are on a distracting site!");
+ if (distractingSites.some(site => domain.endsWith(site))) {
+ // Use a less intrusive notification method
+ chrome.runtime.sendMessage({
+ type: 'showNotification',
+ message: 'You are on a distracting site!'
+ });
}
});
}
📝 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.
function checkSiteType() { | |
const currentUrl = window.location.href; | |
// Retrieve the site lists from storage | |
chrome.storage.sync.get(['productiveSites', 'distractingSites'], (data) => { | |
const productiveSites = data.productiveSites || []; | |
const distractingSites = data.distractingSites || []; | |
// Check if the current URL matches any productive site | |
if (productiveSites.some(site => currentUrl.includes(site))) { | |
createOverlay(); // Display the overlay for productive sites | |
} | |
// Check if the current URL matches any distracting site | |
if (distractingSites.some(site => currentUrl.includes(site))) { | |
alert("You are on a distracting site!"); | |
} | |
}); | |
} | |
function checkSiteType() { | |
const currentUrl = window.location.href; | |
const urlObj = new URL(currentUrl); | |
const domain = urlObj.hostname; | |
// Retrieve the site lists from storage | |
chrome.storage.sync.get(['productiveSites', 'distractingSites'], (data) => { | |
if (chrome.runtime.lastError) { | |
console.error('Error accessing storage:', chrome.runtime.lastError); | |
return; | |
} | |
const productiveSites = data.productiveSites || []; | |
const distractingSites = data.distractingSites || []; | |
// Check if the current URL matches any productive site | |
if (productiveSites.some(site => domain.endsWith(site))) { | |
createOverlay(); | |
} | |
// Check if the current URL matches any distracting site | |
if (distractingSites.some(site => domain.endsWith(site))) { | |
// Use a less intrusive notification method | |
chrome.runtime.sendMessage({ | |
type: 'showNotification', | |
message: 'You are on a distracting site!' | |
}); | |
} | |
}); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (3)
pinne-cheyyam/popup/popup.html (3)
14-14
: Add width and height attributes to the img tag.While you've set the dimensions via CSS classes, explicitly setting width and height attributes helps prevent layout shifts during image loading.
- <img src="../icons/icon.png" alt="Pinne-Cheyyam Logo" class="w-16 h-16 mb-2"> + <img src="../icons/icon.png" alt="Pinne-Cheyyam Logo" width="64" height="64" class="w-16 h-16 mb-2">
20-22
: Add aria-label attributes to buttons for better accessibility.While the button text is descriptive, adding aria-labels can provide additional context for screen readers.
- <button id="start" class="bg-yellow-500 hover:bg-yellow-600 text-white font-bold py-2 px-4 rounded-full mb-4 transition duration-300 ease-in-out shadow-md"> + <button id="start" aria-label="Start annoying mode" class="bg-yellow-500 hover:bg-yellow-600 text-white font-bold py-2 px-4 rounded-full mb-4 transition duration-300 ease-in-out shadow-md"> Start Annoying </button> - <button id="openOptions" class="bg-transparent border border-yellow-500 hover:bg-yellow-500 hover:text-white text-yellow-500 font-bold py-2 px-4 rounded-full transition duration-300 ease-in-out shadow-md"> + <button id="openOptions" aria-label="Open extension settings" class="bg-transparent border border-yellow-500 hover:bg-yellow-500 hover:text-white text-yellow-500 font-bold py-2 px-4 rounded-full transition duration-300 ease-in-out shadow-md"> Settings </button>Also applies to: 24-26
1-32
: Consider adding meta viewport tag for better mobile compatibility.While this is a browser extension popup, adding viewport meta tag ensures proper rendering on different screen sizes.
Add this line in the head section:
<meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Pinne-Cheyyam</title>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
pinne-cheyyam/icons/icon.png
is excluded by!**/*.png
📒 Files selected for processing (1)
pinne-cheyyam/popup/popup.html
(1 hunks)
🔇 Additional comments (2)
pinne-cheyyam/popup/popup.html (2)
11-12
: LGTM! Nice use of Tailwind's backdrop filters.
The gradient background with backdrop blur creates a modern, frosted glass effect. The responsive flex layout ensures proper centering.
29-29
: Verify the popup.js file location and add error handling.
Ensure that popup.js exists and consider adding error handling for script loading.
<!-- Link to your local Tailwind CSS file --> | ||
<script src="../tailwind.js"></script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using a CDN or proper build process for Tailwind CSS.
Loading Tailwind directly via a script tag is not recommended for production. Consider using either:
- A CDN link for development
- A proper build process to generate optimized CSS
- <!-- Link to your local Tailwind CSS file -->
- <script src="../tailwind.js"></script>
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
Committable suggestion skipped: line range outside the PR's diff.
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Documentation
Style