Lightcord/modules/discord_desktop_core/core/app/systemTray.js

264 lines
7.3 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.init = init;
exports.show = show;
exports.displayHowToCloseHint = displayHowToCloseHint;
exports.hasInit = void 0;
var _electron = require("electron");
var _securityUtils = require("../common/securityUtils");
var _appSettings = require("./appSettings");
var _ipcMain = _interopRequireDefault(require("./ipcMain"));
var _utils = require("./utils");
var _Constants = require("./Constants");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const settings = (0, _appSettings.getSettings)(); // These are lazy loaded into temp files
const TrayIconNames = {
DEFAULT: 'tray',
UNREAD: 'tray-unread',
CONNECTED: 'tray-connected',
SPEAKING: 'tray-speaking',
MUTED: 'tray-muted',
DEAFENED: 'tray-deafened'
};
const MenuItems = {
SECRET: 'SECRET',
MUTE: 'MUTE',
DEAFEN: 'DEAFEN',
OPEN: 'OPEN',
VOICE_SETTINGS: 'VOICE_SETTINGS',
CHECK_UPDATE: 'CHECK_UPDATE',
QUIT: 'QUIT',
ACKNOWLEDGEMENTS: 'ACKNOWLEDGEMENTS'
};
let hasInit = false;
exports.hasInit = hasInit;
let currentIcon;
let options;
let menuItems;
let contextMenu;
let atomTray;
let trayIcons;
let applications;
function init(_options) {
if (hasInit) {
console.warn('systemTray: Has already init! Cancelling init.');
return;
}
trayIcons = {};
generateTrayIconPaths();
exports.hasInit = hasInit = true;
options = _options;
currentIcon = trayIcons.DEFAULT;
menuItems = {};
applications = [];
contextMenu = [];
initializeMenuItems();
buildContextMenu();
_ipcMain.default.on('SYSTEM_TRAY_SET_ICON', (evt, icon) => setTrayIcon(icon));
_ipcMain.default.on('SYSTEM_TRAY_SET_APPLICATIONS', (evt, newApplications) => setApplications(newApplications));
}
function generateTrayIconPaths() {
// Load in the icons for current platform
const resourcePath = `app/images/systemtray/${process.platform}`;
const suffix = process.platform === 'darwin' ? 'Template' : '';
for (const key of Object.keys(TrayIconNames)) {
trayIcons[key] = (0, _utils.exposeModuleResource)(resourcePath, `${TrayIconNames[key]}${suffix}.png`);
}
}
function initializeMenuItems() {
const {
onToggleMute,
onToggleDeafen,
onTrayClicked,
onOpenVoiceSettings,
onCheckForUpdates
} = options;
const voiceConnected = currentIcon !== trayIcons.DEFAULT && currentIcon !== trayIcons.UNREAD;
menuItems[MenuItems.SECRET] = {
label: `Lightcord`,
icon: trayIcons.DEFAULT,
enabled: false
};
menuItems[MenuItems.MUTE] = {
label: `Mute`,
type: 'checkbox',
checked: currentIcon === trayIcons.MUTED || currentIcon === trayIcons.DEAFENED,
visible: voiceConnected,
click: onToggleMute
};
menuItems[MenuItems.DEAFEN] = {
label: `Deafen`,
type: 'checkbox',
checked: currentIcon === trayIcons.DEAFENED,
visible: voiceConnected,
click: onToggleDeafen
};
menuItems[MenuItems.OPEN] = {
label: `Open ${_Constants.APP_NAME}`,
type: 'normal',
visible: process.platform === 'linux',
click: onTrayClicked
};
menuItems[MenuItems.VOICE_SETTINGS] = {
label: 'Voice / Video Settings',
type: 'normal',
visible: voiceConnected,
click: onOpenVoiceSettings
};
menuItems[MenuItems.CHECK_UPDATE] = {
label: 'Check for Updates...',
type: 'normal',
visible: process.platform !== 'darwin',
click: onCheckForUpdates
};
menuItems[MenuItems.QUIT] = {
label: `Quit ${_Constants.APP_NAME}`,
role: 'quit'
};
menuItems[MenuItems.ACKNOWLEDGEMENTS] = {
label: 'Acknowledgements',
type: 'normal',
visible: process.platform !== 'darwin',
click: () => (0, _securityUtils.saferShellOpenExternal)('https://discord.com/acknowledgements')
};
}
function buildContextMenu() {
const separator = {
type: 'separator'
};
const hasApplications = applications != null && applications.length > 0;
contextMenu = [
menuItems[MenuItems.SECRET],
separator, ...(hasApplications ? [...applications, separator] : []),
menuItems[MenuItems.OPEN],
menuItems[MenuItems.MUTE],
menuItems[MenuItems.DEAFEN],
menuItems[MenuItems.VOICE_SETTINGS],
// menuItems[MenuItems.CHECK_UPDATE],
menuItems[MenuItems.ACKNOWLEDGEMENTS],
separator,
menuItems[MenuItems.QUIT]
];
}
function setTrayIcon(icon) {
// Keep track of last set icon
currentIcon = trayIcons[icon]; // If icon is null, hide the tray icon. Otherwise show
// These calls also check for tray existence, so minimal cost.
if (icon == null) {
hide();
return;
} else {
show();
} // Keep mute/deafen menu items in sync with client, based on icon states
const muteIndex = contextMenu.indexOf(menuItems[MenuItems.MUTE]);
const deafenIndex = contextMenu.indexOf(menuItems[MenuItems.DEAFEN]);
const voiceConnected = contextMenu[muteIndex].visible;
let shouldSetContextMenu = false;
if (currentIcon !== trayIcons.DEFAULT && currentIcon !== trayIcons.UNREAD) {
// Show mute/deaf controls
if (!voiceConnected) {
contextMenu[muteIndex].visible = true;
contextMenu[deafenIndex].visible = true;
shouldSetContextMenu = true;
}
if (currentIcon === trayIcons.DEAFENED) {
contextMenu[muteIndex].checked = true;
contextMenu[deafenIndex].checked = true;
shouldSetContextMenu = true;
} else if (currentIcon === trayIcons.MUTED) {
contextMenu[muteIndex].checked = true;
contextMenu[deafenIndex].checked = false;
shouldSetContextMenu = true;
} else if (contextMenu[muteIndex].checked || contextMenu[deafenIndex].checked) {
contextMenu[muteIndex].checked = false;
contextMenu[deafenIndex].checked = false;
shouldSetContextMenu = true;
}
} else if (voiceConnected) {
contextMenu[muteIndex].visible = false;
contextMenu[deafenIndex].visible = false;
shouldSetContextMenu = true;
}
shouldSetContextMenu && setContextMenu();
atomTray != null && atomTray.setImage(_electron.nativeImage.createFromPath(currentIcon));
}
function launchApplication(applicationId) {
options.onLaunchApplication(applicationId);
}
function setApplications(newApplications) {
applications = newApplications.map(application => ({
type: 'normal',
label: application.name,
click: () => launchApplication(application.id)
}));
buildContextMenu();
setContextMenu();
}
function setContextMenu() {
atomTray != null && atomTray.setContextMenu(_electron.Menu.buildFromTemplate(contextMenu));
}
function show() {
if (atomTray != null) return;
atomTray = new _electron.Tray(_electron.nativeImage.createFromPath(currentIcon)); // Initialize with last set icon
atomTray.setToolTip(_Constants.APP_NAME); // Set tray context menu
setContextMenu(); // Set Tray click behavior
atomTray.on('click', options.onTrayClicked);
}
function hide() {
if (atomTray == null) {
return;
}
atomTray.destroy();
atomTray = null;
}
function displayHowToCloseHint() {
if (settings.get('trayBalloonShown') != null || atomTray == null) {
return;
} // TODO: localize
const balloonMessage = 'Hi! Lightcord will run in the background to keep you in touch with your friends.' + ' You can right-click here to quit.';
settings.set('trayBalloonShown', true);
settings.save();
atomTray.displayBalloon({
title: 'Lightcord',
content: balloonMessage
});
}