diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/manifest.json | 2 | ||||
-rw-r--r-- | app/scripts/config.js | 3 | ||||
-rw-r--r-- | app/scripts/inpage.js | 18 | ||||
-rw-r--r-- | app/scripts/metamask-controller.js | 33 | ||||
-rw-r--r-- | app/scripts/notice-controller.js | 96 |
5 files changed, 132 insertions, 20 deletions
diff --git a/app/manifest.json b/app/manifest.json index b9d3735ad..f53c3b8b1 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "MetaMask", "short_name": "Metamask", - "version": "2.13.10", + "version": "2.14.0", "manifest_version": 2, "author": "https://metamask.io", "description": "Ethereum Browser Extension", diff --git a/app/scripts/config.js b/app/scripts/config.js index 9a0f2a50b..e09206c5f 100644 --- a/app/scripts/config.js +++ b/app/scripts/config.js @@ -1,6 +1,5 @@ const MAINET_RPC_URL = 'https://mainnet.infura.io/metamask' const TESTNET_RPC_URL = 'https://ropsten.infura.io/metamask' -const MORDEN_RPC_URL = 'https://morden.infura.io/metamask' const DEFAULT_RPC_URL = TESTNET_RPC_URL global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' @@ -11,6 +10,6 @@ module.exports = { default: DEFAULT_RPC_URL, mainnet: MAINET_RPC_URL, testnet: TESTNET_RPC_URL, - morden: MORDEN_RPC_URL, + morden: TESTNET_RPC_URL, }, } diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js index 68c6165c8..42332d92e 100644 --- a/app/scripts/inpage.js +++ b/app/scripts/inpage.js @@ -2,8 +2,8 @@ cleanContextForImports() require('web3/dist/web3.min.js') const LocalMessageDuplexStream = require('post-message-stream') -const PingStream = require('ping-pong-stream/ping') -const endOfStream = require('end-of-stream') +// const PingStream = require('ping-pong-stream/ping') +// const endOfStream = require('end-of-stream') const setupDappAutoReload = require('./lib/auto-reload.js') const MetamaskInpageProvider = require('./lib/inpage-provider.js') restoreContextAfterImports() @@ -40,13 +40,15 @@ reloadStream.once('data', triggerReload) // setup ping timeout autoreload // LocalMessageDuplexStream does not self-close, so reload if pingStream fails -var pingChannel = inpageProvider.multiStream.createStream('pingpong') -var pingStream = new PingStream({ objectMode: true }) +// var pingChannel = inpageProvider.multiStream.createStream('pingpong') +// var pingStream = new PingStream({ objectMode: true }) // wait for first successful reponse -metamaskStream.once('_data', function () { - pingStream.pipe(pingChannel).pipe(pingStream) -}) -endOfStream(pingStream, triggerReload) + +// disable pingStream until https://github.com/MetaMask/metamask-plugin/issues/746 is resolved more gracefully +// metamaskStream.once('data', function(){ +// pingStream.pipe(pingChannel).pipe(pingStream) +// }) +// endOfStream(pingStream, triggerReload) // set web3 defaultAcount inpageProvider.publicConfigStore.subscribe(function (state) { diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index ae761c753..4b8fa4323 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -2,6 +2,7 @@ const extend = require('xtend') const EthStore = require('eth-store') const MetaMaskProvider = require('web3-provider-engine/zero.js') const KeyringController = require('./keyring-controller') +const NoticeController = require('./notice-controller') const messageManager = require('./lib/message-manager') const HostStore = require('./lib/remote-store.js').HostStore const Web3 = require('web3') @@ -22,6 +23,13 @@ module.exports = class MetamaskController { configManager: this.configManager, getNetwork: this.getStateNetwork.bind(this), }) + // notices + this.noticeController = new NoticeController({ + configManager: this.configManager, + }) + this.noticeController.updateNoticesList() + // to be uncommented when retrieving notices from a remote server. + // this.noticeController.startPolling() this.provider = this.initializeProvider(opts) this.ethStore = new EthStore(this.provider) this.keyringController.setStore(this.ethStore) @@ -43,12 +51,14 @@ module.exports = class MetamaskController { this.state, this.ethStore.getState(), this.configManager.getConfig(), - this.keyringController.getState() + this.keyringController.getState(), + this.noticeController.getState() ) } getApi () { const keyringController = this.keyringController + const noticeController = this.noticeController return { getState: (cb) => { cb(null, this.getState()) }, @@ -85,6 +95,9 @@ module.exports = class MetamaskController { buyEth: this.buyEth.bind(this), // shapeshift createShapeShiftTx: this.createShapeShiftTx.bind(this), + // notices + checkNotices: noticeController.updateNoticesList.bind(noticeController), + markNoticeRead: noticeController.markNoticeRead.bind(noticeController), } } @@ -268,7 +281,7 @@ module.exports = class MetamaskController { setTOSHash (hash) { try { this.configManager.setTOSHash(hash) - } catch (e) { + } catch (err) { console.error('Error in setting terms of service hash.') } } @@ -280,17 +293,19 @@ module.exports = class MetamaskController { this.resetDisclaimer() this.setTOSHash(global.TOS_HASH) } - } catch (e) { + } catch (err) { console.error('Error in checking TOS change.') } } + // disclaimer + agreeToDisclaimer (cb) { try { this.configManager.setConfirmedDisclaimer(true) cb() - } catch (e) { - cb(e) + } catch (err) { + cb(err) } } @@ -313,8 +328,8 @@ module.exports = class MetamaskController { conversionDate: this.configManager.getConversionDate(), } cb(data) - } catch (e) { - cb(null, e) + } catch (err) { + cb(null, err) } } @@ -387,8 +402,8 @@ module.exports = class MetamaskController { try { this.configManager.setGasMultiplier(gasMultiplier) cb() - } catch (e) { - cb(e) + } catch (err) { + cb(err) } } diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js new file mode 100644 index 000000000..438f5c27e --- /dev/null +++ b/app/scripts/notice-controller.js @@ -0,0 +1,96 @@ +const EventEmitter = require('events').EventEmitter +const hardCodedNotices = require('../../development/notices.json') + +module.exports = class NoticeController extends EventEmitter { + + constructor (opts) { + super() + this.configManager = opts.configManager + this.noticePoller = null + } + + getState() { + var lastUnreadNotice = this.getLatestUnreadNotice() + + return { + lastUnreadNotice: lastUnreadNotice, + noActiveNotices: !lastUnreadNotice, + } + } + + getNoticesList() { + var data = this.configManager.getData() + if ('noticesList' in data) { + return data.noticesList + } else { + return [] + } + } + + setNoticesList(list) { + var data = this.configManager.getData() + data.noticesList = list + this.configManager.setData(data) + return Promise.resolve(true) + } + + markNoticeRead(notice, cb) { + cb = cb || function(err){ if (err) throw err } + try { + var notices = this.getNoticesList() + var id = notice.id + notices[id].read = true + this.setNoticesList(notices) + let latestNotice = this.getLatestUnreadNotice() + cb(null, latestNotice) + } catch (err) { + cb(err) + } + } + + updateNoticesList() { + return this._retrieveNoticeData().then((newNotices) => { + var oldNotices = this.getNoticesList() + var combinedNotices = this._mergeNotices(oldNotices, newNotices) + return Promise.resolve(this.setNoticesList(combinedNotices)) + }) + } + + getLatestUnreadNotice() { + var notices = this.getNoticesList() + var filteredNotices = notices.filter((notice) => { + return notice.read === false + }) + return filteredNotices[filteredNotices.length - 1] + } + + startPolling () { + if (this.noticePoller) { + clearInterval(this.noticePoller) + } + this.noticePoller = setInterval(() => { + this.noticeController.updateNoticesList() + }, 300000) + } + + _mergeNotices(oldNotices, newNotices) { + var noticeMap = this._mapNoticeIds(oldNotices) + newNotices.forEach((notice) => { + if (noticeMap.indexOf(notice.id) === -1) { + oldNotices.push(notice) + } + }) + return oldNotices + } + + _mapNoticeIds(notices) { + return notices.map((notice) => notice.id) + } + + _retrieveNoticeData() { + // Placeholder for the API. + return Promise.resolve(hardCodedNotices) + } + + +} |