mirror of
				https://github.com/zulip/zulip-desktop.git
				synced 2025-11-03 21:43:18 +00:00 
			
		
		
		
	feature: Add DND button in left sidebar.
This adds the do not disturb button to the left sidebar which disables sound and notifications. It also disables flash taskbar on windows. Fixes: #298.
This commit is contained in:
		
				
					committed by
					
						
						Akash Nimare
					
				
			
			
				
	
			
			
			
						parent
						
							3fccb33fca
						
					
				
				
					commit
					537fbe8f9e
				
			@@ -6,6 +6,7 @@ const { app, shell, BrowserWindow, Menu, dialog } = require('electron');
 | 
				
			|||||||
const fs = require('fs-extra');
 | 
					const fs = require('fs-extra');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ConfigUtil = require(__dirname + '/../renderer/js/utils/config-util.js');
 | 
					const ConfigUtil = require(__dirname + '/../renderer/js/utils/config-util.js');
 | 
				
			||||||
 | 
					const DNDUtil = require(__dirname + '/../renderer/js/utils/dnd-util.js');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const appName = app.getName();
 | 
					const appName = app.getName();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -214,6 +215,13 @@ class AppMenu {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}, {
 | 
								}, {
 | 
				
			||||||
				type: 'separator'
 | 
									type: 'separator'
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									label: 'Toggle Do Not Disturb',
 | 
				
			||||||
 | 
									accelerator: 'Command+Shift+M',
 | 
				
			||||||
 | 
									click() {
 | 
				
			||||||
 | 
										const dndUtil = DNDUtil.toggle();
 | 
				
			||||||
 | 
										AppMenu.sendAction('toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}, {
 | 
								}, {
 | 
				
			||||||
				label: 'Reset App Settings',
 | 
									label: 'Reset App Settings',
 | 
				
			||||||
				accelerator: 'Command+Shift+D',
 | 
									accelerator: 'Command+Shift+D',
 | 
				
			||||||
@@ -316,6 +324,13 @@ class AppMenu {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}, {
 | 
								}, {
 | 
				
			||||||
				type: 'separator'
 | 
									type: 'separator'
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									label: 'Toggle Do Not Disturb',
 | 
				
			||||||
 | 
									accelerator: 'Ctrl+Shift+M',
 | 
				
			||||||
 | 
									click() {
 | 
				
			||||||
 | 
										const dndUtil = DNDUtil.toggle();
 | 
				
			||||||
 | 
										AppMenu.sendAction('toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}, {
 | 
								}, {
 | 
				
			||||||
				label: 'Reset App Settings',
 | 
									label: 'Reset App Settings',
 | 
				
			||||||
				accelerator: 'Ctrl+Shift+D',
 | 
									accelerator: 'Ctrl+Shift+D',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,7 +46,7 @@ body {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#view-controls-container {
 | 
					#view-controls-container {
 | 
				
			||||||
	height: calc(100% - 156px);
 | 
						height: calc(100% - 208px);
 | 
				
			||||||
	overflow-y: hidden;
 | 
						overflow-y: hidden;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -304,6 +304,7 @@ webview.focus {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Tooltip styling */
 | 
					/* Tooltip styling */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#dnd-tooltip,
 | 
				
			||||||
#back-tooltip,
 | 
					#back-tooltip,
 | 
				
			||||||
#reload-tooltip,
 | 
					#reload-tooltip,
 | 
				
			||||||
#setting-tooltip {
 | 
					#setting-tooltip {
 | 
				
			||||||
@@ -321,6 +322,7 @@ webview.focus {
 | 
				
			|||||||
    font-size: 14px;
 | 
					    font-size: 14px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#dnd-tooltip:after,
 | 
				
			||||||
#back-tooltip:after,
 | 
					#back-tooltip:after,
 | 
				
			||||||
#reload-tooltip:after,
 | 
					#reload-tooltip:after,
 | 
				
			||||||
#setting-tooltip:after {
 | 
					#setting-tooltip:after {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ const WebView = require(__dirname + '/js/components/webview.js');
 | 
				
			|||||||
const ServerTab = require(__dirname + '/js/components/server-tab.js');
 | 
					const ServerTab = require(__dirname + '/js/components/server-tab.js');
 | 
				
			||||||
const FunctionalTab = require(__dirname + '/js/components/functional-tab.js');
 | 
					const FunctionalTab = require(__dirname + '/js/components/functional-tab.js');
 | 
				
			||||||
const ConfigUtil = require(__dirname + '/js/utils/config-util.js');
 | 
					const ConfigUtil = require(__dirname + '/js/utils/config-util.js');
 | 
				
			||||||
 | 
					const DNDUtil = require(__dirname + '/js/utils/dnd-util.js');
 | 
				
			||||||
const ReconnectUtil = require(__dirname + '/js/utils/reconnect-util.js');
 | 
					const ReconnectUtil = require(__dirname + '/js/utils/reconnect-util.js');
 | 
				
			||||||
const { feedbackHolder } = require(__dirname + '/js/feedback.js');
 | 
					const { feedbackHolder } = require(__dirname + '/js/feedback.js');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,12 +25,14 @@ class ServerManagerView {
 | 
				
			|||||||
		this.$settingsButton = $actionsContainer.querySelector('#settings-action');
 | 
							this.$settingsButton = $actionsContainer.querySelector('#settings-action');
 | 
				
			||||||
		this.$webviewsContainer = document.getElementById('webviews-container');
 | 
							this.$webviewsContainer = document.getElementById('webviews-container');
 | 
				
			||||||
		this.$backButton = $actionsContainer.querySelector('#back-action');
 | 
							this.$backButton = $actionsContainer.querySelector('#back-action');
 | 
				
			||||||
 | 
							this.$dndButton = $actionsContainer.querySelector('#dnd-action');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.$addServerTooltip = document.getElementById('add-server-tooltip');
 | 
							this.$addServerTooltip = document.getElementById('add-server-tooltip');
 | 
				
			||||||
		this.$reloadTooltip = $actionsContainer.querySelector('#reload-tooltip');
 | 
							this.$reloadTooltip = $actionsContainer.querySelector('#reload-tooltip');
 | 
				
			||||||
		this.$settingsTooltip = $actionsContainer.querySelector('#setting-tooltip');
 | 
							this.$settingsTooltip = $actionsContainer.querySelector('#setting-tooltip');
 | 
				
			||||||
		this.$serverIconTooltip = document.getElementsByClassName('server-tooltip');
 | 
							this.$serverIconTooltip = document.getElementsByClassName('server-tooltip');
 | 
				
			||||||
		this.$backTooltip = $actionsContainer.querySelector('#back-tooltip');
 | 
							this.$backTooltip = $actionsContainer.querySelector('#back-tooltip');
 | 
				
			||||||
 | 
							this.$dndTooltip = $actionsContainer.querySelector('#dnd-tooltip');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.$sidebar = document.getElementById('sidebar');
 | 
							this.$sidebar = document.getElementById('sidebar');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -88,7 +91,12 @@ class ServerManagerView {
 | 
				
			|||||||
			showNotification: true,
 | 
								showNotification: true,
 | 
				
			||||||
			betaUpdate: false,
 | 
								betaUpdate: false,
 | 
				
			||||||
			silent: false,
 | 
								silent: false,
 | 
				
			||||||
			lastActiveTab: 0
 | 
								lastActiveTab: 0,
 | 
				
			||||||
 | 
								dnd: false,
 | 
				
			||||||
 | 
								dndPreviousSettings: {
 | 
				
			||||||
 | 
									showNotification: true,
 | 
				
			||||||
 | 
									silent: false
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Platform specific settings
 | 
							// Platform specific settings
 | 
				
			||||||
@@ -96,6 +104,7 @@ class ServerManagerView {
 | 
				
			|||||||
		if (process.platform === 'win32') {
 | 
							if (process.platform === 'win32') {
 | 
				
			||||||
			// Only available on Windows
 | 
								// Only available on Windows
 | 
				
			||||||
			settingOptions.flashTaskbarOnMessage = true;
 | 
								settingOptions.flashTaskbarOnMessage = true;
 | 
				
			||||||
 | 
								settingOptions.dndPreviousSettings.flashTaskbarOnMessage = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (const i in settingOptions) {
 | 
							for (const i in settingOptions) {
 | 
				
			||||||
@@ -156,6 +165,11 @@ class ServerManagerView {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	initActions() {
 | 
						initActions() {
 | 
				
			||||||
 | 
							this.initDNDButton();
 | 
				
			||||||
 | 
							this.$dndButton.addEventListener('click', () => {
 | 
				
			||||||
 | 
								const dndUtil = DNDUtil.toggle();
 | 
				
			||||||
 | 
								ipcRenderer.send('forward-message', 'toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
		this.$reloadButton.addEventListener('click', () => {
 | 
							this.$reloadButton.addEventListener('click', () => {
 | 
				
			||||||
			this.tabs[this.activeTabIndex].webview.reload();
 | 
								this.tabs[this.activeTabIndex].webview.reload();
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
@@ -180,6 +194,12 @@ class ServerManagerView {
 | 
				
			|||||||
		this.sidebarHoverEvent(this.$settingsButton, this.$settingsTooltip);
 | 
							this.sidebarHoverEvent(this.$settingsButton, this.$settingsTooltip);
 | 
				
			||||||
		this.sidebarHoverEvent(this.$reloadButton, this.$reloadTooltip);
 | 
							this.sidebarHoverEvent(this.$reloadButton, this.$reloadTooltip);
 | 
				
			||||||
		this.sidebarHoverEvent(this.$backButton, this.$backTooltip);
 | 
							this.sidebarHoverEvent(this.$backButton, this.$backTooltip);
 | 
				
			||||||
 | 
							this.sidebarHoverEvent(this.$dndButton, this.$dndTooltip);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						initDNDButton() {
 | 
				
			||||||
 | 
							const dnd = ConfigUtil.getConfigItem('dnd', false);
 | 
				
			||||||
 | 
							this.toggleDNDButton(dnd);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	getTabIndex() {
 | 
						getTabIndex() {
 | 
				
			||||||
@@ -338,6 +358,15 @@ class ServerManagerView {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ipcRenderer.on('toggle-dnd', (event, state, newSettings) => {
 | 
				
			||||||
 | 
								this.toggleDNDButton(state);
 | 
				
			||||||
 | 
								ipcRenderer.send('forward-message', 'toggle-silent', newSettings.silent);
 | 
				
			||||||
 | 
								const selector = 'webview:not([class*=disabled])';
 | 
				
			||||||
 | 
								const webview = document.querySelector(selector);
 | 
				
			||||||
 | 
								const webContents = webview.getWebContents();
 | 
				
			||||||
 | 
								webContents.send('toggle-dnd', state, newSettings);
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	destroyTab(name, index) {
 | 
						destroyTab(name, index) {
 | 
				
			||||||
@@ -404,6 +433,12 @@ class ServerManagerView {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Toggles the dnd button icon.
 | 
				
			||||||
 | 
						toggleDNDButton(alert) {
 | 
				
			||||||
 | 
							this.$dndTooltip.textContent = (alert ? 'Turn Off' : 'Enable') + ' Do Not Disturb';
 | 
				
			||||||
 | 
							this.$dndButton.querySelector('i').textContent = alert ? 'notifications_off' : 'notifications';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	registerIpcs() {
 | 
						registerIpcs() {
 | 
				
			||||||
		const webviewListeners = {
 | 
							const webviewListeners = {
 | 
				
			||||||
			'webview-reload': 'reload',
 | 
								'webview-reload': 'reload',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,6 +97,15 @@ class PreferenceView extends BaseComponent {
 | 
				
			|||||||
		ipcRenderer.on('toggletray', (event, state) => {
 | 
							ipcRenderer.on('toggletray', (event, state) => {
 | 
				
			||||||
			this.handleToggle('tray-option', state);
 | 
								this.handleToggle('tray-option', state);
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ipcRenderer.on('toggle-dnd', (event, state, newSettings) => {
 | 
				
			||||||
 | 
								this.handleToggle('show-notification-option', newSettings.showNotification);
 | 
				
			||||||
 | 
								this.handleToggle('silent-option', newSettings.silent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (process.platform === 'win32') {
 | 
				
			||||||
 | 
									this.handleToggle('flash-taskbar-option', newSettings.flashTaskbarOnMessage);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,10 @@ class ShortcutsSection extends BaseSection {
 | 
				
			|||||||
                  <tr>
 | 
					                  <tr>
 | 
				
			||||||
                    <td><kbd>${userOSKey}</kbd><kbd>K</kbd></td>
 | 
					                    <td><kbd>${userOSKey}</kbd><kbd>K</kbd></td>
 | 
				
			||||||
                    <td>Keyboard Shortcuts</td>
 | 
					                    <td>Keyboard Shortcuts</td>
 | 
				
			||||||
 | 
					                  </tr>
 | 
				
			||||||
 | 
														<tr>
 | 
				
			||||||
 | 
					                    <td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>M</kbd></td>
 | 
				
			||||||
 | 
					                    <td>Toggle Do Not Disturb</td>
 | 
				
			||||||
                  </tr>
 | 
					                  </tr>
 | 
				
			||||||
                  <tr>
 | 
					                  <tr>
 | 
				
			||||||
                    <td><kbd>Shift</kbd><kbd>${userOSKey}</kbd><kbd>D</kbd></td>
 | 
					                    <td><kbd>Shift</kbd><kbd>${userOSKey}</kbd><kbd>D</kbd></td>
 | 
				
			||||||
@@ -174,6 +178,10 @@ class ShortcutsSection extends BaseSection {
 | 
				
			|||||||
                  <tr>
 | 
					                  <tr>
 | 
				
			||||||
                    <td><kbd>${userOSKey}</kbd> + <kbd>K</kbd></td>
 | 
					                    <td><kbd>${userOSKey}</kbd> + <kbd>K</kbd></td>
 | 
				
			||||||
                    <td>Keyboard Shortcuts</td>
 | 
					                    <td>Keyboard Shortcuts</td>
 | 
				
			||||||
 | 
					                  </tr>
 | 
				
			||||||
 | 
														<tr>
 | 
				
			||||||
 | 
					                    <td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>M</kbd></td>
 | 
				
			||||||
 | 
					                    <td>Toggle Do Not Disturb</td>
 | 
				
			||||||
                  </tr>
 | 
					                  </tr>
 | 
				
			||||||
                  <tr>
 | 
					                  <tr>
 | 
				
			||||||
                    <td><kbd>${userOSKey}</kbd> + <kbd>L</kbd></td>
 | 
					                    <td><kbd>${userOSKey}</kbd> + <kbd>L</kbd></td>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										41
									
								
								app/renderer/js/utils/dnd-util.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/renderer/js/utils/dnd-util.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ConfigUtil = require(__dirname + '/config-util.js');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function toggle() {
 | 
				
			||||||
 | 
						const dnd = !ConfigUtil.getConfigItem('dnd', false);
 | 
				
			||||||
 | 
						const dndSettingList = ['showNotification', 'silent'];
 | 
				
			||||||
 | 
						if (process.platform === 'win32') {
 | 
				
			||||||
 | 
							dndSettingList.push('flashTaskbarOnMessage');
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let newSettings;
 | 
				
			||||||
 | 
						if (dnd) {
 | 
				
			||||||
 | 
							const oldSettings = {};
 | 
				
			||||||
 | 
							newSettings = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Iterate through the dndSettingList.
 | 
				
			||||||
 | 
							for (const settingName of dndSettingList) {
 | 
				
			||||||
 | 
								// Store the current value of setting.
 | 
				
			||||||
 | 
								oldSettings[settingName] = ConfigUtil.getConfigItem(settingName);
 | 
				
			||||||
 | 
								// New value of setting.
 | 
				
			||||||
 | 
								newSettings[settingName] = (settingName === 'silent');
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Store old value in oldSettings.
 | 
				
			||||||
 | 
							ConfigUtil.setConfigItem('dndPreviousSettings', oldSettings);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							newSettings = ConfigUtil.getConfigItem('dndPreviousSettings');
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (const settingName of dndSettingList) {
 | 
				
			||||||
 | 
							ConfigUtil.setConfigItem(settingName, newSettings[settingName]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ConfigUtil.setConfigItem('dnd', dnd);
 | 
				
			||||||
 | 
						return {dnd, newSettings};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
						toggle
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -24,6 +24,10 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id="actions-container">
 | 
					    <div id="actions-container">
 | 
				
			||||||
 | 
					      <div class="action-button" id="dnd-action">
 | 
				
			||||||
 | 
					        <i class="material-icons md-48">notifications</i>
 | 
				
			||||||
 | 
					        <span id="dnd-tooltip" style="display:none">Do Not Disturb</span>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
      <div class="action-button" id="reload-action">
 | 
					      <div class="action-button" id="reload-action">
 | 
				
			||||||
        <i class="material-icons md-48">refresh</i>
 | 
					        <i class="material-icons md-48">refresh</i>
 | 
				
			||||||
        <span id="reload-tooltip" style="display:none">Reload</span>
 | 
					        <span id="reload-tooltip" style="display:none">Reload</span>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user