diff --git a/assets/locales/en.json b/assets/locales/en.json index 823baa229..9060c94ea 100644 --- a/assets/locales/en.json +++ b/assets/locales/en.json @@ -4,6 +4,7 @@ "ipfsIsStarting": "IPFS is Starting", "ipfsIsNotRunning": "IPFS is Not Running", "ipfsHasErrored": "IPFS has Errored", + "peerCount": "{peerCount, plural, one {1 peer} other {{peerCount} peers}}", "runningWithGC": "Running (GC in progress)", "runningWhileCheckingForUpdate": "Running (Checking for Updates)", "start": "Start", diff --git a/src/tray.js b/src/tray.js index ea1c71e5f..37b74fdc1 100644 --- a/src/tray.js +++ b/src/tray.js @@ -53,7 +53,7 @@ function buildCheckbox (key, label) { // they natively work as soon as the menu opens. They don't work like that on Windows // or other OSes and must be registered globally. They still collide with global // accelerator. Please see ../utils/setup-global-shortcut.js for more info. -function buildMenu (ctx) { +function buildMenu (ctx, peerCount = 0) { return Menu.buildFromTemplate([ ...[ ['ipfsIsStarting', 'yellow'], @@ -70,6 +70,11 @@ function buildMenu (ctx) { enabled: false, icon: path.resolve(path.join(__dirname, `../assets/icons/status/${color}.png`)) })), + { + id: 'peerCount', + label: i18n.t('peerCount', { peerCount }), + enabled: false + }, { id: 'restartIpfs', label: i18n.t('restart'), @@ -260,7 +265,8 @@ module.exports = function (ctx) { const state = { status: null, gcRunning: false, - isUpdating: false + isUpdating: false, + peerCount: 0 } // macOS tray drop files @@ -284,15 +290,28 @@ module.exports = function (ctx) { tray.on('right-click', popupMenu) tray.on('double-click', () => ctx.launchWebUI('/')) + const fetchPeers = () => { + // If the daemon is running, send a request to retrieve the number + // of connected peers. Emit 'peerCountFetched' event upon retrieval. + if (state.status === STATUS.STARTING_FINISHED && ctx.getIpfsd) { + ctx.getIpfsd().then((daemon) => { + daemon.api.swarm.peers().then((value) => { + ipcMain.emit('peerCountFetched', Array.isArray(value) ? value.length : 0) + }) + }) + } else { + ipcMain.emit('peerCountFetched', 0) + } + } + const setupMenu = () => { - menu = buildMenu(ctx) + menu = buildMenu(ctx, state.peerCount) tray.setContextMenu(menu) - tray.setToolTip('IPFS Desktop') + tray.setToolTip(i18n.t('peerCount', { peerCount: state.peerCount })) menu.on('menu-will-show', () => { ipcMain.emit('menubar-will-open') }) menu.on('menu-will-close', () => { ipcMain.emit('menubar-will-close') }) - updateMenu() } @@ -305,6 +324,7 @@ module.exports = function (ctx) { menu.getMenuItemById('ipfsIsStopping').visible = status === STATUS.STOPPING_STARTED && !gcRunning && !isUpdating menu.getMenuItemById('ipfsIsNotRunning').visible = status === STATUS.STOPPING_FINISHED && !gcRunning && !isUpdating menu.getMenuItemById('ipfsHasErrored').visible = errored && !gcRunning && !isUpdating + menu.getMenuItemById('peerCount').visible = status === STATUS.STARTING_FINISHED menu.getMenuItemById('runningWithGC').visible = gcRunning menu.getMenuItemById('runningWhileCheckingForUpdate').visible = isUpdating @@ -352,9 +372,15 @@ module.exports = function (ctx) { // On Linux, in order for changes made to individual MenuItems to take effect, // you have to call setContextMenu again - https://electronjs.org/docs/api/tray tray.setContextMenu(menu) + tray.setToolTip(i18n.t('peerCount', { peerCount: state.peerCount })) } } + ipcMain.on('menubar-will-open', () => { + fetchPeers() + setupMenu() + }) + ipcMain.on('ipfsd', status => { state.status = status updateMenu() @@ -380,11 +406,31 @@ module.exports = function (ctx) { updateMenu() }) + ipcMain.on('peerCountFetched', peerCount => { + // When a new peer count is retrieved, rebuild the menu and update + // the tray tooltip with the new number if necessary. + if (typeof peerCount === 'number' && peerCount !== state.peerCount) { + state.peerCount = peerCount + tray.setToolTip(i18n.t('peerCount', { peerCount: state.peerCount })) + } + }) + ipcMain.on('configUpdated', () => { updateMenu() }) ipcMain.on('languageUpdated', () => { setupMenu() }) setupMenu() + // Trigger peer count refresh using event available on specific platform + const platformSupportsMouseMoveEvent = IS_MAC || IS_WIN + if (platformSupportsMouseMoveEvent) { + tray.on('mouse-move', fetchPeers) + } else { + /* TODO: what to do on Linux? + - 'mouse-move' event is mac and windows only + - When app indicator is used on Linux, the 'click' events are ignored. + */ + } + ctx.tray = tray logger.info('[tray] started') }