diff --git a/internal_packages/composer-signature/images/ic-settings-signatures-win32@2x.png b/internal_packages/composer-signature/images/ic-settings-signatures-win32@2x.png
deleted file mode 100644
index 1b5d61666..000000000
Binary files a/internal_packages/composer-signature/images/ic-settings-signatures-win32@2x.png and /dev/null differ
diff --git a/internal_packages/composer-signature/images/ic-settings-signatures@2x.png b/internal_packages/composer-signature/images/ic-settings-signatures@2x.png
deleted file mode 100755
index a0f4e7144..000000000
Binary files a/internal_packages/composer-signature/images/ic-settings-signatures@2x.png and /dev/null differ
diff --git a/internal_packages/composer-signature/lib/main.es6 b/internal_packages/composer-signature/lib/main.es6
index 5aaa35a7e..7dd3c3b90 100644
--- a/internal_packages/composer-signature/lib/main.es6
+++ b/internal_packages/composer-signature/lib/main.es6
@@ -1,7 +1,7 @@
-import {PreferencesUIStore, ExtensionRegistry} from 'nylas-exports';
+import {PreferencesUIStore, ExtensionRegistry, SignatureStore, ComponentRegistry} from 'nylas-exports';
import SignatureComposerExtension from './signature-composer-extension';
-import SignatureStore from './signature-store';
+import SignatureComposerDropdown from './signature-composer-dropdown';
import PreferencesSignatures from "./preferences-signatures";
export function activate() {
@@ -14,12 +14,18 @@ export function activate() {
ExtensionRegistry.Composer.register(SignatureComposerExtension);
PreferencesUIStore.registerPreferencesTab(this.preferencesTab);
SignatureStore.activate();
+
+ ComponentRegistry.register(SignatureComposerDropdown, {
+ role: 'Composer:FromFieldComponents',
+ });
}
export function deactivate() {
ExtensionRegistry.Composer.unregister(SignatureComposerExtension);
PreferencesUIStore.unregisterPreferencesTab(this.preferencesTab.sectionId);
SignatureStore.deactivate();
+
+ ComponentRegistry.unregister(SignatureComposerDropdown);
}
export function serialize() {
diff --git a/internal_packages/composer-signature/lib/preferences-signatures.jsx b/internal_packages/composer-signature/lib/preferences-signatures.jsx
index bbe91b04d..e87f5ede0 100644
--- a/internal_packages/composer-signature/lib/preferences-signatures.jsx
+++ b/internal_packages/composer-signature/lib/preferences-signatures.jsx
@@ -1,121 +1,210 @@
import React from 'react';
-import {Contenteditable} from 'nylas-component-kit';
-import {AccountStore} from 'nylas-exports';
-import SignatureStore from './signature-store';
-import SignatureActions from './signature-actions';
+import _ from 'underscore';
+import {
+ Flexbox,
+ RetinaImg,
+ EditableList,
+ Contenteditable,
+ MultiselectDropdown,
+} from 'nylas-component-kit';
+import {AccountStore, SignatureStore, Actions} from 'nylas-exports';
+
export default class PreferencesSignatures extends React.Component {
static displayName = 'PreferencesSignatures';
- constructor(props) {
- super(props);
- this.state = this._getStateFromStores();
+ constructor() {
+ super()
+ this.state = this._getStateFromStores()
}
componentDidMount() {
- this.usub = AccountStore.listen(this._onChange);
+ this.unsubscribers = [
+ SignatureStore.listen(this._onChange),
+ ]
}
componentWillUnmount() {
- this.usub();
+ this.unsubscribers.forEach(unsubscribe => unsubscribe());
}
+
_onChange = () => {
- this.setState(this._getStateFromStores());
+ this.setState(this._getStateFromStores())
}
_getStateFromStores() {
- const accounts = AccountStore.accounts();
- const state = this.state || {};
-
- let {currentAccountId} = state;
- if (!accounts.find(acct => acct.id === currentAccountId)) {
- currentAccountId = accounts[0].id;
- }
+ const signatures = SignatureStore.getSignatures()
+ const accounts = AccountStore.accounts()
+ const selected = SignatureStore.selectedSignature()
+ const defaults = SignatureStore.getDefaults()
return {
- accounts,
- currentAccountId,
- currentSignature: SignatureStore.signatureForAccountId(currentAccountId),
- editAsHTML: state.editAsHTML,
- };
+ signatures: signatures,
+ selectedSignature: selected,
+ defaults: defaults,
+ accounts: accounts,
+ editAsHTML: this.state ? this.state.editAsHTML : false,
+ }
+ }
+
+
+ _onCreateButtonClick = () => {
+ this._onAddSignature()
+ }
+
+ _onAddSignature = () => {
+ Actions.addSignature()
+ }
+
+ _onDeleteSignature = (signature) => {
+ Actions.removeSignature(signature)
+ }
+
+ _onEditSignature = (edit) => {
+ let editedSig;
+ if (typeof edit === "object") {
+ editedSig = {
+ title: this.state.selectedSignature.title,
+ body: edit.target.value,
+ }
+ } else {
+ editedSig = {
+ title: edit,
+ body: this.state.selectedSignature.body,
+ }
+ }
+ Actions.updateSignature(editedSig, this.state.selectedSignature.id)
+ }
+
+ _onSelectSignature = (sig) => {
+ Actions.selectSignature(sig.id)
+ }
+
+ _onToggleAccount = (accountId) => {
+ Actions.toggleAccount(accountId)
+ }
+
+ _onToggleEditAsHTML = () => {
+ const toggled = !this.state.editAsHTML
+ this.setState({editAsHTML: toggled})
+ }
+
+ _renderListItemContent = (sig) => {
+ return sig.title
+ }
+
+ _renderSignatureToolbar() {
+ return (
+
+
+ Default for: {this._renderAccountPicker()}
+
+
+
+
+
+
+ )
+ }
+
+ _selectItemKey = (account) => {
+ return account.accountId
+ }
+
+ _isChecked = (account) => {
+ if (this.state.defaults[account.accountId] === this.state.selectedSignature.id) return true
+ return false
+ }
+
+ _numSelected() {
+ const sel = _.filter(this.state.accounts, (account) => {
+ return this._isChecked(account)
+ })
+ const numSelected = sel.length
+ return numSelected.toString() + (numSelected === 1 ? " Account" : " Accounts")
}
_renderAccountPicker() {
- const options = this.state.accounts.map(account =>
-
- );
-
+ const buttonText = this._numSelected()
return (
-
- );
+
+ )
}
_renderEditableSignature() {
+ const selectedBody = this.state.selectedSignature ? this.state.selectedSignature.body : ""
return (
- );
+ )
}
_renderHTMLSignature() {
return (
);
}
- _onEditSignature = (event) => {
- const html = event.target.value;
- this.setState({currentSignature: html});
-
- SignatureActions.setSignatureForAccountId({
- accountId: this.state.currentAccountId,
- signature: html,
- });
- }
-
- _onSelectAccount = (event) => {
- const accountId = event.target.value;
- this.setState({
- currentSignature: SignatureStore.signatureForAccountId(accountId),
- currentAccountId: accountId,
- });
- }
-
- _renderModeToggle() {
- const label = this.state.editAsHTML ? "Edit live preview" : "Edit raw HTML";
- const action = () => {
- this.setState({editAsHTML: !this.state.editAsHTML});
- return;
- };
-
+ _renderSignatures() {
+ const sigArr = _.values(this.state.signatures)
+ if (sigArr.length === 0) {
+ return (
+
+
+
No signatures
+
+
+ );
+ }
return (
- {label}
- );
+
+
+
+ {this.state.editAsHTML ? this._renderHTMLSignature() : this._renderEditableSignature()}
+ {this._renderSignatureToolbar()}
+
+
+ )
}
render() {
- const rawText = this.state.editAsHTML ? "Raw HTML " : "";
return (
-
-
- {rawText}Signature for: {this._renderAccountPicker()}
-
-
- {this.state.editAsHTML ? this._renderHTMLSignature() : this._renderEditableSignature()}
-
- {this._renderModeToggle()}
-
+
+
+ {this._renderSignatures()}
+
+
)
}
}
diff --git a/internal_packages/composer-signature/lib/signature-actions.es6 b/internal_packages/composer-signature/lib/signature-actions.es6
deleted file mode 100644
index 03578901b..000000000
--- a/internal_packages/composer-signature/lib/signature-actions.es6
+++ /dev/null
@@ -1,12 +0,0 @@
-import Reflux from 'reflux';
-
-const ActionNames = [
- 'setSignatureForAccountId',
-];
-
-const Actions = Reflux.createActions(ActionNames);
-ActionNames.forEach((name) => {
- Actions[name].sync = true;
-});
-
-export default Actions;
diff --git a/internal_packages/composer-signature/lib/signature-composer-dropdown.jsx b/internal_packages/composer-signature/lib/signature-composer-dropdown.jsx
new file mode 100644
index 000000000..be99ead0a
--- /dev/null
+++ b/internal_packages/composer-signature/lib/signature-composer-dropdown.jsx
@@ -0,0 +1,145 @@
+import {
+ React,
+ Actions,
+ SignatureStore,
+} from 'nylas-exports'
+
+import {
+ Menu,
+ RetinaImg,
+ ButtonDropdown,
+} from 'nylas-component-kit'
+import SignatureUtils from './signature-utils'
+import _ from 'underscore'
+
+
+export default class SignatureComposerDropdown extends React.Component {
+ static displayName = 'SignatureComposerDropdown'
+
+ static containerRequired = false
+
+ static propTypes = {
+ draft: React.PropTypes.object.isRequired,
+ session: React.PropTypes.object.isRequired,
+ currentAccount: React.PropTypes.object,
+ accounts: React.PropTypes.array,
+ }
+
+ constructor() {
+ super()
+ this.state = this._getStateFromStores()
+ }
+
+ componentDidMount = () => {
+ this.unsubscribers = [
+ SignatureStore.listen(this._onChange),
+ ]
+ }
+
+ componentDidUpdate(previousProps) {
+ if (previousProps.currentAccount.accountId !== this.props.currentAccount.accountId) {
+ const newAccountDefaultSignature = SignatureStore.signatureForAccountId(this.props.currentAccount.accountId)
+ this._changeSignature(newAccountDefaultSignature)
+ }
+ }
+
+ componentWillUnmount() {
+ this.unsubscribers.forEach(unsubscribe => unsubscribe())
+ }
+
+ _onChange = () => {
+ this.setState(this._getStateFromStores())
+ }
+
+
+ _getStateFromStores() {
+ const signatures = SignatureStore.getSignatures()
+ return {
+ signatures: signatures,
+ }
+ }
+
+ _renderSigItem = (sigItem) => {
+ return (
+ {sigItem.title}
+ )
+ }
+
+ _changeSignature = (sig) => {
+ let body;
+ if (sig) {
+ body = SignatureUtils.applySignature(this.props.draft.body, sig.body)
+ } else {
+ body = SignatureUtils.applySignature(this.props.draft.body, '')
+ }
+ this.props.session.changes.add({body})
+ }
+
+ _isSelected = (sigObj) => {
+ // http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
+ const escapeRegExp = (str) => {
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
+ }
+ const signatureRegex = new RegExp(escapeRegExp(`${sigObj.body}`))
+ const signatureLocation = signatureRegex.exec(this.props.draft.body)
+ if (signatureLocation) return true
+ return false
+ }
+
+ _onClickNoSignature = () => {
+ this._changeSignature({body: ''})
+ }
+
+ _onClickEditSignatures() {
+ Actions.switchPreferencesTab('Signatures')
+ Actions.openPreferences()
+ }
+
+ _renderSignatures() {
+ const header = [No signature
]
+ const footer = [Edit Signatures...
]
+
+ const sigItems = _.values(this.state.signatures)
+ return (
+