Separated Opportunitues from Applied using headers, Added Date Posted to jobs.
This commit is contained in:
@@ -324,6 +324,41 @@ async function notifyNewJob(job) {
|
||||
await sendNtfyNotification(job, companyName);
|
||||
}
|
||||
|
||||
// Opens a job's detail page briefly just to read its "Posted X ago" text,
|
||||
// then closes the tab. Only called for genuinely new jobs, not on every
|
||||
// 5-minute check, to avoid needlessly opening tabs for jobs we already know about.
|
||||
async function fetchPostedDate(url) {
|
||||
if (!url) return null;
|
||||
let tab;
|
||||
try {
|
||||
tab = await chrome.tabs.create({ url: url, active: false });
|
||||
await new Promise((resolve) => setTimeout(resolve, 3500));
|
||||
const postedDate = await new Promise((resolve) => {
|
||||
chrome.tabs.sendMessage(
|
||||
tab.id,
|
||||
{ action: 'extractPostedDate' },
|
||||
(response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
log(
|
||||
'Error extracting posted date:',
|
||||
chrome.runtime.lastError.message,
|
||||
);
|
||||
resolve(null);
|
||||
} else {
|
||||
resolve((response && response.postedDate) || null);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
return postedDate;
|
||||
} catch (err) {
|
||||
log('Error in fetchPostedDate:', err.message);
|
||||
return null;
|
||||
} finally {
|
||||
if (tab) chrome.tabs.remove(tab.id).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
let keepAliveInterval = null;
|
||||
|
||||
function startKeepAlive() {
|
||||
@@ -354,24 +389,61 @@ async function checkForNewJobs() {
|
||||
const allJobs = await fetchJobsViaContentScript();
|
||||
const sortedJobs = sortJobsByRecency(allJobs);
|
||||
|
||||
const result = await getStoredData(['notifiedJobIds']);
|
||||
const result = await getStoredData([
|
||||
'notifiedJobIds',
|
||||
'postedDates',
|
||||
'backfillDone',
|
||||
]);
|
||||
const notifiedJobIds = new Set(result.notifiedJobIds || []);
|
||||
const postedDates = result.postedDates || {};
|
||||
const backfillDone = result.backfillDone || false;
|
||||
|
||||
log('Previously notified jobs: ' + notifiedJobIds.size);
|
||||
sortedJobs.forEach((job) => {
|
||||
if (postedDates[job.id]) job.posted_ago = postedDates[job.id];
|
||||
});
|
||||
|
||||
const newJobs = sortedJobs.filter((job) => !notifiedJobIds.has(job.id));
|
||||
if (!backfillDone) {
|
||||
const toBackfill = sortedJobs.filter(
|
||||
(job) => job.kind === 'opportunity' && !postedDates[job.id],
|
||||
);
|
||||
log(
|
||||
'Backfilling posted dates for ' +
|
||||
toBackfill.length +
|
||||
' existing jobs...',
|
||||
);
|
||||
|
||||
for (const job of toBackfill) {
|
||||
const postedDate = await fetchPostedDate(job.url);
|
||||
if (postedDate) {
|
||||
job.posted_ago = postedDate;
|
||||
postedDates[job.id] = postedDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const newJobs = sortedJobs.filter(
|
||||
(job) => job.kind === 'opportunity' && !notifiedJobIds.has(job.id),
|
||||
);
|
||||
log('Found ' + newJobs.length + ' new jobs');
|
||||
|
||||
for (const job of newJobs) {
|
||||
const postedDate = await fetchPostedDate(job.url);
|
||||
if (postedDate) {
|
||||
job.posted_ago = postedDate;
|
||||
postedDates[job.id] = postedDate;
|
||||
}
|
||||
await notifyNewJob(job);
|
||||
notifiedJobIds.add(job.id);
|
||||
}
|
||||
|
||||
await setStoredData({
|
||||
notifiedJobIds: Array.from(notifiedJobIds),
|
||||
postedDates: postedDates,
|
||||
backfillDone: true,
|
||||
lastAndelaJobs: sortedJobs,
|
||||
lastAndelaUpdated: new Date().toISOString(),
|
||||
totalAndelaMatching: sortedJobs.length,
|
||||
totalAndelaMatching: sortedJobs.filter((j) => j.kind === 'opportunity')
|
||||
.length,
|
||||
});
|
||||
|
||||
log('Notifications stored successfully');
|
||||
|
||||
@@ -8,7 +8,12 @@ function isLoginPage() {
|
||||
var hasLoginForm = !!(emailInput && emailLabel);
|
||||
var isLoginUrl = window.location.pathname.indexOf('/login') === 0;
|
||||
|
||||
console.log('[Andela Content Script] Login check - hasForm:', hasLoginForm, 'isLoginUrl:', isLoginUrl);
|
||||
console.log(
|
||||
'[Andela Content Script] Login check - hasForm:',
|
||||
hasLoginForm,
|
||||
'isLoginUrl:',
|
||||
isLoginUrl,
|
||||
);
|
||||
return hasLoginForm || (isLoginUrl && !!emailInput);
|
||||
}
|
||||
|
||||
@@ -28,19 +33,23 @@ function enterEmailAndClickLogin(email) {
|
||||
emailInput.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
emailInput.dispatchEvent(new KeyboardEvent('keyup', { bubbles: true }));
|
||||
|
||||
console.log('[Andela Content Script] Email entered, looking for submit button...');
|
||||
console.log(
|
||||
'[Andela Content Script] Email entered, looking for submit button...',
|
||||
);
|
||||
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
var submitButton = document.querySelector('button[type="submit"]');
|
||||
|
||||
if (!submitButton) {
|
||||
var buttons = document.querySelectorAll('button');
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
var btnText = buttons[i].textContent.toLowerCase();
|
||||
if (btnText.indexOf('login') !== -1 ||
|
||||
if (
|
||||
btnText.indexOf('login') !== -1 ||
|
||||
btnText.indexOf('sign in') !== -1 ||
|
||||
btnText.indexOf('continue') !== -1 ||
|
||||
btnText.indexOf('submit') !== -1) {
|
||||
btnText.indexOf('submit') !== -1
|
||||
) {
|
||||
submitButton = buttons[i];
|
||||
break;
|
||||
}
|
||||
@@ -48,10 +57,15 @@ function enterEmailAndClickLogin(email) {
|
||||
}
|
||||
|
||||
if (submitButton) {
|
||||
console.log('[Andela Content Script] Clicking submit button:', submitButton.textContent);
|
||||
console.log(
|
||||
'[Andela Content Script] Clicking submit button:',
|
||||
submitButton.textContent,
|
||||
);
|
||||
submitButton.click();
|
||||
} else {
|
||||
console.log('[Andela Content Script] Submit button not found, trying form submit');
|
||||
console.log(
|
||||
'[Andela Content Script] Submit button not found, trying form submit',
|
||||
);
|
||||
var form = emailInput.closest('form');
|
||||
if (form) {
|
||||
if (form.requestSubmit) form.requestSubmit();
|
||||
@@ -67,17 +81,61 @@ function enterEmailAndClickLogin(email) {
|
||||
}
|
||||
}
|
||||
|
||||
// A section counts as "opportunities" if its heading contains this word —
|
||||
// matches "Open Full-Stack Engineer opportunities", "Open AI Engineer
|
||||
// opportunities", etc. Anything else (e.g. "Your applications") is
|
||||
// treated as already-applied.
|
||||
function isOpportunitySection(headingText) {
|
||||
return /opportunit/i.test(headingText || '');
|
||||
}
|
||||
|
||||
// Walks the page in DOM order and tags every "See more" button and every
|
||||
// job-posting link with the heading text of the section it falls under.
|
||||
function getPageSections() {
|
||||
var elements = document.querySelectorAll(
|
||||
'h3, button, a[href*="/job-postings/"]',
|
||||
);
|
||||
var currentHeading = '';
|
||||
var seeMoreButtons = []; // { button, heading }
|
||||
var jobLinks = []; // { link, heading }
|
||||
|
||||
elements.forEach(function (el) {
|
||||
if (el.tagName === 'H3') {
|
||||
currentHeading = el.textContent.trim();
|
||||
console.log(
|
||||
'[Andela Content Script] Section heading found:',
|
||||
currentHeading,
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (el.tagName === 'BUTTON') {
|
||||
var text = (el.textContent || '').trim().toLowerCase();
|
||||
if (text.indexOf('see') === 0 && text.indexOf('more') !== -1) {
|
||||
seeMoreButtons.push({ button: el, heading: currentHeading });
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (el.tagName === 'A') {
|
||||
jobLinks.push({ link: el, heading: currentHeading });
|
||||
}
|
||||
});
|
||||
|
||||
return { seeMoreButtons: seeMoreButtons, jobLinks: jobLinks };
|
||||
}
|
||||
|
||||
// Only expands "See more" under opportunity sections — leaves the
|
||||
// applied-jobs section collapsed as-is.
|
||||
function expandAllSeeMoreButtons(maxRounds) {
|
||||
maxRounds = maxRounds || 25;
|
||||
return new Promise(function(resolve) {
|
||||
return new Promise(function (resolve) {
|
||||
var rounds = 0;
|
||||
|
||||
function findSeeMoreButton() {
|
||||
var buttons = document.querySelectorAll('button');
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
var text = (buttons[i].textContent || '').trim().toLowerCase();
|
||||
if (text.indexOf('see') === 0 && text.indexOf('more') !== -1) {
|
||||
return buttons[i];
|
||||
var sections = getPageSections();
|
||||
for (var i = 0; i < sections.seeMoreButtons.length; i++) {
|
||||
var entry = sections.seeMoreButtons[i];
|
||||
if (isOpportunitySection(entry.heading)) {
|
||||
return entry.button;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -87,7 +145,11 @@ function expandAllSeeMoreButtons(maxRounds) {
|
||||
rounds++;
|
||||
var btn = findSeeMoreButton();
|
||||
if (!btn || rounds > maxRounds) {
|
||||
console.log('[Andela Content Script] Done expanding "See more" buttons after', rounds - 1, 'click(s)');
|
||||
console.log(
|
||||
'[Andela Content Script] Done expanding opportunity "See more" buttons after',
|
||||
rounds - 1,
|
||||
'click(s)',
|
||||
);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
@@ -105,11 +167,15 @@ function extractJobFromLink(link) {
|
||||
var idMatch = href.match(/\/job-postings\/(\d+)/);
|
||||
var id = idMatch ? idMatch[1] : href;
|
||||
|
||||
var card = link.closest('div.rounded-lg.border.border-neutral-200.bg-white') || link.parentElement;
|
||||
var card =
|
||||
link.closest('div.rounded-lg.border.border-neutral-200.bg-white') ||
|
||||
link.parentElement;
|
||||
|
||||
var title = '';
|
||||
var company = '';
|
||||
var titleEl = card ? card.querySelector('.text-primary-900.font-semibold') : null;
|
||||
var titleEl = card
|
||||
? card.querySelector('.text-primary-900.font-semibold')
|
||||
: null;
|
||||
|
||||
if (titleEl) {
|
||||
var clone = titleEl.cloneNode(true);
|
||||
@@ -125,8 +191,12 @@ function extractJobFromLink(link) {
|
||||
var startInfo = paragraphs[0] ? paragraphs[0].textContent.trim() : '';
|
||||
var locationInfo = paragraphs[1] ? paragraphs[1].textContent.trim() : '';
|
||||
|
||||
var skillEls = card ? card.querySelectorAll('.flex.flex-wrap.gap-2 span') : [];
|
||||
var skills = Array.prototype.map.call(skillEls, function(s) { return s.textContent.trim(); });
|
||||
var skillEls = card
|
||||
? card.querySelectorAll('.flex.flex-wrap.gap-2 span')
|
||||
: [];
|
||||
var skills = Array.prototype.map.call(skillEls, function (s) {
|
||||
return s.textContent.trim();
|
||||
});
|
||||
|
||||
var url = href;
|
||||
if (url && url.indexOf('http') !== 0) {
|
||||
@@ -140,7 +210,7 @@ function extractJobFromLink(link) {
|
||||
posted_date: startInfo || '',
|
||||
location: locationInfo || '',
|
||||
skills: skills,
|
||||
url: url
|
||||
url: url,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -148,33 +218,50 @@ function extractJobsFromPage() {
|
||||
console.log('[Andela Content Script] Extracting jobs...');
|
||||
var jobs = [];
|
||||
var seen = {};
|
||||
var links = document.querySelectorAll('a[href*="/job-postings/"]');
|
||||
console.log('[Andela Content Script] Found ' + links.length + ' job-posting links');
|
||||
var jobLinks = getPageSections().jobLinks;
|
||||
console.log(
|
||||
'[Andela Content Script] Found ' + jobLinks.length + ' job-posting links',
|
||||
);
|
||||
|
||||
links.forEach(function(link) {
|
||||
jobLinks.forEach(function (entry) {
|
||||
try {
|
||||
var job = extractJobFromLink(link);
|
||||
var job = extractJobFromLink(entry.link);
|
||||
if (!job.id || seen[job.id]) return;
|
||||
seen[job.id] = true;
|
||||
job.section = entry.heading;
|
||||
job.kind = isOpportunitySection(entry.heading)
|
||||
? 'opportunity'
|
||||
: 'applied';
|
||||
if (job.title) {
|
||||
jobs.push(job);
|
||||
console.log('[Andela Content Script] Extracted job:', job.title, '(' + job.id + ')');
|
||||
console.log(
|
||||
'[Andela Content Script] Extracted job:',
|
||||
job.title,
|
||||
'(' + job.id + ')',
|
||||
'-',
|
||||
job.kind,
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[Andela Content Script] Error extracting a job card:', err);
|
||||
console.error(
|
||||
'[Andela Content Script] Error extracting a job card:',
|
||||
err,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('[Andela Content Script] Extracted ' + jobs.length + ' jobs total');
|
||||
console.log(
|
||||
'[Andela Content Script] Extracted ' + jobs.length + ' jobs total',
|
||||
);
|
||||
return jobs;
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
||||
console.log('[Andela Content Script] Received message:', request);
|
||||
|
||||
if (request.action === 'extractJobs') {
|
||||
expandAllSeeMoreButtons().then(function() {
|
||||
setTimeout(function() {
|
||||
expandAllSeeMoreButtons().then(function () {
|
||||
setTimeout(function () {
|
||||
try {
|
||||
var jobs = extractJobsFromPage();
|
||||
sendResponse({ jobs: jobs });
|
||||
@@ -198,5 +285,15 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
||||
sendResponse({ success: success });
|
||||
}
|
||||
|
||||
if (request.action === 'extractPostedDate') {
|
||||
var el = document.querySelector('span.text-success-500');
|
||||
var postedText = el ? el.textContent.trim() : '';
|
||||
console.log(
|
||||
'[Andela Content Script] Extracted posted date text:',
|
||||
postedText,
|
||||
);
|
||||
sendResponse({ postedDate: postedText });
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Andela Job Notifier",
|
||||
"version": "2.0",
|
||||
"version": "2.1",
|
||||
"description": "Checks for new job opportunities on Andela with auto-login",
|
||||
"permissions": [
|
||||
"notifications",
|
||||
@@ -40,8 +40,10 @@
|
||||
"48": "icon48.png",
|
||||
"128": "icon128.png"
|
||||
},
|
||||
"web_accessible_resources": [{
|
||||
"web_accessible_resources": [
|
||||
{
|
||||
"resources": ["notify.wav"],
|
||||
"matches": ["<all_urls>"]
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<head>
|
||||
<title>Andela Job Notifier</title>
|
||||
<style>
|
||||
body {
|
||||
@@ -15,6 +15,19 @@
|
||||
.job-list {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.section-heading {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
margin: 12px 0 6px;
|
||||
}
|
||||
.section-heading-opportunities {
|
||||
color: #111111;
|
||||
}
|
||||
.section-heading-applied {
|
||||
color: #c0392b;
|
||||
}
|
||||
.job-item {
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
@@ -89,16 +102,16 @@
|
||||
background: #e0e0e0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Andela Job Notifier</h2>
|
||||
<div id="jobCount" class="job-count"></div>
|
||||
<div class="button-row">
|
||||
</head>
|
||||
<body>
|
||||
<h2>Andela Job Notifier</h2>
|
||||
<div id="jobCount" class="job-count"></div>
|
||||
<div class="button-row">
|
||||
<button id="checkNow" class="btn btn-primary">Check Now</button>
|
||||
<button id="openSettings" class="btn btn-secondary">Settings</button>
|
||||
</div>
|
||||
<div id="jobList" class="job-list"></div>
|
||||
<div id="status" class="status"></div>
|
||||
<script src="popup.js"></script>
|
||||
</body>
|
||||
</div>
|
||||
<div id="jobList" class="job-list"></div>
|
||||
<div id="status" class="status"></div>
|
||||
<script src="popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// popup.js
|
||||
|
||||
function sortJobsById(jobs) {
|
||||
return jobs.slice().sort(function(a, b) {
|
||||
return jobs.slice().sort(function (a, b) {
|
||||
return (parseInt(b.id, 10) || 0) - (parseInt(a.id, 10) || 0);
|
||||
});
|
||||
}
|
||||
@@ -11,66 +11,119 @@ function updateUI(data) {
|
||||
var lastAndelaUpdated = data.lastAndelaUpdated;
|
||||
var totalAndelaMatching = data.totalAndelaMatching || 0;
|
||||
|
||||
document.getElementById('jobCount').textContent = totalAndelaMatching + ' jobs found';
|
||||
document.getElementById('jobCount').textContent =
|
||||
totalAndelaMatching + ' open opportunities';
|
||||
|
||||
var jobList = document.getElementById('jobList');
|
||||
jobList.innerHTML = '';
|
||||
|
||||
if (lastAndelaJobs.length === 0) {
|
||||
jobList.innerHTML = '<div class="no-jobs">No jobs found yet. Click "Check Now" to scan for jobs.</div>';
|
||||
jobList.innerHTML =
|
||||
'<div class="no-jobs">No jobs found yet. Click "Check Now" to scan for jobs.</div>';
|
||||
} else {
|
||||
var sortedJobs = sortJobsById(lastAndelaJobs);
|
||||
var opportunities = sortJobsById(
|
||||
lastAndelaJobs.filter(function (j) {
|
||||
return j.kind === 'opportunity';
|
||||
}),
|
||||
);
|
||||
var applied = sortJobsById(
|
||||
lastAndelaJobs.filter(function (j) {
|
||||
return j.kind !== 'opportunity';
|
||||
}),
|
||||
);
|
||||
|
||||
sortedJobs.slice(0, 10).forEach(function(job) {
|
||||
function renderJob(job) {
|
||||
var jobElement = document.createElement('div');
|
||||
jobElement.className = 'job-item';
|
||||
|
||||
var postedDate = job.posted_date || 'Recently posted';
|
||||
var companyName = typeof job.company === 'object' ? (job.company && job.company.name || 'Company') : (job.company || 'Company');
|
||||
var startInfo = job.posted_date || '';
|
||||
var postedAgo = job.posted_ago || '';
|
||||
var companyName =
|
||||
typeof job.company === 'object'
|
||||
? (job.company && job.company.name) || 'Company'
|
||||
: job.company || 'Company';
|
||||
|
||||
jobElement.innerHTML =
|
||||
'<div class="job-title">' + job.title + '</div>' +
|
||||
'<div class="job-company">' + companyName + '</div>' +
|
||||
'<div class="job-location">' + (job.location || 'Remote') + '</div>' +
|
||||
'<div class="job-posted">' + postedDate + '</div>';
|
||||
'<div class="job-title">' +
|
||||
job.title +
|
||||
'</div>' +
|
||||
'<div class="job-company">' +
|
||||
companyName +
|
||||
'</div>' +
|
||||
'<div class="job-location">' +
|
||||
(job.location || 'Remote') +
|
||||
'</div>' +
|
||||
'<div class="job-posted">' +
|
||||
startInfo +
|
||||
(postedAgo ? ' · ' + postedAgo : '') +
|
||||
'</div>';
|
||||
|
||||
jobElement.addEventListener('click', function() {
|
||||
var url = job.url || ('https://app.andela.com/job-postings/' + job.id);
|
||||
jobElement.addEventListener('click', function () {
|
||||
var url = job.url || 'https://app.andela.com/job-postings/' + job.id;
|
||||
chrome.tabs.create({ url: url });
|
||||
});
|
||||
|
||||
jobList.appendChild(jobElement);
|
||||
});
|
||||
}
|
||||
|
||||
if (opportunities.length) {
|
||||
var oppHeading = document.createElement('div');
|
||||
oppHeading.className = 'section-heading section-heading-opportunities';
|
||||
oppHeading.textContent = 'Open Opportunities';
|
||||
jobList.appendChild(oppHeading);
|
||||
opportunities.slice(0, 10).forEach(renderJob);
|
||||
}
|
||||
|
||||
if (applied.length) {
|
||||
var appliedHeading = document.createElement('div');
|
||||
appliedHeading.className = 'section-heading section-heading-applied';
|
||||
appliedHeading.textContent = 'Applied';
|
||||
jobList.appendChild(appliedHeading);
|
||||
applied.slice(0, 10).forEach(renderJob);
|
||||
}
|
||||
}
|
||||
|
||||
var status = document.getElementById('status');
|
||||
status.textContent = lastAndelaUpdated ?
|
||||
'Last checked: ' + new Date(lastAndelaUpdated).toLocaleString() :
|
||||
'Not checked yet';
|
||||
status.textContent = lastAndelaUpdated
|
||||
? 'Last checked: ' + new Date(lastAndelaUpdated).toLocaleString()
|
||||
: 'Not checked yet';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.getElementById('checkNow').addEventListener('click', function() {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
document.getElementById('checkNow').addEventListener('click', function () {
|
||||
console.log('Manual check triggered');
|
||||
chrome.runtime.sendMessage({ action: 'checkNow' }, function(response) {
|
||||
chrome.runtime.sendMessage({ action: 'checkNow' }, function (response) {
|
||||
console.log('Check initiated');
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('openSettings').addEventListener('click', function() {
|
||||
document
|
||||
.getElementById('openSettings')
|
||||
.addEventListener('click', function () {
|
||||
chrome.tabs.create({ url: 'settings.html' });
|
||||
});
|
||||
|
||||
chrome.storage.local.get(['lastAndelaJobs', 'lastAndelaUpdated', 'totalAndelaMatching'], function(result) {
|
||||
chrome.storage.local.get(
|
||||
['lastAndelaJobs', 'lastAndelaUpdated', 'totalAndelaMatching'],
|
||||
function (result) {
|
||||
updateUI(result);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
chrome.storage.onChanged.addListener(function(changes, areaName) {
|
||||
if (areaName === 'local' && (changes.lastAndelaJobs || changes.lastAndelaUpdated || changes.totalAndelaMatching)) {
|
||||
chrome.storage.onChanged.addListener(function (changes, areaName) {
|
||||
if (
|
||||
areaName === 'local' &&
|
||||
(changes.lastAndelaJobs ||
|
||||
changes.lastAndelaUpdated ||
|
||||
changes.totalAndelaMatching)
|
||||
) {
|
||||
console.log('Storage updated, refreshing UI...');
|
||||
chrome.storage.local.get(['lastAndelaJobs', 'lastAndelaUpdated', 'totalAndelaMatching'], function(result) {
|
||||
chrome.storage.local.get(
|
||||
['lastAndelaJobs', 'lastAndelaUpdated', 'totalAndelaMatching'],
|
||||
function (result) {
|
||||
updateUI(result);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user