diff options
Diffstat (limited to 'ui/app/components')
-rw-r--r-- | ui/app/components/main_panel/email_section.js | 97 | ||||
-rw-r--r-- | ui/app/components/main_panel/imap_button.js | 121 | ||||
-rw-r--r-- | ui/app/components/main_panel/main_panel.less | 1 |
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 + + <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 + + <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; |