2020-10-05 12:49:13 +02:00
|
|
|
import * as loader from "tc-loader";
|
|
|
|
import {Stage} from "tc-loader";
|
|
|
|
import {getMenuBarDriver, MenuBarEntry} from "tc-shared/ui/frames/menu-bar/index";
|
|
|
|
import {ClientIcon} from "svg-sprites/client-icons";
|
|
|
|
import {global_client_actions} from "tc-shared/events/GlobalEvents";
|
|
|
|
import {server_connections} from "tc-shared/ConnectionManager";
|
|
|
|
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
|
|
|
import {getBackend} from "tc-shared/backend";
|
2021-01-10 17:36:57 +01:00
|
|
|
import {tr} from "tc-shared/i18n/localize";
|
2021-03-14 19:39:08 +01:00
|
|
|
import {bookmarks} from "tc-shared/Bookmarks";
|
|
|
|
import {RemoteIconInfo} from "tc-shared/file/Icons";
|
|
|
|
import {connectionHistory} from "tc-shared/connectionlog/History";
|
|
|
|
import {spawnModalAddCurrentServerToBookmarks} from "tc-shared/ui/modal/bookmarks-add-server/Controller";
|
2021-06-11 11:43:53 +02:00
|
|
|
import {LogCategory, logTrace} from "tc-shared/log";
|
2020-10-05 12:49:13 +02:00
|
|
|
|
|
|
|
function renderConnectionItems() {
|
|
|
|
const items: MenuBarEntry[] = [];
|
|
|
|
|
2021-01-10 16:26:45 +01:00
|
|
|
const currentConnectionConnected = !!server_connections.getActiveConnectionHandler()?.connected;
|
2020-10-05 12:49:13 +02:00
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Connect to a server"),
|
|
|
|
icon: ClientIcon.Connect,
|
|
|
|
click: () => global_client_actions.fire("action_open_window_connect", { newTab: currentConnectionConnected })
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Disconnect from current server"),
|
|
|
|
icon: ClientIcon.Disconnect,
|
|
|
|
disabled: !currentConnectionConnected,
|
2021-01-10 16:26:45 +01:00
|
|
|
click: () => server_connections.getActiveConnectionHandler()?.disconnectFromServer()
|
2020-10-05 12:49:13 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Disconnect from all servers"),
|
|
|
|
icon: ClientIcon.Disconnect,
|
2021-01-10 16:26:45 +01:00
|
|
|
disabled: server_connections.getAllConnectionHandlers().findIndex(e => e.connected) === -1,
|
|
|
|
click: () => server_connections.getAllConnectionHandlers().forEach(connection => connection.disconnectFromServer())
|
2020-10-05 12:49:13 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
if(__build.target === "client") {
|
|
|
|
items.push({ type: "separator" });
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Quit"),
|
|
|
|
icon: ClientIcon.CloseButton,
|
|
|
|
click: () => getBackend("native").quit()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
2021-06-11 11:43:53 +02:00
|
|
|
let bookmarkServerUniqueIds: string[] = [];
|
2021-03-14 19:39:08 +01:00
|
|
|
async function renderBookmarkItems() {
|
2021-06-11 11:43:53 +02:00
|
|
|
bookmarkServerUniqueIds = [];
|
2021-03-14 19:39:08 +01:00
|
|
|
const bookmarkList = bookmarks.getOrderedRegisteredBookmarks();
|
|
|
|
|
|
|
|
const bookmarkItems: MenuBarEntry[] = [];
|
|
|
|
const parentStack: MenuBarEntry[][] = [];
|
|
|
|
|
|
|
|
while(bookmarkList.length > 0) {
|
|
|
|
const bookmark = bookmarkList.pop_front();
|
|
|
|
const parentList = parentStack.pop() || bookmarkItems;
|
|
|
|
|
|
|
|
if(bookmark.entry.type === "entry") {
|
|
|
|
let icon: RemoteIconInfo;
|
|
|
|
|
|
|
|
try {
|
2021-06-11 11:43:53 +02:00
|
|
|
const connectInfo = await connectionHistory.lastConnectInfo(bookmark.entry.serverAddress, "address", true);
|
2021-03-14 19:39:08 +01:00
|
|
|
if(connectInfo) {
|
2021-06-11 11:43:53 +02:00
|
|
|
bookmarkServerUniqueIds.push(connectInfo.serverUniqueId);
|
2021-03-14 19:39:08 +01:00
|
|
|
const info = await connectionHistory.queryServerInfo(connectInfo.serverUniqueId);
|
|
|
|
if(info && info.iconId > 0) {
|
|
|
|
icon = { iconId: info.iconId, serverUniqueId: connectInfo.serverUniqueId };
|
|
|
|
}
|
|
|
|
}
|
2021-06-11 11:43:53 +02:00
|
|
|
} catch (error) {
|
|
|
|
/* No need to warn in prod build */
|
|
|
|
logTrace(LogCategory.BOOKMARKS, "Failed to query last connect info: %o", error);
|
2021-03-14 19:39:08 +01:00
|
|
|
}
|
2020-10-05 12:49:13 +02:00
|
|
|
|
2021-03-14 19:39:08 +01:00
|
|
|
parentList.push({
|
2020-10-05 12:49:13 +02:00
|
|
|
type: "normal",
|
2021-03-14 19:39:08 +01:00
|
|
|
label: bookmark.entry.displayName,
|
|
|
|
icon: icon,
|
|
|
|
click: () => bookmarks.executeConnect(bookmark.entry.uniqueId, false),
|
|
|
|
});
|
|
|
|
} else if(bookmark.entry.type === "directory") {
|
|
|
|
const children = [];
|
|
|
|
|
|
|
|
parentList.push({
|
2020-10-05 12:49:13 +02:00
|
|
|
type: "normal",
|
2021-03-14 19:39:08 +01:00
|
|
|
label: bookmark.entry.displayName,
|
|
|
|
children: children,
|
2020-10-05 12:49:13 +02:00
|
|
|
icon: ClientIcon.Folder,
|
2021-03-14 19:39:08 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
for(let i = 0; i < bookmark.childCount; i++) {
|
|
|
|
parentStack.push(children);
|
2020-10-05 12:49:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-14 19:39:08 +01:00
|
|
|
const items: MenuBarEntry[] = [];
|
2020-10-05 12:49:13 +02:00
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
icon: ClientIcon.BookmarkManager,
|
|
|
|
label: tr("Manage bookmarks"),
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "bookmark-manage" })
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
icon: ClientIcon.BookmarkAdd,
|
|
|
|
label: tr("Add current server to bookmarks"),
|
2021-01-10 16:26:45 +01:00
|
|
|
disabled: !server_connections.getActiveConnectionHandler()?.connected,
|
2021-03-14 19:39:08 +01:00
|
|
|
click: () => spawnModalAddCurrentServerToBookmarks(server_connections.getActiveConnectionHandler())
|
2020-10-05 12:49:13 +02:00
|
|
|
});
|
|
|
|
|
2021-03-14 19:39:08 +01:00
|
|
|
if(bookmarkItems.length !== 0) {
|
2020-10-05 12:49:13 +02:00
|
|
|
items.push({ type: "separator" });
|
2021-03-14 19:39:08 +01:00
|
|
|
items.push(...bookmarkItems);
|
2020-10-05 12:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderPermissionItems() : MenuBarEntry[] {
|
|
|
|
const items: MenuBarEntry[] = [];
|
|
|
|
|
2021-01-10 16:26:45 +01:00
|
|
|
const currentConnectionConnected = !!server_connections.getActiveConnectionHandler()?.connected;
|
2020-10-05 12:49:13 +02:00
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Server Groups"),
|
|
|
|
icon: ClientIcon.PermissionServerGroups,
|
|
|
|
click: () => global_client_actions.fire("action_open_window_permissions", { defaultTab: "groups-server" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Client Permissions"),
|
|
|
|
icon: ClientIcon.PermissionClient,
|
|
|
|
click: () => global_client_actions.fire("action_open_window_permissions", { defaultTab: "client" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Channel Client Permissions"),
|
|
|
|
icon: ClientIcon.PermissionClient,
|
|
|
|
click: () => global_client_actions.fire("action_open_window_permissions", { defaultTab: "client-channel" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Channel Groups"),
|
|
|
|
icon: ClientIcon.PermissionChannel,
|
|
|
|
click: () => global_client_actions.fire("action_open_window_permissions", { defaultTab: "groups-channel" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Channel Permissions"),
|
|
|
|
icon: ClientIcon.PermissionChannel,
|
|
|
|
click: () => global_client_actions.fire("action_open_window_permissions", { defaultTab: "channel" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({ type: "separator" });
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("List Privilege Keys"),
|
|
|
|
icon: ClientIcon.Token,
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "token-list" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Use Privilege Key"),
|
|
|
|
icon: ClientIcon.TokenUse,
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "token-use" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderToolItems() : MenuBarEntry[] {
|
|
|
|
const items: MenuBarEntry[] = [];
|
|
|
|
|
2021-01-10 16:26:45 +01:00
|
|
|
const currentConnectionConnected = !!server_connections.getActiveConnectionHandler()?.connected;
|
2020-12-02 18:54:31 +01:00
|
|
|
if(__build.target === "web") {
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Echo Test"),
|
|
|
|
icon: ClientIcon.ActivateMicrophone,
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "server-echo-test" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
}
|
2020-11-28 15:34:28 +01:00
|
|
|
|
2020-10-05 12:49:13 +02:00
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Ban List"),
|
|
|
|
icon: ClientIcon.BanList,
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "ban-list" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Query List"),
|
|
|
|
icon: ClientIcon.ServerQuery,
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "query-manage" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Query Create"),
|
|
|
|
icon: ClientIcon.ServerQuery,
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "query-create" }),
|
|
|
|
disabled: !currentConnectionConnected
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({ type: "separator" });
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Modify CSS variables"),
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "css-variable-editor" })
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Open Registry"),
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "settings-registry" })
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({ type: "separator" });
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Settings"),
|
|
|
|
click: () => global_client_actions.fire("action_open_window_settings")
|
|
|
|
});
|
|
|
|
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderHelpItems() : MenuBarEntry[] {
|
|
|
|
const items: MenuBarEntry[] = [];
|
|
|
|
|
|
|
|
if(__build.target === "client") {
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Check for updates"),
|
|
|
|
icon: ClientIcon.CheckUpdate,
|
|
|
|
click: () => getBackend("native").openClientUpdater()
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Open client changelog"),
|
|
|
|
click: () => getBackend("native").openChangeLog()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Visit TeaSpeak.de"),
|
|
|
|
click: () => window.open('https://teaspeak.de/', '_blank')
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Visit TeaSpeak forum"),
|
|
|
|
click: () => window.open('https://forum.teaspeak.de/', '_blank')
|
|
|
|
});
|
|
|
|
|
|
|
|
if(__build.target === "client" && getBackend("native").showDeveloperOptions()) {
|
|
|
|
items.push({ type: "separator" });
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Open developer tools"),
|
|
|
|
click: () => getBackend("native").openDeveloperTools()
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Reload UI"),
|
|
|
|
click: () => getBackend("native").reloadWindow()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
items.push({ type: "separator" });
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: __build.target === "web" ? tr("About TeaWeb") : tr("About TeaClient"),
|
|
|
|
click: () => global_client_actions.fire("action_open_window", { window: "about" })
|
|
|
|
});
|
|
|
|
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateMenuBar() {
|
2021-03-14 19:39:08 +01:00
|
|
|
/* TODO: Only run one update per time */
|
|
|
|
doUpdateMenuBar().then(undefined);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function doUpdateMenuBar() {
|
2020-10-05 12:49:13 +02:00
|
|
|
const items: MenuBarEntry[] = [];
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Connection"),
|
|
|
|
children: renderConnectionItems()
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Favorites"),
|
2021-03-14 19:39:08 +01:00
|
|
|
children: await renderBookmarkItems()
|
2020-10-05 12:49:13 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Permissions"),
|
|
|
|
children: renderPermissionItems()
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Tools"),
|
|
|
|
children: renderToolItems()
|
|
|
|
});
|
|
|
|
|
|
|
|
items.push({
|
|
|
|
type: "normal",
|
|
|
|
label: tr("Help"),
|
|
|
|
children: renderHelpItems()
|
|
|
|
});
|
|
|
|
|
|
|
|
/* TODO: Check if it's not exactly the same menu bar */
|
|
|
|
getMenuBarDriver().setEntries(items);
|
|
|
|
}
|
|
|
|
|
|
|
|
let updateListener: MenuBarUpdateListener;
|
|
|
|
class MenuBarUpdateListener {
|
|
|
|
private generalHandlerEvents: (() => void)[] = [];
|
|
|
|
private registeredHandlerEvents: {[key: string]: (() => void)[]} = {};
|
|
|
|
|
|
|
|
initializeListeners() {
|
|
|
|
this.generalHandlerEvents.push(server_connections.events().on("notify_handler_created", event => {
|
|
|
|
this.registerHandlerEvents(event.handler);
|
|
|
|
}));
|
|
|
|
this.generalHandlerEvents.push(server_connections.events().on("notify_handler_deleted", event => {
|
|
|
|
this.registeredHandlerEvents[event.handlerId]?.forEach(callback => callback());
|
|
|
|
delete this.registeredHandlerEvents[event.handlerId];
|
|
|
|
}));
|
2021-03-14 19:39:08 +01:00
|
|
|
this.generalHandlerEvents.push(server_connections.events().on("notify_active_handler_changed", () => updateMenuBar()));
|
|
|
|
this.generalHandlerEvents.push(bookmarks.events.on(["notify_bookmark_deleted", "notify_bookmark_created", "notify_bookmark_edited", "notify_bookmarks_imported"], () => updateMenuBar()));
|
2021-06-11 11:43:53 +02:00
|
|
|
this.generalHandlerEvents.push(connectionHistory.events.on("notify_server_info_updated", event => {
|
|
|
|
if(bookmarkServerUniqueIds.indexOf(event.serverUniqueId) === -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(event.keys.indexOf("iconId") !== -1) {
|
|
|
|
/* An icon for a bookmark has changed. Send the menu bar with the new icons. */
|
|
|
|
updateMenuBar();
|
|
|
|
}
|
|
|
|
}));
|
2021-01-10 16:26:45 +01:00
|
|
|
server_connections.getAllConnectionHandlers().forEach(handler => this.registerHandlerEvents(handler));
|
2020-10-05 12:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
destroy() {
|
|
|
|
this.generalHandlerEvents.forEach(callback => callback());
|
|
|
|
Object.keys(this.registeredHandlerEvents).forEach(id => this.registeredHandlerEvents[id].forEach(callback => callback()));
|
|
|
|
|
|
|
|
this.registeredHandlerEvents = {};
|
|
|
|
this.generalHandlerEvents = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
private registerHandlerEvents(handler: ConnectionHandler) {
|
|
|
|
const events = this.registeredHandlerEvents[handler.handlerId] = [];
|
|
|
|
events.push(handler.events().on("notify_connection_state_changed", () => {
|
|
|
|
updateMenuBar();
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
loader.register_task(Stage.JAVASCRIPT_INITIALIZING, {
|
2021-03-14 19:39:08 +01:00
|
|
|
name: "menu bar init",
|
2020-10-05 12:49:13 +02:00
|
|
|
function: async () => {
|
|
|
|
updateMenuBar();
|
|
|
|
|
|
|
|
updateListener = new MenuBarUpdateListener();
|
|
|
|
updateListener.initializeListeners();
|
|
|
|
},
|
2021-03-14 19:39:08 +01:00
|
|
|
|
|
|
|
/* initialize after all other systems have been initialized */
|
|
|
|
priority: 0
|
2020-10-05 12:49:13 +02:00
|
|
|
});
|