aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2019-02-13 01:11:31 -0500
committerDeterminant <ted.sybil@gmail.com>2019-02-13 01:11:31 -0500
commitc594888953151ddfb4ca04b7752bfd51edc1d6da (patch)
tree59b6d0b0f514f76d152eee9a4359c08110f73531
parentf28b818cc62c7fff67517a4147e64f08ebd73027 (diff)
WIP: migrate to TypeScriptX
-rw-r--r--.babelrc2
-rw-r--r--package-lock.json109
-rw-r--r--package.json7
-rw-r--r--src/Analyze.tsx (renamed from src/Analyze.js)36
-rw-r--r--src/Chart.tsx (renamed from src/Chart.js)0
-rw-r--r--src/Dashboard.tsx (renamed from src/Dashboard.js)0
-rw-r--r--src/Dialog.tsx (renamed from src/Dialog.js)0
-rw-r--r--src/Logo.tsx (renamed from src/Logo.js)0
-rw-r--r--src/PatternTable.tsx (renamed from src/PatternTable.js)0
-rw-r--r--src/RegexField.tsx (renamed from src/RegexField.js)0
-rw-r--r--src/Settings.tsx (renamed from src/Settings.js)16
-rw-r--r--src/Snackbar.tsx (renamed from src/Snackbar.js)0
-rw-r--r--src/background.ts (renamed from src/background.js)2
-rw-r--r--src/decl.ts1
-rw-r--r--src/duration.js21
-rw-r--r--src/duration.ts26
-rw-r--r--src/gapi.js335
-rw-r--r--src/gapi.ts369
-rw-r--r--src/index.js11
-rw-r--r--src/index.tsx5
-rw-r--r--src/msg.js97
-rw-r--r--src/msg.ts87
-rw-r--r--src/pattern.ts (renamed from src/pattern.js)46
-rw-r--r--src/popup.tsx (renamed from src/popup.js)10
-rw-r--r--src/serviceWorker.js135
-rw-r--r--src/theme.tsx (renamed from src/theme.js)0
-rw-r--r--tsconfig.json16
-rw-r--r--types/lru-cache/index.d.ts10
-rw-r--r--types/lru-cache/log1485
-rw-r--r--webpack.config.js19
30 files changed, 2199 insertions, 646 deletions
diff --git a/.babelrc b/.babelrc
index 58a023d..2775ac7 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,4 +1,4 @@
{
- "presets": ["@babel/preset-env", "@babel/preset-react"],
+ "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"],
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime"]
}
diff --git a/package-lock.json b/package-lock.json
index d5894e7..331f290 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -424,6 +424,15 @@
"@babel/helper-plugin-utils": "^7.0.0"
}
},
+ "@babel/plugin-syntax-typescript": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.2.0.tgz",
+ "integrity": "sha512-WhKr6yu6yGpGcNMVgIBuI9MkredpVc7Y3YR4UzEZmDztHoL6wV56YBHLhWnjO1EvId1B32HrD3DRFc+zSoKI1g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
"@babel/plugin-transform-arrow-functions": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz",
@@ -743,6 +752,16 @@
"@babel/helper-plugin-utils": "^7.0.0"
}
},
+ "@babel/plugin-transform-typescript": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.3.2.tgz",
+ "integrity": "sha512-Pvco0x0ZSCnexJnshMfaibQ5hnK8aUHSvjCQhC1JR8eeg+iBwt0AtCO7gWxJ358zZevuf9wPSO5rv+WJcbHPXQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-syntax-typescript": "^7.2.0"
+ }
+ },
"@babel/plugin-transform-unicode-regex": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz",
@@ -836,6 +855,16 @@
"@babel/plugin-transform-react-jsx-source": "^7.0.0"
}
},
+ "@babel/preset-typescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.1.0.tgz",
+ "integrity": "sha512-LYveByuF9AOM8WrsNne5+N79k1YxjNB6gmpCQsnuSBAcV8QUeB+ZUxQzL7Rz7HksPbahymKkq2qBR+o36ggFZA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-transform-typescript": "^7.1.0"
+ }
+ },
"@babel/runtime": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.1.tgz",
@@ -964,6 +993,27 @@
"react-is": "^16.6.3"
}
},
+ "@types/chrome": {
+ "version": "0.0.79",
+ "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.79.tgz",
+ "integrity": "sha512-4+Xducpig6lpwVX65Hk8KSZwRoURHXMDbd38SDNcV8TBaw4xyJki39fjB1io2h7ip+BsyFvgTm9OxR5qneLPiA==",
+ "requires": {
+ "@types/filesystem": "*"
+ }
+ },
+ "@types/filesystem": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.29.tgz",
+ "integrity": "sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw==",
+ "requires": {
+ "@types/filewriter": "*"
+ }
+ },
+ "@types/filewriter": {
+ "version": "0.0.28",
+ "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz",
+ "integrity": "sha1-wFTor02d11205jq8dviFFocU1LM="
+ },
"@types/jss": {
"version": "9.5.7",
"resolved": "https://registry.npmjs.org/@types/jss/-/jss-9.5.7.tgz",
@@ -1416,6 +1466,15 @@
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"dev": true
},
+ "async": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.10"
+ }
+ },
"async-each": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
@@ -1765,6 +1824,23 @@
"ssri": "^6.0.1",
"unique-filename": "^1.1.1",
"y18n": "^4.0.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "yallist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
+ "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
+ "dev": true
+ }
}
},
"cache-base": {
@@ -4907,7 +4983,6 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
"requires": {
"yallist": "^3.0.2"
}
@@ -6822,6 +6897,16 @@
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
},
+ "source-map-loader": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz",
+ "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==",
+ "dev": true,
+ "requires": {
+ "async": "^2.5.0",
+ "loader-utils": "^1.1.0"
+ }
+ },
"source-map-resolve": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
@@ -7168,6 +7253,19 @@
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
"dev": true
},
+ "ts-loader": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.3.3.tgz",
+ "integrity": "sha512-KwF1SplmOJepnoZ4eRIloH/zXL195F51skt7reEsS6jvDqzgc/YSbz9b8E07GxIUwLXdcD4ssrJu6v8CwaTafA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.3.0",
+ "enhanced-resolve": "^4.0.0",
+ "loader-utils": "^1.0.2",
+ "micromatch": "^3.1.4",
+ "semver": "^5.0.1"
+ }
+ },
"tslib": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
@@ -7200,6 +7298,12 @@
"resolved": "https://registry.npmjs.org/typeface-roboto/-/typeface-roboto-0.0.54.tgz",
"integrity": "sha512-sOFA1FXgP0gOgBYlS6irwq6hHYA370KE3dPlgYEJHL3PJd5X8gQE0RmL79ONif6fL5JZuGDj+rtOrFeOqz5IZQ=="
},
+ "typescript": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3.tgz",
+ "integrity": "sha512-Y21Xqe54TBVp+VDSNbuDYdGw0BpoR/Q6wo/+35M8PAU0vipahnyduJWirxxdxjsAkS7hue53x2zp8gz7F05u0A==",
+ "dev": true
+ },
"ua-parser-js": {
"version": "0.7.19",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz",
@@ -7657,8 +7761,7 @@
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
- "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
- "dev": true
+ "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A=="
},
"yargs": {
"version": "12.0.5",
diff --git a/package.json b/package.json
index 6914549..75f0a66 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"@babel/polyfill": "^7.2.5",
"@babel/preset-env": "^7.3.1",
"@babel/preset-react": "^7.0.0",
+ "@babel/preset-typescript": "^7.1.0",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.5",
"copy-webpack-plugin": "^4.6.0",
@@ -28,7 +29,10 @@
"eslint-loader": "^2.1.2",
"eslint-plugin-react": "^7.12.4",
"html-webpack-plugin": "^4.0.0-beta.5",
+ "source-map-loader": "^0.2.4",
"style-loader": "^0.23.1",
+ "ts-loader": "^5.3.3",
+ "typescript": "^3.3.3",
"url-loader": "^1.1.2",
"webpack": "^4.29.2",
"webpack-cli": "^3.2.3"
@@ -36,6 +40,9 @@
"dependencies": {
"@material-ui/core": "^3.9.2",
"@material-ui/icons": "^3.0.2",
+ "@types/chrome": "0.0.79",
+ "@types/react": "^16.8.2",
+ "lru-cache": "^5.1.1",
"moment": "^2.24.0",
"react": "^16.8.1",
"react-dates": "^19.0.0",
diff --git a/src/Analyze.js b/src/Analyze.tsx
index 98e3ce2..5450998 100644
--- a/src/Analyze.js
+++ b/src/Analyze.tsx
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import 'react-dates/initialize';
import 'react-dates/lib/css/_datepicker.css';
import { DateRangePicker } from 'react-dates';
-import { withStyles } from '@material-ui/core/styles';
+import { Theme, withStyles } from '@material-ui/core/styles';
import cyan from '@material-ui/core/colors/cyan';
import deepOrange from '@material-ui/core/colors/deepOrange';
import CssBaseline from '@material-ui/core/CssBaseline';
@@ -15,51 +15,55 @@ import Grid from '@material-ui/core/Grid';
import AddCircleIcon from '@material-ui/icons/AddCircle';
import IconButton from '@material-ui/core/IconButton';
import * as gapi from './gapi';
-import { msgType, MsgClient } from './msg';
+import { MsgType, MsgClient } from './msg';
import { Pattern, PatternEntry } from './pattern';
import { AnalyzePieChart, getChartData } from './Chart';
import PatternTable from './PatternTable';
import Snackbar from './Snackbar';
import AlertDialog from './Dialog';
+import moment from 'moment';
const default_chart_data = [
{name: 'Work', value: 10, color: cyan[300]},
{name: 'Wasted', value: 10, color: deepOrange[300]}];
-const styles = theme => ({
+const styles = (theme: Theme) => ({
buttonSpacer: {
marginBottom: theme.spacing.unit * 4,
},
});
class Analyze extends React.Component {
+ msgClient: MsgClient;
+
state = {
- patterns: [],
+ patterns: [] as PatternEntry[],
calendars: {},
- startDate: null,
- endDate: null,
+ startDate: null as moment.Moment,
+ endDate: null as moment.Moment,
patternGraphData: default_chart_data,
calendarGraphData: default_chart_data,
snackBarOpen: false,
snackBarMsg: 'unknown',
snackBarVariant: 'error',
dialogOpen: false,
- dialogMsg: {title: '', message: ''},
+ dialogMsg: {title: '', message: ''}
};
- constructor(props) {
+ constructor(props: any) {
super(props);
+
this.msgClient = new MsgClient('main');
this.msgClient.sendMsg({
- type: msgType.getPatterns,
+ type: MsgType.getPatterns,
data: { id: 'analyze' }
}).then(msg => {
this.setState({ patterns: msg.data.map(p => PatternEntry.inflate(p)) });
});
this.msgClient.sendMsg({
- type: msgType.getCalendars,
+ type: MsgType.getCalendars,
data: { enabledOnly: true }
}).then(msg => {
this.setState({ calendars: msg.data });
@@ -71,20 +75,20 @@ class Analyze extends React.Component {
this.dialogPromiseResolver = null;
}
- loadPatterns = patterns => {
+ loadPatterns = (patterns: PatternEntry[]) => {
this.msgClient.sendMsg({
- type: msgType.updatePatterns,
+ type: MsgType.updatePatterns,
data: { id: 'analyze', patterns: patterns.map(p => p.deflate()) }
}).then(() => this.setState({ patterns }));
};
- updatePattern = (field, idx, value) => {
+ updatePattern = (field: string, idx: number, value: PatternEntry[]) => {
let patterns = this.state.patterns;
patterns[idx][field] = value;
this.loadPatterns(patterns);
};
- removePattern = idx => {
+ removePattern = (idx: number) => {
let patterns = this.state.patterns;
patterns.splice(idx, 1);
for (let i = 0; i < patterns.length; i++)
@@ -99,8 +103,8 @@ class Analyze extends React.Component {
this.loadPatterns(patterns);
};
- getCalEvents = (id, start, end) => {
- return this.msgClient.sendMsg({ type: msgType.getCalEvents, data: { id,
+ getCalEvents = (id: string, start: Date, end: Date) => {
+ return this.msgClient.sendMsg({ type: MsgType.getCalEvents, data: { id,
start: start.getTime(),
end: end.getTime() } })
.then(({ data }) => data.map(e => {
diff --git a/src/Chart.js b/src/Chart.tsx
index b1c36ed..b1c36ed 100644
--- a/src/Chart.js
+++ b/src/Chart.tsx
diff --git a/src/Dashboard.js b/src/Dashboard.tsx
index 04ced46..04ced46 100644
--- a/src/Dashboard.js
+++ b/src/Dashboard.tsx
diff --git a/src/Dialog.js b/src/Dialog.tsx
index 7e24176..7e24176 100644
--- a/src/Dialog.js
+++ b/src/Dialog.tsx
diff --git a/src/Logo.js b/src/Logo.tsx
index a4036a9..a4036a9 100644
--- a/src/Logo.js
+++ b/src/Logo.tsx
diff --git a/src/PatternTable.js b/src/PatternTable.tsx
index 93be293..93be293 100644
--- a/src/PatternTable.js
+++ b/src/PatternTable.tsx
diff --git a/src/RegexField.js b/src/RegexField.tsx
index e3fa9f4..e3fa9f4 100644
--- a/src/RegexField.js
+++ b/src/RegexField.tsx
diff --git a/src/Settings.js b/src/Settings.tsx
index 2835483..83f1da6 100644
--- a/src/Settings.js
+++ b/src/Settings.tsx
@@ -20,7 +20,7 @@ import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import Checkbox from '@material-ui/core/Checkbox';
import * as gapi from './gapi';
-import { msgType, MsgClient } from './msg';
+import { MsgType, MsgClient } from './msg';
import { Pattern, PatternEntry } from './pattern';
import PatternTable from './PatternTable';
import Snackbar from './Snackbar';
@@ -137,21 +137,21 @@ class Settings extends React.Component {
this.msgClient = new MsgClient('main');
this.msgClient.sendMsg({
- type: msgType.getPatterns,
+ type: MsgType.getPatterns,
data: { id: 'main' }
}).then(msg => {
this.setState({ patterns: msg.data.map(p => PatternEntry.inflate(p)) });
});
this.msgClient.sendMsg({
- type: msgType.getCalendars,
+ type: MsgType.getCalendars,
data: { enabledOnly: false }
}).then(msg => {
this.setState({ calendars: msg.data });
});
this.msgClient.sendMsg({
- type: msgType.getConfig,
+ type: MsgType.getConfig,
data: ['trackedPeriods']
}).then(msg => {
let config = {
@@ -191,7 +191,7 @@ class Settings extends React.Component {
var calendars = {...this.state.calendars};
calendars[id].enabled = !calendars[id].enabled;
this.msgClient.sendMsg({
- type: msgType.updateCalendars,
+ type: MsgType.updateCalendars,
data: calendars
}).then(() => this.setState({ calendars }));
}
@@ -240,14 +240,14 @@ class Settings extends React.Component {
calendars[id].enabled = this.state.calendars[id].enabled;
}
this.msgClient.sendMsg({
- type: msgType.updateCalendars,
+ type: MsgType.updateCalendars,
data: calendars
}).then(() => this.setState({ calendars }));
};
loadPatterns = (patterns, id) => {
this.msgClient.sendMsg({
- type: msgType.updatePatterns,
+ type: MsgType.updatePatterns,
data: { id, patterns: patterns.map(p => p.deflate()) }
}).then(() => this.setState({ patterns }));
};
@@ -297,7 +297,7 @@ class Settings extends React.Component {
updateTrackedPeriods = trackedPeriods => {
this.msgClient.sendMsg({
- type: msgType.updateConfig,
+ type: MsgType.updateConfig,
data: { trackedPeriods: trackedPeriods.map(p => ({
name: p.name,
start: p.start.deflate(),
diff --git a/src/Snackbar.js b/src/Snackbar.tsx
index f17863c..f17863c 100644
--- a/src/Snackbar.js
+++ b/src/Snackbar.tsx
diff --git a/src/background.js b/src/background.ts
index f22970e..2a23b57 100644
--- a/src/background.js
+++ b/src/background.ts
@@ -5,7 +5,7 @@ import moment from 'moment';
import { getChartData } from './Chart';
import { PatternEntry } from './pattern';
-let mainPatterns = [];
+let mainPatterns: number[] = [];
let analyzePatterns = [];
let calendars = {};
let calData = {};
diff --git a/src/decl.ts b/src/decl.ts
new file mode 100644
index 0000000..5b3daa3
--- /dev/null
+++ b/src/decl.ts
@@ -0,0 +1 @@
+declare module 'react-dates';
diff --git a/src/duration.js b/src/duration.js
deleted file mode 100644
index 53de0ad..0000000
--- a/src/duration.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import moment from 'moment';
-
-export class Duration {
- constructor(value, unit) {
- this.value = value
- this.unit = unit
- }
-
- toMoment() {
- let m = moment.duration(this.value, this.unit);
- if (m.isValid()) return m;
- return null;
- }
-
- static days(n) { return new Duration(n, 'days'); }
- static weeks(n) { return new Duration(n, 'weeks'); }
- static months(n) { return new Duration(n, 'months'); }
-
- deflate() { return { value: this.value, unit: this.unit }; }
- static inflate = obj => new Duration(obj.value, obj.unit);
-}
diff --git a/src/duration.ts b/src/duration.ts
new file mode 100644
index 0000000..18849a0
--- /dev/null
+++ b/src/duration.ts
@@ -0,0 +1,26 @@
+import moment from 'moment';
+
+export type TimeUnit = moment.unitOfTime.DurationConstructor;
+
+export class Duration {
+ value: number;
+ unit: TimeUnit;
+ constructor(value: number, unit: TimeUnit) {
+ this.value = value
+ this.unit = unit
+ }
+
+ isValid() { return moment.duration(this.value, this.unit).isValid(); }
+ toMoment() {
+ let m = moment.duration(this.value, this.unit);
+ if (m.isValid()) return m;
+ return null;
+ }
+
+ static days(n: number) { return new Duration(n, 'days'); }
+ static weeks(n: number) { return new Duration(n, 'weeks'); }
+ static months(n: number) { return new Duration(n, 'months'); }
+
+ deflate() { return { value: this.value, unit: this.unit }; }
+ static inflate = (obj: { value: number, unit: TimeUnit }) => new Duration(obj.value, obj.unit);
+}
diff --git a/src/gapi.js b/src/gapi.js
deleted file mode 100644
index 3938864..0000000
--- a/src/gapi.js
+++ /dev/null
@@ -1,335 +0,0 @@
-/* global chrome */
-import LRU from "lru-cache";
-const gapi_base = 'https://www.googleapis.com/calendar/v3';
-
-const GApiError = Object.freeze({
- invalidSyncToken: Symbol("invalidSyncToken"),
- notLoggedIn: Symbol("notLoggedIn"),
- notLoggedOut: Symbol("notLoggedOut"),
- otherError: Symbol("otherError"),
-});
-
-function to_params(dict) {
- return Object.entries(dict).filter(([k, v]) => v).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&');
-}
-
-let loggedIn = null;
-
-function _getAuthToken(interactive = false) {
- return new Promise(resolver =>
- chrome.identity.getAuthToken(
- { interactive }, token => resolver([token, !chrome.runtime.lastError])))
- .then(([token, ok]) => {
- if (ok) return token;
- else throw GApiError.notLoggedIn;
- });
-}
-
-function _removeCachedAuthToken(token) {
- return new Promise(resolver =>
- chrome.identity.removeCachedAuthToken({ token }, () => resolver()));
-}
-
-export function getLoggedIn() {
- if (loggedIn === null)
- {
- return _getAuthToken(false)
- .then(() => loggedIn = true)
- .catch(() => loggedIn = false)
- .then(() => loggedIn);
- }
- else return Promise.resolve(loggedIn);
-}
-
-export function getAuthToken() {
- return getLoggedIn().then(b => {
- if (b) return _getAuthToken(false);
- else throw GApiError.notLoggedIn;
- });
-}
-
-export function login() {
- return getLoggedIn().then(b => {
- if (!b) return _getAuthToken(true).then(() => loggedIn = true);
- else throw GApiError.notLoggedOut;
- });
-}
-
-export function logout() {
- return getAuthToken().then(token => {
- return fetch(`https://accounts.google.com/o/oauth2/revoke?${to_params({ token })}`,
- { method: 'GET', async: true }).then(response => {
- //if (response.status === 200)
- return _removeCachedAuthToken(token);
- //else throw GApiError.otherError;
- });
- }).then(() => loggedIn = false);
-}
-
-export function getCalendars(token) {
- return fetch(`${gapi_base}/users/me/calendarList?${to_params({access_token: token})}`,
- { method: 'GET', async: true })
- .then(response => response.json())
- .then(data => data.items);
-}
-
-export function getColors(token) {
- return fetch(`${gapi_base}/colors?${to_params({access_token: token})}`,
- { method: 'GET', async: true })
- .then(response => response.json());
-}
-
-function getEvent(calId, eventId, token) {
- return fetch(`${gapi_base}/calendars/${calId}/events/${eventId}?${to_params({access_token: token})}`,
- { method: 'GET', async: true })
- .then(response => response.json());
-}
-
-function getEvents(calId, token, syncToken=null, timeMin=null, timeMax=null, resultsPerRequest=100) {
- let results = [];
- const singleFetch = (pageToken, syncToken) => fetch(`${gapi_base}/calendars/${calId}/events?${to_params({
- access_token: token,
- pageToken,
- syncToken,
- timeMin,
- timeMax,
- maxResults: resultsPerRequest
- })}`, { method: 'GET', async: true })
- .then(response => {
- if (response.status === 200)
- return response.json();
- else if (response.status === 410)
- throw GApiError.invalidSyncToken;
- else throw GApiError.otherError;
- })
- .then(data => {
- results.push(...data.items);
- if (data.nextPageToken) {
- return singleFetch(data.nextPageToken, '');
- } else {
- return ({
- nextSyncToken: data.nextSyncToken,
- results
- });
- }
- })
-
- return singleFetch('', syncToken);
-}
-
-export class GCalendar {
- constructor(calId, name, options={maxCachedItems: 100, nDaysPerSlot: 10, largeQuery: 10}) {
- this.calId = calId;
- this.name = name;
- this.syncToken = '';
- this.cache = new LRU({
- max: options.maxCachedItems,
- dispose: (k, v) => this.onRemoveSlot(k, v)
- });
- this.eventMeta = {};
- this.options = options;
- this.divider = 8.64e7 * this.options.nDaysPerSlot;
- }
-
- get token() { return getAuthToken(); }
-
- dateToCacheKey(date) {
- return Math.floor(date / this.divider);
- }
-
- dateRangeToCacheKeys(range) {
- return {
- start: this.dateToCacheKey(range.start),
- end: this.dateToCacheKey(new Date(range.end.getTime() - 1))
- };
- }
-
- getSlot(k) {
- if (!this.cache.has(k))
- {
- let res = {};
- this.cache.set(k, res);
- return res;
- }
- else return this.cache.get(k);
- }
-
- onRemoveSlot(k, v) {
- for (let id in v) {
- console.assert(this.eventMeta[id]);
- let keys = this.eventMeta[id].keys;
- keys.delete(k);
- if (keys.size === 0)
- delete this.eventMeta[id];
- }
- }
-
- slotStartDate(k) { return new Date(k * this.divider); }
- slotEndDate(k) { return new Date((k + 1) * this.divider); }
-
- addEvent(e, evict = false) {
- //console.log('adding event', e);
- if (this.eventMeta.hasOwnProperty(e.id))
- this.removeEvent(e);
- let r = this.dateRangeToCacheKeys(e);
- let ks = r.start;
- let ke = r.end;
- let t = this.cache.length;
- let keys = new Set();
- for (let i = ks; i <= ke; i++)
- {
- keys.add(i);
- if (!this.cache.has(i)) t++;
- }
- this.eventMeta[e.id] = {
- keys,
- summary: e.summary,
- };
- if (!evict && t > this.options.maxCachedItems) return;
- if (ks === ke)
- this.getSlot(ks)[e.id] = {
- start: e.start,
- end: e.end,
- id: e.id };
- else
- {
- this.getSlot(ks)[e.id] = {
- start: e.start,
- end: this.slotEndDate(ks),
- id: e.id };
- this.getSlot(ke)[e.id] = {
- start: this.slotStartDate(ke),
- end: e.end,
- id: e.id };
- for (let k = ks + 1; k < ke; k++)
- this.getSlot(k)[e.id] = {
- start: this.slotStartDate(k),
- end: this.slotEndDate(k),
- id: e.id};
- }
- }
-
- removeEvent(e) {
- let keys = this.eventMeta[e.id].keys;
- console.assert(keys);
- keys.forEach(k => delete this.getSlot(k)[e.id]);
- delete this.eventMeta[e.id];
- }
-
- getSlotEvents(k, start, end) {
- let s = this.getSlot(k);
- //console.log(s);
- let results = [];
- for (let id in s) {
- if (!(s[id].start >= end || s[id].end <= start))
- {
- results.push({
- id,
- start: s[id].start < start ? start: s[id].start,
- end: s[id].end > end ? end: s[id].end,
- summary: this.eventMeta[id].summary
- });
- }
- }
- return results;
- }
-
- getCachedEvents(_r) {
- let r = this.dateRangeToCacheKeys(_r);
- let ks = r.start;
- let ke = r.end;
- let results = this.getSlotEvents(ks, _r.start, _r.end);
- for (let k = ks + 1; k < ke; k++)
- {
- let s = this.getSlot(k);
- for (let id in s)
- results.push(s[id]);