aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2019-02-06 18:44:02 -0500
committerDeterminant <ted.sybil@gmail.com>2019-02-06 18:44:02 -0500
commita8b8cd7d51cafea253f3e7b2e3d1e76054d97135 (patch)
tree55fb977be1d525a642a5b19edc0313796ea83cb0 /src
parentd3d4345a7ab82e9715b1cbf398d43206d43737f6 (diff)
WIP: settings
Diffstat (limited to 'src')
-rw-r--r--src/CustomAnalyzer.js75
-rw-r--r--src/PatternTable.js1
-rw-r--r--src/Settings.js212
-rw-r--r--src/background.js24
4 files changed, 242 insertions, 70 deletions
diff --git a/src/CustomAnalyzer.js b/src/CustomAnalyzer.js
index f76fa5e..f140151 100644
--- a/src/CustomAnalyzer.js
+++ b/src/CustomAnalyzer.js
@@ -38,20 +38,23 @@ const styles = theme => ({
class CustomAnalyzer extends React.Component {
state = {
patterns: [],
- calendars: [],
- timeRange: null,
+ calendars: {},
+ startDate: null,
+ endDate: null,
patternGraphData: default_chart_data,
calendarGraphData: default_chart_data,
- activePattern: null
};
constructor(props) {
super(props);
this.msgClient = new MsgClient('main');
- this.msgClient.sendMsg({ type: msgType.getPatterns }).then(msg => {
+ this.msgClient.sendMsg({
+ type: msgType.getPatterns,
+ data: { id: 'analyze' }
+ }).then(msg => {
this.setState({ patterns: msg.data.map(p => PatternEntry.revive(p)) });
});
- this.msgClient.sendMsg({ type: msgType.getCalendars }).then(msg => {
+ this.msgClient.sendMsg({ type: msgType.getCalendars, data: { enabledOnly: true }}).then(msg => {
this.setState({ calendars: msg.data });
});
}
@@ -59,8 +62,10 @@ class CustomAnalyzer extends React.Component {
updatePattern = (field, idx, value) => {
let patterns = this.state.patterns;
patterns[idx][field] = value;
- this.setState({ patterns });
- this.msgClient.sendMsg({ type: msgType.updatePatterns, data: patterns });
+ this.msgClient.sendMsg({
+ type: msgType.updatePatterns,
+ data: { id: 'analyze', patterns }
+ }).then(() => this.setState({ patterns }));
};
removePattern = idx => {
@@ -68,26 +73,27 @@ class CustomAnalyzer extends React.Component {
patterns.splice(idx, 1);
for (let i = 0; i < patterns.length; i++)
patterns[i].idx = i;
- this.setState({ patterns });
- this.msgClient.sendMsg({ type: msgType.updatePatterns, data: patterns });
+ this.msgClient.sendMsg({
+ type: msgType.updatePatterns,
+ data: { id: 'analyze', patterns }
+ }).then(() => this.setState({ patterns }));
};
newPattern = () => {
let patterns = [PatternEntry.defaultPatternEntry(0), ...this.state.patterns];
for (let i = 1; i < patterns.length; i++)
patterns[i].idx = i;
- this.setState({ patterns });
- this.msgClient.sendMsg({ type: msgType.updatePatterns, data: patterns });
+ this.msgClient.sendMsg({
+ type: msgType.updatePatterns,
+ data: { id: 'analyze', patterns }
+ }).then(() => this.setState({ patterns }));
};
loadPatterns = patterns => {
- this.setState({ patterns });
- this.msgClient.sendMsg({ type: msgType.updatePatterns, data: patterns });
- };
-
- loadCalendars = calendars => {
- this.setState({ calendars });
- this.msgClient.sendMsg({ type: msgType.updateCalendars, data: calendars });
+ this.msgClient.sendMsg({
+ type: msgType.updatePatterns,
+ data: { id: 'analyze', patterns }
+ }).then(() => this.setState({ patterns }));
};
getCalEvents = (id, start, end) => {
@@ -160,27 +166,10 @@ class CustomAnalyzer extends React.Component {
});
};
- load = () => {
- let colors = gapi.getAuthToken().then(gapi.getColors).then(color => {
- return color.calendar;
- });
- let cals = gapi.getAuthToken().then(gapi.getCalendars);
- Promise.all([colors, cals]).then(([colors, items]) => {
- var cals = {};
- items.forEach(item => {
- cals[item.id] = {
- name: item.summary,
- color: colors[item.colorId],
- //cal: new gapi.GCalendar(item.id, item.summary)
- }});
- this.loadCalendars(cals);
- this.loadPatterns(items.map((item, idx) => {
- return new PatternEntry(item.summary, idx,
- new Pattern(item.id, false, item.summary, item.summary),
- Pattern.anyPattern());
- }));
- });
- };
+ reset = () => {
+ this.loadPatterns([]);
+ this.setState({ startDate: null, endDate: null });
+ }
render() {
const { classes } = this.props;
@@ -191,7 +180,7 @@ class CustomAnalyzer extends React.Component {
<FormControl fullWidth={true}>
<FormGroup>
<Typography variant="h6" component="h1" gutterBottom>
- Event Patterns
+ Analyzed Events
<IconButton
style={{marginBottom: '0.12em', marginLeft: '0.5em'}}
onClick={() => this.newPattern()}><AddCircleIcon /></IconButton>
@@ -224,12 +213,12 @@ class CustomAnalyzer extends React.Component {
<Grid container spacing={16}>
<Grid item md={6} xs={12}>
<FormGroup>
- <Button variant="contained" color="primary" onClick={this.load}>Load</Button>
+ <Button variant="contained" color="primary" onClick={this.analyze}>Analyze</Button>
</FormGroup>
</Grid>
<Grid item md={6} xs={12}>
<FormGroup>
- <Button variant="contained" color="primary" onClick={this.analyze}>Analyze</Button>
+ <Button variant="contained" color="primary" onClick={this.reset}>Reset</Button>
</FormGroup>
</Grid>
</Grid>
@@ -237,7 +226,7 @@ class CustomAnalyzer extends React.Component {
</Grid>
<Grid item md={6} xs={12}>
<Typography variant="h6" component="h1" gutterBottom>
- Graph
+ Results
</Typography>
<PieChart
patternGraphData={this.state.patternGraphData}
diff --git a/src/PatternTable.js b/src/PatternTable.js
index e579921..3e16bbf 100644
--- a/src/PatternTable.js
+++ b/src/PatternTable.js
@@ -43,6 +43,7 @@ class PatternTable extends React.Component {
state = {
page: 0,
rowsPerPage: 5,
+ activePattern: null
};
handleChangePage = (event, page) => {
diff --git a/src/Settings.js b/src/Settings.js
index 11167a0..e071f9e 100644
--- a/src/Settings.js
+++ b/src/Settings.js
@@ -7,6 +7,7 @@ import Button from '@material-ui/core/Button';
import FormControl from '@material-ui/core/FormControl';
import FormGroup from '@material-ui/core/FormGroup';
import Grid from '@material-ui/core/Grid';
+import RefreshIcon from '@material-ui/icons/Refresh';
import AddCircleIcon from '@material-ui/icons/AddCircle';
import IconButton from '@material-ui/core/IconButton';
import Table from '@material-ui/core/Table';
@@ -14,11 +15,28 @@ import TableBody from '@material-ui/core/TableBody';
import TableRow from '@material-ui/core/TableRow';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
+import List from '@material-ui/core/List';
+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 { Pattern, PatternEntry } from './pattern';
+import PatternTable from './PatternTable';
const styles = theme => ({
+ tableHead: {
+ verticalAlign: 'top',
+ textAlign: 'right',
+ lineHeight: '3em',
+ },
+ tableContent: {
+ textAlign: 'left',
+ },
+ calendarList: {
+ maxHeight: 400,
+ overflowY: 'auto'
+ }
});
const STableCell = withStyles(theme => ({
@@ -27,48 +45,194 @@ const STableCell = withStyles(theme => ({
},
}))(TableCell);
+const CompactListItem = withStyles(theme => ({
+ dense: {
+ paddingTop: 0,
+ paddingBottom: 0
+ },
+}))(ListItem);
+
class Settings extends React.Component {
state = {
- isLoggedIn: false
+ isLoggedIn: false,
+ patterns: [],
+ calendars: {},
};
constructor(props) {
super(props);
+ this.msgClient = new MsgClient('main');
gapi.getLoggedIn().then(b => this.setState({ isLoggedIn: b }));
+ this.msgClient.sendMsg({
+ type: msgType.getPatterns,
+ data: { id: 'main' }
+ }).then(msg => {
+ this.setState({ patterns: msg.data.map(p => PatternEntry.revive(p)) });
+ });
+ this.msgClient.sendMsg({ type: msgType.getCalendars, data: { enabledOnly: false } }).then(msg => {
+ this.setState({ calendars: msg.data });
+ });
}
handleLogin = () => {
- gapi.login().then(() => this.setState({ isLoggedIn: true }));
+ gapi.login().then(() => {
+ this.setState({ isLoggedIn: true });
+ this.loadAll(true);
+ });
}
handleLogout = () => {
- gapi.logout().then(() => this.setState({ isLoggedIn: false }));
+ gapi.logout().then(() => {
+ this.setState({ isLoggedIn: false });
+ this.loadPatterns([], 'analyze');
+ });
}
+ handleToggleCalendar = id => {
+ var calendars = {...this.state.calendars};
+ calendars[id].enabled = !calendars[id].enabled;
+ this.msgClient.sendMsg({ type: msgType.updateCalendars, data: calendars }).then(() =>
+ this.setState({ calendars }));
+ }
+
+ loadAll = loadDefaultPatterns => {
+ let colors = gapi.getAuthToken().then(gapi.getColors).then(color => {
+ return color.calendar;
+ });
+ let cals = gapi.getAuthToken().then(gapi.getCalendars);
+ Promise.all([colors, cals]).then(([colors, items]) => {
+ var cals = {};
+ items.forEach(item => {
+ cals[item.id] = {
+ name: item.summary,
+ color: colors[item.colorId],
+ enabled: true
+ //cal: new gapi.GCalendar(item.id, item.summary)
+ }});
+ this.loadCalendars(cals);
+ if (loadDefaultPatterns)
+ {
+ this.loadPatterns(items.map((item, idx) => {
+ return new PatternEntry(item.summary, idx,
+ new Pattern(item.id, false, item.summary, item.summary),
+ Pattern.anyPattern());
+ }), 'main');
+ }
+ });
+ };
+
+ loadCalendars = calendars => {
+ for (let id in this.state.calendars) {
+ if (calendars.hasOwnProperty(id))
+ calendars[id].enabled = this.state.calendars[id].enabled;
+ }
+ this.msgClient.sendMsg({ type: msgType.updateCalendars, data: calendars }).then(() =>
+ this.setState({ calendars }));
+ };
+
+ loadPatterns = (patterns, id) => {
+ this.msgClient.sendMsg({
+ type: msgType.updatePatterns,
+ data: { id, patterns }
+ }).then(() => this.setState({ patterns }));
+ };
+
+ updatePattern = (field, idx, value) => {
+ let patterns = this.state.patterns;
+ patterns[idx][field] = value;
+ this.msgClient.sendMsg({
+ type: msgType.updatePatterns,
+ data: { id: 'main', patterns }
+ }).then(() => this.setState({ patterns }));
+ };
+
+ removePattern = idx => {
+ let patterns = this.state.patterns;
+ patterns.splice(idx, 1);
+ for (let i = 0; i < patterns.length; i++)
+ patterns[i].idx = i;
+ this.msgClient.sendMsg({
+ type: msgType.updatePatterns,
+ data: { id: 'main', patterns }
+ }).then(() => this.setState({ patterns }));
+ };
+
+ newPattern = () => {
+ let patterns = [PatternEntry.defaultPatternEntry(0), ...this.state.patterns];
+ for (let i = 1; i < patterns.length; i++)
+ patterns[i].idx = i;
+ this.msgClient.sendMsg({
+ type: msgType.updatePatterns,
+ data: { id: 'main', patterns }
+ }).then(() => this.setState({ patterns }));
+ };
+
render() {
const { classes } = this.props;
return (
- <Grid container spacing={16}>
- <Grid item md={6} xs={12}>
- <Typography variant="h6" component="h1" gutterBottom>
- General
- </Typography>
- <Table>
- <TableBody>
- <TableRow>
- <STableCell align='right'>Account</STableCell>
- <STableCell align='left'>
- {
- (this.state.isLoggedIn &&
- <Button variant="contained" color="primary" onClick={this.handleLogout}>Logout</Button>) ||
- <Button variant="contained" color="primary" onClick={this.handleLogin}>Login</Button>
- }
- </STableCell>
- </TableRow>
- </TableBody>
- </Table>
- </Grid>
- </Grid>
+ <div>
+ <Typography variant="h6" component="h1" gutterBottom>
+ General
+ </Typography>
+ <Table>
+ <TableBody>
+ <TableRow>
+ <STableCell className={classes.tableHead}>Account</STableCell>
+ <STableCell align='left'>
+ {
+ (this.state.isLoggedIn &&
+ <Button variant="contained" color="primary" onClick={this.handleLogout}>Logout</Button>) ||
+ <Button variant="contained" color="primary" onClick={this.handleLogin}>Login</Button>
+ }
+ </STableCell>
+ </TableRow>
+ <TableRow>
+ <STableCell className={classes.tableHead}>
+ <IconButton
+ style={{marginBottom: '0.12em', marginRight: '0.5em'}}
+ onClick={() => this.loadAll(false)}
+ disabled={!this.state.isLoggedIn}><RefreshIcon /></IconButton>
+ Calendars
+ </STableCell>
+ <STableCell className={classes.tableContent}>
+ {(this.state.isLoggedIn &&
+ <List className={classes.calendarList}>
+ {Object.keys(this.state.calendars).map(id =>
+ <CompactListItem
+ key={id}
+ onClick={() => this.handleToggleCalendar(id)}
+ disableGutters
+ dense button >
+ <Checkbox
+ checked={this.state.calendars[id].enabled}
+ disableRipple />
+ <ListItemText primary={this.state.calendars[id].name} />
+ </CompactListItem>)}
+ </List>) || 'Please Login.'}
+ </STableCell>
+ </TableRow>
+ <TableRow>
+ <STableCell className={classes.tableHead}>
+ <IconButton
+ style={{marginBottom: '0.12em', marginRight: '0.5em'}}
+ onClick={() => this.newPattern()}
+ disabled={!this.state.isLoggedIn}><AddCircleIcon /></IconButton>
+ Tracked Events
+ </STableCell>
+ <STableCell className={classes.tableContent}>
+ {(this.state.isLoggedIn &&
+ <FormControl fullWidth={true}>
+ <PatternTable
+ patterns={this.state.patterns}
+ calendars={this.state.calendars}
+ onRemovePattern={this.removePattern}
+ onUpdatePattern={this.updatePattern} />
+ </FormControl>) || 'Please Login.'}
+ </STableCell>
+ </TableRow>
+ </TableBody>
+ </Table>
+ </div>
);
}
}
diff --git a/src/background.js b/src/background.js
index 177ec68..e9b0f60 100644
--- a/src/background.js
+++ b/src/background.js
@@ -1,7 +1,8 @@
import * as gapi from './gapi';
import { msgType, Msg } from './msg';
-let patterns = [];
+let mainPatterns = [];
+let analyzePatterns = [];
let calendars = {};
let calData = {};
@@ -11,9 +12,18 @@ chrome.runtime.onConnect.addListener(function(port) {
let msg = Msg.inflate(_msg);
console.log(msg);
if (msg.type == msgType.updatePatterns) {
- patterns = msg.data;
+ if (msg.data.id == 'analyze')
+ analyzePatterns = msg.data.patterns;
+ else
+ mainPatterns = msg.data.patterns;
+ port.postMessage(msg.genResp(null));
}
else if (msg.type == msgType.getPatterns) {
+ let patterns;
+ if (msg.data.id == 'analyze')
+ patterns = analyzePatterns;
+ else
+ patterns = mainPatterns;
port.postMessage(msg.genResp(patterns));
}
else if (msg.type == msgType.updateCalendars) {
@@ -22,9 +32,17 @@ chrome.runtime.onConnect.addListener(function(port) {
if (!calData.hasOwnProperty(id))
calData[id] = new gapi.GCalendar(id, calendars[id].summary);
}
+ port.postMessage(msg.genResp(null));
}
else if (msg.type == msgType.getCalendars) {
- port.postMessage(msg.genResp(calendars));
+ let cals = calendars;
+ if (msg.data.enabledOnly)
+ {
+ cals = Object.keys(calendars)
+ .filter(id => calendars[id].enabled)
+ .reduce((res, id) => (res[id] = calendars[id], res), {});
+ }
+ port.postMessage(msg.genResp(cals));
}
else if (msg.type == msgType.getCalEvents) {
calData[msg.data.id].getEvents(new Date(msg.data.start), new Date(msg.data.end))