Resolved all tc-shared imports into relative imports
parent
391205cb34
commit
4a4cbdf38e
|
@ -1,18 +1,78 @@
|
||||||
|
import * as ts from "tsd/libraries/typescript";
|
||||||
|
import {SourceFile, SyntaxKind, TransformerFactory} from "tsd/libraries/typescript";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import * as fs from "fs-extra";
|
import * as fs from "fs-extra";
|
||||||
|
|
||||||
|
type ImportReplacement = { index: number, length: number, replacement: string };
|
||||||
|
let importReplacements: ImportReplacement[] = [];
|
||||||
|
|
||||||
async function processFile(file: string) {
|
const ImportTransformerFactory: (depth: number) => TransformerFactory<SourceFile> = fileDepth => context => source => {
|
||||||
|
const visit = (node: ts.Node, depth: number) => {
|
||||||
|
if(node.kind === SyntaxKind.ImportDeclaration) {
|
||||||
|
const decl = node as ts.ImportDeclaration;
|
||||||
|
if(decl.moduleSpecifier?.kind === SyntaxKind.StringLiteral) {
|
||||||
|
const module = decl.moduleSpecifier as ts.StringLiteral;
|
||||||
|
if(module.text.startsWith("tc-shared")) {
|
||||||
|
const rootPath = [...new Array(fileDepth)].map(() => "..").join("/");
|
||||||
|
const newPath = (rootPath || ".") + module.text.substr(9);
|
||||||
|
console.error("Import: %o -> %o", module.text, newPath);
|
||||||
|
importReplacements.push({
|
||||||
|
index: module.getStart(source, false) + 1,
|
||||||
|
length: module.getWidth(source) - 2,
|
||||||
|
replacement: newPath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(depth > 5) {
|
||||||
|
/* no import decl possible */
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ts.visitEachChild(node, n => visit(n, depth + 1), context);
|
||||||
|
};
|
||||||
|
|
||||||
|
return ts.visitNode(source, n => visit(n, fileDepth));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processDirectory(directory: string) {
|
async function processFile(file: string, fileDepth: number) {
|
||||||
|
if(path.extname(file) !== ".ts") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sourceData = (await fs.readFile(file)).toString();
|
||||||
|
let source = ts.createSourceFile(
|
||||||
|
file,
|
||||||
|
sourceData,
|
||||||
|
ts.ScriptTarget.ES2015,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("Transforming %s", file);
|
||||||
|
|
||||||
|
importReplacements = [];
|
||||||
|
ts.transform(source, [ImportTransformerFactory(fileDepth)]);
|
||||||
|
importReplacements.sort((a, b) => b.index - a.index);
|
||||||
|
importReplacements.forEach(replacement => {
|
||||||
|
sourceData = sourceData.substring(0, replacement.index) + replacement.replacement + sourceData.substring(replacement.index + replacement.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
await fs.writeFile(file, sourceData);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processDirectory(directory: string, depth: number) {
|
||||||
const files = await fs.readdir(directory);
|
const files = await fs.readdir(directory);
|
||||||
for(const file of files) {
|
for(const file of files) {
|
||||||
console.log(file);
|
let filePath = path.join(directory, file);
|
||||||
|
if((await fs.stat(filePath)).isDirectory()) {
|
||||||
|
await processDirectory(filePath, depth + 1);
|
||||||
|
} else {
|
||||||
|
await processFile(filePath, depth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processDirectory(path.join(__dirname, "js")).catch(error => {
|
processDirectory(path.join(__dirname, "js"), 0).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
});
|
});
|
|
@ -1,43 +1,43 @@
|
||||||
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection} from "./connection/ConnectionBase";
|
||||||
import {PermissionManager} from "tc-shared/permission/PermissionManager";
|
import {PermissionManager} from "./permission/PermissionManager";
|
||||||
import {GroupManager} from "tc-shared/permission/GroupManager";
|
import {GroupManager} from "./permission/GroupManager";
|
||||||
import {ServerSettings, Settings, settings, StaticSettings} from "tc-shared/settings";
|
import {ServerSettings, Settings, settings, StaticSettings} from "./settings";
|
||||||
import {Sound, SoundManager} from "tc-shared/sound/Sounds";
|
import {Sound, SoundManager} from "./sound/Sounds";
|
||||||
import {ConnectionProfile} from "tc-shared/profiles/ConnectionProfile";
|
import {ConnectionProfile} from "./profiles/ConnectionProfile";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "./log";
|
||||||
import {LogCategory, logError, logInfo, logWarn} from "tc-shared/log";
|
import {LogCategory, logError, logInfo, logWarn} from "./log";
|
||||||
import {createErrorModal, createInfoModal, createInputModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInfoModal, createInputModal, Modal} from "./ui/elements/Modal";
|
||||||
import {hashPassword} from "tc-shared/utils/helpers";
|
import {hashPassword} from "./utils/helpers";
|
||||||
import {HandshakeHandler} from "tc-shared/connection/HandshakeHandler";
|
import {HandshakeHandler} from "./connection/HandshakeHandler";
|
||||||
import * as htmltags from "./ui/htmltags";
|
import * as htmltags from "./ui/htmltags";
|
||||||
import {FilterMode, InputStartResult, InputState} from "tc-shared/voice/RecorderBase";
|
import {FilterMode, InputStartResult, InputState} from "./voice/RecorderBase";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "./connection/ServerConnectionDeclaration";
|
||||||
import {defaultRecorder, RecorderProfile} from "tc-shared/voice/RecorderProfile";
|
import {defaultRecorder, RecorderProfile} from "./voice/RecorderProfile";
|
||||||
import {Frame} from "tc-shared/ui/frames/chat_frame";
|
import {Frame} from "./ui/frames/chat_frame";
|
||||||
import {Hostbanner} from "tc-shared/ui/frames/hostbanner";
|
import {Hostbanner} from "./ui/frames/hostbanner";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "./ui/frames/connection_handlers";
|
||||||
import {connection_log, Regex} from "tc-shared/ui/modal/ModalConnect";
|
import {connection_log, Regex} from "./ui/modal/ModalConnect";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "./ui/frames/chat";
|
||||||
import {spawnAvatarUpload} from "tc-shared/ui/modal/ModalAvatar";
|
import {spawnAvatarUpload} from "./ui/modal/ModalAvatar";
|
||||||
import * as dns from "tc-backend/dns";
|
import * as dns from "tc-backend/dns";
|
||||||
import {EventHandler, Registry} from "tc-shared/events";
|
import {EventHandler, Registry} from "./events";
|
||||||
import {FileManager} from "tc-shared/file/FileManager";
|
import {FileManager} from "./file/FileManager";
|
||||||
import {FileTransferState, TransferProvider} from "tc-shared/file/Transfer";
|
import {FileTransferState, TransferProvider} from "./file/Transfer";
|
||||||
import {traj} from "tc-shared/i18n/localize";
|
import {traj} from "./i18n/localize";
|
||||||
import {md5} from "tc-shared/crypto/md5";
|
import {md5} from "./crypto/md5";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "./crypto/uid";
|
||||||
import {ServerEventLog} from "tc-shared/ui/frames/log/ServerEventLog";
|
import {ServerEventLog} from "./ui/frames/log/ServerEventLog";
|
||||||
import {EventType} from "tc-shared/ui/frames/log/Definitions";
|
import {EventType} from "./ui/frames/log/Definitions";
|
||||||
import {PluginCmdRegistry} from "tc-shared/connection/PluginCmdHandler";
|
import {PluginCmdRegistry} from "./connection/PluginCmdHandler";
|
||||||
import {W2GPluginCmdHandler} from "tc-shared/video-viewer/W2GPlugin";
|
import {W2GPluginCmdHandler} from "./video-viewer/W2GPlugin";
|
||||||
import {VoiceConnectionStatus, WhisperSessionInitializeData} from "tc-shared/connection/VoiceConnection";
|
import {VoiceConnectionStatus, WhisperSessionInitializeData} from "./connection/VoiceConnection";
|
||||||
import {getServerConnectionFactory} from "tc-shared/connection/ConnectionFactory";
|
import {getServerConnectionFactory} from "./connection/ConnectionFactory";
|
||||||
import {WhisperSession} from "tc-shared/voice/VoiceWhisper";
|
import {WhisperSession} from "./voice/VoiceWhisper";
|
||||||
import {spawnEchoTestModal} from "tc-shared/ui/modal/echo-test/Controller";
|
import {spawnEchoTestModal} from "./ui/modal/echo-test/Controller";
|
||||||
import {ServerFeature, ServerFeatures} from "tc-shared/connection/ServerFeatures";
|
import {ServerFeature, ServerFeatures} from "./connection/ServerFeatures";
|
||||||
import {ChannelTree} from "tc-shared/tree/ChannelTree";
|
import {ChannelTree} from "./tree/ChannelTree";
|
||||||
import {LocalClientEntry} from "tc-shared/tree/Client";
|
import {LocalClientEntry} from "./tree/Client";
|
||||||
import {ServerAddress} from "tc-shared/tree/Server";
|
import {ServerAddress} from "./tree/Server";
|
||||||
|
|
||||||
export enum InputHardwareState {
|
export enum InputHardwareState {
|
||||||
MISSING,
|
MISSING,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "./ui/frames/connection_handlers";
|
||||||
import {EventType, KeyDescriptor, KeyEvent, KeyHook} from "tc-shared/PPTListener";
|
import {EventType, KeyDescriptor, KeyEvent, KeyHook} from "./PPTListener";
|
||||||
import * as ppt from "tc-backend/ppt";
|
import * as ppt from "tc-backend/ppt";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "./settings";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "./log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "./log";
|
||||||
|
|
||||||
export interface KeyControl {
|
export interface KeyControl {
|
||||||
category: string;
|
category: string;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {AbstractInput, LevelMeter} from "tc-shared/voice/RecorderBase";
|
import {AbstractInput, LevelMeter} from "../voice/RecorderBase";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
|
|
||||||
export type DeviceQueryResult = {}
|
export type DeviceQueryResult = {}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "./log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "./log";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "./crypto/uid";
|
||||||
import {createErrorModal, createInfoModal, createInputModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInfoModal, createInputModal} from "./ui/elements/Modal";
|
||||||
import {default_profile, find_profile} from "tc-shared/profiles/ConnectionProfile";
|
import {default_profile, find_profile} from "./profiles/ConnectionProfile";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "./ui/frames/connection_handlers";
|
||||||
import {spawnConnectModal} from "tc-shared/ui/modal/ModalConnect";
|
import {spawnConnectModal} from "./ui/modal/ModalConnect";
|
||||||
import * as top_menu from "./ui/frames/MenuBar";
|
import * as top_menu from "./ui/frames/MenuBar";
|
||||||
import {control_bar_instance} from "tc-shared/ui/frames/control-bar";
|
import {control_bar_instance} from "./ui/frames/control-bar";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "./ConnectionHandler";
|
||||||
|
|
||||||
export const boorkmak_connect = (mark: Bookmark, new_tab?: boolean) => {
|
export const boorkmak_connect = (mark: Bookmark, new_tab?: boolean) => {
|
||||||
const profile = find_profile(mark.connect_profile) || default_profile();
|
const profile = find_profile(mark.connect_profile) || default_profile();
|
||||||
|
|
|
@ -2,8 +2,8 @@ import {
|
||||||
AbstractServerConnection,
|
AbstractServerConnection,
|
||||||
ServerCommand,
|
ServerCommand,
|
||||||
SingleCommandHandler
|
SingleCommandHandler
|
||||||
} from "tc-shared/connection/ConnectionBase";
|
} from "../connection/ConnectionBase";
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
|
|
||||||
export abstract class AbstractCommandHandler {
|
export abstract class AbstractCommandHandler {
|
||||||
readonly connection: AbstractServerConnection;
|
readonly connection: AbstractServerConnection;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {AbstractServerConnection, CommandOptions, ServerCommand} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection, CommandOptions, ServerCommand} from "../connection/ConnectionBase";
|
||||||
import {Sound} from "tc-shared/sound/Sounds";
|
import {Sound} from "../sound/Sounds";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {createErrorModal, createInfoModal, createInputModal, createModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInfoModal, createInputModal, createModal} from "../ui/elements/Modal";
|
||||||
import {
|
import {
|
||||||
ClientConnectionInfo,
|
ClientConnectionInfo,
|
||||||
ClientEntry,
|
ClientEntry,
|
||||||
|
@ -11,19 +11,19 @@ import {
|
||||||
LocalClientEntry,
|
LocalClientEntry,
|
||||||
MusicClientEntry,
|
MusicClientEntry,
|
||||||
SongInfo
|
SongInfo
|
||||||
} from "tc-shared/tree/Client";
|
} from "../tree/Client";
|
||||||
import {ChannelEntry} from "tc-shared/tree/Channel";
|
import {ChannelEntry} from "../tree/Channel";
|
||||||
import {ConnectionHandler, ConnectionState, DisconnectReason, ViewReasonId} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler, ConnectionState, DisconnectReason, ViewReasonId} from "../ConnectionHandler";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../ui/frames/chat";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "../ui/frames/connection_handlers";
|
||||||
import {spawnPoke} from "tc-shared/ui/modal/ModalPoke";
|
import {spawnPoke} from "../ui/modal/ModalPoke";
|
||||||
import {AbstractCommandHandler, AbstractCommandHandlerBoss} from "tc-shared/connection/AbstractCommandHandler";
|
import {AbstractCommandHandler, AbstractCommandHandlerBoss} from "../connection/AbstractCommandHandler";
|
||||||
import {batch_updates, BatchUpdateType, flush_batched_updates} from "tc-shared/ui/react-elements/ReactComponentBase";
|
import {batch_updates, BatchUpdateType, flush_batched_updates} from "../ui/react-elements/ReactComponentBase";
|
||||||
import {OutOfViewClient} from "tc-shared/ui/frames/side/PrivateConversationManager";
|
import {OutOfViewClient} from "../ui/frames/side/PrivateConversationManager";
|
||||||
import {renderBBCodeAsJQuery} from "tc-shared/text/bbcode";
|
import {renderBBCodeAsJQuery} from "../text/bbcode";
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
import {EventClient, EventType} from "tc-shared/ui/frames/log/Definitions";
|
import {EventClient, EventType} from "../ui/frames/log/Definitions";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../connection/ErrorCode";
|
||||||
|
|
||||||
export class ServerConnectionCommandBoss extends AbstractCommandHandlerBoss {
|
export class ServerConnectionCommandBoss extends AbstractCommandHandlerBoss {
|
||||||
constructor(connection: AbstractServerConnection) {
|
constructor(connection: AbstractServerConnection) {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import {ServerCommand, SingleCommandHandler} from "tc-shared/connection/ConnectionBase";
|
import {ServerCommand, SingleCommandHandler} from "../connection/ConnectionBase";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {
|
import {
|
||||||
ClientNameInfo,
|
ClientNameInfo,
|
||||||
CommandResult,
|
CommandResult,
|
||||||
Playlist, PlaylistInfo, PlaylistSong,
|
Playlist, PlaylistInfo, PlaylistSong,
|
||||||
QueryList,
|
QueryList,
|
||||||
QueryListEntry, ServerGroupClient
|
QueryListEntry, ServerGroupClient
|
||||||
} from "tc-shared/connection/ServerConnectionDeclaration";
|
} from "../connection/ServerConnectionDeclaration";
|
||||||
import {AbstractCommandHandler} from "tc-shared/connection/AbstractCommandHandler";
|
import {AbstractCommandHandler} from "../connection/AbstractCommandHandler";
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../connection/ErrorCode";
|
||||||
|
|
||||||
export class CommandHelper extends AbstractCommandHandler {
|
export class CommandHelper extends AbstractCommandHandler {
|
||||||
private whoAmIResponse: any;
|
private whoAmIResponse: any;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import {CommandHelper} from "tc-shared/connection/CommandHelper";
|
import {CommandHelper} from "../connection/CommandHelper";
|
||||||
import {HandshakeHandler} from "tc-shared/connection/HandshakeHandler";
|
import {HandshakeHandler} from "../connection/HandshakeHandler";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {ServerAddress} from "tc-shared/tree/Server";
|
import {ServerAddress} from "../tree/Server";
|
||||||
import {ConnectionHandler, ConnectionState} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler, ConnectionState} from "../ConnectionHandler";
|
||||||
import {AbstractCommandHandlerBoss} from "tc-shared/connection/AbstractCommandHandler";
|
import {AbstractCommandHandlerBoss} from "../connection/AbstractCommandHandler";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {AbstractVoiceConnection} from "tc-shared/connection/VoiceConnection";
|
import {AbstractVoiceConnection} from "../connection/VoiceConnection";
|
||||||
|
|
||||||
export interface CommandOptions {
|
export interface CommandOptions {
|
||||||
flagset?: string[]; /* default: [] */
|
flagset?: string[]; /* default: [] */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection} from "../connection/ConnectionBase";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../ConnectionHandler";
|
||||||
|
|
||||||
export interface ServerConnectionFactory {
|
export interface ServerConnectionFactory {
|
||||||
create(client: ConnectionHandler) : AbstractServerConnection;
|
create(client: ConnectionHandler) : AbstractServerConnection;
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import {
|
import {
|
||||||
AbstractVoiceConnection,
|
AbstractVoiceConnection,
|
||||||
VoiceConnectionStatus, WhisperSessionInitializer
|
VoiceConnectionStatus, WhisperSessionInitializer
|
||||||
} from "tc-shared/connection/VoiceConnection";
|
} from "../connection/VoiceConnection";
|
||||||
import {RecorderProfile} from "tc-shared/voice/RecorderProfile";
|
import {RecorderProfile} from "../voice/RecorderProfile";
|
||||||
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection} from "../connection/ConnectionBase";
|
||||||
import {VoiceClient} from "tc-shared/voice/VoiceClient";
|
import {VoiceClient} from "../voice/VoiceClient";
|
||||||
import {VoicePlayerEvents, VoicePlayerLatencySettings, VoicePlayerState} from "tc-shared/voice/VoicePlayer";
|
import {VoicePlayerEvents, VoicePlayerLatencySettings, VoicePlayerState} from "../voice/VoicePlayer";
|
||||||
import {WhisperSession, WhisperTarget} from "tc-shared/voice/VoiceWhisper";
|
import {WhisperSession, WhisperTarget} from "../voice/VoiceWhisper";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
|
|
||||||
class DummyVoiceClient implements VoiceClient {
|
class DummyVoiceClient implements VoiceClient {
|
||||||
readonly events: Registry<VoicePlayerEvents>;
|
readonly events: Registry<VoicePlayerEvents>;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {IdentitifyType} from "tc-shared/profiles/Identity";
|
import {IdentitifyType} from "../profiles/Identity";
|
||||||
import {TeaSpeakIdentity} from "tc-shared/profiles/identities/TeamSpeakIdentity";
|
import {TeaSpeakIdentity} from "../profiles/identities/TeamSpeakIdentity";
|
||||||
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection} from "../connection/ConnectionBase";
|
||||||
import {ConnectionProfile} from "tc-shared/profiles/ConnectionProfile";
|
import {ConnectionProfile} from "../profiles/ConnectionProfile";
|
||||||
import {settings} from "tc-shared/settings";
|
import {settings} from "../settings";
|
||||||
import {ConnectParameters, DisconnectReason} from "tc-shared/ConnectionHandler";
|
import {ConnectParameters, DisconnectReason} from "../ConnectionHandler";
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
|
|
||||||
export interface HandshakeIdentityHandler {
|
export interface HandshakeIdentityHandler {
|
||||||
connection: AbstractServerConnection;
|
connection: AbstractServerConnection;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../ConnectionHandler";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {AbstractCommandHandler} from "tc-shared/connection/AbstractCommandHandler";
|
import {AbstractCommandHandler} from "../connection/AbstractCommandHandler";
|
||||||
import {AbstractServerConnection, ServerCommand} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection, ServerCommand} from "../connection/ConnectionBase";
|
||||||
|
|
||||||
export interface PluginCommandInvoker {
|
export interface PluginCommandInvoker {
|
||||||
clientId: number;
|
clientId: number;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {LaterPromise} from "tc-shared/utils/LaterPromise";
|
import {LaterPromise} from "../utils/LaterPromise";
|
||||||
|
|
||||||
export class CommandResult {
|
export class CommandResult {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import {ConnectionEvents, ConnectionHandler, ConnectionState} from "tc-shared/ConnectionHandler";
|
import {ConnectionEvents, ConnectionHandler, ConnectionState} from "../ConnectionHandler";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../connection/ErrorCode";
|
||||||
import {LogCategory, logDebug, logTrace, logWarn} from "tc-shared/log";
|
import {LogCategory, logDebug, logTrace, logWarn} from "../log";
|
||||||
import {ExplicitCommandHandler} from "tc-shared/connection/AbstractCommandHandler";
|
import {ExplicitCommandHandler} from "../connection/AbstractCommandHandler";
|
||||||
|
|
||||||
export type ServerFeatureSupport = "unsupported" | "supported" | "experimental" | "deprecated";
|
export type ServerFeatureSupport = "unsupported" | "supported" | "experimental" | "deprecated";
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import {RecorderProfile} from "tc-shared/voice/RecorderProfile";
|
import {RecorderProfile} from "../voice/RecorderProfile";
|
||||||
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection} from "../connection/ConnectionBase";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {VoiceClient} from "tc-shared/voice/VoiceClient";
|
import {VoiceClient} from "../voice/VoiceClient";
|
||||||
import {WhisperSession, WhisperTarget} from "tc-shared/voice/VoiceWhisper";
|
import {WhisperSession, WhisperTarget} from "../voice/VoiceWhisper";
|
||||||
|
|
||||||
export enum VoiceConnectionStatus {
|
export enum VoiceConnectionStatus {
|
||||||
ClientUnsupported,
|
ClientUnsupported,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as log from "./log";
|
import * as log from "./log";
|
||||||
import {LogCategory} from "./log";
|
import {LogCategory} from "./log";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "./crypto/uid";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {useEffect} from "react";
|
import {useEffect} from "react";
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {ClientGlobalControlEvents} from "tc-shared/events/GlobalEvents";
|
import {ClientGlobalControlEvents} from "../events/GlobalEvents";
|
||||||
import {Sound} from "tc-shared/sound/Sounds";
|
import {Sound} from "../sound/Sounds";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../ConnectionHandler";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "../ui/frames/connection_handlers";
|
||||||
import {createErrorModal, createInfoModal, createInputModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInfoModal, createInputModal} from "../ui/elements/Modal";
|
||||||
import {settings} from "tc-shared/settings";
|
import {settings} from "../settings";
|
||||||
import {spawnConnectModal} from "tc-shared/ui/modal/ModalConnect";
|
import {spawnConnectModal} from "../ui/modal/ModalConnect";
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import PermissionType from "../permission/PermissionType";
|
||||||
import {spawnQueryCreate} from "tc-shared/ui/modal/ModalQuery";
|
import {spawnQueryCreate} from "../ui/modal/ModalQuery";
|
||||||
import {openBanList} from "tc-shared/ui/modal/ModalBanList";
|
import {openBanList} from "../ui/modal/ModalBanList";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../ui/frames/chat";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {spawnSettingsModal} from "tc-shared/ui/modal/ModalSettings";
|
import {spawnSettingsModal} from "../ui/modal/ModalSettings";
|
||||||
import {spawnPermissionEditorModal} from "tc-shared/ui/modal/permission/ModalPermissionEditor";
|
import {spawnPermissionEditorModal} from "../ui/modal/permission/ModalPermissionEditor";
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function initialize_sounds(event_registry: Registry<ClientGlobalControlEvents>) {
|
function initialize_sounds(event_registry: Registry<ClientGlobalControlEvents>) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../ConnectionHandler";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
|
|
||||||
export interface ClientGlobalControlEvents {
|
export interface ClientGlobalControlEvents {
|
||||||
/* open a basic window */
|
/* open a basic window */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import * as hex from "tc-shared/crypto/hex";
|
import * as hex from "../crypto/hex";
|
||||||
|
|
||||||
export const kIPCAvatarChannel = "avatars";
|
export const kIPCAvatarChannel = "avatars";
|
||||||
export const kLoadingAvatarImage = "img/loading_image.svg";
|
export const kLoadingAvatarImage = "img/loading_image.svg";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
|
|
||||||
export enum ImageType {
|
export enum ImageType {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import * as ipc from "../ipc/BrowserIPC";
|
import * as ipc from "../ipc/BrowserIPC";
|
||||||
import {ChannelMessage} from "../ipc/BrowserIPC";
|
import {ChannelMessage} from "../ipc/BrowserIPC";
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import {Stage} from "tc-loader";
|
import {Stage} from "tc-loader";
|
||||||
import {image_type, ImageCache, media_image_type} from "tc-shared/file/ImageCache";
|
import {image_type, ImageCache, media_image_type} from "../file/ImageCache";
|
||||||
import {FileManager} from "tc-shared/file/FileManager";
|
import {FileManager} from "../file/FileManager";
|
||||||
import {
|
import {
|
||||||
FileDownloadTransfer,
|
FileDownloadTransfer,
|
||||||
FileTransferState,
|
FileTransferState,
|
||||||
ResponseTransferTarget,
|
ResponseTransferTarget,
|
||||||
TransferProvider,
|
TransferProvider,
|
||||||
TransferTargetType
|
TransferTargetType
|
||||||
} from "tc-shared/file/Transfer";
|
} from "../file/Transfer";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "../ui/frames/connection_handlers";
|
||||||
import {ClientEntry} from "tc-shared/tree/Client";
|
import {ClientEntry} from "../tree/Client";
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
import {
|
import {
|
||||||
AbstractAvatarManager,
|
AbstractAvatarManager,
|
||||||
AbstractAvatarManagerFactory,
|
AbstractAvatarManagerFactory,
|
||||||
|
@ -26,10 +26,10 @@ import {
|
||||||
kIPCAvatarChannel,
|
kIPCAvatarChannel,
|
||||||
setGlobalAvatarManagerFactory,
|
setGlobalAvatarManagerFactory,
|
||||||
uniqueId2AvatarId
|
uniqueId2AvatarId
|
||||||
} from "tc-shared/file/Avatars";
|
} from "../file/Avatars";
|
||||||
import {IPCChannel} from "tc-shared/ipc/BrowserIPC";
|
import {IPCChannel} from "../ipc/BrowserIPC";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../ConnectionHandler";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../connection/ErrorCode";
|
||||||
|
|
||||||
/* FIXME: Retry avatar download after some time! */
|
/* FIXME: Retry avatar download after some time! */
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,11 @@ import {
|
||||||
AbstractAvatarManagerFactory, AvatarState, AvatarStateData, ClientAvatar,
|
AbstractAvatarManagerFactory, AvatarState, AvatarStateData, ClientAvatar,
|
||||||
kIPCAvatarChannel,
|
kIPCAvatarChannel,
|
||||||
setGlobalAvatarManagerFactory, uniqueId2AvatarId
|
setGlobalAvatarManagerFactory, uniqueId2AvatarId
|
||||||
} from "tc-shared/file/Avatars";
|
} from "../file/Avatars";
|
||||||
import {IPCChannel} from "tc-shared/ipc/BrowserIPC";
|
import {IPCChannel} from "../ipc/BrowserIPC";
|
||||||
import {Settings} from "tc-shared/settings";
|
import {Settings} from "../settings";
|
||||||
import {ChannelMessage} from "../ipc/BrowserIPC";
|
import {ChannelMessage} from "../ipc/BrowserIPC";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "../crypto/uid";
|
||||||
|
|
||||||
function isEquivalent(a, b) {
|
function isEquivalent(a, b) {
|
||||||
// Create arrays of property names
|
// Create arrays of property names
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../connection/ErrorCode";
|
||||||
|
|
||||||
/* Transfer source types */
|
/* Transfer source types */
|
||||||
export enum TransferSourceType {
|
export enum TransferSourceType {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
|
|
||||||
interface CountryInfo {
|
interface CountryInfo {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "../crypto/uid";
|
||||||
import {Settings, StaticSettings} from "tc-shared/settings";
|
import {Settings, StaticSettings} from "../settings";
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import {formatMessage, formatMessageString} from "tc-shared/ui/frames/chat";
|
import {formatMessage, formatMessageString} from "../ui/frames/chat";
|
||||||
|
|
||||||
export interface TranslationKey {
|
export interface TranslationKey {
|
||||||
message: string;
|
message: string;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import "broadcastchannel-polyfill";
|
import "broadcastchannel-polyfill";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {ConnectHandler} from "tc-shared/ipc/ConnectHandler";
|
import {ConnectHandler} from "../ipc/ConnectHandler";
|
||||||
|
|
||||||
export interface BroadcastMessage {
|
export interface BroadcastMessage {
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {BasicIPCHandler, IPCChannel, ChannelMessage} from "tc-shared/ipc/BrowserIPC";
|
import {BasicIPCHandler, IPCChannel, ChannelMessage} from "../ipc/BrowserIPC";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "../crypto/uid";
|
||||||
|
|
||||||
export type ConnectRequestData = {
|
export type ConnectRequestData = {
|
||||||
address: string;
|
address: string;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {BasicIPCHandler, IPCChannel, ChannelMessage} from "tc-shared/ipc/BrowserIPC";
|
import {BasicIPCHandler, IPCChannel, ChannelMessage} from "../ipc/BrowserIPC";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "../crypto/uid";
|
||||||
|
|
||||||
export interface MethodProxyInvokeData {
|
export interface MethodProxyInvokeData {
|
||||||
method_name: string;
|
method_name: string;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "./settings";
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
|
|
||||||
export enum LogCategory {
|
export enum LogCategory {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import {LaterPromise} from "tc-shared/utils/LaterPromise";
|
import {LaterPromise} from "../utils/LaterPromise";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {PermissionManager, PermissionValue} from "tc-shared/permission/PermissionManager";
|
import {PermissionManager, PermissionValue} from "../permission/PermissionManager";
|
||||||
import {ServerCommand} from "tc-shared/connection/ConnectionBase";
|
import {ServerCommand} from "../connection/ConnectionBase";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {ConnectionEvents, ConnectionHandler, ConnectionState} from "tc-shared/ConnectionHandler";
|
import {ConnectionEvents, ConnectionHandler, ConnectionState} from "../ConnectionHandler";
|
||||||
import {AbstractCommandHandler} from "tc-shared/connection/AbstractCommandHandler";
|
import {AbstractCommandHandler} from "../connection/AbstractCommandHandler";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
|
|
||||||
export enum GroupType {
|
export enum GroupType {
|
||||||
QUERY,
|
QUERY,
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory, LogType} from "tc-shared/log";
|
import {LogCategory, LogType} from "../log";
|
||||||
import {PermissionType} from "tc-shared/permission/PermissionType";
|
import {PermissionType} from "../permission/PermissionType";
|
||||||
import {LaterPromise} from "tc-shared/utils/LaterPromise";
|
import {LaterPromise} from "../utils/LaterPromise";
|
||||||
import {ServerCommand} from "tc-shared/connection/ConnectionBase";
|
import {ServerCommand} from "../connection/ConnectionBase";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../ConnectionHandler";
|
||||||
import {AbstractCommandHandler} from "tc-shared/connection/AbstractCommandHandler";
|
import {AbstractCommandHandler} from "../connection/AbstractCommandHandler";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {tr} from "tc-shared/i18n/localize";
|
import {tr} from "../i18n/localize";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../connection/ErrorCode";
|
||||||
|
|
||||||
export class PermissionInfo {
|
export class PermissionInfo {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import {decode_identity, IdentitifyType, Identity} from "tc-shared/profiles/Identity";
|
import {decode_identity, IdentitifyType, Identity} from "../profiles/Identity";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "../crypto/uid";
|
||||||
import {TeaForumIdentity} from "tc-shared/profiles/identities/TeaForumIdentity";
|
import {TeaForumIdentity} from "../profiles/identities/TeaForumIdentity";
|
||||||
import {TeaSpeakIdentity} from "tc-shared/profiles/identities/TeamSpeakIdentity";
|
import {TeaSpeakIdentity} from "../profiles/identities/TeamSpeakIdentity";
|
||||||
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection} from "../connection/ConnectionBase";
|
||||||
import {HandshakeIdentityHandler} from "tc-shared/connection/HandshakeHandler";
|
import {HandshakeIdentityHandler} from "../connection/HandshakeHandler";
|
||||||
import {createErrorModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal} from "../ui/elements/Modal";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../ui/frames/chat";
|
||||||
|
|
||||||
export class ConnectionProfile {
|
export class ConnectionProfile {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {AbstractServerConnection, ServerCommand} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection, ServerCommand} from "../connection/ConnectionBase";
|
||||||
import {HandshakeIdentityHandler} from "tc-shared/connection/HandshakeHandler";
|
import {HandshakeIdentityHandler} from "../connection/HandshakeHandler";
|
||||||
import {AbstractCommandHandler} from "tc-shared/connection/AbstractCommandHandler";
|
import {AbstractCommandHandler} from "../connection/AbstractCommandHandler";
|
||||||
|
|
||||||
export enum IdentitifyType {
|
export enum IdentitifyType {
|
||||||
TEAFORO,
|
TEAFORO,
|
||||||
|
|
|
@ -3,12 +3,12 @@ import {
|
||||||
HandshakeCommandHandler,
|
HandshakeCommandHandler,
|
||||||
IdentitifyType,
|
IdentitifyType,
|
||||||
Identity
|
Identity
|
||||||
} from "tc-shared/profiles/Identity";
|
} from "../../profiles/Identity";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection} from "../../connection/ConnectionBase";
|
||||||
import {HandshakeIdentityHandler} from "tc-shared/connection/HandshakeHandler";
|
import {HandshakeIdentityHandler} from "../../connection/HandshakeHandler";
|
||||||
|
|
||||||
class NameHandshakeHandler extends AbstractHandshakeIdentityHandler {
|
class NameHandshakeHandler extends AbstractHandshakeIdentityHandler {
|
||||||
readonly identity: NameIdentity;
|
readonly identity: NameIdentity;
|
||||||
|
|
|
@ -3,12 +3,12 @@ import {
|
||||||
HandshakeCommandHandler,
|
HandshakeCommandHandler,
|
||||||
IdentitifyType,
|
IdentitifyType,
|
||||||
Identity
|
Identity
|
||||||
} from "tc-shared/profiles/Identity";
|
} from "../../profiles/Identity";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection} from "../../connection/ConnectionBase";
|
||||||
import {HandshakeIdentityHandler} from "tc-shared/connection/HandshakeHandler";
|
import {HandshakeIdentityHandler} from "../../connection/HandshakeHandler";
|
||||||
import * as forum from "./teaspeak-forum";
|
import * as forum from "./teaspeak-forum";
|
||||||
|
|
||||||
class TeaForumHandshakeHandler extends AbstractHandshakeIdentityHandler {
|
class TeaForumHandshakeHandler extends AbstractHandshakeIdentityHandler {
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import * as asn1 from "tc-shared/crypto/asn1";
|
import * as asn1 from "../../crypto/asn1";
|
||||||
import * as sha from "tc-shared/crypto/sha";
|
import * as sha from "../../crypto/sha";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AbstractHandshakeIdentityHandler,
|
AbstractHandshakeIdentityHandler,
|
||||||
HandshakeCommandHandler,
|
HandshakeCommandHandler,
|
||||||
IdentitifyType,
|
IdentitifyType,
|
||||||
Identity
|
Identity
|
||||||
} from "tc-shared/profiles/Identity";
|
} from "../../profiles/Identity";
|
||||||
import {arrayBufferBase64, base64_encode_ab, str2ab8} from "tc-shared/utils/buffers";
|
import {arrayBufferBase64, base64_encode_ab, str2ab8} from "../../utils/buffers";
|
||||||
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
import {AbstractServerConnection} from "../../connection/ConnectionBase";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {HandshakeIdentityHandler} from "tc-shared/connection/HandshakeHandler";
|
import {HandshakeIdentityHandler} from "../../connection/HandshakeHandler";
|
||||||
|
|
||||||
export namespace CryptoHelper {
|
export namespace CryptoHelper {
|
||||||
export function base64_url_encode(str){
|
export function base64_url_encode(str){
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {settings, Settings} from "tc-shared/settings";
|
import {settings, Settings} from "../../settings";
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import * as fidentity from "./TeaForumIdentity";
|
import * as fidentity from "./TeaForumIdentity";
|
||||||
import * as log from "../../log";
|
import * as log from "../../log";
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "./log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "./log";
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import {Stage} from "tc-loader";
|
import {Stage} from "tc-loader";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "./events";
|
||||||
|
|
||||||
type ConfigValueTypes = boolean | number | string | object;
|
type ConfigValueTypes = boolean | number | string | object;
|
||||||
type ConfigValueTypeNames = "boolean" | "number" | "string" | "object";
|
type ConfigValueTypeNames = "boolean" | "number" | "string" | "object";
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../settings";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../ConnectionHandler";
|
||||||
import * as sbackend from "tc-backend/audio/sounds";
|
import * as sbackend from "tc-backend/audio/sounds";
|
||||||
|
|
||||||
export enum Sound {
|
export enum Sound {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "./log";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "./log";
|
||||||
|
|
||||||
enum CloseCodes {
|
enum CloseCodes {
|
||||||
UNSET = 3000,
|
UNSET = 3000,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//https://regex101.com/r/YQbfcX/2
|
//https://regex101.com/r/YQbfcX/2
|
||||||
//static readonly URL_REGEX = /^(?<hostname>([a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]{2,63})(?:\/(?<path>(?:[^\s?]+)?)(?:\?(?<query>\S+))?)?$/gm;
|
//static readonly URL_REGEX = /^(?<hostname>([a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]{2,63})(?:\/(?<path>(?:[^\s?]+)?)(?:\?(?<query>\S+))?)?$/gm;
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../settings";
|
||||||
import {renderMarkdownAsBBCode} from "tc-shared/text/markdown";
|
import {renderMarkdownAsBBCode} from "../text/markdown";
|
||||||
import {escapeBBCode} from "tc-shared/text/bbcode";
|
import {escapeBBCode} from "../text/bbcode";
|
||||||
|
|
||||||
const URL_REGEX = /^(([a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]{2,63})(?:\/((?:[^\s?]+)?)(?:\?(\S+))?)?$/gm;
|
const URL_REGEX = /^(([a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]{2,63})(?:\/((?:[^\s?]+)?)(?:\?(\S+))?)?$/gm;
|
||||||
function process_urls(message: string) : string {
|
function process_urls(message: string) : string {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {
|
import {
|
||||||
CodeToken, Env, FenceToken, HeadingOpenToken,
|
CodeToken, Env, FenceToken, HeadingOpenToken,
|
||||||
ImageToken,
|
ImageToken,
|
||||||
|
@ -10,7 +10,7 @@ import {
|
||||||
TextToken,
|
TextToken,
|
||||||
Token
|
Token
|
||||||
} from "remarkable/lib";
|
} from "remarkable/lib";
|
||||||
import {escapeBBCode} from "tc-shared/text/bbcode";
|
import {escapeBBCode} from "../text/bbcode";
|
||||||
const { Remarkable } = require("remarkable");
|
const { Remarkable } = require("remarkable");
|
||||||
|
|
||||||
export class MD2BBCodeRenderer {
|
export class MD2BBCodeRenderer {
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
import {ChannelTree} from "./ChannelTree";
|
import {ChannelTree} from "./ChannelTree";
|
||||||
import {ClientEntry, ClientEvents} from "./Client";
|
import {ClientEntry, ClientEvents} from "./Client";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory, LogType} from "tc-shared/log";
|
import {LogCategory, LogType} from "../log";
|
||||||
import {PermissionType} from "tc-shared/permission/PermissionType";
|
import {PermissionType} from "../permission/PermissionType";
|
||||||
import {settings, Settings} from "tc-shared/settings";
|
import {settings, Settings} from "../settings";
|
||||||
import * as contextmenu from "tc-shared/ui/elements/ContextMenu";
|
import * as contextmenu from "../ui/elements/ContextMenu";
|
||||||
import {MenuEntryType} from "tc-shared/ui/elements/ContextMenu";
|
import {MenuEntryType} from "../ui/elements/ContextMenu";
|
||||||
import {Sound} from "tc-shared/sound/Sounds";
|
import {Sound} from "../sound/Sounds";
|
||||||
import {createErrorModal, createInfoModal, createInputModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInfoModal, createInputModal} from "../ui/elements/Modal";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||||
import * as htmltags from "../ui/htmltags";
|
import * as htmltags from "../ui/htmltags";
|
||||||
import {hashPassword} from "tc-shared/utils/helpers";
|
import {hashPassword} from "../utils/helpers";
|
||||||
import {openChannelInfo} from "tc-shared/ui/modal/ModalChannelInfo";
|
import {openChannelInfo} from "../ui/modal/ModalChannelInfo";
|
||||||
import {createChannelModal} from "tc-shared/ui/modal/ModalCreateChannel";
|
import {createChannelModal} from "../ui/modal/ModalCreateChannel";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../ui/frames/chat";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {ChannelTreeEntry, ChannelTreeEntryEvents} from "./ChannelTreeEntry";
|
import {ChannelTreeEntry, ChannelTreeEntryEvents} from "./ChannelTreeEntry";
|
||||||
import {ChannelEntryView as ChannelEntryView} from "../ui/tree/Channel";
|
import {ChannelEntryView as ChannelEntryView} from "../ui/tree/Channel";
|
||||||
import {spawnFileTransferModal} from "tc-shared/ui/modal/transfer/ModalFileTransfer";
|
import {spawnFileTransferModal} from "../ui/modal/transfer/ModalFileTransfer";
|
||||||
import {ViewReasonId} from "tc-shared/ConnectionHandler";
|
import {ViewReasonId} from "../ConnectionHandler";
|
||||||
import {EventChannelData} from "tc-shared/ui/frames/log/Definitions";
|
import {EventChannelData} from "../ui/frames/log/Definitions";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../connection/ErrorCode";
|
||||||
|
|
||||||
export enum ChannelType {
|
export enum ChannelType {
|
||||||
PERMANENT,
|
PERMANENT,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
|
|
||||||
export interface ChannelTreeEntryEvents {
|
export interface ChannelTreeEntryEvents {
|
||||||
notify_select_state_change: { selected: boolean },
|
notify_select_state_change: { selected: boolean },
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
import * as contextmenu from "tc-shared/ui/elements/ContextMenu";
|
import * as contextmenu from "../ui/elements/ContextMenu";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {ChannelTree} from "./ChannelTree";
|
import {ChannelTree} from "./ChannelTree";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory, logInfo, LogType} from "tc-shared/log";
|
import {LogCategory, logInfo, LogType} from "../log";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../settings";
|
||||||
import {Sound} from "tc-shared/sound/Sounds";
|
import {Sound} from "../sound/Sounds";
|
||||||
import {Group, GroupManager, GroupTarget, GroupType} from "tc-shared/permission/GroupManager";
|
import {Group, GroupManager, GroupTarget, GroupType} from "../permission/GroupManager";
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import PermissionType from "../permission/PermissionType";
|
||||||
import {createErrorModal, createInputModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInputModal} from "../ui/elements/Modal";
|
||||||
import * as htmltags from "tc-shared/ui/htmltags";
|
import * as htmltags from "../ui/htmltags";
|
||||||
import {CommandResult, PlaylistSong} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult, PlaylistSong} from "../connection/ServerConnectionDeclaration";
|
||||||
import {ChannelEntry} from "./Channel";
|
import {ChannelEntry} from "./Channel";
|
||||||
import {ConnectionHandler, ViewReasonId} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler, ViewReasonId} from "../ConnectionHandler";
|
||||||
import {createServerGroupAssignmentModal} from "tc-shared/ui/modal/ModalGroupAssignment";
|
import {createServerGroupAssignmentModal} from "../ui/modal/ModalGroupAssignment";
|
||||||
import {openClientInfo} from "tc-shared/ui/modal/ModalClientInfo";
|
import {openClientInfo} from "../ui/modal/ModalClientInfo";
|
||||||
import {spawnBanClient} from "tc-shared/ui/modal/ModalBanClient";
|
import {spawnBanClient} from "../ui/modal/ModalBanClient";
|
||||||
import {spawnChangeLatency} from "tc-shared/ui/modal/ModalChangeLatency";
|
import {spawnChangeLatency} from "../ui/modal/ModalChangeLatency";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../ui/frames/chat";
|
||||||
import {spawnYesNo} from "tc-shared/ui/modal/ModalYesNo";
|
import {spawnYesNo} from "../ui/modal/ModalYesNo";
|
||||||
import * as hex from "tc-shared/crypto/hex";
|
import * as hex from "../crypto/hex";
|
||||||
import {ClientEntry as ClientEntryView} from "../ui/tree/Client";
|
import {ClientEntry as ClientEntryView} from "../ui/tree/Client";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {ChannelTreeEntry, ChannelTreeEntryEvents} from "./ChannelTreeEntry";
|
import {ChannelTreeEntry, ChannelTreeEntryEvents} from "./ChannelTreeEntry";
|
||||||
import {spawnClientVolumeChange, spawnMusicBotVolumeChange} from "tc-shared/ui/modal/ModalChangeVolumeNew";
|
import {spawnClientVolumeChange, spawnMusicBotVolumeChange} from "../ui/modal/ModalChangeVolumeNew";
|
||||||
import {spawnPermissionEditorModal} from "tc-shared/ui/modal/permission/ModalPermissionEditor";
|
import {spawnPermissionEditorModal} from "../ui/modal/permission/ModalPermissionEditor";
|
||||||
import {EventClient, EventType} from "tc-shared/ui/frames/log/Definitions";
|
import {EventClient, EventType} from "../ui/frames/log/Definitions";
|
||||||
import {W2GPluginCmdHandler} from "tc-shared/video-viewer/W2GPlugin";
|
import {W2GPluginCmdHandler} from "../video-viewer/W2GPlugin";
|
||||||
import {global_client_actions} from "tc-shared/events/GlobalEvents";
|
import {global_client_actions} from "../events/GlobalEvents";
|
||||||
import {ClientIcon} from "svg-sprites/client-icons";
|
import {ClientIcon} from "svg-sprites/client-icons";
|
||||||
import {VoiceClient} from "tc-shared/voice/VoiceClient";
|
import {VoiceClient} from "../voice/VoiceClient";
|
||||||
import {VoicePlayerEvents, VoicePlayerState} from "tc-shared/voice/VoicePlayer";
|
import {VoicePlayerEvents, VoicePlayerState} from "../voice/VoicePlayer";
|
||||||
|
|
||||||
export enum ClientType {
|
export enum ClientType {
|
||||||
CLIENT_VOICE,
|
CLIENT_VOICE,
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
import {ChannelTree} from "./ChannelTree";
|
import {ChannelTree} from "./ChannelTree";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../settings";
|
||||||
import * as contextmenu from "tc-shared/ui/elements/ContextMenu";
|
import * as contextmenu from "../ui/elements/ContextMenu";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory, LogType} from "tc-shared/log";
|
import {LogCategory, LogType} from "../log";
|
||||||
import {Sound} from "tc-shared/sound/Sounds";
|
import {Sound} from "../sound/Sounds";
|
||||||
import * as bookmarks from "tc-shared/bookmarks";
|
import * as bookmarks from "../bookmarks";
|
||||||
import {spawnInviteEditor} from "tc-shared/ui/modal/ModalInvite";
|
import {spawnInviteEditor} from "../ui/modal/ModalInvite";
|
||||||
import {openServerInfo} from "tc-shared/ui/modal/ModalServerInfo";
|
import {openServerInfo} from "../ui/modal/ModalServerInfo";
|
||||||
import {createServerModal} from "tc-shared/ui/modal/ModalServerEdit";
|
import {createServerModal} from "../ui/modal/ModalServerEdit";
|
||||||
import {spawnIconSelect} from "tc-shared/ui/modal/ModalIconSelect";
|
import {spawnIconSelect} from "../ui/modal/ModalIconSelect";
|
||||||
import {spawnAvatarList} from "tc-shared/ui/modal/ModalAvatarList";
|
import {spawnAvatarList} from "../ui/modal/ModalAvatarList";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "../ui/frames/connection_handlers";
|
||||||
import {connection_log} from "tc-shared/ui/modal/ModalConnect";
|
import {connection_log} from "../ui/modal/ModalConnect";
|
||||||
import * as top_menu from "../ui/frames/MenuBar";
|
import * as top_menu from "../ui/frames/MenuBar";
|
||||||
import {control_bar_instance} from "tc-shared/ui/frames/control-bar";
|
import {control_bar_instance} from "../ui/frames/control-bar";
|
||||||
import { ServerEntry as ServerEntryView } from "../ui/tree/Server";
|
import { ServerEntry as ServerEntryView } from "../ui/tree/Server";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../events";
|
||||||
import {ChannelTreeEntry, ChannelTreeEntryEvents} from "./ChannelTreeEntry";
|
import {ChannelTreeEntry, ChannelTreeEntryEvents} from "./ChannelTreeEntry";
|
||||||
|
|
||||||
export class ServerProperties {
|
export class ServerProperties {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../../settings";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface JQuery<TElement = HTMLElement> {
|
interface JQuery<TElement = HTMLElement> {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import {Stage} from "tc-loader";
|
import {Stage} from "tc-loader";
|
||||||
import {KeyCode} from "tc-shared/PPTListener";
|
import {KeyCode} from "../../PPTListener";
|
||||||
import * as $ from "jquery";
|
import * as $ from "jquery";
|
||||||
|
|
||||||
export enum ElementType {
|
export enum ElementType {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
|
|
||||||
export interface SliderOptions {
|
export interface SliderOptions {
|
||||||
min_value?: number;
|
min_value?: number;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {spawnBookmarkModal} from "tc-shared/ui/modal/ModalBookmarks";
|
import {spawnBookmarkModal} from "../../ui/modal/ModalBookmarks";
|
||||||
import {
|
import {
|
||||||
add_server_to_bookmarks,
|
add_server_to_bookmarks,
|
||||||
Bookmark,
|
Bookmark,
|
||||||
|
@ -6,25 +6,25 @@ import {
|
||||||
BookmarkType,
|
BookmarkType,
|
||||||
boorkmak_connect,
|
boorkmak_connect,
|
||||||
DirectoryBookmark
|
DirectoryBookmark
|
||||||
} from "tc-shared/bookmarks";
|
} from "../../bookmarks";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {Sound} from "tc-shared/sound/Sounds";
|
import {Sound} from "../../sound/Sounds";
|
||||||
import {spawnConnectModal} from "tc-shared/ui/modal/ModalConnect";
|
import {spawnConnectModal} from "../../ui/modal/ModalConnect";
|
||||||
import {createErrorModal, createInfoModal, createInputModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInfoModal, createInputModal} from "../../ui/elements/Modal";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {PermissionType} from "tc-shared/permission/PermissionType";
|
import {PermissionType} from "../../permission/PermissionType";
|
||||||
import {openBanList} from "tc-shared/ui/modal/ModalBanList";
|
import {openBanList} from "../../ui/modal/ModalBanList";
|
||||||
import {spawnQueryManage} from "tc-shared/ui/modal/ModalQueryManage";
|
import {spawnQueryManage} from "../../ui/modal/ModalQueryManage";
|
||||||
import {spawnQueryCreate} from "tc-shared/ui/modal/ModalQuery";
|
import {spawnQueryCreate} from "../../ui/modal/ModalQuery";
|
||||||
import {spawnSettingsModal} from "tc-shared/ui/modal/ModalSettings";
|
import {spawnSettingsModal} from "../../ui/modal/ModalSettings";
|
||||||
import {spawnAbout} from "tc-shared/ui/modal/ModalAbout";
|
import {spawnAbout} from "../../ui/modal/ModalAbout";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "../../ui/frames/connection_handlers";
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../../ui/frames/chat";
|
||||||
import {control_bar_instance} from "tc-shared/ui/frames/control-bar";
|
import {control_bar_instance} from "../../ui/frames/control-bar";
|
||||||
import {icon_cache_loader, IconManager, LocalIcon} from "tc-shared/file/Icons";
|
import {icon_cache_loader, IconManager, LocalIcon} from "../../file/Icons";
|
||||||
import {spawnPermissionEditorModal} from "tc-shared/ui/modal/permission/ModalPermissionEditor";
|
import {spawnPermissionEditorModal} from "../../ui/modal/permission/ModalPermissionEditor";
|
||||||
import {spawnModalCssVariableEditor} from "tc-shared/ui/modal/css-editor/Controller";
|
import {spawnModalCssVariableEditor} from "../../ui/modal/css-editor/Controller";
|
||||||
|
|
||||||
export interface HRItem { }
|
export interface HRItem { }
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import {settings, Settings} from "tc-shared/settings";
|
import {settings, Settings} from "../../settings";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
|
|
||||||
export enum ChatType {
|
export enum ChatType {
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
/* the bar on the right with the chats (Channel & Client) */
|
/* the bar on the right with the chats (Channel & Client) */
|
||||||
import {ClientEntry, MusicClientEntry} from "tc-shared/tree/Client";
|
import {ClientEntry, MusicClientEntry} from "../../tree/Client";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {ChannelEntry} from "tc-shared/tree/Channel";
|
import {ChannelEntry} from "../../tree/Channel";
|
||||||
import {ServerEntry} from "tc-shared/tree/Server";
|
import {ServerEntry} from "../../tree/Server";
|
||||||
import {openMusicManage} from "tc-shared/ui/modal/ModalMusicManage";
|
import {openMusicManage} from "../../ui/modal/ModalMusicManage";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../../ui/frames/chat";
|
||||||
import {ClientInfo} from "tc-shared/ui/frames/side/client_info";
|
import {ClientInfo} from "../../ui/frames/side/client_info";
|
||||||
import {MusicInfo} from "tc-shared/ui/frames/side/music_info";
|
import {MusicInfo} from "../../ui/frames/side/music_info";
|
||||||
import {ConversationManager} from "tc-shared/ui/frames/side/ConversationManager";
|
import {ConversationManager} from "../../ui/frames/side/ConversationManager";
|
||||||
import {PrivateConversationManager} from "tc-shared/ui/frames/side/PrivateConversationManager";
|
import {PrivateConversationManager} from "../../ui/frames/side/PrivateConversationManager";
|
||||||
|
|
||||||
export enum InfoFrameMode {
|
export enum InfoFrameMode {
|
||||||
NONE = "none",
|
NONE = "none",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {ConnectionHandler, DisconnectReason} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler, DisconnectReason} from "../../ConnectionHandler";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../../settings";
|
||||||
import * as top_menu from "./MenuBar";
|
import * as top_menu from "./MenuBar";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../../events";
|
||||||
|
|
||||||
export let server_connections: ConnectionManager;
|
export let server_connections: ConnectionManager;
|
||||||
export function initialize() {
|
export function initialize() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {settings, Settings} from "tc-shared/settings";
|
import {settings, Settings} from "../../settings";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
|
|
||||||
export class Hostbanner {
|
export class Hostbanner {
|
||||||
readonly html_tag: JQuery<HTMLElement>;
|
readonly html_tag: JQuery<HTMLElement>;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {PermissionInfo} from "tc-shared/permission/PermissionManager";
|
import {PermissionInfo} from "../../../permission/PermissionManager";
|
||||||
import {ViewReasonId} from "tc-shared/ConnectionHandler";
|
import {ViewReasonId} from "../../../ConnectionHandler";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {ServerEventLog} from "tc-shared/ui/frames/log/ServerEventLog";
|
import {ServerEventLog} from "../../../ui/frames/log/ServerEventLog";
|
||||||
|
|
||||||
export enum EventType {
|
export enum EventType {
|
||||||
CONNECTION_BEGIN = "connection.begin",
|
CONNECTION_BEGIN = "connection.begin",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {EventType} from "tc-shared/ui/frames/log/Definitions";
|
import {EventType} from "../../../ui/frames/log/Definitions";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../../../settings";
|
||||||
|
|
||||||
const focusDefaultStatus = {};
|
const focusDefaultStatus = {};
|
||||||
focusDefaultStatus[EventType.CLIENT_POKE_RECEIVED] = true;
|
focusDefaultStatus[EventType.CLIENT_POKE_RECEIVED] = true;
|
||||||
|
|
|
@ -2,14 +2,14 @@ import * as loader from "tc-loader";
|
||||||
import {Stage} from "tc-loader";
|
import {Stage} from "tc-loader";
|
||||||
import * as log from "../../../log";
|
import * as log from "../../../log";
|
||||||
import {LogCategory} from "../../../log";
|
import {LogCategory} from "../../../log";
|
||||||
import {EventClient, EventServerAddress, EventType, TypeInfo} from "tc-shared/ui/frames/log/Definitions";
|
import {EventClient, EventServerAddress, EventType, TypeInfo} from "../../../ui/frames/log/Definitions";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "../../../ui/frames/connection_handlers";
|
||||||
import {renderBBCodeAsText} from "tc-shared/text/bbcode";
|
import {renderBBCodeAsText} from "../../../text/bbcode";
|
||||||
import {format_time} from "tc-shared/ui/frames/chat";
|
import {format_time} from "../../../ui/frames/chat";
|
||||||
import {ViewReasonId} from "tc-shared/ConnectionHandler";
|
import {ViewReasonId} from "../../../ConnectionHandler";
|
||||||
import {findLogDispatcher} from "tc-shared/ui/frames/log/DispatcherLog";
|
import {findLogDispatcher} from "../../../ui/frames/log/DispatcherLog";
|
||||||
import {formatDate} from "tc-shared/MessageFormatter";
|
import {formatDate} from "../../../MessageFormatter";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../../../settings";
|
||||||
|
|
||||||
export type DispatcherLog<T extends keyof TypeInfo> = (data: TypeInfo[T], handlerId: string, eventType: T) => void;
|
export type DispatcherLog<T extends keyof TypeInfo> = (data: TypeInfo[T], handlerId: string, eventType: T) => void;
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,15 @@ import {
|
||||||
ChatEventMessage, ChatHistoryState, ChatMessage,
|
ChatEventMessage, ChatHistoryState, ChatMessage,
|
||||||
ChatState, ConversationHistoryResponse,
|
ChatState, ConversationHistoryResponse,
|
||||||
ConversationUIEvents
|
ConversationUIEvents
|
||||||
} from "tc-shared/ui/frames/side/ConversationDefinitions";
|
} from "../../../ui/frames/side/ConversationDefinitions";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../../ConnectionHandler";
|
||||||
import {EventHandler, Registry} from "tc-shared/events";
|
import {EventHandler, Registry} from "../../../events";
|
||||||
import {preprocessChatMessageForSend} from "tc-shared/text/chat";
|
import {preprocessChatMessageForSend} from "../../../text/chat";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../../connection/ServerConnectionDeclaration";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../../log";
|
||||||
import {tra} from "tc-shared/i18n/localize";
|
import {tra} from "../../../i18n/localize";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../../../connection/ErrorCode";
|
||||||
|
|
||||||
export const kMaxChatFrameMessageSize = 50; /* max 100 messages, since the server does not support more than 100 messages queried at once */
|
export const kMaxChatFrameMessageSize = 50; /* max 100 messages, since the server does not support more than 100 messages queried at once */
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {ConnectionHandler, ConnectionState} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler, ConnectionState} from "../../../ConnectionHandler";
|
||||||
import {EventHandler, Registry} from "tc-shared/events";
|
import {EventHandler, Registry} from "../../../events";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../../log";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../../connection/ServerConnectionDeclaration";
|
||||||
import {ServerCommand} from "tc-shared/connection/ConnectionBase";
|
import {ServerCommand} from "../../../connection/ConnectionBase";
|
||||||
import {Settings} from "tc-shared/settings";
|
import {Settings} from "../../../settings";
|
||||||
import {traj} from "tc-shared/i18n/localize";
|
import {traj} from "../../../i18n/localize";
|
||||||
import {createErrorModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal} from "../../../ui/elements/Modal";
|
||||||
import ReactDOM = require("react-dom");
|
import ReactDOM = require("react-dom");
|
||||||
import {
|
import {
|
||||||
ChatMessage, ConversationHistoryResponse,
|
ChatMessage, ConversationHistoryResponse,
|
||||||
ConversationUIEvents
|
ConversationUIEvents
|
||||||
} from "tc-shared/ui/frames/side/ConversationDefinitions";
|
} from "../../../ui/frames/side/ConversationDefinitions";
|
||||||
import {ConversationPanel} from "tc-shared/ui/frames/side/ConversationUI";
|
import {ConversationPanel} from "../../../ui/frames/side/ConversationUI";
|
||||||
import {AbstractChat, AbstractChatManager, kMaxChatFrameMessageSize} from "./AbstractConversion";
|
import {AbstractChat, AbstractChatManager, kMaxChatFrameMessageSize} from "./AbstractConversion";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../../../connection/ErrorCode";
|
||||||
|
|
||||||
const kSuccessQueryThrottle = 5 * 1000;
|
const kSuccessQueryThrottle = 5 * 1000;
|
||||||
const kErrorQueryThrottle = 30 * 1000;
|
const kErrorQueryThrottle = 30 * 1000;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {ConversationUIEvents} from "tc-shared/ui/frames/side/ConversationDefinitions";
|
import {ConversationUIEvents} from "../../../ui/frames/side/ConversationDefinitions";
|
||||||
|
|
||||||
export type PrivateConversationInfo = {
|
export type PrivateConversationInfo = {
|
||||||
nickname: string;
|
nickname: string;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import {Stage} from "tc-loader";
|
import {Stage} from "tc-loader";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../../log";
|
||||||
import {ChatEvent} from "tc-shared/ui/frames/side/ConversationDefinitions";
|
import {ChatEvent} from "../../../ui/frames/side/ConversationDefinitions";
|
||||||
|
|
||||||
const clientUniqueId2StoreName = uniqueId => "conversation-" + uniqueId;
|
const clientUniqueId2StoreName = uniqueId => "conversation-" + uniqueId;
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
import {ClientEntry} from "tc-shared/tree/Client";
|
import {ClientEntry} from "../../../tree/Client";
|
||||||
import {ConnectionHandler, ConnectionState} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler, ConnectionState} from "../../../ConnectionHandler";
|
||||||
import {EventHandler, Registry} from "tc-shared/events";
|
import {EventHandler, Registry} from "../../../events";
|
||||||
import {
|
import {
|
||||||
PrivateConversationInfo,
|
PrivateConversationInfo,
|
||||||
PrivateConversationUIEvents
|
PrivateConversationUIEvents
|
||||||
} from "tc-shared/ui/frames/side/PrivateConversationDefinitions";
|
} from "../../../ui/frames/side/PrivateConversationDefinitions";
|
||||||
import * as ReactDOM from "react-dom";
|
import * as ReactDOM from "react-dom";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {PrivateConversationsPanel} from "tc-shared/ui/frames/side/PrivateConversationUI";
|
import {PrivateConversationsPanel} from "../../../ui/frames/side/PrivateConversationUI";
|
||||||
import {
|
import {
|
||||||
ChatEvent,
|
ChatEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
ConversationHistoryResponse,
|
ConversationHistoryResponse,
|
||||||
ConversationUIEvents
|
ConversationUIEvents
|
||||||
} from "tc-shared/ui/frames/side/ConversationDefinitions";
|
} from "../../../ui/frames/side/ConversationDefinitions";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../../log";
|
||||||
import {queryConversationEvents, registerConversationEvent} from "tc-shared/ui/frames/side/PrivateConversationHistory";
|
import {queryConversationEvents, registerConversationEvent} from "../../../ui/frames/side/PrivateConversationHistory";
|
||||||
import {AbstractChat, AbstractChatManager} from "tc-shared/ui/frames/side/AbstractConversion";
|
import {AbstractChat, AbstractChatManager} from "../../../ui/frames/side/AbstractConversion";
|
||||||
|
|
||||||
export type OutOfViewClient = {
|
export type OutOfViewClient = {
|
||||||
nickname: string,
|
nickname: string,
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import {GroupManager} from "tc-shared/permission/GroupManager";
|
import {GroupManager} from "../../../permission/GroupManager";
|
||||||
import {Frame, FrameContent} from "tc-shared/ui/frames/chat_frame";
|
import {Frame, FrameContent} from "../../../ui/frames/chat_frame";
|
||||||
import {openClientInfo} from "tc-shared/ui/modal/ModalClientInfo";
|
import {openClientInfo} from "../../../ui/modal/ModalClientInfo";
|
||||||
import * as htmltags from "tc-shared/ui/htmltags";
|
import * as htmltags from "../../../ui/htmltags";
|
||||||
import * as image_preview from "../image_preview";
|
import * as image_preview from "../image_preview";
|
||||||
import * as i18nc from "tc-shared/i18n/country";
|
import * as i18nc from "../../../i18n/country";
|
||||||
import {ClientEntry, LocalClientEntry} from "tc-shared/tree/Client";
|
import {ClientEntry, LocalClientEntry} from "../../../tree/Client";
|
||||||
import {format_online_time} from "tc-shared/utils/TimeUtils";
|
import {format_online_time} from "../../../utils/TimeUtils";
|
||||||
|
|
||||||
export class ClientInfo {
|
export class ClientInfo {
|
||||||
readonly handle: Frame;
|
readonly handle: Frame;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import {Frame, FrameContent} from "tc-shared/ui/frames/chat_frame";
|
import {Frame, FrameContent} from "../../../ui/frames/chat_frame";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../../log";
|
||||||
import {CommandResult, PlaylistSong} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult, PlaylistSong} from "../../../connection/ServerConnectionDeclaration";
|
||||||
import {createErrorModal, createInputModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInputModal} from "../../../ui/elements/Modal";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../../log";
|
||||||
import * as image_preview from "../image_preview";
|
import * as image_preview from "../image_preview";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../../../events";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../../../connection/ErrorCode";
|
||||||
import {ClientEvents, MusicClientEntry, SongInfo} from "tc-shared/tree/Client";
|
import {ClientEvents, MusicClientEntry, SongInfo} from "../../../tree/Client";
|
||||||
|
|
||||||
export interface MusicSidebarEvents {
|
export interface MusicSidebarEvents {
|
||||||
"open": {}, /* triggers when frame should be shown */
|
"open": {}, /* triggers when frame should be shown */
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
import {ChannelEntry} from "tc-shared/tree/Channel";
|
import {ChannelEntry} from "../tree/Channel";
|
||||||
import {ClientEntry} from "tc-shared/tree/Client";
|
import {ClientEntry} from "../tree/Client";
|
||||||
import {htmlEscape} from "tc-shared/ui/frames/chat";
|
import {htmlEscape} from "../ui/frames/chat";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "../ui/frames/connection_handlers";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "../crypto/uid";
|
||||||
|
|
||||||
let mouse_coordinates: {x: number, y: number} = {x: 0, y: 0};
|
let mouse_coordinates: {x: number, y: number} = {x: 0, y: 0};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../log";
|
||||||
|
|
||||||
export function setupJSRender() : boolean {
|
export function setupJSRender() : boolean {
|
||||||
if(!$.views) {
|
if(!$.views) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {createModal} from "tc-shared/ui/elements/Modal";
|
import {createModal} from "../../ui/elements/Modal";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import * as log from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
|
|
||||||
function format_date(date: number) {
|
function format_date(date: number) {
|
||||||
const d = new Date(date);
|
const d = new Date(date);
|
||||||
|
@ -29,7 +29,7 @@ export function spawnAbout() {
|
||||||
connectModal.htmlTag.find(".modal-body").addClass("modal-about");
|
connectModal.htmlTag.find(".modal-body").addClass("modal-about");
|
||||||
connectModal.open();
|
connectModal.open();
|
||||||
|
|
||||||
if(__build.target !== "web") {
|
if (__build.target !== "web") {
|
||||||
(window as any).native.client_version().then(version => {
|
(window as any).native.client_version().then(version => {
|
||||||
connectModal.htmlTag.find(".version-client").text(version);
|
connectModal.htmlTag.find(".version-client").text(version);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//TODO: Test if we could render this image and not only the browser by knowing the type.
|
//TODO: Test if we could render this image and not only the browser by knowing the type.
|
||||||
import {createErrorModal, createModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createModal} from "../../ui/elements/Modal";
|
||||||
import {tra} from "tc-shared/i18n/localize";
|
import {tra} from "../../i18n/localize";
|
||||||
import {arrayBufferBase64} from "tc-shared/utils/buffers";
|
import {arrayBufferBase64} from "../../utils/buffers";
|
||||||
|
|
||||||
export function spawnAvatarUpload(callback_data: (data: ArrayBuffer | undefined | null) => any) {
|
export function spawnAvatarUpload(callback_data: (data: ArrayBuffer | undefined | null) => any) {
|
||||||
const modal = createModal({
|
const modal = createModal({
|
||||||
|
@ -20,7 +20,7 @@ export function spawnAvatarUpload(callback_data: (data: ArrayBuffer | undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
modal.htmlTag.find(".button-delete").on('click', () => {
|
modal.htmlTag.find(".button-delete").on('click', () => {
|
||||||
if(_data_submitted)
|
if (_data_submitted)
|
||||||
return;
|
return;
|
||||||
_data_submitted = true;
|
_data_submitted = true;
|
||||||
modal.close();
|
modal.close();
|
||||||
|
@ -54,7 +54,7 @@ export function spawnAvatarUpload(callback_data: (data: ArrayBuffer | undefined
|
||||||
(async () => {
|
(async () => {
|
||||||
const data = await read_file(input_node.files[0]);
|
const data = await read_file(input_node.files[0]);
|
||||||
|
|
||||||
if(!data.startsWith("data:image/")) {
|
if (!data.startsWith("data:image/")) {
|
||||||
console.error(tr("Failed to load file %s: Invalid data media type (%o)"), input_node.files[0].name, data);
|
console.error(tr("Failed to load file %s: Invalid data media type (%o)"), input_node.files[0].name, data);
|
||||||
createErrorModal(tr("Icon upload failed"), tra("Failed to select avatar {}.<br>File is not an image", input_node.files[0].name)).open();
|
createErrorModal(tr("Icon upload failed"), tra("Failed to select avatar {}.<br>File is not an image", input_node.files[0].name)).open();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import {createErrorModal, createModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createModal} from "../../ui/elements/Modal";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {LogCategory} from "../../log";
|
||||||
import {base64_encode_ab} from "tc-shared/utils/buffers";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {spawnYesNo} from "tc-shared/ui/modal/ModalYesNo";
|
import {base64_encode_ab} from "../../utils/buffers";
|
||||||
import {ClientEntry} from "tc-shared/tree/Client";
|
import {spawnYesNo} from "../../ui/modal/ModalYesNo";
|
||||||
import * as log from "tc-shared/log";
|
import {ClientEntry} from "../../tree/Client";
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
|
|
||||||
const avatar_to_uid = (id: string) => {
|
const avatar_to_uid = (id: string) => {
|
||||||
const buffer = new Uint8Array(id.length / 2);
|
const buffer = new Uint8Array(id.length / 2);
|
||||||
for(let index = 0; index < id.length; index += 2) {
|
for (let index = 0; index < id.length; index += 2) {
|
||||||
const upper_nibble = id.charCodeAt(index) - 97;
|
const upper_nibble = id.charCodeAt(index) - 97;
|
||||||
const lower_nibble = id.charCodeAt(index + 1) - 97;
|
const lower_nibble = id.charCodeAt(index + 1) - 97;
|
||||||
buffer[index / 2] = (upper_nibble << 4) | lower_nibble;
|
buffer[index / 2] = (upper_nibble << 4) | lower_nibble;
|
||||||
|
@ -18,7 +18,7 @@ const avatar_to_uid = (id: string) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const human_file_size = (size: number) => {
|
export const human_file_size = (size: number) => {
|
||||||
if(size < 1000)
|
if (size < 1000)
|
||||||
return size + "B";
|
return size + "B";
|
||||||
const exp = Math.floor(Math.log2(size) / 10);
|
const exp = Math.floor(Math.log2(size) / 10);
|
||||||
return (size / Math.pow(1024, exp)).toFixed(2) + 'KMGTPE'.charAt(exp - 1) + "iB";
|
return (size / Math.pow(1024, exp)).toFixed(2) + 'KMGTPE'.charAt(exp - 1) + "iB";
|
||||||
|
@ -48,7 +48,7 @@ export function spawnAvatarList(client: ConnectionHandler) {
|
||||||
const set_selected_avatar = (unique_id: string, avatar_id: string, size: number) => {
|
const set_selected_avatar = (unique_id: string, avatar_id: string, size: number) => {
|
||||||
button_download.prop("disabled", true);
|
button_download.prop("disabled", true);
|
||||||
callback_download = undefined;
|
callback_download = undefined;
|
||||||
if(!unique_id) {
|
if (!unique_id) {
|
||||||
overlay_no_user.show();
|
overlay_no_user.show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ export function spawnAvatarList(client: ConnectionHandler) {
|
||||||
|
|
||||||
callback_delete = () => {
|
callback_delete = () => {
|
||||||
spawnYesNo(tr("Are you sure?"), tr("Do you really want to delete this avatar?"), result => {
|
spawnYesNo(tr("Are you sure?"), tr("Do you really want to delete this avatar?"), result => {
|
||||||
if(result) {
|
if (result) {
|
||||||
createErrorModal(tr("Not implemented"), tr("Avatar delete hasn't implemented yet")).open();
|
createErrorModal(tr("Not implemented"), tr("Avatar delete hasn't implemented yet")).open();
|
||||||
//TODO Implement avatar delete
|
//TODO Implement avatar delete
|
||||||
}
|
}
|
||||||
|
@ -108,8 +108,8 @@ export function spawnAvatarList(client: ConnectionHandler) {
|
||||||
list_entries.empty();
|
list_entries.empty();
|
||||||
|
|
||||||
client.fileManager.requestFileList("/").then(files => {
|
client.fileManager.requestFileList("/").then(files => {
|
||||||
const username_resolve: {[unique_id: string]:((name:string) => any)[]} = {};
|
const username_resolve: { [unique_id: string]: ((name: string) => any)[] } = {};
|
||||||
for(const entry of files) {
|
for (const entry of files) {
|
||||||
const avatar_id = entry.name.substr('avatar_'.length);
|
const avatar_id = entry.name.substr('avatar_'.length);
|
||||||
const unique_id = avatar_to_uid(avatar_id);
|
const unique_id = avatar_to_uid(avatar_id);
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ export function spawnAvatarList(client: ConnectionHandler) {
|
||||||
|
|
||||||
(username_resolve[unique_id] || (username_resolve[unique_id] = [])).push(name => {
|
(username_resolve[unique_id] || (username_resolve[unique_id] = [])).push(name => {
|
||||||
const tag_username = tag.find(".column-username").empty();
|
const tag_username = tag.find(".column-username").empty();
|
||||||
if(name) {
|
if (name) {
|
||||||
tag_username.append(ClientEntry.chatTag(0, name, unique_id, false));
|
tag_username.append(ClientEntry.chatTag(0, name, unique_id, false));
|
||||||
} else {
|
} else {
|
||||||
tag_username.text("unknown");
|
tag_username.text("unknown");
|
||||||
|
@ -138,15 +138,15 @@ export function spawnAvatarList(client: ConnectionHandler) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(container_list.hasScrollBar())
|
if (container_list.hasScrollBar())
|
||||||
container_list.addClass("scrollbar");
|
container_list.addClass("scrollbar");
|
||||||
|
|
||||||
client.serverConnection.command_helper.getInfoFromUniqueId(...Object.keys(username_resolve)).then(result => {
|
client.serverConnection.command_helper.getInfoFromUniqueId(...Object.keys(username_resolve)).then(result => {
|
||||||
for(const info of result) {
|
for (const info of result) {
|
||||||
username_resolve[info.clientUniqueId].forEach(e => e(info.clientNickname));
|
username_resolve[info.clientUniqueId].forEach(e => e(info.clientNickname));
|
||||||
delete username_resolve[info.clientUniqueId];
|
delete username_resolve[info.clientUniqueId];
|
||||||
}
|
}
|
||||||
for(const uid of Object.keys(username_resolve)) {
|
for (const uid of Object.keys(username_resolve)) {
|
||||||
(username_resolve[uid] || []).forEach(e => e(undefined));
|
(username_resolve[uid] || []).forEach(e => e(undefined));
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
@ -160,8 +160,10 @@ export function spawnAvatarList(client: ConnectionHandler) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
button_download.on('click', () => (callback_download || (() => {}))());
|
button_download.on('click', () => (callback_download || (() => {
|
||||||
button_delete.on('click', () => (callback_delete || (() => {}))());
|
}))());
|
||||||
|
button_delete.on('click', () => (callback_delete || (() => {
|
||||||
|
}))());
|
||||||
setTimeout(() => update_avatar_list(), 250);
|
setTimeout(() => update_avatar_list(), 250);
|
||||||
modal.open();
|
modal.open();
|
||||||
}
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import PermissionType from "../../permission/PermissionType";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {createModal} from "tc-shared/ui/elements/Modal";
|
import {createModal} from "../../ui/elements/Modal";
|
||||||
import {duration_data} from "tc-shared/ui/modal/ModalBanList";
|
import {duration_data} from "../../ui/modal/ModalBanList";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
|
|
||||||
export type BanEntry = {
|
export type BanEntry = {
|
||||||
name?: string;
|
name?: string;
|
||||||
unique_id: string;
|
unique_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function spawnBanClient(client: ConnectionHandler, entries: BanEntry | BanEntry[], callback: (data: {
|
export function spawnBanClient(client: ConnectionHandler, entries: BanEntry | BanEntry[], callback: (data: {
|
||||||
length: number,
|
length: number,
|
||||||
reason: string,
|
reason: string,
|
||||||
|
@ -58,8 +59,8 @@ export function spawnBanClient(client: ConnectionHandler, entries: BanEntry | Ba
|
||||||
const disabled = input_duration_type.prop("disabled");
|
const disabled = input_duration_type.prop("disabled");
|
||||||
|
|
||||||
input_duration_value.prop("disabled", type === "perm" || disabled).firstParent(".input-boxed").toggleClass("disabled", type === "perm" || disabled);
|
input_duration_value.prop("disabled", type === "perm" || disabled).firstParent(".input-boxed").toggleClass("disabled", type === "perm" || disabled);
|
||||||
if(type !== "perm") {
|
if (type !== "perm") {
|
||||||
if(input_duration_value.attr("x-saved-value")) {
|
if (input_duration_value.attr("x-saved-value")) {
|
||||||
input_duration_value.val(parseInt(input_duration_value.attr("x-saved-value")));
|
input_duration_value.val(parseInt(input_duration_value.attr("x-saved-value")));
|
||||||
input_duration_value.attr("x-saved-value", null);
|
input_duration_value.attr("x-saved-value", null);
|
||||||
}
|
}
|
||||||
|
@ -68,18 +69,18 @@ export function spawnBanClient(client: ConnectionHandler, entries: BanEntry | Ba
|
||||||
const max = parseInt(selected_option.attr("duration-max"));
|
const max = parseInt(selected_option.attr("duration-max"));
|
||||||
|
|
||||||
input_duration_value.attr("max", max);
|
input_duration_value.attr("max", max);
|
||||||
if((value > max && max != -1) || value < 1) {
|
if ((value > max && max != -1) || value < 1) {
|
||||||
input_duration_value.firstParent(".input-boxed").addClass("is-invalid");
|
input_duration_value.firstParent(".input-boxed").addClass("is-invalid");
|
||||||
} else {
|
} else {
|
||||||
input_duration_value.firstParent(".input-boxed").removeClass("is-invalid");
|
input_duration_value.firstParent(".input-boxed").removeClass("is-invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(max != -1)
|
if (max != -1)
|
||||||
tooltip_duration_max.html(tr("You're allowed to ban a maximum of ") + "<b>" + max + " " + duration_data[type][max == 1 ? "1-text" : "text"] + "</b>");
|
tooltip_duration_max.html(tr("You're allowed to ban a maximum of ") + "<b>" + max + " " + duration_data[type][max == 1 ? "1-text" : "text"] + "</b>");
|
||||||
else
|
else
|
||||||
tooltip_duration_max.html(tr("You're allowed to ban <b>permanent</b>."));
|
tooltip_duration_max.html(tr("You're allowed to ban <b>permanent</b>."));
|
||||||
} else {
|
} else {
|
||||||
if(value && !Number.isNaN(value))
|
if (value && !Number.isNaN(value))
|
||||||
input_duration_value.attr("x-saved-value", value);
|
input_duration_value.attr("x-saved-value", value);
|
||||||
input_duration_value.attr("placeholder", tr("for ever")).val(null);
|
input_duration_value.attr("placeholder", tr("for ever")).val(null);
|
||||||
tooltip_duration_max.html(tr("You're allowed to ban <b>permanent</b>."));
|
tooltip_duration_max.html(tr("You're allowed to ban <b>permanent</b>."));
|
||||||
|
@ -88,15 +89,17 @@ export function spawnBanClient(client: ConnectionHandler, entries: BanEntry | Ba
|
||||||
};
|
};
|
||||||
|
|
||||||
/* initialize ban time */
|
/* initialize ban time */
|
||||||
Promise.resolve(max_ban_time).catch(error => { /* TODO: Error handling? */ return 0; }).then(max_time => {
|
Promise.resolve(max_ban_time).catch(error => { /* TODO: Error handling? */
|
||||||
|
return 0;
|
||||||
|
}).then(max_time => {
|
||||||
let unlimited = max_time == 0 || max_time == -1;
|
let unlimited = max_time == 0 || max_time == -1;
|
||||||
if(unlimited || typeof(max_time) === "undefined") max_time = 0;
|
if (unlimited || typeof (max_time) === "undefined") max_time = 0;
|
||||||
|
|
||||||
for(const value of Object.keys(duration_data)) {
|
for (const value of Object.keys(duration_data)) {
|
||||||
input_duration_type.find("option[value='" + value + "']")
|
input_duration_type.find("option[value='" + value + "']")
|
||||||
.prop("disabled", !unlimited && max_time >= duration_data[value].scale)
|
.prop("disabled", !unlimited && max_time >= duration_data[value].scale)
|
||||||
.attr("duration-scale", duration_data[value].scale)
|
.attr("duration-scale", duration_data[value].scale)
|
||||||
.attr("duration-max", unlimited ? -1 : Math.floor(max_time / duration_data[value].scale));
|
.attr("duration-max", unlimited ? -1 : Math.floor(max_time / duration_data[value].scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
input_duration_type.find("option[value='perm']")
|
input_duration_type.find("option[value='perm']")
|
||||||
|
@ -114,7 +117,7 @@ export function spawnBanClient(client: ConnectionHandler, entries: BanEntry | Ba
|
||||||
const input = container_reason.find("textarea");
|
const input = container_reason.find("textarea");
|
||||||
|
|
||||||
const insert_tag = (open: string, close: string) => {
|
const insert_tag = (open: string, close: string) => {
|
||||||
if(input.prop("disabled"))
|
if (input.prop("disabled"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const node = input[0] as HTMLTextAreaElement;
|
const node = input[0] as HTMLTextAreaElement;
|
||||||
|
@ -145,7 +148,7 @@ export function spawnBanClient(client: ConnectionHandler, entries: BanEntry | Ba
|
||||||
{
|
{
|
||||||
button_cancel.on('click', event => modal.close());
|
button_cancel.on('click', event => modal.close());
|
||||||
button_ok.on('click', event => {
|
button_ok.on('click', event => {
|
||||||
const duration = input_duration_type.val() === "perm" ? 0 : (1000 * parseInt(input_duration_type.find("option[value='" + input_duration_type.val() + "']").attr("duration-scale")) * parseInt(input_duration_value.val() as string));
|
const duration = input_duration_type.val() === "perm" ? 0 : (1000 * parseInt(input_duration_type.find("option[value='" + input_duration_type.val() + "']").attr("duration-scale")) * parseInt(input_duration_value.val() as string));
|
||||||
|
|
||||||
modal.close();
|
modal.close();
|
||||||
callback({
|
callback({
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {createErrorModal, createInfoModal, createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInfoModal, createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {SingleCommandHandler} from "tc-shared/connection/ConnectionBase";
|
import {SingleCommandHandler} from "../../connection/ConnectionBase";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import PermissionType from "../../permission/PermissionType";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import * as log from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
import * as htmltags from "tc-shared/ui/htmltags";
|
import * as htmltags from "../../ui/htmltags";
|
||||||
import {format_time, formatMessage} from "tc-shared/ui/frames/chat";
|
import {format_time, formatMessage} from "../../ui/frames/chat";
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../../connection/ErrorCode";
|
||||||
|
|
||||||
export function openBanList(client: ConnectionHandler) {
|
export function openBanList(client: ConnectionHandler) {
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
|
@ -22,7 +22,7 @@ export function openBanList(client: ConnectionHandler) {
|
||||||
const json = command.arguments;
|
const json = command.arguments;
|
||||||
|
|
||||||
let bans: BanEntry[] = [];
|
let bans: BanEntry[] = [];
|
||||||
for(const entry of json) {
|
for (const entry of json) {
|
||||||
bans.push({
|
bans.push({
|
||||||
server_id: parseInt(entry["sid"]),
|
server_id: parseInt(entry["sid"]),
|
||||||
banid: parseInt(entry["banid"]),
|
banid: parseInt(entry["banid"]),
|
||||||
|
@ -55,7 +55,7 @@ export function openBanList(client: ConnectionHandler) {
|
||||||
const json = command.arguments;
|
const json = command.arguments;
|
||||||
|
|
||||||
let triggers: TriggerEntry[] = [];
|
let triggers: TriggerEntry[] = [];
|
||||||
for(const entry of json) {
|
for (const entry of json) {
|
||||||
triggers.push({
|
triggers.push({
|
||||||
unique_id: entry["client_unique_identifier"],
|
unique_id: entry["client_unique_identifier"],
|
||||||
client_nickname: entry["client_nickname"],
|
client_nickname: entry["client_nickname"],
|
||||||
|
@ -86,20 +86,20 @@ export function openBanList(client: ConnectionHandler) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
client.serverConnection.send_command("banlist", { sid: 0 }, {process_result: false}).catch(error => {
|
client.serverConnection.send_command("banlist", {sid: 0}, {process_result: false}).catch(error => {
|
||||||
//TODO: May lookup for permissions
|
//TODO: May lookup for permissions
|
||||||
}),
|
}),
|
||||||
client.serverConnection.send_command("banlist").catch(async error => {
|
client.serverConnection.send_command("banlist").catch(async error => {
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
if(error.id === ErrorCode.DATABASE_EMPTY_RESULT)
|
if (error.id === ErrorCode.DATABASE_EMPTY_RESULT)
|
||||||
return;
|
return;
|
||||||
throw error;
|
throw error;
|
||||||
})
|
})
|
||||||
]).then(() => {
|
]).then(() => {
|
||||||
if(_callback_bans) resolve();
|
if (_callback_bans) resolve();
|
||||||
cleanup();
|
cleanup();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if(_callback_bans) reject(error);
|
if (_callback_bans) reject(error);
|
||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -118,18 +118,18 @@ export function openBanList(client: ConnectionHandler) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const data = {banid: ban.ban_id};
|
const data = {banid: ban.ban_id};
|
||||||
if(typeof ban.server_id !== "undefined")
|
if (typeof ban.server_id !== "undefined")
|
||||||
data["sid"] = ban.server_id;
|
data["sid"] = ban.server_id;
|
||||||
client.serverConnection.send_command("bantriggerlist", data).catch(async error => {
|
client.serverConnection.send_command("bantriggerlist", data).catch(async error => {
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
if(error.id === ErrorCode.DATABASE_EMPTY_RESULT)
|
if (error.id === ErrorCode.DATABASE_EMPTY_RESULT)
|
||||||
return;
|
return;
|
||||||
throw error;
|
throw error;
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if(_callback_triggers) resolve();
|
if (_callback_triggers) resolve();
|
||||||
cleanup();
|
cleanup();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if(_callback_triggers) reject(error);
|
if (_callback_triggers) reject(error);
|
||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -153,27 +153,33 @@ export function openBanList(client: ConnectionHandler) {
|
||||||
add_ban(entry: BanEntry): Promise<void> {
|
add_ban(entry: BanEntry): Promise<void> {
|
||||||
const data = {};
|
const data = {};
|
||||||
|
|
||||||
if(entry.ip) data["ip"] = entry.ip;
|
if (entry.ip) data["ip"] = entry.ip;
|
||||||
if(entry.name) data["name"] = entry.name;
|
if (entry.name) data["name"] = entry.name;
|
||||||
if(entry.unique_id) data["uid"] = entry.unique_id;
|
if (entry.unique_id) data["uid"] = entry.unique_id;
|
||||||
if(entry.hardware_id) data["hwid"] = entry.hardware_id;
|
if (entry.hardware_id) data["hwid"] = entry.hardware_id;
|
||||||
if(entry.reason) data["banreason"] = entry.reason;
|
if (entry.reason) data["banreason"] = entry.reason;
|
||||||
if(entry.timestamp_expire) data["time"] = Math.floor((entry.timestamp_expire - entry.timestamp_created) / 1000);
|
if (entry.timestamp_expire) data["time"] = Math.floor((entry.timestamp_expire - entry.timestamp_created) / 1000);
|
||||||
if(typeof(entry.server_id) === "number") data["sid"] = entry.server_id;
|
if (typeof (entry.server_id) === "number") data["sid"] = entry.server_id;
|
||||||
|
|
||||||
return client.serverConnection.send_command("banadd", data).then(e => { if(!e.success) throw e; });
|
return client.serverConnection.send_command("banadd", data).then(e => {
|
||||||
|
if (!e.success) throw e;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
edit_ban(data: any): Promise<void> {
|
edit_ban(data: any): Promise<void> {
|
||||||
return client.serverConnection.send_command("banedit", data).then(e => { if(!e.success) throw e; });
|
return client.serverConnection.send_command("banedit", data).then(e => {
|
||||||
|
if (!e.success) throw e;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
delete_ban(entry_id, server_id): Promise<void> {
|
delete_ban(entry_id, server_id): Promise<void> {
|
||||||
const data = {
|
const data = {
|
||||||
banid: entry_id
|
banid: entry_id
|
||||||
};
|
};
|
||||||
if(typeof(server_id) === "number")
|
if (typeof (server_id) === "number")
|
||||||
data["sid"] = server_id;
|
data["sid"] = server_id;
|
||||||
|
|
||||||
return client.serverConnection.send_command("bandel", data).then(e => { if(!e.success) throw e; });
|
return client.serverConnection.send_command("bandel", data).then(e => {
|
||||||
|
if (!e.success) throw e;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -232,16 +238,21 @@ interface TriggerEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BanListController {
|
interface BanListController {
|
||||||
request_list(callback_bans: (entries: BanEntry[]) => any) : Promise<void>;
|
request_list(callback_bans: (entries: BanEntry[]) => any): Promise<void>;
|
||||||
request_trigger_list(ban: {ban_id: number, server_id: number | undefined}, callback_triggers: (entries: TriggerEntry[]) => any) : Promise<void>;
|
|
||||||
|
|
||||||
max_bantime() : Promise<number>;
|
request_trigger_list(ban: { ban_id: number, server_id: number | undefined }, callback_triggers: (entries: TriggerEntry[]) => any): Promise<void>;
|
||||||
permission_edit() : Promise<boolean[]>;
|
|
||||||
permission_add() : Promise<boolean[]>;
|
|
||||||
|
|
||||||
add_ban(entry: BanEntry) : Promise<void>;
|
max_bantime(): Promise<number>;
|
||||||
edit_ban(data: any) : Promise<void>;
|
|
||||||
delete_ban(entry_id: number, server_id: number | undefined) : Promise<void>;
|
permission_edit(): Promise<boolean[]>;
|
||||||
|
|
||||||
|
permission_add(): Promise<boolean[]>;
|
||||||
|
|
||||||
|
add_ban(entry: BanEntry): Promise<void>;
|
||||||
|
|
||||||
|
edit_ban(data: any): Promise<void>;
|
||||||
|
|
||||||
|
delete_ban(entry_id: number, server_id: number | undefined): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Note: This object must be sorted (from shortest to longest)!
|
//Note: This object must be sorted (from shortest to longest)!
|
||||||
|
@ -272,7 +283,7 @@ export const duration_data = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function generate_dom(controller: BanListController) : JQuery {
|
function generate_dom(controller: BanListController): JQuery {
|
||||||
const template = $("#tmpl_ban_list").renderTag();
|
const template = $("#tmpl_ban_list").renderTag();
|
||||||
|
|
||||||
let callback_ban_filter: ((text: string, flag_own: boolean, highlight_own: boolean) => boolean)[] = [];
|
let callback_ban_filter: ((text: string, flag_own: boolean, highlight_own: boolean) => boolean)[] = [];
|
||||||
|
@ -312,17 +323,17 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
controller.permission_add().then(result => permission_add = result).catch(error => {
|
controller.permission_add().then(result => permission_add = result).catch(error => {
|
||||||
log.error(LogCategory.CLIENT, tr("Failed to query ban add permissions: %o"), error);
|
log.error(LogCategory.CLIENT, tr("Failed to query ban add permissions: %o"), error);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if(permission_add[0] !== permission_add[1]) {
|
if (permission_add[0] !== permission_add[1]) {
|
||||||
const input_global = container_add.find(".group-global input");
|
const input_global = container_add.find(".group-global input");
|
||||||
input_global.prop("checked", permission_add[1]).prop("disabled", true).firstParent(".checkbox").addClass("disabled");
|
input_global.prop("checked", permission_add[1]).prop("disabled", true).firstParent(".checkbox").addClass("disabled");
|
||||||
} else if(!permission_add[0])
|
} else if (!permission_add[0])
|
||||||
container_add_no_permissions.show();
|
container_add_no_permissions.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
controller.permission_edit().then(result => permission_edit = result).catch(error => {
|
controller.permission_edit().then(result => permission_edit = result).catch(error => {
|
||||||
log.error(LogCategory.CLIENT, tr("Failed to query ban edit permissions: %o"), error);
|
log.error(LogCategory.CLIENT, tr("Failed to query ban edit permissions: %o"), error);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if(selected_ban) update_edit_window(false);
|
if (selected_ban) update_edit_window(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* category switch */
|
/* category switch */
|
||||||
|
@ -342,7 +353,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
});
|
});
|
||||||
|
|
||||||
category_edit.on('click', event => {
|
category_edit.on('click', event => {
|
||||||
if(!selected_ban) return;
|
if (!selected_ban) return;
|
||||||
|
|
||||||
container_add.addClass("hidden");
|
container_add.addClass("hidden");
|
||||||
category_add.removeClass("selected");
|
category_add.removeClass("selected");
|
||||||
|
@ -377,7 +388,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
);
|
);
|
||||||
|
|
||||||
tag.on('click', event => {
|
tag.on('click', event => {
|
||||||
if(selected_ban === entry || event.isDefaultPrevented()) return;
|
if (selected_ban === entry || event.isDefaultPrevented()) return;
|
||||||
selected_ban = entry;
|
selected_ban = entry;
|
||||||
|
|
||||||
container_ban_entries.find(".entry.selected").removeClass("selected");
|
container_ban_entries.find(".entry.selected").removeClass("selected");
|
||||||
|
@ -391,19 +402,19 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
|
|
||||||
controller.delete_ban(entry.banid, entry.server_id).then(() => {
|
controller.delete_ban(entry.banid, entry.server_id).then(() => {
|
||||||
tag.css({opacity: 1}).animate({opacity: 0}, 250, () => tag.animate({"max-height": 0}, 250, () => tag.remove()));
|
tag.css({opacity: 1}).animate({opacity: 0}, 250, () => tag.animate({"max-height": 0}, 250, () => tag.remove()));
|
||||||
if(entry === selected_ban) {
|
if (entry === selected_ban) {
|
||||||
selected_ban = undefined;
|
selected_ban = undefined;
|
||||||
update_edit_window(false);
|
update_edit_window(false);
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
log.error(LogCategory.CLIENT, tr("Failed to delete ban: %o"), error);
|
log.error(LogCategory.CLIENT, tr("Failed to delete ban: %o"), error);
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? "no permissions" : error.extra_message || error.message;
|
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? "no permissions" : error.extra_message || error.message;
|
||||||
createErrorModal(tr("Failed to delete ban"), formatMessage(tr("Failed to delete ban. {:br:}Error: {}"), error)).open();
|
createErrorModal(tr("Failed to delete ban"), formatMessage(tr("Failed to delete ban. {:br:}Error: {}"), error)).open();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if(selected) {
|
if (selected) {
|
||||||
selected_ban = entry;
|
selected_ban = entry;
|
||||||
update_edit_window(false);
|
update_edit_window(false);
|
||||||
}
|
}
|
||||||
|
@ -415,12 +426,12 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
(entry.ip || "").toLowerCase() + " " +
|
(entry.ip || "").toLowerCase() + " " +
|
||||||
(entry.hardware_id || "").toLowerCase();
|
(entry.hardware_id || "").toLowerCase();
|
||||||
callback_ban_filter.push((text, flag_own, highlight_own) => {
|
callback_ban_filter.push((text, flag_own, highlight_own) => {
|
||||||
if(text && lower_mesh.indexOf(text) == -1) {
|
if (text && lower_mesh.indexOf(text) == -1) {
|
||||||
tag.hide();
|
tag.hide();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flag_own && !entry.flag_own) {
|
if (flag_own && !entry.flag_own) {
|
||||||
tag.hide();
|
tag.hide();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -445,7 +456,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
|
|
||||||
let bans = [];
|
let bans = [];
|
||||||
controller.request_list(_bans => bans.push(..._bans)).then(() => {
|
controller.request_list(_bans => bans.push(..._bans)).then(() => {
|
||||||
if(bans.length) {
|
if (bans.length) {
|
||||||
container_ban_entries.append(...bans.map(e => build_ban_entry(e, e.banid === selected_ban)));
|
container_ban_entries.append(...bans.map(e => build_ban_entry(e, e.banid === selected_ban)));
|
||||||
container_ban_entries_empty.hide();
|
container_ban_entries_empty.hide();
|
||||||
} else {
|
} else {
|
||||||
|
@ -454,7 +465,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
update_ban_filter();
|
update_ban_filter();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
log.info(LogCategory.CLIENT, tr("Failed to update ban list: %o"), error);
|
log.info(LogCategory.CLIENT, tr("Failed to update ban list: %o"), error);
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? tr("no permissions") : error.extra_message || error.message;
|
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? tr("no permissions") : error.extra_message || error.message;
|
||||||
container_ban_entries_error.show().find("a").text(tr("Failed to receive banlist: ") + error);
|
container_ban_entries_error.show().find("a").text(tr("Failed to receive banlist: ") + error);
|
||||||
container_ban_entries_empty.hide();
|
container_ban_entries_empty.hide();
|
||||||
|
@ -475,7 +486,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
let cause_hwid = !cause_ip && !!selected_ban.hardware_id && selected_ban.hardware_id.toLowerCase() === (entry.hardware_id || "").toLowerCase();
|
let cause_hwid = !cause_ip && !!selected_ban.hardware_id && selected_ban.hardware_id.toLowerCase() === (entry.hardware_id || "").toLowerCase();
|
||||||
|
|
||||||
/* we guess that IP is the cause because we dont see the IP and there is no other reason */
|
/* we guess that IP is the cause because we dont see the IP and there is no other reason */
|
||||||
if(!cause_name && !cause_uid && !cause_ip && !cause_hwid && entry.connection_ip === "hidden")
|
if (!cause_name && !cause_uid && !cause_ip && !cause_hwid && entry.connection_ip === "hidden")
|
||||||
cause_ip = true;
|
cause_ip = true;
|
||||||
|
|
||||||
const time_str = moment(entry.timestamp).format('DD.MM.YYYY hh:mm');
|
const time_str = moment(entry.timestamp).format('DD.MM.YYYY hh:mm');
|
||||||
|
@ -498,7 +509,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
time_str + " " +
|
time_str + " " +
|
||||||
entry.timestamp;
|
entry.timestamp;
|
||||||
callback_trigger_filter.push(text => {
|
callback_trigger_filter.push(text => {
|
||||||
if(text && lower_mesh.indexOf(text) == -1) {
|
if (text && lower_mesh.indexOf(text) == -1) {
|
||||||
tag.hide();
|
tag.hide();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -522,7 +533,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
ban_id: selected_ban.banid,
|
ban_id: selected_ban.banid,
|
||||||
server_id: selected_ban.server_id
|
server_id: selected_ban.server_id
|
||||||
}, _triggers => triggers.push(..._triggers)).then(() => {
|
}, _triggers => triggers.push(..._triggers)).then(() => {
|
||||||
if(triggers.length) {
|
if (triggers.length) {
|
||||||
container_trigger_entries.append(...triggers.sort((a, b) => b.timestamp - a.timestamp).map(e => build_trigger_entry(e)));
|
container_trigger_entries.append(...triggers.sort((a, b) => b.timestamp - a.timestamp).map(e => build_trigger_entry(e)));
|
||||||
container_trigger_entries_empty.hide();
|
container_trigger_entries_empty.hide();
|
||||||
} else {
|
} else {
|
||||||
|
@ -532,7 +543,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
update_trigger_filter();
|
update_trigger_filter();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
log.info(LogCategory.CLIENT, tr("Failed to update trigger list: %o"), error);
|
log.info(LogCategory.CLIENT, tr("Failed to update trigger list: %o"), error);
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? tr("no permissions") : error.extra_message || error.message;
|
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? tr("no permissions") : error.extra_message || error.message;
|
||||||
container_trigger_entries_error.show().find("a").text(tr("Failed to receive trigger list: ") + error);
|
container_trigger_entries_error.show().find("a").text(tr("Failed to receive trigger list: ") + error);
|
||||||
container_trigger_entries_empty.hide();
|
container_trigger_entries_empty.hide();
|
||||||
|
@ -562,7 +573,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
{
|
{
|
||||||
//TODO: Check if in regex mode or not
|
//TODO: Check if in regex mode or not
|
||||||
const value = input_name.val() as string || "";
|
const value = input_name.val() as string || "";
|
||||||
if(value.length > 255) {
|
if (value.length > 255) {
|
||||||
_input_invalid = true;
|
_input_invalid = true;
|
||||||
input_name.firstParent(".input-boxed").addClass("is-invalid");
|
input_name.firstParent(".input-boxed").addClass("is-invalid");
|
||||||
} else {
|
} else {
|
||||||
|
@ -574,7 +585,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
{
|
{
|
||||||
//TODO: Check if in regex mode or not
|
//TODO: Check if in regex mode or not
|
||||||
const value = input_ip.val() as string || "";
|
const value = input_ip.val() as string || "";
|
||||||
if(value.length > 255) {
|
if (value.length > 255) {
|
||||||
_input_invalid = true;
|
_input_invalid = true;
|
||||||
input_ip.firstParent(".input-boxed").addClass("is-invalid");
|
input_ip.firstParent(".input-boxed").addClass("is-invalid");
|
||||||
} else {
|
} else {
|
||||||
|
@ -586,11 +597,11 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
{
|
{
|
||||||
const value = input_uid.val() as string || "";
|
const value = input_uid.val() as string || "";
|
||||||
try {
|
try {
|
||||||
if(value && atob(value).length != 20) throw "";
|
if (value && atob(value).length != 20) throw "";
|
||||||
|
|
||||||
_criteria_set = _criteria_set || !!value;
|
_criteria_set = _criteria_set || !!value;
|
||||||
input_uid.firstParent(".input-boxed").removeClass("is-invalid");
|
input_uid.firstParent(".input-boxed").removeClass("is-invalid");
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
_input_invalid = true;
|
_input_invalid = true;
|
||||||
input_uid.firstParent(".input-boxed").addClass("is-invalid");
|
input_uid.firstParent(".input-boxed").addClass("is-invalid");
|
||||||
}
|
}
|
||||||
|
@ -598,7 +609,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
|
|
||||||
{
|
{
|
||||||
const value = input_hwid.val() as string || "";
|
const value = input_hwid.val() as string || "";
|
||||||
if(value.length > 255) {
|
if (value.length > 255) {
|
||||||
_input_invalid = true;
|
_input_invalid = true;
|
||||||
input_hwid.firstParent(".input-boxed").addClass("is-invalid");
|
input_hwid.firstParent(".input-boxed").addClass("is-invalid");
|
||||||
} else {
|
} else {
|
||||||
|
@ -609,7 +620,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
|
|
||||||
{
|
{
|
||||||
const value = input_reason.val() as string || "";
|
const value = input_reason.val() as string || "";
|
||||||
if(value.length > 512) {
|
if (value.length > 512) {
|
||||||
_input_invalid = true;
|
_input_invalid = true;
|
||||||
input_reason.firstParent(".input-boxed").addClass("is-invalid");
|
input_reason.firstParent(".input-boxed").addClass("is-invalid");
|
||||||
} else {
|
} else {
|
||||||
|
@ -623,8 +634,8 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
const disabled = input_duration_type.prop("disabled");
|
const disabled = input_duration_type.prop("disabled");
|
||||||
|
|
||||||
input_duration_value.prop("disabled", type === "perm" || disabled).firstParent(".input-boxed").toggleClass("disabled", type === "perm" || disabled);
|
input_duration_value.prop("disabled", type === "perm" || disabled).firstParent(".input-boxed").toggleClass("disabled", type === "perm" || disabled);
|
||||||
if(type !== "perm") {
|
if (type !== "perm") {
|
||||||
if(input_duration_value.attr("x-saved-value")) {
|
if (input_duration_value.attr("x-saved-value")) {
|
||||||
input_duration_value.val(parseInt(input_duration_value.attr("x-saved-value")));
|
input_duration_value.val(parseInt(input_duration_value.attr("x-saved-value")));
|
||||||
input_duration_value.attr("x-saved-value", null);
|
input_duration_value.attr("x-saved-value", null);
|
||||||
}
|
}
|
||||||
|
@ -633,19 +644,19 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
const max = parseInt(selected_option.attr("duration-max"));
|
const max = parseInt(selected_option.attr("duration-max"));
|
||||||
|
|
||||||
input_duration_value.attr("max", max);
|
input_duration_value.attr("max", max);
|
||||||
if((value > max && max != -1) || value < 1) {
|
if ((value > max && max != -1) || value < 1) {
|
||||||
_input_invalid = true;
|
_input_invalid = true;
|
||||||
input_duration_value.firstParent(".input-boxed").addClass("is-invalid");
|
input_duration_value.firstParent(".input-boxed").addClass("is-invalid");
|
||||||
} else {
|
} else {
|
||||||
input_duration_value.firstParent(".input-boxed").removeClass("is-invalid");
|
input_duration_value.firstParent(".input-boxed").removeClass("is-invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(max != -1)
|
if (max != -1)
|
||||||
tooltip_duration_max.html(tr("You're allowed to ban a maximum of ") + "<b>" + max + " " + duration_data[type][max == 1 ? "1-text" : "text"] + "</b>");
|
tooltip_duration_max.html(tr("You're allowed to ban a maximum of ") + "<b>" + max + " " + duration_data[type][max == 1 ? "1-text" : "text"] + "</b>");
|
||||||
else
|
else
|
||||||
tooltip_duration_max.html(tr("You're allowed to ban <b>permanent</b>."));
|
tooltip_duration_max.html(tr("You're allowed to ban <b>permanent</b>."));
|
||||||
} else {
|
} else {
|
||||||
if(value && !Number.isNaN(value))
|
if (value && !Number.isNaN(value))
|
||||||
input_duration_value.attr("x-saved-value", value);
|
input_duration_value.attr("x-saved-value", value);
|
||||||
input_duration_value.attr("placeholder", tr("for ever")).val(null);
|
input_duration_value.attr("placeholder", tr("for ever")).val(null);
|
||||||
tooltip_duration_max.html(tr("You're allowed to ban <b>permanent</b>."));
|
tooltip_duration_max.html(tr("You're allowed to ban <b>permanent</b>."));
|
||||||
|
@ -656,15 +667,17 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* initialize ban time */
|
/* initialize ban time */
|
||||||
controller.max_bantime().catch(error => { /* TODO: Error handling? */ return 0; }).then(max_time => {
|
controller.max_bantime().catch(error => { /* TODO: Error handling? */
|
||||||
|
return 0;
|
||||||
|
}).then(max_time => {
|
||||||
let unlimited = max_time == 0 || max_time == -1;
|
let unlimited = max_time == 0 || max_time == -1;
|
||||||
if(unlimited) max_time = 0;
|
if (unlimited) max_time = 0;
|
||||||
|
|
||||||
for(const value of Object.keys(duration_data)) {
|
for (const value of Object.keys(duration_data)) {
|
||||||
input_duration_type.find("option[value='" + value + "']")
|
input_duration_type.find("option[value='" + value + "']")
|
||||||
.prop("disabled", !unlimited && max_time >= duration_data[value].scale)
|
.prop("disabled", !unlimited && max_time >= duration_data[value].scale)
|
||||||
.attr("duration-scale", duration_data[value].scale)
|
.attr("duration-scale", duration_data[value].scale)
|
||||||
.attr("duration-max", unlimited ? -1 : Math.floor(max_time / duration_data[value].scale));
|
.attr("duration-max", unlimited ? -1 : Math.floor(max_time / duration_data[value].scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
input_duration_type.find("option[value='perm']")
|
input_duration_type.find("option[value='perm']")
|
||||||
|
@ -706,7 +719,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
input_hwid.val(selected_ban ? selected_ban.hardware_id : null).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
input_hwid.val(selected_ban ? selected_ban.hardware_id : null).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
||||||
input_reason.val(selected_ban ? selected_ban.reason : null).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
input_reason.val(selected_ban ? selected_ban.reason : null).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
||||||
|
|
||||||
input_interpret.find("option").eq(selected_ban && typeof(selected_ban.name_type) === "number" ? selected_ban.name_type : 2).prop("selected", true).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
input_interpret.find("option").eq(selected_ban && typeof (selected_ban.name_type) === "number" ? selected_ban.name_type : 2).prop("selected", true).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
||||||
label_enforcement_count.text((selected_ban ? selected_ban.enforcements : 0) || 0);
|
label_enforcement_count.text((selected_ban ? selected_ban.enforcements : 0) || 0);
|
||||||
button_enforcement_list.prop("disabled", !selected_ban || selected_ban.enforcements == 0);
|
button_enforcement_list.prop("disabled", !selected_ban || selected_ban.enforcements == 0);
|
||||||
|
|
||||||
|
@ -715,17 +728,17 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
input_duration_type.prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
input_duration_type.prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
||||||
input_duration_value.prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
input_duration_value.prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable);
|
||||||
|
|
||||||
if(selected_ban) {
|
if (selected_ban) {
|
||||||
if(selected_ban.timestamp_expire > selected_ban.timestamp_created) {
|
if (selected_ban.timestamp_expire > selected_ban.timestamp_created) {
|
||||||
const duration = Math.ceil((selected_ban.timestamp_expire - selected_ban.timestamp_created) / 1000);
|
const duration = Math.ceil((selected_ban.timestamp_expire - selected_ban.timestamp_created) / 1000);
|
||||||
|
|
||||||
const periods = Object.keys(duration_data);
|
const periods = Object.keys(duration_data);
|
||||||
let index;
|
let index;
|
||||||
for(index = 0; index < periods.length; index++) {
|
for (index = 0; index < periods.length; index++) {
|
||||||
if(duration_data[periods[index]].scale > duration + 1 || ((duration + 1) % duration_data[periods[index]].scale) > 1.9)
|
if (duration_data[periods[index]].scale > duration + 1 || ((duration + 1) % duration_data[periods[index]].scale) > 1.9)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(index > 0) index--;
|
if (index > 0) index--;
|
||||||
input_duration_type.find("option[value='" + periods[index] + "']").prop("selected", true);
|
input_duration_type.find("option[value='" + periods[index] + "']").prop("selected", true);
|
||||||
input_duration_value.val(Math.ceil(duration / duration_data[periods[index]].scale));
|
input_duration_value.val(Math.ceil(duration / duration_data[periods[index]].scale));
|
||||||
tooltip_duration_detailed.text($.spawn("div").append(...formatMessage(tr("The ban lasts for exact {}."), format_time(duration * 1000, "never"))).text());
|
tooltip_duration_detailed.text($.spawn("div").append(...formatMessage(tr("The ban lasts for exact {}."), format_time(duration * 1000, "never"))).text());
|
||||||
|
@ -737,7 +750,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
container_creator.empty();
|
container_creator.empty();
|
||||||
if(selected_ban) {
|
if (selected_ban) {
|
||||||
container_creator.append(
|
container_creator.append(
|
||||||
htmltags.generate_client_object({
|
htmltags.generate_client_object({
|
||||||
client_id: 0,
|
client_id: 0,
|
||||||
|
@ -748,7 +761,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(switch_to)
|
if (switch_to)
|
||||||
category_edit.trigger('click');
|
category_edit.trigger('click');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -757,26 +770,26 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
|
|
||||||
const data = {banid: selected_ban.banid};
|
const data = {banid: selected_ban.banid};
|
||||||
|
|
||||||
if(input_ip.val() != selected_ban.ip)
|
if (input_ip.val() != selected_ban.ip)
|
||||||
data["ip"] = input_ip.val();
|
data["ip"] = input_ip.val();
|
||||||
|
|
||||||
if(input_name.val() != selected_ban.name)
|
if (input_name.val() != selected_ban.name)
|
||||||
data["name"] = input_name.val();
|
data["name"] = input_name.val();
|
||||||
|
|
||||||
if(input_uid.val() != selected_ban.unique_id)
|
if (input_uid.val() != selected_ban.unique_id)
|
||||||
data["uid"] = input_uid.val();
|
data["uid"] = input_uid.val();
|
||||||
|
|
||||||
if(input_hwid.val() != selected_ban.hardware_id)
|
if (input_hwid.val() != selected_ban.hardware_id)
|
||||||
data["hwid"] = input_hwid.val();
|
data["hwid"] = input_hwid.val();
|
||||||
|
|
||||||
if(input_reason.val() != selected_ban.reason)
|
if (input_reason.val() != selected_ban.reason)
|
||||||
data["banreason"] = input_reason.val();
|
data["banreason"] = input_reason.val();
|
||||||
|
|
||||||
if(input_reason.val() != selected_ban.reason)
|
if (input_reason.val() != selected_ban.reason)
|
||||||
data["reason"] = input_reason.val();
|
data["reason"] = input_reason.val();
|
||||||
|
|
||||||
const duration = input_duration_type.val() === "perm" ? 0 : (1000 * parseInt(input_duration_type.find("option[value='" + input_duration_type.val() + "']").attr("duration-scale")) * parseInt(input_duration_value.val() as string));
|
const duration = input_duration_type.val() === "perm" ? 0 : (1000 * parseInt(input_duration_type.find("option[value='" + input_duration_type.val() + "']").attr("duration-scale")) * parseInt(input_duration_value.val() as string));
|
||||||
if(selected_ban.timestamp_expire > 0 ? (selected_ban.timestamp_expire - selected_ban.timestamp_created != duration) : duration != 0)
|
if (selected_ban.timestamp_expire > 0 ? (selected_ban.timestamp_expire - selected_ban.timestamp_created != duration) : duration != 0)
|
||||||
data["time"] = Math.floor(duration / 1000);
|
data["time"] = Math.floor(duration / 1000);
|
||||||
|
|
||||||
controller.edit_ban(data).then(() => {
|
controller.edit_ban(data).then(() => {
|
||||||
|
@ -788,7 +801,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
createInfoModal(tr("Ban successfully edited"), tr("Your ban has been successfully edited.")).open();
|
createInfoModal(tr("Ban successfully edited"), tr("Your ban has been successfully edited.")).open();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
log.error(LogCategory.CLIENT, tr("Failed to edited ban: %o"), error);
|
log.error(LogCategory.CLIENT, tr("Failed to edited ban: %o"), error);
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? "no permissions" : error.extra_message || error.message;
|
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? "no permissions" : error.extra_message || error.message;
|
||||||
createErrorModal(tr("Failed to edited ban"), formatMessage(tr("Failed to edited ban. {:br:}Error: {}"), error)).open();
|
createErrorModal(tr("Failed to edited ban"), formatMessage(tr("Failed to edited ban. {:br:}Error: {}"), error)).open();
|
||||||
});
|
});
|
||||||
|
@ -814,34 +827,34 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
const input_duration_type = tag.find(".group-duration select");
|
const input_duration_type = tag.find(".group-duration select");
|
||||||
|
|
||||||
button_apply.on('click', event => {
|
button_apply.on('click', event => {
|
||||||
if(!button_apply_state[0] || button_apply_state_index != 0) return;
|
if (!button_apply_state[0] || button_apply_state_index != 0) return;
|
||||||
|
|
||||||
const data: BanEntry = {
|
const data: BanEntry = {
|
||||||
banid: 0,
|
banid: 0,
|
||||||
enforcements: 0,
|
enforcements: 0,
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
if(input_global.prop('checked'))
|
if (input_global.prop('checked'))
|
||||||
data.server_id = 0;
|
data.server_id = 0;
|
||||||
|
|
||||||
if(input_ip.val())
|
if (input_ip.val())
|
||||||
data.ip = input_ip.val() as any;
|
data.ip = input_ip.val() as any;
|
||||||
|
|
||||||
if(input_name.val())
|
if (input_name.val())
|
||||||
data.name = input_name.val() as any;
|
data.name = input_name.val() as any;
|
||||||
|
|
||||||
if(input_uid.val())
|
if (input_uid.val())
|
||||||
data.unique_id = input_uid.val() as any;
|
data.unique_id = input_uid.val() as any;
|
||||||
|
|
||||||
if(input_hwid.val())
|
if (input_hwid.val())
|
||||||
data.hardware_id = input_hwid.val() as any;
|
data.hardware_id = input_hwid.val() as any;
|
||||||
|
|
||||||
if(input_reason.val())
|
if (input_reason.val())
|
||||||
data.reason = input_reason.val() as any;
|
data.reason = input_reason.val() as any;
|
||||||
|
|
||||||
data.timestamp_created = Date.now();
|
data.timestamp_created = Date.now();
|
||||||
|
|
||||||
data.timestamp_expire = input_duration_type.val() === "perm" ? 0 : (data.timestamp_created + 1000 * parseInt(input_duration_type.find("option[value='" + input_duration_type.val() + "']").attr("duration-scale")) * parseInt(input_duration_value.val() as string));
|
data.timestamp_expire = input_duration_type.val() === "perm" ? 0 : (data.timestamp_created + 1000 * parseInt(input_duration_type.find("option[value='" + input_duration_type.val() + "']").attr("duration-scale")) * parseInt(input_duration_value.val() as string));
|
||||||
//TODO: input_interpret (Currently not supported by TeaSpeak)
|
//TODO: input_interpret (Currently not supported by TeaSpeak)
|
||||||
|
|
||||||
controller.add_ban(data).then(() => {
|
controller.add_ban(data).then(() => {
|
||||||
|
@ -856,7 +869,7 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
createInfoModal(tr("Ban successfully added"), tr("Your ban has been successfully added.")).open();
|
createInfoModal(tr("Ban successfully added"), tr("Your ban has been successfully added.")).open();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
log.error(LogCategory.CLIENT, tr("Failed to add ban: %o"), error);
|
log.error(LogCategory.CLIENT, tr("Failed to add ban: %o"), error);
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? "no permissions" : error.extra_message || error.message;
|
error = error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS ? "no permissions" : error.extra_message || error.message;
|
||||||
createErrorModal(tr("Failed to add ban"), formatMessage(tr("Failed to add ban. {:br:}Error: {}"), error)).open();
|
createErrorModal(tr("Failed to add ban"), formatMessage(tr("Failed to add ban. {:br:}Error: {}"), error)).open();
|
||||||
});
|
});
|
||||||
|
@ -875,11 +888,11 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
const flag_hightlight_own = option_hightlight_own.prop('checked');
|
const flag_hightlight_own = option_hightlight_own.prop('checked');
|
||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for(const entry of callback_ban_filter)
|
for (const entry of callback_ban_filter)
|
||||||
if(entry(text, flag_show_own, flag_hightlight_own))
|
if (entry(text, flag_show_own, flag_hightlight_own))
|
||||||
count++;
|
count++;
|
||||||
if(callback_ban_filter.length != 0) {
|
if (callback_ban_filter.length != 0) {
|
||||||
if(count > 0)
|
if (count > 0)
|
||||||
container_ban_entries_empty.hide();
|
container_ban_entries_empty.hide();
|
||||||
else
|
else
|
||||||
container_ban_entries_empty.show().find("a").text(tr("No bans found"));
|
container_ban_entries_empty.show().find("a").text(tr("No bans found"));
|
||||||
|
@ -897,11 +910,11 @@ function generate_dom(controller: BanListController) : JQuery {
|
||||||
const text = (input_filter.val() as string || "").toLowerCase();
|
const text = (input_filter.val() as string || "").toLowerCase();
|
||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for(const entry of callback_trigger_filter)
|
for (const entry of callback_trigger_filter)
|
||||||
if(entry(text))
|
if (entry(text))
|
||||||
count++;
|
count++;
|
||||||
if(callback_trigger_filter.length != 0) {
|
if (callback_trigger_filter.length != 0) {
|
||||||
if(count > 0)
|
if (count > 0)
|
||||||
container_trigger_entries_empty.hide();
|
container_trigger_entries_empty.hide();
|
||||||
else
|
else
|
||||||
container_trigger_entries_empty.show().find("a").text(tr("No trigger events found"));
|
container_trigger_entries_empty.show().find("a").text(tr("No trigger events found"));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {createInputModal, createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createInputModal, createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {
|
import {
|
||||||
Bookmark,
|
Bookmark,
|
||||||
bookmarks,
|
bookmarks,
|
||||||
|
@ -9,25 +9,25 @@ import {
|
||||||
delete_bookmark,
|
delete_bookmark,
|
||||||
DirectoryBookmark,
|
DirectoryBookmark,
|
||||||
save_bookmark
|
save_bookmark
|
||||||
} from "tc-shared/bookmarks";
|
} from "../../bookmarks";
|
||||||
import {connection_log, Regex} from "tc-shared/ui/modal/ModalConnect";
|
import {connection_log, Regex} from "../../ui/modal/ModalConnect";
|
||||||
import {profiles} from "tc-shared/profiles/ConnectionProfile";
|
import {profiles} from "../../profiles/ConnectionProfile";
|
||||||
import {spawnYesNo} from "tc-shared/ui/modal/ModalYesNo";
|
import {spawnYesNo} from "../../ui/modal/ModalYesNo";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../../settings";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import * as i18nc from "tc-shared/i18n/country";
|
import * as i18nc from "../../i18n/country";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../../ui/frames/chat";
|
||||||
import * as top_menu from "../frames/MenuBar";
|
import * as top_menu from "../frames/MenuBar";
|
||||||
import {control_bar_instance} from "tc-shared/ui/frames/control-bar";
|
import {control_bar_instance} from "../../ui/frames/control-bar";
|
||||||
import {icon_cache_loader, IconManager} from "tc-shared/file/Icons";
|
import {icon_cache_loader, IconManager} from "../../file/Icons";
|
||||||
|
|
||||||
export function spawnBookmarkModal() {
|
export function spawnBookmarkModal() {
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
modal = createModal({
|
modal = createModal({
|
||||||
header: tr("Manage bookmarks"),
|
header: tr("Manage bookmarks"),
|
||||||
body: () => {
|
body: () => {
|
||||||
let template = $("#tmpl_manage_bookmarks").renderTag({ });
|
let template = $("#tmpl_manage_bookmarks").renderTag({});
|
||||||
let selected_bookmark: Bookmark | DirectoryBookmark | undefined;
|
let selected_bookmark: Bookmark | DirectoryBookmark | undefined;
|
||||||
|
|
||||||
const button_delete = template.find(".button-delete");
|
const button_delete = template.find(".button-delete");
|
||||||
|
@ -61,11 +61,11 @@ export function spawnBookmarkModal() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const update_connect_info = () => {
|
const update_connect_info = () => {
|
||||||
if(selected_bookmark && selected_bookmark.type === BookmarkType.ENTRY) {
|
if (selected_bookmark && selected_bookmark.type === BookmarkType.ENTRY) {
|
||||||
const entry = selected_bookmark as Bookmark;
|
const entry = selected_bookmark as Bookmark;
|
||||||
|
|
||||||
const history = connection_log.history().find(e => e.address.hostname === entry.server_properties.server_address && e.address.port === entry.server_properties.server_port);
|
const history = connection_log.history().find(e => e.address.hostname === entry.server_properties.server_address && e.address.port === entry.server_properties.server_port);
|
||||||
if(history) {
|
if (history) {
|
||||||
label_server_name.text(history.name);
|
label_server_name.text(history.name);
|
||||||
label_server_region.empty().append(
|
label_server_region.empty().append(
|
||||||
$.spawn("div").addClass("country flag-" + history.country.toLowerCase()),
|
$.spawn("div").addClass("country flag-" + history.country.toLowerCase()),
|
||||||
|
@ -99,12 +99,12 @@ export function spawnBookmarkModal() {
|
||||||
input_server_address.prop("disabled", !selected_bookmark || selected_bookmark.type !== BookmarkType.ENTRY);
|
input_server_address.prop("disabled", !selected_bookmark || selected_bookmark.type !== BookmarkType.ENTRY);
|
||||||
input_server_password.prop("disabled", !selected_bookmark || selected_bookmark.type !== BookmarkType.ENTRY);
|
input_server_password.prop("disabled", !selected_bookmark || selected_bookmark.type !== BookmarkType.ENTRY);
|
||||||
|
|
||||||
if(selected_bookmark) {
|
if (selected_bookmark) {
|
||||||
input_bookmark_name.val(selected_bookmark.display_name);
|
input_bookmark_name.val(selected_bookmark.display_name);
|
||||||
label_bookmark_name.text(selected_bookmark.display_name);
|
label_bookmark_name.text(selected_bookmark.display_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(selected_bookmark && selected_bookmark.type === BookmarkType.ENTRY) {
|
if (selected_bookmark && selected_bookmark.type === BookmarkType.ENTRY) {
|
||||||
const entry = selected_bookmark as Bookmark;
|
const entry = selected_bookmark as Bookmark;
|
||||||
|
|
||||||
const address = entry.server_properties.server_address + (entry.server_properties.server_port == 9987 ? "" : (" " + entry.server_properties.server_port));
|
const address = entry.server_properties.server_address + (entry.server_properties.server_port == 9987 ? "" : (" " + entry.server_properties.server_port));
|
||||||
|
@ -112,7 +112,7 @@ export function spawnBookmarkModal() {
|
||||||
input_server_address.val(address);
|
input_server_address.val(address);
|
||||||
|
|
||||||
let profile = input_connect_profile.find("option[value='" + entry.connect_profile + "']");
|
let profile = input_connect_profile.find("option[value='" + entry.connect_profile + "']");
|
||||||
if(profile.length == 0) {
|
if (profile.length == 0) {
|
||||||
log.warn(LogCategory.GENERAL, tr("Failed to find bookmark profile %s. Displaying default one."), entry.connect_profile);
|
log.warn(LogCategory.GENERAL, tr("Failed to find bookmark profile %s. Displaying default one."), entry.connect_profile);
|
||||||
profile = input_connect_profile.find("option[value=default]");
|
profile = input_connect_profile.find("option[value=default]");
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ export function spawnBookmarkModal() {
|
||||||
update_selected();
|
update_selected();
|
||||||
|
|
||||||
const hide_links: boolean[] = [];
|
const hide_links: boolean[] = [];
|
||||||
const build_entry = (entry: Bookmark | DirectoryBookmark, sibling_data: {first: boolean; last: boolean;}, index: number) => {
|
const build_entry = (entry: Bookmark | DirectoryBookmark, sibling_data: { first: boolean; last: boolean; }, index: number) => {
|
||||||
let container = $.spawn("div")
|
let container = $.spawn("div")
|
||||||
.addClass(entry.type === BookmarkType.ENTRY ? "bookmark" : "directory")
|
.addClass(entry.type === BookmarkType.ENTRY ? "bookmark" : "directory")
|
||||||
.addClass(index > 0 ? "linked" : "")
|
.addClass(index > 0 ? "linked" : "")
|
||||||
|
@ -169,7 +169,7 @@ export function spawnBookmarkModal() {
|
||||||
|
|
||||||
container.appendTo(container_bookmarks);
|
container.appendTo(container_bookmarks);
|
||||||
container.on('click', event => {
|
container.on('click', event => {
|
||||||
if(selected_bookmark === entry)
|
if (selected_bookmark === entry)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
selected_bookmark = entry;
|
selected_bookmark = entry;
|
||||||
|
@ -178,7 +178,7 @@ export function spawnBookmarkModal() {
|
||||||
update_buttons();
|
update_buttons();
|
||||||
update_selected();
|
update_selected();
|
||||||
});
|
});
|
||||||
if(entry.unique_id === _current_selected)
|
if (entry.unique_id === _current_selected)
|
||||||
container.trigger('click');
|
container.trigger('click');
|
||||||
|
|
||||||
hide_links.push(sibling_data.last);
|
hide_links.push(sibling_data.last);
|
||||||
|
@ -203,7 +203,7 @@ export function spawnBookmarkModal() {
|
||||||
.text("")
|
.text("")
|
||||||
.css("display", "none")
|
.css("display", "none")
|
||||||
);
|
);
|
||||||
for(const profile of profiles()) {
|
for (const profile of profiles()) {
|
||||||
input_connect_profile.append(
|
input_connect_profile.append(
|
||||||
$.spawn("option")
|
$.spawn("option")
|
||||||
.attr("value", profile.id)
|
.attr("value", profile.id)
|
||||||
|
@ -215,11 +215,11 @@ export function spawnBookmarkModal() {
|
||||||
/* buttons */
|
/* buttons */
|
||||||
{
|
{
|
||||||
button_delete.on('click', event => {
|
button_delete.on('click', event => {
|
||||||
if(!selected_bookmark) return;
|
if (!selected_bookmark) return;
|
||||||
|
|
||||||
if(selected_bookmark.type === BookmarkType.DIRECTORY && (selected_bookmark as DirectoryBookmark).content.length > 0) {
|
if (selected_bookmark.type === BookmarkType.DIRECTORY && (selected_bookmark as DirectoryBookmark).content.length > 0) {
|
||||||
spawnYesNo(tr("Are you sure"), tr("Do you really want to delete this non empty directory?"), answer => {
|
spawnYesNo(tr("Are you sure"), tr("Do you really want to delete this non empty directory?"), answer => {
|
||||||
if(answer) {
|
if (answer) {
|
||||||
delete_bookmark(selected_bookmark);
|
delete_bookmark(selected_bookmark);
|
||||||
save_bookmark(selected_bookmark);
|
save_bookmark(selected_bookmark);
|
||||||
update_bookmark_list(undefined);
|
update_bookmark_list(undefined);
|
||||||
|
@ -236,7 +236,7 @@ export function spawnBookmarkModal() {
|
||||||
createInputModal(tr("Enter a folder name"), tr("Enter the folder name"), text => {
|
createInputModal(tr("Enter a folder name"), tr("Enter the folder name"), text => {
|
||||||
return true;
|
return true;
|
||||||
}, result => {
|
}, result => {
|
||||||
if(result) {
|
if (result) {
|
||||||
const mark = create_bookmark_directory(
|
const mark = create_bookmark_directory(
|
||||||
selected_bookmark ?
|
selected_bookmark ?
|
||||||
selected_bookmark.type === BookmarkType.DIRECTORY ?
|
selected_bookmark.type === BookmarkType.DIRECTORY ?
|
||||||
|
@ -255,7 +255,7 @@ export function spawnBookmarkModal() {
|
||||||
createInputModal(tr("Enter a bookmark name"), tr("Enter the bookmark name"), text => {
|
createInputModal(tr("Enter a bookmark name"), tr("Enter the bookmark name"), text => {
|
||||||
return true;
|
return true;
|
||||||
}, result => {
|
}, result => {
|
||||||
if(result) {
|
if (result) {
|
||||||
const mark = create_bookmark(result as string,
|
const mark = create_bookmark(result as string,
|
||||||
selected_bookmark ?
|
selected_bookmark ?
|
||||||
selected_bookmark.type === BookmarkType.DIRECTORY ?
|
selected_bookmark.type === BookmarkType.DIRECTORY ?
|
||||||
|
@ -285,8 +285,8 @@ export function spawnBookmarkModal() {
|
||||||
|
|
||||||
button_duplicate.on('click', event => {
|
button_duplicate.on('click', event => {
|
||||||
createInputModal(tr("Enter a bookmark name"), tr("Enter the bookmark name for the duplicate"), text => text.length > 0, result => {
|
createInputModal(tr("Enter a bookmark name"), tr("Enter the bookmark name for the duplicate"), text => text.length > 0, result => {
|
||||||
if(result) {
|
if (result) {
|
||||||
if(!selected_bookmark) return;
|
if (!selected_bookmark) return;
|
||||||
|
|
||||||
const original = selected_bookmark as Bookmark;
|
const original = selected_bookmark as Bookmark;
|
||||||
const mark = create_bookmark(result as string,
|
const mark = create_bookmark(result as string,
|
||||||
|
@ -307,7 +307,7 @@ export function spawnBookmarkModal() {
|
||||||
const valid = name.length > 3;
|
const valid = name.length > 3;
|
||||||
input_bookmark_name.firstParent(".input-boxed").toggleClass("is-invalid", !valid);
|
input_bookmark_name.firstParent(".input-boxed").toggleClass("is-invalid", !valid);
|
||||||
|
|
||||||
if(event.type === "change" && valid) {
|
if (event.type === "change" && valid) {
|
||||||
selected_bookmark.display_name = name;
|
selected_bookmark.display_name = name;
|
||||||
label_bookmark_name.text(name);
|
label_bookmark_name.text(name);
|
||||||
save_bookmark(selected_bookmark);
|
save_bookmark(selected_bookmark);
|
||||||
|
@ -319,11 +319,11 @@ export function spawnBookmarkModal() {
|
||||||
const valid = !!address.match(Regex.IP_V4) || !!address.match(Regex.IP_V6) || !!address.match(Regex.DOMAIN);
|
const valid = !!address.match(Regex.IP_V4) || !!address.match(Regex.IP_V6) || !!address.match(Regex.DOMAIN);
|
||||||
input_server_address.firstParent(".input-boxed").toggleClass("is-invalid", !valid);
|
input_server_address.firstParent(".input-boxed").toggleClass("is-invalid", !valid);
|
||||||
|
|
||||||
if(valid) {
|
if (valid) {
|
||||||
const entry = selected_bookmark as Bookmark;
|
const entry = selected_bookmark as Bookmark;
|
||||||
let _v6_end = address.indexOf(']');
|
let _v6_end = address.indexOf(']');
|
||||||
let idx = address.lastIndexOf(':');
|
let idx = address.lastIndexOf(':');
|
||||||
if(idx != -1 && idx > _v6_end) {
|
if (idx != -1 && idx > _v6_end) {
|
||||||
entry.server_properties.server_port = parseInt(address.substr(idx + 1));
|
entry.server_properties.server_port = parseInt(address.substr(idx + 1));
|
||||||
entry.server_properties.server_address = address.substr(0, idx);
|
entry.server_properties.server_address = address.substr(0, idx);
|
||||||
} else {
|
} else {
|
||||||
|
@ -346,7 +346,7 @@ export function spawnBookmarkModal() {
|
||||||
input_connect_profile.on('change', event => {
|
input_connect_profile.on('change', event => {
|
||||||
const id = input_connect_profile.val() as string;
|
const id = input_connect_profile.val() as string;
|
||||||
const profile = profiles().find(e => e.id === id);
|
const profile = profiles().find(e => e.id === id);
|
||||||
if(profile) {
|
if (profile) {
|
||||||
(selected_bookmark as Bookmark).connect_profile = id;
|
(selected_bookmark as Bookmark).connect_profile = id;
|
||||||
save_bookmark(selected_bookmark);
|
save_bookmark(selected_bookmark);
|
||||||
} else {
|
} else {
|
||||||
|
@ -364,8 +364,8 @@ export function spawnBookmarkModal() {
|
||||||
_focus_listener = event => {
|
_focus_listener = event => {
|
||||||
_focused = false;
|
_focused = false;
|
||||||
let element = event.target as HTMLElement;
|
let element = event.target as HTMLElement;
|
||||||
while(element) {
|
while (element) {
|
||||||
if(element === container_bookmarks[0]) {
|
if (element === container_bookmarks[0]) {
|
||||||
_focused = true;
|
_focused = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -374,11 +374,11 @@ export function spawnBookmarkModal() {
|
||||||
};
|
};
|
||||||
|
|
||||||
_key_listener = event => {
|
_key_listener = event => {
|
||||||
if(!_focused) return;
|
if (!_focused) return;
|
||||||
|
|
||||||
if(event.key.toLowerCase() === "arrowdown") {
|
if (event.key.toLowerCase() === "arrowdown") {
|
||||||
container_bookmarks.find(".selected").next().trigger('click');
|
container_bookmarks.find(".selected").next().trigger('click');
|
||||||
} else if(event.key.toLowerCase() === "arrowup") {
|
} else if (event.key.toLowerCase() === "arrowup") {
|
||||||
container_bookmarks.find(".selected").prev().trigger('click');
|
container_bookmarks.find(".selected").prev().trigger('click');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -404,7 +404,7 @@ export function spawnBookmarkModal() {
|
||||||
|
|
||||||
modal.htmlTag.dividerfy().find(".modal-body").addClass("modal-bookmarks");
|
modal.htmlTag.dividerfy().find(".modal-body").addClass("modal-bookmarks");
|
||||||
modal.close_listener.push(() => {
|
modal.close_listener.push(() => {
|
||||||
control_bar_instance()?.events().fire("update_state", { state: "bookmarks" });
|
control_bar_instance()?.events().fire("update_state", {state: "bookmarks"});
|
||||||
top_menu.rebuild_bookmarks();
|
top_menu.rebuild_bookmarks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import {createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {ClientEntry} from "tc-shared/tree/Client";
|
import {ClientEntry} from "../../tree/Client";
|
||||||
import {Slider, sliderfy} from "tc-shared/ui/elements/Slider";
|
import {Slider, sliderfy} from "../../ui/elements/Slider";
|
||||||
import * as htmltags from "tc-shared/ui/htmltags";
|
import * as htmltags from "../../ui/htmltags";
|
||||||
import {VoicePlayerLatencySettings} from "tc-shared/voice/VoicePlayer";
|
import {VoicePlayerLatencySettings} from "../../voice/VoicePlayer";
|
||||||
|
|
||||||
let modalInstance: Modal;
|
let modalInstance: Modal;
|
||||||
export function spawnChangeLatency(client: ClientEntry, current: VoicePlayerLatencySettings, reset: () => VoicePlayerLatencySettings, apply: (settings: VoicePlayerLatencySettings) => void, callback_flush?: () => any) {
|
export function spawnChangeLatency(client: ClientEntry, current: VoicePlayerLatencySettings, reset: () => VoicePlayerLatencySettings, apply: (settings: VoicePlayerLatencySettings) => void, callback_flush?: () => any) {
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
//TODO: Use the max limit!
|
//TODO: Use the max limit!
|
||||||
|
|
||||||
import {sliderfy} from "tc-shared/ui/elements/Slider";
|
import {sliderfy} from "../../ui/elements/Slider";
|
||||||
import {createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {ClientEntry} from "tc-shared/tree/Client";
|
import {ClientEntry} from "../../tree/Client";
|
||||||
import * as htmltags from "tc-shared/ui/htmltags";
|
import * as htmltags from "../../ui/htmltags";
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
|
|
||||||
export function spawnChangeVolume(client: ClientEntry, local: boolean, current: number, max: number | undefined, callback: (number) => void) {
|
export function spawnChangeVolume(client: ClientEntry, local: boolean, current: number, max: number | undefined, callback: (number) => void) {
|
||||||
if(modal) modal.close();
|
if (modal) modal.close();
|
||||||
|
|
||||||
let new_value: number;
|
let new_value: number;
|
||||||
modal = createModal({
|
modal = createModal({
|
||||||
|
@ -29,7 +30,7 @@ export function spawnChangeVolume(client: ClientEntry, local: boolean, current:
|
||||||
container_value.html((value == 100 ? "±" : value > 100 ? "+" : "-") + number + "%");
|
container_value.html((value == 100 ? "±" : value > 100 ? "+" : "-") + number + "%");
|
||||||
|
|
||||||
new_value = value / 100;
|
new_value = value / 100;
|
||||||
if(local) callback(new_value);
|
if (local) callback(new_value);
|
||||||
};
|
};
|
||||||
set_value(current * 100);
|
set_value(current * 100);
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ export function spawnChangeVolume(client: ClientEntry, local: boolean, current:
|
||||||
slider_tag.on('change', event => set_value(parseInt(slider_tag.attr("value"))));
|
slider_tag.on('change', event => set_value(parseInt(slider_tag.attr("value"))));
|
||||||
|
|
||||||
tag.find(".button-save").on('click', event => {
|
tag.find(".button-save").on('click', event => {
|
||||||
if(typeof(new_value) !== "undefined") callback(new_value);
|
if (typeof (new_value) !== "undefined") callback(new_value);
|
||||||
modal.close();
|
modal.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import {createInfoModal, createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createInfoModal, createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {ChannelEntry} from "tc-shared/tree/Channel";
|
import {ChannelEntry} from "../../tree/Channel";
|
||||||
import {copy_to_clipboard} from "tc-shared/utils/helpers";
|
import {copy_to_clipboard} from "../../utils/helpers";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../../ui/frames/chat";
|
||||||
|
|
||||||
export function openChannelInfo(channel: ChannelEntry) {
|
export function openChannelInfo(channel: ChannelEntry) {
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
|
@ -39,12 +39,13 @@ export function openChannelInfo(channel: ChannelEntry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const xbbcode;
|
declare const xbbcode;
|
||||||
|
|
||||||
function apply_channel_description(container: JQuery, channel: ChannelEntry) {
|
function apply_channel_description(container: JQuery, channel: ChannelEntry) {
|
||||||
const container_value = container.find(".value");
|
const container_value = container.find(".value");
|
||||||
const container_no_value = container.find(".no-value");
|
const container_no_value = container.find(".no-value");
|
||||||
|
|
||||||
channel.getChannelDescription().then(description => {
|
channel.getChannelDescription().then(description => {
|
||||||
if(description) {
|
if (description) {
|
||||||
const result = xbbcode.parse(description, {});
|
const result = xbbcode.parse(description, {});
|
||||||
container_value[0].innerHTML = result.build_html();
|
container_value[0].innerHTML = result.build_html();
|
||||||
container_no_value.hide();
|
container_no_value.hide();
|
||||||
|
@ -71,9 +72,9 @@ function apply_general(container: JQuery, channel: ChannelEntry) {
|
||||||
/* channel type */
|
/* channel type */
|
||||||
{
|
{
|
||||||
const tag = container.find(".channel-type .value").empty();
|
const tag = container.find(".channel-type .value").empty();
|
||||||
if(channel.properties.channel_flag_permanent)
|
if (channel.properties.channel_flag_permanent)
|
||||||
tag.text(tr("Permanent"));
|
tag.text(tr("Permanent"));
|
||||||
else if(channel.properties.channel_flag_semi_permanent)
|
else if (channel.properties.channel_flag_semi_permanent)
|
||||||
tag.text(tr("Semi permanent"));
|
tag.text(tr("Semi permanent"));
|
||||||
else
|
else
|
||||||
//TODO: Channel delete delay!
|
//TODO: Channel delete delay!
|
||||||
|
@ -83,12 +84,12 @@ function apply_general(container: JQuery, channel: ChannelEntry) {
|
||||||
/* chat mode */
|
/* chat mode */
|
||||||
{
|
{
|
||||||
const tag = container.find(".chat-mode .value").empty();
|
const tag = container.find(".chat-mode .value").empty();
|
||||||
if(channel.properties.channel_flag_conversation_private || channel.properties.channel_flag_password) {
|
if (channel.properties.channel_flag_conversation_private || channel.properties.channel_flag_password) {
|
||||||
tag.text(tr("Private"));
|
tag.text(tr("Private"));
|
||||||
} else {
|
} else {
|
||||||
if(channel.properties.channel_conversation_history_length == -1)
|
if (channel.properties.channel_conversation_history_length == -1)
|
||||||
tag.text(tr("Public; Semi permanent message saving"));
|
tag.text(tr("Public; Semi permanent message saving"));
|
||||||
else if(channel.properties.channel_conversation_history_length == 0)
|
else if (channel.properties.channel_conversation_history_length == 0)
|
||||||
tag.text(tr("Public; Permanent message saving"));
|
tag.text(tr("Public; Permanent message saving"));
|
||||||
else
|
else
|
||||||
tag.append(formatMessage(tr("Public; Saving last {} messages"), channel.properties.channel_conversation_history_length));
|
tag.append(formatMessage(tr("Public; Saving last {} messages"), channel.properties.channel_conversation_history_length));
|
||||||
|
@ -99,13 +100,13 @@ function apply_general(container: JQuery, channel: ChannelEntry) {
|
||||||
{
|
{
|
||||||
const tag = container.find(".current-clients .value").empty();
|
const tag = container.find(".current-clients .value").empty();
|
||||||
|
|
||||||
if(channel.flag_subscribed) {
|
if (channel.flag_subscribed) {
|
||||||
const current = channel.clients().length;
|
const current = channel.clients().length;
|
||||||
let channel_limit = tr("Unlimited");
|
let channel_limit = tr("Unlimited");
|
||||||
if(!channel.properties.channel_flag_maxclients_unlimited)
|
if (!channel.properties.channel_flag_maxclients_unlimited)
|
||||||
channel_limit = "" + channel.properties.channel_maxclients;
|
channel_limit = "" + channel.properties.channel_maxclients;
|
||||||
else if(!channel.properties.channel_flag_maxfamilyclients_unlimited) {
|
else if (!channel.properties.channel_flag_maxfamilyclients_unlimited) {
|
||||||
if(channel.properties.channel_maxfamilyclients >= 0)
|
if (channel.properties.channel_maxfamilyclients >= 0)
|
||||||
channel_limit = "" + channel.properties.channel_maxfamilyclients;
|
channel_limit = "" + channel.properties.channel_maxfamilyclients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,9 +127,9 @@ function apply_general(container: JQuery, channel: ChannelEntry) {
|
||||||
const tag = container.find(".audio-encrypted .value").empty();
|
const tag = container.find(".audio-encrypted .value").empty();
|
||||||
const mode = channel.channelTree.server.properties.virtualserver_codec_encryption_mode;
|
const mode = channel.channelTree.server.properties.virtualserver_codec_encryption_mode;
|
||||||
let appendix;
|
let appendix;
|
||||||
if(mode == 1)
|
if (mode == 1)
|
||||||
appendix = tr("Overridden by the server with Unencrypted!");
|
appendix = tr("Overridden by the server with Unencrypted!");
|
||||||
else if(mode == 2)
|
else if (mode == 2)
|
||||||
appendix = tr("Overridden by the server with Encrypted!");
|
appendix = tr("Overridden by the server with Encrypted!");
|
||||||
|
|
||||||
tag.html((channel.properties.channel_codec_is_unencrypted ? tr("Unencrypted") : tr("Encrypted")) + (appendix ? "<br>" + appendix : ""))
|
tag.html((channel.properties.channel_codec_is_unencrypted ? tr("Unencrypted") : tr("Encrypted")) + (appendix ? "<br>" + appendix : ""))
|
||||||
|
@ -137,7 +138,7 @@ function apply_general(container: JQuery, channel: ChannelEntry) {
|
||||||
/* flag password */
|
/* flag password */
|
||||||
{
|
{
|
||||||
const tag = container.find(".flag-password .value").empty();
|
const tag = container.find(".flag-password .value").empty();
|
||||||
if(channel.properties.channel_flag_password)
|
if (channel.properties.channel_flag_password)
|
||||||
tag.text(tr("Yes"));
|
tag.text(tr("Yes"));
|
||||||
else
|
else
|
||||||
tag.text(tr("No"));
|
tag.text(tr("No"));
|
||||||
|
@ -147,7 +148,7 @@ function apply_general(container: JQuery, channel: ChannelEntry) {
|
||||||
{
|
{
|
||||||
const container_tag = container.find(".topic");
|
const container_tag = container.find(".topic");
|
||||||
const tag = container_tag.find(".value").empty();
|
const tag = container_tag.find(".value").empty();
|
||||||
if(channel.properties.channel_topic) {
|
if (channel.properties.channel_topic) {
|
||||||
container_tag.show();
|
container_tag.show();
|
||||||
tag.text(channel.properties.channel_topic);
|
tag.text(channel.properties.channel_topic);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import {ClientConnectionInfo, ClientEntry} from "tc-shared/tree/Client";
|
import {ClientConnectionInfo, ClientEntry} from "../../tree/Client";
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import PermissionType from "../../permission/PermissionType";
|
||||||
import {createInfoModal, createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createInfoModal, createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {copy_to_clipboard} from "tc-shared/utils/helpers";
|
import {copy_to_clipboard} from "../../utils/helpers";
|
||||||
import * as i18nc from "tc-shared/i18n/country";
|
import * as i18nc from "../../i18n/country";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
import {format_number, network} from "tc-shared/ui/frames/chat";
|
import {format_number, network} from "../../ui/frames/chat";
|
||||||
|
|
||||||
type InfoUpdateCallback = (info: ClientConnectionInfo) => any;
|
type InfoUpdateCallback = (info: ClientConnectionInfo) => any;
|
||||||
|
|
||||||
export function openClientInfo(client: ClientEntry) {
|
export function openClientInfo(client: ClientEntry) {
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let update_callbacks: InfoUpdateCallback[] = [];
|
let update_callbacks: InfoUpdateCallback[] = [];
|
||||||
|
@ -64,31 +65,31 @@ const TIME_WEEK = 7 * TIME_DAY;
|
||||||
|
|
||||||
function format_time(time: number, default_value: string) {
|
function format_time(time: number, default_value: string) {
|
||||||
let result = "";
|
let result = "";
|
||||||
if(time > TIME_WEEK) {
|
if (time > TIME_WEEK) {
|
||||||
const amount = Math.floor(time / TIME_WEEK);
|
const amount = Math.floor(time / TIME_WEEK);
|
||||||
result += " " + amount + " " + (amount > 1 ? tr("Weeks") : tr("Week"));
|
result += " " + amount + " " + (amount > 1 ? tr("Weeks") : tr("Week"));
|
||||||
time -= amount * TIME_WEEK;
|
time -= amount * TIME_WEEK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(time > TIME_DAY) {
|
if (time > TIME_DAY) {
|
||||||
const amount = Math.floor(time / TIME_DAY);
|
const amount = Math.floor(time / TIME_DAY);
|
||||||
result += " " + amount + " " + (amount > 1 ? tr("Days") : tr("Day"));
|
result += " " + amount + " " + (amount > 1 ? tr("Days") : tr("Day"));
|
||||||
time -= amount * TIME_DAY;
|
time -= amount * TIME_DAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(time > TIME_HOUR) {
|
if (time > TIME_HOUR) {
|
||||||
const amount = Math.floor(time / TIME_HOUR);
|
const amount = Math.floor(time / TIME_HOUR);
|
||||||
result += " " + amount + " " + (amount > 1 ? tr("Hours") : tr("Hour"));
|
result += " " + amount + " " + (amount > 1 ? tr("Hours") : tr("Hour"));
|
||||||
time -= amount * TIME_HOUR;
|
time -= amount * TIME_HOUR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(time > TIME_MINUTE) {
|
if (time > TIME_MINUTE) {
|
||||||
const amount = Math.floor(time / TIME_MINUTE);
|
const amount = Math.floor(time / TIME_MINUTE);
|
||||||
result += " " + amount + " " + (amount > 1 ? tr("Minutes") : tr("Minute"));
|
result += " " + amount + " " + (amount > 1 ? tr("Minutes") : tr("Minute"));
|
||||||
time -= amount * TIME_MINUTE;
|
time -= amount * TIME_MINUTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(time > TIME_SECOND) {
|
if (time > TIME_SECOND) {
|
||||||
const amount = Math.floor(time / TIME_SECOND);
|
const amount = Math.floor(time / TIME_SECOND);
|
||||||
result += " " + amount + " " + (amount > 1 ? tr("Seconds") : tr("Second"));
|
result += " " + amount + " " + (amount > 1 ? tr("Seconds") : tr("Second"));
|
||||||
time -= amount * TIME_SECOND;
|
time -= amount * TIME_SECOND;
|
||||||
|
@ -99,7 +100,10 @@ function format_time(time: number, default_value: string) {
|
||||||
|
|
||||||
function apply_static_info(client: ClientEntry, tag: JQuery, modal: Modal, callbacks: InfoUpdateCallback[]) {
|
function apply_static_info(client: ClientEntry, tag: JQuery, modal: Modal, callbacks: InfoUpdateCallback[]) {
|
||||||
tag.find(".container-avatar").append(
|
tag.find(".container-avatar").append(
|
||||||
client.channelTree.client.fileManager.avatars.generate_chat_tag({database_id: client.properties.client_database_id, id: client.clientId()}, client.properties.client_unique_identifier)
|
client.channelTree.client.fileManager.avatars.generate_chat_tag({
|
||||||
|
database_id: client.properties.client_database_id,
|
||||||
|
id: client.clientId()
|
||||||
|
}, client.properties.client_unique_identifier)
|
||||||
);
|
);
|
||||||
|
|
||||||
tag.find(".container-name").append(
|
tag.find(".container-name").append(
|
||||||
|
@ -120,7 +124,7 @@ function apply_client_status(client: ClientEntry, tag: JQuery, modal: Modal, cal
|
||||||
|
|
||||||
|
|
||||||
tag.find(".status-away").toggle(client.properties.client_away);
|
tag.find(".status-away").toggle(client.properties.client_away);
|
||||||
if(client.properties.client_away_message) {
|
if (client.properties.client_away_message) {
|
||||||
tag.find(".container-away-message").show().find("a").text(client.properties.client_away_message);
|
tag.find(".container-away-message").show().find("a").text(client.properties.client_away_message);
|
||||||
} else {
|
} else {
|
||||||
tag.find(".container-away-message").hide();
|
tag.find(".container-away-message").hide();
|
||||||
|
@ -145,15 +149,15 @@ function apply_basic_info(client: ClientEntry, tag: JQuery, modal: Modal, callba
|
||||||
{
|
{
|
||||||
const container = tag.find(".property-teaforo .value").empty();
|
const container = tag.find(".property-teaforo .value").empty();
|
||||||
|
|
||||||
if(client.properties.client_teaforo_id) {
|
if (client.properties.client_teaforo_id) {
|
||||||
container.children().remove();
|
container.children().remove();
|
||||||
|
|
||||||
let text = client.properties.client_teaforo_name;
|
let text = client.properties.client_teaforo_name;
|
||||||
if((client.properties.client_teaforo_flags & 0x01) > 0)
|
if ((client.properties.client_teaforo_flags & 0x01) > 0)
|
||||||
text += " (" + tr("Banned") + ")";
|
text += " (" + tr("Banned") + ")";
|
||||||
if((client.properties.client_teaforo_flags & 0x02) > 0)
|
if ((client.properties.client_teaforo_flags & 0x02) > 0)
|
||||||
text += " (" + tr("Stuff") + ")";
|
text += " (" + tr("Stuff") + ")";
|
||||||
if((client.properties.client_teaforo_flags & 0x04) > 0)
|
if ((client.properties.client_teaforo_flags & 0x04) > 0)
|
||||||
text += " (" + tr("Premium") + ")";
|
text += " (" + tr("Premium") + ")";
|
||||||
|
|
||||||
$.spawn("a")
|
$.spawn("a")
|
||||||
|
@ -186,7 +190,7 @@ function apply_basic_info(client: ClientEntry, tag: JQuery, modal: Modal, callba
|
||||||
timestamp = parseInt(ts);
|
timestamp = parseInt(ts);
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
if(timestamp > 0) {
|
if (timestamp > 0) {
|
||||||
container_timestamp.find(".value-timestamp").text(moment(timestamp * 1000).format('MMMM Do YYYY, h:mm:ss a'));
|
container_timestamp.find(".value-timestamp").text(moment(timestamp * 1000).format('MMMM Do YYYY, h:mm:ss a'));
|
||||||
container_timestamp.show();
|
container_timestamp.show();
|
||||||
} else {
|
} else {
|
||||||
|
@ -248,7 +252,7 @@ function apply_basic_info(client: ClientEntry, tag: JQuery, modal: Modal, callba
|
||||||
const container = tag.find(".property-online-since");
|
const container = tag.find(".property-online-since");
|
||||||
|
|
||||||
const node = container.find(".value a")[0];
|
const node = container.find(".value a")[0];
|
||||||
if(node) {
|
if (node) {
|
||||||
const update = () => {
|
const update = () => {
|
||||||
node.innerText = format_time(client.calculateOnlineTime() * 1000, tr("0 Seconds"));
|
node.innerText = format_time(client.calculateOnlineTime() * 1000, tr("0 Seconds"));
|
||||||
};
|
};
|
||||||
|
@ -262,7 +266,7 @@ function apply_basic_info(client: ClientEntry, tag: JQuery, modal: Modal, callba
|
||||||
{
|
{
|
||||||
const container = tag.find(".property-idle-time");
|
const container = tag.find(".property-idle-time");
|
||||||
const node = container.find(".value a")[0];
|
const node = container.find(".value a")[0];
|
||||||
if(node) {
|
if (node) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
node.innerText = format_time(info.connection_idle_time, tr("Currently active"));
|
node.innerText = format_time(info.connection_idle_time, tr("Currently active"));
|
||||||
});
|
});
|
||||||
|
@ -275,11 +279,11 @@ function apply_basic_info(client: ClientEntry, tag: JQuery, modal: Modal, callba
|
||||||
const container = tag.find(".property-ping");
|
const container = tag.find(".property-ping");
|
||||||
const node = container.find(".value a")[0];
|
const node = container.find(".value a")[0];
|
||||||
|
|
||||||
if(node) {
|
if (node) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
if(info.connection_ping >= 0)
|
if (info.connection_ping >= 0)
|
||||||
node.innerText = info.connection_ping.toFixed(0) + "ms ± " + info.connection_ping_deviation.toFixed(2) + "ms";
|
node.innerText = info.connection_ping.toFixed(0) + "ms ± " + info.connection_ping_deviation.toFixed(2) + "ms";
|
||||||
else if(info.connection_ping == -1 && info.connection_ping_deviation == -1)
|
else if (info.connection_ping == -1 && info.connection_ping_deviation == -1)
|
||||||
node.innerText = tr("Not calculated");
|
node.innerText = tr("Not calculated");
|
||||||
else
|
else
|
||||||
node.innerText = tr("loading...");
|
node.innerText = tr("loading...");
|
||||||
|
@ -299,12 +303,12 @@ function apply_groups(client: ClientEntry, tag: JQuery, modal: Modal, callbacks:
|
||||||
container_entries.empty();
|
container_entries.empty();
|
||||||
container_empty.show();
|
container_empty.show();
|
||||||
|
|
||||||
for(const group_id of client.assignedServerGroupIds()) {
|
for (const group_id of client.assignedServerGroupIds()) {
|
||||||
if(group_id == client.channelTree.server.properties.virtualserver_default_server_group)
|
if (group_id == client.channelTree.server.properties.virtualserver_default_server_group)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const group = client.channelTree.client.groups.findServerGroup(group_id);
|
const group = client.channelTree.client.groups.findServerGroup(group_id);
|
||||||
if(!group) continue; //This shall never happen!
|
if (!group) continue; //This shall never happen!
|
||||||
|
|
||||||
container_empty.hide();
|
container_empty.hide();
|
||||||
container_entries.append($.spawn("div").addClass("entry").append(
|
container_entries.append($.spawn("div").addClass("entry").append(
|
||||||
|
@ -339,14 +343,14 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
const node_downstream = container.find(".downstream .value")[0];
|
const node_downstream = container.find(".downstream .value")[0];
|
||||||
const node_upstream = container.find(".upstream .value")[0];
|
const node_upstream = container.find(".upstream .value")[0];
|
||||||
|
|
||||||
if(node_downstream) {
|
if (node_downstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
node_downstream.innerText = info.connection_server2client_packetloss_control < 0 ? tr("Not calculated") : (info.connection_server2client_packetloss_control || 0).toFixed();
|
node_downstream.innerText = info.connection_server2client_packetloss_control < 0 ? tr("Not calculated") : (info.connection_server2client_packetloss_control || 0).toFixed();
|
||||||
});
|
});
|
||||||
node_downstream.innerText = tr("loading...");
|
node_downstream.innerText = tr("loading...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node_upstream) {
|
if (node_upstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
node_upstream.innerText = info.connection_client2server_packetloss_total < 0 ? tr("Not calculated") : (info.connection_client2server_packetloss_total || 0).toFixed();
|
node_upstream.innerText = info.connection_client2server_packetloss_total < 0 ? tr("Not calculated") : (info.connection_client2server_packetloss_total || 0).toFixed();
|
||||||
});
|
});
|
||||||
|
@ -360,13 +364,13 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
const node_downstream = container.find(".downstream .value")[0];
|
const node_downstream = container.find(".downstream .value")[0];
|
||||||
const node_upstream = container.find(".upstream .value")[0];
|
const node_upstream = container.find(".upstream .value")[0];
|
||||||
|
|
||||||
if(node_downstream) {
|
if (node_downstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
let packets = 0;
|
let packets = 0;
|
||||||
packets += info.connection_packets_received_speech > 0 ? info.connection_packets_received_speech : 0;
|
packets += info.connection_packets_received_speech > 0 ? info.connection_packets_received_speech : 0;
|
||||||
packets += info.connection_packets_received_control > 0 ? info.connection_packets_received_control : 0;
|
packets += info.connection_packets_received_control > 0 ? info.connection_packets_received_control : 0;
|
||||||
packets += info.connection_packets_received_keepalive > 0 ? info.connection_packets_received_keepalive : 0;
|
packets += info.connection_packets_received_keepalive > 0 ? info.connection_packets_received_keepalive : 0;
|
||||||
if(packets == 0 && info.connection_packets_received_keepalive == -1)
|
if (packets == 0 && info.connection_packets_received_keepalive == -1)
|
||||||
node_downstream.innerText = tr("Not calculated");
|
node_downstream.innerText = tr("Not calculated");
|
||||||
else
|
else
|
||||||
node_downstream.innerText = format_number(packets, {unit: "Packets"});
|
node_downstream.innerText = format_number(packets, {unit: "Packets"});
|
||||||
|
@ -374,13 +378,13 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
node_downstream.innerText = tr("loading...");
|
node_downstream.innerText = tr("loading...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node_upstream) {
|
if (node_upstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
let packets = 0;
|
let packets = 0;
|
||||||
packets += info.connection_packets_sent_speech > 0 ? info.connection_packets_sent_speech : 0;
|
packets += info.connection_packets_sent_speech > 0 ? info.connection_packets_sent_speech : 0;
|
||||||
packets += info.connection_packets_sent_control > 0 ? info.connection_packets_sent_control : 0;
|
packets += info.connection_packets_sent_control > 0 ? info.connection_packets_sent_control : 0;
|
||||||
packets += info.connection_packets_sent_keepalive > 0 ? info.connection_packets_sent_keepalive : 0;
|
packets += info.connection_packets_sent_keepalive > 0 ? info.connection_packets_sent_keepalive : 0;
|
||||||
if(packets == 0 && info.connection_packets_sent_keepalive == -1)
|
if (packets == 0 && info.connection_packets_sent_keepalive == -1)
|
||||||
node_upstream.innerText = tr("Not calculated");
|
node_upstream.innerText = tr("Not calculated");
|
||||||
else
|
else
|
||||||
node_upstream.innerText = format_number(packets, {unit: "Packets"});
|
node_upstream.innerText = format_number(packets, {unit: "Packets"});
|
||||||
|
@ -395,13 +399,13 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
const node_downstream = container.find(".downstream .value")[0];
|
const node_downstream = container.find(".downstream .value")[0];
|
||||||
const node_upstream = container.find(".upstream .value")[0];
|
const node_upstream = container.find(".upstream .value")[0];
|
||||||
|
|
||||||
if(node_downstream) {
|
if (node_downstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
let bytes = 0;
|
let bytes = 0;
|
||||||
bytes += info.connection_bytes_received_speech > 0 ? info.connection_bytes_received_speech : 0;
|
bytes += info.connection_bytes_received_speech > 0 ? info.connection_bytes_received_speech : 0;
|
||||||
bytes += info.connection_bytes_received_control > 0 ? info.connection_bytes_received_control : 0;
|
bytes += info.connection_bytes_received_control > 0 ? info.connection_bytes_received_control : 0;
|
||||||
bytes += info.connection_bytes_received_keepalive > 0 ? info.connection_bytes_received_keepalive : 0;
|
bytes += info.connection_bytes_received_keepalive > 0 ? info.connection_bytes_received_keepalive : 0;
|
||||||
if(bytes == 0 && info.connection_bytes_received_keepalive == -1)
|
if (bytes == 0 && info.connection_bytes_received_keepalive == -1)
|
||||||
node_downstream.innerText = tr("Not calculated");
|
node_downstream.innerText = tr("Not calculated");
|
||||||
else
|
else
|
||||||
node_downstream.innerText = network.format_bytes(bytes);
|
node_downstream.innerText = network.format_bytes(bytes);
|
||||||
|
@ -409,13 +413,13 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
node_downstream.innerText = tr("loading...");
|
node_downstream.innerText = tr("loading...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node_upstream) {
|
if (node_upstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
let bytes = 0;
|
let bytes = 0;
|
||||||
bytes += info.connection_bytes_sent_speech > 0 ? info.connection_bytes_sent_speech : 0;
|
bytes += info.connection_bytes_sent_speech > 0 ? info.connection_bytes_sent_speech : 0;
|
||||||
bytes += info.connection_bytes_sent_control > 0 ? info.connection_bytes_sent_control : 0;
|
bytes += info.connection_bytes_sent_control > 0 ? info.connection_bytes_sent_control : 0;
|
||||||
bytes += info.connection_bytes_sent_keepalive > 0 ? info.connection_bytes_sent_keepalive : 0;
|
bytes += info.connection_bytes_sent_keepalive > 0 ? info.connection_bytes_sent_keepalive : 0;
|
||||||
if(bytes == 0 && info.connection_bytes_sent_keepalive == -1)
|
if (bytes == 0 && info.connection_bytes_sent_keepalive == -1)
|
||||||
node_upstream.innerText = tr("Not calculated");
|
node_upstream.innerText = tr("Not calculated");
|
||||||
else
|
else
|
||||||
node_upstream.innerText = network.format_bytes(bytes);
|
node_upstream.innerText = network.format_bytes(bytes);
|
||||||
|
@ -430,27 +434,27 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
const node_downstream = container.find(".downstream .value")[0];
|
const node_downstream = container.find(".downstream .value")[0];
|
||||||
const node_upstream = container.find(".upstream .value")[0];
|
const node_upstream = container.find(".upstream .value")[0];
|
||||||
|
|
||||||
if(node_downstream) {
|
if (node_downstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
let bytes = 0;
|
let bytes = 0;
|
||||||
bytes += info.connection_bandwidth_received_last_second_speech > 0 ? info.connection_bandwidth_received_last_second_speech : 0;
|
bytes += info.connection_bandwidth_received_last_second_speech > 0 ? info.connection_bandwidth_received_last_second_speech : 0;
|
||||||
bytes += info.connection_bandwidth_received_last_second_control > 0 ? info.connection_bandwidth_received_last_second_control : 0;
|
bytes += info.connection_bandwidth_received_last_second_control > 0 ? info.connection_bandwidth_received_last_second_control : 0;
|
||||||
bytes += info.connection_bandwidth_received_last_second_keepalive > 0 ? info.connection_bandwidth_received_last_second_keepalive : 0;
|
bytes += info.connection_bandwidth_received_last_second_keepalive > 0 ? info.connection_bandwidth_received_last_second_keepalive : 0;
|
||||||
if(bytes == 0 && info.connection_bandwidth_received_last_second_keepalive == -1)
|
if (bytes == 0 && info.connection_bandwidth_received_last_second_keepalive == -1)
|
||||||
node_downstream.innerText = tr("Not calculated");
|
node_downstream.innerText = tr("Not calculated");
|
||||||
else
|
else
|
||||||
node_downstream.innerText = network.format_bytes(bytes, {time: "s"});
|
node_downstream.innerText = network.format_bytes(bytes, {time: "s"});
|
||||||
});
|
});
|
||||||
node_downstream.innerText = tr("loading...");
|
node_downstream.innerText = tr("loading...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node_upstream) {
|
if (node_upstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
let bytes = 0;
|
let bytes = 0;
|
||||||
bytes += info.connection_bandwidth_sent_last_second_speech > 0 ? info.connection_bandwidth_sent_last_second_speech : 0;
|
bytes += info.connection_bandwidth_sent_last_second_speech > 0 ? info.connection_bandwidth_sent_last_second_speech : 0;
|
||||||
bytes += info.connection_bandwidth_sent_last_second_control > 0 ? info.connection_bandwidth_sent_last_second_control : 0;
|
bytes += info.connection_bandwidth_sent_last_second_control > 0 ? info.connection_bandwidth_sent_last_second_control : 0;
|
||||||
bytes += info.connection_bandwidth_sent_last_second_keepalive > 0 ? info.connection_bandwidth_sent_last_second_keepalive : 0;
|
bytes += info.connection_bandwidth_sent_last_second_keepalive > 0 ? info.connection_bandwidth_sent_last_second_keepalive : 0;
|
||||||
if(bytes == 0 && info.connection_bandwidth_sent_last_second_keepalive == -1)
|
if (bytes == 0 && info.connection_bandwidth_sent_last_second_keepalive == -1)
|
||||||
node_upstream.innerText = tr("Not calculated");
|
node_upstream.innerText = tr("Not calculated");
|
||||||
else
|
else
|
||||||
node_upstream.innerText = network.format_bytes(bytes, {time: "s"});
|
node_upstream.innerText = network.format_bytes(bytes, {time: "s"});
|
||||||
|
@ -465,13 +469,13 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
const node_downstream = container.find(".downstream .value")[0];
|
const node_downstream = container.find(".downstream .value")[0];
|
||||||
const node_upstream = container.find(".upstream .value")[0];
|
const node_upstream = container.find(".upstream .value")[0];
|
||||||
|
|
||||||
if(node_downstream) {
|
if (node_downstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
let bytes = 0;
|
let bytes = 0;
|
||||||
bytes += info.connection_bandwidth_received_last_minute_speech > 0 ? info.connection_bandwidth_received_last_minute_speech : 0;
|
bytes += info.connection_bandwidth_received_last_minute_speech > 0 ? info.connection_bandwidth_received_last_minute_speech : 0;
|
||||||
bytes += info.connection_bandwidth_received_last_minute_control > 0 ? info.connection_bandwidth_received_last_minute_control : 0;
|
bytes += info.connection_bandwidth_received_last_minute_control > 0 ? info.connection_bandwidth_received_last_minute_control : 0;
|
||||||
bytes += info.connection_bandwidth_received_last_minute_keepalive > 0 ? info.connection_bandwidth_received_last_minute_keepalive : 0;
|
bytes += info.connection_bandwidth_received_last_minute_keepalive > 0 ? info.connection_bandwidth_received_last_minute_keepalive : 0;
|
||||||
if(bytes == 0 && info.connection_bandwidth_received_last_minute_keepalive == -1)
|
if (bytes == 0 && info.connection_bandwidth_received_last_minute_keepalive == -1)
|
||||||
node_downstream.innerText = tr("Not calculated");
|
node_downstream.innerText = tr("Not calculated");
|
||||||
else
|
else
|
||||||
node_downstream.innerText = network.format_bytes(bytes, {time: "s"});
|
node_downstream.innerText = network.format_bytes(bytes, {time: "s"});
|
||||||
|
@ -479,13 +483,13 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
node_downstream.innerText = tr("loading...");
|
node_downstream.innerText = tr("loading...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node_upstream) {
|
if (node_upstream) {
|
||||||
callbacks.push(info => {
|
callbacks.push(info => {
|
||||||
let bytes = 0;
|
let bytes = 0;
|
||||||
bytes += info.connection_bandwidth_sent_last_minute_speech > 0 ? info.connection_bandwidth_sent_last_minute_speech : 0;
|
bytes += info.connection_bandwidth_sent_last_minute_speech > 0 ? info.connection_bandwidth_sent_last_minute_speech : 0;
|
||||||
bytes += info.connection_bandwidth_sent_last_minute_control > 0 ? info.connection_bandwidth_sent_last_minute_control : 0;
|
bytes += info.connection_bandwidth_sent_last_minute_control > 0 ? info.connection_bandwidth_sent_last_minute_control : 0;
|
||||||
bytes += info.connection_bandwidth_sent_last_minute_keepalive > 0 ? info.connection_bandwidth_sent_last_minute_keepalive : 0;
|
bytes += info.connection_bandwidth_sent_last_minute_keepalive > 0 ? info.connection_bandwidth_sent_last_minute_keepalive : 0;
|
||||||
if(bytes == 0 && info.connection_bandwidth_sent_last_minute_keepalive == -1)
|
if (bytes == 0 && info.connection_bandwidth_sent_last_minute_keepalive == -1)
|
||||||
node_upstream.innerText = tr("Not calculated");
|
node_upstream.innerText = tr("Not calculated");
|
||||||
else
|
else
|
||||||
node_upstream.innerText = network.format_bytes(bytes, {time: "s"});
|
node_upstream.innerText = network.format_bytes(bytes, {time: "s"});
|
||||||
|
@ -500,7 +504,7 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
const node_downstream = container.find(".downstream .value")[0];
|
const node_downstream = container.find(".downstream .value")[0];
|
||||||
const node_upstream = container.find(".upstream .value")[0];
|
const node_upstream = container.find(".upstream .value")[0];
|
||||||
|
|
||||||
if(node_downstream) {
|
if (node_downstream) {
|
||||||
client.updateClientVariables().then(info => {
|
client.updateClientVariables().then(info => {
|
||||||
//TODO: Test for own client info and if so then show the max quota (needed permission)
|
//TODO: Test for own client info and if so then show the max quota (needed permission)
|
||||||
node_downstream.innerText = network.format_bytes(client.properties.client_month_bytes_downloaded, {exact: false});
|
node_downstream.innerText = network.format_bytes(client.properties.client_month_bytes_downloaded, {exact: false});
|
||||||
|
@ -508,7 +512,7 @@ function apply_packets(client: ClientEntry, tag: JQuery, modal: Modal, callbacks
|
||||||
node_downstream.innerText = tr("loading...");
|
node_downstream.innerText = tr("loading...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node_upstream) {
|
if (node_upstream) {
|
||||||
client.updateClientVariables().then(info => {
|
client.updateClientVariables().then(info => {
|
||||||
//TODO: Test for own client info and if so then show the max quota (needed permission)
|
//TODO: Test for own client info and if so then show the max quota (needed permission)
|
||||||
node_upstream.innerText = network.format_bytes(client.properties.client_month_bytes_uploaded, {exact: false});
|
node_upstream.innerText = network.format_bytes(client.properties.client_month_bytes_uploaded, {exact: false});
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../../settings";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import * as log from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import {createModal} from "tc-shared/ui/elements/Modal";
|
import {createModal} from "../../ui/elements/Modal";
|
||||||
import {ConnectionProfile, default_profile, find_profile, profiles} from "tc-shared/profiles/ConnectionProfile";
|
import {ConnectionProfile, default_profile, find_profile, profiles} from "../../profiles/ConnectionProfile";
|
||||||
import {KeyCode} from "tc-shared/PPTListener";
|
import {KeyCode} from "../../PPTListener";
|
||||||
import * as i18nc from "tc-shared/i18n/country";
|
import * as i18nc from "../../i18n/country";
|
||||||
import {spawnSettingsModal} from "tc-shared/ui/modal/ModalSettings";
|
import {spawnSettingsModal} from "../../ui/modal/ModalSettings";
|
||||||
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
|
import {server_connections} from "../../ui/frames/connection_handlers";
|
||||||
import {icon_cache_loader, IconManager} from "tc-shared/file/Icons";
|
import {icon_cache_loader, IconManager} from "../../file/Icons";
|
||||||
|
|
||||||
//FIXME: Move this shit out of this file!
|
//FIXME: Move this shit out of this file!
|
||||||
export namespace connection_log {
|
export namespace connection_log {
|
||||||
|
@ -36,9 +36,10 @@ export namespace connection_log {
|
||||||
}
|
}
|
||||||
|
|
||||||
let _history: ConnectionEntry[] = [];
|
let _history: ConnectionEntry[] = [];
|
||||||
|
|
||||||
export function log_connect(address: { hostname: string; port: number }) {
|
export function log_connect(address: { hostname: string; port: number }) {
|
||||||
let entry = _history.find(e => e.address.hostname.toLowerCase() == address.hostname.toLowerCase() && e.address.port == address.port);
|
let entry = _history.find(e => e.address.hostname.toLowerCase() == address.hostname.toLowerCase() && e.address.port == address.port);
|
||||||
if(!entry) {
|
if (!entry) {
|
||||||
_history.push(entry = {
|
_history.push(entry = {
|
||||||
last_timestamp: Date.now(),
|
last_timestamp: Date.now(),
|
||||||
first_timestamp: Date.now(),
|
first_timestamp: Date.now(),
|
||||||
|
@ -62,8 +63,8 @@ export namespace connection_log {
|
||||||
|
|
||||||
export function update_address_info(address: { hostname: string; port: number }, data: ConnectionData) {
|
export function update_address_info(address: { hostname: string; port: number }, data: ConnectionData) {
|
||||||
_history.filter(e => e.address.hostname.toLowerCase() == address.hostname.toLowerCase() && e.address.port == address.port).forEach(e => {
|
_history.filter(e => e.address.hostname.toLowerCase() == address.hostname.toLowerCase() && e.address.port == address.port).forEach(e => {
|
||||||
for(const key of Object.keys(data)) {
|
for (const key of Object.keys(data)) {
|
||||||
if(typeof(data[key]) !== "undefined") {
|
if (typeof (data[key]) !== "undefined") {
|
||||||
e[key] = data[key];
|
e[key] = data[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +83,7 @@ export namespace connection_log {
|
||||||
settings.changeGlobal(Settings.KEY_CONNECT_HISTORY, JSON.stringify(_history));
|
settings.changeGlobal(Settings.KEY_CONNECT_HISTORY, JSON.stringify(_history));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function history() : ConnectionEntry[] {
|
export function history(): ConnectionEntry[] {
|
||||||
return _history.sort((a, b) => b.last_timestamp - a.last_timestamp);
|
return _history.sort((a, b) => b.last_timestamp - a.last_timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ export namespace connection_log {
|
||||||
_history = [];
|
_history = [];
|
||||||
try {
|
try {
|
||||||
_history = JSON.parse(settings.global(Settings.KEY_CONNECT_HISTORY, "[]"));
|
_history = JSON.parse(settings.global(Settings.KEY_CONNECT_HISTORY, "[]"));
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
log.warn(LogCategory.CLIENT, tr("Failed to load connection history: {}"), error);
|
log.warn(LogCategory.CLIENT, tr("Failed to load connection history: {}"), error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,9 +107,13 @@ export namespace connection_log {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const native_client;
|
declare const native_client;
|
||||||
|
|
||||||
export function spawnConnectModal(options: {
|
export function spawnConnectModal(options: {
|
||||||
default_connect_new_tab?: boolean /* default false */
|
default_connect_new_tab?: boolean /* default false */
|
||||||
}, defaultHost: { url: string, enforce: boolean} = { url: "ts.TeaSpeak.de", enforce: false}, connect_profile?: { profile: ConnectionProfile, enforce: boolean}) {
|
}, defaultHost: { url: string, enforce: boolean } = {
|
||||||
|
url: "ts.TeaSpeak.de",
|
||||||
|
enforce: false
|
||||||
|
}, connect_profile?: { profile: ConnectionProfile, enforce: boolean }) {
|
||||||
let selected_profile: ConnectionProfile;
|
let selected_profile: ConnectionProfile;
|
||||||
|
|
||||||
const random_id = (() => {
|
const random_id = (() => {
|
||||||
|
@ -124,7 +129,7 @@ export function spawnConnectModal(options: {
|
||||||
forum_path: "https://forum.teaspeak.de/",
|
forum_path: "https://forum.teaspeak.de/",
|
||||||
password_id: random_id,
|
password_id: random_id,
|
||||||
multi_tab: !settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION),
|
multi_tab: !settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION),
|
||||||
default_connect_new_tab: typeof(options.default_connect_new_tab) === "boolean" && options.default_connect_new_tab
|
default_connect_new_tab: typeof (options.default_connect_new_tab) === "boolean" && options.default_connect_new_tab
|
||||||
}),
|
}),
|
||||||
footer: () => undefined,
|
footer: () => undefined,
|
||||||
min_width: "28em"
|
min_width: "28em"
|
||||||
|
@ -162,7 +167,7 @@ export function spawnConnectModal(options: {
|
||||||
const input_password = body.find(".container-password input");
|
const input_password = body.find(".container-password input");
|
||||||
|
|
||||||
let updateFields = (reset_current_data: boolean) => {
|
let updateFields = (reset_current_data: boolean) => {
|
||||||
if(reset_current_data) {
|
if (reset_current_data) {
|
||||||
current_connect_data = undefined;
|
current_connect_data = undefined;
|
||||||
container_last_server_body.find(".selected").removeClass("selected");
|
container_last_server_body.find(".selected").removeClass("selected");
|
||||||
}
|
}
|
||||||
|
@ -172,7 +177,7 @@ export function spawnConnectModal(options: {
|
||||||
let flag_address = !!address.match(Regex.IP_V4) || !!address.match(Regex.IP_V6) || !!address.match(Regex.DOMAIN);
|
let flag_address = !!address.match(Regex.IP_V4) || !!address.match(Regex.IP_V6) || !!address.match(Regex.DOMAIN);
|
||||||
|
|
||||||
let nickname = input_nickname.val().toString();
|
let nickname = input_nickname.val().toString();
|
||||||
if(nickname)
|
if (nickname)
|
||||||
settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, nickname);
|
settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, nickname);
|
||||||
else
|
else
|
||||||
nickname = input_nickname.attr("placeholder") || "";
|
nickname = input_nickname.attr("placeholder") || "";
|
||||||
|
@ -190,7 +195,7 @@ export function spawnConnectModal(options: {
|
||||||
input_address
|
input_address
|
||||||
.on("keyup", () => updateFields(true))
|
.on("keyup", () => updateFields(true))
|
||||||
.on('keydown', event => {
|
.on('keydown', event => {
|
||||||
if(event.keyCode == KeyCode.KEY_ENTER && !event.shiftKey)
|
if (event.keyCode == KeyCode.KEY_ENTER && !event.shiftKey)
|
||||||
button_connect.trigger('click');
|
button_connect.trigger('click');
|
||||||
});
|
});
|
||||||
button_manage.on('click', event => {
|
button_manage.on('click', event => {
|
||||||
|
@ -203,7 +208,7 @@ export function spawnConnectModal(options: {
|
||||||
|
|
||||||
/* Connect Profiles */
|
/* Connect Profiles */
|
||||||
{
|
{
|
||||||
for(const profile of profiles()) {
|
for (const profile of profiles()) {
|
||||||
input_profile.append(
|
input_profile.append(
|
||||||
$.spawn("option").text(profile.profile_name).val(profile.id)
|
$.spawn("option").text(profile.profile_name).val(profile.id)
|
||||||
);
|
);
|
||||||
|
@ -229,7 +234,7 @@ export function spawnConnectModal(options: {
|
||||||
}
|
}
|
||||||
|
|
||||||
const last_nickname = settings.static_global(Settings.KEY_CONNECT_USERNAME, undefined);
|
const last_nickname = settings.static_global(Settings.KEY_CONNECT_USERNAME, undefined);
|
||||||
if(last_nickname) /* restore */
|
if (last_nickname) /* restore */
|
||||||
settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, last_nickname);
|
settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, last_nickname);
|
||||||
|
|
||||||
input_nickname.val(last_nickname);
|
input_nickname.val(last_nickname);
|
||||||
|
@ -238,7 +243,7 @@ export function spawnConnectModal(options: {
|
||||||
|
|
||||||
const server_address = () => {
|
const server_address = () => {
|
||||||
let address = input_address.val().toString();
|
let address = input_address.val().toString();
|
||||||
if(address.match(Regex.IP_V6) && !address.startsWith("["))
|
if (address.match(Regex.IP_V6) && !address.startsWith("["))
|
||||||
return "[" + address + "]";
|
return "[" + address + "]";
|
||||||
return address;
|
return address;
|
||||||
};
|
};
|
||||||
|
@ -246,14 +251,17 @@ export function spawnConnectModal(options: {
|
||||||
modal.close();
|
modal.close();
|
||||||
|
|
||||||
const connection = server_connections.active_connection();
|
const connection = server_connections.active_connection();
|
||||||
if(connection) {
|
if (connection) {
|
||||||
connection.startConnection(
|
connection.startConnection(
|
||||||
current_connect_data ? current_connect_data.address.hostname + ":" + current_connect_data.address.port : server_address(),
|
current_connect_data ? current_connect_data.address.hostname + ":" + current_connect_data.address.port : server_address(),
|
||||||
selected_profile,
|
selected_profile,
|
||||||
true,
|
true,
|
||||||
{
|
{
|
||||||
nickname: input_nickname.val().toString() || input_nickname.attr("placeholder"),
|
nickname: input_nickname.val().toString() || input_nickname.attr("placeholder"),
|
||||||
password: (current_connect_data && current_connect_data.password_hash) ? {password: current_connect_data.password_hash, hashed: true} : {password: input_password.val().toString(), hashed: false}
|
password: (current_connect_data && current_connect_data.password_hash) ? {
|
||||||
|
password: current_connect_data.password_hash,
|
||||||
|
hashed: true
|
||||||
|
} : {password: input_password.val().toString(), hashed: false}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -266,12 +274,15 @@ export function spawnConnectModal(options: {
|
||||||
const connection = server_connections.spawn_server_connection();
|
const connection = server_connections.spawn_server_connection();
|
||||||
server_connections.set_active_connection(connection);
|
server_connections.set_active_connection(connection);
|
||||||
connection.startConnection(
|
connection.startConnection(
|
||||||
current_connect_data ? current_connect_data.address.hostname + ":" + current_connect_data.address.port : server_address(),
|
current_connect_data ? current_connect_data.address.hostname + ":" + current_connect_data.address.port : server_address(),
|
||||||
selected_profile,
|
selected_profile,
|
||||||
true,
|
true,
|
||||||
{
|
{
|
||||||
nickname: input_nickname.val().toString() || input_nickname.attr("placeholder"),
|
nickname: input_nickname.val().toString() || input_nickname.attr("placeholder"),
|
||||||
password: (current_connect_data && current_connect_data.password_hash) ? {password: current_connect_data.password_hash, hashed: true} : {password: input_password.val().toString(), hashed: false}
|
password: (current_connect_data && current_connect_data.password_hash) ? {
|
||||||
|
password: current_connect_data.password_hash,
|
||||||
|
hashed: true
|
||||||
|
} : {password: input_password.val().toString(), hashed: false}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -279,7 +290,7 @@ export function spawnConnectModal(options: {
|
||||||
|
|
||||||
/* connect history show */
|
/* connect history show */
|
||||||
{
|
{
|
||||||
for(const entry of connection_log.history().slice(0, 10)) {
|
for (const entry of connection_log.history().slice(0, 10)) {
|
||||||
$.spawn("div").addClass("row").append(
|
$.spawn("div").addClass("row").append(
|
||||||
$.spawn("div").addClass("column delete").append($.spawn("div").addClass("icon_em client-delete")).on('click', event => {
|
$.spawn("div").addClass("column delete").append($.spawn("div").addClass("icon_em client-delete")).on('click', event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -310,7 +321,7 @@ export function spawnConnectModal(options: {
|
||||||
).append(
|
).append(
|
||||||
$.spawn("div").addClass("column connections").text(entry.total_connection + "")
|
$.spawn("div").addClass("column connections").text(entry.total_connection + "")
|
||||||
).on('click', event => {
|
).on('click', event => {
|
||||||
if(event.isDefaultPrevented())
|
if (event.isDefaultPrevented())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import PermissionType from "../../permission/PermissionType";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {ChannelEntry, ChannelProperties} from "tc-shared/tree/Channel";
|
import {ChannelEntry, ChannelProperties} from "../../tree/Channel";
|
||||||
import {PermissionManager, PermissionValue} from "tc-shared/permission/PermissionManager";
|
import {PermissionManager, PermissionValue} from "../../permission/PermissionManager";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import {createModal} from "tc-shared/ui/elements/Modal";
|
import {createModal} from "../../ui/elements/Modal";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import {Settings, settings} from "tc-shared/settings";
|
import {Settings, settings} from "../../settings";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
import {spawnIconSelect} from "tc-shared/ui/modal/ModalIconSelect";
|
import {spawnIconSelect} from "../../ui/modal/ModalIconSelect";
|
||||||
import {hashPassword} from "tc-shared/utils/helpers";
|
import {hashPassword} from "../../utils/helpers";
|
||||||
import {sliderfy} from "tc-shared/ui/elements/Slider";
|
import {sliderfy} from "../../ui/elements/Slider";
|
||||||
|
|
||||||
export function createChannelModal(connection: ConnectionHandler, channel: ChannelEntry | undefined, parent: ChannelEntry | undefined, permissions: PermissionManager, callback: (properties?: ChannelProperties, permissions?: PermissionValue[]) => any) {
|
export function createChannelModal(connection: ConnectionHandler, channel: ChannelEntry | undefined, parent: ChannelEntry | undefined, permissions: PermissionManager, callback: (properties?: ChannelProperties, permissions?: PermissionValue[]) => any) {
|
||||||
let properties: ChannelProperties = { } as ChannelProperties; //The changes properties
|
let properties: ChannelProperties = { } as ChannelProperties; //The changes properties
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import {createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import {ClientEntry} from "tc-shared/tree/Client";
|
import {ClientEntry} from "../../tree/Client";
|
||||||
import {GroupManager, GroupType} from "tc-shared/permission/GroupManager";
|
import {GroupManager, GroupType} from "../../permission/GroupManager";
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import PermissionType from "../../permission/PermissionType";
|
||||||
|
|
||||||
let current_modal: Modal;
|
let current_modal: Modal;
|
||||||
export function createServerGroupAssignmentModal(client: ClientEntry, callback: (groups: number[], flag: boolean) => Promise<boolean>) {
|
export function createServerGroupAssignmentModal(client: ClientEntry, callback: (groups: number[], flag: boolean) => Promise<boolean>) {
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import PermissionType from "../../permission/PermissionType";
|
||||||
import {createErrorModal, createModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createModal} from "../../ui/elements/Modal";
|
||||||
import * as log from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {tra, traj} from "tc-shared/i18n/localize";
|
import {tra, traj} from "../../i18n/localize";
|
||||||
import {arrayBufferBase64} from "tc-shared/utils/buffers";
|
import {arrayBufferBase64} from "../../utils/buffers";
|
||||||
import * as crc32 from "tc-shared/crypto/crc32";
|
import * as crc32 from "../../crypto/crc32";
|
||||||
import {FileInfo} from "tc-shared/file/FileManager";
|
import {FileInfo} from "../../file/FileManager";
|
||||||
import {FileTransferState, TransferProvider} from "tc-shared/file/Transfer";
|
import {FileTransferState, TransferProvider} from "../../file/Transfer";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../../connection/ErrorCode";
|
||||||
|
|
||||||
export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id: number) => any, selected_icon?: number) {
|
export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id: number) => any, selected_icon?: number) {
|
||||||
selected_icon = selected_icon || 0;
|
selected_icon = selected_icon || 0;
|
||||||
|
@ -49,9 +49,9 @@ export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id:
|
||||||
const update_local_icons = (icons: number[]) => {
|
const update_local_icons = (icons: number[]) => {
|
||||||
container_icons_local.empty();
|
container_icons_local.empty();
|
||||||
|
|
||||||
for(const icon_id of icons) {
|
for (const icon_id of icons) {
|
||||||
const tag = client.fileManager.icons.generateTag(icon_id, {animate: false}).attr('title', "Icon " + icon_id);
|
const tag = client.fileManager.icons.generateTag(icon_id, {animate: false}).attr('title', "Icon " + icon_id);
|
||||||
if(callback_icon) {
|
if (callback_icon) {
|
||||||
tag.on('click', event => {
|
tag.on('click', event => {
|
||||||
container_icons.find(".selected").removeClass("selected");
|
container_icons.find(".selected").removeClass("selected");
|
||||||
tag.addClass("selected");
|
tag.addClass("selected");
|
||||||
|
@ -64,7 +64,7 @@ export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id:
|
||||||
callback_icon(icon_id);
|
callback_icon(icon_id);
|
||||||
modal.close();
|
modal.close();
|
||||||
});
|
});
|
||||||
if(icon_id == selected_icon)
|
if (icon_id == selected_icon)
|
||||||
tag.trigger('click');
|
tag.trigger('click');
|
||||||
}
|
}
|
||||||
tag.appendTo(container_icons_local);
|
tag.appendTo(container_icons_local);
|
||||||
|
@ -76,7 +76,7 @@ export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id:
|
||||||
container_error.hide();
|
container_error.hide();
|
||||||
container_loading.show();
|
container_loading.show();
|
||||||
const display_remote_error = (error?: string) => {
|
const display_remote_error = (error?: string) => {
|
||||||
if(typeof(error) === "string") {
|
if (typeof (error) === "string") {
|
||||||
container_error.find(".error-message").text(error);
|
container_error.find(".error-message").text(error);
|
||||||
container_error.show();
|
container_error.show();
|
||||||
} else {
|
} else {
|
||||||
|
@ -91,23 +91,23 @@ export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id:
|
||||||
const chunk_size = 50;
|
const chunk_size = 50;
|
||||||
const icon_chunks: FileInfo[][] = [];
|
const icon_chunks: FileInfo[][] = [];
|
||||||
let index = 0;
|
let index = 0;
|
||||||
while(icons.length > index) {
|
while (icons.length > index) {
|
||||||
icon_chunks.push(icons.slice(index, index + chunk_size));
|
icon_chunks.push(icons.slice(index, index + chunk_size));
|
||||||
index += chunk_size;
|
index += chunk_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
const process_next_chunk = () => {
|
const process_next_chunk = () => {
|
||||||
const chunk = icon_chunks.pop_front();
|
const chunk = icon_chunks.pop_front();
|
||||||
if(!chunk) return;
|
if (!chunk) return;
|
||||||
|
|
||||||
for(const icon of chunk) {
|
for (const icon of chunk) {
|
||||||
const icon_id = parseInt(icon.name.substr("icon_".length));
|
const icon_id = parseInt(icon.name.substr("icon_".length));
|
||||||
if(Number.isNaN(icon_id)) {
|
if (Number.isNaN(icon_id)) {
|
||||||
log.warn(LogCategory.GENERAL, tr("Received an unparsable icon within icon list (%o)"), icon);
|
log.warn(LogCategory.GENERAL, tr("Received an unparsable icon within icon list (%o)"), icon);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const tag = client.fileManager.icons.generateTag(icon_id, {animate: false}).attr('title', "Icon " + icon_id);
|
const tag = client.fileManager.icons.generateTag(icon_id, {animate: false}).attr('title', "Icon " + icon_id);
|
||||||
if(callback_icon || allow_manage) {
|
if (callback_icon || allow_manage) {
|
||||||
tag.on('click', event => {
|
tag.on('click', event => {
|
||||||
container_icons.find(".selected").removeClass("selected");
|
container_icons.find(".selected").removeClass("selected");
|
||||||
tag.addClass("selected");
|
tag.addClass("selected");
|
||||||
|
@ -118,13 +118,13 @@ export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id:
|
||||||
button_delete.prop("disabled", !allow_manage);
|
button_delete.prop("disabled", !allow_manage);
|
||||||
});
|
});
|
||||||
tag.on('dblclick', event => {
|
tag.on('dblclick', event => {
|
||||||
if(!callback_icon)
|
if (!callback_icon)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
callback_icon(icon_id);
|
callback_icon(icon_id);
|
||||||
modal.close();
|
modal.close();
|
||||||
});
|
});
|
||||||
if(icon_id == selected_icon)
|
if (icon_id == selected_icon)
|
||||||
tag.trigger('click');
|
tag.trigger('click');
|
||||||
}
|
}
|
||||||
tag.appendTo(container_icons_remote);
|
tag.appendTo(container_icons_remote);
|
||||||
|
@ -138,7 +138,7 @@ export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id:
|
||||||
container_loading.hide();
|
container_loading.hide();
|
||||||
container_no_permissions.hide();
|
container_no_permissions.hide();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if(error instanceof CommandResult && error.id == ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS) {
|
if (error instanceof CommandResult && error.id == ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS) {
|
||||||
container_no_permissions.show();
|
container_no_permissions.show();
|
||||||
} else {
|
} else {
|
||||||
log.error(LogCategory.GENERAL, tr("Failed to fetch icon list. Error: %o"), error);
|
log.error(LogCategory.GENERAL, tr("Failed to fetch icon list. Error: %o"), error);
|
||||||
|
@ -149,19 +149,19 @@ export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id:
|
||||||
};
|
};
|
||||||
|
|
||||||
button_delete.on('click', event => {
|
button_delete.on('click', event => {
|
||||||
if(!selected_icon)
|
if (!selected_icon)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const selected = modal.htmlTag.find(".selected");
|
const selected = modal.htmlTag.find(".selected");
|
||||||
if(selected.length != 1)
|
if (selected.length != 1)
|
||||||
console.warn(tr("UI selected icon length does not equal with 1! (%o)"), selected.length);
|
console.warn(tr("UI selected icon length does not equal with 1! (%o)"), selected.length);
|
||||||
|
|
||||||
if(selected_icon < 1000) return; /* we cant delete local icons */
|
if (selected_icon < 1000) return; /* we cant delete local icons */
|
||||||
|
|
||||||
client.fileManager.icons.delete_icon(selected_icon).then(() => {
|
client.fileManager.icons.delete_icon(selected_icon).then(() => {
|
||||||
selected.detach();
|
selected.detach();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if(error instanceof CommandResult && error.id == ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS)
|
if (error instanceof CommandResult && error.id == ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS)
|
||||||
return;
|
return;
|
||||||
console.warn(tr("Failed to delete icon %d: %o"), selected_icon, error);
|
console.warn(tr("Failed to delete icon %d: %o"), selected_icon, error);
|
||||||
|
|
||||||
|
@ -177,11 +177,11 @@ export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id:
|
||||||
update_remote_icons();
|
update_remote_icons();
|
||||||
modal.htmlTag.find('.button-reload').on('click', () => update_remote_icons());
|
modal.htmlTag.find('.button-reload').on('click', () => update_remote_icons());
|
||||||
button_select.prop("disabled", true).on('click', () => {
|
button_select.prop("disabled", true).on('click', () => {
|
||||||
if(callback_icon) callback_icon(selected_icon);
|
if (callback_icon) callback_icon(selected_icon);
|
||||||
modal.close();
|
modal.close();
|
||||||
});
|
});
|
||||||
modal.htmlTag.find(".button-select-no-icon").on('click', () => {
|
modal.htmlTag.find(".button-select-no-icon").on('click', () => {
|
||||||
if(callback_icon) callback_icon(0);
|
if (callback_icon) callback_icon(0);
|
||||||
modal.close();
|
modal.close();
|
||||||
});
|
});
|
||||||
modal.open();
|
modal.open();
|
||||||
|
@ -203,7 +203,7 @@ interface UploadingIcon {
|
||||||
icon_id: string;
|
icon_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIcon {
|
function handle_icon_upload(file: File, client: ConnectionHandler): UploadingIcon {
|
||||||
const icon = {} as UploadingIcon;
|
const icon = {} as UploadingIcon;
|
||||||
icon.file = file;
|
icon.file = file;
|
||||||
icon.upload_state = "unset";
|
icon.upload_state = "unset";
|
||||||
|
@ -213,9 +213,9 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>The given file is too big!", file.name)).open();
|
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>The given file is too big!", file.name)).open();
|
||||||
icon.state = "error";
|
icon.state = "error";
|
||||||
};
|
};
|
||||||
if(file.size > 1024 * 1024 * 512) {
|
if (file.size > 1024 * 1024 * 512) {
|
||||||
file_too_big();
|
file_too_big();
|
||||||
} else if((file.size | 0) <= 0) {
|
} else if ((file.size | 0) <= 0) {
|
||||||
console.error(tr("Failed to load file %s: Your browser does not support file sizes!"), file.name);
|
console.error(tr("Failed to load file %s: Your browser does not support file sizes!"), file.name);
|
||||||
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>Your browser does not support file sizes!", file.name)).open();
|
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>Your browser does not support file sizes!", file.name)).open();
|
||||||
icon.state = "error";
|
icon.state = "error";
|
||||||
|
@ -231,7 +231,7 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
reader.onerror = reject;
|
reader.onerror = reject;
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
});
|
});
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
console.log("Image failed to load (%o)", error);
|
console.log("Image failed to load (%o)", error);
|
||||||
console.error(tr("Failed to load file %s: Image failed to load"), file.name);
|
console.error(tr("Failed to load file %s: Image failed to load"), file.name);
|
||||||
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>Failed to load image", file.name)).open();
|
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>Failed to load image", file.name)).open();
|
||||||
|
@ -240,7 +240,7 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = reader.result as string;
|
const result = reader.result as string;
|
||||||
if(typeof(result) !== "string") {
|
if (typeof (result) !== "string") {
|
||||||
console.error(tr("Failed to load file %s: Result is not an media string (%o)"), file.name, result);
|
console.error(tr("Failed to load file %s: Result is not an media string (%o)"), file.name, result);
|
||||||
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>Result is not an media string", file.name)).open();
|
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>Result is not an media string", file.name)).open();
|
||||||
icon.state = "error";
|
icon.state = "error";
|
||||||
|
@ -250,7 +250,7 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
|
|
||||||
/* get the CRC32 sum */
|
/* get the CRC32 sum */
|
||||||
{
|
{
|
||||||
if(!result.startsWith("data:image/")) {
|
if (!result.startsWith("data:image/")) {
|
||||||
console.error(tr("Failed to load file %s: Invalid data media type (%o)"), file.name, result);
|
console.error(tr("Failed to load file %s: Invalid data media type (%o)"), file.name, result);
|
||||||
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>File is not an image", file.name)).open();
|
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>File is not an image", file.name)).open();
|
||||||
icon.state = "error";
|
icon.state = "error";
|
||||||
|
@ -259,7 +259,7 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
const semi = result.indexOf(';');
|
const semi = result.indexOf(';');
|
||||||
const type = result.substring(11, semi);
|
const type = result.substring(11, semi);
|
||||||
console.log(tr("Given image has type %s"), type);
|
console.log(tr("Given image has type %s"), type);
|
||||||
if(!result.substr(semi + 1).startsWith("base64,")) {
|
if (!result.substr(semi + 1).startsWith("base64,")) {
|
||||||
console.error(tr("Failed to load file %s: Mimetype isnt base64 encoded (%o)"), file.name, result.substr(semi + 1));
|
console.error(tr("Failed to load file %s: Mimetype isnt base64 encoded (%o)"), file.name, result.substr(semi + 1));
|
||||||
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>Decoder returned unknown result", file.name)).open();
|
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.<br>Decoder returned unknown result", file.name)).open();
|
||||||
icon.state = "error";
|
icon.state = "error";
|
||||||
|
@ -279,7 +279,7 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
image.onerror = reject;
|
image.onerror = reject;
|
||||||
image.src = result;
|
image.src = result;
|
||||||
});
|
});
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
console.log("Image failed to load (%o)", error);
|
console.log("Image failed to load (%o)", error);
|
||||||
console.error(tr("Failed to load file %s: Image failed to load"), file.name);
|
console.error(tr("Failed to load file %s: Image failed to load"), file.name);
|
||||||
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.{:br:}Failed to load image", file.name)).open();
|
createErrorModal(tr("Icon upload failed"), tra("Failed to upload icon {}.{:br:}Failed to load image", file.name)).open();
|
||||||
|
@ -292,16 +292,16 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
icon.state = "error";
|
icon.state = "error";
|
||||||
};
|
};
|
||||||
|
|
||||||
if(!result.startsWith("data:image/svg+xml")) {
|
if (!result.startsWith("data:image/svg+xml")) {
|
||||||
if(image.naturalWidth > 128 && image.naturalHeight > 128) {
|
if (image.naturalWidth > 128 && image.naturalHeight > 128) {
|
||||||
width_error("width and height (max 32px). Given: " + image.naturalWidth + "x" + image.naturalHeight);
|
width_error("width and height (max 32px). Given: " + image.naturalWidth + "x" + image.naturalHeight);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(image.naturalWidth > 128) {
|
if (image.naturalWidth > 128) {
|
||||||
width_error("width (max 32px)");
|
width_error("width (max 32px)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(image.naturalHeight > 128) {
|
if (image.naturalHeight > 128) {
|
||||||
width_error("height (max 32px)");
|
width_error("height (max 32px)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
const message = $.spawn("div").addClass("progress-message");
|
const message = $.spawn("div").addClass("progress-message");
|
||||||
const set_value = value => {
|
const set_value = value => {
|
||||||
indicator.stop(true, false).animate({width: value + "%"}, 250);
|
indicator.stop(true, false).animate({width: value + "%"}, 250);
|
||||||
if(value === 100)
|
if (value === 100)
|
||||||
setTimeout(() => indicator.removeClass("progress-bar-striped progress-bar-animated"), 900)
|
setTimeout(() => indicator.removeClass("progress-bar-striped progress-bar-animated"), 900)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -349,14 +349,14 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
};
|
};
|
||||||
|
|
||||||
const html_tag = $.spawn("div")
|
const html_tag = $.spawn("div")
|
||||||
.addClass("upload-entry")
|
.addClass("upload-entry")
|
||||||
.append(container_image)
|
.append(container_image)
|
||||||
.append(bar.html_tag);
|
.append(bar.html_tag);
|
||||||
|
|
||||||
icon.upload_html_tag = html_tag;
|
icon.upload_html_tag = html_tag;
|
||||||
|
|
||||||
let icon_added = false;
|
let icon_added = false;
|
||||||
if(icon.image_element) {
|
if (icon.image_element) {
|
||||||
container_image.append(icon.image_element());
|
container_image.append(icon.image_element());
|
||||||
icon_added = true;
|
icon_added = true;
|
||||||
}
|
}
|
||||||
|
@ -368,21 +368,21 @@ function handle_icon_upload(file: File, client: ConnectionHandler) : UploadingIc
|
||||||
return async () => {
|
return async () => {
|
||||||
const time_begin = Date.now();
|
const time_begin = Date.now();
|
||||||
|
|
||||||
if(icon.state === "loading") {
|
if (icon.state === "loading") {
|
||||||
bar.set_message(tr("Awaiting local processing"));
|
bar.set_message(tr("Awaiting local processing"));
|
||||||
await icon.loader;
|
await icon.loader;
|
||||||
// @ts-ignore Could happen because the loader function updates the state
|
// @ts-ignore Could happen because the loader function updates the state
|
||||||
if(icon.state !== "valid") {
|
if (icon.state !== "valid") {
|
||||||
set_error(tr("local processing failed"));
|
set_error(tr("local processing failed"));
|
||||||
icon.upload_state = "error";
|
icon.upload_state = "error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if(icon.state === "error") {
|
} else if (icon.state === "error") {
|
||||||
set_error(tr("local processing error"));
|
set_error(tr("local processing error"));
|
||||||
icon.upload_state = "error";
|
icon.upload_state = "error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!icon_added)
|
if (!icon_added)
|
||||||
container_image.append(icon.image_element());
|
container_image.append(icon.image_element());
|
||||||
|
|
||||||
bar.set_value(25);
|
bar.set_value(25);
|
||||||
|
@ -474,11 +474,11 @@ export function spawnIconUpload(client: ConnectionHandler) {
|
||||||
const add_icon = (icon: UploadingIcon) => {
|
const add_icon = (icon: UploadingIcon) => {
|
||||||
icons.push(icon);
|
icons.push(icon);
|
||||||
icon.loader.then(e => {
|
icon.loader.then(e => {
|
||||||
if(icon.state === "valid") {
|
if (icon.state === "valid") {
|
||||||
const image = icon.image_element();
|
const image = icon.image_element();
|
||||||
const element = $.spawn("div")
|
const element = $.spawn("div")
|
||||||
.addClass("icon-container")
|
.addClass("icon-container")
|
||||||
.append(image);
|
.append(image);
|
||||||
container_icons.append(icon.html_tag = element);
|
container_icons.append(icon.html_tag = element);
|
||||||
|
|
||||||
element.on('click', event => {
|
element.on('click', event => {
|
||||||
|
@ -494,10 +494,10 @@ export function spawnIconUpload(client: ConnectionHandler) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
button_delete.on('click', event => {
|
button_delete.on('click', event => {
|
||||||
if(!selected_icon)
|
if (!selected_icon)
|
||||||
return;
|
return;
|
||||||
icons = icons.filter(e => e !== selected_icon);
|
icons = icons.filter(e => e !== selected_icon);
|
||||||
if(selected_icon.html_tag)
|
if (selected_icon.html_tag)
|
||||||
selected_icon.html_tag.detach();
|
selected_icon.html_tag.detach();
|
||||||
button_delete.prop("disabled", true);
|
button_delete.prop("disabled", true);
|
||||||
update_upload_button();
|
update_upload_button();
|
||||||
|
@ -505,18 +505,18 @@ export function spawnIconUpload(client: ConnectionHandler) {
|
||||||
|
|
||||||
button_add.on('click', event => input_file.click());
|
button_add.on('click', event => input_file.click());
|
||||||
input_file.on('change', event => {
|
input_file.on('change', event => {
|
||||||
if(input_file[0].files.length > 0) {
|
if (input_file[0].files.length > 0) {
|
||||||
for(let index = 0; index < input_file[0].files.length; index++) {
|
for (let index = 0; index < input_file[0].files.length; index++) {
|
||||||
const file = input_file[0].files.item(index);
|
const file = input_file[0].files.item(index);
|
||||||
{
|
{
|
||||||
let duplicate = false;
|
let duplicate = false;
|
||||||
|
|
||||||
for(const icon of icons)
|
for (const icon of icons)
|
||||||
if(icon.file.name === file.name && icon.file.lastModified === file.lastModified && icon.state !== "error") {
|
if (icon.file.name === file.name && icon.file.lastModified === file.lastModified && icon.state !== "error") {
|
||||||
duplicate = true;
|
duplicate = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(duplicate)
|
if (duplicate)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,17 +534,17 @@ export function spawnIconUpload(client: ConnectionHandler) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
for(let index = 0; index < event.dataTransfer.files.length; index++) {
|
for (let index = 0; index < event.dataTransfer.files.length; index++) {
|
||||||
const file = event.dataTransfer.files.item(index);
|
const file = event.dataTransfer.files.item(index);
|
||||||
{
|
{
|
||||||
let duplicate = false;
|
let duplicate = false;
|
||||||
|
|
||||||
for(const icon of icons)
|
for (const icon of icons)
|
||||||
if(icon.file === file && icon.state !== "error") {
|
if (icon.file === file && icon.state !== "error") {
|
||||||
duplicate = true;
|
duplicate = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(duplicate)
|
if (duplicate)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ export function spawnIconUpload(client: ConnectionHandler) {
|
||||||
|
|
||||||
const finish_upload = () => {
|
const finish_upload = () => {
|
||||||
icons = icons.filter(e => {
|
icons = icons.filter(e => {
|
||||||
if(e.upload_state === "uploaded") {
|
if (e.upload_state === "uploaded") {
|
||||||
e.html_tag.detach();
|
e.html_tag.detach();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -585,13 +585,13 @@ export function spawnIconUpload(client: ConnectionHandler) {
|
||||||
|
|
||||||
|
|
||||||
const execute_upload = async () => {
|
const execute_upload = async () => {
|
||||||
if(!client || !client.fileManager) {
|
if (!client || !client.fileManager) {
|
||||||
show_critical_error(tr("Invalid client handle"));
|
show_critical_error(tr("Invalid client handle"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!client.connected) {
|
if (!client.connected) {
|
||||||
show_critical_error(tr("Not connected"));
|
show_critical_error(tr("Not connected"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let invoke_count = 0;
|
let invoke_count = 0;
|
||||||
|
@ -600,28 +600,28 @@ export function spawnIconUpload(client: ConnectionHandler) {
|
||||||
|
|
||||||
const uploads = icons.filter(e => e.state !== "error");
|
const uploads = icons.filter(e => e.state !== "error");
|
||||||
|
|
||||||
const executes: {icon: UploadingIcon, task: () => Promise<void>}[] = [];
|
const executes: { icon: UploadingIcon, task: () => Promise<void> }[] = [];
|
||||||
for(const icon of uploads) {
|
for (const icon of uploads) {
|
||||||
executes.push({
|
executes.push({
|
||||||
icon: icon,
|
icon: icon,
|
||||||
task: icon.upload_icon()
|
task: icon.upload_icon()
|
||||||
});
|
});
|
||||||
|
|
||||||
if(!icon.upload_html_tag)
|
if (!icon.upload_html_tag)
|
||||||
continue; /* TODO: error? */
|
continue; /* TODO: error? */
|
||||||
icon.upload_html_tag.appendTo(container_process);
|
icon.upload_html_tag.appendTo(container_process);
|
||||||
}
|
}
|
||||||
|
|
||||||
const update_state = () => container_statistics.text(invoke_count + " | " + succeed_count + " | " + failed_count);
|
const update_state = () => container_statistics.text(invoke_count + " | " + succeed_count + " | " + failed_count);
|
||||||
for(const execute of executes) {
|
for (const execute of executes) {
|
||||||
invoke_count++;
|
invoke_count++;
|
||||||
update_state();
|
update_state();
|
||||||
try {
|
try {
|
||||||
await execute.task();
|
await execute.task();
|
||||||
if(execute.icon.upload_state !== "uploaded")
|
if (execute.icon.upload_state !== "uploaded")
|
||||||
throw "failed";
|
throw "failed";
|
||||||
succeed_count++;
|
succeed_count++;
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
failed_count++;
|
failed_count++;
|
||||||
}
|
}
|
||||||
update_state();
|
update_state();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {createErrorModal, createInfoModal, createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInfoModal, createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {TeaSpeakIdentity} from "tc-shared/profiles/identities/TeamSpeakIdentity";
|
import {TeaSpeakIdentity} from "../../profiles/identities/TeamSpeakIdentity";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../../ui/frames/chat";
|
||||||
|
|
||||||
export function spawnTeamSpeakIdentityImprove(identity: TeaSpeakIdentity, name: string): Modal {
|
export function spawnTeamSpeakIdentityImprove(identity: TeaSpeakIdentity, name: string): Modal {
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
|
@ -125,7 +125,7 @@ export function spawnTeamSpeakIdentityImprove(identity: TeaSpeakIdentity, name:
|
||||||
export function spawnTeamSpeakIdentityImport(callback: (identity: TeaSpeakIdentity) => any): Modal {
|
export function spawnTeamSpeakIdentityImport(callback: (identity: TeaSpeakIdentity) => any): Modal {
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let selected_type: string;
|
let selected_type: string;
|
||||||
let identities: {[key: string]: TeaSpeakIdentity} = {};
|
let identities: { [key: string]: TeaSpeakIdentity } = {};
|
||||||
|
|
||||||
modal = createModal({
|
modal = createModal({
|
||||||
header: tr("Import identity"),
|
header: tr("Import identity"),
|
||||||
|
@ -141,7 +141,7 @@ export function spawnTeamSpeakIdentityImport(callback: (identity: TeaSpeakIdenti
|
||||||
|
|
||||||
const set_status = (message: string | undefined, type: "error" | "loading" | "success") => {
|
const set_status = (message: string | undefined, type: "error" | "loading" | "success") => {
|
||||||
container_status.toggleClass("hidden", !message);
|
container_status.toggleClass("hidden", !message);
|
||||||
if(message) {
|
if (message) {
|
||||||
container_status.toggleClass("error", type === "error");
|
container_status.toggleClass("error", type === "error");
|
||||||
container_status.toggleClass("loading", type === "loading");
|
container_status.toggleClass("loading", type === "loading");
|
||||||
container_status.find("a").text(message);
|
container_status.find("a").text(message);
|
||||||
|
@ -173,7 +173,7 @@ export function spawnTeamSpeakIdentityImport(callback: (identity: TeaSpeakIdenti
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/* file select button */
|
/* file select button */
|
||||||
input_file.on('change', event => {
|
input_file.on('change', event => {
|
||||||
const element = event.target as HTMLInputElement;
|
const element = event.target as HTMLInputElement;
|
||||||
const file_reader = new FileReader();
|
const file_reader = new FileReader();
|
||||||
|
@ -195,12 +195,12 @@ export function spawnTeamSpeakIdentityImport(callback: (identity: TeaSpeakIdenti
|
||||||
|
|
||||||
input_text.on('change keyup', event => {
|
input_text.on('change keyup', event => {
|
||||||
const text = input_text.val() as string;
|
const text = input_text.val() as string;
|
||||||
if(!text) {
|
if (!text) {
|
||||||
set_status("", "success");
|
set_status("", "success");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(text.indexOf('V') == -1) {
|
if (text.indexOf('V') == -1) {
|
||||||
set_status(tr("Invalid identity string"), "error");
|
set_status(tr("Invalid identity string"), "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {settings, Settings} from "tc-shared/settings";
|
import {settings, Settings} from "../../settings";
|
||||||
import {createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {ServerAddress} from "tc-shared/tree/Server";
|
import {ServerAddress} from "../../tree/Server";
|
||||||
|
|
||||||
type URLGeneratorSettings = {
|
type URLGeneratorSettings = {
|
||||||
flag_direct: boolean,
|
flag_direct: boolean,
|
||||||
|
@ -23,16 +23,16 @@ type URLGenerator = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const build_url = (base, params) => {
|
const build_url = (base, params) => {
|
||||||
if(Object.keys(params).length == 0)
|
if (Object.keys(params).length == 0)
|
||||||
return base;
|
return base;
|
||||||
|
|
||||||
return base + "?" + Object.keys(params)
|
return base + "?" + Object.keys(params)
|
||||||
.map(e => e + "=" + encodeURIComponent(params[e]))
|
.map(e => e + "=" + encodeURIComponent(params[e]))
|
||||||
.join("&");
|
.join("&");
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO: Server password
|
//TODO: Server password
|
||||||
const url_generators: {[key: string]:URLGenerator} = {
|
const url_generators: { [key: string]: URLGenerator } = {
|
||||||
"tea-web": {
|
"tea-web": {
|
||||||
generate: properties => {
|
generate: properties => {
|
||||||
const address = properties.resolved_address ? properties.resolved_address : properties.address;
|
const address = properties.resolved_address ? properties.resolved_address : properties.address;
|
||||||
|
@ -40,15 +40,15 @@ const url_generators: {[key: string]:URLGenerator} = {
|
||||||
const parameter = "connect_default=" + (properties.flag_direct ? 1 : 0) + "&connect_address=" + encodeURIComponent(address_str);
|
const parameter = "connect_default=" + (properties.flag_direct ? 1 : 0) + "&connect_address=" + encodeURIComponent(address_str);
|
||||||
|
|
||||||
let pathbase = "";
|
let pathbase = "";
|
||||||
if(document.location.protocol !== 'https:') {
|
if (document.location.protocol !== 'https:') {
|
||||||
/*
|
/*
|
||||||
* Seems to be a test environment or the TeaClient for localhost where we dont have to use https.
|
* Seems to be a test environment or the TeaClient for localhost where we dont have to use https.
|
||||||
*/
|
*/
|
||||||
pathbase = "https://web.teaspeak.de/";
|
pathbase = "https://web.teaspeak.de/";
|
||||||
} else if(document.location.hostname === "localhost" || document.location.host.startsWith("127.")) {
|
} else if (document.location.hostname === "localhost" || document.location.host.startsWith("127.")) {
|
||||||
pathbase = "https://web.teaspeak.de/";
|
pathbase = "https://web.teaspeak.de/";
|
||||||
} else {
|
} else {
|
||||||
pathbase = document.location.origin + document.location.pathname;
|
pathbase = document.location.origin + document.location.pathname;
|
||||||
}
|
}
|
||||||
return pathbase + "?" + parameter;
|
return pathbase + "?" + parameter;
|
||||||
},
|
},
|
||||||
|
@ -68,7 +68,7 @@ const url_generators: {[key: string]:URLGenerator} = {
|
||||||
connect_default: properties.flag_direct ? 1 : 0
|
connect_default: properties.flag_direct ? 1 : 0
|
||||||
};
|
};
|
||||||
|
|
||||||
if(address.port != 9987)
|
if (address.port != 9987)
|
||||||
parameters["port"] = address.port;
|
parameters["port"] = address.port;
|
||||||
|
|
||||||
return build_url("teaclient://" + address.host + "/", parameters);
|
return build_url("teaclient://" + address.host + "/", parameters);
|
||||||
|
@ -85,7 +85,7 @@ const url_generators: {[key: string]:URLGenerator} = {
|
||||||
const address = properties.resolved_address ? properties.resolved_address : properties.address;
|
const address = properties.resolved_address ? properties.resolved_address : properties.address;
|
||||||
|
|
||||||
let parameters = {};
|
let parameters = {};
|
||||||
if(address.port != 9987)
|
if (address.port != 9987)
|
||||||
parameters["port"] = address.port;
|
parameters["port"] = address.port;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -138,7 +138,7 @@ export function spawnInviteEditor(connection: ConnectionHandler) {
|
||||||
value: node => node.prop('checked'),
|
value: node => node.prop('checked'),
|
||||||
set_value: (node, value) => node.prop('checked', value == "1"),
|
set_value: (node, value) => node.prop('checked', value == "1"),
|
||||||
disable: (node, flag) => node.prop('disabled', flag)
|
disable: (node, flag) => node.prop('disabled', flag)
|
||||||
.firstParent('.checkbox').toggleClass('disabled', flag)
|
.firstParent('.checkbox').toggleClass('disabled', flag)
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -147,25 +147,25 @@ export function spawnInviteEditor(connection: ConnectionHandler) {
|
||||||
value: node => node.prop('checked'),
|
value: node => node.prop('checked'),
|
||||||
set_value: (node, value) => node.prop('checked', value == "1"),
|
set_value: (node, value) => node.prop('checked', value == "1"),
|
||||||
disable: (node, flag) => node.prop('disabled', flag)
|
disable: (node, flag) => node.prop('disabled', flag)
|
||||||
.firstParent('.checkbox').toggleClass('disabled', flag)
|
.firstParent('.checkbox').toggleClass('disabled', flag)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const update_buttons = () => {
|
const update_buttons = () => {
|
||||||
const generator = url_generators[input_type.val() as string];
|
const generator = url_generators[input_type.val() as string];
|
||||||
if(!generator) {
|
if (!generator) {
|
||||||
for(const s of invite_settings)
|
for (const s of invite_settings)
|
||||||
s.disable(s.node, true);
|
s.disable(s.node, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const s of invite_settings)
|
for (const s of invite_settings)
|
||||||
s.disable(s.node, !generator.setting_available(s.key as any));
|
s.disable(s.node, !generator.setting_available(s.key as any));
|
||||||
};
|
};
|
||||||
|
|
||||||
const update_link = () => {
|
const update_link = () => {
|
||||||
const generator = url_generators[input_type.val() as string];
|
const generator = url_generators[input_type.val() as string];
|
||||||
if(!generator) {
|
if (!generator) {
|
||||||
button_copy.prop('disabled', true);
|
button_copy.prop('disabled', true);
|
||||||
label_output.text(tr("Missing link generator"));
|
label_output.text(tr("Missing link generator"));
|
||||||
return;
|
return;
|
||||||
|
@ -176,14 +176,14 @@ export function spawnInviteEditor(connection: ConnectionHandler) {
|
||||||
address: connection.channelTree.server.remote_address,
|
address: connection.channelTree.server.remote_address,
|
||||||
resolved_address: connection.channelTree.client.serverConnection.remote_address()
|
resolved_address: connection.channelTree.client.serverConnection.remote_address()
|
||||||
};
|
};
|
||||||
for(const s of invite_settings)
|
for (const s of invite_settings)
|
||||||
properties[s.key] = s.value(s.node);
|
properties[s.key] = s.value(s.node);
|
||||||
|
|
||||||
label_output.text(generator.generate(properties as any));
|
label_output.text(generator.generate(properties as any));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
for(const s of invite_settings) {
|
for (const s of invite_settings) {
|
||||||
s.node.on('change keyup', () => {
|
s.node.on('change keyup', () => {
|
||||||
settings.changeGlobal(Settings.FN_INVITE_LINK_SETTING(s.key), s.value(s.node));
|
settings.changeGlobal(Settings.FN_INVITE_LINK_SETTING(s.key), s.value(s.node));
|
||||||
update_link()
|
update_link()
|
||||||
|
@ -193,10 +193,10 @@ export function spawnInviteEditor(connection: ConnectionHandler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
input_type.on('change', () => {
|
input_type.on('change', () => {
|
||||||
settings.changeGlobal(Settings.KEY_LAST_INVITE_LINK_TYPE, input_type.val() as string);
|
settings.changeGlobal(Settings.KEY_LAST_INVITE_LINK_TYPE, input_type.val() as string);
|
||||||
update_buttons();
|
update_buttons();
|
||||||
update_link();
|
update_link();
|
||||||
}).val(settings.global(Settings.KEY_LAST_INVITE_LINK_TYPE));
|
}).val(settings.global(Settings.KEY_LAST_INVITE_LINK_TYPE));
|
||||||
|
|
||||||
button_copy.on('click', event => {
|
button_copy.on('click', event => {
|
||||||
label_output.select();
|
label_output.select();
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import {createModal} from "tc-shared/ui/elements/Modal";
|
import {createModal} from "../../ui/elements/Modal";
|
||||||
import {EventType, key_description, KeyEvent} from "tc-shared/PPTListener";
|
import {EventType, key_description, KeyEvent} from "../../PPTListener";
|
||||||
import * as ppt from "tc-backend/ppt";
|
import * as ppt from "tc-backend/ppt";
|
||||||
|
|
||||||
export function spawnKeySelect(callback: (key?: KeyEvent) => void) {
|
export function spawnKeySelect(callback: (key?: KeyEvent) => void) {
|
||||||
let modal = createModal({
|
let modal = createModal({
|
||||||
header: tr("Select a key"),
|
header: tr("Select a key"),
|
||||||
body: () => $("#tmpl_key_select").renderTag().children(),
|
body: () => $("#tmpl_key_select").renderTag().children(),
|
||||||
footer: null,
|
footer: null,
|
||||||
|
|
||||||
width: "",
|
width: "",
|
||||||
|
@ -20,7 +20,7 @@ export function spawnKeySelect(callback: (key?: KeyEvent) => void) {
|
||||||
let last_key: KeyEvent;
|
let last_key: KeyEvent;
|
||||||
let current_key: KeyEvent;
|
let current_key: KeyEvent;
|
||||||
const listener = (event: KeyEvent) => {
|
const listener = (event: KeyEvent) => {
|
||||||
if(event.type === EventType.KEY_PRESS) {
|
if (event.type === EventType.KEY_PRESS) {
|
||||||
//console.log(tr("Key select got key press for %o"), event);
|
//console.log(tr("Key select got key press for %o"), event);
|
||||||
last_key = current_key;
|
last_key = current_key;
|
||||||
current_key = event;
|
current_key = event;
|
||||||
|
@ -33,9 +33,9 @@ export function spawnKeySelect(callback: (key?: KeyEvent) => void) {
|
||||||
|
|
||||||
|
|
||||||
button_save.on('click', () => {
|
button_save.on('click', () => {
|
||||||
if(__build.version !== "web") {
|
if (__build.version !== "web") {
|
||||||
/* Because pressing the close button is also a mouse action */
|
/* Because pressing the close button is also a mouse action */
|
||||||
if(current_key_age + 1000 > Date.now() && current_key.key_code == "MOUSE1")
|
if (current_key_age + 1000 > Date.now() && current_key.key_code == "MOUSE1")
|
||||||
current_key = last_key;
|
current_key = last_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
import {createErrorModal, createModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createModal} from "../../ui/elements/Modal";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {MusicClientEntry} from "tc-shared/tree/Client";
|
import {MusicClientEntry} from "../../tree/Client";
|
||||||
import {Registry} from "tc-shared/events";
|
import {modal, Registry} from "../../events";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import * as log from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import {tra} from "tc-shared/i18n/localize";
|
import {tra} from "../../i18n/localize";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
import { modal } from "tc-shared/events";
|
import * as i18nc from "../../i18n/country";
|
||||||
import * as i18nc from "tc-shared/i18n/country";
|
import {find} from "../../permission/PermissionManager";
|
||||||
import {find} from "tc-shared/permission/PermissionManager";
|
import * as htmltags from "../../ui/htmltags";
|
||||||
|
import {ErrorCode} from "../../connection/ErrorCode";
|
||||||
import ServerGroup = find.ServerGroup;
|
import ServerGroup = find.ServerGroup;
|
||||||
import * as htmltags from "tc-shared/ui/htmltags";
|
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
|
||||||
|
|
||||||
export function openMusicManage(client: ConnectionHandler, bot: MusicClientEntry) {
|
export function openMusicManage(client: ConnectionHandler, bot: MusicClientEntry) {
|
||||||
const ev_registry = new Registry<modal.music_manage>();
|
const ev_registry = new Registry<modal.music_manage>();
|
||||||
|
@ -22,7 +21,7 @@ export function openMusicManage(client: ConnectionHandler, bot: MusicClientEntry
|
||||||
|
|
||||||
let modal = createModal({
|
let modal = createModal({
|
||||||
header: tr(tr("Playlist Manage")),
|
header: tr(tr("Playlist Manage")),
|
||||||
body: () => build_modal(ev_registry),
|
body: () => build_modal(ev_registry),
|
||||||
footer: null,
|
footer: null,
|
||||||
|
|
||||||
min_width: "35em",
|
min_width: "35em",
|
||||||
|
@ -40,13 +39,13 @@ export function openMusicManage(client: ConnectionHandler, bot: MusicClientEntry
|
||||||
|
|
||||||
function permission_controller(event_registry: Registry<modal.music_manage>, bot: MusicClientEntry, client: ConnectionHandler) {
|
function permission_controller(event_registry: Registry<modal.music_manage>, bot: MusicClientEntry, client: ConnectionHandler) {
|
||||||
const error_msg = error => {
|
const error_msg = error => {
|
||||||
if(error instanceof CommandResult) {
|
if (error instanceof CommandResult) {
|
||||||
if(error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS) {
|
if (error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS) {
|
||||||
const permission = client.permissions.resolveInfo(error.json["failed_permid"]);
|
const permission = client.permissions.resolveInfo(error.json["failed_permid"]);
|
||||||
return tr("failed on permission ") + (permission ? permission.name : tr("unknown"));
|
return tr("failed on permission ") + (permission ? permission.name : tr("unknown"));
|
||||||
}
|
}
|
||||||
return error.extra_message || error.message;
|
return error.extra_message || error.message;
|
||||||
} else if(typeof error === "string")
|
} else if (typeof error === "string")
|
||||||
return error;
|
return error;
|
||||||
else
|
else
|
||||||
return tr("command error");
|
return tr("command error");
|
||||||
|
@ -85,14 +84,14 @@ function permission_controller(event_registry: Registry<modal.music_manage>, bot
|
||||||
};
|
};
|
||||||
|
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
if(event.key === "notify_song_change") {
|
if (event.key === "notify_song_change") {
|
||||||
return client.serverConnection.send_command("clientedit", {
|
return client.serverConnection.send_command("clientedit", {
|
||||||
clid: bot.clientId(),
|
clid: bot.clientId(),
|
||||||
client_flag_notify_song_change: event.value
|
client_flag_notify_song_change: event.value
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const property = property_map[event.key];
|
const property = property_map[event.key];
|
||||||
if(!property) return Promise.reject(tr("unknown property"));
|
if (!property) return Promise.reject(tr("unknown property"));
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
playlist_id: playlist_id
|
playlist_id: playlist_id
|
||||||
|
@ -158,7 +157,7 @@ function permission_controller(event_registry: Registry<modal.music_manage>, bot
|
||||||
|
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
const property = property_map[event.key];
|
const property = property_map[event.key];
|
||||||
if(!property) return Promise.reject(tr("unknown property"));
|
if (!property) return Promise.reject(tr("unknown property"));
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
clid: bot.clientId()
|
clid: bot.clientId()
|
||||||
|
@ -188,8 +187,8 @@ function permission_controller(event_registry: Registry<modal.music_manage>, bot
|
||||||
const playlist_id = bot.properties.client_playlist_id;
|
const playlist_id = bot.properties.client_playlist_id;
|
||||||
client.permissions.requestPlaylistPermissions(playlist_id).then(result => {
|
client.permissions.requestPlaylistPermissions(playlist_id).then(result => {
|
||||||
const permissions = {};
|
const permissions = {};
|
||||||
for(const permission of result)
|
for (const permission of result)
|
||||||
if(permission.hasValue())
|
if (permission.hasValue())
|
||||||
permissions[permission.type.name] = permission.value;
|
permissions[permission.type.name] = permission.value;
|
||||||
event_registry.fire("general_permissions", {
|
event_registry.fire("general_permissions", {
|
||||||
status: "success",
|
status: "success",
|
||||||
|
@ -234,8 +233,8 @@ function permission_controller(event_registry: Registry<modal.music_manage>, bot
|
||||||
const client_id = event.client_database_id;
|
const client_id = event.client_database_id;
|
||||||
client.permissions.requestPlaylistClientPermissions(playlist_id, client_id).then(result => {
|
client.permissions.requestPlaylistClientPermissions(playlist_id, client_id).then(result => {
|
||||||
const permissions = {};
|
const permissions = {};
|
||||||
for(const permission of result)
|
for (const permission of result)
|
||||||
if(permission.hasValue())
|
if (permission.hasValue())
|
||||||
permissions[permission.type.name] = permission.value;
|
permissions[permission.type.name] = permission.value;
|
||||||
event_registry.fire("client_permissions", {
|
event_registry.fire("client_permissions", {
|
||||||
status: "success",
|
status: "success",
|
||||||
|
@ -307,24 +306,25 @@ function permission_controller(event_registry: Registry<modal.music_manage>, bot
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("search_client", event => {
|
event_registry.on("search_client", event => {
|
||||||
if(!event.text) return;
|
if (!event.text) return;
|
||||||
|
|
||||||
const text = event.text;
|
const text = event.text;
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
let is_uuid = false;
|
let is_uuid = false;
|
||||||
try {
|
try {
|
||||||
is_uuid = atob(text).length === 32;
|
is_uuid = atob(text).length === 32;
|
||||||
} catch(e) {}
|
} catch (e) {
|
||||||
if(is_uuid) {
|
}
|
||||||
|
if (is_uuid) {
|
||||||
return client.serverConnection.command_helper.getInfoFromUniqueId(text);
|
return client.serverConnection.command_helper.getInfoFromUniqueId(text);
|
||||||
} else if(text.match(/^[0-9]{1,7}$/) && !isNaN(parseInt(text))) {
|
} else if (text.match(/^[0-9]{1,7}$/) && !isNaN(parseInt(text))) {
|
||||||
return client.serverConnection.command_helper.getInfoFromClientDatabaseId(parseInt(text));
|
return client.serverConnection.command_helper.getInfoFromClientDatabaseId(parseInt(text));
|
||||||
} else {
|
} else {
|
||||||
//TODO: Database name lookup?
|
//TODO: Database name lookup?
|
||||||
return Promise.reject("no results");
|
return Promise.reject("no results");
|
||||||
}
|
}
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
if(result.length) {
|
if (result.length) {
|
||||||
const client = result[0];
|
const client = result[0];
|
||||||
event_registry.fire("search_client_result", {
|
event_registry.fire("search_client_result", {
|
||||||
status: "success",
|
status: "success",
|
||||||
|
@ -351,11 +351,11 @@ function permission_controller(event_registry: Registry<modal.music_manage>, bot
|
||||||
event_registry.on("query_group_permissions", event => {
|
event_registry.on("query_group_permissions", event => {
|
||||||
client.permissions.find_permission(event.permission_name).then(result => {
|
client.permissions.find_permission(event.permission_name).then(result => {
|
||||||
let groups = [];
|
let groups = [];
|
||||||
for(const e of result) {
|
for (const e of result) {
|
||||||
if(e.type !== "server_group") continue;
|
if (e.type !== "server_group") continue;
|
||||||
|
|
||||||
const group = client.groups.findServerGroup((e as ServerGroup).group_id);
|
const group = client.groups.findServerGroup((e as ServerGroup).group_id);
|
||||||
if(!group) continue;
|
if (!group) continue;
|
||||||
|
|
||||||
groups.push({
|
groups.push({
|
||||||
name: group.name,
|
name: group.name,
|
||||||
|
@ -511,7 +511,7 @@ function dummy_controller(event_registry: Registry<modal.music_manage>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function build_modal(event_registry: Registry<modal.music_manage>) : JQuery<HTMLElement> {
|
function build_modal(event_registry: Registry<modal.music_manage>): JQuery<HTMLElement> {
|
||||||
const tag = $("#tmpl_music_manage").renderTag();
|
const tag = $("#tmpl_music_manage").renderTag();
|
||||||
|
|
||||||
const container_settings = tag.find(".body > .category-settings");
|
const container_settings = tag.find(".body > .category-settings");
|
||||||
|
@ -532,8 +532,8 @@ function build_modal(event_registry: Registry<modal.music_manage>) : JQuery<HTML
|
||||||
container_permissions.toggleClass("hidden", data.container !== "permissions");
|
container_permissions.toggleClass("hidden", data.container !== "permissions");
|
||||||
});
|
});
|
||||||
category_permissions.on('click', event => {
|
category_permissions.on('click', event => {
|
||||||
if(shown_container === "permissions") return;
|
if (shown_container === "permissions") return;
|
||||||
event_registry.fire("show_container", { container: "permissions" });
|
event_registry.fire("show_container", {container: "permissions"});
|
||||||
});
|
});
|
||||||
|
|
||||||
const category_settings = header.find(".category-settings");
|
const category_settings = header.find(".category-settings");
|
||||||
|
@ -542,8 +542,8 @@ function build_modal(event_registry: Registry<modal.music_manage>) : JQuery<HTML
|
||||||
container_settings.toggleClass("hidden", data.container !== "settings");
|
container_settings.toggleClass("hidden", data.container !== "settings");
|
||||||
});
|
});
|
||||||
category_settings.on('click', event => {
|
category_settings.on('click', event => {
|
||||||
if(shown_container === "settings") return;
|
if (shown_container === "settings") return;
|
||||||
event_registry.fire("show_container", { container: "settings" });
|
event_registry.fire("show_container", {container: "settings"});
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("show_container", data => shown_container = data.container);
|
event_registry.on("show_container", data => shown_container = data.container);
|
||||||
|
@ -554,13 +554,13 @@ function build_modal(event_registry: Registry<modal.music_manage>) : JQuery<HTML
|
||||||
const input = event.target as HTMLInputElement;
|
const input = event.target as HTMLInputElement;
|
||||||
const max = parseInt(input.getAttribute("maxlength"));
|
const max = parseInt(input.getAttribute("maxlength"));
|
||||||
const text = input.value;
|
const text = input.value;
|
||||||
if(!isNaN(max) && text && text.length > max)
|
if (!isNaN(max) && text && text.length > max)
|
||||||
//input.value = text.substr(text.length - max);
|
//input.value = text.substr(text.length - max);
|
||||||
input.value = text.substr(0, max);
|
input.value = text.substr(0, max);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* initialize */
|
/* initialize */
|
||||||
event_registry.fire("show_container", { container: "settings" });
|
event_registry.fire("show_container", {container: "settings"});
|
||||||
return tag.children();
|
return tag.children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,7 +587,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("bot_status", event => {
|
event_registry.on("bot_status", event => {
|
||||||
if(event.status === "error")
|
if (event.status === "error")
|
||||||
input
|
input
|
||||||
.prop("disabled", true)
|
.prop("disabled", true)
|
||||||
.val(null)
|
.val(null)
|
||||||
|
@ -600,9 +600,9 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_bot_status_result", event => {
|
event_registry.on("set_bot_status_result", event => {
|
||||||
if(event.key !== "name") return;
|
if (event.key !== "name") return;
|
||||||
|
|
||||||
if(event.status !== "success")
|
if (event.status !== "success")
|
||||||
show_change_error(tr("Failed to set bot name"), event.error_msg || tr("timeout"));
|
show_change_error(tr("Failed to set bot name"), event.error_msg || tr("timeout"));
|
||||||
else
|
else
|
||||||
last_value = event.value;
|
last_value = event.value;
|
||||||
|
@ -616,8 +616,8 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
input.on("keyup", event => event.key === "Enter" && input.trigger("focusout"));
|
input.on("keyup", event => event.key === "Enter" && input.trigger("focusout"));
|
||||||
input.on("focusout", event => {
|
input.on("focusout", event => {
|
||||||
const value = input.val() as string;
|
const value = input.val() as string;
|
||||||
if(value === last_value) return;
|
if (value === last_value) return;
|
||||||
if(!value) {
|
if (!value) {
|
||||||
input.val(last_value);
|
input.val(last_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -643,8 +643,8 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
const update_country_code = input => {
|
const update_country_code = input => {
|
||||||
input = input || fallback_country || "ts";
|
input = input || fallback_country || "ts";
|
||||||
flag.each((_, e) => {
|
flag.each((_, e) => {
|
||||||
for(const [index, klass] of e.classList.entries())
|
for (const [index, klass] of e.classList.entries())
|
||||||
if(klass.startsWith("flag-"))
|
if (klass.startsWith("flag-"))
|
||||||
e.classList.remove(klass);
|
e.classList.remove(klass);
|
||||||
});
|
});
|
||||||
flag.addClass("flag-" + input.toLowerCase());
|
flag.addClass("flag-" + input.toLowerCase());
|
||||||
|
@ -661,7 +661,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("bot_status", event => {
|
event_registry.on("bot_status", event => {
|
||||||
if(event.status === "error")
|
if (event.status === "error")
|
||||||
input
|
input
|
||||||
.prop("disabled", true)
|
.prop("disabled", true)
|
||||||
.val(null)
|
.val(null)
|
||||||
|
@ -677,9 +677,9 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_bot_status_result", event => {
|
event_registry.on("set_bot_status_result", event => {
|
||||||
if(event.key !== "country_code") return;
|
if (event.key !== "country_code") return;
|
||||||
|
|
||||||
if(event.status !== "success")
|
if (event.status !== "success")
|
||||||
show_change_error(tr("Failed to set bots country"), event.error_msg || tr("timeout"));
|
show_change_error(tr("Failed to set bots country"), event.error_msg || tr("timeout"));
|
||||||
else
|
else
|
||||||
last_value = event.value;
|
last_value = event.value;
|
||||||
|
@ -699,8 +699,8 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
input.on("keyup", event => event.key === "Enter" && input.trigger("focusout"));
|
input.on("keyup", event => event.key === "Enter" && input.trigger("focusout"));
|
||||||
input.on("focusout", event => {
|
input.on("focusout", event => {
|
||||||
const value = input.val() as string;
|
const value = input.val() as string;
|
||||||
if(value === last_value) return;
|
if (value === last_value) return;
|
||||||
if(value && value.length != 2) {
|
if (value && value.length != 2) {
|
||||||
input.firstParent(".input-boxed").addClass("is-invalid");
|
input.firstParent(".input-boxed").addClass("is-invalid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -734,7 +734,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("bot_status", event => {
|
event_registry.on("bot_status", event => {
|
||||||
if(event.status === "error") {
|
if (event.status === "error") {
|
||||||
label.addClass("disabled");
|
label.addClass("disabled");
|
||||||
input
|
input
|
||||||
.prop("checked", false)
|
.prop("checked", false)
|
||||||
|
@ -748,9 +748,9 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_bot_status_result", event => {
|
event_registry.on("set_bot_status_result", event => {
|
||||||
if(event.key !== "channel_commander") return;
|
if (event.key !== "channel_commander") return;
|
||||||
|
|
||||||
if(event.status !== "success")
|
if (event.status !== "success")
|
||||||
show_change_error(tr("Failed to change channel commander state"), event.error_msg || tr("timeout"));
|
show_change_error(tr("Failed to change channel commander state"), event.error_msg || tr("timeout"));
|
||||||
else
|
else
|
||||||
last_value = event.value;
|
last_value = event.value;
|
||||||
|
@ -788,7 +788,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("bot_status", event => {
|
event_registry.on("bot_status", event => {
|
||||||
if(event.status === "error") {
|
if (event.status === "error") {
|
||||||
label.addClass("disabled");
|
label.addClass("disabled");
|
||||||
input
|
input
|
||||||
.prop("checked", false)
|
.prop("checked", false)
|
||||||
|
@ -802,9 +802,9 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_bot_status_result", event => {
|
event_registry.on("set_bot_status_result", event => {
|
||||||
if(event.key !== "priority_speaker") return;
|
if (event.key !== "priority_speaker") return;
|
||||||
|
|
||||||
if(event.status !== "success")
|
if (event.status !== "success")
|
||||||
show_change_error(tr("Failed to change priority speaker state"), event.error_msg || tr("timeout"));
|
show_change_error(tr("Failed to change priority speaker state"), event.error_msg || tr("timeout"));
|
||||||
else
|
else
|
||||||
last_value = event.value;
|
last_value = event.value;
|
||||||
|
@ -842,7 +842,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
|
|
||||||
/* set status timeout */
|
/* set status timeout */
|
||||||
{
|
{
|
||||||
let timeouts: {[key: string]:any} = {};
|
let timeouts: { [key: string]: any } = {};
|
||||||
event_registry.on("set_bot_status", event => {
|
event_registry.on("set_bot_status", event => {
|
||||||
clearTimeout(timeouts[event.key]);
|
clearTimeout(timeouts[event.key]);
|
||||||
timeouts[event.key] = setTimeout(() => {
|
timeouts[event.key] = setTimeout(() => {
|
||||||
|
@ -870,11 +870,11 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
let last_value = undefined;
|
let last_value = undefined;
|
||||||
|
|
||||||
const update_value = text => {
|
const update_value = text => {
|
||||||
if(text) {
|
if (text) {
|
||||||
input.prop("disabled", true).addClass("disabled");
|
input.prop("disabled", true).addClass("disabled");
|
||||||
input.val("-1");
|
input.val("-1");
|
||||||
input.find("option[value=-1]").text(text);
|
input.find("option[value=-1]").text(text);
|
||||||
} else if(last_value >= 0 && last_value <= 3) {
|
} else if (last_value >= 0 && last_value <= 3) {
|
||||||
input
|
input
|
||||||
.prop("disabled", false)
|
.prop("disabled", false)
|
||||||
.removeClass("disabled");
|
.removeClass("disabled");
|
||||||
|
@ -890,7 +890,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("playlist_status", event => {
|
event_registry.on("playlist_status", event => {
|
||||||
if(event.status === "error") {
|
if (event.status === "error") {
|
||||||
update_value(event.error_msg || tr("error while loading"));
|
update_value(event.error_msg || tr("error while loading"));
|
||||||
} else {
|
} else {
|
||||||
last_value = event.data.replay_mode;
|
last_value = event.data.replay_mode;
|
||||||
|
@ -899,9 +899,9 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_playlist_status_result", event => {
|
event_registry.on("set_playlist_status_result", event => {
|
||||||
if(event.key !== "replay_mode") return;
|
if (event.key !== "replay_mode") return;
|
||||||
|
|
||||||
if(event.status !== "success")
|
if (event.status !== "success")
|
||||||
show_change_error(tr("Failed to change replay mode"), event.error_msg || tr("timeout"));
|
show_change_error(tr("Failed to change replay mode"), event.error_msg || tr("timeout"));
|
||||||
else
|
else
|
||||||
last_value = event.value;
|
last_value = event.value;
|
||||||
|
@ -912,7 +912,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
input.on("change", event => {
|
input.on("change", event => {
|
||||||
const value = parseInt(input.val() as string);
|
const value = parseInt(input.val() as string);
|
||||||
console.log(value);
|
console.log(value);
|
||||||
if(isNaN(value)) return;
|
if (isNaN(value)) return;
|
||||||
|
|
||||||
update_value(tr("applying..."));
|
update_value(tr("applying..."));
|
||||||
event_registry.fire("set_playlist_status", {
|
event_registry.fire("set_playlist_status", {
|
||||||
|
@ -937,7 +937,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("playlist_status", event => {
|
event_registry.on("playlist_status", event => {
|
||||||
if(event.status === "error")
|
if (event.status === "error")
|
||||||
input
|
input
|
||||||
.prop("disabled", true)
|
.prop("disabled", true)
|
||||||
.val(null)
|
.val(null)
|
||||||
|
@ -952,9 +952,9 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_playlist_status_result", event => {
|
event_registry.on("set_playlist_status_result", event => {
|
||||||
if(event.key !== "max_size") return;
|
if (event.key !== "max_size") return;
|
||||||
|
|
||||||
if(event.status !== "success")
|
if (event.status !== "success")
|
||||||
show_change_error(tr("Failed to change max playlist size"), event.error_msg || tr("timeout"));
|
show_change_error(tr("Failed to change max playlist size"), event.error_msg || tr("timeout"));
|
||||||
else
|
else
|
||||||
last_value = event.value;
|
last_value = event.value;
|
||||||
|
@ -970,12 +970,12 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
input.on("keyup", event => event.key === "Enter" && input.trigger("focusout"));
|
input.on("keyup", event => event.key === "Enter" && input.trigger("focusout"));
|
||||||
input.on("focusout", event => {
|
input.on("focusout", event => {
|
||||||
const value = input.val() as string;
|
const value = input.val() as string;
|
||||||
if(value === last_value) return;
|
if (value === last_value) return;
|
||||||
if(value === "") {
|
if (value === "") {
|
||||||
input.val(last_value);
|
input.val(last_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(isNaN(parseInt(value))) {
|
if (isNaN(parseInt(value))) {
|
||||||
input.parentsUntil(".input-boxed").addClass("is-invalid");
|
input.parentsUntil(".input-boxed").addClass("is-invalid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1010,7 +1010,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("playlist_status", event => {
|
event_registry.on("playlist_status", event => {
|
||||||
if(event.status === "error") {
|
if (event.status === "error") {
|
||||||
label.addClass("disabled");
|
label.addClass("disabled");
|
||||||
input
|
input
|
||||||
.prop("checked", false)
|
.prop("checked", false)
|
||||||
|
@ -1024,9 +1024,9 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_playlist_status_result", event => {
|
event_registry.on("set_playlist_status_result", event => {
|
||||||
if(event.key !== "delete_played") return;
|
if (event.key !== "delete_played") return;
|
||||||
|
|
||||||
if(event.status !== "success")
|
if (event.status !== "success")
|
||||||
show_change_error(tr("Failed to change delete state"), event.error_msg || tr("timeout"));
|
show_change_error(tr("Failed to change delete state"), event.error_msg || tr("timeout"));
|
||||||
else
|
else
|
||||||
last_value = event.value;
|
last_value = event.value;
|
||||||
|
@ -1064,7 +1064,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("playlist_status", event => {
|
event_registry.on("playlist_status", event => {
|
||||||
if(event.status === "error") {
|
if (event.status === "error") {
|
||||||
label.addClass("disabled");
|
label.addClass("disabled");
|
||||||
input
|
input
|
||||||
.prop("checked", false)
|
.prop("checked", false)
|
||||||
|
@ -1078,9 +1078,9 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_playlist_status_result", event => {
|
event_registry.on("set_playlist_status_result", event => {
|
||||||
if(event.key !== "notify_song_change") return;
|
if (event.key !== "notify_song_change") return;
|
||||||
|
|
||||||
if(event.status !== "success")
|
if (event.status !== "success")
|
||||||
show_change_error(tr("Failed to change notify state"), event.error_msg || tr("timeout"));
|
show_change_error(tr("Failed to change notify state"), event.error_msg || tr("timeout"));
|
||||||
else
|
else
|
||||||
last_value = event.value;
|
last_value = event.value;
|
||||||
|
@ -1118,7 +1118,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
|
|
||||||
/* set status timeout */
|
/* set status timeout */
|
||||||
{
|
{
|
||||||
let timeouts: {[key: string]:any} = {};
|
let timeouts: { [key: string]: any } = {};
|
||||||
event_registry.on("set_playlist_status", event => {
|
event_registry.on("set_playlist_status", event => {
|
||||||
clearTimeout(timeouts[event.key]);
|
clearTimeout(timeouts[event.key]);
|
||||||
timeouts[event.key] = setTimeout(() => {
|
timeouts[event.key] = setTimeout(() => {
|
||||||
|
@ -1162,7 +1162,7 @@ function build_settings_container(event_registry: Registry<modal.music_manage>,
|
||||||
{
|
{
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
event_registry.on("show_container", event => {
|
event_registry.on("show_container", event => {
|
||||||
if(event.container !== "settings" || initialized) return;
|
if (event.container !== "settings" || initialized) return;
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
event_registry.fire("query_bot_status");
|
event_registry.fire("query_bot_status");
|
||||||
|
@ -1203,15 +1203,15 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
let last_query;
|
let last_query;
|
||||||
input_search.on('keyup', event => {
|
input_search.on('keyup', event => {
|
||||||
const text = input_search.val() as string;
|
const text = input_search.val() as string;
|
||||||
if(text === last_query) return;
|
if (text === last_query) return;
|
||||||
|
|
||||||
if(text)
|
if (text)
|
||||||
event_registry.fire("filter_client_list", { filter: text });
|
event_registry.fire("filter_client_list", {filter: text});
|
||||||
else
|
else
|
||||||
event_registry.fire("filter_client_list", { filter: undefined });
|
event_registry.fire("filter_client_list", {filter: undefined});
|
||||||
|
|
||||||
input_search.toggleClass("is-invalid", !list_shown && text === last_query);
|
input_search.toggleClass("is-invalid", !list_shown && text === last_query);
|
||||||
if(!list_shown) {
|
if (!list_shown) {
|
||||||
button_search.prop("disabled", !text || !!search_timeout);
|
button_search.prop("disabled", !text || !!search_timeout);
|
||||||
} else {
|
} else {
|
||||||
last_query = text;
|
last_query = text;
|
||||||
|
@ -1219,7 +1219,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
});
|
});
|
||||||
|
|
||||||
input_search.on('keydown', event => {
|
input_search.on('keydown', event => {
|
||||||
if(event.key === "Enter" && !list_shown && !button_search.prop("disabled"))
|
if (event.key === "Enter" && !list_shown && !button_search.prop("disabled"))
|
||||||
button_search.trigger("click");
|
button_search.trigger("click");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1252,10 +1252,10 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
search_timeout = 0;
|
search_timeout = 0;
|
||||||
|
|
||||||
button_search.prop("disabled", !input_search.val());
|
button_search.prop("disabled", !input_search.val());
|
||||||
if(event.status === "timeout") {
|
if (event.status === "timeout") {
|
||||||
createErrorModal(tr("Client search failed"), tr("Failed to perform client search.<br>Search resulted in a timeout.")).open();
|
createErrorModal(tr("Client search failed"), tr("Failed to perform client search.<br>Search resulted in a timeout.")).open();
|
||||||
return;
|
return;
|
||||||
} else if(event.status === "error" || event.status === "empty") {
|
} else if (event.status === "error" || event.status === "empty") {
|
||||||
//TODO: Display the error somehow?
|
//TODO: Display the error somehow?
|
||||||
input_search.addClass("is-invalid");
|
input_search.addClass("is-invalid");
|
||||||
return;
|
return;
|
||||||
|
@ -1280,18 +1280,18 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
event_registry.on("special_client_list", data => {
|
event_registry.on("special_client_list", data => {
|
||||||
button_refresh.prop("disabled", false);
|
button_refresh.prop("disabled", false);
|
||||||
container.find(".overlay").addClass("hidden");
|
container.find(".overlay").addClass("hidden");
|
||||||
if(data.status === "error-permission") {
|
if (data.status === "error-permission") {
|
||||||
const overlay = container.find(".overlay-query-error-permissions");
|
const overlay = container.find(".overlay-query-error-permissions");
|
||||||
overlay.find("a").text(tr("Insufficient permissions"));
|
overlay.find("a").text(tr("Insufficient permissions"));
|
||||||
overlay.removeClass("hidden");
|
overlay.removeClass("hidden");
|
||||||
} else if(data.status === "success") {
|
} else if (data.status === "success") {
|
||||||
container_entries.find(".client").remove(); /* clear */
|
container_entries.find(".client").remove(); /* clear */
|
||||||
|
|
||||||
if(!data.clients.length) {
|
if (!data.clients.length) {
|
||||||
const overlay = container.find(".overlay-empty-list");
|
const overlay = container.find(".overlay-empty-list");
|
||||||
overlay.removeClass("hidden");
|
overlay.removeClass("hidden");
|
||||||
} else {
|
} else {
|
||||||
for(const client of data.clients) {
|
for (const client of data.clients) {
|
||||||
const tag = $.spawn("div").addClass("client").append(
|
const tag = $.spawn("div").addClass("client").append(
|
||||||
htmltags.generate_client_object({
|
htmltags.generate_client_object({
|
||||||
add_braces: false,
|
add_braces: false,
|
||||||
|
@ -1301,7 +1301,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
client_unique_id: client.unique_id
|
client_unique_id: client.unique_id
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
tag.on('dblclick', event => event_registry.fire("special_client_set", { client: client }));
|
tag.on('dblclick', event => event_registry.fire("special_client_set", {client: client}));
|
||||||
tag.attr("x-filter", client.database_id + "_" + client.name + "_" + client.unique_id);
|
tag.attr("x-filter", client.database_id + "_" + client.name + "_" + client.unique_id);
|
||||||
container_entries.append(tag);
|
container_entries.append(tag);
|
||||||
}
|
}
|
||||||
|
@ -1339,7 +1339,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
{
|
{
|
||||||
let shown;
|
let shown;
|
||||||
event_registry.on('show_client_list', event => {
|
event_registry.on('show_client_list', event => {
|
||||||
if(shown) return;
|
if (shown) return;
|
||||||
shown = true;
|
shown = true;
|
||||||
|
|
||||||
event_registry.fire("query_special_clients");
|
event_registry.fire("query_special_clients");
|
||||||
|
@ -1355,7 +1355,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
let shown = 0, hidden = 0;
|
let shown = 0, hidden = 0;
|
||||||
container_entries.find(".client").each(function () {
|
container_entries.find(".client").each(function () {
|
||||||
const text = this.getAttribute("x-filter");
|
const text = this.getAttribute("x-filter");
|
||||||
if(!filter || text.toLowerCase().indexOf(filter) != -1) {
|
if (!filter || text.toLowerCase().indexOf(filter) != -1) {
|
||||||
this.classList.remove("hidden");
|
this.classList.remove("hidden");
|
||||||
shown++;
|
shown++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1363,7 +1363,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
hidden++;
|
hidden++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if(shown == 0 && hidden == 0) return;
|
if (shown == 0 && hidden == 0) return;
|
||||||
overlay.toggleClass("hidden", shown != 0);
|
overlay.toggleClass("hidden", shown != 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1386,7 +1386,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
const container = tag.find(".table-head .column-client-specific .client-info");
|
const container = tag.find(".table-head .column-client-specific .client-info");
|
||||||
|
|
||||||
container.find(".button-client-deselect").on("click", event => {
|
container.find(".button-client-deselect").on("click", event => {
|
||||||
event_registry.fire("special_client_set", { client: undefined });
|
event_registry.fire("special_client_set", {client: undefined});
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("special_client_set", event => {
|
event_registry.on("special_client_set", event => {
|
||||||
|
@ -1394,7 +1394,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
|
|
||||||
const client_container = container.find(".container-selected-client");
|
const client_container = container.find(".container-selected-client");
|
||||||
client_container.find(".htmltag-client").remove();
|
client_container.find(".htmltag-client").remove();
|
||||||
if(event.client) {
|
if (event.client) {
|
||||||
client_container.append(htmltags.generate_client_object({
|
client_container.append(htmltags.generate_client_object({
|
||||||
client_unique_id: event.client.unique_id,
|
client_unique_id: event.client.unique_id,
|
||||||
client_name: event.client.name,
|
client_name: event.client.name,
|
||||||
|
@ -1432,7 +1432,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
const elem = $(_e) as JQuery<HTMLDivElement>;
|
const elem = $(_e) as JQuery<HTMLDivElement>;
|
||||||
|
|
||||||
const permission_name = elem.attr("x-permission");
|
const permission_name = elem.attr("x-permission");
|
||||||
if(!permission_name) return;
|
if (!permission_name) return;
|
||||||
|
|
||||||
const input = elem.find("input");
|
const input = elem.find("input");
|
||||||
input.attr("maxlength", 6);
|
input.attr("maxlength", 6);
|
||||||
|
@ -1446,9 +1446,9 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
|
|
||||||
event_registry.on("general_permissions", event => {
|
event_registry.on("general_permissions", event => {
|
||||||
input.prop("disabled", true).val(null);
|
input.prop("disabled", true).val(null);
|
||||||
if(event.status === "timeout") {
|
if (event.status === "timeout") {
|
||||||
input.attr("placeholder", tr("load timeout"));
|
input.attr("placeholder", tr("load timeout"));
|
||||||
} else if(event.status === "success") {
|
} else if (event.status === "success") {
|
||||||
input.prop("disabled", false); //TODO: Check permissions?
|
input.prop("disabled", false); //TODO: Check permissions?
|
||||||
input.attr("placeholder", null);
|
input.attr("placeholder", null);
|
||||||
const value = event.permissions ? event.permissions[permission_name] || 0 : 0;
|
const value = event.permissions ? event.permissions[permission_name] || 0 : 0;
|
||||||
|
@ -1460,24 +1460,24 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_general_permission_result", event => {
|
event_registry.on("set_general_permission_result", event => {
|
||||||
if(event.key !== permission_name) return;
|
if (event.key !== permission_name) return;
|
||||||
|
|
||||||
input.prop("disabled", false); //TODO: Check permissions?
|
input.prop("disabled", false); //TODO: Check permissions?
|
||||||
input.attr("placeholder", null);
|
input.attr("placeholder", null);
|
||||||
if(event.status === "success") {
|
if (event.status === "success") {
|
||||||
input.val(event.value);
|
input.val(event.value);
|
||||||
last_sync_value = event.value;
|
last_sync_value = event.value;
|
||||||
} else if(event.status === "error") {
|
} else if (event.status === "error") {
|
||||||
if(typeof last_sync_value === "number") input.val(last_sync_value);
|
if (typeof last_sync_value === "number") input.val(last_sync_value);
|
||||||
createErrorModal(tr("Failed to change permission"), tra("Failed to change permission:{:br:}{}", event.error_msg)).open();
|
createErrorModal(tr("Failed to change permission"), tra("Failed to change permission:{:br:}{}", event.error_msg)).open();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
input.on("focusout", event => {
|
input.on("focusout", event => {
|
||||||
if(input.prop("disabled")) return;
|
if (input.prop("disabled")) return;
|
||||||
|
|
||||||
const value = parseInt(input.val() as string);
|
const value = parseInt(input.val() as string);
|
||||||
if(value === last_sync_value) return;
|
if (value === last_sync_value) return;
|
||||||
|
|
||||||
input.prop("disabled", true).val(null);
|
input.prop("disabled", true).val(null);
|
||||||
input.attr("placeholder", tr("applying..."));
|
input.attr("placeholder", tr("applying..."));
|
||||||
|
@ -1496,10 +1496,10 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
const elem = $(_e) as JQuery<HTMLDivElement>;
|
const elem = $(_e) as JQuery<HTMLDivElement>;
|
||||||
|
|
||||||
const permission_name = elem.attr("x-permission");
|
const permission_name = elem.attr("x-permission");
|
||||||
if(!permission_name) return;
|
if (!permission_name) return;
|
||||||
|
|
||||||
const required_power = needed_power_map[permission_name];
|
const required_power = needed_power_map[permission_name];
|
||||||
if(!required_power) return;
|
if (!required_power) return;
|
||||||
|
|
||||||
let last_sync_value = undefined;
|
let last_sync_value = undefined;
|
||||||
let current_tag: JQuery;
|
let current_tag: JQuery;
|
||||||
|
@ -1516,14 +1516,14 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
};
|
};
|
||||||
|
|
||||||
event_registry.on("general_permissions", event => {
|
event_registry.on("general_permissions", event => {
|
||||||
if(event.status === "success")
|
if (event.status === "success")
|
||||||
last_sync_value = event.permissions ? event.permissions[permission_name] || 0 : 0;
|
last_sync_value = event.permissions ? event.permissions[permission_name] || 0 : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("set_general_permission_result", event => {
|
event_registry.on("set_general_permission_result", event => {
|
||||||
if(event.key !== permission_name) return;
|
if (event.key !== permission_name) return;
|
||||||
|
|
||||||
if(event.status === "success")
|
if (event.status === "success")
|
||||||
last_sync_value = event.value;
|
last_sync_value = event.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1532,26 +1532,26 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
});
|
});
|
||||||
|
|
||||||
const show_query_result = () => {
|
const show_query_result = () => {
|
||||||
if(!current_tag) return;
|
if (!current_tag) return;
|
||||||
|
|
||||||
const container_groups = current_tag.find(".container-groups");
|
const container_groups = current_tag.find(".container-groups");
|
||||||
container_groups.children().remove();
|
container_groups.children().remove();
|
||||||
current_tag.find(".container-status").addClass("hidden");
|
current_tag.find(".container-status").addClass("hidden");
|
||||||
|
|
||||||
if(loading) {
|
if (loading) {
|
||||||
current_tag.find(".status-loading").removeClass("hidden");
|
current_tag.find(".status-loading").removeClass("hidden");
|
||||||
} else if(!query_result || query_result.status === "error") {
|
} else if (!query_result || query_result.status === "error") {
|
||||||
current_tag
|
current_tag
|
||||||
.find(".status-error").removeClass("hidden")
|
.find(".status-error").removeClass("hidden")
|
||||||
.text((query_result ? query_result.error_msg : "") || tr("failed to query data"));
|
.text((query_result ? query_result.error_msg : "") || tr("failed to query data"));
|
||||||
} else if(query_result.status === "timeout") {
|
} else if (query_result.status === "timeout") {
|
||||||
current_tag
|
current_tag
|
||||||
.find(".status-error").removeClass("hidden")
|
.find(".status-error").removeClass("hidden")
|
||||||
.text(tr("timeout while loading"));
|
.text(tr("timeout while loading"));
|
||||||
} else {
|
} else {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for(const group of (query_result.groups || [])) {
|
for (const group of (query_result.groups || [])) {
|
||||||
if(group.value !== -1 && group.value < last_sync_value) continue;
|
if (group.value !== -1 && group.value < last_sync_value) continue;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
container_groups.append($.spawn("div").addClass("group").text(
|
container_groups.append($.spawn("div").addClass("group").text(
|
||||||
|
@ -1559,7 +1559,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(count === 0) current_tag.find(".status-no-groups").removeClass("hidden");
|
if (count === 0) current_tag.find(".status-no-groups").removeClass("hidden");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1567,7 +1567,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
on_show(tag: JQuery<HTMLElement>) {
|
on_show(tag: JQuery<HTMLElement>) {
|
||||||
current_tag = tag;
|
current_tag = tag;
|
||||||
|
|
||||||
if(!query_result && !loading) {
|
if (!query_result && !loading) {
|
||||||
event_registry.fire("query_group_permissions", {
|
event_registry.fire("query_group_permissions", {
|
||||||
permission_name: required_power
|
permission_name: required_power
|
||||||
});
|
});
|
||||||
|
@ -1581,7 +1581,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on("group_permissions", event => {
|
event_registry.on("group_permissions", event => {
|
||||||
if(event.permission_name !== required_power) return;
|
if (event.permission_name !== required_power) return;
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
query_result = event;
|
query_result = event;
|
||||||
|
@ -1598,9 +1598,9 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
|
|
||||||
/* permission set timeout */
|
/* permission set timeout */
|
||||||
{
|
{
|
||||||
let permission_timers: {[key: string]:any} = {};
|
let permission_timers: { [key: string]: any } = {};
|
||||||
event_registry.on("set_general_permission", event => {
|
event_registry.on("set_general_permission", event => {
|
||||||
if(permission_timers[event.key])
|
if (permission_timers[event.key])
|
||||||
clearTimeout(permission_timers[event.key]);
|
clearTimeout(permission_timers[event.key]);
|
||||||
permission_timers[event.key] = setTimeout(() => {
|
permission_timers[event.key] = setTimeout(() => {
|
||||||
event_registry.fire("set_general_permission_result", {
|
event_registry.fire("set_general_permission_result", {
|
||||||
|
@ -1619,9 +1619,9 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
|
|
||||||
/* group query timeout */
|
/* group query timeout */
|
||||||
{
|
{
|
||||||
let timers: {[key: string]:any} = {};
|
let timers: { [key: string]: any } = {};
|
||||||
event_registry.on("query_group_permissions", event => {
|
event_registry.on("query_group_permissions", event => {
|
||||||
if(timers[event.permission_name])
|
if (timers[event.permission_name])
|
||||||
clearTimeout(timers[event.permission_name]);
|
clearTimeout(timers[event.permission_name]);
|
||||||
timers[event.permission_name] = setTimeout(() => {
|
timers[event.permission_name] = setTimeout(() => {
|
||||||
event_registry.fire("group_permissions", {
|
event_registry.fire("group_permissions", {
|
||||||
|
@ -1700,12 +1700,12 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
const container = tag.find(".column-client-specific");
|
const container = tag.find(".column-client-specific");
|
||||||
|
|
||||||
let client_database_id = 0;
|
let client_database_id = 0;
|
||||||
let needed_permissions: {[key: string]:number} = {};
|
let needed_permissions: { [key: string]: number } = {};
|
||||||
|
|
||||||
/* needed permissions updater */
|
/* needed permissions updater */
|
||||||
{
|
{
|
||||||
event_registry.on("general_permissions", event => {
|
event_registry.on("general_permissions", event => {
|
||||||
if(event.status !== "success") return;
|
if (event.status !== "success") return;
|
||||||
|
|
||||||
needed_permissions = event.permissions;
|
needed_permissions = event.permissions;
|
||||||
});
|
});
|
||||||
|
@ -1721,8 +1721,8 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
client_database_id = event.client ? event.client.database_id : 0;
|
client_database_id = event.client ? event.client.database_id : 0;
|
||||||
container.find(".client-permission").toggleClass("hidden", !event.client);
|
container.find(".client-permission").toggleClass("hidden", !event.client);
|
||||||
|
|
||||||
if(client_database_id)
|
if (client_database_id)
|
||||||
event_registry.fire("query_client_permissions", { client_database_id: client_database_id });
|
event_registry.fire("query_client_permissions", {client_database_id: client_database_id});
|
||||||
});
|
});
|
||||||
|
|
||||||
const enabled_class = "client-apply";
|
const enabled_class = "client-apply";
|
||||||
|
@ -1740,7 +1740,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
let last_sync_value = undefined;
|
let last_sync_value = undefined;
|
||||||
let hide_indicator = false;
|
let hide_indicator = false;
|
||||||
|
|
||||||
if(typeof permission_needed_name !== "string") {
|
if (typeof permission_needed_name !== "string") {
|
||||||
log.warn(LogCategory.GENERAL, tr("Missing permission needed mapping for %s"), permission_name);
|
log.warn(LogCategory.GENERAL, tr("Missing permission needed mapping for %s"), permission_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1759,15 +1759,15 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
});
|
});
|
||||||
event_registry.on("general_permissions", event => update_indicator());
|
event_registry.on("general_permissions", event => update_indicator());
|
||||||
event_registry.on("set_general_permission_result", event => {
|
event_registry.on("set_general_permission_result", event => {
|
||||||
if(event.key !== permission_needed_name) return;
|
if (event.key !== permission_needed_name) return;
|
||||||
if(event.status !== "success") return;
|
if (event.status !== "success") return;
|
||||||
|
|
||||||
update_indicator();
|
update_indicator();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* loading the permission */
|
/* loading the permission */
|
||||||
event_registry.on("query_client_permissions", event => {
|
event_registry.on("query_client_permissions", event => {
|
||||||
if(event.client_database_id !== client_database_id) return;
|
if (event.client_database_id !== client_database_id) return;
|
||||||
|
|
||||||
last_sync_value = undefined;
|
last_sync_value = undefined;
|
||||||
hide_indicator = true;
|
hide_indicator = true;
|
||||||
|
@ -1777,13 +1777,13 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
});
|
});
|
||||||
|
|
||||||
event_registry.on('client_permissions', event => {
|
event_registry.on('client_permissions', event => {
|
||||||
if(event.client_database_id !== client_database_id) return;
|
if (event.client_database_id !== client_database_id) return;
|
||||||
|
|
||||||
hide_indicator = false;
|
hide_indicator = false;
|
||||||
input.prop("disabled", true).val(null);
|
input.prop("disabled", true).val(null);
|
||||||
if(event.status === "timeout") {
|
if (event.status === "timeout") {
|
||||||
input.attr("placeholder", tr("load timeout"));
|
input.attr("placeholder", tr("load timeout"));
|
||||||
} else if(event.status === "success") {
|
} else if (event.status === "success") {
|
||||||
input.prop("disabled", false); //TODO: Check permissions?
|
input.prop("disabled", false); //TODO: Check permissions?
|
||||||
input.attr("placeholder", null);
|
input.attr("placeholder", null);
|
||||||
const value = event.permissions ? event.permissions[permission_name] || 0 : 0;
|
const value = event.permissions ? event.permissions[permission_name] || 0 : 0;
|
||||||
|
@ -1798,10 +1798,10 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
/* permission editing */
|
/* permission editing */
|
||||||
input.attr("maxlength", 6);
|
input.attr("maxlength", 6);
|
||||||
input.on("focusout", event => {
|
input.on("focusout", event => {
|
||||||
if(!client_database_id) return;
|
if (!client_database_id) return;
|
||||||
|
|
||||||
const value = parseInt(input.val() as string);
|
const value = parseInt(input.val() as string);
|
||||||
if(value === last_sync_value) return;
|
if (value === last_sync_value) return;
|
||||||
|
|
||||||
input.prop("disabled", true).val(null);
|
input.prop("disabled", true).val(null);
|
||||||
input.attr("placeholder", tr("applying..."));
|
input.attr("placeholder", tr("applying..."));
|
||||||
|
@ -1818,15 +1818,15 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
input.on("keyup", event => event.key === "Enter" && input.blur());
|
input.on("keyup", event => event.key === "Enter" && input.blur());
|
||||||
|
|
||||||
event_registry.on("set_client_permission_result", event => {
|
event_registry.on("set_client_permission_result", event => {
|
||||||
if(event.key !== permission_name) return;
|
if (event.key !== permission_name) return;
|
||||||
|
|
||||||
input.prop("disabled", false); //TODO: Check permissions?
|
input.prop("disabled", false); //TODO: Check permissions?
|
||||||
input.attr("placeholder", null);
|
input.attr("placeholder", null);
|
||||||
if(event.status === "success") {
|
if (event.status === "success") {
|
||||||
input.val(event.value);
|
input.val(event.value);
|
||||||
last_sync_value = event.value;
|
last_sync_value = event.value;
|
||||||
} else if(event.status === "error") {
|
} else if (event.status === "error") {
|
||||||
if(typeof last_sync_value === "number") input.val(last_sync_value);
|
if (typeof last_sync_value === "number") input.val(last_sync_value);
|
||||||
createErrorModal(tr("Failed to change permission"), tra("Failed to change permission:{:br:}{}", event.error_msg)).open();
|
createErrorModal(tr("Failed to change permission"), tra("Failed to change permission:{:br:}{}", event.error_msg)).open();
|
||||||
}
|
}
|
||||||
hide_indicator = false;
|
hide_indicator = false;
|
||||||
|
@ -1836,9 +1836,9 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
|
|
||||||
/* client permission query timeout */
|
/* client permission query timeout */
|
||||||
{
|
{
|
||||||
let timeout: {[key: number]: any} = {};
|
let timeout: { [key: number]: any } = {};
|
||||||
event_registry.on("query_client_permissions", event => {
|
event_registry.on("query_client_permissions", event => {
|
||||||
if(timeout[event.client_database_id])
|
if (timeout[event.client_database_id])
|
||||||
clearTimeout(timeout[event.client_database_id]);
|
clearTimeout(timeout[event.client_database_id]);
|
||||||
timeout[event.client_database_id] = setTimeout(() => {
|
timeout[event.client_database_id] = setTimeout(() => {
|
||||||
event_registry.fire("client_permissions", {
|
event_registry.fire("client_permissions", {
|
||||||
|
@ -1855,10 +1855,10 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
|
|
||||||
/* client permission set timeout */
|
/* client permission set timeout */
|
||||||
{
|
{
|
||||||
let timeout: {[key: string]: any} = {};
|
let timeout: { [key: string]: any } = {};
|
||||||
event_registry.on("set_client_permission", event => {
|
event_registry.on("set_client_permission", event => {
|
||||||
const key = event.client_database_id + "_" + event.key;
|
const key = event.client_database_id + "_" + event.key;
|
||||||
if(timeout[key])
|
if (timeout[key])
|
||||||
clearTimeout(timeout[key]);
|
clearTimeout(timeout[key]);
|
||||||
|
|
||||||
timeout[key] = setTimeout(() => {
|
timeout[key] = setTimeout(() => {
|
||||||
|
@ -1873,7 +1873,7 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
|
|
||||||
event_registry.on("set_client_permission_result", event => {
|
event_registry.on("set_client_permission_result", event => {
|
||||||
const key = event.client_database_id + "_" + event.key;
|
const key = event.client_database_id + "_" + event.key;
|
||||||
if(timeout[key]) {
|
if (timeout[key]) {
|
||||||
clearTimeout(timeout[key]);
|
clearTimeout(timeout[key]);
|
||||||
delete timeout[key];
|
delete timeout[key];
|
||||||
}
|
}
|
||||||
|
@ -1881,8 +1881,8 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
}
|
}
|
||||||
|
|
||||||
event_registry.on("refresh_permissions", event => {
|
event_registry.on("refresh_permissions", event => {
|
||||||
if(client_database_id)
|
if (client_database_id)
|
||||||
event_registry.fire("query_client_permissions", { client_database_id: client_database_id });
|
event_registry.fire("query_client_permissions", {client_database_id: client_database_id});
|
||||||
});
|
});
|
||||||
tooltip.initialize(container);
|
tooltip.initialize(container);
|
||||||
}
|
}
|
||||||
|
@ -1896,10 +1896,10 @@ function build_permission_container(event_registry: Registry<modal.music_manage>
|
||||||
{
|
{
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
event_registry.on("show_container", event => {
|
event_registry.on("show_container", event => {
|
||||||
if(event.container !== "permissions" || initialized) return;
|
if (event.container !== "permissions" || initialized) return;
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
event_registry.fire("special_client_set", { client: undefined });
|
event_registry.fire("special_client_set", {client: undefined});
|
||||||
event_registry.fire("query_general_permissions", {});
|
event_registry.fire("query_general_permissions", {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import {createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createModal, Modal} from "tc-shared/ui/elements/Modal";
|
||||||
import {tra} from "tc-shared/i18n/localize";
|
import {tra} from "tc-shared/i18n/localize";
|
||||||
import {Registry} from "tc-shared/events";
|
import {modal as emodal, Registry} from "tc-shared/events";
|
||||||
import {modal_settings} from "tc-shared/ui/modal/ModalSettings";
|
import {modal_settings} from "tc-shared/ui/modal/ModalSettings";
|
||||||
import {spawnYesNo} from "tc-shared/ui/modal/ModalYesNo";
|
import {spawnYesNo} from "tc-shared/ui/modal/ModalYesNo";
|
||||||
import {initialize_audio_microphone_controller, MicrophoneSettingsEvents} from "tc-shared/ui/modal/settings/Microphone";
|
import {initialize_audio_microphone_controller, MicrophoneSettingsEvents} from "tc-shared/ui/modal/settings/Microphone";
|
||||||
import {MicrophoneSettings} from "tc-shared/ui/modal/settings/MicrophoneRenderer";
|
import {MicrophoneSettings} from "tc-shared/ui/modal/settings/MicrophoneRenderer";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as ReactDOM from "react-dom";
|
import * as ReactDOM from "react-dom";
|
||||||
import { modal as emodal } from "tc-shared/events";
|
|
||||||
|
|
||||||
export interface EventModalNewcomer {
|
export interface EventModalNewcomer {
|
||||||
"show_step": {
|
"show_step": {
|
||||||
|
@ -25,25 +24,25 @@ export interface EventModalNewcomer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const next_step: {[key: string]:string} = {
|
const next_step: { [key: string]: string } = {
|
||||||
"welcome": "microphone",
|
"welcome": "microphone",
|
||||||
//"microphone": app.is_web() ? "identity" : "speaker", /* speaker setup only for the native client! */
|
//"microphone": app.is_web() ? "identity" : "speaker", /* speaker setup only for the native client! */
|
||||||
"microphone": "identity",
|
"microphone": "identity",
|
||||||
"speaker": "identity",
|
"speaker": "identity",
|
||||||
"identity": "finish"
|
"identity": "finish"
|
||||||
};
|
};
|
||||||
const last_step: {[key: string]:string} = (() => {
|
const last_step: { [key: string]: string } = (() => {
|
||||||
const result = {};
|
const result = {};
|
||||||
for(const key of Object.keys(next_step))
|
for (const key of Object.keys(next_step))
|
||||||
if(!result[next_step[key]])
|
if (!result[next_step[key]])
|
||||||
result[next_step[key]] = key;
|
result[next_step[key]] = key;
|
||||||
return result;
|
return result;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
export function openModalNewcomer() : Modal {
|
export function openModalNewcomer(): Modal {
|
||||||
let modal = createModal({
|
let modal = createModal({
|
||||||
header: tra("Welcome to the {}", __build.version === "web" ? "TeaSpeak - Web client" : "TeaSpeak - Client"),
|
header: tra("Welcome to the {}", __build.version === "web" ? "TeaSpeak - Web client" : "TeaSpeak - Client"),
|
||||||
body: () => $("#tmpl_newcomer").renderTag({
|
body: () => $("#tmpl_newcomer").renderTag({
|
||||||
is_web: __build.version === "web"
|
is_web: __build.version === "web"
|
||||||
}).children(),
|
}).children(),
|
||||||
footer: null,
|
footer: null,
|
||||||
|
@ -64,9 +63,9 @@ export function openModalNewcomer() : Modal {
|
||||||
initializeStepFinish(modal.htmlTag.find(".container-body .step.step-finish"), event_registry);
|
initializeStepFinish(modal.htmlTag.find(".container-body .step.step-finish"), event_registry);
|
||||||
|
|
||||||
event_registry.on("exit_guide", event => {
|
event_registry.on("exit_guide", event => {
|
||||||
if(event.ask_yesno) {
|
if (event.ask_yesno) {
|
||||||
spawnYesNo(tr("Are you sure?"), tr("Do you really want to skip the basic setup guide?"), result => {
|
spawnYesNo(tr("Are you sure?"), tr("Do you really want to skip the basic setup guide?"), result => {
|
||||||
if(result)
|
if (result)
|
||||||
event_registry.fire("exit_guide", {ask_yesno: false});
|
event_registry.fire("exit_guide", {ask_yesno: false});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,23 +100,23 @@ function initializeBasicFunctionality(tag: JQuery, event_registry: Registry<Even
|
||||||
let allowNextStep = true;
|
let allowNextStep = true;
|
||||||
|
|
||||||
button_last_step.on('click', () => {
|
button_last_step.on('click', () => {
|
||||||
if(last_step[current_step])
|
if (last_step[current_step])
|
||||||
event_registry.fire("show_step", { step: last_step[current_step] as any });
|
event_registry.fire("show_step", {step: last_step[current_step] as any});
|
||||||
else
|
else
|
||||||
event_registry.fire("exit_guide", {ask_yesno: true});
|
event_registry.fire("exit_guide", {ask_yesno: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
let current_step;
|
let current_step;
|
||||||
button_next_step.on('click', event => {
|
button_next_step.on('click', event => {
|
||||||
if(!allowNextStep) {
|
if (!allowNextStep) {
|
||||||
event_registry.fire("action-next-help");
|
event_registry.fire("action-next-help");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(next_step[current_step]) {
|
if (next_step[current_step]) {
|
||||||
event_registry.fire("show_step", { step: next_step[current_step] as any });
|
event_registry.fire("show_step", {step: next_step[current_step] as any});
|
||||||
} else {
|
} else {
|
||||||
event_registry.fire("exit_guide", { ask_yesno: false });
|
event_registry.fire("exit_guide", {ask_yesno: false});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -137,17 +136,17 @@ function initializeBasicFunctionality(tag: JQuery, event_registry: Registry<Even
|
||||||
|
|
||||||
function initializeStepWelcome(tag: JQuery, event_registry: Registry<EventModalNewcomer>) {
|
function initializeStepWelcome(tag: JQuery, event_registry: Registry<EventModalNewcomer>) {
|
||||||
event_registry.on("show_step", e => {
|
event_registry.on("show_step", e => {
|
||||||
if(e.step !== "welcome") return;
|
if (e.step !== "welcome") return;
|
||||||
|
|
||||||
event_registry.fire_async("step-status", { allowNextStep: true, allowPreviousStep: true });
|
event_registry.fire_async("step-status", {allowNextStep: true, allowPreviousStep: true});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializeStepFinish(tag: JQuery, event_registry: Registry<EventModalNewcomer>) {
|
function initializeStepFinish(tag: JQuery, event_registry: Registry<EventModalNewcomer>) {
|
||||||
event_registry.on("show_step", e => {
|
event_registry.on("show_step", e => {
|
||||||
if(e.step !== "finish") return;
|
if (e.step !== "finish") return;
|
||||||
|
|
||||||
event_registry.fire_async("step-status", {allowNextStep: true, allowPreviousStep: true });
|
event_registry.fire_async("step-status", {allowNextStep: true, allowPreviousStep: true});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,17 +154,20 @@ function initializeStepIdentity(tag: JQuery, event_registry: Registry<EventModal
|
||||||
const profile_events = new Registry<emodal.settings.profiles>();
|
const profile_events = new Registry<emodal.settings.profiles>();
|
||||||
profile_events.enableDebug("settings-identity");
|
profile_events.enableDebug("settings-identity");
|
||||||
modal_settings.initialize_identity_profiles_controller(profile_events);
|
modal_settings.initialize_identity_profiles_controller(profile_events);
|
||||||
modal_settings.initialize_identity_profiles_view(tag, profile_events, { forum_setuppable: false });
|
modal_settings.initialize_identity_profiles_view(tag, profile_events, {forum_setuppable: false});
|
||||||
|
|
||||||
let stepShown = false;
|
let stepShown = false;
|
||||||
let help_animation_done = false;
|
let help_animation_done = false;
|
||||||
const update_step_status = () => {
|
const update_step_status = () => {
|
||||||
event_registry.fire_async("step-status", { allowNextStep: help_animation_done, allowPreviousStep: help_animation_done });
|
event_registry.fire_async("step-status", {
|
||||||
|
allowNextStep: help_animation_done,
|
||||||
|
allowPreviousStep: help_animation_done
|
||||||
|
});
|
||||||
};
|
};
|
||||||
profile_events.on("query-profile-validity-result", event => stepShown && event.status === "success" && event.valid && update_step_status());
|
profile_events.on("query-profile-validity-result", event => stepShown && event.status === "success" && event.valid && update_step_status());
|
||||||
event_registry.on("show_step", e => {
|
event_registry.on("show_step", e => {
|
||||||
stepShown = e.step === "identity";
|
stepShown = e.step === "identity";
|
||||||
if(!stepShown) return;
|
if (!stepShown) return;
|
||||||
|
|
||||||
update_step_status();
|
update_step_status();
|
||||||
});
|
});
|
||||||
|
@ -187,7 +189,7 @@ function initializeStepIdentity(tag: JQuery, event_registry: Registry<EventModal
|
||||||
};
|
};
|
||||||
|
|
||||||
event_registry.on("show_step", event => {
|
event_registry.on("show_step", event => {
|
||||||
if(helpStep > 0 || event.step !== "identity") {
|
if (helpStep > 0 || event.step !== "identity") {
|
||||||
document.body.removeEventListener("mousedown", listenerClick);
|
document.body.removeEventListener("mousedown", listenerClick);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -323,12 +325,12 @@ function initializeStepIdentity(tag: JQuery, event_registry: Registry<EventModal
|
||||||
|
|
||||||
const listenerClick = () => event_registry.fire("action-next-help");
|
const listenerClick = () => event_registry.fire("action-next-help");
|
||||||
event_registry.on("action-next-help", () => {
|
event_registry.on("action-next-help", () => {
|
||||||
if(!stepShown) {
|
if (!stepShown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn = steps[helpStep++];
|
const fn = steps[helpStep++];
|
||||||
if(typeof fn === "function") {
|
if (typeof fn === "function") {
|
||||||
fn();
|
fn();
|
||||||
}
|
}
|
||||||
update_step_status();
|
update_step_status();
|
||||||
|
@ -342,21 +344,21 @@ function initializeStepMicrophone(tag: JQuery, event_registry: Registry<EventMod
|
||||||
let stepShown = false;
|
let stepShown = false;
|
||||||
|
|
||||||
const settingEvents = new Registry<MicrophoneSettingsEvents>();
|
const settingEvents = new Registry<MicrophoneSettingsEvents>();
|
||||||
settingEvents.on("query_help", () => settingEvents.fire_async("notify_highlight", { field: helpStep <= 2 ? ("hs-" + helpStep) as any : undefined }));
|
settingEvents.on("query_help", () => settingEvents.fire_async("notify_highlight", {field: helpStep <= 2 ? ("hs-" + helpStep) as any : undefined}));
|
||||||
settingEvents.on("action_help_click", () => {
|
settingEvents.on("action_help_click", () => {
|
||||||
if(!stepShown) {
|
if (!stepShown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
helpStep++;
|
helpStep++;
|
||||||
settingEvents.fire("query_help");
|
settingEvents.fire("query_help");
|
||||||
|
|
||||||
event_registry.fire_async("step-status", { allowNextStep: helpStep > 2, allowPreviousStep: helpStep > 2 })
|
event_registry.fire_async("step-status", {allowNextStep: helpStep > 2, allowPreviousStep: helpStep > 2})
|
||||||
});
|
});
|
||||||
event_registry.on("action-next-help", () => settingEvents.fire("action_help_click"));
|
event_registry.on("action-next-help", () => settingEvents.fire("action_help_click"));
|
||||||
|
|
||||||
initialize_audio_microphone_controller(settingEvents);
|
initialize_audio_microphone_controller(settingEvents);
|
||||||
ReactDOM.render(<MicrophoneSettings events={settingEvents} />, tag[0]);
|
ReactDOM.render(<MicrophoneSettings events={settingEvents}/>, tag[0]);
|
||||||
|
|
||||||
modal.close_listener.push(() => {
|
modal.close_listener.push(() => {
|
||||||
settingEvents.fire("notify_destroy");
|
settingEvents.fire("notify_destroy");
|
||||||
|
@ -366,10 +368,10 @@ function initializeStepMicrophone(tag: JQuery, event_registry: Registry<EventMod
|
||||||
|
|
||||||
event_registry.on("show_step", event => {
|
event_registry.on("show_step", event => {
|
||||||
stepShown = event.step === "microphone";
|
stepShown = event.step === "microphone";
|
||||||
if(!stepShown) {
|
if (!stepShown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event_registry.fire_async("step-status", { allowNextStep: helpStep > 2, allowPreviousStep: helpStep > 2 });
|
event_registry.fire_async("step-status", {allowNextStep: helpStep > 2, allowPreviousStep: helpStep > 2});
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import * as htmltags from "tc-shared/ui/htmltags";
|
import * as htmltags from "../../ui/htmltags";
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
import {renderBBCodeAsJQuery} from "tc-shared/text/bbcode";
|
import {renderBBCodeAsJQuery} from "../../text/bbcode";
|
||||||
|
|
||||||
let global_modal: PokeModal;
|
let global_modal: PokeModal;
|
||||||
|
|
||||||
export interface ServerEntry {
|
export interface ServerEntry {
|
||||||
source: ConnectionHandler;
|
source: ConnectionHandler;
|
||||||
|
|
||||||
add_message(invoker: PokeInvoker, message: string);
|
add_message(invoker: PokeInvoker, message: string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,15 +30,18 @@ class PokeModal {
|
||||||
this._handle.close_listener.push(() => this._handle_close());
|
this._handle.close_listener.push(() => this._handle_close());
|
||||||
}
|
}
|
||||||
|
|
||||||
modal() { return this._handle; }
|
modal() {
|
||||||
|
return this._handle;
|
||||||
|
}
|
||||||
|
|
||||||
add_poke(source: ConnectionHandler, invoker: PokeInvoker, message: string) {
|
add_poke(source: ConnectionHandler, invoker: PokeInvoker, message: string) {
|
||||||
let handler: ServerEntry;
|
let handler: ServerEntry;
|
||||||
for(const entry of this.source_map)
|
for (const entry of this.source_map)
|
||||||
if(entry.source === source) {
|
if (entry.source === source) {
|
||||||
handler = entry;
|
handler = entry;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!handler) {
|
if (!handler) {
|
||||||
const html_tag = $.spawn("div").addClass("server");
|
const html_tag = $.spawn("div").addClass("server");
|
||||||
const poke_list = $.spawn("div").addClass("poke-list");
|
const poke_list = $.spawn("div").addClass("poke-list");
|
||||||
$.spawn("div")
|
$.spawn("div")
|
||||||
|
@ -58,9 +62,9 @@ class PokeModal {
|
||||||
client_name: invoker.name,
|
client_name: invoker.name,
|
||||||
client_unique_id: invoker.unique_id
|
client_unique_id: invoker.unique_id
|
||||||
}))).appendTo(container);
|
}))).appendTo(container);
|
||||||
if(message) {
|
if (message) {
|
||||||
$.spawn("div").addClass("text").text(tr("pokes you:")).appendTo(container);
|
$.spawn("div").addClass("text").text(tr("pokes you:")).appendTo(container);
|
||||||
$.spawn("div").addClass("poke-message").append(...renderBBCodeAsJQuery(message, { convertSingleUrls: false })).appendTo(container);
|
$.spawn("div").addClass("poke-message").append(...renderBBCodeAsJQuery(message, {convertSingleUrls: false})).appendTo(container);
|
||||||
} else {
|
} else {
|
||||||
$.spawn("div").addClass("text").text(tr("pokes you.")).appendTo(container);
|
$.spawn("div").addClass("text").text(tr("pokes you.")).appendTo(container);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +91,7 @@ export type PokeInvoker = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function spawnPoke(source: ConnectionHandler, invoker: PokeInvoker, message: string) {
|
export function spawnPoke(source: ConnectionHandler, invoker: PokeInvoker, message: string) {
|
||||||
if(!global_modal)
|
if (!global_modal)
|
||||||
global_modal = new PokeModal();
|
global_modal = new PokeModal();
|
||||||
global_modal.add_poke(source, invoker, message);
|
global_modal.add_poke(source, invoker, message);
|
||||||
global_modal.modal().open();
|
global_modal.modal().open();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {createErrorModal, createModal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createModal} from "../../ui/elements/Modal";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {SingleCommandHandler} from "tc-shared/connection/ConnectionBase";
|
import {SingleCommandHandler} from "../../connection/ConnectionBase";
|
||||||
|
|
||||||
export function spawnQueryCreate(connection: ConnectionHandler, callback_created?: (user, pass) => any) {
|
export function spawnQueryCreate(connection: ConnectionHandler, callback_created?: (user, pass) => any) {
|
||||||
let modal;
|
let modal;
|
||||||
|
@ -14,7 +14,7 @@ export function spawnQueryCreate(connection: ConnectionHandler, callback_created
|
||||||
template.find(".button-close").on('click', event => modal.close());
|
template.find(".button-close").on('click', event => modal.close());
|
||||||
template.find(".button-create").on('click', event => {
|
template.find(".button-create").on('click', event => {
|
||||||
const name = template.find(".input-name").val() as string;
|
const name = template.find(".input-name").val() as string;
|
||||||
if(name.length < 3 || name.length > 64) {
|
if (name.length < 3 || name.length > 64) {
|
||||||
createErrorModal(tr("Invalid username"), tr("Please enter a valid name!")).open();
|
createErrorModal(tr("Invalid username"), tr("Please enter a valid name!")).open();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export function spawnQueryCreate(connection: ConnectionHandler, callback_created
|
||||||
password: json.client_login_password
|
password: json.client_login_password
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
if(callback_created)
|
if (callback_created)
|
||||||
callback_created(name, json.client_login_password);
|
callback_created(name, json.client_login_password);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -38,7 +38,7 @@ export function spawnQueryCreate(connection: ConnectionHandler, callback_created
|
||||||
connection.serverConnection.send_command("querycreate", {
|
connection.serverConnection.send_command("querycreate", {
|
||||||
client_login_name: name
|
client_login_name: name
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.extra_message || error.message;
|
error = error.extra_message || error.message;
|
||||||
createErrorModal(tr("Unable to create account"), tr("Failed to create account<br>Message: ") + error).open();
|
createErrorModal(tr("Unable to create account"), tr("Failed to create account<br>Message: ") + error).open();
|
||||||
}).then(() => connection.serverConnection.command_handler_boss().remove_single_handler(single_handler));
|
}).then(() => connection.serverConnection.command_handler_boss().remove_single_handler(single_handler));
|
||||||
|
|
|
@ -157,18 +157,18 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//tmpl_query_manager
|
//tmpl_query_manager
|
||||||
import {createErrorModal, createInfoModal, createInputModal, createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createInfoModal, createInputModal, createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {CommandResult, QueryListEntry} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult, QueryListEntry} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {SingleCommandHandler} from "tc-shared/connection/ConnectionBase";
|
import {SingleCommandHandler} from "../../connection/ConnectionBase";
|
||||||
import {copy_to_clipboard} from "tc-shared/utils/helpers";
|
import {copy_to_clipboard} from "../../utils/helpers";
|
||||||
import {spawnYesNo} from "tc-shared/ui/modal/ModalYesNo";
|
import {spawnYesNo} from "../../ui/modal/ModalYesNo";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import {LogCategory} from "../../log";
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import PermissionType from "../../permission/PermissionType";
|
||||||
import * as log from "tc-shared/log";
|
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||||
import {spawnQueryCreate, spawnQueryCreated} from "tc-shared/ui/modal/ModalQuery";
|
import {spawnQueryCreate, spawnQueryCreated} from "../../ui/modal/ModalQuery";
|
||||||
import {formatMessage} from "tc-shared/ui/frames/chat";
|
import {formatMessage} from "../../ui/frames/chat";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../../connection/ErrorCode";
|
||||||
|
|
||||||
export function spawnQueryManage(client: ConnectionHandler) {
|
export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
|
@ -210,7 +210,7 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
button_create.prop('disabled', !permission_create);
|
button_create.prop('disabled', !permission_create);
|
||||||
|
|
||||||
const set_error = (error: string | undefined) => {
|
const set_error = (error: string | undefined) => {
|
||||||
if(typeof(error) === "string")
|
if (typeof (error) === "string")
|
||||||
container_list_error.text(error).show();
|
container_list_error.text(error).show();
|
||||||
else
|
else
|
||||||
container_list_error.hide();
|
container_list_error.hide();
|
||||||
|
@ -228,12 +228,12 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
current_server = server_id;
|
current_server = server_id;
|
||||||
|
|
||||||
client.serverConnection.command_helper.requestQueryList(server_id).then(result => {
|
client.serverConnection.command_helper.requestQueryList(server_id).then(result => {
|
||||||
if(!result || !result.queries.length) {
|
if (!result || !result.queries.length) {
|
||||||
container_list_empty.text(tr("No queries available"));
|
container_list_empty.text(tr("No queries available"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const entry of result.queries) {
|
for (const entry of result.queries) {
|
||||||
const tag = $.spawn("div").addClass("entry").text(entry.username + " (" + entry.unique_id + ")");
|
const tag = $.spawn("div").addClass("entry").text(entry.username + " (" + entry.unique_id + ")");
|
||||||
tag.on('click', event => {
|
tag.on('click', event => {
|
||||||
container_list.find(".selected").removeClass("selected");
|
container_list.find(".selected").removeClass("selected");
|
||||||
|
@ -241,11 +241,11 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
set_selected(entry, false);
|
set_selected(entry, false);
|
||||||
});
|
});
|
||||||
container_list.append(tag);
|
container_list.append(tag);
|
||||||
if(entry.username === selected_entry) tag.trigger('click');
|
if (entry.username === selected_entry) tag.trigger('click');
|
||||||
|
|
||||||
const text_mesh = (entry.username + " " + entry.unique_id + " " + entry.bounded_server).toLowerCase();
|
const text_mesh = (entry.username + " " + entry.unique_id + " " + entry.bounded_server).toLowerCase();
|
||||||
filter_callbacks.push(text => {
|
filter_callbacks.push(text => {
|
||||||
if(typeof(text) === "undefined" || text_mesh.indexOf(text) != -1) {
|
if (typeof (text) === "undefined" || text_mesh.indexOf(text) != -1) {
|
||||||
tag.show();
|
tag.show();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -260,7 +260,7 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
button_update.prop('disabled', false);
|
button_update.prop('disabled', false);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
button_update.prop('disabled', false);
|
button_update.prop('disabled', false);
|
||||||
if(error instanceof CommandResult && error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS) {
|
if (error instanceof CommandResult && error.id === ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS) {
|
||||||
set_error(tr("No permissions"));
|
set_error(tr("No permissions"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -275,10 +275,10 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const set_selected = (entry: QueryListEntry | undefined, force: boolean) => {
|
const set_selected = (entry: QueryListEntry | undefined, force: boolean) => {
|
||||||
if(entry === selected_query && !force) return;
|
if (entry === selected_query && !force) return;
|
||||||
selected_query = entry;
|
selected_query = entry;
|
||||||
|
|
||||||
if(!selected_query) {
|
if (!selected_query) {
|
||||||
detail_name.text("-");
|
detail_name.text("-");
|
||||||
detail_unique_id.text("-");
|
detail_unique_id.text("-");
|
||||||
detail_bound_server.text("-");
|
detail_bound_server.text("-");
|
||||||
|
@ -289,16 +289,16 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
} else {
|
} else {
|
||||||
detail_name.text(selected_query.username);
|
detail_name.text(selected_query.username);
|
||||||
detail_unique_id.text(selected_query.unique_id);
|
detail_unique_id.text(selected_query.unique_id);
|
||||||
if(selected_query.bounded_server == 0)
|
if (selected_query.bounded_server == 0)
|
||||||
detail_bound_server.text(tr("On the instance"));
|
detail_bound_server.text(tr("On the instance"));
|
||||||
else if(selected_query.bounded_server === current_server)
|
else if (selected_query.bounded_server === current_server)
|
||||||
detail_bound_server.text(tr("On the current server"));
|
detail_bound_server.text(tr("On the current server"));
|
||||||
else
|
else
|
||||||
detail_bound_server.text(selected_query.bounded_server.toString());
|
detail_bound_server.text(selected_query.bounded_server.toString());
|
||||||
|
|
||||||
button_delete.prop('disabled', !permission_delete && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_delete_own));
|
button_delete.prop('disabled', !permission_delete && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_delete_own));
|
||||||
button_rename.prop('disabled', !permission_rename && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_rename_own));
|
button_rename.prop('disabled', !permission_rename && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_rename_own));
|
||||||
if(selected_query.bounded_server != 0) {
|
if (selected_query.bounded_server != 0) {
|
||||||
button_change_password.prop('disabled', !permission_password && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_password_own));
|
button_change_password.prop('disabled', !permission_password && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_password_own));
|
||||||
} else {
|
} else {
|
||||||
button_change_password.prop('disabled', !permission_password_global && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_password_own));
|
button_change_password.prop('disabled', !permission_password_global && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_password_own));
|
||||||
|
@ -308,11 +308,11 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
|
|
||||||
const update_filter = () => {
|
const update_filter = () => {
|
||||||
let value = input_filter.val() as string;
|
let value = input_filter.val() as string;
|
||||||
if(!value) value = undefined;
|
if (!value) value = undefined;
|
||||||
else value = value.toLowerCase();
|
else value = value.toLowerCase();
|
||||||
|
|
||||||
const shown = filter_callbacks.filter(e => e(value)).length;
|
const shown = filter_callbacks.filter(e => e(value)).length;
|
||||||
if(shown > 0) {
|
if (shown > 0) {
|
||||||
container_list_empty.hide();
|
container_list_empty.hide();
|
||||||
} else {
|
} else {
|
||||||
container_list_empty.text(tr("No accounts found")).show();
|
container_list_empty.text(tr("No accounts found")).show();
|
||||||
|
@ -323,7 +323,7 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
/* all buttons */
|
/* all buttons */
|
||||||
{
|
{
|
||||||
detail_unique_id_copy.on('click', event => {
|
detail_unique_id_copy.on('click', event => {
|
||||||
if(!selected_query) return;
|
if (!selected_query) return;
|
||||||
|
|
||||||
copy_to_clipboard(selected_query.unique_id);
|
copy_to_clipboard(selected_query.unique_id);
|
||||||
createInfoModal(tr("Unique ID copied"), tr("The unique id has been successfully copied to your clipboard.")).open();
|
createInfoModal(tr("Unique ID copied"), tr("The unique id has been successfully copied to your clipboard.")).open();
|
||||||
|
@ -334,17 +334,17 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
});
|
});
|
||||||
|
|
||||||
button_delete.on('click', event => {
|
button_delete.on('click', event => {
|
||||||
if(!selected_query) return;
|
if (!selected_query) return;
|
||||||
|
|
||||||
spawnYesNo(tr("Are you sure?"), tr("Do you really want to delete this account?"), result => {
|
spawnYesNo(tr("Are you sure?"), tr("Do you really want to delete this account?"), result => {
|
||||||
if(result) {
|
if (result) {
|
||||||
client.serverConnection.send_command("querydelete", {
|
client.serverConnection.send_command("querydelete", {
|
||||||
client_login_name: selected_query.username
|
client_login_name: selected_query.username
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
createInfoModal(tr("Account successfully deleted"), tr("The query account has been successfully deleted!")).open();
|
createInfoModal(tr("Account successfully deleted"), tr("The query account has been successfully deleted!")).open();
|
||||||
update_list(undefined);
|
update_list(undefined);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.extra_message || error.message;
|
error = error.extra_message || error.message;
|
||||||
createErrorModal(tr("Unable to delete account"), formatMessage(tr("Failed to delete account{:br:}Message: {}"), error)).open();
|
createErrorModal(tr("Unable to delete account"), formatMessage(tr("Failed to delete account{:br:}Message: {}"), error)).open();
|
||||||
});
|
});
|
||||||
|
@ -353,10 +353,10 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
});
|
});
|
||||||
|
|
||||||
button_rename.on('click', () => {
|
button_rename.on('click', () => {
|
||||||
if(!selected_query) return;
|
if (!selected_query) return;
|
||||||
|
|
||||||
createInputModal(tr("Change account name"), tr("Enter the new name for the login:"), text => text.length >= 3, result => {
|
createInputModal(tr("Change account name"), tr("Enter the new name for the login:"), text => text.length >= 3, result => {
|
||||||
if(result) {
|
if (result) {
|
||||||
client.serverConnection.send_command("queryrename", {
|
client.serverConnection.send_command("queryrename", {
|
||||||
client_login_name: selected_query.username,
|
client_login_name: selected_query.username,
|
||||||
client_new_login_name: result
|
client_new_login_name: result
|
||||||
|
@ -364,7 +364,7 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
createInfoModal(tr("Account successfully renamed"), tr("The query account has been renamed!")).open();
|
createInfoModal(tr("Account successfully renamed"), tr("The query account has been renamed!")).open();
|
||||||
update_list(result as string);
|
update_list(result as string);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.extra_message || error.message;
|
error = error.extra_message || error.message;
|
||||||
createErrorModal(tr("Unable to rename account"), formatMessage(tr("Failed to rename account{:br:}Message: {}"), error)).open();
|
createErrorModal(tr("Unable to rename account"), formatMessage(tr("Failed to rename account{:br:}Message: {}"), error)).open();
|
||||||
});
|
});
|
||||||
|
@ -373,10 +373,10 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
});
|
});
|
||||||
|
|
||||||
button_change_password.on('click', () => {
|
button_change_password.on('click', () => {
|
||||||
if(!selected_query) return;
|
if (!selected_query) return;
|
||||||
|
|
||||||
createInputModal(tr("Change account's password"), tr("Enter a new password (leave blank for auto generation):"), text => true, result => {
|
createInputModal(tr("Change account's password"), tr("Enter a new password (leave blank for auto generation):"), text => true, result => {
|
||||||
if(result !== false) {
|
if (result !== false) {
|
||||||
const single_handler: SingleCommandHandler = {
|
const single_handler: SingleCommandHandler = {
|
||||||
command: "notifyquerypasswordchanges",
|
command: "notifyquerypasswordchanges",
|
||||||
function: command => {
|
function: command => {
|
||||||
|
@ -395,7 +395,7 @@ export function spawnQueryManage(client: ConnectionHandler) {
|
||||||
client_login_password: result
|
client_login_password: result
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
client.serverConnection.command_handler_boss().remove_single_handler(single_handler);
|
client.serverConnection.command_handler_boss().remove_single_handler(single_handler);
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.extra_message || error.message;
|
error = error.extra_message || error.message;
|
||||||
createErrorModal(tr("Unable to change password"), formatMessage(tr("Failed to change password{:br:}Message: {}"), error)).open();
|
createErrorModal(tr("Unable to change password"), formatMessage(tr("Failed to change password{:br:}Message: {}"), error)).open();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
import {ServerEntry, ServerProperties} from "tc-shared/tree/Server";
|
import {ServerEntry, ServerProperties} from "../../tree/Server";
|
||||||
import {createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import PermissionType from "tc-shared/permission/PermissionType";
|
import PermissionType from "../../permission/PermissionType";
|
||||||
import {GroupManager} from "tc-shared/permission/GroupManager";
|
import {GroupManager} from "../../permission/GroupManager";
|
||||||
import {hashPassword} from "tc-shared/utils/helpers";
|
import {hashPassword} from "../../utils/helpers";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
import {spawnIconSelect} from "tc-shared/ui/modal/ModalIconSelect";
|
import {spawnIconSelect} from "../../ui/modal/ModalIconSelect";
|
||||||
import {network} from "tc-shared/ui/frames/chat";
|
import {network} from "../../ui/frames/chat";
|
||||||
|
|
||||||
export function createServerModal(server: ServerEntry, callback: (properties?: ServerProperties) => Promise<void>) {
|
export function createServerModal(server: ServerEntry, callback: (properties?: ServerProperties) => Promise<void>) {
|
||||||
const properties = Object.assign({}, server.properties);
|
const properties = Object.assign({}, server.properties);
|
||||||
|
|
||||||
let _valid_states: {[key: string]:boolean} = {
|
let _valid_states: { [key: string]: boolean } = {
|
||||||
general: false
|
general: false
|
||||||
};
|
};
|
||||||
|
|
||||||
let _toggle_valid = (key: string | undefined, value?: boolean) => {
|
let _toggle_valid = (key: string | undefined, value?: boolean) => {
|
||||||
if(typeof(key) === "string") {
|
if (typeof (key) === "string") {
|
||||||
_valid_states[key] = value;
|
_valid_states[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
let flag = true;
|
let flag = true;
|
||||||
for(const key of Object.keys(_valid_states))
|
for (const key of Object.keys(_valid_states))
|
||||||
if(!_valid_states[key]) {
|
if (!_valid_states[key]) {
|
||||||
flag = false;
|
flag = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flag) {
|
if (flag) {
|
||||||
flag = false;
|
flag = false;
|
||||||
for(const property_name of Object.keys(properties)) {
|
for (const property_name of Object.keys(properties)) {
|
||||||
if(server.properties[property_name] !== properties[property_name]) {
|
if (server.properties[property_name] !== properties[property_name]) {
|
||||||
flag = true;
|
flag = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ export function createServerModal(server: ServerEntry, callback: (properties?: S
|
||||||
header: tr("Manage the Virtual Server"),
|
header: tr("Manage the Virtual Server"),
|
||||||
body: () => {
|
body: () => {
|
||||||
const template = $("#tmpl_server_edit").renderTag(Object.assign(Object.assign({}, server.properties), {
|
const template = $("#tmpl_server_edit").renderTag(Object.assign(Object.assign({}, server.properties), {
|
||||||
server_icon: server.channelTree.client.fileManager.icons.generateTag(server.properties.virtualserver_icon_id)
|
server_icon: server.channelTree.client.fileManager.icons.generateTag(server.properties.virtualserver_icon_id)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/* the tab functionality */
|
/* the tab functionality */
|
||||||
|
@ -80,8 +80,8 @@ export function createServerModal(server: ServerEntry, callback: (properties?: S
|
||||||
const button_save = modal.htmlTag.find(".button-save");
|
const button_save = modal.htmlTag.find(".button-save");
|
||||||
button_save.on('click', event => {
|
button_save.on('click', event => {
|
||||||
const changed = {} as ServerProperties;
|
const changed = {} as ServerProperties;
|
||||||
for(const property_name of Object.keys(properties))
|
for (const property_name of Object.keys(properties))
|
||||||
if(server.properties[property_name] !== properties[property_name])
|
if (server.properties[property_name] !== properties[property_name])
|
||||||
changed[property_name] = properties[property_name];
|
changed[property_name] = properties[property_name];
|
||||||
callback(changed).then(() => {
|
callback(changed).then(() => {
|
||||||
_toggle_valid(undefined);
|
_toggle_valid(undefined);
|
||||||
|
@ -125,7 +125,7 @@ function apply_general_listener(tag: JQuery, server: ServerEntry, properties: Se
|
||||||
console.log("Selected icon ID: %d", id);
|
console.log("Selected icon ID: %d", id);
|
||||||
properties.virtualserver_icon_id = id;
|
properties.virtualserver_icon_id = id;
|
||||||
callback_valid(undefined); //Toggle save button update
|
callback_valid(undefined); //Toggle save button update
|
||||||
}, properties.virtualserver_icon_id);
|
}, properties.virtualserver_icon_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
tag.find(".button-icon-remove").on('click', event => {
|
tag.find(".button-icon-remove").on('click', event => {
|
||||||
|
@ -148,7 +148,7 @@ function apply_general_listener(tag: JQuery, server: ServerEntry, properties: Se
|
||||||
container.on('change', event => {
|
container.on('change', event => {
|
||||||
const password = container.val() as string;
|
const password = container.val() as string;
|
||||||
properties.virtualserver_flag_password = !!password;
|
properties.virtualserver_flag_password = !!password;
|
||||||
if(properties.virtualserver_flag_password) {
|
if (properties.virtualserver_flag_password) {
|
||||||
hashPassword(password).then(pass => properties.virtualserver_password = pass);
|
hashPassword(password).then(pass => properties.virtualserver_password = pass);
|
||||||
}
|
}
|
||||||
callback_valid(undefined); //Toggle save button update
|
callback_valid(undefined); //Toggle save button update
|
||||||
|
@ -196,7 +196,7 @@ function apply_general_listener(tag: JQuery, server: ServerEntry, properties: Se
|
||||||
const input = container.find("textarea");
|
const input = container.find("textarea");
|
||||||
|
|
||||||
const insert_tag = (open: string, close: string) => {
|
const insert_tag = (open: string, close: string) => {
|
||||||
if(input.prop("disabled"))
|
if (input.prop("disabled"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const node = input[0] as HTMLTextAreaElement;
|
const node = input[0] as HTMLTextAreaElement;
|
||||||
|
@ -347,27 +347,27 @@ function apply_network_listener(tag: JQuery, server: ServerEntry, properties: Se
|
||||||
}
|
}
|
||||||
|
|
||||||
/* quota update task */
|
/* quota update task */
|
||||||
if(server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CONNECTIONINFO_VIEW).granted(1)) {
|
if (server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CONNECTIONINFO_VIEW).granted(1)) {
|
||||||
const month_bytes_downloaded = tag.find(".value.virtualserver_month_bytes_downloaded")[0];
|
const month_bytes_downloaded = tag.find(".value.virtualserver_month_bytes_downloaded")[0];
|
||||||
const month_bytes_uploaded = tag.find(".value.virtualserver_month_bytes_uploaded")[0];
|
const month_bytes_uploaded = tag.find(".value.virtualserver_month_bytes_uploaded")[0];
|
||||||
const total_bytes_downloaded = tag.find(".value.virtualserver_total_bytes_downloaded")[0];
|
const total_bytes_downloaded = tag.find(".value.virtualserver_total_bytes_downloaded")[0];
|
||||||
const total_bytes_uploaded = tag.find(".value.virtualserver_total_bytes_uploaded")[0];
|
const total_bytes_uploaded = tag.find(".value.virtualserver_total_bytes_uploaded")[0];
|
||||||
|
|
||||||
let id = setInterval(() => {
|
let id = setInterval(() => {
|
||||||
if(!modal.shown) {
|
if (!modal.shown) {
|
||||||
clearInterval(id);
|
clearInterval(id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
server.request_connection_info().then(info => {
|
server.request_connection_info().then(info => {
|
||||||
if(info.connection_filetransfer_bytes_sent_month && month_bytes_downloaded)
|
if (info.connection_filetransfer_bytes_sent_month && month_bytes_downloaded)
|
||||||
month_bytes_downloaded.innerText = network.format_bytes(info.connection_filetransfer_bytes_sent_month);
|
month_bytes_downloaded.innerText = network.format_bytes(info.connection_filetransfer_bytes_sent_month);
|
||||||
if(info.connection_filetransfer_bytes_received_month && month_bytes_uploaded)
|
if (info.connection_filetransfer_bytes_received_month && month_bytes_uploaded)
|
||||||
month_bytes_uploaded.innerText = network.format_bytes(info.connection_filetransfer_bytes_received_month);
|
month_bytes_uploaded.innerText = network.format_bytes(info.connection_filetransfer_bytes_received_month);
|
||||||
|
|
||||||
if(info.connection_filetransfer_bytes_sent_total && total_bytes_downloaded)
|
if (info.connection_filetransfer_bytes_sent_total && total_bytes_downloaded)
|
||||||
total_bytes_downloaded.innerText = network.format_bytes(info.connection_filetransfer_bytes_sent_total);
|
total_bytes_downloaded.innerText = network.format_bytes(info.connection_filetransfer_bytes_sent_total);
|
||||||
if(info.connection_filetransfer_bytes_received_total && total_bytes_uploaded)
|
if (info.connection_filetransfer_bytes_received_total && total_bytes_uploaded)
|
||||||
total_bytes_uploaded.innerText = network.format_bytes(info.connection_filetransfer_bytes_received_total);
|
total_bytes_uploaded.innerText = network.format_bytes(info.connection_filetransfer_bytes_received_total);
|
||||||
});
|
});
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
@ -624,10 +624,10 @@ function apply_misc_listener(tag: JQuery, server: ServerEntry, properties: Serve
|
||||||
callback_valid(undefined); //Toggle save button update
|
callback_valid(undefined); //Toggle save button update
|
||||||
}).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission);
|
}).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission);
|
||||||
|
|
||||||
for(const group of server.channelTree.client.groups.serverGroups.sort(GroupManager.sorter())) {
|
for (const group of server.channelTree.client.groups.serverGroups.sort(GroupManager.sorter())) {
|
||||||
if(group.type != 2) continue;
|
if (group.type != 2) continue;
|
||||||
let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id);
|
let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id);
|
||||||
if(group.id == server.properties.virtualserver_default_server_group)
|
if (group.id == server.properties.virtualserver_default_server_group)
|
||||||
group_tag.prop("selected", true);
|
group_tag.prop("selected", true);
|
||||||
group_tag.appendTo(container);
|
group_tag.appendTo(container);
|
||||||
}
|
}
|
||||||
|
@ -643,10 +643,10 @@ function apply_misc_listener(tag: JQuery, server: ServerEntry, properties: Serve
|
||||||
callback_valid(undefined); //Toggle save button update
|
callback_valid(undefined); //Toggle save button update
|
||||||
}).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission);
|
}).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission);
|
||||||
|
|
||||||
for(const group of server.channelTree.client.groups.serverGroups.sort(GroupManager.sorter())) {
|
for (const group of server.channelTree.client.groups.serverGroups.sort(GroupManager.sorter())) {
|
||||||
if(group.type != 2) continue;
|
if (group.type != 2) continue;
|
||||||
let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id);
|
let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id);
|
||||||
if(group.id == server.properties.virtualserver_default_music_group)
|
if (group.id == server.properties.virtualserver_default_music_group)
|
||||||
group_tag.prop("selected", true);
|
group_tag.prop("selected", true);
|
||||||
group_tag.appendTo(container);
|
group_tag.appendTo(container);
|
||||||
}
|
}
|
||||||
|
@ -662,10 +662,10 @@ function apply_misc_listener(tag: JQuery, server: ServerEntry, properties: Serve
|
||||||
callback_valid(undefined); //Toggle save button update
|
callback_valid(undefined); //Toggle save button update
|
||||||
}).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission);
|
}).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission);
|
||||||
|
|
||||||
for(const group of server.channelTree.client.groups.channelGroups.sort(GroupManager.sorter())) {
|
for (const group of server.channelTree.client.groups.channelGroups.sort(GroupManager.sorter())) {
|
||||||
if(group.type != 2) continue;
|
if (group.type != 2) continue;
|
||||||
let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id);
|
let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id);
|
||||||
if(group.id == server.properties.virtualserver_default_channel_admin_group)
|
if (group.id == server.properties.virtualserver_default_channel_admin_group)
|
||||||
group_tag.prop("selected", true);
|
group_tag.prop("selected", true);
|
||||||
group_tag.appendTo(container);
|
group_tag.appendTo(container);
|
||||||
}
|
}
|
||||||
|
@ -681,10 +681,10 @@ function apply_misc_listener(tag: JQuery, server: ServerEntry, properties: Serve
|
||||||
callback_valid(undefined); //Toggle save button update
|
callback_valid(undefined); //Toggle save button update
|
||||||
}).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission);
|
}).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission);
|
||||||
|
|
||||||
for(const group of server.channelTree.client.groups.channelGroups.sort(GroupManager.sorter())) {
|
for (const group of server.channelTree.client.groups.channelGroups.sort(GroupManager.sorter())) {
|
||||||
if(group.type != 2) continue;
|
if (group.type != 2) continue;
|
||||||
let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id);
|
let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id);
|
||||||
if(group.id == server.properties.virtualserver_default_channel_group)
|
if (group.id == server.properties.virtualserver_default_channel_group)
|
||||||
group_tag.prop("selected", true);
|
group_tag.prop("selected", true);
|
||||||
group_tag.appendTo(container);
|
group_tag.appendTo(container);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,18 @@ import {
|
||||||
openServerInfoBandwidth,
|
openServerInfoBandwidth,
|
||||||
RequestInfoStatus,
|
RequestInfoStatus,
|
||||||
ServerBandwidthInfoUpdateCallback
|
ServerBandwidthInfoUpdateCallback
|
||||||
} from "tc-shared/ui/modal/ModalServerInfoBandwidth";
|
} from "../../ui/modal/ModalServerInfoBandwidth";
|
||||||
import {ServerEntry} from "tc-shared/tree/Server";
|
import {ServerEntry} from "../../tree/Server";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {createErrorModal, createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createErrorModal, createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {LogCategory} from "tc-shared/log";
|
import * as log from "../../log";
|
||||||
import * as log from "tc-shared/log";
|
import {LogCategory} from "../../log";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
import * as i18nc from "tc-shared/i18n/country";
|
import * as i18nc from "../../i18n/country";
|
||||||
import {format_time, formatMessage} from "tc-shared/ui/frames/chat";
|
import {format_time, formatMessage} from "../../ui/frames/chat";
|
||||||
import {Hostbanner} from "tc-shared/ui/frames/hostbanner";
|
import {Hostbanner} from "../../ui/frames/hostbanner";
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../../connection/ErrorCode";
|
||||||
|
|
||||||
export function openServerInfo(server: ServerEntry) {
|
export function openServerInfo(server: ServerEntry) {
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
|
@ -41,7 +41,7 @@ export function openServerInfo(server: ServerEntry) {
|
||||||
update_values();
|
update_values();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
log.warn(LogCategory.CLIENT, tr("Failed to refresh server properties: %o"), error);
|
log.warn(LogCategory.CLIENT, tr("Failed to refresh server properties: %o"), error);
|
||||||
if(error instanceof CommandResult)
|
if (error instanceof CommandResult)
|
||||||
error = error.extra_message || error.message;
|
error = error.extra_message || error.message;
|
||||||
createErrorModal(tr("Refresh failed"), formatMessage(tr("Failed to refresh server properties.{:br:}Error: {}"), error)).open();
|
createErrorModal(tr("Refresh failed"), formatMessage(tr("Failed to refresh server properties.{:br:}Error: {}"), error)).open();
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
@ -59,7 +59,7 @@ export function openServerInfo(server: ServerEntry) {
|
||||||
|
|
||||||
const updater = setInterval(() => {
|
const updater = setInterval(() => {
|
||||||
server.request_connection_info().then(info => update_callbacks.forEach(e => e(RequestInfoStatus.SUCCESS, info))).catch(error => {
|
server.request_connection_info().then(info => update_callbacks.forEach(e => e(RequestInfoStatus.SUCCESS, info))).catch(error => {
|
||||||
if(error instanceof CommandResult && error.id == ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS) {
|
if (error instanceof CommandResult && error.id == ErrorCode.SERVER_INSUFFICIENT_PERMISSIONS) {
|
||||||
update_callbacks.forEach(e => e(RequestInfoStatus.NO_PERMISSION));
|
update_callbacks.forEach(e => e(RequestInfoStatus.NO_PERMISSION));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,9 @@ export function openServerInfo(server: ServerEntry) {
|
||||||
modal.htmlTag.find(".button-close").on('click', event => modal.close());
|
modal.htmlTag.find(".button-close").on('click', event => modal.close());
|
||||||
modal.htmlTag.find(".button-show-bandwidth").on('click', event => {
|
modal.htmlTag.find(".button-show-bandwidth").on('click', event => {
|
||||||
const custom_callbacks = [];
|
const custom_callbacks = [];
|
||||||
const custom_callback_caller = (status, info) => { custom_callbacks.forEach(e => e(status, info)); };
|
const custom_callback_caller = (status, info) => {
|
||||||
|
custom_callbacks.forEach(e => e(status, info));
|
||||||
|
};
|
||||||
|
|
||||||
update_callbacks.push(custom_callback_caller);
|
update_callbacks.push(custom_callback_caller);
|
||||||
openServerInfoBandwidth(server, custom_callbacks).close_listener.push(() => {
|
openServerInfoBandwidth(server, custom_callbacks).close_listener.push(() => {
|
||||||
|
@ -92,7 +94,7 @@ function apply_hostbanner(server: ServerEntry, tag: JQuery) {
|
||||||
|
|
||||||
const htag = Hostbanner.generate_tag(server.properties.virtualserver_hostbanner_gfx_url, server.properties.virtualserver_hostbanner_gfx_interval, server.properties.virtualserver_hostbanner_mode);
|
const htag = Hostbanner.generate_tag(server.properties.virtualserver_hostbanner_gfx_url, server.properties.virtualserver_hostbanner_gfx_interval, server.properties.virtualserver_hostbanner_mode);
|
||||||
htag.then(t => {
|
htag.then(t => {
|
||||||
if(!t) return;
|
if (!t) return;
|
||||||
|
|
||||||
tag.removeClass("hidden");
|
tag.removeClass("hidden");
|
||||||
container.append(t);
|
container.append(t);
|
||||||
|
@ -120,11 +122,11 @@ function apply_category_1(server: ServerEntry, tag: JQuery, update_callbacks: Se
|
||||||
const container = tag.find(".server-slots");
|
const container = tag.find(".server-slots");
|
||||||
|
|
||||||
let text = server.properties.virtualserver_clientsonline + "/" + server.properties.virtualserver_maxclients;
|
let text = server.properties.virtualserver_clientsonline + "/" + server.properties.virtualserver_maxclients;
|
||||||
if(server.properties.virtualserver_queryclientsonline)
|
if (server.properties.virtualserver_queryclientsonline)
|
||||||
text += " +" + (server.properties.virtualserver_queryclientsonline > 1 ?
|
text += " +" + (server.properties.virtualserver_queryclientsonline > 1 ?
|
||||||
server.properties.virtualserver_queryclientsonline + " " + tr("Queries") :
|
server.properties.virtualserver_queryclientsonline + " " + tr("Queries") :
|
||||||
server.properties.virtualserver_queryclientsonline + " " + tr("Query"));
|
server.properties.virtualserver_queryclientsonline + " " + tr("Query"));
|
||||||
if(server.properties.virtualserver_reserved_slots)
|
if (server.properties.virtualserver_reserved_slots)
|
||||||
text += " (" + server.properties.virtualserver_reserved_slots + " " + tr("Reserved") + ")";
|
text += " (" + server.properties.virtualserver_reserved_slots + " " + tr("Reserved") + ")";
|
||||||
|
|
||||||
container.text(text);
|
container.text(text);
|
||||||
|
@ -184,9 +186,9 @@ function apply_category_2(server: ServerEntry, tag: JQuery, update_callbacks: Se
|
||||||
const container = tag.find(".server-ping");
|
const container = tag.find(".server-ping");
|
||||||
container.text(tr("calculating..."));
|
container.text(tr("calculating..."));
|
||||||
update_callbacks.push((status, data) => {
|
update_callbacks.push((status, data) => {
|
||||||
if(status === RequestInfoStatus.SUCCESS)
|
if (status === RequestInfoStatus.SUCCESS)
|
||||||
container.text(data.connection_ping.toFixed(0) + " " + "ms");
|
container.text(data.connection_ping.toFixed(0) + " " + "ms");
|
||||||
else if(status === RequestInfoStatus.NO_PERMISSION)
|
else if (status === RequestInfoStatus.NO_PERMISSION)
|
||||||
container.text(tr("No Permissions"));
|
container.text(tr("No Permissions"));
|
||||||
else
|
else
|
||||||
container.text(tr("receiving..."));
|
container.text(tr("receiving..."));
|
||||||
|
@ -198,9 +200,9 @@ function apply_category_2(server: ServerEntry, tag: JQuery, update_callbacks: Se
|
||||||
const container = tag.find(".server-packet-loss");
|
const container = tag.find(".server-packet-loss");
|
||||||
container.text(tr("receiving..."));
|
container.text(tr("receiving..."));
|
||||||
update_callbacks.push((status, data) => {
|
update_callbacks.push((status, data) => {
|
||||||
if(status === RequestInfoStatus.SUCCESS)
|
if (status === RequestInfoStatus.SUCCESS)
|
||||||
container.text(data.connection_packetloss_total.toFixed(2) + "%");
|
container.text(data.connection_packetloss_total.toFixed(2) + "%");
|
||||||
else if(status === RequestInfoStatus.NO_PERMISSION)
|
else if (status === RequestInfoStatus.NO_PERMISSION)
|
||||||
container.text(tr("No Permissions"));
|
container.text(tr("No Permissions"));
|
||||||
else
|
else
|
||||||
container.text(tr("receiving..."));
|
container.text(tr("receiving..."));
|
||||||
|
@ -218,9 +220,9 @@ function apply_category_3(server: ServerEntry, tag: JQuery, update_callbacks: Se
|
||||||
/* voice encryption */
|
/* voice encryption */
|
||||||
{
|
{
|
||||||
const container = tag.find(".server-voice-encryption");
|
const container = tag.find(".server-voice-encryption");
|
||||||
if(server.properties.virtualserver_codec_encryption_mode == 0)
|
if (server.properties.virtualserver_codec_encryption_mode == 0)
|
||||||
container.text(tr("Globally off"));
|
container.text(tr("Globally off"));
|
||||||
else if(server.properties.virtualserver_codec_encryption_mode == 1)
|
else if (server.properties.virtualserver_codec_encryption_mode == 1)
|
||||||
container.text(tr("Individually configured per channel"));
|
container.text(tr("Individually configured per channel"));
|
||||||
else
|
else
|
||||||
container.text(tr("Globally on"));
|
container.text(tr("Globally on"));
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import {ServerConnectionInfo, ServerEntry} from "tc-shared/tree/Server";
|
import {ServerConnectionInfo, ServerEntry} from "../../tree/Server";
|
||||||
import {createModal, Modal} from "tc-shared/ui/elements/Modal";
|
import {createModal, Modal} from "../../ui/elements/Modal";
|
||||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||||
import {Graph} from "tc-shared/ui/elements/NetGraph";
|
import {Graph} from "../../ui/elements/NetGraph";
|
||||||
import * as tooltip from "tc-shared/ui/elements/Tooltip";
|
import * as tooltip from "../../ui/elements/Tooltip";
|
||||||
import {network} from "tc-shared/ui/frames/chat";
|
import {network} from "../../ui/frames/chat";
|
||||||
import {ErrorCode} from "tc-shared/connection/ErrorCode";
|
import {ErrorCode} from "../../connection/ErrorCode";
|
||||||
|
|
||||||
export enum RequestInfoStatus {
|
export enum RequestInfoStatus {
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
import {BodyCreator, createModal, ModalFunctions} from "tc-shared/ui/elements/Modal";
|
import {BodyCreator, createModal, ModalFunctions} from "../../ui/elements/Modal";
|
||||||
|
|
||||||
export function spawnYesNo(header: BodyCreator, body: BodyCreator, callback: (_: boolean) => any, properties?: {
|
export function spawnYesNo(header: BodyCreator, body: BodyCreator, callback: (_: boolean) => any, properties?: {
|
||||||
text_yes?: string,
|
text_yes?: string,
|
||||||
|
@ -17,14 +17,14 @@ export function spawnYesNo(header: BodyCreator, body: BodyCreator, callback: (_:
|
||||||
props.header = header;
|
props.header = header;
|
||||||
props.template_properties.question = ModalFunctions.jqueriefy(body);
|
props.template_properties.question = ModalFunctions.jqueriefy(body);
|
||||||
|
|
||||||
props.closeable = typeof(properties.closeable) !== "boolean" || properties.closeable;
|
props.closeable = typeof (properties.closeable) !== "boolean" || properties.closeable;
|
||||||
const modal = createModal(props);
|
const modal = createModal(props);
|
||||||
let submited = false;
|
let submited = false;
|
||||||
const button_yes = modal.htmlTag.find(".button-yes");
|
const button_yes = modal.htmlTag.find(".button-yes");
|
||||||
const button_no = modal.htmlTag.find(".button-no");
|
const button_no = modal.htmlTag.find(".button-no");
|
||||||
|
|
||||||
button_yes.on('click', event => {
|
button_yes.on('click', event => {
|
||||||
if(!submited) {
|
if (!submited) {
|
||||||
submited = true;
|
submited = true;
|
||||||
callback(true);
|
callback(true);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ export function spawnYesNo(header: BodyCreator, body: BodyCreator, callback: (_:
|
||||||
});
|
});
|
||||||
|
|
||||||
button_no.on('click', event => {
|
button_no.on('click', event => {
|
||||||
if(!submited) {
|
if (!submited) {
|
||||||
submited = true;
|
submited = true;
|
||||||
callback(false);
|
callback(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as loader from "tc-loader";
|
import * as loader from "tc-loader";
|
||||||
import {Stage} from "tc-loader";
|
import {Stage} from "tc-loader";
|
||||||
import {CssEditorEvents, CssVariable} from "tc-shared/ui/modal/css-editor/Definitions";
|
import {CssEditorEvents, CssVariable} from "../../../ui/modal/css-editor/Definitions";
|
||||||
import {spawnExternalModal} from "tc-shared/ui/react-elements/external-modal";
|
import {spawnExternalModal} from "../../../ui/react-elements/external-modal";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "../../../events";
|
||||||
import {LogCategory, logWarn} from "tc-shared/log";
|
import {LogCategory, logWarn} from "../../../log";
|
||||||
|
|
||||||
interface CustomVariable {
|
interface CustomVariable {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -12,17 +12,17 @@ interface CustomVariable {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CssVariableManager {
|
class CssVariableManager {
|
||||||
private customVariables: {[key: string]: CustomVariable} = {};
|
private customVariables: { [key: string]: CustomVariable } = {};
|
||||||
private htmlTag: HTMLStyleElement;
|
private htmlTag: HTMLStyleElement;
|
||||||
|
|
||||||
private loadLocalStorage() {
|
private loadLocalStorage() {
|
||||||
try {
|
try {
|
||||||
const payloadString = localStorage.getItem("css-custom-variables");
|
const payloadString = localStorage.getItem("css-custom-variables");
|
||||||
if(typeof payloadString === "undefined" || !payloadString)
|
if (typeof payloadString === "undefined" || !payloadString)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const payload = JSON.parse(payloadString);
|
const payload = JSON.parse(payloadString);
|
||||||
if(payload.version !== 1)
|
if (payload.version !== 1)
|
||||||
throw "invalid payload version";
|
throw "invalid payload version";
|
||||||
|
|
||||||
this.customVariables = payload["customVariables"];
|
this.customVariables = payload["customVariables"];
|
||||||
|
@ -39,24 +39,24 @@ class CssVariableManager {
|
||||||
this.updateCustomVariables(false);
|
this.updateCustomVariables(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllCssVariables() : CssVariable[] {
|
getAllCssVariables(): CssVariable[] {
|
||||||
let variables: {[key: string]: CssVariable} = {};
|
let variables: { [key: string]: CssVariable } = {};
|
||||||
|
|
||||||
const ownStyleSheets = Array.from(document.styleSheets)
|
const ownStyleSheets = Array.from(document.styleSheets)
|
||||||
.filter(sheet => sheet.href === null || sheet.href.startsWith(window.location.origin)) as CSSStyleSheet[];
|
.filter(sheet => sheet.href === null || sheet.href.startsWith(window.location.origin)) as CSSStyleSheet[];
|
||||||
for(const sheet of ownStyleSheets) {
|
for (const sheet of ownStyleSheets) {
|
||||||
for(const rule of sheet.cssRules) {
|
for (const rule of sheet.cssRules) {
|
||||||
if(!(rule instanceof CSSStyleRule))
|
if (!(rule instanceof CSSStyleRule))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(rule.selectorText !== "html:root" && rule.selectorText !== ":root")
|
if (rule.selectorText !== "html:root" && rule.selectorText !== ":root")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(const entry of rule.style) {
|
for (const entry of rule.style) {
|
||||||
if(!entry.startsWith("--"))
|
if (!entry.startsWith("--"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(variables[entry])
|
if (variables[entry])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const customVariable = this.customVariables[entry];
|
const customVariable = this.customVariables[entry];
|
||||||
|
@ -74,7 +74,11 @@ class CssVariableManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
setVariable(name: string, value: string) {
|
setVariable(name: string, value: string) {
|
||||||
const customVariable = this.customVariables[name] || (this.customVariables[name] = { name: name, value: undefined, enabled: false });
|
const customVariable = this.customVariables[name] || (this.customVariables[name] = {
|
||||||
|
name: name,
|
||||||
|
value: undefined,
|
||||||
|
enabled: false
|
||||||
|
});
|
||||||
customVariable.enabled = true;
|
customVariable.enabled = true;
|
||||||
customVariable.value = value;
|
customVariable.value = value;
|
||||||
this.updateCustomVariables(true);
|
this.updateCustomVariables(true);
|
||||||
|
@ -82,25 +86,25 @@ class CssVariableManager {
|
||||||
|
|
||||||
toggleCustomVariable(name: string, flag: boolean, value?: string) {
|
toggleCustomVariable(name: string, flag: boolean, value?: string) {
|
||||||
let customVariable = this.customVariables[name];
|
let customVariable = this.customVariables[name];
|
||||||
if(!customVariable) {
|
if (!customVariable) {
|
||||||
if(!flag)
|
if (!flag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
customVariable = this.customVariables[name] = { name: name, value: value, enabled: true };
|
customVariable = this.customVariables[name] = {name: name, value: value, enabled: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
customVariable.enabled = flag;
|
customVariable.enabled = flag;
|
||||||
if(flag && typeof value === "string")
|
if (flag && typeof value === "string")
|
||||||
customVariable.value = value;
|
customVariable.value = value;
|
||||||
this.updateCustomVariables(true);
|
this.updateCustomVariables(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
exportConfig(allValues: boolean) {
|
exportConfig(allValues: boolean) {
|
||||||
if(allValues) {
|
if (allValues) {
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
version: 1,
|
version: 1,
|
||||||
variables: this.getAllCssVariables().map<CustomVariable>(variable => {
|
variables: this.getAllCssVariables().map<CustomVariable>(variable => {
|
||||||
if(this.customVariables[variable.name]) {
|
if (this.customVariables[variable.name]) {
|
||||||
return this.customVariables[variable.name];
|
return this.customVariables[variable.name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +125,7 @@ class CssVariableManager {
|
||||||
|
|
||||||
importConfig(config: string) {
|
importConfig(config: string) {
|
||||||
const data = JSON.parse(config);
|
const data = JSON.parse(config);
|
||||||
if(data.version !== 1)
|
if (data.version !== 1)
|
||||||
throw "unsupported config version";
|
throw "unsupported config version";
|
||||||
|
|
||||||
this.customVariables = data.variables;
|
this.customVariables = data.variables;
|
||||||
|
@ -147,12 +151,12 @@ class CssVariableManager {
|
||||||
|
|
||||||
private updateCustomVariables(updateConfig: boolean) {
|
private updateCustomVariables(updateConfig: boolean) {
|
||||||
let text = "html:root {\n";
|
let text = "html:root {\n";
|
||||||
for(const variable of Object.values(this.customVariables))
|
for (const variable of Object.values(this.customVariables))
|
||||||
text += " " + variable.name + ": " + variable.value + ";\n";
|
text += " " + variable.name + ": " + variable.value + ";\n";
|
||||||
text += "}";
|
text += "}";
|
||||||
this.htmlTag.textContent = text;
|
this.htmlTag.textContent = text;
|
||||||
|
|
||||||
if(updateConfig) {
|
if (updateConfig) {
|
||||||
localStorage.setItem("css-custom-variables", JSON.stringify({
|
localStorage.setItem("css-custom-variables", JSON.stringify({
|
||||||
version: 1,
|
version: 1,
|
||||||
customVariables: this.customVariables
|
customVariables: this.customVariables
|
||||||
|
@ -160,6 +164,7 @@ class CssVariableManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let cssVariableManager: CssVariableManager;
|
let cssVariableManager: CssVariableManager;
|
||||||
|
|
||||||
export function spawnModalCssVariableEditor() {
|
export function spawnModalCssVariableEditor() {
|
||||||
|
@ -194,24 +199,24 @@ function cssVariableEditorController(events: Registry<CssEditorEvents>) {
|
||||||
events.on("action_import", event => {
|
events.on("action_import", event => {
|
||||||
try {
|
try {
|
||||||
cssVariableManager.importConfig(event.config);
|
cssVariableManager.importConfig(event.config);
|
||||||
events.fire_async("notify_import_result", { success: true });
|
events.fire_async("notify_import_result", {success: true});
|
||||||
events.fire_async("action_select_entry", { variable: undefined });
|
events.fire_async("action_select_entry", {variable: undefined});
|
||||||
events.fire_async("query_css_variables");
|
events.fire_async("query_css_variables");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn("Failed to import CSS variable values: %o", error);
|
console.warn("Failed to import CSS variable values: %o", error);
|
||||||
events.fire_async("notify_import_result", { success: false });
|
events.fire_async("notify_import_result", {success: false});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
events.on("action_reset", () => {
|
events.on("action_reset", () => {
|
||||||
cssVariableManager.reset();
|
cssVariableManager.reset();
|
||||||
events.fire_async("action_select_entry", { variable: undefined });
|
events.fire_async("action_select_entry", {variable: undefined});
|
||||||
events.fire_async("query_css_variables");
|
events.fire_async("query_css_variables");
|
||||||
});
|
});
|
||||||
|
|
||||||
events.on("action_randomize", () => {
|
events.on("action_randomize", () => {
|
||||||
cssVariableManager.randomize();
|
cssVariableManager.randomize();
|
||||||
events.fire_async("action_select_entry", { variable: undefined });
|
events.fire_async("action_select_entry", {variable: undefined});
|
||||||
events.fire_async("query_css_variables");
|
events.fire_async("query_css_variables");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ export interface CssEditorEvents {
|
||||||
action_select_entry: { variable: CssVariable },
|
action_select_entry: { variable: CssVariable },
|
||||||
action_override_toggle: { variableName: string, enabled: boolean, value?: string }
|
action_override_toggle: { variableName: string, enabled: boolean, value?: string }
|
||||||
action_change_override_value: { variableName: string, value: string },
|
action_change_override_value: { variableName: string, value: string },
|
||||||
action_reset: { },
|
action_reset: {},
|
||||||
action_randomize: {},
|
action_randomize: {},
|
||||||
|
|
||||||
action_export: { allValues: boolean },
|
action_export: { allValues: boolean },
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import {useState} from "react";
|
||||||
import {CssEditorEvents, CssEditorUserData, CssVariable} from "tc-shared/ui/modal/css-editor/Definitions";
|
import {CssEditorEvents, CssEditorUserData, CssVariable} from "tc-shared/ui/modal/css-editor/Definitions";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "tc-shared/events";
|
||||||
import {Translatable} from "tc-shared/ui/react-elements/i18n";
|
import {Translatable} from "tc-shared/ui/react-elements/i18n";
|
||||||
import {BoxedInputField, FlatInputField} from "tc-shared/ui/react-elements/InputField";
|
import {BoxedInputField, FlatInputField} from "tc-shared/ui/react-elements/InputField";
|
||||||
import {useState} from "react";
|
|
||||||
import {LoadingDots} from "tc-shared/ui/react-elements/LoadingDots";
|
import {LoadingDots} from "tc-shared/ui/react-elements/LoadingDots";
|
||||||
import {Checkbox} from "tc-shared/ui/react-elements/Checkbox";
|
import {Checkbox} from "tc-shared/ui/react-elements/Checkbox";
|
||||||
import {Button} from "tc-shared/ui/react-elements/Button";
|
import {Button} from "tc-shared/ui/react-elements/Button";
|
||||||
|
@ -13,22 +13,22 @@ import {AbstractModal} from "tc-shared/ui/react-elements/ModalDefinitions";
|
||||||
const cssStyle = require("./Renderer.scss");
|
const cssStyle = require("./Renderer.scss");
|
||||||
|
|
||||||
const CssVariableRenderer = React.memo((props: { events: Registry<CssEditorEvents>, variable: CssVariable, selected: boolean }) => {
|
const CssVariableRenderer = React.memo((props: { events: Registry<CssEditorEvents>, variable: CssVariable, selected: boolean }) => {
|
||||||
const [ selected, setSelected ] = useState(props.selected);
|
const [selected, setSelected] = useState(props.selected);
|
||||||
const [ override, setOverride ] = useState(props.variable.overwriteValue);
|
const [override, setOverride] = useState(props.variable.overwriteValue);
|
||||||
const [ overrideColor, setOverrideColor ] = useState(props.variable.customValue);
|
const [overrideColor, setOverrideColor] = useState(props.variable.customValue);
|
||||||
|
|
||||||
props.events.reactUse("action_select_entry", event => setSelected(event.variable === props.variable));
|
props.events.reactUse("action_select_entry", event => setSelected(event.variable === props.variable));
|
||||||
props.events.reactUse("action_override_toggle", event => {
|
props.events.reactUse("action_override_toggle", event => {
|
||||||
if(event.variableName !== props.variable.name)
|
if (event.variableName !== props.variable.name)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setOverride(event.enabled);
|
setOverride(event.enabled);
|
||||||
if(event.enabled)
|
if (event.enabled)
|
||||||
setOverrideColor(event.value);
|
setOverrideColor(event.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
props.events.reactUse("action_change_override_value", event => {
|
props.events.reactUse("action_change_override_value", event => {
|
||||||
if(event.variableName !== props.variable.name)
|
if (event.variableName !== props.variable.name)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setOverrideColor(event.value);
|
setOverrideColor(event.value);
|
||||||
|
@ -38,22 +38,22 @@ const CssVariableRenderer = React.memo((props: { events: Registry<CssEditorEvent
|
||||||
<div
|
<div
|
||||||
className={cssStyle.variable + " " + (selected ? cssStyle.selected : "")}
|
className={cssStyle.variable + " " + (selected ? cssStyle.selected : "")}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if(selected)
|
if (selected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
props.events.fire("action_select_entry", { variable: props.variable })
|
props.events.fire("action_select_entry", {variable: props.variable})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={cssStyle.preview}>
|
<div className={cssStyle.preview}>
|
||||||
<div
|
<div
|
||||||
className={cssStyle.color}
|
className={cssStyle.color}
|
||||||
style={{ backgroundColor: props.variable.defaultValue }}
|
style={{backgroundColor: props.variable.defaultValue}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={cssStyle.preview}>
|
<div className={cssStyle.preview}>
|
||||||
<div
|
<div
|
||||||
className={cssStyle.color}
|
className={cssStyle.color}
|
||||||
style={{ backgroundColor: override ? overrideColor : undefined }}
|
style={{backgroundColor: override ? overrideColor : undefined}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<a>{props.variable.name}</a>
|
<a>{props.variable.name}</a>
|
||||||
|
@ -62,31 +62,31 @@ const CssVariableRenderer = React.memo((props: { events: Registry<CssEditorEvent
|
||||||
});
|
});
|
||||||
|
|
||||||
const CssVariableListBodyRenderer = (props: { events: Registry<CssEditorEvents> }) => {
|
const CssVariableListBodyRenderer = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
const [ variables, setVariables ] = useState<"loading" | CssVariable[]>(() => {
|
const [variables, setVariables] = useState<"loading" | CssVariable[]>(() => {
|
||||||
props.events.fire_async("query_css_variables");
|
props.events.fire_async("query_css_variables");
|
||||||
return "loading";
|
return "loading";
|
||||||
});
|
});
|
||||||
|
|
||||||
const [ filter, setFilter ] = useState(undefined);
|
const [filter, setFilter] = useState(undefined);
|
||||||
const [ selectedVariable, setSelectedVariable ] = useState(undefined);
|
const [selectedVariable, setSelectedVariable] = useState(undefined);
|
||||||
|
|
||||||
props.events.reactUse("action_select_entry", event => setSelectedVariable(event.variable));
|
props.events.reactUse("action_select_entry", event => setSelectedVariable(event.variable));
|
||||||
props.events.reactUse("query_css_variables", () => setVariables("loading"));
|
props.events.reactUse("query_css_variables", () => setVariables("loading"));
|
||||||
|
|
||||||
let content;
|
let content;
|
||||||
if(variables === "loading") {
|
if (variables === "loading") {
|
||||||
content = (
|
content = (
|
||||||
<div className={cssStyle.overlay} key={"loading"}>
|
<div className={cssStyle.overlay} key={"loading"}>
|
||||||
<a>
|
<a>
|
||||||
<Translatable>Loading</Translatable>
|
<Translatable>Loading</Translatable>
|
||||||
<LoadingDots />
|
<LoadingDots/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
content = [];
|
content = [];
|
||||||
for(const variable of variables) {
|
for (const variable of variables) {
|
||||||
if(filter && variable.name.toLowerCase().indexOf(filter) === -1)
|
if (filter && variable.name.toLowerCase().indexOf(filter) === -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
content.push(<CssVariableRenderer
|
content.push(<CssVariableRenderer
|
||||||
|
@ -97,7 +97,7 @@ const CssVariableListBodyRenderer = (props: { events: Registry<CssEditorEvents>
|
||||||
/>);
|
/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(content.length === 0) {
|
if (content.length === 0) {
|
||||||
content.push(
|
content.push(
|
||||||
<div className={cssStyle.overlay} key={"no-match"}>
|
<div className={cssStyle.overlay} key={"no-match"}>
|
||||||
<a><Translatable>No variable matched your filter</Translatable></a>
|
<a><Translatable>No variable matched your filter</Translatable></a>
|
||||||
|
@ -111,27 +111,27 @@ const CssVariableListBodyRenderer = (props: { events: Registry<CssEditorEvents>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cssStyle.body} onKeyPress={event => {
|
<div className={cssStyle.body} onKeyPress={event => {
|
||||||
if(variables === "loading")
|
if (variables === "loading")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* TODO: This isn't working since the div isn't focused properly yet */
|
/* TODO: This isn't working since the div isn't focused properly yet */
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
if(event.key === "ArrowDown") {
|
if (event.key === "ArrowDown") {
|
||||||
offset = 1;
|
offset = 1;
|
||||||
} else if(event.key === "ArrowUp") {
|
} else if (event.key === "ArrowUp") {
|
||||||
offset = -1;
|
offset = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(offset !== 0) {
|
if (offset !== 0) {
|
||||||
const selectIndex = variables.findIndex(e => e === selectedVariable);
|
const selectIndex = variables.findIndex(e => e === selectedVariable);
|
||||||
if(selectIndex === -1)
|
if (selectIndex === -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const variable = variables[selectIndex + offset];
|
const variable = variables[selectIndex + offset];
|
||||||
if(!variable)
|
if (!variable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
props.events.fire("action_select_entry", { variable: variable });
|
props.events.fire("action_select_entry", {variable: variable});
|
||||||
}
|
}
|
||||||
}} tabIndex={0}>
|
}} tabIndex={0}>
|
||||||
{content}
|
{content}
|
||||||
|
@ -140,7 +140,7 @@ const CssVariableListBodyRenderer = (props: { events: Registry<CssEditorEvents>
|
||||||
};
|
};
|
||||||
|
|
||||||
const CssVariableListSearchRenderer = (props: { events: Registry<CssEditorEvents> }) => {
|
const CssVariableListSearchRenderer = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
const [ isLoading, setLoading ] = useState(true);
|
const [isLoading, setLoading] = useState(true);
|
||||||
|
|
||||||
props.events.reactUse("notify_css_variables", () => setLoading(false));
|
props.events.reactUse("notify_css_variables", () => setLoading(false));
|
||||||
props.events.reactUse("query_css_variables", () => setLoading(true));
|
props.events.reactUse("query_css_variables", () => setLoading(true));
|
||||||
|
@ -151,7 +151,7 @@ const CssVariableListSearchRenderer = (props: { events: Registry<CssEditorEvents
|
||||||
label={<Translatable>Filter variables</Translatable>}
|
label={<Translatable>Filter variables</Translatable>}
|
||||||
labelType={"floating"}
|
labelType={"floating"}
|
||||||
className={cssStyle.input}
|
className={cssStyle.input}
|
||||||
onInput={text => props.events.fire("action_set_filter", { filter: text })}
|
onInput={text => props.events.fire("action_set_filter", {filter: text})}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -164,14 +164,14 @@ const CssVariableListRenderer = (props: { events: Registry<CssEditorEvents> }) =
|
||||||
<a><Translatable>CSS Variable list</Translatable></a>
|
<a><Translatable>CSS Variable list</Translatable></a>
|
||||||
</div>
|
</div>
|
||||||
<div className={cssStyle.list} onKeyPress={event => console.error(event.key)}>
|
<div className={cssStyle.list} onKeyPress={event => console.error(event.key)}>
|
||||||
<CssVariableListBodyRenderer events={props.events} />
|
<CssVariableListBodyRenderer events={props.events}/>
|
||||||
<CssVariableListSearchRenderer events={props.events} />
|
<CssVariableListSearchRenderer events={props.events}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const SelectedVariableInfo = (props: { events: Registry<CssEditorEvents> }) => {
|
const SelectedVariableInfo = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
const [ selectedVariable, setSelectedVariable ] = useState<CssVariable>(undefined);
|
const [selectedVariable, setSelectedVariable] = useState<CssVariable>(undefined);
|
||||||
props.events.reactUse("action_select_entry", event => setSelectedVariable(event.variable));
|
props.events.reactUse("action_select_entry", event => setSelectedVariable(event.variable));
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
|
@ -201,9 +201,9 @@ const SelectedVariableInfo = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const OverrideVariableInfo = (props: { events: Registry<CssEditorEvents> }) => {
|
const OverrideVariableInfo = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
const [ selectedVariable, setSelectedVariable ] = useState<CssVariable>(undefined);
|
const [selectedVariable, setSelectedVariable] = useState<CssVariable>(undefined);
|
||||||
const [ overwriteValue, setOverwriteValue ] = useState<string>(undefined);
|
const [overwriteValue, setOverwriteValue] = useState<string>(undefined);
|
||||||
const [ overwriteEnabled, setOverwriteEnabled ] = useState(false);
|
const [overwriteEnabled, setOverwriteEnabled] = useState(false);
|
||||||
|
|
||||||
props.events.reactUse("action_select_entry", event => {
|
props.events.reactUse("action_select_entry", event => {
|
||||||
setSelectedVariable(event.variable);
|
setSelectedVariable(event.variable);
|
||||||
|
@ -212,17 +212,17 @@ const OverrideVariableInfo = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
props.events.reactUse("action_override_toggle", event => {
|
props.events.reactUse("action_override_toggle", event => {
|
||||||
if(event.variableName !== selectedVariable?.name)
|
if (event.variableName !== selectedVariable?.name)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
selectedVariable.overwriteValue = event.enabled;
|
selectedVariable.overwriteValue = event.enabled;
|
||||||
setOverwriteEnabled(event.enabled);
|
setOverwriteEnabled(event.enabled);
|
||||||
if(event.enabled)
|
if (event.enabled)
|
||||||
setOverwriteValue(event.value);
|
setOverwriteValue(event.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
props.events.reactUse("action_change_override_value", event => {
|
props.events.reactUse("action_change_override_value", event => {
|
||||||
if(event.variableName !== selectedVariable?.name)
|
if (event.variableName !== selectedVariable?.name)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setOverwriteValue(event.value);
|
setOverwriteValue(event.value);
|
||||||
|
@ -251,31 +251,34 @@ const OverrideVariableInfo = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
value={overwriteValue || " "}
|
value={overwriteValue || " "}
|
||||||
onInput={text => {
|
onInput={text => {
|
||||||
selectedVariable.customValue = text;
|
selectedVariable.customValue = text;
|
||||||
props.events.fire("action_change_override_value", { value: text, variableName: selectedVariable.name });
|
props.events.fire("action_change_override_value", {
|
||||||
|
value: text,
|
||||||
|
variableName: selectedVariable.name
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<CssVariableColorPicker events={props.events} selectedVariable={selectedVariable} />
|
<CssVariableColorPicker events={props.events} selectedVariable={selectedVariable}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>);
|
</>);
|
||||||
};
|
};
|
||||||
|
|
||||||
const CssVariableColorPicker = (props: { events: Registry<CssEditorEvents>, selectedVariable: CssVariable }) => {
|
const CssVariableColorPicker = (props: { events: Registry<CssEditorEvents>, selectedVariable: CssVariable }) => {
|
||||||
const [ overwriteValue, setOverwriteValue ] = useState<string>(undefined);
|
const [overwriteValue, setOverwriteValue] = useState<string>(undefined);
|
||||||
const [ overwriteEnabled, setOverwriteEnabled ] = useState(false);
|
const [overwriteEnabled, setOverwriteEnabled] = useState(false);
|
||||||
|
|
||||||
props.events.reactUse("action_override_toggle", event => {
|
props.events.reactUse("action_override_toggle", event => {
|
||||||
if(event.variableName !== props.selectedVariable?.name)
|
if (event.variableName !== props.selectedVariable?.name)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
props.selectedVariable.overwriteValue = event.enabled;
|
props.selectedVariable.overwriteValue = event.enabled;
|
||||||
setOverwriteEnabled(event.enabled);
|
setOverwriteEnabled(event.enabled);
|
||||||
if(event.enabled)
|
if (event.enabled)
|
||||||
setOverwriteValue(event.value);
|
setOverwriteValue(event.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
props.events.reactUse("action_change_override_value", event => {
|
props.events.reactUse("action_change_override_value", event => {
|
||||||
if(event.variableName !== props.selectedVariable?.name || 'cpInvoker' in event)
|
if (event.variableName !== props.selectedVariable?.name || 'cpInvoker' in event)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setOverwriteValue(event.value);
|
setOverwriteValue(event.value);
|
||||||
|
@ -284,23 +287,26 @@ const CssVariableColorPicker = (props: { events: Registry<CssEditorEvents>, sele
|
||||||
let currentInput: string;
|
let currentInput: string;
|
||||||
let inputTimeout: number;
|
let inputTimeout: number;
|
||||||
return (
|
return (
|
||||||
<label className={cssStyle.colorButton} >
|
<label className={cssStyle.colorButton}>
|
||||||
<input
|
<input
|
||||||
disabled={!overwriteEnabled}
|
disabled={!overwriteEnabled}
|
||||||
type={"color"}
|
type={"color"}
|
||||||
value={overwriteValue}
|
value={overwriteValue}
|
||||||
onChange={event => {
|
onChange={event => {
|
||||||
currentInput = event.target.value;
|
currentInput = event.target.value;
|
||||||
if(inputTimeout)
|
if (inputTimeout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
inputTimeout = setTimeout(() => {
|
inputTimeout = setTimeout(() => {
|
||||||
inputTimeout = undefined;
|
inputTimeout = undefined;
|
||||||
props.events.fire("action_change_override_value", { value: currentInput, variableName: props.selectedVariable.name });
|
props.events.fire("action_change_override_value", {
|
||||||
|
value: currentInput,
|
||||||
|
variableName: props.selectedVariable.name
|
||||||
|
});
|
||||||
}, 150);
|
}, 150);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<a className="rainbow-letter" style={{ borderBottomColor: overwriteValue }}>C</a>
|
<a className="rainbow-letter" style={{borderBottomColor: overwriteValue}}>C</a>
|
||||||
</label>
|
</label>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -324,7 +330,7 @@ const ControlButtons = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
color={"blue"}
|
color={"blue"}
|
||||||
type={"normal"}
|
type={"normal"}
|
||||||
className={cssStyle.button}
|
className={cssStyle.button}
|
||||||
onClick={event => props.events.fire("action_export", { allValues: event.shiftKey })}
|
onClick={event => props.events.fire("action_export", {allValues: event.shiftKey})}
|
||||||
title={tr("Click to export the changed values, Shift click to export all values")}
|
title={tr("Click to export the changed values, Shift click to export all values")}
|
||||||
><Translatable>Export</Translatable></Button>
|
><Translatable>Export</Translatable></Button>
|
||||||
<Button
|
<Button
|
||||||
|
@ -332,7 +338,7 @@ const ControlButtons = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
type={"normal"}
|
type={"normal"}
|
||||||
className={cssStyle.button}
|
className={cssStyle.button}
|
||||||
onClick={() => requestFileAsText().then(content => {
|
onClick={() => requestFileAsText().then(content => {
|
||||||
props.events.fire("action_import", { config: content })
|
props.events.fire("action_import", {config: content})
|
||||||
})}
|
})}
|
||||||
><Translatable>Import</Translatable></Button>
|
><Translatable>Import</Translatable></Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -345,9 +351,9 @@ const CssVariableEditor = (props: { events: Registry<CssEditorEvents> }) => {
|
||||||
<div className={cssStyle.header}>
|
<div className={cssStyle.header}>
|
||||||
<a><Translatable>Variable details</Translatable></a>
|
<a><Translatable>Variable details</Translatable></a>
|
||||||
</div>
|
</div>
|
||||||
<SelectedVariableInfo events={props.events} />
|
<SelectedVariableInfo events={props.events}/>
|
||||||
<OverrideVariableInfo events={props.events} />
|
<OverrideVariableInfo events={props.events}/>
|
||||||
<ControlButtons events={props.events} />
|
<ControlButtons events={props.events}/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -374,7 +380,7 @@ const requestFileAsText = async (): Promise<string> => {
|
||||||
element.onchange = resolve;
|
element.onchange = resolve;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(element.files.length !== 1)
|
if (element.files.length !== 1)
|
||||||
return undefined;
|
return undefined;
|
||||||
const file = element.files[0];
|
const file = element.files[0];
|
||||||
element.remove();
|
element.remove();
|
||||||
|
@ -397,7 +403,7 @@ class PopoutConversationUI extends AbstractModal {
|
||||||
downloadTextAsFile(event.config, "teaweb-style.json");
|
downloadTextAsFile(event.config, "teaweb-style.json");
|
||||||
});
|
});
|
||||||
this.events.on("notify_import_result", event => {
|
this.events.on("notify_import_result", event => {
|
||||||
if(event.success)
|
if (event.success)
|
||||||
createInfoModal(tr("Config imported successfully"), tr("The config has been imported successfully.")).open();
|
createInfoModal(tr("Config imported successfully"), tr("The config has been imported successfully.")).open();
|
||||||
else
|
else
|
||||||
createErrorModal(tr("Config imported failed"), tr("The config import has been failed.")).open();
|
createErrorModal(tr("Config imported failed"), tr("The config import has been failed.")).open();
|
||||||
|
@ -407,8 +413,8 @@ class PopoutConversationUI extends AbstractModal {
|
||||||
renderBody() {
|
renderBody() {
|
||||||
return (
|
return (
|
||||||
<div className={cssStyle.container}>
|
<div className={cssStyle.container}>
|
||||||
<CssVariableListRenderer events={this.events} />
|
<CssVariableListRenderer events={this.events}/>
|
||||||
<CssVariableEditor events={this.events} />
|
<CssVariableEditor events={this.events}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ export function spawnEchoTestModal(connection: ConnectionHandler) {
|
||||||
renderBody(): React.ReactElement {
|
renderBody(): React.ReactElement {
|
||||||
return (
|
return (
|
||||||
<EchoTestEventRegistry.Provider value={events}>
|
<EchoTestEventRegistry.Provider value={events}>
|
||||||
<EchoTestModal />
|
<EchoTestModal/>
|
||||||
</EchoTestEventRegistry.Provider>
|
</EchoTestEventRegistry.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -50,10 +50,10 @@ export function spawnEchoTestModal(connection: ConnectionHandler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializeController(connection: ConnectionHandler, events: Registry<EchoTestEvents>) {
|
function initializeController(connection: ConnectionHandler, events: Registry<EchoTestEvents>) {
|
||||||
let testState: TestState = { state: "stopped" };
|
let testState: TestState = {state: "stopped"};
|
||||||
|
|
||||||
events.on("action_open_microphone_settings", () => {
|
events.on("action_open_microphone_settings", () => {
|
||||||
global_client_actions.fire("action_open_window_settings", { defaultCategory: "audio-microphone" });
|
global_client_actions.fire("action_open_window_settings", {defaultCategory: "audio-microphone"});
|
||||||
});
|
});
|
||||||
|
|
||||||
events.on("action_toggle_tests", event => {
|
events.on("action_toggle_tests", event => {
|
||||||
|
@ -61,57 +61,57 @@ function initializeController(connection: ConnectionHandler, events: Registry<Ec
|
||||||
});
|
});
|
||||||
|
|
||||||
events.on("query_test_state", () => {
|
events.on("query_test_state", () => {
|
||||||
events.fire_async("notify_tests_toggle", { enabled: settings.global(Settings.KEY_VOICE_ECHO_TEST_ENABLED) });
|
events.fire_async("notify_tests_toggle", {enabled: settings.global(Settings.KEY_VOICE_ECHO_TEST_ENABLED)});
|
||||||
});
|
});
|
||||||
|
|
||||||
events.on("notify_destroy", settings.globalChangeListener(Settings.KEY_VOICE_ECHO_TEST_ENABLED, value => {
|
events.on("notify_destroy", settings.globalChangeListener(Settings.KEY_VOICE_ECHO_TEST_ENABLED, value => {
|
||||||
events.fire_async("notify_tests_toggle", { enabled: value });
|
events.fire_async("notify_tests_toggle", {enabled: value});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
events.on("action_test_result", event => {
|
events.on("action_test_result", event => {
|
||||||
if(event.status === "success") {
|
if (event.status === "success") {
|
||||||
events.fire("action_close");
|
events.fire("action_close");
|
||||||
} else {
|
} else {
|
||||||
events.fire("action_stop_test");
|
events.fire("action_stop_test");
|
||||||
events.fire("notify_test_phase", { phase: "troubleshooting" });
|
events.fire("notify_test_phase", {phase: "troubleshooting"});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
events.on("action_troubleshooting_finished", event => {
|
events.on("action_troubleshooting_finished", event => {
|
||||||
if(event.status === "aborted") {
|
if (event.status === "aborted") {
|
||||||
events.fire("action_close");
|
events.fire("action_close");
|
||||||
} else {
|
} else {
|
||||||
events.fire("notify_test_phase", { phase: "testing" });
|
events.fire("notify_test_phase", {phase: "testing"});
|
||||||
events.fire("action_start_test");
|
events.fire("action_start_test");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const reportVoiceConnectionState = (state: VoiceConnectionStatus) => {
|
const reportVoiceConnectionState = (state: VoiceConnectionStatus) => {
|
||||||
if(state === VoiceConnectionStatus.Connected) {
|
if (state === VoiceConnectionStatus.Connected) {
|
||||||
beginTest();
|
beginTest();
|
||||||
} else {
|
} else {
|
||||||
endTest();
|
endTest();
|
||||||
}
|
}
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case VoiceConnectionStatus.Connected:
|
case VoiceConnectionStatus.Connected:
|
||||||
events.fire("notify_voice_connection_state", { state: "connected" });
|
events.fire("notify_voice_connection_state", {state: "connected"});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VoiceConnectionStatus.Disconnected:
|
case VoiceConnectionStatus.Disconnected:
|
||||||
case VoiceConnectionStatus.Disconnecting:
|
case VoiceConnectionStatus.Disconnecting:
|
||||||
events.fire("notify_voice_connection_state", { state: "disconnected" });
|
events.fire("notify_voice_connection_state", {state: "disconnected"});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VoiceConnectionStatus.Connecting:
|
case VoiceConnectionStatus.Connecting:
|
||||||
events.fire("notify_voice_connection_state", { state: "connecting" });
|
events.fire("notify_voice_connection_state", {state: "connecting"});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VoiceConnectionStatus.ClientUnsupported:
|
case VoiceConnectionStatus.ClientUnsupported:
|
||||||
events.fire("notify_voice_connection_state", { state: "unsupported-client" });
|
events.fire("notify_voice_connection_state", {state: "unsupported-client"});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VoiceConnectionStatus.ServerUnsupported:
|
case VoiceConnectionStatus.ServerUnsupported:
|
||||||
events.fire("notify_voice_connection_state", { state: "unsupported-server" });
|
events.fire("notify_voice_connection_state", {state: "unsupported-server"});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ function initializeController(connection: ConnectionHandler, events: Registry<Ec
|
||||||
events.on("query_voice_connection_state", () => reportVoiceConnectionState(connection.getServerConnection().getVoiceConnection().getConnectionState()));
|
events.on("query_voice_connection_state", () => reportVoiceConnectionState(connection.getServerConnection().getVoiceConnection().getConnectionState()));
|
||||||
|
|
||||||
events.on("query_test_state", () => {
|
events.on("query_test_state", () => {
|
||||||
events.fire_async("notify_test_state", { state: testState });
|
events.fire_async("notify_test_state", {state: testState});
|
||||||
});
|
});
|
||||||
|
|
||||||
events.on("action_start_test", () => {
|
events.on("action_start_test", () => {
|
||||||
|
@ -133,51 +133,51 @@ function initializeController(connection: ConnectionHandler, events: Registry<Ec
|
||||||
|
|
||||||
const setTestState = (state: TestState) => {
|
const setTestState = (state: TestState) => {
|
||||||
testState = state;
|
testState = state;
|
||||||
events.fire("notify_test_state", { state: state });
|
events.fire("notify_test_state", {state: state});
|
||||||
}
|
}
|
||||||
|
|
||||||
let testId = 0;
|
let testId = 0;
|
||||||
const beginTest = () => {
|
const beginTest = () => {
|
||||||
if(testState.state === "initializing" || testState.state === "running") {
|
if (testState.state === "initializing" || testState.state === "running") {
|
||||||
return;
|
return;
|
||||||
} else if(!connection.serverFeatures.supportsFeature(ServerFeature.WHISPER_ECHO)) {
|
} else if (!connection.serverFeatures.supportsFeature(ServerFeature.WHISPER_ECHO)) {
|
||||||
setTestState({ state: "unsupported" });
|
setTestState({state: "unsupported"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTestState({ state: "initializing" });
|
setTestState({state: "initializing"});
|
||||||
|
|
||||||
|
|
||||||
const currentTestId = ++testId;
|
const currentTestId = ++testId;
|
||||||
connection.startEchoTest().then(() => {
|
connection.startEchoTest().then(() => {
|
||||||
if(currentTestId !== testId) {
|
if (currentTestId !== testId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTestState({ state: "running" });
|
setTestState({state: "running"});
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if(currentTestId !== testId) {
|
if (currentTestId !== testId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let message;
|
let message;
|
||||||
if(error instanceof CommandResult) {
|
if (error instanceof CommandResult) {
|
||||||
message = error.formattedMessage();
|
message = error.formattedMessage();
|
||||||
} else if(error instanceof Error) {
|
} else if (error instanceof Error) {
|
||||||
message = error.message;
|
message = error.message;
|
||||||
} else if(typeof error === "string") {
|
} else if (typeof error === "string") {
|
||||||
message = error;
|
message = error;
|
||||||
} else {
|
} else {
|
||||||
message = tr("lookup the console");
|
message = tr("lookup the console");
|
||||||
logError(LogCategory.AUDIO, tr("Failed to begin echo testing: %o"), error);
|
logError(LogCategory.AUDIO, tr("Failed to begin echo testing: %o"), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTestState({ state: "start-failed", error: message });
|
setTestState({state: "start-failed", error: message});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const endTest = () => {
|
const endTest = () => {
|
||||||
setTestState({ state: "stopped" });
|
setTestState({state: "stopped"});
|
||||||
connection.stopEchoTest();
|
connection.stopEchoTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
export type VoiceConnectionState = "connecting" | "connected" | "disconnected" | "unsupported-client" | "unsupported-server";
|
export type VoiceConnectionState =
|
||||||
export type TestState = { state: "initializing" | "running" | "stopped" | "microphone-invalid" | "unsupported" } | { state: "start-failed", error: string };
|
"connecting"
|
||||||
|
| "connected"
|
||||||
|
| "disconnected"
|
||||||
|
| "unsupported-client"
|
||||||
|
| "unsupported-server";
|
||||||
|
export type TestState =
|
||||||
|
{ state: "initializing" | "running" | "stopped" | "microphone-invalid" | "unsupported" }
|
||||||
|
| { state: "start-failed", error: string };
|
||||||
|
|
||||||
export interface EchoTestEvents {
|
export interface EchoTestEvents {
|
||||||
action_troubleshooting_finished: { status: "test-again" | "aborted" }
|
action_troubleshooting_finished: { status: "test-again" | "aborted" }
|
||||||
|
|
|
@ -16,7 +16,7 @@ export const EchoTestEventRegistry = React.createContext<Registry<EchoTestEvents
|
||||||
const VoiceStateOverlay = () => {
|
const VoiceStateOverlay = () => {
|
||||||
const events = useContext(EchoTestEventRegistry);
|
const events = useContext(EchoTestEventRegistry);
|
||||||
|
|
||||||
const [ state, setState ] = useState<"loading" | VoiceConnectionState>(() => {
|
const [state, setState] = useState<"loading" | VoiceConnectionState>(() => {
|
||||||
events.fire("query_voice_connection_state");
|
events.fire("query_voice_connection_state");
|
||||||
return "loading";
|
return "loading";
|
||||||
});
|
});
|
||||||
|
@ -35,17 +35,17 @@ const VoiceStateOverlay = () => {
|
||||||
|
|
||||||
case "unsupported-client":
|
case "unsupported-client":
|
||||||
inner = <a key={state}>
|
inner = <a key={state}>
|
||||||
<Translatable>Voice connection isn't supported by your browser.</Translatable><br />
|
<Translatable>Voice connection isn't supported by your browser.</Translatable><br/>
|
||||||
<Translatable>Please use another browser.</Translatable>
|
<Translatable>Please use another browser.</Translatable>
|
||||||
</a>;
|
</a>;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "connecting":
|
case "connecting":
|
||||||
inner = <a key={state}><Translatable>establishing voice connection</Translatable> <LoadingDots /></a>;
|
inner = <a key={state}><Translatable>establishing voice connection</Translatable> <LoadingDots/></a>;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "loading":
|
case "loading":
|
||||||
inner = <a key={state}><Translatable>loading</Translatable> <LoadingDots /></a>;
|
inner = <a key={state}><Translatable>loading</Translatable> <LoadingDots/></a>;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "connected":
|
case "connected":
|
||||||
|
@ -66,12 +66,12 @@ const VoiceStateOverlay = () => {
|
||||||
const TestStateOverlay = () => {
|
const TestStateOverlay = () => {
|
||||||
const events = useContext(EchoTestEventRegistry);
|
const events = useContext(EchoTestEventRegistry);
|
||||||
|
|
||||||
const [ state, setState ] = useState<{ state: "loading" } | TestState>(() => {
|
const [state, setState] = useState<{ state: "loading" } | TestState>(() => {
|
||||||
events.fire("query_test_state");
|
events.fire("query_test_state");
|
||||||
return { state: "loading" };
|
return {state: "loading"};
|
||||||
});
|
});
|
||||||
|
|
||||||
const [ voiceConnected, setVoiceConnected ] = useState<"loading" | boolean>(() => {
|
const [voiceConnected, setVoiceConnected] = useState<"loading" | boolean>(() => {
|
||||||
return "loading";
|
return "loading";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -90,13 +90,15 @@ const TestStateOverlay = () => {
|
||||||
<VariadicTranslatable text={"Failed to start echo test:\n{0}"}>
|
<VariadicTranslatable text={"Failed to start echo test:\n{0}"}>
|
||||||
{state.error}
|
{state.error}
|
||||||
</VariadicTranslatable>
|
</VariadicTranslatable>
|
||||||
<br />
|
<br/>
|
||||||
<Button type={"small"} color={"green"} onClick={() => events.fire("action_start_test")}><Translatable>Try again</Translatable></Button>
|
<Button type={"small"} color={"green"} onClick={() => events.fire("action_start_test")}><Translatable>Try
|
||||||
|
again</Translatable></Button>
|
||||||
</a>;
|
</a>;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "unsupported":
|
case "unsupported":
|
||||||
inner = <a key={"initializing"}><Translatable>Echo testing hasn't been supported by the server.</Translatable></a>;
|
inner = <a key={"initializing"}><Translatable>Echo testing hasn't been supported by the
|
||||||
|
server.</Translatable></a>;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +112,7 @@ const TestStateOverlay = () => {
|
||||||
const TroubleshootingSoundOverlay = () => {
|
const TroubleshootingSoundOverlay = () => {
|
||||||
const events = useContext(EchoTestEventRegistry);
|
const events = useContext(EchoTestEventRegistry);
|
||||||
|
|
||||||
const [ visible, setVisible ] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
|
|
||||||
events.reactUse("notify_test_phase", event => setVisible(event.phase === "troubleshooting"));
|
events.reactUse("notify_test_phase", event => setVisible(event.phase === "troubleshooting"));
|
||||||
|
|
||||||
|
@ -118,50 +120,58 @@ const TroubleshootingSoundOverlay = () => {
|
||||||
<div className={cssStyle.overlay + " " + cssStyle.troubleshoot + " " + (visible ? cssStyle.shown : "")}>
|
<div className={cssStyle.overlay + " " + cssStyle.troubleshoot + " " + (visible ? cssStyle.shown : "")}>
|
||||||
<div className={cssStyle.top}>
|
<div className={cssStyle.top}>
|
||||||
<div className={cssStyle.containerIcon}>
|
<div className={cssStyle.containerIcon}>
|
||||||
<ClientIconRenderer icon={ClientIcon.MicrophoneBroken} className={cssStyle.icon} />
|
<ClientIconRenderer icon={ClientIcon.MicrophoneBroken} className={cssStyle.icon}/>
|
||||||
</div>
|
</div>
|
||||||
<div className={cssStyle.help}>
|
<div className={cssStyle.help}>
|
||||||
<h1><Translatable>Troubleshooting guide</Translatable></h1>
|
<h1><Translatable>Troubleshooting guide</Translatable></h1>
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
<h2><Translatable>Correct microphone selected?</Translatable>
|
<h2><Translatable>Correct microphone selected?</Translatable>
|
||||||
<Button type={"extra-small"} onClick={() => events.fire("action_open_microphone_settings")}>
|
<Button type={"extra-small"}
|
||||||
|
onClick={() => events.fire("action_open_microphone_settings")}>
|
||||||
<Translatable>Open Microphone settings</Translatable>
|
<Translatable>Open Microphone settings</Translatable>
|
||||||
</Button>
|
</Button>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<Translatable>Check within the settings, if the right microphone has been selected.</Translatable>
|
<Translatable>Check within the settings, if the right microphone has been
|
||||||
|
selected.</Translatable>
|
||||||
<Translatable>The indicators will show you any voice activity.</Translatable>
|
<Translatable>The indicators will show you any voice activity.</Translatable>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h2><Translatable>Are any addons blocking the microphone access?</Translatable></h2>
|
<h2><Translatable>Are any addons blocking the microphone access?</Translatable></h2>
|
||||||
<p>
|
<p>
|
||||||
<Translatable>Some addons might block the access to your microphone. Try to disable all addons and reload the site.</Translatable>
|
<Translatable>Some addons might block the access to your microphone. Try to disable all
|
||||||
|
addons and reload the site.</Translatable>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h2><Translatable>Has WebRTC been enabled?</Translatable></h2>
|
<h2><Translatable>Has WebRTC been enabled?</Translatable></h2>
|
||||||
<p>
|
<p>
|
||||||
<VariadicTranslatable text={"In some cases, WebRTC has been disabled. Click {0} to troubleshoot any WebRTC related issues."}>
|
<VariadicTranslatable
|
||||||
<a href={"https://test.webrtc.org"} hrefLang={"en"} target={"_blank"}><Translatable>here</Translatable></a>
|
text={"In some cases, WebRTC has been disabled. Click {0} to troubleshoot any WebRTC related issues."}>
|
||||||
|
<a href={"https://test.webrtc.org"} hrefLang={"en"}
|
||||||
|
target={"_blank"}><Translatable>here</Translatable></a>
|
||||||
</VariadicTranslatable>
|
</VariadicTranslatable>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h2><Translatable>Reload the site</Translatable></h2>
|
<h2><Translatable>Reload the site</Translatable></h2>
|
||||||
<p>
|
<p>
|
||||||
<Translatable>In some cases, reloading the site will already solve the issue for you.</Translatable>
|
<Translatable>In some cases, reloading the site will already solve the issue for
|
||||||
|
you.</Translatable>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h2><Translatable>Nothing worked? Submit an issue</Translatable></h2>
|
<h2><Translatable>Nothing worked? Submit an issue</Translatable></h2>
|
||||||
<p>
|
<p>
|
||||||
<VariadicTranslatable text={"If still nothing worked, try to seek help in our {0}."}>
|
<VariadicTranslatable text={"If still nothing worked, try to seek help in our {0}."}>
|
||||||
<a href={"https://forum.teaspeak.de"} hrefLang={"en"} target={"_blank"}><Translatable>forum</Translatable></a>
|
<a href={"https://forum.teaspeak.de"} hrefLang={"en"}
|
||||||
|
target={"_blank"}><Translatable>forum</Translatable></a>
|
||||||
</VariadicTranslatable>
|
</VariadicTranslatable>
|
||||||
<VariadicTranslatable text={"You can also create a new issue/bug report {0}."}>
|
<VariadicTranslatable text={"You can also create a new issue/bug report {0}."}>
|
||||||
<a href={"https://github.com/TeaSpeak/TeaWeb/issues"} hrefLang={"en"} target={"_blank"}><Translatable>here</Translatable></a>
|
<a href={"https://github.com/TeaSpeak/TeaWeb/issues"} hrefLang={"en"}
|
||||||
|
target={"_blank"}><Translatable>here</Translatable></a>
|
||||||
</VariadicTranslatable>
|
</VariadicTranslatable>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
@ -169,11 +179,13 @@ const TroubleshootingSoundOverlay = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={cssStyle.buttons}>
|
<div className={cssStyle.buttons}>
|
||||||
<Button type={"small"} color={"red"} onClick={() => events.fire("action_troubleshooting_finished", { status: "aborted" })}>
|
<Button type={"small"} color={"red"}
|
||||||
|
onClick={() => events.fire("action_troubleshooting_finished", {status: "aborted"})}>
|
||||||
<Translatable>Abort test</Translatable>
|
<Translatable>Abort test</Translatable>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button type={"small"} color={"green"} onClick={() => events.fire("action_troubleshooting_finished", { status: "test-again" })}>
|
<Button type={"small"} color={"green"}
|
||||||
|
onClick={() => events.fire("action_troubleshooting_finished", {status: "test-again"})}>
|
||||||
<Translatable>Test again</Translatable>
|
<Translatable>Test again</Translatable>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -184,7 +196,7 @@ const TroubleshootingSoundOverlay = () => {
|
||||||
export const TestToggle = () => {
|
export const TestToggle = () => {
|
||||||
const events = useContext(EchoTestEventRegistry);
|
const events = useContext(EchoTestEventRegistry);
|
||||||
|
|
||||||
const [ state, setState ] = useState<"loading" | boolean>(() => {
|
const [state, setState] = useState<"loading" | boolean>(() => {
|
||||||
events.fire("query_test_state");
|
events.fire("query_test_state");
|
||||||
return "loading";
|
return "loading";
|
||||||
});
|
});
|
||||||
|
@ -195,7 +207,7 @@ export const TestToggle = () => {
|
||||||
<Checkbox
|
<Checkbox
|
||||||
value={state === true}
|
value={state === true}
|
||||||
disabled={state === "loading"}
|
disabled={state === "loading"}
|
||||||
onChange={() => events.fire("action_toggle_tests", { enabled: state === false })}
|
onChange={() => events.fire("action_toggle_tests", {enabled: state === false})}
|
||||||
label={<Translatable>Show this on the next connect</Translatable>}
|
label={<Translatable>Show this on the next connect</Translatable>}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
@ -211,26 +223,29 @@ export const EchoTestModal = () => {
|
||||||
</h1>
|
</h1>
|
||||||
<div className={cssStyle.buttons}>
|
<div className={cssStyle.buttons}>
|
||||||
<div className={cssStyle.buttonContainer}>
|
<div className={cssStyle.buttonContainer}>
|
||||||
<div className={cssStyle.button + " " + cssStyle.success} title={tr("Yes")} onClick={() => events.fire("action_test_result", { status: "success" })}>
|
<div className={cssStyle.button + " " + cssStyle.success} title={tr("Yes")}
|
||||||
<ClientIconRenderer icon={ClientIcon.Apply} className={cssStyle.icon} />
|
onClick={() => events.fire("action_test_result", {status: "success"})}>
|
||||||
|
<ClientIconRenderer icon={ClientIcon.Apply} className={cssStyle.icon}/>
|
||||||
</div>
|
</div>
|
||||||
<a><Translatable>Yes</Translatable></a>
|
<a><Translatable>Yes</Translatable></a>
|
||||||
</div>
|
</div>
|
||||||
<div className={cssStyle.buttonContainer}>
|
<div className={cssStyle.buttonContainer}>
|
||||||
<div className={cssStyle.button + " " + cssStyle.fail} title={tr("No")} onClick={() => events.fire("action_test_result", { status: "fail" })}>
|
<div className={cssStyle.button + " " + cssStyle.fail} title={tr("No")}
|
||||||
<ClientIconRenderer icon={ClientIcon.Delete} className={cssStyle.icon} />
|
onClick={() => events.fire("action_test_result", {status: "fail"})}>
|
||||||
|
<ClientIconRenderer icon={ClientIcon.Delete} className={cssStyle.icon}/>
|
||||||
</div>
|
</div>
|
||||||
<a><Translatable>No</Translatable></a>
|
<a><Translatable>No</Translatable></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<VoiceStateOverlay />
|
<VoiceStateOverlay/>
|
||||||
<TestStateOverlay />
|
<TestStateOverlay/>
|
||||||
</div>
|
</div>
|
||||||
<div className={cssStyle.footer}>
|
<div className={cssStyle.footer}>
|
||||||
<TestToggle />
|
<TestToggle/>
|
||||||
<Button color={"red"} type={"small"} onClick={() => events.fire("action_close")}><Translatable>Close</Translatable></Button>
|
<Button color={"red"} type={"small"}
|
||||||
|
onClick={() => events.fire("action_close")}><Translatable>Close</Translatable></Button>
|
||||||
</div>
|
</div>
|
||||||
<TroubleshootingSoundOverlay />
|
<TroubleshootingSoundOverlay/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue