summaryrefslogtreecommitdiff
path: root/ui/app/components
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/components')
-rw-r--r--ui/app/components/main_panel/email_section.js97
-rw-r--r--ui/app/components/main_panel/imap_button.js121
-rw-r--r--ui/app/components/main_panel/main_panel.less1
3 files changed, 213 insertions, 6 deletions
diff --git a/ui/app/components/main_panel/email_section.js b/ui/app/components/main_panel/email_section.js
index a3ff11c2..2bb5865d 100644
--- a/ui/app/components/main_panel/email_section.js
+++ b/ui/app/components/main_panel/email_section.js
@@ -1,10 +1,57 @@
import React from 'react'
-//import { Button, Glyphicon, Alert } from 'react-bootstrap'
+import { Button, Glyphicon, Alert } from 'react-bootstrap'
+
import SectionLayout from './section_layout'
+import IMAPButton from './imap_button'
+
import Account from 'models/account'
import Spinner from 'components/spinner'
import bitmask from 'lib/bitmask'
+const GENERAL_NOTICES = [
+ "KEYMANAGER_KEY_FOUND", // (address)
+ "KEYMANAGER_KEY_NOT_FOUND", // (address)
+ "KEYMANAGER_LOOKING_FOR_KEY", // (address)
+ "KEYMANAGER_DONE_UPLOADING_KEYS", // (address)
+
+ "SMTP_START_ENCRYPT_AND_SIGN", // (from_addr)
+ "SMTP_END_ENCRYPT_AND_SIGN", // (from_addr)
+ "SMTP_START_SIGN", // (from_addr)
+ "SMTP_END_SIGN", // (from_addr)
+ "SMTP_SEND_MESSAGE_START", // (from_addr)
+ "SMTP_SEND_MESSAGE_SUCCESS" // (from_addr)
+]
+
+const ACCOUNT_NOTICES = [
+ "IMAP_CLIENT_LOGIN", // (username)
+
+ "MAIL_FETCHED_INCOMING", // (userid)
+ "MAIL_MSG_DECRYPTED", // (userid)
+ "MAIL_MSG_DELETED_INCOMING", // (userid)
+ "MAIL_MSG_PROCESSING", // (userid)
+ "MAIL_MSG_SAVED_LOCALLY", // (userid)
+
+ "SMTP_RECIPIENT_ACCEPTED_ENCRYPTED", // (userid, dest)
+ "SMTP_RECIPIENT_ACCEPTED_UNENCRYPTED", // (userid, dest)
+ "SMTP_RECIPIENT_REJECTED", // (userid, dest)
+ "SMTP_SEND_MESSAGE_ERROR" // (userid, dest)
+]
+
+const STATUSES = [
+ "KEYMANAGER_FINISHED_KEY_GENERATION", // (address)
+ "KEYMANAGER_STARTED_KEY_GENERATION", // (address)
+ "SMTP_SERVICE_STARTED",
+ "MAIL_UNREAD_MESSAGES", // (userid, number)
+ "IMAP_SERVICE_STARTED"
+]
+
+const STATUS_ERRORS = [
+ "IMAP_SERVICE_FAILED_TO_START",
+ "IMAP_UNHANDLED_ERROR",
+ "SMTP_SERVICE_FAILED_TO_START",
+ "SMTP_CONNECTION_LOST", // (userid, dest)
+]
+
export default class EmailSection extends React.Component {
static get defaultProps() {return{
@@ -14,17 +61,46 @@ export default class EmailSection extends React.Component {
constructor(props) {
super(props)
this.state = {
- status: null
+ status: 'unknown', // on, off, unknown, wait, disabled, error
+ messages: [],
+ expanded: true
}
+ this.expand = this.expand.bind(this)
this.openKeys = this.openKeys.bind(this)
this.openApp = this.openApp.bind(this)
this.openPrefs = this.openPrefs.bind(this)
+ this.logEvent = this.logEvent.bind(this)
+ }
+
+ componentWillMount() {
+ let events = [].concat(GENERAL_NOTICES, ACCOUNT_NOTICES, STATUSES, STATUS_ERRORS)
+ for (let event of events) {
+ bitmask.events.register(event, this.logEvent)
+ }
+ bitmask.mail.status().then(status => {
+ // either 'running' or 'disabled'
+ let newstatus = 'error'
+ if (status['mail'] == 'running') {
+ newstatus = 'on'
+ } else if (status['mail'] == 'disabled') {
+ newstatus = 'disabled'
+ }
+ this.setState({status: newstatus})
+ })
+ }
+
+ logEvent(event, msg) {
+ console.log("EVENT: " + event, msg)
}
openKeys() {}
openApp() {}
openPrefs() {}
+ expand() {
+ this.setState({expanded: !this.state.expanded})
+ }
+
render () {
//let message = null
//if (this.state.error) {
@@ -34,13 +110,22 @@ export default class EmailSection extends React.Component {
// )
//}
let button = null
- if (this.state.status == 'ready') {
+ let body = null
+ let header = <h1>Mail</h1>
+ if (this.state.status == 'on') {
button = <Button onClick={this.openApp}>Open Email</Button>
}
+ if (this.state.status == 'disabled') {
+ header = <h1>Mail Disabled</h1>
+ }
+ if (this.state.expanded) {
+ body = (
+ <IMAPButton account={this.props.account} />
+ )
+ }
return (
- <SectionLayout icon="envelope" status="on" button={button}>
- <h1>inbox: </h1>
- </SectionLayout>
+ <SectionLayout icon="envelope" status={this.state.status}
+ onExpand={this.expand} buttons={button} header={header} body={body} />
)
}
}
diff --git a/ui/app/components/main_panel/imap_button.js b/ui/app/components/main_panel/imap_button.js
new file mode 100644
index 00000000..98d8bad0
--- /dev/null
+++ b/ui/app/components/main_panel/imap_button.js
@@ -0,0 +1,121 @@
+//
+// Button to show details for configuring mail clients
+//
+
+import React from 'react'
+import { Modal, Form, FormGroup, ControlLabel, FormControl, Col, Label, Button} from 'react-bootstrap'
+import Account from 'models/account'
+import bitmask from 'lib/bitmask'
+
+export default class IMAPButton extends React.Component {
+
+ static get defaultProps() {return{
+ account: null,
+ title: "Connect Mail Client"
+ }}
+
+ constructor(props) {
+ super(props)
+ this.state = {
+ showModal: false,
+ imapPort: '1984',
+ smtpPort: '2013',
+ token: ''
+ }
+ this.onClick = this.onClick.bind(this)
+ this.onClose = this.onClose.bind(this)
+ }
+
+ onClose() {
+ this.setState({showModal: false})
+ }
+
+ onClick() {
+ if (!this.state.token) {
+ bitmask.mail.get_token().then(response => {
+ if (response.user == this.props.account.address) {
+ this.setState({token: response.token})
+ }
+ })
+ }
+ this.setState({showModal: true})
+ }
+
+ componentWillMount() {}
+
+ // don't allow fields to be changed
+ onChange() {}
+
+ render () {
+ let rowStyle = {height: '30px'} // to match bootstrap's input element height
+ let form = null
+ let modal = null
+
+ if (this.state.showModal) {
+ form = (
+ <Form horizontal>
+ <p>
+ You can use any application that supports IMAP to read and send
+ email through Bitmask.
+ </p>
+ <h3>Configuration for Thunderbird</h3>
+ <p>
+ For Thunderbird, you can use the Bitmask extension. Search for
+ "Bitmask" in Thunderbird's add-on manager.
+ </p>
+ <h3>Configuration for other mail clients</h3>
+ <p>
+ Alternately, configure your mail client with the following options:
+ </p>
+ <FormGroup>
+ <Col sm={2} componentClass={ControlLabel}>Username</Col>
+ <Col sm={10}>
+ <FormControl value={this.props.account.address} onChange={this.onChange}/>
+ </Col>
+ </FormGroup>
+ <FormGroup>
+ <Col sm={2} componentClass={ControlLabel}>Password</Col>
+ <Col sm={10}>
+ <FormControl value={this.state.token} onChange={this.onChange}/>
+ </Col>
+ </FormGroup>
+ <FormGroup>
+ <Col sm={2} componentClass={ControlLabel}>IMAP</Col>
+ <Col sm={10} className="center-vertical" style={rowStyle}>
+ <div className="center-item">
+ <Label>Host</Label> localhost
+ &nbsp;&nbsp;&nbsp;
+ <Label>Port</Label> {this.state.imapPort}
+ </div>
+ </Col>
+ </FormGroup>
+ <FormGroup>
+ <Col sm={2} componentClass={ControlLabel}>SMTP</Col>
+ <Col sm={10} className="center-vertical" style={rowStyle}>
+ <div className="center-item">
+ <Label>Host</Label> localhost
+ &nbsp;&nbsp;&nbsp;
+ <Label>Port</Label> {this.state.smtpPort}
+ </div>
+ </Col>
+ </FormGroup>
+ </Form>
+ )
+ modal = (
+ <Modal show={true} onHide={this.onClose}>
+ <Modal.Header closeButton>
+ <Modal.Title>{this.props.title}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ {form}
+ </Modal.Body>
+ </Modal>
+ )
+ }
+
+ return (
+ <Button onClick={this.onClick}>{this.props.title} {modal}</Button>
+ )
+ }
+
+}
diff --git a/ui/app/components/main_panel/main_panel.less b/ui/app/components/main_panel/main_panel.less
index 2e979138..7383a6c8 100644
--- a/ui/app/components/main_panel/main_panel.less
+++ b/ui/app/components/main_panel/main_panel.less
@@ -229,6 +229,7 @@
}
.icon {
padding-right: @section-padding;
+ height: @icon-size;
img {
width: @icon-size;
height: @icon-size;