diff --git a/.gitignore b/.gitignore index be3fb44..669aa66 100644 --- a/.gitignore +++ b/.gitignore @@ -117,8 +117,11 @@ jspm_packages/ # Test Coverage coverage/ +# Development Build Code +dev-build + # Production Build Code -dist/ +prod-build # Typescript v1 declaration files typings/ diff --git a/assets/manifest.json b/assets/manifest.json index 14aca15..46a151f 100644 --- a/assets/manifest.json +++ b/assets/manifest.json @@ -1,6 +1,6 @@ { "name": "Offie - Airbnb Wifi Reviews", - "description": "View Airbnb Wifi and workspace info from the search results page", + "description": "View Airbnb Wifi and workspace info from the search results page.", "manifest_version": 3, "version": "0.0.3", "icons": { diff --git a/src/background/index.ts b/src/background/index.ts index 28d5c32..7743998 100644 --- a/src/background/index.ts +++ b/src/background/index.ts @@ -1,7 +1,13 @@ +import mixpanel from 'mixpanel-browser'; +import { rollbar, initAnalytics, logUrlChange } from '../utils'; import { ChromeUrlUpdate } from '../types/Chrome'; +initAnalytics(); + chrome.tabs.onUpdated.addListener((tabId, { url }) => { if (url) { + logUrlChange(url); + const newUrl: ChromeUrlUpdate = { event: 'URL_UPDATE', url }; chrome.tabs.sendMessage(tabId, newUrl); @@ -9,10 +15,21 @@ chrome.tabs.onUpdated.addListener((tabId, { url }) => { }); chrome.runtime.onInstalled.addListener(() => { - chrome.runtime.setUninstallURL('https://offie.co/uninstall'); + const environment = process.env.NODE_ENV; + + if (!environment) { + rollbar.error(`Failed to find NODE_ENV env var!`); + return; + } + + if (process.env.NODE_ENV === 'production') { + chrome.runtime.setUninstallURL( + `https://offie.co/uninstall?id=${mixpanel.get_distinct_id()}` + ); - chrome.tabs.create({ - url: 'https://offie.co/welcome', - active: true, - }); + chrome.tabs.create({ + url: 'https://offie.co/welcome', + active: true, + }); + } }); diff --git a/src/content/App.tsx b/src/content/App.tsx index b257724..05b9a3d 100644 --- a/src/content/App.tsx +++ b/src/content/App.tsx @@ -2,7 +2,6 @@ import { useState } from 'react'; import { useUrlChangeChrome } from './hooks/useUrlChangeChrome'; import { OffiePortals } from './components/OffiePortals'; import { hasWifiOrWorkspaceFilter, isHomesSearchPage } from './utils'; -import * as analytics from './analytics'; export const App = (): JSX.Element | null => { const [isVisible, setIsVisible] = useState(false); @@ -15,7 +14,6 @@ export const App = (): JSX.Element | null => { const newIsVisible = hasWifiOrWorkspaceFilter(newUrl); setIsVisible(newIsVisible); - analytics.logUrlChange(newUrl); } }); diff --git a/src/content/api.ts b/src/content/api.ts index d5507d6..42ea795 100644 --- a/src/content/api.ts +++ b/src/content/api.ts @@ -1,6 +1,6 @@ /* eslint-disable import/prefer-default-export */ import axios from 'axios'; -import { rollbar } from './utils'; +import { rollbar } from '../utils'; import type { ListingsDetailsRes, OffieApiRes } from '../types/Offie'; export const getListingsDetails = async ( diff --git a/src/content/components/OffieButton.tsx b/src/content/components/OffieButton.tsx index 8cbe695..6e741ca 100644 --- a/src/content/components/OffieButton.tsx +++ b/src/content/components/OffieButton.tsx @@ -3,7 +3,7 @@ import { Button, ButtonProps } from '@mui/material'; import { Wifi as WifiIcon } from '@mui/icons-material'; import { ListingDetails, ReviewWithSentiment } from '../../types/Offie'; import { sortReviewsByDateDesc, sentimentKeys } from '../utils'; -import * as analytics from '../analytics'; +import * as analytics from '../../utils/analytics'; import { InfoPopover } from './InfoPopover'; export interface OffieButtonProps extends ButtonProps { diff --git a/src/content/hooks/useUrlChangeChrome.ts b/src/content/hooks/useUrlChangeChrome.ts index a21de3b..c332377 100644 --- a/src/content/hooks/useUrlChangeChrome.ts +++ b/src/content/hooks/useUrlChangeChrome.ts @@ -1,7 +1,7 @@ /* eslint-disable react-hooks/exhaustive-deps */ import { useEffect } from 'react'; import { ChromeUrlUpdate } from '../../types/Chrome'; -import * as analytics from '../analytics'; +import * as analytics from '../../utils/analytics'; /** * Invoke the `onUrlChange` param when Chrome detects that @@ -19,7 +19,6 @@ export const useUrlChangeChrome = ( const onUrlChangeWrapper = (request: ChromeUrlUpdate) => { if (request.event === 'URL_UPDATE') { onUrlChange(request.url); - analytics.logUrlChange(request.url); } }; @@ -27,7 +26,6 @@ export const useUrlChangeChrome = ( if (runOnInit) { onUrlChange(window.location.href); - analytics.logUrlChange(window.location.href); } return () => { diff --git a/src/content/index.tsx b/src/content/index.tsx index 93fac16..000e9f8 100644 --- a/src/content/index.tsx +++ b/src/content/index.tsx @@ -1,19 +1,13 @@ import '@fontsource/montserrat'; import '@fontsource/montserrat/600.css'; -import mixpanel from 'mixpanel-browser'; import { StrictMode } from 'react'; import ReactDOM from 'react-dom'; import { ThemeProvider } from '@mui/material'; -import { theme, rollbar } from './utils'; +import { theme } from './utils'; import { App } from './App'; +import { initAnalytics } from '../utils'; -const mixpanelToken = process.env.MIXPANEL_PROJECT_TOKEN; - -if (mixpanelToken) { - mixpanel.init(mixpanelToken); -} else { - rollbar.error('Failed to find `MIXPANEL_PROJECT_TOKEN` env var!'); -} +initAnalytics(); const rootOffieNode = document.createElement('div'); rootOffieNode.id = 'offie-node-root'; diff --git a/src/content/utils/airbnb.ts b/src/content/utils/airbnb.ts index 1bb9da5..cd024e0 100644 --- a/src/content/utils/airbnb.ts +++ b/src/content/utils/airbnb.ts @@ -1,5 +1,5 @@ import * as qs from 'qs'; -import { rollbar } from './rollbar'; +import { rollbar } from '../../utils/rollbar'; import { getParsedUrlSearch } from './misc'; export interface AirbnbFilterKeyMap { diff --git a/src/content/utils/dom.ts b/src/content/utils/dom.ts index b2f36ad..aa48448 100644 --- a/src/content/utils/dom.ts +++ b/src/content/utils/dom.ts @@ -1,4 +1,4 @@ -import { rollbar } from './rollbar'; +import { rollbar } from '../../utils/rollbar'; export const OFFIE_NODE_ID_PREFIX = 'offie-node'; export const LISTINGS_FOOTER_SECTION_ID = 'EXPLORE_NUMBERED_PAGINATION'; diff --git a/src/content/utils/index.ts b/src/content/utils/index.ts index 1afef0d..1bd04dd 100644 --- a/src/content/utils/index.ts +++ b/src/content/utils/index.ts @@ -2,4 +2,3 @@ export * from './misc'; export * from './dom'; export * from './theme'; export * from './airbnb'; -export * from './rollbar'; diff --git a/src/content/analytics.ts b/src/utils/analytics.ts similarity index 69% rename from src/content/analytics.ts rename to src/utils/analytics.ts index 50c29bb..8d53d65 100644 --- a/src/content/analytics.ts +++ b/src/utils/analytics.ts @@ -1,7 +1,11 @@ import * as mixpanel from 'mixpanel-browser'; import { WifiSentiment } from '../types/Offie'; -import { getSearchLocation, getMappedSearchFilters } from './utils/airbnb'; -import { getParsedUrlSearch } from './utils/misc'; +import { + getSearchLocation, + getMappedSearchFilters, +} from '../content/utils/airbnb'; +import { getParsedUrlSearch } from '../content/utils/misc'; +import { rollbar } from './rollbar'; export const eventNames = { AIRBNB_SEARCH_URL: 'airbnbSearchUrl', @@ -9,6 +13,16 @@ export const eventNames = { MODAL_OPEN: 'offieModalOpen', }; +export const initAnalytics = (): void => { + const mixpanelToken = process.env.MIXPANEL_PROJECT_TOKEN; + + if (mixpanelToken) { + mixpanel.init(mixpanelToken); + } else { + rollbar.error('Failed to find `MIXPANEL_PROJECT_TOKEN` env var!'); + } +}; + export const logUrlChange = (urlStr: string): void => { const search = getParsedUrlSearch(urlStr); diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..7d24214 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,2 @@ +export * from './rollbar'; +export * from './analytics'; diff --git a/src/content/utils/rollbar.ts b/src/utils/rollbar.ts similarity index 100% rename from src/content/utils/rollbar.ts rename to src/utils/rollbar.ts diff --git a/webpack.config.js b/webpack.config.js index 8d29ed2..8515a5a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,7 +7,13 @@ module.exports = (env) => ({ content: path.join(__dirname, './src/content/index.tsx'), background: path.join(__dirname, './src/background/index.ts'), }, - output: { path: path.join(__dirname, 'dist'), filename: '[name].js' }, + output: { + path: path.join( + __dirname, + `${env.production ? 'prod-build' : 'dev-build'}` + ), + filename: '[name].js', + }, devtool: 'cheap-module-source-map', module: { rules: [