From 6915417d72e59445cef5c58780b3743507ae00b0 Mon Sep 17 00:00:00 2001 From: Stuart Nelson Date: Sun, 14 Feb 2021 15:06:25 -0700 Subject: [PATCH 1/3] feat: Show discovered peer count --- assets/locales/en.json | 1 + src/tray.js | 47 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/assets/locales/en.json b/assets/locales/en.json index 823baa229..3c4c25deb 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": "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..aa8b62676 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) { 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: peerCount.toString() + ' ' + i18n.t('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,30 @@ module.exports = function (ctx) { tray.on('right-click', popupMenu) tray.on('double-click', () => ctx.launchWebUI('/')) + const pollPeers = () => { + // If the daemon is running, send a request to retrieve the number + // of connected peers. Emit 'peersPolled' event upon retrieval. + if (state.status === STATUS.STARTING_FINISHED && ctx.getIpfsd) { + ctx.getIpfsd().then((daemon) => { + daemon.api.swarm.peers().then((value) => { + if (value.length) { + ipcMain.emit('peersPolled', value.length) + } + }) + }) + } else { + ipcMain.emit('peersPolled', 0) + } + } + const setupMenu = () => { - menu = buildMenu(ctx) + menu = buildMenu(ctx, state.peerCount) tray.setContextMenu(menu) - tray.setToolTip('IPFS Desktop') + tray.setToolTip(state.peerCount.toString() + ' ' + i18n.t('peerCount')) menu.on('menu-will-show', () => { ipcMain.emit('menubar-will-open') }) menu.on('menu-will-close', () => { ipcMain.emit('menubar-will-close') }) - updateMenu() } @@ -305,6 +326,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 @@ -380,10 +402,25 @@ module.exports = function (ctx) { updateMenu() }) + ipcMain.on('peersPolled', peerCount => { + // When a new peer count is retrieved, rebuild the menu and update + // the tray tooltip with the new number if necessary. + if (peerCount !== state.peerCount) { + state.peerCount = peerCount + menu = buildMenu(ctx, state.peerCount) + menu.on('menu-will-show', () => { ipcMain.emit('menubar-will-open') }) + menu.on('menu-will-close', () => { ipcMain.emit('menubar-will-close') }) + tray.setContextMenu(menu) + tray.setToolTip(state.peerCount.toString() + ' ' + i18n.t('peerCount')) + updateMenu() + } + }) + ipcMain.on('configUpdated', () => { updateMenu() }) ipcMain.on('languageUpdated', () => { setupMenu() }) setupMenu() + setInterval(pollPeers, 60000) ctx.tray = tray logger.info('[tray] started') From 413ea2bd89fc9d36060c37fa74eef3bb3001b98e Mon Sep 17 00:00:00 2001 From: Stuart Nelson Date: Sun, 14 Feb 2021 15:06:25 -0700 Subject: [PATCH 2/3] feat: Show discovered peer count --- src/tray.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/tray.js b/src/tray.js index aa8b62676..b08e55cb4 100644 --- a/src/tray.js +++ b/src/tray.js @@ -290,19 +290,19 @@ module.exports = function (ctx) { tray.on('right-click', popupMenu) tray.on('double-click', () => ctx.launchWebUI('/')) - const pollPeers = () => { + const fetchPeers = () => { // If the daemon is running, send a request to retrieve the number - // of connected peers. Emit 'peersPolled' event upon retrieval. + // 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) => { if (value.length) { - ipcMain.emit('peersPolled', value.length) + ipcMain.emit('peerCountFetched', value.length) } }) }) } else { - ipcMain.emit('peersPolled', 0) + ipcMain.emit('peerCountFetched', 0) } } @@ -377,6 +377,12 @@ module.exports = function (ctx) { } } + ipcMain.on('menubar-will-open', () => { + fetchPeers() + setupMenu() + updateMenu() + }) + ipcMain.on('ipfsd', status => { state.status = status updateMenu() @@ -402,17 +408,12 @@ module.exports = function (ctx) { updateMenu() }) - ipcMain.on('peersPolled', peerCount => { + 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 (peerCount !== state.peerCount) { state.peerCount = peerCount - menu = buildMenu(ctx, state.peerCount) - menu.on('menu-will-show', () => { ipcMain.emit('menubar-will-open') }) - menu.on('menu-will-close', () => { ipcMain.emit('menubar-will-close') }) - tray.setContextMenu(menu) tray.setToolTip(state.peerCount.toString() + ' ' + i18n.t('peerCount')) - updateMenu() } }) @@ -420,8 +421,8 @@ module.exports = function (ctx) { ipcMain.on('languageUpdated', () => { setupMenu() }) setupMenu() - setInterval(pollPeers, 60000) + tray.on('mouse-move', () => { fetchPeers() }) ctx.tray = tray logger.info('[tray] started') } From 848c9ab7c32c87282e19acb393bd6cc1c115eb5e Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 30 Apr 2021 17:46:56 +0200 Subject: [PATCH 3/3] fix(i18n): pluralization of peerCount label License: MIT Signed-off-by: Marcin Rataj --- assets/locales/en.json | 2 +- src/tray.js | 28 ++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/assets/locales/en.json b/assets/locales/en.json index 3c4c25deb..9060c94ea 100644 --- a/assets/locales/en.json +++ b/assets/locales/en.json @@ -4,7 +4,7 @@ "ipfsIsStarting": "IPFS is Starting", "ipfsIsNotRunning": "IPFS is Not Running", "ipfsHasErrored": "IPFS has Errored", - "peerCount": "Peers", + "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 b08e55cb4..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, peerCount) { +function buildMenu (ctx, peerCount = 0) { return Menu.buildFromTemplate([ ...[ ['ipfsIsStarting', 'yellow'], @@ -72,7 +72,7 @@ function buildMenu (ctx, peerCount) { })), { id: 'peerCount', - label: peerCount.toString() + ' ' + i18n.t('peerCount'), + label: i18n.t('peerCount', { peerCount }), enabled: false }, { @@ -296,9 +296,7 @@ module.exports = function (ctx) { if (state.status === STATUS.STARTING_FINISHED && ctx.getIpfsd) { ctx.getIpfsd().then((daemon) => { daemon.api.swarm.peers().then((value) => { - if (value.length) { - ipcMain.emit('peerCountFetched', value.length) - } + ipcMain.emit('peerCountFetched', Array.isArray(value) ? value.length : 0) }) }) } else { @@ -310,7 +308,7 @@ module.exports = function (ctx) { menu = buildMenu(ctx, state.peerCount) tray.setContextMenu(menu) - tray.setToolTip(state.peerCount.toString() + ' ' + i18n.t('peerCount')) + 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') }) @@ -374,13 +372,13 @@ 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() - updateMenu() }) ipcMain.on('ipfsd', status => { @@ -411,9 +409,9 @@ module.exports = function (ctx) { 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 (peerCount !== state.peerCount) { + if (typeof peerCount === 'number' && peerCount !== state.peerCount) { state.peerCount = peerCount - tray.setToolTip(state.peerCount.toString() + ' ' + i18n.t('peerCount')) + tray.setToolTip(i18n.t('peerCount', { peerCount: state.peerCount })) } }) @@ -422,7 +420,17 @@ module.exports = function (ctx) { setupMenu() - tray.on('mouse-move', () => { fetchPeers() }) + // 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') }