diff --git a/src/actions/settings.js b/src/actions/settings.js index afd189d4..dae9f335 100644 --- a/src/actions/settings.js +++ b/src/actions/settings.js @@ -15,6 +15,7 @@ export const setDeveloperMode = (developerMode: boolean) => saveSettings({ devel export const setSentryLogs = (sentryLogs: boolean) => saveSettings({ sentryLogs }) export const setShareAnalytics = (shareAnalytics: boolean) => saveSettings({ shareAnalytics }) export const setMarketIndicator = (marketIndicator: *) => saveSettings({ marketIndicator }) +export const setAutoLockTimeout = (autoLockTimeout: *) => saveSettings({ autoLockTimeout }) export const setCounterValue = (counterValue: string) => saveSettings({ counterValue, diff --git a/src/components/Idler.js b/src/components/Idler.js new file mode 100644 index 00000000..12444110 --- /dev/null +++ b/src/components/Idler.js @@ -0,0 +1,66 @@ +// @flow + +import { PureComponent } from 'react' +import { createStructuredSelector } from 'reselect' +import { connect } from 'react-redux' +import { hasPasswordSelector, autoLockTimeoutSelector } from 'reducers/settings' +import debounce from 'lodash/debounce' +import { lock } from 'reducers/application' + +type Props = { + autoLockTimeout: number, + hasPassword: boolean, + lock: Function, +} + +const mapStateToProps = createStructuredSelector({ + autoLockTimeout: autoLockTimeoutSelector, + hasPassword: hasPasswordSelector, +}) + +const mapDispatchToProps = { + lock, +} + +class Idler extends PureComponent { + componentDidMount() { + window.addEventListener('keydown', this.debounceOnChange) + window.addEventListener('mouseover', this.debounceOnChange) + this.interval = setInterval(this.checkForAutoLock, 10000) + } + + componentWillUnmount() { + window.removeEventListener('keydown', this.debounceOnChange) + window.removeEventListener('mouseover', this.debounceOnChange) + clearInterval(this.interval) + this.debounceOnChange.cancel() + } + + interval: IntervalID + + lastAction: number = -1 + + debounceOnChange = debounce(_ => this.idleTimeHandler(), 1000) + + checkForAutoLock = _ => { + const timeout = this.props.autoLockTimeout + if (this.props.hasPassword && timeout && timeout !== -1) { + if (Date.now() - (this.lastAction + timeout * 60000) > 0) { + this.props.lock() + } + } + } + + idleTimeHandler = _ => { + this.lastAction = Date.now() + } + + render() { + return null + } +} + +export default connect( + mapStateToProps, + mapDispatchToProps, +)(Idler) diff --git a/src/components/SettingsPage/PasswordAutoLockSelect.js b/src/components/SettingsPage/PasswordAutoLockSelect.js new file mode 100644 index 00000000..556fa845 --- /dev/null +++ b/src/components/SettingsPage/PasswordAutoLockSelect.js @@ -0,0 +1,63 @@ +// @flow + +import React, { PureComponent } from 'react' +import { translate } from 'react-i18next' +import { createStructuredSelector } from 'reselect' +import { connect } from 'react-redux' +import { setAutoLockTimeout, saveSettings } from 'actions/settings' +import Select from 'components/base/Select' +import type { T } from 'types/common' +import { autoLockTimeoutSelector } from 'reducers/settings' + +type Props = { + autoLockTimeout: string, + setAutoLockTimeout: (?number) => void, + t: T, +} + +const mapStateToProps = createStructuredSelector({ + autoLockTimeout: autoLockTimeoutSelector, +}) + +const mapDispatchToProps = { + saveSettings, + setAutoLockTimeout, +} + +class PasswordAutoLockSelect extends PureComponent { + handleChangeTimeout = ({ value: timeoutKey }: *) => { + this.props.setAutoLockTimeout(+timeoutKey) + } + + timeouts = [ + { value: 1, label: `1 ${this.props.t('app:time.minute')}` }, + { value: 10, label: `10 ${this.props.t('app:time.minute')}s` }, + { value: 30, label: `30 ${this.props.t('app:time.minute')}s` }, + { value: 60, label: `1 ${this.props.t('app:time.hour')}` }, + { value: -1, label: this.props.t(`app:common.never`) }, + ] + + render() { + const { autoLockTimeout } = this.props + const currentTimeout = this.timeouts.find(l => l.value === autoLockTimeout) + + return ( +