From 821bcaca9b1f1a50582750d410b88379a2ed6941 Mon Sep 17 00:00:00 2001 From: zubyj Date: Sat, 12 Apr 2025 00:37:10 -0700 Subject: [PATCH 1/9] better button & border contrast --- src/content-script/update-solutions-tab.ts | 36 +++++++++++++------- src/popup/popup.css | 38 +++++++++++++++------- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/content-script/update-solutions-tab.ts b/src/content-script/update-solutions-tab.ts index 27badbc..2668618 100644 --- a/src/content-script/update-solutions-tab.ts +++ b/src/content-script/update-solutions-tab.ts @@ -22,27 +22,36 @@ function createStyledButton(text: string, isActive: boolean = false): HTMLButton chrome.storage.local.get(['isDarkTheme'], (result) => { const isDark = result.isDarkTheme; - button.style.backgroundColor = isDark ? '#373737' : '#f3f4f5'; - button.style.color = isDark ? '#fff' : '#1a1a1a'; - button.style.border = `1px solid ${isDark ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'}`; + button.style.backgroundColor = isDark ? '#2d2d2d' : '#f3f4f5'; + button.style.color = isDark ? '#e6e6e6' : '#2d2d2d'; + button.style.border = `1px solid ${isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)'}`; + button.style.fontWeight = '500'; button.addEventListener('mouseenter', () => { if (!button.classList.contains('active')) { - button.style.backgroundColor = isDark ? '#424242' : '#e6e6e6'; + button.style.backgroundColor = isDark ? '#3d3d3d' : '#e6e6e6'; + button.style.borderColor = isDark ? 'rgba(255, 255, 255, 0.25)' : 'rgba(0, 0, 0, 0.25)'; } }); button.addEventListener('mouseleave', () => { if (!button.classList.contains('active')) { - button.style.backgroundColor = isDark ? '#373737' : '#f3f4f5'; + button.style.backgroundColor = isDark ? '#2d2d2d' : '#f3f4f5'; + button.style.borderColor = isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)'; } }); + + if (isActive) { + button.style.backgroundColor = isDark ? '#404040' : '#e0e0e0'; + button.style.color = isDark ? '#ffffff' : '#000000'; + button.style.borderColor = isDark ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)'; + } }); button.style.width = '120px'; button.style.padding = '4px 8px'; button.style.margin = '0 8px'; button.style.borderRadius = '6px'; - button.style.fontSize = '11px'; + button.style.fontSize = '12px'; button.style.transition = 'all 0.2s ease'; button.style.letterSpacing = '0.5px'; button.style.cursor = 'pointer'; @@ -358,23 +367,26 @@ function createLanguageButtons(problem: any) { langButton.style.gap = '8px'; langButton.style.padding = '6px 12px'; langButton.style.borderRadius = '6px'; - langButton.style.fontSize = '11px'; + langButton.style.fontSize = '12px'; langButton.style.letterSpacing = '.5px'; langButton.style.transition = 'all 0.2s ease'; langButton.style.cursor = 'pointer'; + langButton.style.fontWeight = '500'; chrome.storage.local.get(['isDarkTheme'], (result) => { const isDark = result.isDarkTheme; - langButton.style.backgroundColor = isDark ? '#373737' : '#f3f4f5'; - langButton.style.color = isDark ? '#fff' : '#1a1a1a'; - langButton.style.border = `1px solid ${isDark ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'}`; + langButton.style.backgroundColor = isDark ? '#2d2d2d' : '#f3f4f5'; + langButton.style.color = isDark ? '#e6e6e6' : '#2d2d2d'; + langButton.style.border = `1px solid ${isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)'}`; // on hover just make the background a few shades darker or lighter langButton.addEventListener('mouseenter', () => { - langButton.style.backgroundColor = isDark ? '#424242' : '#e6e6e6'; + langButton.style.backgroundColor = isDark ? '#3d3d3d' : '#e6e6e6'; + langButton.style.borderColor = isDark ? 'rgba(255, 255, 255, 0.25)' : 'rgba(0, 0, 0, 0.25)'; }); langButton.addEventListener('mouseleave', () => { - langButton.style.backgroundColor = isDark ? '#373737' : '#f3f4f5'; + langButton.style.backgroundColor = isDark ? '#2d2d2d' : '#f3f4f5'; + langButton.style.borderColor = isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)'; }); }); diff --git a/src/popup/popup.css b/src/popup/popup.css index 2a1d678..5df831d 100644 --- a/src/popup/popup.css +++ b/src/popup/popup.css @@ -6,22 +6,32 @@ --icon-size: 16px; --spacing: 10px; --transition-speed: 0.2s; - --border-color: black; + --border-color: rgba(0, 0, 0, 0.15); --link-color: #303134; - --text-color: black; + --text-color: #2d2d2d; + --button-bg-color: #f3f4f5; --button-hover-bg: #e6e6e6; + --button-hover-border: rgba(0, 0, 0, 0.25); } /* Dark theme */ [data-theme="dark"] { --background-color: #202124; - --border-color: #5f6368; + --border-color: rgba(255, 255, 255, 0.15); --link-color: #8ab4f8; - --button-bg-color: #303134; - --button-hover-bg: #424242; - --text-color: #e8eaed; + --button-bg-color: #2d2d2d; + --button-hover-bg: #3d3d3d; + --text-color: #e6e6e6; --code-bg-color: #303134; --info-message-bg: rgba(48, 49, 52, 0.5); + --button-hover-border: rgba(255, 255, 255, 0.25); + --active-text: #ffffff; + --active-bg: #404040; +} + +[data-theme="light"] { + --active-text: #000000; + --active-bg: #e0e0e0; } /* Display size variations */ @@ -73,11 +83,13 @@ body { border-radius: var(--border-radius); cursor: pointer; font-size: var(--base-font-size); + letter-spacing: 0.5px; transition: all var(--transition-speed) ease; } .material-button:hover, .code-btn:hover { background-color: var(--button-hover-bg) !important; + border-color: var(--button-hover-border); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } @@ -104,23 +116,24 @@ a { } .tab { - background: transparent; - border: none; + background: transparent !important; + border: 1px solid transparent; border-radius: 5px; font-size: var(--base-font-size); + font-weight: 500; padding: calc(var(--spacing) * 0.6) var(--spacing); cursor: pointer; color: var(--text-color); - transition: color var(--transition-speed) ease, border-bottom var(--transition-speed) ease; + letter-spacing: 0.5px; + transition: all var(--transition-speed) ease; } .tab:hover { - background-color: var(--button-hover-bg) !important; + border: 1px solid var(--button-hover-bg) !important; } .tab.active { - border-bottom: 2px solid var(--link-color); - color: var(--link-color); + background-color: var(--active-bg) !important; } /* Main content on popup and settings*/ @@ -167,6 +180,7 @@ a { color: var(--color); border-radius: 8px; background-color: var(--info-message-bg); + letter-spacing: .5px; } /* Response containers */ From e6c317bcc72a5b4a2dc05933b908218b05492991 Mon Sep 17 00:00:00 2001 From: zubyj Date: Sat, 12 Apr 2025 01:01:33 -0700 Subject: [PATCH 2/9] improved button hover and active states --- src/content-script/update-solutions-tab.ts | 84 ++++++++++++++++++---- src/problems-by-company/company.css | 30 +++++--- 2 files changed, 91 insertions(+), 23 deletions(-) diff --git a/src/content-script/update-solutions-tab.ts b/src/content-script/update-solutions-tab.ts index 2668618..5529a77 100644 --- a/src/content-script/update-solutions-tab.ts +++ b/src/content-script/update-solutions-tab.ts @@ -20,33 +20,86 @@ function createStyledButton(text: string, isActive: boolean = false): HTMLButton button.classList.add('nav-button'); if (isActive) button.classList.add('active'); - chrome.storage.local.get(['isDarkTheme'], (result) => { - const isDark = result.isDarkTheme; - button.style.backgroundColor = isDark ? '#2d2d2d' : '#f3f4f5'; - button.style.color = isDark ? '#e6e6e6' : '#2d2d2d'; - button.style.border = `1px solid ${isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)'}`; - button.style.fontWeight = '500'; + const updateButtonStyles = (isDark: boolean, isButtonActive: boolean) => { + // Light theme colors + const lightTheme = { + base: '#f3f4f5', + active: '#e0e0e0', + hover: '#e6e6e6', + border: 'rgba(0, 0, 0, 0.15)', + activeBorder: '#f3f4f5', + hoverBorder: 'rgba(0, 0, 0, 0.25)', + text: '#2d2d2d' + }; + + // Dark theme colors + const darkTheme = { + base: '#2d2d2d', + active: '#404040', + hover: '#3d3d3d', + border: 'rgba(255, 255, 255, 0.15)', + activeBorder: '#2d2d2d', + hoverBorder: 'rgba(255, 255, 255, 0.25)', + text: '#e6e6e6' + }; + + const theme = isDark ? darkTheme : lightTheme; + + button.style.backgroundColor = isButtonActive ? theme.active : theme.base; + button.style.color = theme.text; + button.style.border = `1px solid ${isButtonActive ? theme.activeBorder : theme.border}`; + button.style.boxShadow = isButtonActive ? `0 0 0 1px ${theme.activeBorder}` : 'none'; + // Remove existing listeners + const oldMouseEnter = button.onmouseenter; + const oldMouseLeave = button.onmouseleave; + if (oldMouseEnter) button.removeEventListener('mouseenter', oldMouseEnter); + if (oldMouseLeave) button.removeEventListener('mouseleave', oldMouseLeave); + + // Add new theme-aware listeners button.addEventListener('mouseenter', () => { if (!button.classList.contains('active')) { - button.style.backgroundColor = isDark ? '#3d3d3d' : '#e6e6e6'; - button.style.borderColor = isDark ? 'rgba(255, 255, 255, 0.25)' : 'rgba(0, 0, 0, 0.25)'; + button.style.backgroundColor = theme.hover; + button.style.borderColor = theme.hoverBorder; } }); + button.addEventListener('mouseleave', () => { if (!button.classList.contains('active')) { - button.style.backgroundColor = isDark ? '#2d2d2d' : '#f3f4f5'; - button.style.borderColor = isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(0, 0, 0, 0.15)'; + button.style.backgroundColor = theme.base; + button.style.borderColor = theme.border; + } else { + button.style.backgroundColor = theme.active; + button.style.borderColor = theme.activeBorder; } }); + }; - if (isActive) { - button.style.backgroundColor = isDark ? '#404040' : '#e0e0e0'; - button.style.color = isDark ? '#ffffff' : '#000000'; - button.style.borderColor = isDark ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)'; + // Initial style setup + chrome.storage.local.get(['isDarkTheme'], (result) => { + updateButtonStyles(result.isDarkTheme, isActive); + }); + + // Listen for theme changes + chrome.storage.onChanged.addListener((changes) => { + if (changes.isDarkTheme) { + updateButtonStyles(changes.isDarkTheme.newValue, button.classList.contains('active')); } }); + // Update styles when active state changes + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.type === 'attributes' && mutation.attributeName === 'class') { + chrome.storage.local.get(['isDarkTheme'], (result) => { + updateButtonStyles(result.isDarkTheme, button.classList.contains('active')); + }); + } + }); + }); + + observer.observe(button, { attributes: true }); + button.style.width = '120px'; button.style.padding = '4px 8px'; button.style.margin = '0 8px'; @@ -252,7 +305,8 @@ function showContent(type: 'Discussion' | 'Video' | 'Code') { // Update button states const buttons = document.querySelectorAll('.nav-button'); buttons.forEach(button => { - if (button.textContent === type) { + const isActive = button.textContent === type; + if (isActive) { button.classList.add('active'); } else { button.classList.remove('active'); diff --git a/src/problems-by-company/company.css b/src/problems-by-company/company.css index 39537cd..96f9ca4 100644 --- a/src/problems-by-company/company.css +++ b/src/problems-by-company/company.css @@ -46,16 +46,28 @@ button, nav button { font-weight: 500; - letter-spacing: 0.8px; - text-transform: uppercase; + letter-spacing: 0.5px; + text-transform: none; + display: flex; + align-items: center; + gap: 8px; + padding: 8px 16px; + min-width: 130px; + height: 40px; + background-color: var(--button-bg-color); + color: var(--text-color); + border: 1px solid var(--border-color); + border-radius: 6px; + font-size: 12px; + transition: all 0.2s ease; } button:hover { - background-color: #424242; - border-color: rgba(255, 255, 255, 0.2); + background-color: var(--button-hover-bg); + border-color: var(--button-hover-border); cursor: pointer; transform: translateY(-1px); - color: #ffd700; + color: var(--link-color); } table { @@ -77,12 +89,14 @@ td { } th { - background-color: #424242; - color: #40a9ff; + background-color: var(--button-bg-color); + color: var(--link-color); font-weight: 500; font-size: 14px; - text-transform: uppercase; + text-transform: none; letter-spacing: 0.5px; + padding: 12px 16px; + border-bottom: 1px solid var(--border-color); } td { From 6944827a400ac83fff526a8f38abce1d70bd7515 Mon Sep 17 00:00:00 2001 From: zubyj Date: Sat, 12 Apr 2025 01:05:10 -0700 Subject: [PATCH 3/9] better nav company button hover animation --- src/problems-by-company/company.css | 2 -- src/problems-by-company/company.ts | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/problems-by-company/company.css b/src/problems-by-company/company.css index 96f9ca4..af00db6 100644 --- a/src/problems-by-company/company.css +++ b/src/problems-by-company/company.css @@ -66,8 +66,6 @@ button:hover { background-color: var(--button-hover-bg); border-color: var(--button-hover-border); cursor: pointer; - transform: translateY(-1px); - color: var(--link-color); } table { diff --git a/src/problems-by-company/company.ts b/src/problems-by-company/company.ts index 6667979..40657c7 100644 --- a/src/problems-by-company/company.ts +++ b/src/problems-by-company/company.ts @@ -35,11 +35,12 @@ function addNavbarLinks() { }); }; button.onmouseover = () => { - button.style.color = 'orange'; + button.style.backgroundColor = '#404040'; button.style.cursor = 'pointer'; }; button.onmouseout = () => { - button.style.color = 'white'; + button.style.backgroundColor = '#373737'; + button.style.color = '#fff'; }; button.style.display = 'flex'; button.style.alignItems = 'center'; From 10b77e2f2be495fb227faa16a897d475350ad9d0 Mon Sep 17 00:00:00 2001 From: zubyj Date: Sat, 12 Apr 2025 01:14:05 -0700 Subject: [PATCH 4/9] comment out console logs --- src/background/background.ts | 2 +- src/content-script/get-user-code.ts | 2 +- src/content-script/themeDetector.js | 2 -- src/content-script/update-description-tab.ts | 8 ++++---- src/content-script/update-solutions-tab.ts | 6 +++--- src/popup/popup.ts | 2 +- src/popup/settings.js | 8 +++----- src/utils/theme.ts | 14 +++++++------- 8 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/background/background.ts b/src/background/background.ts index 788a825..b80da5e 100644 --- a/src/background/background.ts +++ b/src/background/background.ts @@ -152,7 +152,7 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { isViewChange ? 'View Changed' : isActualRefresh ? 'Page Refresh' : 'Page Load'; - console.log(`State change detected - ${changeType}`); + //console.log(`State change detected - ${changeType}`); // Update last state lastState.problemPath = problemPath; diff --git a/src/content-script/get-user-code.ts b/src/content-script/get-user-code.ts index 7a1bef4..16416ea 100644 --- a/src/content-script/get-user-code.ts +++ b/src/content-script/get-user-code.ts @@ -70,7 +70,7 @@ function getProblem() { // Get test cases, output, and expected output const consoleData = getConsoleData(); if (consoleData.length > 0) { - console.log('Console Data:', consoleData); + //console.log('Console Data:', consoleData); collectedData.push("\n--- Test Cases and Results ---\n" + consoleData.join('\n')); } diff --git a/src/content-script/themeDetector.js b/src/content-script/themeDetector.js index 1d6d8f0..1c00849 100644 --- a/src/content-script/themeDetector.js +++ b/src/content-script/themeDetector.js @@ -82,7 +82,6 @@ function isColorDark(color) { // Extract RGB values const rgb = color.match(/\d+/g); if (!rgb || rgb.length < 3) { - console.log('Could not extract RGB values from color:', color); return true; // Default to dark if can't extract } @@ -93,7 +92,6 @@ function isColorDark(color) { // Weighted luminance formula (human eye is more sensitive to green) const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b; - console.log(`Color luminance: ${luminance} (< 0.5 is dark)`); // Return true for dark colors (lower luminance) return luminance < 0.5; diff --git a/src/content-script/update-description-tab.ts b/src/content-script/update-description-tab.ts index 260040d..16f87f9 100644 --- a/src/content-script/update-description-tab.ts +++ b/src/content-script/update-description-tab.ts @@ -45,7 +45,7 @@ function detectAndSyncTheme() { isDarkTheme: leetcodeTheme === 'dark' }); - console.log(`Theme auto-detected: ${leetcodeTheme}`); + //console.log(`Theme auto-detected: ${leetcodeTheme}`); // Set up observer for future theme changes observeThemeChanges(); @@ -70,7 +70,7 @@ function observeThemeChanges() { chrome.storage.local.set({ isDarkTheme: leetcodeTheme === 'dark' }); - console.log(`Theme changed to: ${leetcodeTheme}`); + //console.log(`Theme changed to: ${leetcodeTheme}`); } }); }); @@ -215,7 +215,7 @@ function showCompanyTags(problemTitle: string) { } if (!description) { - console.log('Failed to find description element after all retries'); + //console.log('Failed to find description element after all retries'); // If still not found, set up a MutationObserver to watch for DOM changes const observer = new MutationObserver((mutations, obs) => { @@ -375,7 +375,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'updateDescription') { // Only detect theme on first load, problem change, or refresh if (!request.isProblemChange && !request.isRefresh) { - console.log('Skipping theme detection for internal navigation'); + //console.log('Skipping theme detection for internal navigation'); return; } diff --git a/src/content-script/update-solutions-tab.ts b/src/content-script/update-solutions-tab.ts index 5529a77..8af1789 100644 --- a/src/content-script/update-solutions-tab.ts +++ b/src/content-script/update-solutions-tab.ts @@ -673,7 +673,7 @@ function updateSolutionsTab(title: string) { // If it's the same problem and the wrapper is in the DOM, preserve state if (wrapperTitle === currentTitle && document.contains(existingWrapper)) { - console.log('Content exists for current problem, preserving state'); + //console.log('Content exists for current problem, preserving state'); return; } @@ -694,13 +694,13 @@ function updateSolutionsTab(title: string) { // Use exponential backoff for retry delay const delay = baseDelay * Math.pow(1.5, retryCount); retryCount++; - console.log(`Attempt ${retryCount}: Waiting for search bar element to load... Retrying in ${delay}ms`); + //console.log(`Attempt ${retryCount}: Waiting for search bar element to load... Retrying in ${delay}ms`); setTimeout(tryInsertContent, delay); return; } if (!searchBar) { - console.log('Failed to find search bar element after all retries'); + //console.log('Failed to find search bar element after all retries'); // If still not found, set up a MutationObserver to watch for DOM changes const observer = new MutationObserver((mutations, obs) => { diff --git a/src/popup/popup.ts b/src/popup/popup.ts index 8cf2e31..712bf85 100644 --- a/src/popup/popup.ts +++ b/src/popup/popup.ts @@ -77,7 +77,7 @@ function initActionButton(buttonId: string, action: 'analyze' | 'fix', aiProvide actionButton.onclick = async () => { const codeText = await getCodeFromActiveTab(); if (codeText) { - console.log(codeText); + //console.log(codeText); processCode(aiProvider, codeText, action); } else { const errorMessage = "Cannot read from page. Please open a Leetcode problem and refresh the page."; diff --git a/src/popup/settings.js b/src/popup/settings.js index 09c6ff6..04ee248 100644 --- a/src/popup/settings.js +++ b/src/popup/settings.js @@ -28,10 +28,10 @@ document.addEventListener('DOMContentLoaded', () => { // Helper function to send messages safely to content script function safelySendMessage(message) { - console.log('Sending message to content script:', message); + //console.log('Sending message to content script:', message); chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { if (!tabs || !tabs[0] || !tabs[0].id) { - console.log('No active tab found'); + //console.log('No active tab found'); return; } @@ -51,9 +51,7 @@ document.addEventListener('DOMContentLoaded', () => { }).catch(err => { console.log('Error injecting content script:', err); }); - } else { - console.log('Message sent successfully, response:', response); - } + } }); } catch (error) { console.log('Error sending message:', error); diff --git a/src/utils/theme.ts b/src/utils/theme.ts index 809499b..ef6f580 100644 --- a/src/utils/theme.ts +++ b/src/utils/theme.ts @@ -56,14 +56,14 @@ const THEME_STYLES = { // Initialize theme on load export function initializeTheme(): void { - console.log('Initializing theme...'); + //console.log('Initializing theme...'); // Get saved theme settings chrome.storage.local.get(['isDarkTheme', 'themeMode', 'lastDetectedTheme'], (result) => { let theme: ThemeName = result.isDarkTheme ? 'dark' : 'light'; const mode: ThemeMode = result.themeMode === 'auto' ? 'auto' : 'manual'; - console.log(`Theme settings: Theme=${theme}, Mode=${mode}`); + //console.log(`Theme settings: Theme=${theme}, Mode=${mode}`); // For auto mode, use last detected theme if available if (mode === 'auto' && result.lastDetectedTheme) { @@ -82,7 +82,7 @@ export function initializeTheme(): void { // Set theme based on dropdown selection export function setTheme(theme: ThemeName | 'auto'): void { - console.log(`Setting theme to: ${theme}`); + //console.log(`Setting theme to: ${theme}`); if (theme === 'auto') { // Enable auto mode but keep current theme until detection @@ -103,7 +103,7 @@ export function setTheme(theme: ThemeName | 'auto'): void { // Apply a theme to the current page function applyTheme(theme: ThemeName, mode: ThemeMode): void { - console.log(`Applying theme: ${theme}, mode: ${mode}`); + //console.log(`Applying theme: ${theme}, mode: ${mode}`); // Set data attribute for CSS variables document.documentElement.setAttribute('data-theme', theme); @@ -174,7 +174,7 @@ function updateThemeUI(theme: ThemeName, mode: ThemeMode): void { // Detect theme from active LeetCode page function detectThemeFromPage(): void { - console.log('Detecting theme from active tab...'); + //console.log('Detecting theme from active tab...'); chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { if (tabs[0]?.id) { @@ -183,12 +183,12 @@ function detectThemeFromPage(): void { { action: 'getTheme' }, (response) => { if (chrome.runtime.lastError) { - console.log('Error detecting theme:', chrome.runtime.lastError); + //console.log('Error detecting theme:', chrome.runtime.lastError); return; } if (response?.theme) { - console.log('Detected theme:', response.theme); + //console.log('Detected theme:', response.theme); // Apply the detected theme applyTheme(response.theme, 'auto'); From 280f211c6df7fe031f5465f507edcafa8c122c8e Mon Sep 17 00:00:00 2001 From: zubyj Date: Sat, 12 Apr 2025 01:15:57 -0700 Subject: [PATCH 5/9] comment out console logs --- src/content-script/get-user-code.ts | 2 +- src/content-script/update-description-tab.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content-script/get-user-code.ts b/src/content-script/get-user-code.ts index 16416ea..eeff836 100644 --- a/src/content-script/get-user-code.ts +++ b/src/content-script/get-user-code.ts @@ -79,7 +79,7 @@ function getProblem() { if (errorPanel) { const errorText = errorPanel.textContent?.trim(); if (errorText) { - console.log('Error from LeetCode:', errorText); + //console.log('Error from LeetCode:', errorText); collectedData.push("\n--- LeetCode Error Message ---\n" + errorText); collectedData.push("\nPlease fix the above error in the code."); } diff --git a/src/content-script/update-description-tab.ts b/src/content-script/update-description-tab.ts index 16f87f9..dc7d0ab 100644 --- a/src/content-script/update-description-tab.ts +++ b/src/content-script/update-description-tab.ts @@ -209,7 +209,7 @@ function showCompanyTags(problemTitle: string) { // Use exponential backoff for retry delay const delay = baseDelay * Math.pow(1.5, retryCount); retryCount++; - console.log(`Attempt ${retryCount}: Waiting for description element to load... Retrying in ${delay}ms`); + //console.log(`Attempt ${retryCount}: Waiting for description element to load... Retrying in ${delay}ms`); setTimeout(tryInsertCompanyTags, delay); return; } From 921ce7eea00750a687cc70209a9f810ddc820a92 Mon Sep 17 00:00:00 2001 From: zubyj Date: Sat, 12 Apr 2025 01:24:22 -0700 Subject: [PATCH 6/9] fix opening page to solutions tab not loading company tags --- src/content-script/update-description-tab.ts | 97 +++++++++++++++----- 1 file changed, 76 insertions(+), 21 deletions(-) diff --git a/src/content-script/update-description-tab.ts b/src/content-script/update-description-tab.ts index dc7d0ab..b4ea84b 100644 --- a/src/content-script/update-description-tab.ts +++ b/src/content-script/update-description-tab.ts @@ -412,38 +412,93 @@ function initializeDescriptionTab() { // Set up theme detection and synchronization setupDescriptionThemeListener(); - // Get the problem title from the page - const problemTitle = document.title.replace(' - LeetCode', ''); + // Initial load of enhancements + updatePageContent(); - // Apply all enhancements - showDifficulty(); - showRating(problemTitle); - showCompanyTags(problemTitle); - showExamples(); - - // Set up a MutationObserver to detect tab changes + // Set up URL change detection using History API + const originalPushState = history.pushState; + const originalReplaceState = history.replaceState; + + history.pushState = function(data: any, unused: string, url?: string | URL) { + originalPushState.call(this, data, unused, url); + handleUrlChange(); + }; + + history.replaceState = function(data: any, unused: string, url?: string | URL) { + originalReplaceState.call(this, data, unused, url); + handleUrlChange(); + }; + + window.addEventListener('popstate', handleUrlChange); + + // Set up a MutationObserver to detect tab and content changes const observer = new MutationObserver((mutations) => { + let shouldUpdate = false; + mutations.forEach((mutation) => { - if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { - // Check if we're on the description tab - const descriptionTab = document.querySelector('[data-cy="description-tab"]'); - if (descriptionTab && descriptionTab.classList.contains('active')) { - // Re-apply company tags when switching to description tab - const problemTitle = document.title.replace(' - LeetCode', ''); - showCompanyTags(problemTitle); + // Check for tab changes + if (mutation.target instanceof HTMLElement) { + const isTabChange = mutation.target.getAttribute('role') === 'tab' || + mutation.target.closest('[role="tab"]'); + if (isTabChange) { + shouldUpdate = true; } } + + // Check for content changes in the main container + if (mutation.type === 'childList' && + ((mutation.target instanceof HTMLElement && mutation.target.classList?.contains('elfjS')) || + mutation.addedNodes.length > 0)) { + shouldUpdate = true; + } }); + + if (shouldUpdate) { + // Small delay to ensure DOM is fully updated + setTimeout(updatePageContent, 100); + } }); - // Start observing the tab container - const tabContainer = document.querySelector('[role="tablist"]'); - if (tabContainer) { - observer.observe(tabContainer, { childList: true, subtree: true }); - } + // Observe both the tab container and the main content area + observer.observe(document.body, { + childList: true, + subtree: true, + attributes: true, + attributeFilter: ['class', 'data-cy'] + }); + } +} + +// Update all page content +function updatePageContent() { + const problemTitle = document.title.replace(' - LeetCode', '').split('-')[0].trim(); + const isDescriptionTab = isOnDescriptionTab(); + + if (isDescriptionTab) { + showCompanyTags(problemTitle); + showDifficulty(); + showRating(problemTitle); + showExamples(); } } +// Check if we're on the description tab +function isOnDescriptionTab() { + // Check multiple conditions to determine if we're on the description tab + const descriptionTab = document.querySelector('[data-cy="description-tab"]'); + const isDescriptionActive = descriptionTab?.classList.contains('active'); + const notOnSolutions = !window.location.href.includes('/solutions'); + const hasDescriptionContent = !!document.getElementsByClassName('elfjS')[0]; + + return (isDescriptionActive || notOnSolutions) && hasDescriptionContent; +} + +// Handle URL changes +function handleUrlChange() { + // Small delay to ensure DOM is updated + setTimeout(updatePageContent, 200); +} + // Initialize the content script initializeDescriptionTab(); From 36c514e633a21a82ad79d6f4cef814d8130ccf60 Mon Sep 17 00:00:00 2001 From: zubyj Date: Sat, 12 Apr 2025 01:27:27 -0700 Subject: [PATCH 7/9] rm console logs --- src/background/background.ts | 5 ++--- src/content-script/update-description-tab.ts | 3 --- src/content-script/update-solutions-tab.ts | 3 --- src/popup/popup.ts | 2 +- src/popup/settings.js | 8 +++----- src/popup/settings.ts | 1 - src/utils/theme.ts | 14 +------------- 7 files changed, 7 insertions(+), 29 deletions(-) diff --git a/src/background/background.ts b/src/background/background.ts index b80da5e..281721c 100644 --- a/src/background/background.ts +++ b/src/background/background.ts @@ -25,7 +25,7 @@ chrome.runtime.onInstalled.addListener(() => { chrome.storage.local.set({ leetcodeProblems: data }); }) .catch((error) => { - console.error(error); + console.error('Failed to load problem data:', error); }); // Load problems by company JSON file into storage @@ -36,7 +36,7 @@ chrome.runtime.onInstalled.addListener(() => { chrome.storage.local.set({ companyProblems: data }); }) .catch((error) => { - console.error(error); + console.error('Failed to load company problems:', error); }); // Load default settings @@ -152,7 +152,6 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { isViewChange ? 'View Changed' : isActualRefresh ? 'Page Refresh' : 'Page Load'; - //console.log(`State change detected - ${changeType}`); // Update last state lastState.problemPath = problemPath; diff --git a/src/content-script/update-description-tab.ts b/src/content-script/update-description-tab.ts index b4ea84b..33cfe1b 100644 --- a/src/content-script/update-description-tab.ts +++ b/src/content-script/update-description-tab.ts @@ -209,13 +209,11 @@ function showCompanyTags(problemTitle: string) { // Use exponential backoff for retry delay const delay = baseDelay * Math.pow(1.5, retryCount); retryCount++; - //console.log(`Attempt ${retryCount}: Waiting for description element to load... Retrying in ${delay}ms`); setTimeout(tryInsertCompanyTags, delay); return; } if (!description) { - //console.log('Failed to find description element after all retries'); // If still not found, set up a MutationObserver to watch for DOM changes const observer = new MutationObserver((mutations, obs) => { @@ -375,7 +373,6 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'updateDescription') { // Only detect theme on first load, problem change, or refresh if (!request.isProblemChange && !request.isRefresh) { - //console.log('Skipping theme detection for internal navigation'); return; } diff --git a/src/content-script/update-solutions-tab.ts b/src/content-script/update-solutions-tab.ts index 8af1789..c3b981a 100644 --- a/src/content-script/update-solutions-tab.ts +++ b/src/content-script/update-solutions-tab.ts @@ -673,7 +673,6 @@ function updateSolutionsTab(title: string) { // If it's the same problem and the wrapper is in the DOM, preserve state if (wrapperTitle === currentTitle && document.contains(existingWrapper)) { - //console.log('Content exists for current problem, preserving state'); return; } @@ -694,13 +693,11 @@ function updateSolutionsTab(title: string) { // Use exponential backoff for retry delay const delay = baseDelay * Math.pow(1.5, retryCount); retryCount++; - //console.log(`Attempt ${retryCount}: Waiting for search bar element to load... Retrying in ${delay}ms`); setTimeout(tryInsertContent, delay); return; } if (!searchBar) { - //console.log('Failed to find search bar element after all retries'); // If still not found, set up a MutationObserver to watch for DOM changes const observer = new MutationObserver((mutations, obs) => { diff --git a/src/popup/popup.ts b/src/popup/popup.ts index 712bf85..3e00c70 100644 --- a/src/popup/popup.ts +++ b/src/popup/popup.ts @@ -293,7 +293,7 @@ async function main(): Promise { elements['getComplexityBtn']?.classList.remove('hidden'); elements['fixCodeBtn']?.classList.remove('hidden'); } catch (error) { - console.log(error); + console.error('Failed to initialize popup:', error); } } diff --git a/src/popup/settings.js b/src/popup/settings.js index 04ee248..90ebae4 100644 --- a/src/popup/settings.js +++ b/src/popup/settings.js @@ -28,17 +28,15 @@ document.addEventListener('DOMContentLoaded', () => { // Helper function to send messages safely to content script function safelySendMessage(message) { - //console.log('Sending message to content script:', message); chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { if (!tabs || !tabs[0] || !tabs[0].id) { - //console.log('No active tab found'); return; } try { chrome.tabs.sendMessage(tabs[0].id, message, response => { if (chrome.runtime.lastError) { - console.log('Error sending message:', chrome.runtime.lastError.message); + console.error('Error sending message:', chrome.runtime.lastError.message); // Attempt to inject the content script if it's not already injected chrome.scripting.executeScript({ target: { tabId: tabs[0].id }, @@ -49,12 +47,12 @@ document.addEventListener('DOMContentLoaded', () => { chrome.tabs.sendMessage(tabs[0].id, message); }, 100); }).catch(err => { - console.log('Error injecting content script:', err); + console.error('Error injecting content script:', err); }); } }); } catch (error) { - console.log('Error sending message:', error); + console.error('Error sending message:', error); } }); } diff --git a/src/popup/settings.ts b/src/popup/settings.ts index f3305a4..db11146 100644 --- a/src/popup/settings.ts +++ b/src/popup/settings.ts @@ -32,7 +32,6 @@ document.addEventListener('DOMContentLoaded', () => { // Set up change listener themeSelect.addEventListener('change', () => { const selectedValue = themeSelect.value as 'dark' | 'light' | 'auto'; - console.log('Theme dropdown changed to:', selectedValue); // Apply the selected theme setTheme(selectedValue); diff --git a/src/utils/theme.ts b/src/utils/theme.ts index ef6f580..10c0182 100644 --- a/src/utils/theme.ts +++ b/src/utils/theme.ts @@ -56,15 +56,11 @@ const THEME_STYLES = { // Initialize theme on load export function initializeTheme(): void { - //console.log('Initializing theme...'); - // Get saved theme settings chrome.storage.local.get(['isDarkTheme', 'themeMode', 'lastDetectedTheme'], (result) => { let theme: ThemeName = result.isDarkTheme ? 'dark' : 'light'; const mode: ThemeMode = result.themeMode === 'auto' ? 'auto' : 'manual'; - //console.log(`Theme settings: Theme=${theme}, Mode=${mode}`); - // For auto mode, use last detected theme if available if (mode === 'auto' && result.lastDetectedTheme) { theme = result.lastDetectedTheme; @@ -82,8 +78,6 @@ export function initializeTheme(): void { // Set theme based on dropdown selection export function setTheme(theme: ThemeName | 'auto'): void { - //console.log(`Setting theme to: ${theme}`); - if (theme === 'auto') { // Enable auto mode but keep current theme until detection chrome.storage.local.get(['isDarkTheme'], (result) => { @@ -103,8 +97,6 @@ export function setTheme(theme: ThemeName | 'auto'): void { // Apply a theme to the current page function applyTheme(theme: ThemeName, mode: ThemeMode): void { - //console.log(`Applying theme: ${theme}, mode: ${mode}`); - // Set data attribute for CSS variables document.documentElement.setAttribute('data-theme', theme); @@ -174,8 +166,6 @@ function updateThemeUI(theme: ThemeName, mode: ThemeMode): void { // Detect theme from active LeetCode page function detectThemeFromPage(): void { - //console.log('Detecting theme from active tab...'); - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { if (tabs[0]?.id) { chrome.tabs.sendMessage( @@ -183,13 +173,11 @@ function detectThemeFromPage(): void { { action: 'getTheme' }, (response) => { if (chrome.runtime.lastError) { - //console.log('Error detecting theme:', chrome.runtime.lastError); + console.error('Error detecting theme:', chrome.runtime.lastError); return; } if (response?.theme) { - //console.log('Detected theme:', response.theme); - // Apply the detected theme applyTheme(response.theme, 'auto'); } From cb4051ce1f8c8c3c9132f85bcce9574003141791 Mon Sep 17 00:00:00 2001 From: zubyj Date: Sat, 12 Apr 2025 18:00:26 -0700 Subject: [PATCH 8/9] fix show/hide examples, difficulty, rating not toggling instantly --- src/background/background.ts | 16 ++++++ src/content-script/update-description-tab.ts | 9 ++- src/popup/settings.ts | 58 +++++++++++++++----- 3 files changed, 67 insertions(+), 16 deletions(-) diff --git a/src/background/background.ts b/src/background/background.ts index 281721c..ac4cd50 100644 --- a/src/background/background.ts +++ b/src/background/background.ts @@ -51,6 +51,22 @@ chrome.runtime.onInstalled.addListener(() => { }); chrome.runtime.onMessage.addListener((request) => { + // Direct path for settings updates + if (request.action === 'settingsUpdate') { + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + const tab = tabs[0]; + if (tab?.id && tab.url?.includes('leetcode.com/problems/')) { + chrome.tabs.sendMessage(tab.id, { + action: 'updateDescription', + title: tab.title || 'title', + isSettingsUpdate: true + }); + } + }); + return; + } + + // Existing message handlers if (request.action === 'openCompanyPage') { chrome.storage.local.set({ clickedCompany: request.company }); chrome.tabs.create({ diff --git a/src/content-script/update-description-tab.ts b/src/content-script/update-description-tab.ts index 33cfe1b..d3c0247 100644 --- a/src/content-script/update-description-tab.ts +++ b/src/content-script/update-description-tab.ts @@ -371,9 +371,16 @@ function setupDescriptionThemeListener() { chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'updateDescription') { + // For settings updates, bypass the state checks + if (request.isSettingsUpdate) { + console.log('Updating description tab due to settings change...'); + updatePageContent(); + return true; + } + // Only detect theme on first load, problem change, or refresh if (!request.isProblemChange && !request.isRefresh) { - return; + return true; } console.log('Updating description tab...'); diff --git a/src/popup/settings.ts b/src/popup/settings.ts index db11146..f8a6820 100644 --- a/src/popup/settings.ts +++ b/src/popup/settings.ts @@ -115,6 +115,45 @@ document.addEventListener('DOMContentLoaded', () => { if (showRatingIcon) showRatingIcon.textContent = result.showRating ? '✅' : '❌'; }); + // Helper function to send messages safely to content script + function safelySendMessage(message: any) { + chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { + const tabId = tabs[0]?.id; + if (!tabs || !tabs[0] || typeof tabId === 'undefined') { + return; + } + + try { + // Send message to background script for settings updates + if (message.action === 'updateDescription') { + chrome.runtime.sendMessage({ action: 'settingsUpdate' }); + return; + } + + // For other messages, send directly to content script + chrome.tabs.sendMessage(tabId, message, response => { + if (chrome.runtime.lastError) { + console.error('Error sending message:', chrome.runtime.lastError.message); + // Attempt to inject the content script if it's not already injected + chrome.scripting.executeScript({ + target: { tabId }, + files: ['dist/content-script/update-description-tab.js'] + }).then(() => { + // Try sending the message again after injecting the script + setTimeout(() => { + chrome.tabs.sendMessage(tabId, message); + }, 100); + }).catch(err => { + console.error('Error injecting content script:', err); + }); + } + }); + } catch (error) { + console.error('Error sending message:', error); + } + }); + } + // Set up toggle event handlers const showCompanyTagsBtn = document.getElementById('show-company-tags-btn'); showCompanyTagsBtn && showCompanyTagsBtn.addEventListener('click', function () { @@ -123,9 +162,7 @@ document.addEventListener('DOMContentLoaded', () => { chrome.storage.local.set({ showCompanyTags: showCompanyTags }, () => { const showCompanyTagsIcon = document.getElementById('show-company-tags-icon'); showCompanyTagsIcon && (showCompanyTagsIcon.textContent = showCompanyTags ? '✅' : '❌'); - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - chrome.tabs.sendMessage(tabs[0].id || 0, { action: 'updateDescription', title: tabs[0].title || 'title' }); - }); + safelySendMessage({ action: 'updateDescription', title: document.title || 'title' }); }); }); }); @@ -137,10 +174,7 @@ document.addEventListener('DOMContentLoaded', () => { chrome.storage.local.set({ showExamples: showExamples }, () => { const showExamplesIcon = document.getElementById('show-examples-icon'); showExamplesIcon && (showExamplesIcon.textContent = showExamples ? '✅' : '❌'); - }); - // Manually trigger the update description after toggling - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - chrome.tabs.sendMessage(tabs[0].id || 0, { action: 'updateDescription', title: tabs[0].title || 'title' }); + safelySendMessage({ action: 'updateDescription', title: document.title || 'title' }); }); }); }); @@ -152,10 +186,7 @@ document.addEventListener('DOMContentLoaded', () => { chrome.storage.local.set({ showDifficulty: showDifficulty }, () => { const showDifficultyIcon = document.getElementById('show-difficulty-icon'); if (showDifficultyIcon) showDifficultyIcon.textContent = showDifficulty ? '✅' : '❌'; - }); - // Manually trigger the update description after toggling - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - chrome.tabs.sendMessage(tabs[0].id || 0, { action: 'updateDescription', title: tabs[0].title || 'title' }); + safelySendMessage({ action: 'updateDescription', title: document.title || 'title' }); }); }); }); @@ -167,10 +198,7 @@ document.addEventListener('DOMContentLoaded', () => { chrome.storage.local.set({ showRating: showRating }, () => { const showRatingIcon = document.getElementById('show-rating-icon'); if (showRatingIcon) showRatingIcon.textContent = showRating ? '✅' : '❌'; - }); - // Manually trigger the update description after toggling - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - chrome.tabs.sendMessage(tabs[0].id || 0, { action: 'updateDescription', title: tabs[0].title || 'title' }); + safelySendMessage({ action: 'updateDescription', title: document.title || 'title' }); }); }); }); From 979d10eb8ed95c903afa1bce1bdd7ecdd1aa1685 Mon Sep 17 00:00:00 2001 From: zubyj Date: Sat, 12 Apr 2025 18:03:51 -0700 Subject: [PATCH 9/9] fix company tag only working on refresh --- src/content-script/update-description-tab.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/content-script/update-description-tab.ts b/src/content-script/update-description-tab.ts index d3c0247..5dbbbda 100644 --- a/src/content-script/update-description-tab.ts +++ b/src/content-script/update-description-tab.ts @@ -162,16 +162,21 @@ function showRating(problemTitle: string) { // show the company tags if the user has enabled it in the settings function showCompanyTags(problemTitle: string) { chrome.storage.local.get(['showCompanyTags'], (result) => { - if (!result.showCompanyTags) { - return; - } - // Check if we're on the description tab before proceeding const isDescriptionPage = !window.location.href.includes('/solutions'); if (!isDescriptionPage) { return; } + // Remove existing container if setting is disabled + const existingContainer = document.getElementById('companyTagContainer'); + if (!result.showCompanyTags) { + if (existingContainer) { + existingContainer.remove(); + } + return; + } + // Try to find the description element with retries const maxRetries = 10; const baseDelay = 300;