mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-02-20 22:23:53 +08:00
feat(tracking): sticky tracking state and consolidate component
This commit is contained in:
parent
73bc277d68
commit
9ad088f899
4 changed files with 160 additions and 90 deletions
|
@ -1,8 +1,8 @@
|
|||
import {DraftStore, React, Actions, NylasAPI, DatabaseStore, Message, Rx} from 'nylas-exports'
|
||||
import {RetinaImg} from 'nylas-component-kit'
|
||||
// import {DraftStore, React, Actions, NylasAPI, DatabaseStore, Message, Rx} from 'nylas-exports'
|
||||
import {React} from 'nylas-exports'
|
||||
import {MetadataComposerToggleButton} from 'nylas-component-kit'
|
||||
import {PLUGIN_ID, PLUGIN_NAME} from './link-tracking-constants'
|
||||
|
||||
|
||||
export default class LinkTrackingButton extends React.Component {
|
||||
static displayName = 'LinkTrackingButton';
|
||||
|
||||
|
@ -10,55 +10,26 @@ export default class LinkTrackingButton extends React.Component {
|
|||
draftClientId: React.PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {enabled: false};
|
||||
_title(enabled) {
|
||||
const dir = enabled ? "Disable" : "Enable";
|
||||
return `${dir} link tracking`
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const query = DatabaseStore.findBy(Message, {clientId: this.props.draftClientId});
|
||||
this._subscription = Rx.Observable.fromQuery(query).subscribe(this.setStateFromDraft);
|
||||
_errorMessage(error) {
|
||||
return `Sorry, we were unable to save your link tracking settings. ${error.message}`
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._subscription.dispose();
|
||||
}
|
||||
|
||||
setStateFromDraft = (draft)=> {
|
||||
if (!draft) return;
|
||||
const metadata = draft.metadataForPluginId(PLUGIN_ID);
|
||||
this.setState({enabled: metadata ? metadata.tracked : false});
|
||||
};
|
||||
|
||||
_onClick = ()=> {
|
||||
const currentlyEnabled = this.state.enabled;
|
||||
|
||||
// write metadata into the draft to indicate tracked state
|
||||
DraftStore.sessionForClientId(this.props.draftClientId).then((session) => {
|
||||
const draft = session.draft();
|
||||
|
||||
NylasAPI.authPlugin(PLUGIN_ID, PLUGIN_NAME, draft.accountId)
|
||||
.then(() => {
|
||||
Actions.setMetadata(draft, PLUGIN_ID, currentlyEnabled ? null : {tracked: true});
|
||||
})
|
||||
.catch((error)=> {
|
||||
NylasEnv.reportError(error);
|
||||
NylasEnv.showErrorDialog(`Sorry, we were unable to save your link tracking settings. ${error.message}`);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const title = this.state.enabled ? "Disable" : "Enable"
|
||||
return (
|
||||
<button
|
||||
title={`${title} link tracking`}
|
||||
className={`btn btn-toolbar ${this.state.enabled ? "btn-enabled" : ""}`}
|
||||
onClick={this._onClick}>
|
||||
<RetinaImg
|
||||
name="icon-composer-linktracking.png"
|
||||
mode={RetinaImg.Mode.ContentIsMask} />
|
||||
</button>
|
||||
<MetadataComposerToggleButton
|
||||
title={this._title}
|
||||
iconName="icon-composer-linktracking.png"
|
||||
pluginId={PLUGIN_ID}
|
||||
pluginName={PLUGIN_NAME}
|
||||
metadataKey="tracked"
|
||||
stickyToggle
|
||||
errorMessage={this._errorMessage}
|
||||
draftClientId={this.props.draftClientId} />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +1,35 @@
|
|||
import {DraftStore, React, Actions, NylasAPI, DatabaseStore, Message, Rx} from 'nylas-exports'
|
||||
import {RetinaImg} from 'nylas-component-kit'
|
||||
// import {DraftStore, React, Actions, NylasAPI, DatabaseStore, Message, Rx} from 'nylas-exports'
|
||||
import {React} from 'nylas-exports'
|
||||
import {MetadataComposerToggleButton} from 'nylas-component-kit'
|
||||
import {PLUGIN_ID, PLUGIN_NAME} from './open-tracking-constants'
|
||||
|
||||
export default class OpenTrackingButton extends React.Component {
|
||||
|
||||
static displayName = 'OpenTrackingButton';
|
||||
|
||||
static propTypes = {
|
||||
draftClientId: React.PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {enabled: false};
|
||||
_title(enabled) {
|
||||
const dir = enabled ? "Disable" : "Enable";
|
||||
return `${dir} read receipts`
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const query = DatabaseStore.findBy(Message, {clientId: this.props.draftClientId});
|
||||
this._subscription = Rx.Observable.fromQuery(query).subscribe(this.setStateFromDraft)
|
||||
_errorMessage(error) {
|
||||
return `Sorry, we were unable to save your read receipt settings. ${error.message}`
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._subscription.dispose();
|
||||
}
|
||||
|
||||
setStateFromDraft = (draft)=> {
|
||||
if (!draft) return;
|
||||
const metadata = draft.metadataForPluginId(PLUGIN_ID);
|
||||
this.setState({enabled: metadata ? metadata.tracked : false});
|
||||
};
|
||||
|
||||
_onClick=()=> {
|
||||
const currentlyEnabled = this.state.enabled;
|
||||
|
||||
// write metadata into the draft to indicate tracked state
|
||||
DraftStore.sessionForClientId(this.props.draftClientId).then((session)=> {
|
||||
const draft = session.draft();
|
||||
|
||||
NylasAPI.authPlugin(PLUGIN_ID, PLUGIN_NAME, draft.accountId)
|
||||
.then(() => {
|
||||
Actions.setMetadata(draft, PLUGIN_ID, currentlyEnabled ? null : {tracked: true});
|
||||
})
|
||||
.catch((error)=> {
|
||||
NylasEnv.reportError(error);
|
||||
NylasEnv.showErrorDialog(`Sorry, we were unable to save your read receipt settings. ${error.message}`);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const title = this.state.enabled ? "Disable" : "Enable";
|
||||
return (<button className={`btn btn-toolbar ${this.state.enabled ? "btn-enabled" : ""}`}
|
||||
onClick={this._onClick} title={`${title} read receipts`}>
|
||||
<RetinaImg url="nylas://open-tracking/assets/icon-composer-eye@2x.png"
|
||||
mode={RetinaImg.Mode.ContentIsMask} />
|
||||
</button>)
|
||||
return (
|
||||
<MetadataComposerToggleButton
|
||||
title={this._title}
|
||||
iconUrl="nylas://open-tracking/assets/icon-composer-eye@2x.png"
|
||||
pluginId={PLUGIN_ID}
|
||||
pluginName={PLUGIN_NAME}
|
||||
metadataKey="tracked"
|
||||
stickyToggle
|
||||
errorMessage={this._errorMessage}
|
||||
draftClientId={this.props.draftClientId} />
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
123
src/components/metadata-composer-toggle-button.jsx
Normal file
123
src/components/metadata-composer-toggle-button.jsx
Normal file
|
@ -0,0 +1,123 @@
|
|||
import {DraftStore, React, Actions, NylasAPI, DatabaseStore, Message, Rx} from 'nylas-exports'
|
||||
import {RetinaImg} from 'nylas-component-kit'
|
||||
import classnames from 'classnames'
|
||||
|
||||
export default class MetadataComposerToggleButton extends React.Component {
|
||||
|
||||
static displayName = 'MetadataComposerToggleButton';
|
||||
|
||||
static propTypes = {
|
||||
title: React.PropTypes.func.isRequired,
|
||||
iconUrl: React.PropTypes.string,
|
||||
iconName: React.PropTypes.string,
|
||||
pluginId: React.PropTypes.string.isRequired,
|
||||
pluginName: React.PropTypes.string.isRequired,
|
||||
metadataKey: React.PropTypes.string.isRequired,
|
||||
stickyToggle: React.PropTypes.bool,
|
||||
errorMessage: React.PropTypes.func.isRequired,
|
||||
draftClientId: React.PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
stickyToggle: false,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
enabled: false,
|
||||
isSetup: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._mounted = true;
|
||||
const query = DatabaseStore.findBy(Message, {clientId: this.props.draftClientId});
|
||||
this._subscription = Rx.Observable.fromQuery(query).subscribe(this._onDraftChange)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._mounted = false
|
||||
this._subscription.dispose();
|
||||
}
|
||||
|
||||
_configKey() {
|
||||
return `plugins.${this.props.pluginId}.defaultOn`
|
||||
}
|
||||
|
||||
_isDefaultOn() {
|
||||
return NylasEnv.config.get(this._configKey())
|
||||
}
|
||||
|
||||
_onDraftChange = (draft)=> {
|
||||
if (!this._mounted || !draft) { return; }
|
||||
const metadata = draft.metadataForPluginId(this.props.pluginId);
|
||||
if (!metadata) {
|
||||
if (!this.state.isSetup) {
|
||||
if (this._isDefaultOn()) {
|
||||
this._setMetadataValueTo(true)
|
||||
}
|
||||
this.setState({isSetup: true})
|
||||
}
|
||||
} else {
|
||||
this.setState({enabled: metadata.tracked, isSetup: true});
|
||||
}
|
||||
};
|
||||
|
||||
_setMetadataValueTo(enabled) {
|
||||
const newValue = {}
|
||||
newValue[this.props.metadataKey] = enabled
|
||||
this.setState({enabled, pending: true});
|
||||
const metadataValue = enabled ? newValue : null
|
||||
// write metadata into the draft to indicate tracked state
|
||||
return DraftStore.sessionForClientId(this.props.draftClientId).then((session)=> {
|
||||
const draft = session.draft();
|
||||
|
||||
return NylasAPI.authPlugin(this.props.pluginId, this.props.pluginName, draft.accountId)
|
||||
.then(() => {
|
||||
Actions.setMetadata(draft, this.props.pluginId, metadataValue);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({enabled: false});
|
||||
NylasEnv.reportError(error);
|
||||
NylasEnv.showErrorDialog(this.props.errorMessage(error));
|
||||
})
|
||||
}).finally(() => {
|
||||
this.setState({pending: false})
|
||||
});
|
||||
}
|
||||
|
||||
_onClick = () => {
|
||||
// Toggle.
|
||||
if (this.state.pending) { return; }
|
||||
if (this.props.stickyToggle) {
|
||||
NylasEnv.config.set(this._configKey(), !this.state.enabled)
|
||||
}
|
||||
this._setMetadataValueTo(!this.state.enabled)
|
||||
};
|
||||
|
||||
render() {
|
||||
const title = this.props.title(this.state.enabled)
|
||||
|
||||
const className = classnames({
|
||||
"btn": true,
|
||||
"btn-toolbar": true,
|
||||
"btn-pending": this.state.pending,
|
||||
"btn-enabled": this.state.enabled,
|
||||
});
|
||||
|
||||
const attrs = {}
|
||||
if (this.props.iconUrl) {
|
||||
attrs.url = this.props.iconUrl
|
||||
} else if (this.props.iconName) {
|
||||
attrs.name = this.props.iconName
|
||||
}
|
||||
|
||||
return (
|
||||
<button className={className} onClick={this._onClick} title={title}>
|
||||
<RetinaImg {...attrs} mode={RetinaImg.Mode.ContentIsMask} />
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,6 +32,7 @@ class NylasComponentKit
|
|||
@load "MultiselectActionBar", 'multiselect-action-bar'
|
||||
@load "InjectedComponentSet", 'injected-component-set'
|
||||
@load "TimeoutTransitionGroup", 'timeout-transition-group'
|
||||
@load "MetadataComposerToggleButton", 'metadata-composer-toggle-button'
|
||||
@load "ConfigPropContainer", "config-prop-container"
|
||||
@load "DisclosureTriangle", "disclosure-triangle"
|
||||
@load "EditableList", "editable-list"
|
||||
|
|
Loading…
Reference in a new issue