diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/background.ts | 70 | ||||
-rw-r--r-- | src/popup.tsx | 18 |
2 files changed, 61 insertions, 27 deletions
diff --git a/src/background.ts b/src/background.ts index b92509e..e4e2824 100644 --- a/src/background.ts +++ b/src/background.ts @@ -19,13 +19,29 @@ let config = { let mainGraphData: GraphData[] = []; let dirtyMetadata = false; -function loadMetadata() { - return new Promise(resolver => chrome.storage.local.get([ - 'calendars', 'config', 'mainPatterns', 'analyzePatterns', - ], items => { - if (chrome.runtime.lastError) - console.error("error while loading saved metadata"); - else if (!items.hasOwnProperty('config')) +enum ChromeError { + storageGetError = "storageGetError", + storageSetError = "storageSetError" +} + +const chromeStorageGet = (keys: string[]): Promise<any> => ( + new Promise(resolver => chrome.storage.local.get(keys, items => { + if (chrome.runtime.lastError) throw ChromeError.storageGetError; + resolver(items); + })) +); + +const chromeStorageSet = (obj: {[key: string]: any}): Promise<void> => ( + new Promise(resolver => chrome.storage.local.set(obj, () => { + if (chrome.runtime.lastError) throw ChromeError.storageSetError; + resolver(); + })) +); + +async function loadMetadata() { + try { + let items = await chromeStorageGet(['calendars', 'config', 'mainPatterns', 'analyzePatterns']); + if (!items.hasOwnProperty('config')) console.log("no saved metadata"); else { @@ -37,22 +53,24 @@ function loadMetadata() { mainPatterns = items.mainPatterns.map((p: PatternEntryFlat) => PatternEntry.inflate(p)); analyzePatterns = items.analyzePatterns.map((p: PatternEntryFlat) => PatternEntry.inflate(p)); } - resolver(); - })); + } catch (_) { + console.error("error while loading saved metadata"); + } } -function saveMetadata() { - return new Promise(resolver => chrome.storage.local.set({ +async function saveMetadata() { + await chromeStorageSet({ calendars, config: { trackedPeriods: config.trackedPeriods.map(p => p.deflate()) }, mainPatterns: mainPatterns.map(p => p.deflate()), analyzePatterns: analyzePatterns.map(p => p.deflate()) - }, () => { - console.log('metadata saved'); - resolver(); - })); + }); + console.log('metadata saved'); +} + +async function saveCachedCals() { } async function getCalEvents(id: string, start: Date, end: Date) { @@ -116,9 +134,7 @@ async function pollSync() { )); } -loadMetadata().then(() => pollSync()); - -chrome.runtime.onConnect.addListener(function(port) { +function handleMsg(port: chrome.runtime.Port) { console.assert(port.name == 'main'); port.onMessage.addListener(_msg => { let msg = Msg.inflate<any>(_msg); @@ -185,17 +201,27 @@ chrome.runtime.onConnect.addListener(function(port) { break; } case MsgType.getGraphData: { - (msg.data.sync ? updateMainGraphData().then(() => {}) : Promise.resolve()).then(() => ( + (async () => { + await (msg.data.sync ? updateMainGraphData().then(() => {}) : Promise.resolve()); + if (mainGraphData.length === 0) + await updateMainGraphData(); port.postMessage(msg.genResp(mainGraphData.map(d => ({ name: d.name, start: d.start.toISOString(), end: d.end.toISOString(), data: d.data - })))) - )); + })))); + })(); break; } default: console.error("unknown msg opt"); } }); -}); +} + +(async () => { + await loadMetadata(); + pollSync(); +})(); + +chrome.runtime.onConnect.addListener(handleMsg); diff --git a/src/popup.tsx b/src/popup.tsx index 20f08e0..0c0c8cc 100644 --- a/src/popup.tsx +++ b/src/popup.tsx @@ -1,12 +1,13 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { Theme, withStyles, MuiThemeProvider } from '@material-ui/core/styles'; +import { Theme, withStyles, StyleRules, MuiThemeProvider } from '@material-ui/core/styles'; import CssBaseline from '@material-ui/core/CssBaseline'; import Typography from '@material-ui/core/Typography'; import Button from '@material-ui/core/Button'; import IconButton from '@material-ui/core/IconButton'; import RefreshIcon from '@material-ui/icons/Refresh'; import Divider from '@material-ui/core/Divider'; +import CircularProgress from '@material-ui/core/CircularProgress'; import Logo from './Logo'; import { theme } from './theme'; @@ -19,7 +20,7 @@ function openOptions() { chrome.tabs.create({ url: "index.html" }); } -const styles = (theme: Theme) => ({ +const styles = (theme: Theme): StyleRules => ({ content: { padding: theme.spacing.unit * 1, overflow: 'auto', @@ -32,13 +33,17 @@ const styles = (theme: Theme) => ({ buttonSpacer: { marginBottom: theme.spacing.unit * 2, }, + loading: { + textAlign: 'center' + } }); type PopupProps = { classes: { content: string, buttons: string, - buttonSpacer: string + buttonSpacer: string, + loading: string } }; @@ -92,6 +97,7 @@ class Popup extends React.Component<PopupProps> { </div> <div className={classes.buttonSpacer} /> { + (data.length > 0 && data.map((d, idx) => ( <div key={idx}> <Typography variant="subtitle1" align="center" color="textPrimary"> @@ -104,11 +110,13 @@ class Popup extends React.Component<PopupProps> { {(d.data.some(dd => dd.value > 1e-3) && <StyledPatternPieChart data={d.data} />) || <Typography variant="subtitle1" align="center" color="textSecondary"> - No data available + No matching events. </Typography>} {idx + 1 < data.length && <Divider />} </div> - )) + ))) || ( + <div className={classes.loading}><CircularProgress color="primary" /></div> + ) } </main> </MuiThemeProvider> |