aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/background.ts70
-rw-r--r--src/popup.tsx18
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>