From 7878aec2a71072372b24d97d17454a2fa17e6adf Mon Sep 17 00:00:00 2001 From: Saksham Sirohi Date: Sat, 5 Jul 2025 20:20:08 +0530 Subject: [PATCH 1/2] added cross-browser compatibility for gekko and blink based browsers --- package.json | 5 +- src/manifest.json | 18 +- src/popup.html | 1 + src/scripts/browser-polyfill.js | 7 + src/scripts/main.js | 385 ++++++++++++++-------------- src/scripts/popup.js | 286 ++++++++++----------- src/scripts/scrumHelper.js | 430 ++++++++++++++++---------------- 7 files changed, 572 insertions(+), 560 deletions(-) create mode 100644 src/scripts/browser-polyfill.js diff --git a/package.json b/package.json index 9262264..505845b 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "tailwindcss": "^4.1.4" }, "dependencies": { - "@tailwindcss/cli": "^4.1.3" + "@tailwindcss/cli": "^4.1.3", + "browser-polyfill": "^3.20.2" } -} \ No newline at end of file +} diff --git a/src/manifest.json b/src/manifest.json index 69eaa16..abb4556 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -11,21 +11,29 @@ "96": "icons/icon.png", "48": "icons/icon.png" }, - "background": { - "service_worker": "scripts/background.js" + "browser_specific_settings": { + "gecko": { + "id": "scrum-helper@fossasia.org", + "strict_min_version": "109.0" + } }, "content_scripts": [ { "matches": [ - "*://groups.google.com/forum/*", + "*://groups.google.com/forum/*", "*://groups.google.com/g/*", "*://groups.google.com/u/*/g/*", "*://mail.google.com/*", "*://outlook.live.com/*", "*://outlook.office.com/*", - "*://mail.yahoo.com/*" + "*://mail.yahoo.com/*" ], - "js": ["scripts/jquery-3.2.1.min.js", "scripts/emailClientAdapter.js", "scripts/scrumHelper.js"] + "js": [ + "scripts/browser-polyfill.js", + "scripts/jquery-3.2.1.min.js", + "scripts/emailClientAdapter.js", + "scripts/scrumHelper.js" + ] } ], diff --git a/src/popup.html b/src/popup.html index 522ee84..5f8e5cf 100644 --- a/src/popup.html +++ b/src/popup.html @@ -260,6 +260,7 @@

Note:

+ diff --git a/src/scripts/browser-polyfill.js b/src/scripts/browser-polyfill.js new file mode 100644 index 0000000..1eb3307 --- /dev/null +++ b/src/scripts/browser-polyfill.js @@ -0,0 +1,7 @@ +if (typeof browser === "undefined") { + window.browser = typeof chrome !== "undefined" ? chrome : {}; + // Create global browser reference + if (typeof chrome !== "undefined") { + var browser = chrome; + } +} \ No newline at end of file diff --git a/src/scripts/main.js b/src/scripts/main.js index 383e6e2..ab5c928 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -12,247 +12,244 @@ let userReasonElement = document.getElementById('userReason'); let showCommitsElement = document.getElementById('showCommits'); function handleBodyOnLoad() { - chrome.storage.local.get( - [ - 'githubUsername', - 'projectName', - 'enableToggle', - 'startingDate', - 'endingDate', - 'showOpenLabel', - 'userReason', - 'lastWeekContribution', - 'yesterdayContribution', - 'cacheInput', - 'githubToken', - 'showCommits', - ], - (items) => { - if (items.githubUsername) { - githubUsernameElement.value = items.githubUsername; - } - if (items.githubToken) { - githubTokenElement.value = items.githubToken; - } - if (items.projectName) { - projectNameElement.value = items.projectName; - } - if (items.cacheInput) { - cacheInputElement.value = items.cacheInput; - } - if (items.enableToggle) { - enableToggleElement.checked = items.enableToggle; - } else if (items.enableToggle !== false) { - // undefined - enableToggleElement.checked = true; - handleEnableChange(); - } - if (items.endingDate) { - endingDateElement.value = items.endingDate; - } - if (items.startingDate) { - startingDateElement.value = items.startingDate; - } - if (items.showOpenLabel) { - showOpenLabelElement.checked = items.showOpenLabel; - } else if (items.showOpenLabel !== false) { - // undefined - showOpenLabelElement.checked = true; - handleOpenLabelChange(); - } - if (items.userReason) { - userReasonElement.value = items.userReason; - } - if (items.lastWeekContribution) { - lastWeekContributionElement.checked = items.lastWeekContribution; - handleLastWeekContributionChange(); - } - else if (items.lastWeekContribution !== false) { - lastWeekContributionElement.checked = true; - handleLastWeekContributionChange(); - } - if (items.yesterdayContribution) { - yesterdayContributionElement.checked = items.yesterdayContribution; - handleYesterdayContributionChange(); - } - else if (items.yesterdayContribution !== false) { - yesterdayContributionElement.checked = true; - handleYesterdayContributionChange(); - } - if (items.showCommits){ - showCommitsElement.checked = items.showCommits; - } else { - showCommitsElement.checked = false; - handleShowCommitsChange(); - } - }, - ); + browser.storage.local.get( + [ + 'githubUsername', + 'projectName', + 'enableToggle', + 'startingDate', + 'endingDate', + 'showOpenLabel', + 'userReason', + 'lastWeekContribution', + 'yesterdayContribution', + 'cacheInput', + 'githubToken', + 'showCommits', + ], + (items) => { + if (items.githubUsername) { + githubUsernameElement.value = items.githubUsername; + } + if (items.githubToken) { + githubTokenElement.value = items.githubToken; + } + if (items.projectName) { + projectNameElement.value = items.projectName; + } + if (items.cacheInput) { + cacheInputElement.value = items.cacheInput; + } + if (items.enableToggle) { + enableToggleElement.checked = items.enableToggle; + } else if (items.enableToggle !== false) { + enableToggleElement.checked = true; + handleEnableChange(); + } + if (items.endingDate) { + endingDateElement.value = items.endingDate; + } + if (items.startingDate) { + startingDateElement.value = items.startingDate; + } + if (items.showOpenLabel) { + showOpenLabelElement.checked = items.showOpenLabel; + } else if (items.showOpenLabel !== false) { + showOpenLabelElement.checked = true; + handleOpenLabelChange(); + } + if (items.userReason) { + userReasonElement.value = items.userReason; + } + if (items.lastWeekContribution) { + lastWeekContributionElement.checked = items.lastWeekContribution; + handleLastWeekContributionChange(); + } + else if (items.lastWeekContribution !== false) { + lastWeekContributionElement.checked = true; + handleLastWeekContributionChange(); + } + if (items.yesterdayContribution) { + yesterdayContributionElement.checked = items.yesterdayContribution; + handleYesterdayContributionChange(); + } + else if (items.yesterdayContribution !== false) { + yesterdayContributionElement.checked = true; + handleYesterdayContributionChange(); + } + if (items.showCommits) { + showCommitsElement.checked = items.showCommits; + } else { + showCommitsElement.checked = false; + handleShowCommitsChange(); + } + }, + ); } document.getElementById('refreshCache').addEventListener('click', async (e) => { - const button = e.currentTarget; - button.classList.add('loading'); - button.disabled = true; + const button = e.currentTarget; + button.classList.add('loading'); + button.disabled = true; - try { - const tabs = await chrome.tabs.query({ active: true, currentWindow: true }); - await chrome.tabs.sendMessage(tabs[0].id, { - action: 'forceRefresh', - timestamp: Date.now() - }); + try { + const tabs = await browser.tabs.query({ active: true, currentWindow: true }); + await browser.tabs.sendMessage(tabs[0].id, { + action: 'forceRefresh', + timestamp: Date.now() + }); - // Reload the active tab to re-inject content - chrome.tabs.reload(tabs[0].id); + browser.tabs.reload(tabs[0].id); - Materialize.toast({ html: 'Data refreshed successfully!', classes: 'green' }); - } catch (err) { - console.log('Refresh successful',); - } finally { - setTimeout(() => { - button.classList.remove('loading'); - button.disabled = false; - }, 500); - } + Materialize.toast({ html: 'Data refreshed successfully!', classes: 'green' }); + } catch (err) { + console.log('Refresh successful',); + } finally { + setTimeout(() => { + button.classList.remove('loading'); + button.disabled = false; + }, 500); + } }); function handleEnableChange() { - let value = enableToggleElement.checked; - chrome.storage.local.set({ enableToggle: value }); + let value = enableToggleElement.checked; + browser.storage.local.set({ enableToggle: value }); } function handleStartingDateChange() { - let value = startingDateElement.value; - chrome.storage.local.set({ startingDate: value }); + let value = startingDateElement.value; + browser.storage.local.set({ startingDate: value }); } function handleEndingDateChange() { - let value = endingDateElement.value; - chrome.storage.local.set({ endingDate: value }); + let value = endingDateElement.value; + browser.storage.local.set({ endingDate: value }); } function handleLastWeekContributionChange() { - let value = lastWeekContributionElement.checked; - let labelElement = document.querySelector("label[for='lastWeekContribution']"); - if (value) { - startingDateElement.readOnly = true; - endingDateElement.readOnly = true; - endingDateElement.value = getToday(); - startingDateElement.value = getLastWeek(); - handleEndingDateChange(); - handleStartingDateChange(); - labelElement.classList.add("selectedLabel"); - labelElement.classList.remove("unselectedLabel"); - } else { - startingDateElement.readOnly = false; - endingDateElement.readOnly = false; - labelElement.classList.add("unselectedLabel"); - labelElement.classList.remove("selectedLabel"); - } + let value = lastWeekContributionElement.checked; + let labelElement = document.querySelector("label[for='lastWeekContribution']"); + if (value) { + startingDateElement.readOnly = true; + endingDateElement.readOnly = true; + endingDateElement.value = getToday(); + startingDateElement.value = getLastWeek(); + handleEndingDateChange(); + handleStartingDateChange(); + labelElement.classList.add("selectedLabel"); + labelElement.classList.remove("unselectedLabel"); + } else { + startingDateElement.readOnly = false; + endingDateElement.readOnly = false; + labelElement.classList.add("unselectedLabel"); + labelElement.classList.remove("selectedLabel"); + } - chrome.storage.local.set({ lastWeekContribution: value }); + browser.storage.local.set({ lastWeekContribution: value }); } function handleYesterdayContributionChange() { - let value = yesterdayContributionElement.checked; - let labelElement = document.querySelector("label[for='yesterdayContribution']"); + let value = yesterdayContributionElement.checked; + let labelElement = document.querySelector("label[for='yesterdayContribution']"); - if (value) { - startingDateElement.readOnly = true; - endingDateElement.readOnly = true; - endingDateElement.value = getToday(); - startingDateElement.value = getYesterday(); - handleEndingDateChange(); - handleStartingDateChange(); - labelElement.classList.add("selectedLabel"); - labelElement.classList.remove("unselectedLabel"); - } else { - startingDateElement.readOnly = false; - endingDateElement.readOnly = false; - labelElement.classList.add("unselectedLabel"); - labelElement.classList.remove("selectedLabel"); - } - chrome.storage.local.set({ yesterdayContribution: value }); + if (value) { + startingDateElement.readOnly = true; + endingDateElement.readOnly = true; + endingDateElement.value = getToday(); + startingDateElement.value = getYesterday(); + handleEndingDateChange(); + handleStartingDateChange(); + labelElement.classList.add("selectedLabel"); + labelElement.classList.remove("unselectedLabel"); + } else { + startingDateElement.readOnly = false; + endingDateElement.readOnly = false; + labelElement.classList.add("unselectedLabel"); + labelElement.classList.remove("selectedLabel"); + } + browser.storage.local.set({ yesterdayContribution: value }); } function getLastWeek() { - let today = new Date(); - let lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); - let lastWeekMonth = lastWeek.getMonth() + 1; - let lastWeekDay = lastWeek.getDate(); - let lastWeekYear = lastWeek.getFullYear(); - let lastWeekDisplayPadded = - ('0000' + lastWeekYear.toString()).slice(-4) + - '-' + - ('00' + lastWeekMonth.toString()).slice(-2) + - '-' + - ('00' + lastWeekDay.toString()).slice(-2); - return lastWeekDisplayPadded; + let today = new Date(); + let lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); + let lastWeekMonth = lastWeek.getMonth() + 1; + let lastWeekDay = lastWeek.getDate(); + let lastWeekYear = lastWeek.getFullYear(); + let lastWeekDisplayPadded = + ('0000' + lastWeekYear.toString()).slice(-4) + + '-' + + ('00' + lastWeekMonth.toString()).slice(-2) + + '-' + + ('00' + lastWeekDay.toString()).slice(-2); + return lastWeekDisplayPadded; } function getYesterday() { - let today = new Date(); - let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); - let yesterdayMonth = yesterday.getMonth() + 1; - let yesterdayWeekDay = yesterday.getDate(); - let yesterdayYear = yesterday.getFullYear(); - let yesterdayPadded = - ('0000' + yesterdayYear.toString()).slice(-4) + - '-' + - ('00' + yesterdayMonth.toString()).slice(-2) + - '-' + - ('00' + yesterdayWeekDay.toString()).slice(-2); - return yesterdayPadded; + let today = new Date(); + let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); + let yesterdayMonth = yesterday.getMonth() + 1; + let yesterdayWeekDay = yesterday.getDate(); + let yesterdayYear = yesterday.getFullYear(); + let yesterdayPadded = + ('0000' + yesterdayYear.toString()).slice(-4) + + '-' + + ('00' + yesterdayMonth.toString()).slice(-2) + + '-' + + ('00' + yesterdayWeekDay.toString()).slice(-2); + return yesterdayPadded; } function getToday() { - let today = new Date(); - let Week = new Date(today.getFullYear(), today.getMonth(), today.getDate()); - let WeekMonth = Week.getMonth() + 1; - let WeekDay = Week.getDate(); - let WeekYear = Week.getFullYear(); - let WeekDisplayPadded = - ('0000' + WeekYear.toString()).slice(-4) + - '-' + - ('00' + WeekMonth.toString()).slice(-2) + - '-' + - ('00' + WeekDay.toString()).slice(-2); - return WeekDisplayPadded; + let today = new Date(); + let Week = new Date(today.getFullYear(), today.getMonth(), today.getDate()); + let WeekMonth = Week.getMonth() + 1; + let WeekDay = Week.getDate(); + let WeekYear = Week.getFullYear(); + let WeekDisplayPadded = + ('0000' + WeekYear.toString()).slice(-4) + + '-' + + ('00' + WeekMonth.toString()).slice(-2) + + '-' + + ('00' + WeekDay.toString()).slice(-2); + return WeekDisplayPadded; } function handleGithubUsernameChange() { - let value = githubUsernameElement.value; - chrome.storage.local.set({ githubUsername: value }); + let value = githubUsernameElement.value; + browser.storage.local.set({ githubUsername: value }); } function handleGithubTokenChange() { - let value = githubTokenElement.value; - chrome.storage.local.set({ githubToken: value }); + let value = githubTokenElement.value; + browser.storage.local.set({ githubToken: value }); } function handleProjectNameChange() { - let value = projectNameElement.value; - chrome.storage.local.set({ projectName: value }); + let value = projectNameElement.value; + browser.storage.local.set({ projectName: value }); } function handleCacheInputChange() { - let value = cacheInputElement.value; - chrome.storage.local.set({ cacheInput: value }); + let value = cacheInputElement.value; + browser.storage.local.set({ cacheInput: value }); } function handleOpenLabelChange() { - let value = showOpenLabelElement.checked; - let labelElement = document.querySelector("label[for='showOpenLabel']"); + let value = showOpenLabelElement.checked; + let labelElement = document.querySelector("label[for='showOpenLabel']"); - if (value) { - labelElement.classList.add("selectedLabel"); - labelElement.classList.remove("unselectedLabel"); - } else { - labelElement.classList.add("unselectedLabel"); - labelElement.classList.remove("selectedLabel"); - } + if (value) { + labelElement.classList.add("selectedLabel"); + labelElement.classList.remove("unselectedLabel"); + } else { + labelElement.classList.add("unselectedLabel"); + labelElement.classList.remove("selectedLabel"); + } - chrome.storage.local.set({ showOpenLabel: value }); + browser.storage.local.set({ showOpenLabel: value }); } function handleUserReasonChange() { - let value = userReasonElement.value; - chrome.storage.local.set({ userReason: value }); + let value = userReasonElement.value; + browser.storage.local.set({ userReason: value }); } function handleShowCommitsChange() { let value = showCommitsElement.checked; - chrome.storage.local.set({ showCommits: value }); + browser.storage.local.set({ showCommits: value }); } enableToggleElement.addEventListener('change', handleEnableChange); diff --git a/src/scripts/popup.js b/src/scripts/popup.js index 855da2a..90940a7 100644 --- a/src/scripts/popup.js +++ b/src/scripts/popup.js @@ -43,6 +43,23 @@ function getYesterday() { } document.addEventListener('DOMContentLoaded', function () { + // Cross-browser storage detection + const storage = typeof browser !== 'undefined' ? browser.storage : chrome.storage; + + // Firefox date input fix + const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; + if (isFirefox) { + document.querySelectorAll('input[type="date"]').forEach(input => { + if (!input.value) { + input.type = 'text'; + input.placeholder = 'YYYY-MM-DD'; + } + input.addEventListener('blur', () => { + if (input.value) input.type = 'date'; + }); + }); + } + // Dark mode setup const darkModeToggle = document.querySelector('img[alt="Night Mode"]'); const settingsIcon = document.getElementById('settingsIcon'); @@ -62,12 +79,12 @@ document.addEventListener('DOMContentLoaded', function () { const orgInput = document.getElementById('orgInput'); const setOrgBtn = document.getElementById('setOrgBtn'); - chrome.storage.local.get(['darkMode'], function (result) { + storage.local.get(['darkMode'], function (result) { if (result.darkMode) { body.classList.add('dark-mode'); darkModeToggle.src = 'icons/light-mode.png'; if (settingsIcon) { - settingsIcon.src = 'icons/settings-night.png'; // Changed from settings-night.png + settingsIcon.src = 'icons/settings-night.png'; } } }); @@ -87,7 +104,7 @@ document.addEventListener('DOMContentLoaded', function () { darkModeToggle.addEventListener('click', function () { body.classList.toggle('dark-mode'); const isDarkMode = body.classList.contains('dark-mode'); - chrome.storage.local.set({ darkMode: isDarkMode }); + storage.local.set({ darkMode: isDarkMode }); this.src = isDarkMode ? 'icons/light-mode.png' : 'icons/night-mode.png'; const settingsIcon = document.getElementById('settingsIcon'); if (settingsIcon) { @@ -129,7 +146,6 @@ document.addEventListener('DOMContentLoaded', function () { 'githubToken', 'projectName', 'settingsToggle', - ]; const radios = document.querySelectorAll('input[name="timeframe"]'); @@ -163,7 +179,6 @@ document.addEventListener('DOMContentLoaded', function () { } }); - if (customDateContainer) { if (!enableToggle) { customDateContainer.style.opacity = '0.5'; @@ -188,7 +203,7 @@ document.addEventListener('DOMContentLoaded', function () { } } - chrome.storage.local.get(['enableToggle'], (items) => { + storage.local.get(['enableToggle'], (items) => { const enableToggle = items.enableToggle !== false; updateContentState(enableToggle); if (!enableToggle) { @@ -198,18 +213,16 @@ document.addEventListener('DOMContentLoaded', function () { initializePopup(); }) - chrome.storage.onChanged.addListener((changes, namespace) => { + storage.onChanged.addListener((changes, namespace) => { if (namespace === 'local' && changes.enableToggle) { updateContentState(changes.enableToggle.newValue); if (changes.enableToggle.newValue) { - // re-initialize if enabled initializePopup(); } } }); function initializePopup() { - // Button setup const generateBtn = document.getElementById('generateReport'); const copyBtn = document.getElementById('copyReport'); @@ -220,7 +233,7 @@ document.addEventListener('DOMContentLoaded', function () { if (!org) { org = 'fossasia'; } - chrome.storage.local.set({ orgName: org }, () => { + storage.local.set({ orgName: org }, () => { generateBtn.innerHTML = ' Generating...'; generateBtn.disabled = true; window.generateScrumReport(); @@ -267,14 +280,14 @@ document.addEventListener('DOMContentLoaded', function () { startDateInput.readOnly = false; endDateInput.readOnly = false; - chrome.storage.local.set({ + storage.local.set({ lastWeekContribution: false, yesterdayContribution: false, selectedTimeframe: null }); }); - chrome.storage.local.get([ + storage.local.get([ 'selectedTimeframe', 'lastWeekContribution', 'yesterdayContribution', @@ -283,13 +296,11 @@ document.addEventListener('DOMContentLoaded', function () { ], (items) => { console.log('Restoring state:', items); - if (items.startingDate && items.endingDate && !items.lastWeekContribution && !items.yesterdayContribution) { const startDateInput = document.getElementById('startingDate'); const endDateInput = document.getElementById('endingDate'); if (startDateInput && endDateInput) { - startDateInput.value = items.startingDate; endDateInput.value = items.endingDate; startDateInput.readOnly = false; @@ -325,7 +336,7 @@ document.addEventListener('DOMContentLoaded', function () { } startDateInput.readOnly = endDateInput.readOnly = true; - chrome.storage.local.set({ + storage.local.set({ startingDate: startDateInput.value, endingDate: endDateInput.value, lastWeekContribution: items.selectedTimeframe === 'lastWeekContribution', @@ -372,7 +383,7 @@ document.addEventListener('DOMContentLoaded', function () { showReportView(); // Load org from storage or default - chrome.storage.local.get(['orgName'], function (result) { + storage.local.get(['orgName'], function (result) { orgInput.value = result.orgName || ''; }); @@ -382,8 +393,8 @@ document.addEventListener('DOMContentLoaded', function () { if (!org) { org = 'fossasia'; } - chrome.storage.local.set({ orgName: org }, function () { - chrome.storage.local.remove('githubCache'); // Clear cache on org change + storage.local.set({ orgName: org }, function () { + storage.local.remove('githubCache'); }); }); @@ -425,14 +436,14 @@ document.addEventListener('DOMContentLoaded', function () { } const oldToast = document.getElementById('invalid-org-toast'); if (oldToast) oldToast.parentNode.removeChild(oldToast); - chrome.storage.local.set({ orgName: org }, function () { + storage.local.set({ orgName: org }, function () { // Always clear the scrum report and show org changed message const scrumReport = document.getElementById('scrumReport'); if (scrumReport) { scrumReport.innerHTML = '

Organization changed. Click Generate button to fetch the GitHub activities.

'; } // Clear the githubCache for previous org - chrome.storage.local.remove('githubCache'); + storage.local.remove('githubCache'); setOrgBtn.disabled = false; setOrgBtn.innerHTML = originalText; // Always show green toast: org is set @@ -484,7 +495,7 @@ document.addEventListener('DOMContentLoaded', function () { let cacheInput = document.getElementById('cacheInput'); if (cacheInput) { - chrome.storage.local.get(['cacheInput'], function (result) { + storage.local.get(['cacheInput'], function (result) { if (result.cacheInput) { cacheInput.value = result.cacheInput; } else { @@ -506,150 +517,147 @@ document.addEventListener('DOMContentLoaded', function () { this.style.borderColor = '#10b981'; } - chrome.storage.local.set({ cacheInput: ttlValue }, function () { + storage.local.set({ cacheInput: ttlValue }, function () { console.log('Cache TTL saved:', ttlValue, 'minutes'); }); }); - } -}); + // Tooltip bubble + document.querySelectorAll('.tooltip-container').forEach(container => { + const bubble = container.querySelector('.tooltip-bubble'); + if (!bubble) return; -// Tooltip bubble -document.querySelectorAll('.tooltip-container').forEach(container => { - const bubble = container.querySelector('.tooltip-bubble'); - if (!bubble) return; + function positionTooltip() { + const icon = container.querySelector('.question-icon') || container; + const rect = icon.getBoundingClientRect(); + const bubbleRect = bubble.getBoundingClientRect(); + const padding = 8; - function positionTooltip() { - const icon = container.querySelector('.question-icon') || container; - const rect = icon.getBoundingClientRect(); - const bubbleRect = bubble.getBoundingClientRect(); - const padding = 8; + let top = rect.top + window.scrollY; + let left = rect.right + padding + window.scrollX; - let top = rect.top + window.scrollY; - let left = rect.right + padding + window.scrollX; + if (left + bubbleRect.width > window.innerWidth - 10) { + left = rect.left - bubbleRect.width - padding + window.scrollX; + } + if (left < 8) left = 8; + if (top + bubbleRect.height > window.innerHeight - 10) { + top = rect.top - bubbleRect.height - padding + window.scrollY; + } + if (top < 8) top = 8; - if (left + bubbleRect.width > window.innerWidth - 10) { - left = rect.left - bubbleRect.width - padding + window.scrollX; - } - if (left < 8) left = 8; - if (top + bubbleRect.height > window.innerHeight - 10) { - top = rect.top - bubbleRect.height - padding + window.scrollY; + bubble.style.left = left + 'px'; + bubble.style.top = top + 'px'; } - if (top < 8) top = 8; - bubble.style.left = left + 'px'; - bubble.style.top = top + 'px'; - } - - container.addEventListener('mouseenter', positionTooltip); - container.addEventListener('focusin', positionTooltip); - container.addEventListener('mousemove', positionTooltip); - container.addEventListener('mouseleave', () => { - bubble.style.left = ''; - bubble.style.top = ''; - }); - container.addEventListener('focusout', () => { - bubble.style.left = ''; - bubble.style.top = ''; + container.addEventListener('mouseenter', positionTooltip); + container.addEventListener('focusin', positionTooltip); + container.addEventListener('mousemove', positionTooltip); + container.addEventListener('mouseleave', () => { + bubble.style.left = ''; + bubble.style.top = ''; + }); + container.addEventListener('focusout', () => { + bubble.style.left = ''; + bubble.style.top = ''; + }); }); -}); -// Radio button click handlers with toggle functionality -document.querySelectorAll('input[name="timeframe"]').forEach(radio => { - radio.addEventListener('click', function () { - if (this.dataset.wasChecked === 'true') { - this.checked = false; - this.dataset.wasChecked = 'false'; + // Radio button click handlers with toggle functionality + document.querySelectorAll('input[name="timeframe"]').forEach(radio => { + radio.addEventListener('click', function () { + if (this.dataset.wasChecked === 'true') { + this.checked = false; + this.dataset.wasChecked = 'false'; - const startDateInput = document.getElementById('startingDate'); - const endDateInput = document.getElementById('endingDate'); - startDateInput.readOnly = false; - endDateInput.readOnly = false; + const startDateInput = document.getElementById('startingDate'); + const endDateInput = document.getElementById('endingDate'); + startDateInput.readOnly = false; + endDateInput.readOnly = false; - chrome.storage.local.set({ - lastWeekContribution: false, - yesterdayContribution: false, - selectedTimeframe: null - }); - } else { - document.querySelectorAll('input[name="timeframe"]').forEach(r => { - r.dataset.wasChecked = 'false'; - }); - this.dataset.wasChecked = 'true'; - toggleRadio(this); - } + storage.local.set({ + lastWeekContribution: false, + yesterdayContribution: false, + selectedTimeframe: null + }); + } else { + document.querySelectorAll('input[name="timeframe"]').forEach(r => { + r.dataset.wasChecked = 'false'; + }); + this.dataset.wasChecked = 'true'; + toggleRadio(this); + } + }); }); -}); -// refresh cache button -document.getElementById('refreshCache').addEventListener('click', async function () { - const button = this; - const originalText = button.innerHTML; + // refresh cache button + document.getElementById('refreshCache').addEventListener('click', async function () { + const button = this; + const originalText = button.innerHTML; - button.classList.add('loading'); - button.innerHTML = 'Refreshing...'; - button.disabled = true; + button.classList.add('loading'); + button.innerHTML = 'Refreshing...'; + button.disabled = true; - try { - // Clear local cache - await forceGithubDataRefresh(); + try { + // Clear local cache + await forceGithubDataRefresh(); - // Clear the scrum report - const scrumReport = document.getElementById('scrumReport'); - if (scrumReport) { - scrumReport.innerHTML = '

Cache cleared successfully. Click "Generate Report" to fetch fresh data.

'; - } + // Clear the scrum report + const scrumReport = document.getElementById('scrumReport'); + if (scrumReport) { + scrumReport.innerHTML = '

Cache cleared successfully. Click "Generate Report" to fetch fresh data.

'; + } - button.innerHTML = 'Cache Cleared!'; - button.classList.remove('loading'); + button.innerHTML = 'Cache Cleared!'; + button.classList.remove('loading'); - setTimeout(() => { - button.innerHTML = originalText; - button.disabled = false; - }, 2000); + setTimeout(() => { + button.innerHTML = originalText; + button.disabled = false; + }, 2000); - } catch (error) { - console.error('Cache clear failed:', error); - button.innerHTML = 'Failed to clear cache'; - button.classList.remove('loading'); + } catch (error) { + console.error('Cache clear failed:', error); + button.innerHTML = 'Failed to clear cache'; + button.classList.remove('loading'); - setTimeout(() => { - button.innerHTML = originalText; - button.disabled = false; - }, 3000); - } -}); + setTimeout(() => { + button.innerHTML = originalText; + button.disabled = false; + }, 3000); + } + }); -function toggleRadio(radio) { - const startDateInput = document.getElementById('startingDate'); - const endDateInput = document.getElementById('endingDate'); + function toggleRadio(radio) { + const startDateInput = document.getElementById('startingDate'); + const endDateInput = document.getElementById('endingDate'); - console.log('Toggling radio:', radio.id); + console.log('Toggling radio:', radio.id); - if (radio.id === 'lastWeekContribution') { - startDateInput.value = getLastWeek(); - endDateInput.value = getToday(); - } else if (radio.id === 'yesterdayContribution') { - startDateInput.value = getYesterday(); - endDateInput.value = getToday(); - } + if (radio.id === 'lastWeekContribution') { + startDateInput.value = getLastWeek(); + endDateInput.value = getToday(); + } else if (radio.id === 'yesterdayContribution') { + startDateInput.value = getYesterday(); + endDateInput.value = getToday(); + } - startDateInput.readOnly = endDateInput.readOnly = true; - - chrome.storage.local.set({ - startingDate: startDateInput.value, - endingDate: endDateInput.value, - lastWeekContribution: radio.id === 'lastWeekContribution', - yesterdayContribution: radio.id === 'yesterdayContribution', - selectedTimeframe: radio.id, - githubCache: null // Clear cache to force new fetch - }, () => { - console.log('State saved, dates:', { - start: startDateInput.value, - end: endDateInput.value, - isLastWeek: radio.id === 'lastWeekContribution' + startDateInput.readOnly = endDateInput.readOnly = true; + + storage.local.set({ + startingDate: startDateInput.value, + endingDate: endDateInput.value, + lastWeekContribution: radio.id === 'lastWeekContribution', + yesterdayContribution: radio.id === 'yesterdayContribution', + selectedTimeframe: radio.id, + githubCache: null // Clear cache to force new fetch + }, () => { + console.log('State saved, dates:', { + start: startDateInput.value, + end: endDateInput.value, + isLastWeek: radio.id === 'lastWeekContribution' + }); }); - }); -} - + } +}); diff --git a/src/scripts/scrumHelper.js b/src/scripts/scrumHelper.js index 3aebad4..4aecc01 100644 --- a/src/scripts/scrumHelper.js +++ b/src/scripts/scrumHelper.js @@ -1,4 +1,21 @@ const DEBUG = true; +// Unified browser storage API using polyfilled browser object +const storage = browser.storage; +const runtime = browser.runtime; + +// Unified storage functions +function storageGet(keys) { + return new Promise(resolve => browser.storage.local.get(keys, resolve)); +} + +function storageSet(items) { + return new Promise(resolve => browser.storage.local.set(items, resolve)); +} + +function storageRemove(keys) { + return new Promise(resolve => browser.storage.local.remove(keys, resolve)); +} + function log(...args) { if (DEBUG) { console.log(`[SCRUM-HELPER]:`, ...args); @@ -21,8 +38,9 @@ function allIncluded(outputTarget = 'email') { return; } scrumGenerationInProgress = true; - console.log('allIncluded called with outputTarget:', outputTarget); - console.log('Current window context:', window.location.href); + log('allIncluded called with outputTarget:', outputTarget); + log('Current window context:', window.location.href); + let scrumBody = null; let scrumSubject = null; let startingDate = ''; @@ -59,129 +77,120 @@ function allIncluded(outputTarget = 'email') { let issue_opened_button = '
open
'; + async function getStorageData() { + log("Getting storage data for context:", outputTarget); + const items = await storageGet([ + 'githubUsername', + 'githubToken', + 'projectName', + 'enableToggle', + 'startingDate', + 'endingDate', + 'showOpenLabel', + 'showClosedLabel', + 'lastWeekContribution', + 'yesterdayContribution', + 'userReason', + 'showCommits', + 'githubCache', + 'cacheInput', + 'orgName' + ]); + log("Storage items received:", items); - // let linkStyle = ''; - function getChromeData() { - console.log("Getting Chrome data for context:", outputTarget); - chrome.storage.local.get( - [ - 'githubUsername', - 'githubToken', - 'projectName', - 'enableToggle', - 'startingDate', - 'endingDate', - 'showOpenLabel', - 'showClosedLabel', - 'lastWeekContribution', - 'yesterdayContribution', - 'userReason', - 'showCommits', - 'githubCache', - 'cacheInput', - 'orgName' - ], - (items) => { - console.log("Storage items received:", items); - - - if (outputTarget === 'popup') { - const usernameFromDOM = document.getElementById('githubUsername')?.value; - const projectFromDOM = document.getElementById('projectName')?.value; - const reasonFromDOM = document.getElementById('userReason')?.value; - const tokenFromDOM = document.getElementById('githubToken')?.value; - - items.githubUsername = usernameFromDOM || items.githubUsername; - items.projectName = projectFromDOM || items.projectName; - items.userReason = reasonFromDOM || items.userReason; - items.githubToken = tokenFromDOM || items.githubToken; - - chrome.storage.local.set({ - githubUsername: items.githubUsername, - projectName: items.projectName, - userReason: items.userReason, - githubToken: items.githubToken - }); - } + if (outputTarget === 'popup') { + const usernameFromDOM = document.getElementById('githubUsername')?.value; + const projectFromDOM = document.getElementById('projectName')?.value; + const reasonFromDOM = document.getElementById('userReason')?.value; + const tokenFromDOM = document.getElementById('githubToken')?.value; + + items.githubUsername = usernameFromDOM || items.githubUsername; + items.projectName = projectFromDOM || items.projectName; + items.userReason = reasonFromDOM || items.userReason; + items.githubToken = tokenFromDOM || items.githubToken; + + await storageSet({ + githubUsername: items.githubUsername, + projectName: items.projectName, + userReason: items.userReason, + githubToken: items.githubToken + }); + } - githubUsername = items.githubUsername; - projectName = items.projectName; - userReason = items.userReason || 'No Blocker at the moment'; - githubToken = items.githubToken; - lastWeekContribution = items.lastWeekContribution; - yesterdayContribution = items.yesterdayContribution; + githubUsername = items.githubUsername; + projectName = items.projectName; + userReason = items.userReason || 'No Blocker at the moment'; + githubToken = items.githubToken; + lastWeekContribution = items.lastWeekContribution; + yesterdayContribution = items.yesterdayContribution; - if (!items.enableToggle) { - enableToggle = items.enableToggle; - } + if (!items.enableToggle) { + enableToggle = items.enableToggle; + } - if (items.lastWeekContribution) { - handleLastWeekContributionChange(); - } else if (items.yesterdayContribution) { - handleYesterdayContributionChange(); - } else if (items.startingDate && items.endingDate) { - startingDate = items.startingDate; - endingDate = items.endingDate; - } else { - handleLastWeekContributionChange(); //on fresh unpack - default to last week. - if (outputTarget === 'popup') { - chrome.storage.local.set({ lastWeekContribution: true, yesterdayContribution: false }); - } - } - if (githubUsername) { - console.log("About to fetch GitHub data for:", githubUsername); - fetchGithubData(); - } else { - if (outputTarget === 'popup') { - console.log("No username found - popup context"); - // Show error in popup - const scrumReport = document.getElementById('scrumReport'); - const generateBtn = document.getElementById('generateReport'); - if (scrumReport) { - scrumReport.innerHTML = '
Please enter your GitHub username to generate a report.
'; - } - if (generateBtn) { - generateBtn.innerHTML = ' Generate Report'; - generateBtn.disabled = false; - } - scrumGenerationInProgress = false; - } else { - console.warn('No GitHub username found in storage'); - scrumGenerationInProgress = false; - } - return; - } - if (items.cacheInput) { - cacheInput = items.cacheInput; + if (items.lastWeekContribution) { + handleLastWeekContributionChange(); + } else if (items.yesterdayContribution) { + handleYesterdayContributionChange(); + } else if (items.startingDate && items.endingDate) { + startingDate = items.startingDate; + endingDate = items.endingDate; + } else { + handleLastWeekContributionChange(); + if (outputTarget === 'popup') { + await storageSet({ lastWeekContribution: true, yesterdayContribution: false }); + } + } + if (githubUsername) { + log("About to fetch GitHub data for:", githubUsername); + fetchGithubData(); + } else { + if (outputTarget === 'popup') { + log("No username found - popup context"); + const scrumReport = document.getElementById('scrumReport'); + const generateBtn = document.getElementById('generateReport'); + if (scrumReport) { + scrumReport.innerHTML = '
Please enter your GitHub username to generate a report.
'; } - if (items.showCommits !== undefined) { - showCommits = items.showCommits; - } else { - showCommits = false; // Default value + if (generateBtn) { + generateBtn.innerHTML = ' Generate Report'; + generateBtn.disabled = false; } + scrumGenerationInProgress = false; + } else { + logError('No GitHub username found in storage'); + scrumGenerationInProgress = false; + } + return; + } + if (items.cacheInput) { + cacheInput = items.cacheInput; + } + if (items.showCommits !== undefined) { + showCommits = items.showCommits; + } else { + showCommits = false; + } + if (!items.showOpenLabel) { + showOpenLabel = false; + pr_open_button = ''; + issue_opened_button = ''; + pr_merged_button = ''; + issue_closed_button = ''; + } + if (items.githubCache) { + githubCache.data = items.githubCache.data; + githubCache.cacheKey = items.githubCache.cacheKey; + githubCache.timestamp = items.githubCache.timestamp; + log('Restored cache from storage'); + } - if (!items.showOpenLabel) { - showOpenLabel = false; - pr_unmerged_button = ''; - issue_opened_button = ''; - pr_merged_button = ''; - issue_closed_button = ''; - } - if (items.githubCache) { - githubCache.data = items.githubCache.data; - githubCache.cacheKey = items.githubCache.cacheKey; - githubCache.timestamp = items.githubCache.timestamp; - log('Restored cache from storage'); - } - - if (items.orgName) { - orgName = items.orgName; - } - }, - ); + if (items.orgName) { + orgName = items.orgName; + } } - getChromeData(); + getStorageData(); function handleLastWeekContributionChange() { endingDate = getToday(); @@ -248,16 +257,12 @@ function allIncluded(outputTarget = 'email') { }; async function getCacheTTL() { - return new Promise((resolve) => { - chrome.storage.local.get(['cacheInput'], function (result) { - const ttlMinutes = result.cacheInput || 10; - resolve(ttlMinutes * 60 * 1000); - }); - }); + const result = await storageGet(['cacheInput']); + const ttlMinutes = result.cacheInput || 10; + return ttlMinutes * 60 * 1000; } - - function saveToStorage(data, subject = null) { + async function saveToStorage(data, subject = null) { const cacheData = { data: data, cacheKey: githubCache.cacheKey, @@ -270,57 +275,55 @@ function allIncluded(outputTarget = 'email') { hasSubject: !!subject, }); - return new Promise((resolve) => { - chrome.storage.local.set({ githubCache: cacheData }, () => { - if (chrome.runtime.lastError) { - logError('Storage save failed: ', chrome.runtime.lastError); - resolve(false); - } else { - log('Cache saved successfuly'); - githubCache.data = data; - githubCache.subject = subject; - resolve(true); - } - }); - }); + try { + await storageSet({ githubCache: cacheData }); + log('Cache saved successfully'); + githubCache.data = data; + githubCache.subject = subject; + return true; + } catch (err) { + logError('Storage save failed: ', err); + return false; + } } - function loadFromStorage() { + async function loadFromStorage() { log('Loading cache from storage'); - return new Promise(async (resolve) => { + try { + const result = await storageGet('githubCache'); + const cache = result.githubCache; + if (!cache) { + log('No cache found in storage'); + return false; + } + const currentTTL = await getCacheTTL(); - chrome.storage.local.get('githubCache', (result) => { - const cache = result.githubCache; - if (!cache) { - log('No cache found in storage'); - resolve(false); - return; - } - const isCacheExpired = (Date.now() - cache.timestamp) > currentTTL; - if (isCacheExpired) { - log('Cached data is expired'); - resolve(false); - return; - } - log('Found valid cache:', { - cacheKey: cache.cacheKey, - age: `${((Date.now() - cache.timestamp) / 1000 / 60).toFixed(1)} minutes`, - }); - - githubCache.data = cache.data; - githubCache.cacheKey = cache.cacheKey; - githubCache.timestamp = cache.timestamp; - githubCache.subject = cache.subject; - githubCache.usedToken = cache.usedToken || false; + const isCacheExpired = (Date.now() - cache.timestamp) > currentTTL; + if (isCacheExpired) { + log('Cached data is expired'); + return false; + } + + log('Found valid cache:', { + cacheKey: cache.cacheKey, + age: `${((Date.now() - cache.timestamp) / 1000 / 60).toFixed(1)} minutes`, + }); + githubCache.data = cache.data; + githubCache.cacheKey = cache.cacheKey; + githubCache.timestamp = cache.timestamp; + githubCache.subject = cache.subject; + githubCache.usedToken = cache.usedToken || false; - if (cache.subject && scrumSubject) { - scrumSubject.value = cache.subject; - scrumSubject.dispatchEvent(new Event('input', { bubbles: true })); - } - resolve(true); - }); - }); + if (cache.subject && scrumSubject) { + scrumSubject.value = cache.subject; + scrumSubject.dispatchEvent(new Event('input', { bubbles: true })); + } + return true; + } catch (err) { + logError('Error loading from storage:', err); + return false; + } } async function fetchGithubData() { @@ -344,7 +347,7 @@ function allIncluded(outputTarget = 'email') { // Check if we need to load from storage if (!githubCache.data && !githubCache.fetching) { await loadFromStorage(); - }; + } const currentTTL = await getCacheTTL(); githubCache.ttl = currentTTL; @@ -355,8 +358,8 @@ function allIncluded(outputTarget = 'email') { const isCacheKeyMatch = githubCache.cacheKey === cacheKey; const needsToken = !!githubToken; const cacheUsedToken = !!githubCache.usedToken; - if (githubCache.data && isCacheFresh & isCacheKeyMatch) { //should be && check after rebase - if (needsToken & !cacheUsedToken) { + if (githubCache.data && isCacheFresh && isCacheKeyMatch) { + if (needsToken && !cacheUsedToken) { log('Cache was fetched without token, but user now has a token. Invalidating cache.'); githubCache.data = null; } else { @@ -417,8 +420,8 @@ function allIncluded(outputTarget = 'email') { } if (issuesRes.status === 404 || prRes.status === 404) { - if (outputTarget === 'popup') { - Materialize.toast && Materialize.toast('Organization not found on GitHub', 3000); + if (outputTarget === 'popup' && typeof Materialize !== 'undefined' && Materialize.toast) { + Materialize.toast('Organization not found on GitHub', 3000); } throw new Error('Organization not found'); } @@ -469,6 +472,7 @@ function allIncluded(outputTarget = 'email') { if (outputTarget === 'popup') { const generateBtn = document.getElementById('generateReport'); + const scrumReport = document.getElementById('scrumReport'); if (scrumReport) { let errorMsg = 'An error occurred while generating the report.'; if (err) { @@ -477,8 +481,6 @@ function allIncluded(outputTarget = 'email') { else errorMsg = JSON.stringify(err) } scrumReport.innerHTML = `
${err.message || 'An error occurred while generating the report.'}
`; - generateBtn.innerHTML = ' Generate Report'; - generateBtn.disabled = false; } if (generateBtn) { generateBtn.innerHTML = ' Generate Report'; @@ -502,24 +504,23 @@ function allIncluded(outputTarget = 'email') { const owner = repoParts[repoParts.length - 2]; const repo = repoParts[repoParts.length - 1]; return ` - pr${idx}: repository(owner: "${owner}", name: "${repo}") { - pullRequest(number: ${pr.number}) { - commits(first: 100) { - nodes { - commit { - messageHeadline - committedDate - url - author { - name - user { login } - } - } - } - } - } - - }`; + pr${idx}: repository(owner: "${owner}", name: "${repo}") { + pullRequest(number: ${pr.number}) { + commits(first: 100) { + nodes { + commit { + messageHeadline + committedDate + url + author { + name + user { login } + } + } + } + } + } + }`; }).join('\n'); const query = `query { ${queries} }`; log('GraphQL query for commits:', query); @@ -554,6 +555,7 @@ function allIncluded(outputTarget = 'email') { }); return commitMap; } + async function verifyCacheStatus() { log('Cache Status: ', { hasCachedData: !!githubCache.data, @@ -562,9 +564,7 @@ function allIncluded(outputTarget = 'email') { isFetching: githubCache.fetching, queueLength: githubCache.queue.length }); - const storageData = await new Promise(resolve => { - chrome.storage.local.get('githubCache', resolve); - }); + const storageData = await storageGet('githubCache'); log('Storage Status:', { hasStoredData: !!storageData.githubCache, storedCacheKey: storageData.githubCache?.cacheKey, @@ -952,13 +952,8 @@ ${userReason}`; const hasCommitsInRange = showCommits && item._allCommits && item._allCommits.length > 0; if (!hasCommitsInRange) { - - continue; //skip these prs - created outside daterange with no commits - } else { - + continue; } - } else { - } const prAction = isNewPR ? 'Made PR' : 'Existing PR'; if (isDraft) { @@ -1105,7 +1100,7 @@ ${userReason}`; }, 1000); } function handleRefresh() { - hasInjectedContent = false; // Reset the flag before refresh + hasInjectedContent = false; allIncluded(); } } @@ -1113,14 +1108,10 @@ ${userReason}`; async function forceGithubDataRefresh() { let showCommits = false; - await new Promise(resolve => { - chrome.storage.local.get('showCommits', (result) => { - if (result.showCommits !== undefined) { - showCommits = result.showCommits; - } - resolve(); - }); - }); + const result = await storageGet('showCommits'); + if (result.showCommits !== undefined) { + showCommits = result.showCommits; + } if (typeof githubCache !== 'undefined') { githubCache.data = null; @@ -1131,11 +1122,8 @@ async function forceGithubDataRefresh() { githubCache.queue = []; } - await new Promise(resolve => { - chrome.storage.local.remove('githubCache', resolve); - }); - - chrome.storage.local.set({ showCommits: showCommits }); + await storageRemove('githubCache'); + await storageSet({ showCommits: showCommits }); hasInjectedContent = false; @@ -1147,8 +1135,10 @@ async function forceGithubDataRefresh() { if (window.location.protocol.startsWith('http')) { allIncluded('email'); - $('button>span:contains(New conversation)').parent('button').click(() => { - allIncluded(); + document.querySelectorAll('button').forEach(button => { + if (button.textContent.includes('New conversation')) { + button.addEventListener('click', () => allIncluded()); + } }); } @@ -1156,7 +1146,7 @@ window.generateScrumReport = function () { allIncluded('popup'); } -chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { +runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'forceRefresh') { forceGithubDataRefresh() .then(result => sendResponse(result)).catch(err => { From ea6d19d3772260ffb138824d52e0e0ae16b6c58f Mon Sep 17 00:00:00 2001 From: Saksham Sirohi Date: Sat, 5 Jul 2025 21:01:20 +0530 Subject: [PATCH 2/2] some other changes --- src/manifest.json | 4 +- src/scripts/background.js | 0 src/scripts/browser-polyfill.js | 2 +- src/scripts/main.js | 380 ++++++++++++++++---------------- src/scripts/popup.js | 243 ++++++++++---------- src/scripts/scrumHelper.js | 214 +++++++++--------- 6 files changed, 414 insertions(+), 429 deletions(-) delete mode 100644 src/scripts/background.js diff --git a/src/manifest.json b/src/manifest.json index abb4556..5565687 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -20,13 +20,13 @@ "content_scripts": [ { "matches": [ - "*://groups.google.com/forum/*", + "*://groups.google.com/forum/*", "*://groups.google.com/g/*", "*://groups.google.com/u/*/g/*", "*://mail.google.com/*", "*://outlook.live.com/*", "*://outlook.office.com/*", - "*://mail.yahoo.com/*" + "*://mail.yahoo.com/*" ], "js": [ "scripts/browser-polyfill.js", diff --git a/src/scripts/background.js b/src/scripts/background.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/scripts/browser-polyfill.js b/src/scripts/browser-polyfill.js index 1eb3307..5bb0652 100644 --- a/src/scripts/browser-polyfill.js +++ b/src/scripts/browser-polyfill.js @@ -4,4 +4,4 @@ if (typeof browser === "undefined") { if (typeof chrome !== "undefined") { var browser = chrome; } -} \ No newline at end of file +} diff --git a/src/scripts/main.js b/src/scripts/main.js index ab5c928..2c58f1f 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -12,239 +12,239 @@ let userReasonElement = document.getElementById('userReason'); let showCommitsElement = document.getElementById('showCommits'); function handleBodyOnLoad() { - browser.storage.local.get( - [ - 'githubUsername', - 'projectName', - 'enableToggle', - 'startingDate', - 'endingDate', - 'showOpenLabel', - 'userReason', - 'lastWeekContribution', - 'yesterdayContribution', - 'cacheInput', - 'githubToken', - 'showCommits', - ], - (items) => { - if (items.githubUsername) { - githubUsernameElement.value = items.githubUsername; - } - if (items.githubToken) { - githubTokenElement.value = items.githubToken; - } - if (items.projectName) { - projectNameElement.value = items.projectName; - } - if (items.cacheInput) { - cacheInputElement.value = items.cacheInput; - } - if (items.enableToggle) { - enableToggleElement.checked = items.enableToggle; - } else if (items.enableToggle !== false) { - enableToggleElement.checked = true; - handleEnableChange(); - } - if (items.endingDate) { - endingDateElement.value = items.endingDate; - } - if (items.startingDate) { - startingDateElement.value = items.startingDate; - } - if (items.showOpenLabel) { - showOpenLabelElement.checked = items.showOpenLabel; - } else if (items.showOpenLabel !== false) { - showOpenLabelElement.checked = true; - handleOpenLabelChange(); - } - if (items.userReason) { - userReasonElement.value = items.userReason; - } - if (items.lastWeekContribution) { - lastWeekContributionElement.checked = items.lastWeekContribution; - handleLastWeekContributionChange(); - } - else if (items.lastWeekContribution !== false) { - lastWeekContributionElement.checked = true; - handleLastWeekContributionChange(); - } - if (items.yesterdayContribution) { - yesterdayContributionElement.checked = items.yesterdayContribution; - handleYesterdayContributionChange(); - } - else if (items.yesterdayContribution !== false) { - yesterdayContributionElement.checked = true; - handleYesterdayContributionChange(); - } - if (items.showCommits) { - showCommitsElement.checked = items.showCommits; - } else { - showCommitsElement.checked = false; - handleShowCommitsChange(); - } - }, - ); + browser.storage.local.get( + [ + 'githubUsername', + 'projectName', + 'enableToggle', + 'startingDate', + 'endingDate', + 'showOpenLabel', + 'userReason', + 'lastWeekContribution', + 'yesterdayContribution', + 'cacheInput', + 'githubToken', + 'showCommits', + ], + (items) => { + if (items.githubUsername) { + githubUsernameElement.value = items.githubUsername; + } + if (items.githubToken) { + githubTokenElement.value = items.githubToken; + } + if (items.projectName) { + projectNameElement.value = items.projectName; + } + if (items.cacheInput) { + cacheInputElement.value = items.cacheInput; + } + if (items.enableToggle) { + enableToggleElement.checked = items.enableToggle; + } else if (items.enableToggle !== false) { + enableToggleElement.checked = true; + handleEnableChange(); + } + if (items.endingDate) { + endingDateElement.value = items.endingDate; + } + if (items.startingDate) { + startingDateElement.value = items.startingDate; + } + if (items.showOpenLabel) { + showOpenLabelElement.checked = items.showOpenLabel; + } else if (items.showOpenLabel !== false) { + showOpenLabelElement.checked = true; + handleOpenLabelChange(); + } + if (items.userReason) { + userReasonElement.value = items.userReason; + } + if (items.lastWeekContribution) { + lastWeekContributionElement.checked = items.lastWeekContribution; + handleLastWeekContributionChange(); + } + else if (items.lastWeekContribution !== false) { + lastWeekContributionElement.checked = true; + handleLastWeekContributionChange(); + } + if (items.yesterdayContribution) { + yesterdayContributionElement.checked = items.yesterdayContribution; + handleYesterdayContributionChange(); + } + else if (items.yesterdayContribution !== false) { + yesterdayContributionElement.checked = true; + handleYesterdayContributionChange(); + } + if (items.showCommits) { + showCommitsElement.checked = items.showCommits; + } else { + showCommitsElement.checked = false; + handleShowCommitsChange(); + } + }, + ); } document.getElementById('refreshCache').addEventListener('click', async (e) => { - const button = e.currentTarget; - button.classList.add('loading'); - button.disabled = true; + const button = e.currentTarget; + button.classList.add('loading'); + button.disabled = true; - try { - const tabs = await browser.tabs.query({ active: true, currentWindow: true }); - await browser.tabs.sendMessage(tabs[0].id, { - action: 'forceRefresh', - timestamp: Date.now() - }); + try { + const tabs = await browser.tabs.query({ active: true, currentWindow: true }); + await browser.tabs.sendMessage(tabs[0].id, { + action: 'forceRefresh', + timestamp: Date.now() + }); - browser.tabs.reload(tabs[0].id); + browser.tabs.reload(tabs[0].id); - Materialize.toast({ html: 'Data refreshed successfully!', classes: 'green' }); - } catch (err) { - console.log('Refresh successful',); - } finally { - setTimeout(() => { - button.classList.remove('loading'); - button.disabled = false; - }, 500); - } + Materialize.toast({ html: 'Data refreshed successfully!', classes: 'green' }); + } catch (err) { + console.log('Refresh successful',); + } finally { + setTimeout(() => { + button.classList.remove('loading'); + button.disabled = false; + }, 500); + } }); function handleEnableChange() { - let value = enableToggleElement.checked; - browser.storage.local.set({ enableToggle: value }); + let value = enableToggleElement.checked; + browser.storage.local.set({ enableToggle: value }); } function handleStartingDateChange() { - let value = startingDateElement.value; - browser.storage.local.set({ startingDate: value }); + let value = startingDateElement.value; + browser.storage.local.set({ startingDate: value }); } function handleEndingDateChange() { - let value = endingDateElement.value; - browser.storage.local.set({ endingDate: value }); + let value = endingDateElement.value; + browser.storage.local.set({ endingDate: value }); } function handleLastWeekContributionChange() { - let value = lastWeekContributionElement.checked; - let labelElement = document.querySelector("label[for='lastWeekContribution']"); - if (value) { - startingDateElement.readOnly = true; - endingDateElement.readOnly = true; - endingDateElement.value = getToday(); - startingDateElement.value = getLastWeek(); - handleEndingDateChange(); - handleStartingDateChange(); - labelElement.classList.add("selectedLabel"); - labelElement.classList.remove("unselectedLabel"); - } else { - startingDateElement.readOnly = false; - endingDateElement.readOnly = false; - labelElement.classList.add("unselectedLabel"); - labelElement.classList.remove("selectedLabel"); - } + let value = lastWeekContributionElement.checked; + let labelElement = document.querySelector("label[for='lastWeekContribution']"); + if (value) { + startingDateElement.readOnly = true; + endingDateElement.readOnly = true; + endingDateElement.value = getToday(); + startingDateElement.value = getLastWeek(); + handleEndingDateChange(); + handleStartingDateChange(); + labelElement.classList.add("selectedLabel"); + labelElement.classList.remove("unselectedLabel"); + } else { + startingDateElement.readOnly = false; + endingDateElement.readOnly = false; + labelElement.classList.add("unselectedLabel"); + labelElement.classList.remove("selectedLabel"); + } - browser.storage.local.set({ lastWeekContribution: value }); + browser.storage.local.set({ lastWeekContribution: value }); } function handleYesterdayContributionChange() { - let value = yesterdayContributionElement.checked; - let labelElement = document.querySelector("label[for='yesterdayContribution']"); + let value = yesterdayContributionElement.checked; + let labelElement = document.querySelector("label[for='yesterdayContribution']"); - if (value) { - startingDateElement.readOnly = true; - endingDateElement.readOnly = true; - endingDateElement.value = getToday(); - startingDateElement.value = getYesterday(); - handleEndingDateChange(); - handleStartingDateChange(); - labelElement.classList.add("selectedLabel"); - labelElement.classList.remove("unselectedLabel"); - } else { - startingDateElement.readOnly = false; - endingDateElement.readOnly = false; - labelElement.classList.add("unselectedLabel"); - labelElement.classList.remove("selectedLabel"); - } - browser.storage.local.set({ yesterdayContribution: value }); + if (value) { + startingDateElement.readOnly = true; + endingDateElement.readOnly = true; + endingDateElement.value = getToday(); + startingDateElement.value = getYesterday(); + handleEndingDateChange(); + handleStartingDateChange(); + labelElement.classList.add("selectedLabel"); + labelElement.classList.remove("unselectedLabel"); + } else { + startingDateElement.readOnly = false; + endingDateElement.readOnly = false; + labelElement.classList.add("unselectedLabel"); + labelElement.classList.remove("selectedLabel"); + } + browser.storage.local.set({ yesterdayContribution: value }); } function getLastWeek() { - let today = new Date(); - let lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); - let lastWeekMonth = lastWeek.getMonth() + 1; - let lastWeekDay = lastWeek.getDate(); - let lastWeekYear = lastWeek.getFullYear(); - let lastWeekDisplayPadded = - ('0000' + lastWeekYear.toString()).slice(-4) + - '-' + - ('00' + lastWeekMonth.toString()).slice(-2) + - '-' + - ('00' + lastWeekDay.toString()).slice(-2); - return lastWeekDisplayPadded; + let today = new Date(); + let lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); + let lastWeekMonth = lastWeek.getMonth() + 1; + let lastWeekDay = lastWeek.getDate(); + let lastWeekYear = lastWeek.getFullYear(); + let lastWeekDisplayPadded = + ('0000' + lastWeekYear.toString()).slice(-4) + + '-' + + ('00' + lastWeekMonth.toString()).slice(-2) + + '-' + + ('00' + lastWeekDay.toString()).slice(-2); + return lastWeekDisplayPadded; } function getYesterday() { - let today = new Date(); - let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); - let yesterdayMonth = yesterday.getMonth() + 1; - let yesterdayWeekDay = yesterday.getDate(); - let yesterdayYear = yesterday.getFullYear(); - let yesterdayPadded = - ('0000' + yesterdayYear.toString()).slice(-4) + - '-' + - ('00' + yesterdayMonth.toString()).slice(-2) + - '-' + - ('00' + yesterdayWeekDay.toString()).slice(-2); - return yesterdayPadded; + let today = new Date(); + let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); + let yesterdayMonth = yesterday.getMonth() + 1; + let yesterdayWeekDay = yesterday.getDate(); + let yesterdayYear = yesterday.getFullYear(); + let yesterdayPadded = + ('0000' + yesterdayYear.toString()).slice(-4) + + '-' + + ('00' + yesterdayMonth.toString()).slice(-2) + + '-' + + ('00' + yesterdayWeekDay.toString()).slice(-2); + return yesterdayPadded; } function getToday() { - let today = new Date(); - let Week = new Date(today.getFullYear(), today.getMonth(), today.getDate()); - let WeekMonth = Week.getMonth() + 1; - let WeekDay = Week.getDate(); - let WeekYear = Week.getFullYear(); - let WeekDisplayPadded = - ('0000' + WeekYear.toString()).slice(-4) + - '-' + - ('00' + WeekMonth.toString()).slice(-2) + - '-' + - ('00' + WeekDay.toString()).slice(-2); - return WeekDisplayPadded; + let today = new Date(); + let Week = new Date(today.getFullYear(), today.getMonth(), today.getDate()); + let WeekMonth = Week.getMonth() + 1; + let WeekDay = Week.getDate(); + let WeekYear = Week.getFullYear(); + let WeekDisplayPadded = + ('0000' + WeekYear.toString()).slice(-4) + + '-' + + ('00' + WeekMonth.toString()).slice(-2) + + '-' + + ('00' + WeekDay.toString()).slice(-2); + return WeekDisplayPadded; } function handleGithubUsernameChange() { - let value = githubUsernameElement.value; - browser.storage.local.set({ githubUsername: value }); + let value = githubUsernameElement.value; + browser.storage.local.set({ githubUsername: value }); } function handleGithubTokenChange() { - let value = githubTokenElement.value; - browser.storage.local.set({ githubToken: value }); + let value = githubTokenElement.value; + browser.storage.local.set({ githubToken: value }); } function handleProjectNameChange() { - let value = projectNameElement.value; - browser.storage.local.set({ projectName: value }); + let value = projectNameElement.value; + browser.storage.local.set({ projectName: value }); } function handleCacheInputChange() { - let value = cacheInputElement.value; - browser.storage.local.set({ cacheInput: value }); + let value = cacheInputElement.value; + browser.storage.local.set({ cacheInput: value }); } function handleOpenLabelChange() { - let value = showOpenLabelElement.checked; - let labelElement = document.querySelector("label[for='showOpenLabel']"); + let value = showOpenLabelElement.checked; + let labelElement = document.querySelector("label[for='showOpenLabel']"); - if (value) { - labelElement.classList.add("selectedLabel"); - labelElement.classList.remove("unselectedLabel"); - } else { - labelElement.classList.add("unselectedLabel"); - labelElement.classList.remove("selectedLabel"); - } + if (value) { + labelElement.classList.add("selectedLabel"); + labelElement.classList.remove("unselectedLabel"); + } else { + labelElement.classList.add("unselectedLabel"); + labelElement.classList.remove("selectedLabel"); + } - browser.storage.local.set({ showOpenLabel: value }); + browser.storage.local.set({ showOpenLabel: value }); } function handleUserReasonChange() { - let value = userReasonElement.value; - browser.storage.local.set({ userReason: value }); + let value = userReasonElement.value; + browser.storage.local.set({ userReason: value }); } function handleShowCommitsChange() { diff --git a/src/scripts/popup.js b/src/scripts/popup.js index 90940a7..4b9b335 100644 --- a/src/scripts/popup.js +++ b/src/scripts/popup.js @@ -46,20 +46,6 @@ document.addEventListener('DOMContentLoaded', function () { // Cross-browser storage detection const storage = typeof browser !== 'undefined' ? browser.storage : chrome.storage; - // Firefox date input fix - const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; - if (isFirefox) { - document.querySelectorAll('input[type="date"]').forEach(input => { - if (!input.value) { - input.type = 'text'; - input.placeholder = 'YYYY-MM-DD'; - } - input.addEventListener('blur', () => { - if (input.value) input.type = 'date'; - }); - }); - } - // Dark mode setup const darkModeToggle = document.querySelector('img[alt="Night Mode"]'); const settingsIcon = document.getElementById('settingsIcon'); @@ -523,141 +509,140 @@ document.addEventListener('DOMContentLoaded', function () { }); } - // Tooltip bubble - document.querySelectorAll('.tooltip-container').forEach(container => { - const bubble = container.querySelector('.tooltip-bubble'); - if (!bubble) return; +// Tooltip bubble +document.querySelectorAll('.tooltip-container').forEach(container => { + const bubble = container.querySelector('.tooltip-bubble'); + if (!bubble) return; - function positionTooltip() { - const icon = container.querySelector('.question-icon') || container; - const rect = icon.getBoundingClientRect(); - const bubbleRect = bubble.getBoundingClientRect(); - const padding = 8; + function positionTooltip() { + const icon = container.querySelector('.question-icon') || container; + const rect = icon.getBoundingClientRect(); + const bubbleRect = bubble.getBoundingClientRect(); + const padding = 8; - let top = rect.top + window.scrollY; - let left = rect.right + padding + window.scrollX; + let top = rect.top + window.scrollY; + let left = rect.right + padding + window.scrollX; - if (left + bubbleRect.width > window.innerWidth - 10) { - left = rect.left - bubbleRect.width - padding + window.scrollX; - } - if (left < 8) left = 8; - if (top + bubbleRect.height > window.innerHeight - 10) { - top = rect.top - bubbleRect.height - padding + window.scrollY; - } - if (top < 8) top = 8; - - bubble.style.left = left + 'px'; - bubble.style.top = top + 'px'; + if (left + bubbleRect.width > window.innerWidth - 10) { + left = rect.left - bubbleRect.width - padding + window.scrollX; + } + if (left < 8) left = 8; + if (top + bubbleRect.height > window.innerHeight - 10) { + top = rect.top - bubbleRect.height - padding + window.scrollY; } + if (top < 8) top = 8; - container.addEventListener('mouseenter', positionTooltip); - container.addEventListener('focusin', positionTooltip); - container.addEventListener('mousemove', positionTooltip); - container.addEventListener('mouseleave', () => { - bubble.style.left = ''; - bubble.style.top = ''; - }); - container.addEventListener('focusout', () => { - bubble.style.left = ''; - bubble.style.top = ''; - }); + bubble.style.left = left + 'px'; + bubble.style.top = top + 'px'; + } + + container.addEventListener('mouseenter', positionTooltip); + container.addEventListener('focusin', positionTooltip); + container.addEventListener('mousemove', positionTooltip); + container.addEventListener('mouseleave', () => { + bubble.style.left = ''; + bubble.style.top = ''; }); + container.addEventListener('focusout', () => { + bubble.style.left = ''; + bubble.style.top = ''; + }); +}); - // Radio button click handlers with toggle functionality - document.querySelectorAll('input[name="timeframe"]').forEach(radio => { - radio.addEventListener('click', function () { - if (this.dataset.wasChecked === 'true') { - this.checked = false; - this.dataset.wasChecked = 'false'; +// Radio button click handlers with toggle functionality +document.querySelectorAll('input[name="timeframe"]').forEach(radio => { + radio.addEventListener('click', function () { + if (this.dataset.wasChecked === 'true') { + this.checked = false; + this.dataset.wasChecked = 'false'; - const startDateInput = document.getElementById('startingDate'); - const endDateInput = document.getElementById('endingDate'); - startDateInput.readOnly = false; - endDateInput.readOnly = false; + const startDateInput = document.getElementById('startingDate'); + const endDateInput = document.getElementById('endingDate'); + startDateInput.readOnly = false; + endDateInput.readOnly = false; - storage.local.set({ - lastWeekContribution: false, - yesterdayContribution: false, - selectedTimeframe: null - }); - } else { - document.querySelectorAll('input[name="timeframe"]').forEach(r => { - r.dataset.wasChecked = 'false'; - }); - this.dataset.wasChecked = 'true'; - toggleRadio(this); - } - }); + storage.local.set({ + lastWeekContribution: false, + yesterdayContribution: false, + selectedTimeframe: null + }); + } else { + document.querySelectorAll('input[name="timeframe"]').forEach(r => { + r.dataset.wasChecked = 'false'; + }); + this.dataset.wasChecked = 'true'; + toggleRadio(this); + } }); +}); - // refresh cache button - document.getElementById('refreshCache').addEventListener('click', async function () { - const button = this; - const originalText = button.innerHTML; +// refresh cache button +document.getElementById('refreshCache').addEventListener('click', async function () { + const button = this; + const originalText = button.innerHTML; - button.classList.add('loading'); - button.innerHTML = 'Refreshing...'; - button.disabled = true; + button.classList.add('loading'); + button.innerHTML = 'Refreshing...'; + button.disabled = true; - try { - // Clear local cache - await forceGithubDataRefresh(); + try { + // Clear local cache + await forceGithubDataRefresh(); - // Clear the scrum report - const scrumReport = document.getElementById('scrumReport'); - if (scrumReport) { - scrumReport.innerHTML = '

Cache cleared successfully. Click "Generate Report" to fetch fresh data.

'; - } + // Clear the scrum report + const scrumReport = document.getElementById('scrumReport'); + if (scrumReport) { + scrumReport.innerHTML = '

Cache cleared successfully. Click "Generate Report" to fetch fresh data.

'; + } - button.innerHTML = 'Cache Cleared!'; - button.classList.remove('loading'); + button.innerHTML = 'Cache Cleared!'; + button.classList.remove('loading'); - setTimeout(() => { - button.innerHTML = originalText; - button.disabled = false; - }, 2000); + setTimeout(() => { + button.innerHTML = originalText; + button.disabled = false; + }, 2000); - } catch (error) { - console.error('Cache clear failed:', error); - button.innerHTML = 'Failed to clear cache'; - button.classList.remove('loading'); + } catch (error) { + console.error('Cache clear failed:', error); + button.innerHTML = 'Failed to clear cache'; + button.classList.remove('loading'); - setTimeout(() => { - button.innerHTML = originalText; - button.disabled = false; - }, 3000); - } - }); + setTimeout(() => { + button.innerHTML = originalText; + button.disabled = false; + }, 3000); + } +}); - function toggleRadio(radio) { - const startDateInput = document.getElementById('startingDate'); - const endDateInput = document.getElementById('endingDate'); +function toggleRadio(radio) { + const startDateInput = document.getElementById('startingDate'); + const endDateInput = document.getElementById('endingDate'); - console.log('Toggling radio:', radio.id); + console.log('Toggling radio:', radio.id); - if (radio.id === 'lastWeekContribution') { - startDateInput.value = getLastWeek(); - endDateInput.value = getToday(); - } else if (radio.id === 'yesterdayContribution') { - startDateInput.value = getYesterday(); - endDateInput.value = getToday(); - } + if (radio.id === 'lastWeekContribution') { + startDateInput.value = getLastWeek(); + endDateInput.value = getToday(); + } else if (radio.id === 'yesterdayContribution') { + startDateInput.value = getYesterday(); + endDateInput.value = getToday(); + } - startDateInput.readOnly = endDateInput.readOnly = true; - - storage.local.set({ - startingDate: startDateInput.value, - endingDate: endDateInput.value, - lastWeekContribution: radio.id === 'lastWeekContribution', - yesterdayContribution: radio.id === 'yesterdayContribution', - selectedTimeframe: radio.id, - githubCache: null // Clear cache to force new fetch - }, () => { - console.log('State saved, dates:', { - start: startDateInput.value, - end: endDateInput.value, - isLastWeek: radio.id === 'lastWeekContribution' - }); + startDateInput.readOnly = endDateInput.readOnly = true; + + storage.local.set({ + startingDate: startDateInput.value, + endingDate: endDateInput.value, + lastWeekContribution: radio.id === 'lastWeekContribution', + yesterdayContribution: radio.id === 'yesterdayContribution', + selectedTimeframe: radio.id, + githubCache: null // Clear cache to force new fetch + }, () => { + console.log('State saved, dates:', { + start: startDateInput.value, + end: endDateInput.value, + isLastWeek: radio.id === 'lastWeekContribution' }); - } -}); + }); +}}); diff --git a/src/scripts/scrumHelper.js b/src/scripts/scrumHelper.js index 4aecc01..57caa6e 100644 --- a/src/scripts/scrumHelper.js +++ b/src/scripts/scrumHelper.js @@ -1,7 +1,7 @@ const DEBUG = true; // Unified browser storage API using polyfilled browser object -const storage = browser.storage; -const runtime = browser.runtime; +const {storage} = browser; +const runtime = {browser}; // Unified storage functions function storageGet(keys) { @@ -98,99 +98,99 @@ function allIncluded(outputTarget = 'email') { ]); log("Storage items received:", items); - if (outputTarget === 'popup') { - const usernameFromDOM = document.getElementById('githubUsername')?.value; - const projectFromDOM = document.getElementById('projectName')?.value; - const reasonFromDOM = document.getElementById('userReason')?.value; - const tokenFromDOM = document.getElementById('githubToken')?.value; - - items.githubUsername = usernameFromDOM || items.githubUsername; - items.projectName = projectFromDOM || items.projectName; - items.userReason = reasonFromDOM || items.userReason; - items.githubToken = tokenFromDOM || items.githubToken; - - await storageSet({ - githubUsername: items.githubUsername, - projectName: items.projectName, - userReason: items.userReason, - githubToken: items.githubToken - }); - } + if (outputTarget === 'popup') { + const usernameFromDOM = document.getElementById('githubUsername')?.value; + const projectFromDOM = document.getElementById('projectName')?.value; + const reasonFromDOM = document.getElementById('userReason')?.value; + const tokenFromDOM = document.getElementById('githubToken')?.value; + + items.githubUsername = usernameFromDOM || items.githubUsername; + items.projectName = projectFromDOM || items.projectName; + items.userReason = reasonFromDOM || items.userReason; + items.githubToken = tokenFromDOM || items.githubToken; + + await storageSet({ + githubUsername: items.githubUsername, + projectName: items.projectName, + userReason: items.userReason, + githubToken: items.githubToken + }); + } - githubUsername = items.githubUsername; - projectName = items.projectName; - userReason = items.userReason || 'No Blocker at the moment'; - githubToken = items.githubToken; - lastWeekContribution = items.lastWeekContribution; - yesterdayContribution = items.yesterdayContribution; + githubUsername = items.githubUsername; + projectName = items.projectName; + userReason = items.userReason || 'No Blocker at the moment'; + githubToken = items.githubToken; + lastWeekContribution = items.lastWeekContribution; + yesterdayContribution = items.yesterdayContribution; - if (!items.enableToggle) { - enableToggle = items.enableToggle; - } + if (!items.enableToggle) { + enableToggle = items.enableToggle; + } - if (items.lastWeekContribution) { - handleLastWeekContributionChange(); - } else if (items.yesterdayContribution) { - handleYesterdayContributionChange(); - } else if (items.startingDate && items.endingDate) { - startingDate = items.startingDate; - endingDate = items.endingDate; - } else { - handleLastWeekContributionChange(); - if (outputTarget === 'popup') { - await storageSet({ lastWeekContribution: true, yesterdayContribution: false }); - } - } - if (githubUsername) { - log("About to fetch GitHub data for:", githubUsername); - fetchGithubData(); - } else { - if (outputTarget === 'popup') { - log("No username found - popup context"); - const scrumReport = document.getElementById('scrumReport'); - const generateBtn = document.getElementById('generateReport'); - if (scrumReport) { - scrumReport.innerHTML = '
Please enter your GitHub username to generate a report.
'; + if (items.lastWeekContribution) { + handleLastWeekContributionChange(); + } else if (items.yesterdayContribution) { + handleYesterdayContributionChange(); + } else if (items.startingDate && items.endingDate) { + startingDate = items.startingDate; + endingDate = items.endingDate; + } else { + handleLastWeekContributionChange(); + if (outputTarget === 'popup') { + await storageSet({ lastWeekContribution: true, yesterdayContribution: false }); + } } - if (generateBtn) { - generateBtn.innerHTML = ' Generate Report'; - generateBtn.disabled = false; + if (githubUsername) { + log("About to fetch GitHub data for:", githubUsername); + fetchGithubData(); + } else { + if (outputTarget === 'popup') { + log("No username found - popup context"); + const scrumReport = document.getElementById('scrumReport'); + const generateBtn = document.getElementById('generateReport'); + if (scrumReport) { + scrumReport.innerHTML = '
Please enter your GitHub username to generate a report.
'; + } + if (generateBtn) { + generateBtn.innerHTML = ' Generate Report'; + generateBtn.disabled = false; + } + scrumGenerationInProgress = false; + } else { + logError('No GitHub username found in storage'); + scrumGenerationInProgress = false; + } + return; + } + if (items.cacheInput) { + cacheInput = items.cacheInput; + } + if (items.showCommits !== undefined) { + showCommits = items.showCommits; + } else { + showCommits = false; } - scrumGenerationInProgress = false; - } else { - logError('No GitHub username found in storage'); - scrumGenerationInProgress = false; - } - return; - } - if (items.cacheInput) { - cacheInput = items.cacheInput; - } - if (items.showCommits !== undefined) { - showCommits = items.showCommits; - } else { - showCommits = false; - } - if (!items.showOpenLabel) { - showOpenLabel = false; - pr_open_button = ''; - issue_opened_button = ''; - pr_merged_button = ''; - issue_closed_button = ''; - } - if (items.githubCache) { - githubCache.data = items.githubCache.data; - githubCache.cacheKey = items.githubCache.cacheKey; - githubCache.timestamp = items.githubCache.timestamp; - log('Restored cache from storage'); - } + if (!items.showOpenLabel) { + showOpenLabel = false; + pr_open_button = ''; + issue_opened_button = ''; + pr_merged_button = ''; + issue_closed_button = ''; + } + if (items.githubCache) { + githubCache.data = items.githubCache.data; + githubCache.cacheKey = items.githubCache.cacheKey; + githubCache.timestamp = items.githubCache.timestamp; + log('Restored cache from storage'); + } - if (items.orgName) { - orgName = items.orgName; - } - } - getStorageData(); + if (items.orgName) { + orgName = items.orgName; + } + } + getStorageData(); function handleLastWeekContributionChange() { endingDate = getToday(); @@ -504,23 +504,23 @@ function allIncluded(outputTarget = 'email') { const owner = repoParts[repoParts.length - 2]; const repo = repoParts[repoParts.length - 1]; return ` - pr${idx}: repository(owner: "${owner}", name: "${repo}") { - pullRequest(number: ${pr.number}) { - commits(first: 100) { - nodes { - commit { - messageHeadline - committedDate - url - author { - name - user { login } - } - } - } - } - } - }`; + pr${idx}: repository(owner: "${owner}", name: "${repo}") { + pullRequest(number: ${pr.number}) { + commits(first: 100) { + nodes { + commit { + messageHeadline + committedDate + url + author { + name + user { login } + } + } + } + } + } + }`; }).join('\n'); const query = `query { ${queries} }`; log('GraphQL query for commits:', query); @@ -1100,7 +1100,7 @@ ${userReason}`; }, 1000); } function handleRefresh() { - hasInjectedContent = false; + hasInjectedContent = false; // Reset the flag before refresh allIncluded(); } } @@ -1136,7 +1136,7 @@ async function forceGithubDataRefresh() { if (window.location.protocol.startsWith('http')) { allIncluded('email'); document.querySelectorAll('button').forEach(button => { - if (button.textContent.includes('New conversation')) { + if (button.textContent.includes() === 'New conversation' && button.closest('.conversation-toolbar')) { button.addEventListener('click', () => allIncluded()); } });