diff --git a/src/App.tsx b/src/App.tsx index 1a8dfd8..0cf35f1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,33 +1,24 @@ import * as React from 'react'; import { connect } from 'react-redux'; -import { HashRouter, NavLink } from 'react-router-dom'; +import { HashRouter } from 'react-router-dom'; import getMuiTheme from 'material-ui/styles/getMuiTheme'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import { amber500, amber700, lightBlue500, darkBlack, white } from 'material-ui/styles/colors'; import AppBar from 'material-ui/AppBar'; import Drawer from 'material-ui/Drawer'; import IconButton from 'material-ui/IconButton'; -import { List, ListItem } from 'material-ui/List'; -import Subheader from 'material-ui/Subheader'; -import Divider from 'material-ui/Divider'; -import ActionCode from 'material-ui/svg-icons/action/code'; -import ActionHome from 'material-ui/svg-icons/action/home'; -import ActionBugReport from 'material-ui/svg-icons/action/bug-report'; -import ActionQuestionAnswer from 'material-ui/svg-icons/action/question-answer'; -import LogoutIcon from 'material-ui/svg-icons/action/power-settings-new'; import NavigationMenu from 'material-ui/svg-icons/navigation/menu'; import './App.css'; +import SideMenu from './SideMenu'; import EteSyncContext from './EteSyncContext'; import { RouteResolver } from './routes'; import * as C from './Constants'; import * as store from './store'; -const logo = require('./images/logo.svg'); - const muiTheme = getMuiTheme({ palette: { primary1Color: amber500, @@ -84,7 +75,6 @@ class App extends React.Component { this.toggleDrawer = this.toggleDrawer.bind(this); this.closeDrawer = this.closeDrawer.bind(this); - this.logout = this.logout.bind(this); } toggleDrawer() { @@ -95,15 +85,8 @@ class App extends React.Component { this.setState({drawerOpen: false}); } - logout() { - store.store.dispatch(store.logout()); - this.closeDrawer(); - } - render() { - const username = (this.props.credentials && this.props.credentials.value) ? - this.props.credentials.value.credentials.email - : C.appName; + const credentials = (this.props.credentials) ? this.props.credentials.value : null; return ( @@ -119,27 +102,7 @@ class App extends React.Component { open={this.state.drawerOpen} onRequestChange={this.toggleDrawer} > -
- -
- {username} -
-
- - - } onClick={this.closeDrawer} /> - - } onClick={this.logout} /> - - External Links - } href={C.homePage} /> - } href={C.faq} /> - } href={C.sourceCode} /> - } href={C.reportIssue} /> - + diff --git a/src/SideMenu.tsx b/src/SideMenu.tsx new file mode 100644 index 0000000..cda786c --- /dev/null +++ b/src/SideMenu.tsx @@ -0,0 +1,125 @@ +import * as React from 'react'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router'; +import { NavLink } from 'react-router-dom'; +import { List, ListItem } from 'material-ui/List'; +import Subheader from 'material-ui/Subheader'; +import Divider from 'material-ui/Divider'; +import ActionCode from 'material-ui/svg-icons/action/code'; +import ActionHome from 'material-ui/svg-icons/action/home'; +import ActionBugReport from 'material-ui/svg-icons/action/bug-report'; +import ActionQuestionAnswer from 'material-ui/svg-icons/action/question-answer'; +import LogoutIcon from 'material-ui/svg-icons/action/power-settings-new'; + +const logo = require('./images/logo.svg'); + +import SideMenuJournals from './SideMenuJournals'; + +import { routeResolver, getPalette } from './App'; + +import { store, logout, JournalsType, fetchJournals, StoreState, CredentialsData } from './store'; + +import * as C from './Constants'; + +interface PropsType { + etesync: CredentialsData | null; + onCloseDrawerRequest: () => void; +} + +interface PropsTypeInner extends PropsType { + journals: JournalsType; +} + +class SideMenu extends React.Component { + props: PropsTypeInner; + + constructor(props: any) { + super(props); + this.logout = this.logout.bind(this); + } + + logout() { + store.dispatch(logout()); + this.props.onCloseDrawerRequest(); + } + + fetchJournals() { + if (this.props.etesync !== null) { + store.dispatch(fetchJournals(this.props.etesync)); + } + } + + componentDidMount() { + this.fetchJournals(); + } + + componentWillReceiveProps(nextProps: PropsTypeInner) { + if (this.props.etesync !== nextProps.etesync) { + this.fetchJournals(); + } + } + + render() { + const username = (this.props.etesync && this.props.etesync.credentials.email) ? + this.props.etesync.credentials.email + : C.appName; + + let loggedInItems; + if (this.props.etesync) { + const journals = (this.props.journals && this.props.journals.value) && ( + + + Journals + + + ); + + loggedInItems = ( + + } onClick={this.logout} /> + {journals} + + ); + } + + return ( + +
+ +
+ {username} +
+
+ + + } onClick={this.props.onCloseDrawerRequest} /> + + {loggedInItems} + + External Links + } href={C.homePage} /> + } href={C.faq} /> + } href={C.sourceCode} /> + } href={C.reportIssue} /> + +
+ ); + } +} + +const mapStateToProps = (state: StoreState, props: PropsType) => { + return { + journals: state.cache.journals, + }; +}; + +export default withRouter(connect( + mapStateToProps +)(SideMenu)); diff --git a/src/SideMenuJournals.tsx b/src/SideMenuJournals.tsx new file mode 100644 index 0000000..6add32f --- /dev/null +++ b/src/SideMenuJournals.tsx @@ -0,0 +1,81 @@ +import * as React from 'react'; +import { Link } from 'react-router-dom'; + +import { ListItem } from 'material-ui/List'; + +import * as EteSync from './api/EteSync'; + +import { routeResolver } from './App'; +import { JournalsData, CredentialsData } from './store'; + +class SideMenuJournals extends React.Component { + props: { + etesync: CredentialsData; + journals: JournalsData; + onItemClick: () => void; + }; + + constructor(props: any) { + super(props); + } + + render() { + const derived = this.props.etesync.encryptionKey; + const journalMap = this.props.journals.reduce( + (ret, journal) => { + if (journal.key) { + const key = 'UNSUPPORTED'; + ret[key] = ret[key] || []; + ret[key].push( + + {journal.uid.slice(0, 20)} + + ); + } else { + let cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version); + let info = journal.getInfo(cryptoManager); + ret[info.type] = ret[info.type] || []; + ret[info.type].push( + + + {info.displayName} ({journal.uid.slice(0, 5)}) + + + ); + } + + return ret; + }, + { CALENDAR: [], + ADDRESS_BOOK: [], + UNSUPPORTED: [] as Array}); + + return ( + + + + + + { journalMap.UNSUPPORTED && ( + + )} + + ); + } +} + +export default SideMenuJournals;