Allow disabling alerts (#8550)
The unconnected account alert can now be disabled. A "don't show this again" checkbox has been added to the alert, which prevents that alert from being shown in the future. An alert settings page has been added to the settings as well. This page allows the user to disable or enable any alert.feature/default_network_editable
parent
c0489163b5
commit
c4fb514f3d
@ -0,0 +1,54 @@ |
||||
import ObservableStore from 'obs-store' |
||||
|
||||
/** |
||||
* @typedef {Object} AlertControllerInitState |
||||
* @property {Object} alertEnabledness - A map of any alerts that were suppressed keyed by alert ID, where the value |
||||
* is the timestamp of when the user suppressed the alert. |
||||
*/ |
||||
|
||||
/** |
||||
* @typedef {Object} AlertControllerOptions |
||||
* @property {AlertControllerInitState} initState - The initial controller state |
||||
*/ |
||||
|
||||
export const ALERT_TYPES = { |
||||
unconnectedAccount: 'unconnectedAccount', |
||||
} |
||||
|
||||
const defaultState = { |
||||
alertEnabledness: Object.keys(ALERT_TYPES) |
||||
.reduce( |
||||
(alertEnabledness, alertType) => { |
||||
alertEnabledness[alertType] = true |
||||
return alertEnabledness |
||||
}, |
||||
{} |
||||
), |
||||
} |
||||
|
||||
/** |
||||
* Controller responsible for maintaining |
||||
* alert related state |
||||
*/ |
||||
export default class AlertController { |
||||
/** |
||||
* @constructor |
||||
* @param {AlertControllerOptions} [opts] - Controller configuration parameters |
||||
*/ |
||||
constructor (opts = {}) { |
||||
const { initState } = opts |
||||
const state = Object.assign( |
||||
{}, |
||||
defaultState, |
||||
initState, |
||||
) |
||||
this.store = new ObservableStore(state) |
||||
} |
||||
|
||||
setAlertEnabledness (alertId, enabledness) { |
||||
let { alertEnabledness } = this.store.getState() |
||||
alertEnabledness = { ...alertEnabledness } |
||||
alertEnabledness[alertId] = enabledness |
||||
this.store.updateState({ alertEnabledness }) |
||||
} |
||||
} |
@ -0,0 +1,71 @@ |
||||
import React, { useContext } from 'react' |
||||
import PropTypes from 'prop-types' |
||||
import { useDispatch, useSelector } from 'react-redux' |
||||
|
||||
import { ALERT_TYPES } from '../../../../../app/scripts/controllers/alert' |
||||
import { I18nContext } from '../../../contexts/i18n' |
||||
import Tooltip from '../../../components/ui/tooltip-v2' |
||||
import ToggleButton from '../../../components/ui/toggle-button' |
||||
import { setAlertEnabledness } from '../../../store/actions' |
||||
import { getAlertEnabledness } from '../../../ducks/metamask/metamask' |
||||
|
||||
const AlertSettingsEntry = ({ alertId, description, title }) => { |
||||
const t = useContext(I18nContext) |
||||
const dispatch = useDispatch() |
||||
const isEnabled = useSelector((state) => getAlertEnabledness(state)[alertId]) |
||||
|
||||
return ( |
||||
<> |
||||
<span> |
||||
{ title } |
||||
</span> |
||||
<Tooltip |
||||
position="top" |
||||
title={description} |
||||
wrapperClassName="alerts-tab__description" |
||||
> |
||||
<i className="fa fa-info-circle" /> |
||||
</Tooltip> |
||||
<ToggleButton |
||||
offLabel={t('off')} |
||||
onLabel={t('on')} |
||||
onToggle={() => dispatch(setAlertEnabledness(alertId, !isEnabled))} |
||||
value={isEnabled} |
||||
/> |
||||
</> |
||||
) |
||||
} |
||||
|
||||
AlertSettingsEntry.propTypes = { |
||||
alertId: PropTypes.string.isRequired, |
||||
description: PropTypes.string.isRequired, |
||||
title: PropTypes.string.isRequired, |
||||
} |
||||
|
||||
const AlertsTab = () => { |
||||
const t = useContext(I18nContext) |
||||
|
||||
const alertConfig = { |
||||
[ALERT_TYPES.unconnectedAccount]: { |
||||
title: t('alertSettingsUnconnectedAccount'), |
||||
description: t('alertSettingsUnconnectedAccountDescription'), |
||||
}, |
||||
} |
||||
|
||||
return ( |
||||
<div className="alerts-tab__body"> |
||||
{ |
||||
Object.entries(alertConfig).map(([alertId, { title, description }]) => ( |
||||
<AlertSettingsEntry |
||||
alertId={alertId} |
||||
description={description} |
||||
key={alertId} |
||||
title={title} |
||||
/> |
||||
)) |
||||
} |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default AlertsTab |
@ -0,0 +1,28 @@ |
||||
.alerts-tab { |
||||
&__body { |
||||
display: grid; |
||||
grid-template-columns: 8fr 30px max-content; |
||||
grid-template-rows: 1fr 1fr; |
||||
font-size: 14px; |
||||
align-items: center; |
||||
} |
||||
|
||||
&__body > * { |
||||
border-bottom: 1px solid $Grey-100; |
||||
padding: 16px 8px; |
||||
height: 100%; |
||||
} |
||||
|
||||
&__body > :nth-child(1n) { |
||||
padding-left: 32px; |
||||
} |
||||
|
||||
&__body > :nth-child(3n) { |
||||
padding-right: 32px; |
||||
} |
||||
|
||||
&__description { |
||||
display: flex; |
||||
align-items: center; |
||||
} |
||||
} |
@ -0,0 +1 @@ |
||||
export { default } from './alerts-tab' |
Loading…
Reference in new issue