feat(notifications): Allow notifications to be dismissable

This commit is contained in:
Jackie Luo 2016-11-04 16:30:28 -07:00
parent db84da1eba
commit 3dbd9b7278
3 changed files with 64 additions and 14 deletions

View file

@ -7,7 +7,6 @@ export default class UnstableChannelNotification extends React.Component {
constructor() { constructor() {
super(); super();
this.state = { this.state = {
isDismissed: false,
isUnstableChannel: UpdateChannelStore.currentIsUnstable(), isUnstableChannel: UpdateChannelStore.currentIsUnstable(),
} }
} }
@ -26,31 +25,27 @@ export default class UnstableChannelNotification extends React.Component {
} }
} }
_onDismiss = () => {
this.setState({isDismissed: true});
}
_onReportIssue = () => { _onReportIssue = () => {
NylasEnv.windowEventHandler.openLink({href: 'mailto:support@nylas.com'}) NylasEnv.windowEventHandler.openLink({href: 'mailto:support@nylas.com'})
} }
render() { render() {
if (!this.state.isUnstableChannel || this.state.isDismissed) { if (!this.state.isUnstableChannel) {
return <span /> return <span />
} }
return ( return (
<Notification <Notification
priority="0" priority="0"
displayName={UnstableChannelNotification.displayName}
title="You're on a pre-release channel. We'd love your feedback." title="You're on a pre-release channel. We'd love your feedback."
subtitle="You can switch back to stable from N1's preferences." subtitle="You can switch back to stable from N1's preferences."
icon="volstead-defaultclient.png" icon="volstead-defaultclient.png"
actions={[{ actions={[{
label: "Feedback", label: "Feedback",
fn: this._onReportIssue, fn: this._onReportIssue,
}, {
label: "Dismiss",
fn: this._onDismiss,
}]} }]}
isDismissable
isPermanentlyDismissable
/> />
) )
} }

View file

@ -5,6 +5,7 @@ export default class Notification extends React.Component {
static containerRequired = false; static containerRequired = false;
static propTypes = { static propTypes = {
displayName: React.PropTypes.string,
title: React.PropTypes.string, title: React.PropTypes.string,
subtitle: React.PropTypes.string, subtitle: React.PropTypes.string,
subtitleAction: React.PropTypes.func, subtitleAction: React.PropTypes.func,
@ -12,11 +13,16 @@ export default class Notification extends React.Component {
icon: React.PropTypes.string, icon: React.PropTypes.string,
priority: React.PropTypes.string, priority: React.PropTypes.string,
isError: React.PropTypes.bool, isError: React.PropTypes.bool,
isDismissable: React.PropTypes.bool,
isPermanentlyDismissable: React.PropTypes.bool,
} }
constructor() { constructor(props) {
super() super(props)
this.state = {loadingActions: []} this.state = {
loadingActions: [],
isDismissed: this._isDismissed(),
}
} }
componentDidMount() { componentDidMount() {
@ -27,6 +33,23 @@ export default class Notification extends React.Component {
this.mounted = false; this.mounted = false;
} }
_isDismissed() {
if (this.props.isPermanentlyDismissable) {
return this._numAsks() >= 5
}
return false
}
_numAsks() {
if (!NylasEnv.savedState.dismissedNotificationAsks) {
NylasEnv.savedState.dismissedNotificationAsks = {}
}
if (!NylasEnv.savedState.dismissedNotificationAsks[this.props.displayName]) {
NylasEnv.savedState.dismissedNotificationAsks[this.props.displayName] = 0
}
return NylasEnv.savedState.dismissedNotificationAsks[this.props.displayName]
}
_onClick(actionId, actionFn) { _onClick(actionId, actionFn) {
const result = actionFn(); const result = actionFn();
if (result instanceof Promise) { if (result instanceof Promise) {
@ -44,8 +67,38 @@ export default class Notification extends React.Component {
} }
} }
_subtitle() {
if (this.props.isPermanentlyDismissable && this._numAsks() >= 1) {
return "Don't show this again"
}
return this.props.subtitle
}
_subtitleAction = () => {
if (this.props.isPermanentlyDismissable && this._numAsks() >= 1) {
return () => {
NylasEnv.savedState.dismissedNotificationAsks[this.props.displayName] = 5
this.setState({isDismissed: true})
}
}
return this.props.subtitleAction
}
render() { render() {
if (this.state.isDismissed) return <span />
const actions = this.props.actions || []; const actions = this.props.actions || [];
if (this.props.isDismissable) {
actions.push({
label: 'Dismiss',
fn: () => {
NylasEnv.savedState.dismissedNotificationAsks[this.props.displayName] = this._numAsks() + 1
this.setState({isDismissed: true})
},
})
}
const actionElems = actions.map((action, idx) => { const actionElems = actions.map((action, idx) => {
const id = `action-${idx}`; const id = `action-${idx}`;
let className = 'action' let className = 'action'
@ -64,7 +117,9 @@ export default class Notification extends React.Component {
); );
}) })
const {isError, priority, icon, title, subtitleAction, subtitle} = this.props; const {isError, priority, icon, title} = this.props;
const subtitle = this._subtitle();
const subtitleAction = this._subtitleAction();
let iconEl = null; let iconEl = null;
if (icon) { if (icon) {

@ -1 +1 @@
Subproject commit f43812f2b36ba0861143d9dcfe23e1ef41df7b98 Subproject commit f94dfe30ed9dbb3d0306bb5173d5239b38be02c3