mirror of
				https://github.com/zulip/zulip-desktop.git
				synced 2025-11-04 05:53:21 +00:00 
			
		
		
		
	The changes are mostly done via `xo --fix`; the other changes are either trivial or disabling new linter rules that we plan to address in future commits.
		
			
				
	
	
		
			505 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			505 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
'use strict';
 | 
						|
import { ipcRenderer, remote, OpenDialogOptions } from 'electron';
 | 
						|
 | 
						|
import path = require('path');
 | 
						|
import fs = require('fs-extra');
 | 
						|
 | 
						|
const { app, dialog } = remote;
 | 
						|
const currentBrowserWindow = remote.getCurrentWindow();
 | 
						|
 | 
						|
import BaseSection = require('./base-section');
 | 
						|
import ConfigUtil = require('../../utils/config-util');
 | 
						|
import EnterpriseUtil = require('./../../utils/enterprise-util');
 | 
						|
import t = require('../../utils/translation-util');
 | 
						|
 | 
						|
class GeneralSection extends BaseSection {
 | 
						|
	// TODO: TypeScript - Here props should be object type
 | 
						|
	props: any;
 | 
						|
	constructor(props: any) {
 | 
						|
		super();
 | 
						|
		this.props = props;
 | 
						|
	}
 | 
						|
 | 
						|
	template(): string {
 | 
						|
		return `
 | 
						|
            <div class="settings-pane">
 | 
						|
                <div class="title">${t.__('Appearance')}</div>
 | 
						|
                <div id="appearance-option-settings" class="settings-card">
 | 
						|
					<div class="setting-row" id="tray-option">
 | 
						|
						<div class="setting-description">${t.__('Show app icon in system tray')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="menubar-option" style= "display:${process.platform === 'darwin' ? 'none' : ''}">
 | 
						|
						<div class="setting-description">${t.__('Auto hide menu bar (Press Alt key to display)')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="sidebar-option">
 | 
						|
						<div class="setting-description">${t.__('Show sidebar')} (<span class="code">${process.platform === 'darwin' ? 'Cmd+Shift+S' : 'Ctrl+Shift+S'}</span>)</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="badge-option">
 | 
						|
						<div class="setting-description">${t.__('Show app unread badge')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="dock-bounce-option" style= "display:${process.platform === 'darwin' ? '' : 'none'}">
 | 
						|
						<div class="setting-description">${t.__('Bounce dock on new private message')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="flash-taskbar-option" style= "display:${process.platform === 'win32' ? '' : 'none'}">
 | 
						|
						<div class="setting-description">${t.__('Flash taskbar on new message')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
				</div>
 | 
						|
				<div class="title">${t.__('Desktop Notifications')}</div>
 | 
						|
				<div class="settings-card">
 | 
						|
					<div class="setting-row" id="show-notification-option">
 | 
						|
						<div class="setting-description">${t.__('Show desktop notifications')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="silent-option">
 | 
						|
						<div class="setting-description">${t.__('Mute all sounds from Zulip')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
				</div>
 | 
						|
				<div class="title">${t.__('App Updates')}</div>
 | 
						|
				<div class="settings-card">
 | 
						|
				<div class="setting-row" id="autoupdate-option">
 | 
						|
						<div class="setting-description">${t.__('Enable auto updates')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="betaupdate-option">
 | 
						|
						<div class="setting-description">${t.__('Get beta updates')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
				</div>
 | 
						|
				<div class="title">${t.__('Functionality')}</div>
 | 
						|
                <div class="settings-card">
 | 
						|
					<div class="setting-row" id="startAtLogin-option">
 | 
						|
						<div class="setting-description">${t.__('Start app at login')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="start-minimize-option">
 | 
						|
						<div class="setting-description">${t.__('Always start minimized')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="quitOnClose-option">
 | 
						|
						<div class="setting-description">${t.__('Quit when the window is closed')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="enable-spellchecker-option">
 | 
						|
						<div class="setting-description">${t.__('Enable spellchecker (requires restart)')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
				</div>
 | 
						|
				<div class="title">${t.__('Advanced')}</div>
 | 
						|
				<div class="settings-card">
 | 
						|
					<div class="setting-row" id="enable-error-reporting">
 | 
						|
						<div class="setting-description">${t.__('Enable error reporting (requires restart)')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="force-login-app">
 | 
						|
						<div class="setting-description">${t.__('Force social login in app instead of browser')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="show-download-folder">
 | 
						|
						<div class="setting-description">${t.__('Show downloaded files in file manager')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="add-custom-css">
 | 
						|
						<div class="setting-description">
 | 
						|
							${t.__('Add custom CSS')}
 | 
						|
						</div>
 | 
						|
						<button class="custom-css-button green">${t.__('Upload')}</button>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="remove-custom-css">
 | 
						|
						<div class="setting-description">
 | 
						|
							<div class="selected-css-path" id="custom-css-path">${ConfigUtil.getConfigItem('customCSS')}</div>
 | 
						|
						</div>
 | 
						|
						<div class="action red" id="css-delete-action">
 | 
						|
							<i class="material-icons">indeterminate_check_box</i>
 | 
						|
							<span>${t.__('Delete')}</span>
 | 
						|
						</div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="download-folder">
 | 
						|
						<div class="setting-description">
 | 
						|
							${t.__('Default download location')}
 | 
						|
						</div>
 | 
						|
						<button class="download-folder-button green">${t.__('Change')}</button>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row">
 | 
						|
						<div class="setting-description">
 | 
						|
							<div class="download-folder-path">${ConfigUtil.getConfigItem('downloadsPath', `${app.getPath('downloads')}`)}</div>
 | 
						|
						</div>
 | 
						|
					</div>
 | 
						|
					<div class="setting-row" id="prompt-download">
 | 
						|
						<div class="setting-description">${t.__('Ask where to save files before downloading')}</div>
 | 
						|
						<div class="setting-control"></div>
 | 
						|
					</div>
 | 
						|
				</div>
 | 
						|
				<div class="title">${t.__('Reset Application Data')}</div>
 | 
						|
                <div class="settings-card">
 | 
						|
					<div class="setting-row" id="resetdata-option">
 | 
						|
						<div class="setting-description">${t.__('This will delete all application data including all added accounts and preferences')}
 | 
						|
						</div>
 | 
						|
						<button class="reset-data-button red w-150">${t.__('Reset App Data')}</button>
 | 
						|
					</div>
 | 
						|
				</div>
 | 
						|
            </div>
 | 
						|
		`;
 | 
						|
	}
 | 
						|
 | 
						|
	init(): void {
 | 
						|
		this.props.$root.innerHTML = this.template();
 | 
						|
		this.updateTrayOption();
 | 
						|
		this.updateBadgeOption();
 | 
						|
		this.updateSilentOption();
 | 
						|
		this.autoUpdateOption();
 | 
						|
		this.betaUpdateOption();
 | 
						|
		this.updateSidebarOption();
 | 
						|
		this.updateStartAtLoginOption();
 | 
						|
		this.updateResetDataOption();
 | 
						|
		this.showDesktopNotification();
 | 
						|
		this.enableSpellchecker();
 | 
						|
		this.minimizeOnStart();
 | 
						|
		this.addCustomCSS();
 | 
						|
		this.showCustomCSSPath();
 | 
						|
		this.removeCustomCSS();
 | 
						|
		this.downloadFolder();
 | 
						|
		this.showDownloadFolder();
 | 
						|
		this.updateQuitOnCloseOption();
 | 
						|
		this.updatePromptDownloadOption();
 | 
						|
		this.enableErrorReporting();
 | 
						|
		this.enableLoginInApp();
 | 
						|
 | 
						|
		// Platform specific settings
 | 
						|
 | 
						|
		// Flashing taskbar on Windows
 | 
						|
		if (process.platform === 'win32') {
 | 
						|
			this.updateFlashTaskbar();
 | 
						|
		}
 | 
						|
		// Dock bounce on macOS
 | 
						|
		if (process.platform === 'darwin') {
 | 
						|
			this.updateDockBouncing();
 | 
						|
		}
 | 
						|
 | 
						|
		// Auto hide menubar on Windows and Linux
 | 
						|
		if (process.platform !== 'darwin') {
 | 
						|
			this.updateMenubarOption();
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	updateTrayOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#tray-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('trayIcon', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('trayIcon');
 | 
						|
				ConfigUtil.setConfigItem('trayIcon', newValue);
 | 
						|
				ipcRenderer.send('forward-message', 'toggletray');
 | 
						|
				this.updateTrayOption();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	updateMenubarOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#menubar-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('autoHideMenubar', false),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('autoHideMenubar');
 | 
						|
				ConfigUtil.setConfigItem('autoHideMenubar', newValue);
 | 
						|
				ipcRenderer.send('toggle-menubar', newValue);
 | 
						|
				this.updateMenubarOption();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	updateBadgeOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#badge-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('badgeOption', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('badgeOption');
 | 
						|
				ConfigUtil.setConfigItem('badgeOption', newValue);
 | 
						|
				ipcRenderer.send('toggle-badge-option', newValue);
 | 
						|
				this.updateBadgeOption();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	updateDockBouncing(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#dock-bounce-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('dockBouncing', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('dockBouncing');
 | 
						|
				ConfigUtil.setConfigItem('dockBouncing', newValue);
 | 
						|
				this.updateDockBouncing();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	updateFlashTaskbar(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#flash-taskbar-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('flashTaskbarOnMessage', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('flashTaskbarOnMessage');
 | 
						|
				ConfigUtil.setConfigItem('flashTaskbarOnMessage', newValue);
 | 
						|
				this.updateFlashTaskbar();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	autoUpdateOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#autoupdate-option .setting-control'),
 | 
						|
			disabled: EnterpriseUtil.configItemExists('autoUpdate'),
 | 
						|
			value: ConfigUtil.getConfigItem('autoUpdate', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('autoUpdate');
 | 
						|
				ConfigUtil.setConfigItem('autoUpdate', newValue);
 | 
						|
				if (!newValue) {
 | 
						|
					ConfigUtil.setConfigItem('betaUpdate', false);
 | 
						|
					this.betaUpdateOption();
 | 
						|
				}
 | 
						|
				this.autoUpdateOption();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	betaUpdateOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#betaupdate-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('betaUpdate', false),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('betaUpdate');
 | 
						|
				if (ConfigUtil.getConfigItem('autoUpdate')) {
 | 
						|
					ConfigUtil.setConfigItem('betaUpdate', newValue);
 | 
						|
					this.betaUpdateOption();
 | 
						|
				}
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	updateSilentOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#silent-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('silent', false),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('silent', true);
 | 
						|
				ConfigUtil.setConfigItem('silent', newValue);
 | 
						|
				this.updateSilentOption();
 | 
						|
				// TODO: TypeScript: currentWindow of type BrowserWindow doesn't
 | 
						|
				// have a .send() property per typescript.
 | 
						|
				(currentBrowserWindow as any).send('toggle-silent', newValue);
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	showDesktopNotification(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#show-notification-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('showNotification', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('showNotification', true);
 | 
						|
				ConfigUtil.setConfigItem('showNotification', newValue);
 | 
						|
				this.showDesktopNotification();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	updateSidebarOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#sidebar-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('showSidebar', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('showSidebar');
 | 
						|
				ConfigUtil.setConfigItem('showSidebar', newValue);
 | 
						|
				ipcRenderer.send('forward-message', 'toggle-sidebar', newValue);
 | 
						|
				this.updateSidebarOption();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	updateStartAtLoginOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#startAtLogin-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('startAtLogin', false),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('startAtLogin');
 | 
						|
				ConfigUtil.setConfigItem('startAtLogin', newValue);
 | 
						|
				ipcRenderer.send('toggleAutoLauncher', newValue);
 | 
						|
				this.updateStartAtLoginOption();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	updateQuitOnCloseOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#quitOnClose-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('quitOnClose', false),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('quitOnClose');
 | 
						|
				ConfigUtil.setConfigItem('quitOnClose', newValue);
 | 
						|
				this.updateQuitOnCloseOption();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	enableSpellchecker(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#enable-spellchecker-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('enableSpellchecker', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('enableSpellchecker');
 | 
						|
				ConfigUtil.setConfigItem('enableSpellchecker', newValue);
 | 
						|
				this.enableSpellchecker();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	enableErrorReporting(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#enable-error-reporting .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('errorReporting', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('errorReporting');
 | 
						|
				ConfigUtil.setConfigItem('errorReporting', newValue);
 | 
						|
				this.enableErrorReporting();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	enableLoginInApp(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#force-login-app .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('loginInApp', true),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('loginInApp');
 | 
						|
				ConfigUtil.setConfigItem('loginInApp', newValue);
 | 
						|
				this.enableLoginInApp();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	async clearAppDataDialog(): Promise<void> {
 | 
						|
		const clearAppDataMessage = 'By clicking proceed you will be removing all added accounts and preferences from Zulip. When the application restarts, it will be as if you are starting Zulip for the first time.';
 | 
						|
		const getAppPath = path.join(app.getPath('appData'), app.name);
 | 
						|
 | 
						|
		const { response } = await dialog.showMessageBox({
 | 
						|
			type: 'warning',
 | 
						|
			buttons: ['YES', 'NO'],
 | 
						|
			defaultId: 0,
 | 
						|
			message: 'Are you sure',
 | 
						|
			detail: clearAppDataMessage
 | 
						|
		});
 | 
						|
		if (response === 0) {
 | 
						|
			fs.remove(getAppPath);
 | 
						|
			setTimeout(() => ipcRenderer.send('forward-message', 'hard-reload'), 1000);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	async customCssDialog(): Promise<void> {
 | 
						|
		const showDialogOptions: OpenDialogOptions = {
 | 
						|
			title: 'Select file',
 | 
						|
			properties: ['openFile'],
 | 
						|
			filters: [{ name: 'CSS file', extensions: ['css'] }]
 | 
						|
		};
 | 
						|
 | 
						|
		const { filePaths, canceled } = await dialog.showOpenDialog(showDialogOptions);
 | 
						|
		if (!canceled) {
 | 
						|
			ConfigUtil.setConfigItem('customCSS', filePaths[0]);
 | 
						|
			ipcRenderer.send('forward-message', 'hard-reload');
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	updateResetDataOption(): void {
 | 
						|
		const resetDataButton = document.querySelector('#resetdata-option .reset-data-button');
 | 
						|
		resetDataButton.addEventListener('click', () => {
 | 
						|
			this.clearAppDataDialog();
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	minimizeOnStart(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#start-minimize-option .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('startMinimized', false),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('startMinimized');
 | 
						|
				ConfigUtil.setConfigItem('startMinimized', newValue);
 | 
						|
				this.minimizeOnStart();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	addCustomCSS(): void {
 | 
						|
		const customCSSButton = document.querySelector('#add-custom-css .custom-css-button');
 | 
						|
		customCSSButton.addEventListener('click', () => {
 | 
						|
			this.customCssDialog();
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	showCustomCSSPath(): void {
 | 
						|
		if (!ConfigUtil.getConfigItem('customCSS')) {
 | 
						|
			const cssPATH: HTMLElement = document.querySelector('#remove-custom-css');
 | 
						|
			cssPATH.style.display = 'none';
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	removeCustomCSS(): void {
 | 
						|
		const removeCSSButton = document.querySelector('#css-delete-action');
 | 
						|
		removeCSSButton.addEventListener('click', () => {
 | 
						|
			ConfigUtil.setConfigItem('customCSS', '');
 | 
						|
			ipcRenderer.send('forward-message', 'hard-reload');
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	async downloadFolderDialog(): Promise<void> {
 | 
						|
		const showDialogOptions: OpenDialogOptions = {
 | 
						|
			title: 'Select Download Location',
 | 
						|
			properties: ['openDirectory']
 | 
						|
		};
 | 
						|
 | 
						|
		const { filePaths, canceled } = await dialog.showOpenDialog(showDialogOptions);
 | 
						|
		if (!canceled) {
 | 
						|
			ConfigUtil.setConfigItem('downloadsPath', filePaths[0]);
 | 
						|
			const downloadFolderPath: HTMLElement = document.querySelector('.download-folder-path');
 | 
						|
			downloadFolderPath.textContent = filePaths[0];
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	downloadFolder(): void {
 | 
						|
		const downloadFolder = document.querySelector('#download-folder .download-folder-button');
 | 
						|
		downloadFolder.addEventListener('click', () => {
 | 
						|
			this.downloadFolderDialog();
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	showDownloadFolder(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#show-download-folder .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('showDownloadFolder', false),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('showDownloadFolder');
 | 
						|
				ConfigUtil.setConfigItem('showDownloadFolder', newValue);
 | 
						|
				this.showDownloadFolder();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
 | 
						|
	updatePromptDownloadOption(): void {
 | 
						|
		this.generateSettingOption({
 | 
						|
			$element: document.querySelector('#prompt-download .setting-control'),
 | 
						|
			value: ConfigUtil.getConfigItem('promptDownload', false),
 | 
						|
			clickHandler: () => {
 | 
						|
				const newValue = !ConfigUtil.getConfigItem('promptDownload');
 | 
						|
				ConfigUtil.setConfigItem('promptDownload', newValue);
 | 
						|
				this.updatePromptDownloadOption();
 | 
						|
			}
 | 
						|
		});
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
export = GeneralSection;
 |