From a2d82b526e731123b1004045e064fca6229c46f1 Mon Sep 17 00:00:00 2001 From: Ivelin Megdanov Date: Fri, 12 Jul 2024 17:14:36 +0300 Subject: [PATCH 1/2] Moved api logic to background service worker --- src/index.html | 15 +++++-- src/js/api.js | 15 +++---- src/js/apiCecoAdapter.js | 41 ++++++++---------- src/js/background.js | 31 ++++++++++++++ src/js/bitcoin.js | 91 +++++++++++++++++++++------------------- src/manifest.json | 5 ++- 6 files changed, 117 insertions(+), 81 deletions(-) create mode 100644 src/js/background.js diff --git a/src/index.html b/src/index.html index 91314a3..62b40bc 100644 --- a/src/index.html +++ b/src/index.html @@ -7,7 +7,10 @@ @@favicons - + @@socialMediaTags @@ -40,7 +43,11 @@

-:-

- + -:- - + diff --git a/src/js/api.js b/src/js/api.js index c55fc68..d31a934 100644 --- a/src/js/api.js +++ b/src/js/api.js @@ -8,14 +8,11 @@ class API { get(_endpoint) { App.Loader.init(); - return axios.get(this.apiAdapter.baseURL + _endpoint) - .then( r => r.data ) - .then (r => { - App.Message.clear(); - App.Loader.destroy(); - - return r; - }); + return this.apiAdapter.getBitcoinRatesForPeriod(_endpoint).then((r) => { + App.Message.clear(); + App.Loader.destroy(); + return r; + }); } mapData(_r, _period) { @@ -49,7 +46,7 @@ class API { getBitcoinRatesNow() { return this.apiAdapter.getBitcoinRatesNow(); } -}; +} // window.App.API = new API(App.apiFakeAdapter); //window.App.API = new API(App.apiGoranAdapter); diff --git a/src/js/apiCecoAdapter.js b/src/js/apiCecoAdapter.js index 2b7534b..1135b48 100644 --- a/src/js/apiCecoAdapter.js +++ b/src/js/apiCecoAdapter.js @@ -1,12 +1,6 @@ window.App = window.App || {}; window.App.apiCecoAdapter = { - baseURL: 'https://api.crypto-tab.com/v1/', - - get: function (_endpoint) { - return App.API.get(_endpoint); - }, - mapData: function (response, dateLabelFormat) { return response .map((_rec) => ({ @@ -19,44 +13,43 @@ window.App.apiCecoAdapter = { .reverse(); }, - _createDateAsUTC: function (date) { - return new Date( - Date.UTC( - date.getFullYear(), - date.getMonth(), - date.getDate(), - date.getHours(), - date.getMinutes(), - date.getSeconds() - ) - ); + getBitcoinRatesForPeriod: function (period) { + return new Promise((resolve, reject) => { + chrome.runtime.sendMessage({ type: 'getBitcoinPrice', period: period }, (response) => { + if (response && !response.error) { + resolve(response.data); + } else { + reject(response.error || 'Failed to retrieve Bitcoin price data'); + } + }); + }); }, getBitcoinRatesForAll: function () { - return this.get('bitcoin/all'); + return this.getBitcoinRatesForPeriod('ALL'); }, getBitcoinRatesForOneYear: function () { - return this.get('bitcoin/year'); + return this.getBitcoinRatesForPeriod('ONE_YEAR'); }, getBitcoinRatesForOneMonth: function () { - return this.get('bitcoin/month'); + return this.getBitcoinRatesForPeriod('ONE_MONTH'); }, getBitcoinRatesForOneWeek: function () { - return this.get('bitcoin/week'); + return this.getBitcoinRatesForPeriod('ONE_WEEK'); }, getBitcoinRatesForOneDay: function () { - return this.get('bitcoin/day'); + return this.getBitcoinRatesForPeriod('ONE_DAY'); }, getBitcoinRatesForOneHour: function () { - return this.get('bitcoin/hour'); + return this.getBitcoinRatesForPeriod('ONE_HOUR'); }, getBitcoinRatesNow: function () { - return this.get('bitcoin/now'); + return this.getBitcoinRatesForPeriod('NOW'); }, }; diff --git a/src/js/background.js b/src/js/background.js new file mode 100644 index 0000000..92f9518 --- /dev/null +++ b/src/js/background.js @@ -0,0 +1,31 @@ +let bitcoinPriceData = {}; + +async function fetchBitcoinPrice(period) { + const endpoints = { + ALL: 'bitcoin/all', + ONE_YEAR: 'bitcoin/year', + ONE_MONTH: 'bitcoin/month', + ONE_WEEK: 'bitcoin/week', + ONE_DAY: 'bitcoin/day', + ONE_HOUR: 'bitcoin/hour', + NOW: 'bitcoin/now', + }; + + try { + const response = await fetch(`https://api.crypto-tab.com/v1/${endpoints[period]}`); + const data = await response.json(); + bitcoinPriceData[period] = data; + } catch (error) { + console.error(`Error fetching Bitcoin price for ${period}:`, error); + } +} + +chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + if (request.type === 'getBitcoinPrice') { + const period = request.period; + fetchBitcoinPrice(period).then(() => { + sendResponse({ data: bitcoinPriceData[period], cached: false }); + }); + return true; // Indicates that the response will be sent asynchronously + } +}); diff --git a/src/js/bitcoin.js b/src/js/bitcoin.js index de9801d..dcb6b64 100644 --- a/src/js/bitcoin.js +++ b/src/js/bitcoin.js @@ -30,8 +30,7 @@ window.App.Bitcoin = { this.classList.add('active'); const period = this.dataset.period; - self.repositories[period] - .getData() + self.getBitcoinData(period) .then((_data) => self.chart.init(_data)) .catch((error) => { self.handleChartRejection(period, error); @@ -45,26 +44,21 @@ window.App.Bitcoin = { App.Settings.get().then(({ period }) => { const selectedTab = period ? Object.keys(this.PERIODS).indexOf(period) : 1; - self.$dataPeriods[selectedTab].click(); }); }, getBitcoinData(period) { - switch (period) { - case 'ALL': - return App.API.getBitcoinRatesForAll(); - case 'ONE_YEAR': - return App.API.getBitcoinRatesForOneYear(); - case 'ONE_MONTH': - return App.API.getBitcoinRatesForOneMonth(); - case 'ONE_WEEK': - return App.API.getBitcoinRatesForOneWeek(); - case 'ONE_DAY': - return App.API.getBitcoinRatesForOneDay(); - case 'ONE_HOUR': - return App.API.getBitcoinRatesForOneHour(); - } + return new Promise((resolve, reject) => { + this.repositories[period] + .getData() + .then((response) => { + resolve(response); + }) + .catch((error) => { + reject(error || 'Failed to retrieve Bitcoin price data'); + }); + }); }, getLabelFormat(period) { @@ -74,7 +68,7 @@ window.App.Bitcoin = { case 'ONE_YEAR': return 'MMM YYYY'; case 'ONE_MONTH': - return 'Do MMM'; + return 'D MMM'; case 'ONE_WEEK': return 'dddd'; case 'ONE_DAY': @@ -95,7 +89,6 @@ window.App.Bitcoin = { this.chart.destroy(); } else if (_res.localData.length) { App.Message.clear(); - this.chart.init(_res.localData); this.setLastUpdated(true); } @@ -103,7 +96,6 @@ window.App.Bitcoin = { }, handleNowRejection() { this.isLocalNowDataOld = true; - App.Loader.destroy(); }, @@ -112,29 +104,28 @@ window.App.Bitcoin = { const storageSetting = App.ENV.platform === 'EXTENSION' ? 'BROWSER_STORAGE' : 'LOCAL_STORAGE'; - Object.keys(this.PERIODS).forEach( - (period) => - (this.repositories[period] = new SuperRepo({ - storage: storageSetting, - name: 'bitcoin-' + period, - outOfDateAfter: 15 * 60 * 1000, - mapData: (r) => App.API.mapData(r, this.getLabelFormat(period)), - request: () => - this.getBitcoinData(period) - .then((res) => { - this.isLocalChartDataOld = false; - return res; - }) - .catch((jqXHR, textStatus, errorThrown) => { - this.handleChartRejection(period, jqXHR); - }), - })) - ); + Object.keys(this.PERIODS).forEach((period) => { + this.repositories[period] = new SuperRepo({ + storage: storageSetting, + name: 'bitcoin-' + period, + outOfDateAfter: 0.1 * 60 * 1000, // 15 minutes + mapData: (r) => App.API.mapData(r, this.getLabelFormat(period)), + request: () => + this.getBitcoinDataFromBackground(period) + .then((res) => { + this.isLocalChartDataOld = false; + return res; + }) + .catch((jqXHR, textStatus, errorThrown) => { + this.handleChartRejection(period, jqXHR); + }), + }); + }); this.repositories['NOW'] = new SuperRepo({ storage: storageSetting, name: 'bitcoin-NOW', - outOfDateAfter: 3 * 60 * 1000, + outOfDateAfter: 0.1 * 60 * 1000, // 3 minutes mapData: (data) => { const { value, changePercent } = data[0]; const { dayAgo, weekAgo, monthAgo } = changePercent; @@ -145,7 +136,7 @@ window.App.Bitcoin = { }; }, request: () => - App.API.getBitcoinRatesNow() + this.getBitcoinDataFromBackground('NOW') .then((res) => { this.isLocalNowDataOld = false; return res; @@ -156,6 +147,18 @@ window.App.Bitcoin = { }); }, + getBitcoinDataFromBackground(period) { + return new Promise((resolve, reject) => { + chrome.runtime.sendMessage({ type: 'getBitcoinPrice', period: period }, (response) => { + if (response && !response.error) { + resolve(response.data); + } else { + reject(response.error || 'Failed to retrieve Bitcoin price data'); + } + }); + }); + }, + $priceNow: document.querySelector('#price-now'), setPriceNow(_price) { this.$priceNow.textContent = App.Utils.formatPrice(Math.round(_price)); @@ -201,16 +204,16 @@ window.App.Bitcoin = { } const getSignedPercentage = (_number) => { - const isChangePisitive = _number >= 0; + const isChangePositive = _number >= 0; const isChangeZero = _number === 0; - return isChangePisitive && !isChangeZero ? `+${_number}%` : `${_number}%`; + return isChangePositive && !isChangeZero ? `+${_number}%` : `${_number}%`; }; const getVisualClass = (_number) => { - const isChangePisitive = _number >= 0; + const isChangePositive = _number >= 0; const isChangeZero = _number === 0; - return isChangeZero ? '' : isChangePisitive ? 'positive' : 'negative'; + return isChangeZero ? '' : isChangePositive ? 'positive' : 'negative'; }; this.$change.innerHTML = ` (${getSignedPercentage(changePercent)} diff --git a/src/manifest.json b/src/manifest.json index 83b481a..871a611 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -15,5 +15,8 @@ "host_permissions": [ "https://bitcoin-price-api.devlabs-projects.info/**/*", "https://api.crypto-tab.com/**/*" - ] + ], + "background": { + "service_worker": "js/background.js" + } } From 9fcda0355f2f74fbe31bfb79925662980abc83ec Mon Sep 17 00:00:00 2001 From: Ivelin Megdanov Date: Fri, 12 Jul 2024 17:52:04 +0300 Subject: [PATCH 2/2] Fixed cache time --- src/js/bitcoin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/bitcoin.js b/src/js/bitcoin.js index dcb6b64..98200c0 100644 --- a/src/js/bitcoin.js +++ b/src/js/bitcoin.js @@ -108,7 +108,7 @@ window.App.Bitcoin = { this.repositories[period] = new SuperRepo({ storage: storageSetting, name: 'bitcoin-' + period, - outOfDateAfter: 0.1 * 60 * 1000, // 15 minutes + outOfDateAfter: 15 * 60 * 1000, // 15 minutes mapData: (r) => App.API.mapData(r, this.getLabelFormat(period)), request: () => this.getBitcoinDataFromBackground(period) @@ -125,7 +125,7 @@ window.App.Bitcoin = { this.repositories['NOW'] = new SuperRepo({ storage: storageSetting, name: 'bitcoin-NOW', - outOfDateAfter: 0.1 * 60 * 1000, // 3 minutes + outOfDateAfter: 3 * 60 * 1000, // 3 minutes mapData: (data) => { const { value, changePercent } = data[0]; const { dayAgo, weekAgo, monthAgo } = changePercent;