175 lines
6.4 KiB
TypeScript
175 lines
6.4 KiB
TypeScript
|
import * as loader from "tc-loader";
|
||
|
import {Stage} from "tc-loader";
|
||
|
|
||
|
import {MenuItemConstructorOptions, NativeImage, remote, Tray} from "electron";
|
||
|
import {clientIconClassToImage} from "./IconHelper";
|
||
|
import {ClientIcon} from "svg-sprites/client-icons";
|
||
|
import {ConnectionHandler, ConnectionState} from "tc-shared/ConnectionHandler";
|
||
|
import {server_connections} from "tc-shared/ConnectionManager";
|
||
|
import {tr} from "tc-shared/i18n/localize";
|
||
|
import {global_client_actions} from "tc-shared/events/GlobalEvents";
|
||
|
|
||
|
const kTrayGlobalUniqueId = "9ccaf91c-a54f-45e0-b061-c50c9f7864ca";
|
||
|
|
||
|
let tray: Tray;
|
||
|
let eventListener = [];
|
||
|
let defaultIcon: NativeImage;
|
||
|
async function initializeTray() {
|
||
|
defaultIcon = clientIconClassToImage(ClientIcon.TeaspeakLogo);
|
||
|
defaultIcon = remote.nativeImage.createFromBuffer(defaultIcon.toPNG());
|
||
|
|
||
|
tray = new remote.Tray(defaultIcon);
|
||
|
tray.setTitle("TeaSpeak - Client");
|
||
|
tray.on("double-click", () => remote.getCurrentWindow().show());
|
||
|
|
||
|
server_connections.events().on("notify_active_handler_changed", event => initializeConnection(event.newHandler));
|
||
|
initializeConnection(undefined);
|
||
|
}
|
||
|
|
||
|
function initializeConnection(connection: ConnectionHandler) {
|
||
|
eventListener.forEach(callback => callback());
|
||
|
eventListener = [];
|
||
|
|
||
|
let showClientStatus = connection?.connection_state === ConnectionState.CONNECTED;
|
||
|
let clientStatusIcon: ClientIcon = connection?.getClient().getStatusIcon();
|
||
|
|
||
|
const updateTray = () => {
|
||
|
if(showClientStatus) {
|
||
|
let icon = clientIconClassToImage(clientStatusIcon);
|
||
|
icon = remote.nativeImage.createFromBuffer(icon.toPNG());
|
||
|
tray.setImage(icon);
|
||
|
tray.setToolTip("TeaSpeak - Client\nConnected to " + connection.channelTree.server.properties.virtualserver_name);
|
||
|
} else {
|
||
|
tray.setImage(defaultIcon);
|
||
|
tray.setToolTip("TeaSpeak - Client");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const updateContextMenu = () => {
|
||
|
let items: MenuItemConstructorOptions[] = [];
|
||
|
|
||
|
items.push(
|
||
|
{ label: tr("Show TeaClient"), type: "normal", icon: defaultIcon, click: () => remote.getCurrentWindow().show() },
|
||
|
{ label: "seperator", type: "separator" },
|
||
|
);
|
||
|
|
||
|
items.push(
|
||
|
{
|
||
|
label: tr("Connect to server"),
|
||
|
type: "normal",
|
||
|
icon: clientIconClassToImage(ClientIcon.Connect),
|
||
|
click: () => {
|
||
|
global_client_actions.fire("action_open_window_connect", { newTab: connection?.connected });
|
||
|
remote.getCurrentWindow().show();
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
label: tr("Disconnect from current server"),
|
||
|
type: "normal",
|
||
|
icon: clientIconClassToImage(ClientIcon.Disconnect),
|
||
|
click: () => connection.disconnectFromServer(),
|
||
|
enabled: connection?.connected
|
||
|
},
|
||
|
{ label: "seperator", type: "separator" },
|
||
|
)
|
||
|
|
||
|
if(connection) {
|
||
|
if(connection.isMicrophoneDisabled()) {
|
||
|
items.push({
|
||
|
label: tr("Enable microphone"),
|
||
|
type: "normal",
|
||
|
icon: clientIconClassToImage(ClientIcon.ActivateMicrophone),
|
||
|
checked: true,
|
||
|
click: () => connection.setMicrophoneMuted(false)
|
||
|
});
|
||
|
} else if(connection.isMicrophoneMuted()) {
|
||
|
items.push({
|
||
|
label: tr("Unmute microphone"),
|
||
|
type: "normal",
|
||
|
icon: clientIconClassToImage(ClientIcon.InputMuted),
|
||
|
checked: true,
|
||
|
click: () => {
|
||
|
connection.setMicrophoneMuted(false);
|
||
|
connection.acquireInputHardware().then(() => {});
|
||
|
}
|
||
|
});
|
||
|
} else {
|
||
|
items.push({
|
||
|
label: tr("Mute microphone"),
|
||
|
type: "normal",
|
||
|
icon: clientIconClassToImage(ClientIcon.InputMuted),
|
||
|
checked: false,
|
||
|
click: () => connection.setMicrophoneMuted(true)
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if(connection.isSpeakerMuted()) {
|
||
|
items.push({
|
||
|
label: tr("Unmute speaker/headphones"),
|
||
|
type: "normal",
|
||
|
icon: clientIconClassToImage(ClientIcon.OutputMuted),
|
||
|
checked: true,
|
||
|
click: () => connection.setSpeakerMuted(false)
|
||
|
});
|
||
|
} else {
|
||
|
items.push({
|
||
|
label: tr("Mute speaker/headphones"),
|
||
|
type: "normal",
|
||
|
icon: clientIconClassToImage(ClientIcon.OutputMuted),
|
||
|
checked: true,
|
||
|
click: () => connection.setSpeakerMuted(false)
|
||
|
});
|
||
|
}
|
||
|
|
||
|
items.push(
|
||
|
{ label: "seperator", type: "separator" }
|
||
|
);
|
||
|
}
|
||
|
|
||
|
items.push(
|
||
|
{ label: tr("Quit"), type: "normal", icon: clientIconClassToImage(ClientIcon.CloseButton), click: () => remote.getCurrentWindow().close() }
|
||
|
);
|
||
|
|
||
|
tray.setContextMenu(remote.Menu.buildFromTemplate(items));
|
||
|
};
|
||
|
|
||
|
if(connection) {
|
||
|
eventListener.push(connection.channelTree.server.events.on("notify_properties_updated", event => {
|
||
|
if("virtualserver_name" in event.updated_properties) {
|
||
|
updateTray();
|
||
|
}
|
||
|
}));
|
||
|
|
||
|
eventListener.push(connection.events().on("notify_connection_state_changed", event => {
|
||
|
showClientStatus = event.new_state === ConnectionState.CONNECTED;
|
||
|
updateTray();
|
||
|
updateContextMenu();
|
||
|
}));
|
||
|
|
||
|
eventListener.push(connection.getClient().events.on("notify_status_icon_changed", event => {
|
||
|
clientStatusIcon = event.newIcon;
|
||
|
updateTray();
|
||
|
}));
|
||
|
|
||
|
eventListener.push(connection.events().on("notify_state_updated", event => {
|
||
|
switch (event.state) {
|
||
|
case "away":
|
||
|
case "microphone":
|
||
|
case "speaker":
|
||
|
updateContextMenu();
|
||
|
break;
|
||
|
}
|
||
|
}));
|
||
|
}
|
||
|
|
||
|
updateContextMenu();
|
||
|
updateTray();
|
||
|
}
|
||
|
|
||
|
loader.register_task(Stage.JAVASCRIPT_INITIALIZING, {
|
||
|
name: "tray bar",
|
||
|
function: initializeTray,
|
||
|
priority: 10
|
||
|
});
|
||
|
|
||
|
window.addEventListener("unload", () => tray.destroy());
|