mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
3d0ffc50f8
The inactive timer was being reset upon any change to the preferences store. The intent was only to update the timer when the auto-lock timeout had changed, so the subscription was updated to only update in those cases. There are no indications that this had any effect upon the user. It looks like the preferences store never updates while the extension is unattended, so in practice this may have been harmless. It was still pointless however. This also protects against the possibility of the preferences store being updated while unattended at some point in the future.
147 lines
3.7 KiB
JavaScript
147 lines
3.7 KiB
JavaScript
import ObservableStore from 'obs-store'
|
|
import EventEmitter from 'events'
|
|
|
|
export default class AppStateController extends EventEmitter {
|
|
/**
|
|
* @constructor
|
|
* @param opts
|
|
*/
|
|
constructor (opts = {}) {
|
|
const {
|
|
addUnlockListener,
|
|
isUnlocked,
|
|
initState,
|
|
onInactiveTimeout,
|
|
showUnlockRequest,
|
|
preferencesStore,
|
|
} = opts
|
|
const { preferences } = preferencesStore.getState()
|
|
|
|
super()
|
|
|
|
this.onInactiveTimeout = onInactiveTimeout || (() => {})
|
|
this.store = new ObservableStore(Object.assign({
|
|
timeoutMinutes: 0,
|
|
connectedStatusPopoverHasBeenShown: true,
|
|
}, initState))
|
|
this.timer = null
|
|
|
|
this.isUnlocked = isUnlocked
|
|
this.waitingForUnlock = []
|
|
addUnlockListener(this.handleUnlock.bind(this))
|
|
|
|
this._showUnlockRequest = showUnlockRequest
|
|
|
|
preferencesStore.subscribe(({ preferences }) => {
|
|
const currentState = this.store.getState()
|
|
if (currentState.timeoutMinutes !== preferences.autoLockTimeLimit) {
|
|
this._setInactiveTimeout(preferences.autoLockTimeLimit)
|
|
}
|
|
})
|
|
|
|
this._setInactiveTimeout(preferences.autoLockTimeLimit)
|
|
}
|
|
|
|
/**
|
|
* Get a Promise that resolves when the extension is unlocked.
|
|
* This Promise will never reject.
|
|
*
|
|
* @param {boolean} shouldShowUnlockRequest - Whether the extension notification
|
|
* popup should be opened.
|
|
* @returns {Promise<void>} A promise that resolves when the extension is
|
|
* unlocked, or immediately if the extension is already unlocked.
|
|
*/
|
|
getUnlockPromise (shouldShowUnlockRequest) {
|
|
return new Promise((resolve) => {
|
|
if (this.isUnlocked()) {
|
|
resolve()
|
|
} else {
|
|
this.waitForUnlock(resolve, shouldShowUnlockRequest)
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Adds a Promise's resolve function to the waitingForUnlock queue.
|
|
* Also opens the extension popup if specified.
|
|
*
|
|
* @param {Promise.resolve} resolve - A Promise's resolve function that will
|
|
* be called when the extension is unlocked.
|
|
* @param {boolean} shouldShowUnlockRequest - Whether the extension notification
|
|
* popup should be opened.
|
|
*/
|
|
waitForUnlock (resolve, shouldShowUnlockRequest) {
|
|
this.waitingForUnlock.push({ resolve })
|
|
this.emit('updateBadge')
|
|
if (shouldShowUnlockRequest) {
|
|
this._showUnlockRequest()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Drains the waitingForUnlock queue, resolving all the related Promises.
|
|
*/
|
|
handleUnlock () {
|
|
if (this.waitingForUnlock.length > 0) {
|
|
while (this.waitingForUnlock.length > 0) {
|
|
this.waitingForUnlock.shift().resolve()
|
|
}
|
|
this.emit('updateBadge')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Record that the user has seen the connected status info popover
|
|
*/
|
|
setConnectedStatusPopoverHasBeenShown () {
|
|
this.store.updateState({
|
|
connectedStatusPopoverHasBeenShown: true,
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Sets the last active time to the current time
|
|
* @returns {void}
|
|
*/
|
|
setLastActiveTime () {
|
|
this._resetTimer()
|
|
}
|
|
|
|
/**
|
|
* Sets the inactive timeout for the app
|
|
* @param {number} timeoutMinutes - the inactive timeout in minutes
|
|
* @returns {void}
|
|
* @private
|
|
*/
|
|
_setInactiveTimeout (timeoutMinutes) {
|
|
this.store.updateState({
|
|
timeoutMinutes,
|
|
})
|
|
|
|
this._resetTimer()
|
|
}
|
|
|
|
/**
|
|
* Resets the internal inactive timer
|
|
*
|
|
* If the {@code timeoutMinutes} state is falsy (i.e., zero) then a new
|
|
* timer will not be created.
|
|
*
|
|
* @returns {void}
|
|
* @private
|
|
*/
|
|
_resetTimer () {
|
|
const { timeoutMinutes } = this.store.getState()
|
|
|
|
if (this.timer) {
|
|
clearTimeout(this.timer)
|
|
}
|
|
|
|
if (!timeoutMinutes) {
|
|
return
|
|
}
|
|
|
|
this.timer = setTimeout(() => this.onInactiveTimeout(), timeoutMinutes * 60 * 1000)
|
|
}
|
|
}
|