Starting with webpack
parent
a6f0fcdda9
commit
13b65a1f35
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
|
@ -17,29 +17,41 @@
|
|||
"csso": "csso",
|
||||
"rebuild-structure-web-dev": "php files.php generate web dev",
|
||||
"minify-web-rel-file": "terser --compress --mangle --ecma 6 --keep_classnames --keep_fnames --output",
|
||||
"start": "npm run compile-file-helper && node file.js ndevelop"
|
||||
"start": "npm run compile-file-helper && node file.js ndevelop",
|
||||
"build": "webpack --config webpack.config.js",
|
||||
"watch": "webpack --watch"
|
||||
},
|
||||
"author": "TeaSpeak (WolverinDEV)",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/emscripten": "^1.38.0",
|
||||
"@types/jquery": "^3.3.31",
|
||||
"@types/jquery": "^3.3.34",
|
||||
"@types/lodash": "^4.14.149",
|
||||
"@types/moment": "^2.13.0",
|
||||
"@types/node": "^12.7.2",
|
||||
"@types/react-dom": "^16.9.5",
|
||||
"@types/sha256": "^0.2.0",
|
||||
"@types/websocket": "0.0.40",
|
||||
"clean-css": "^4.2.1",
|
||||
"css-loader": "^3.4.2",
|
||||
"csso-cli": "^2.0.2",
|
||||
"fs-extra": "latest",
|
||||
"gulp": "^4.0.2",
|
||||
"mime-types": "^2.1.24",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"node-sass": "^4.13.1",
|
||||
"sass": "1.22.10",
|
||||
"sass-loader": "^8.0.2",
|
||||
"sha256": "^0.2.0",
|
||||
"style-loader": "^1.1.3",
|
||||
"terser": "^4.2.1",
|
||||
"ts-loader": "^6.2.2",
|
||||
"ttypescript": "^1.5.10",
|
||||
"typescript": "3.6.5",
|
||||
"wat2wasm": "^1.0.2",
|
||||
"fs-extra": "latest"
|
||||
"webpack": "^4.42.1",
|
||||
"webpack-cli": "^3.3.11"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -50,6 +62,8 @@
|
|||
},
|
||||
"homepage": "https://www.teaspeak.de",
|
||||
"dependencies": {
|
||||
"@types/fs-extra": "^8.0.1"
|
||||
"@types/fs-extra": "^8.0.1",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,96 +94,7 @@
|
|||
}
|
||||
|
||||
&.channel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.container-channel {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
|
||||
width: 100%;
|
||||
min-height: 16px;
|
||||
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
.channel-type {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.container-channel-name {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
|
||||
justify-content: left;
|
||||
|
||||
max-width: 100%; /* important for the repetitive channel name! */
|
||||
overflow-x: hidden;
|
||||
height: 16px;
|
||||
|
||||
&.align-right {
|
||||
justify-content: right;
|
||||
}
|
||||
|
||||
&.align-center, &.align-repetitive {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.channel-name {
|
||||
align-self: center;
|
||||
color: $channel_tree_entry_text_color;
|
||||
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&.align-repetitive {
|
||||
.channel-name {
|
||||
text-overflow: clip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&.move-selected {
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
.show-channel-normal-only {
|
||||
display: none;
|
||||
|
||||
&.channel-normal {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.icon_no_sound {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.container-clients {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
&.client {
|
||||
|
@ -272,40 +183,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.channel .container-channel, &.client, &.server {
|
||||
.marker-text-unread {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
width: 1px;
|
||||
background-color: #a814147F;
|
||||
|
||||
opacity: 1;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
width: 24px;
|
||||
|
||||
background: -moz-linear-gradient(left, rgba(168,20,20,.18) 0%, rgba(168,20,20,0) 100%); /* FF3.6-15 */
|
||||
background: -webkit-linear-gradient(left, rgba(168,20,20,.18) 0%,rgba(168,20,20,0) 100%); /* Chrome10-25,Safari5.1-6 */
|
||||
background: linear-gradient(to right, rgba(168,20,20,.18) 0%,rgba(168,20,20,0) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@include transition(opacity $button_hover_animation_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
interface Window {
|
||||
export interface Window {
|
||||
BroadcastChannel: BroadcastChannel;
|
||||
}
|
||||
|
||||
namespace bipc {
|
||||
export namespace bipc {
|
||||
export interface BroadcastMessage {
|
||||
timestamp: number;
|
||||
receiver: string;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/// <reference path="log.ts" />
|
||||
/// <reference path="proto.ts" />
|
||||
/// <reference path="ui/view.ts" />
|
||||
/// <reference path="channel-tree/view.ts" />
|
||||
/// <reference path="settings.ts" />
|
||||
/// <reference path="FileManager.ts" />
|
||||
/// <reference path="permission/PermissionManager.ts" />
|
||||
|
@ -8,7 +8,17 @@
|
|||
/// <reference path="ui/frames/ControlBar.ts" />
|
||||
/// <reference path="connection/ConnectionBase.ts" />
|
||||
|
||||
enum DisconnectReason {
|
||||
import {ChannelTree} from "./channel-tree/view";
|
||||
import {LocalClientEntry} from "./channel-tree/client";
|
||||
import {ServerAddress} from "./channel-tree/server";
|
||||
import {ChannelEntry} from "./channel-tree/channel";
|
||||
import {AbstractServerConnection} from "./connection/ConnectionBase";
|
||||
import {PermissionManager} from "./permission/PermissionManager";
|
||||
import {GroupManager} from "./permission/GroupManager";
|
||||
import {ServerSettings} from "./settings";
|
||||
import {Hostbanner} from "./ui/frames/hostbanner";
|
||||
|
||||
export enum DisconnectReason {
|
||||
HANDLER_DESTROYED,
|
||||
REQUESTED,
|
||||
DNS_FAILED,
|
||||
|
@ -28,7 +38,7 @@ enum DisconnectReason {
|
|||
UNKNOWN
|
||||
}
|
||||
|
||||
enum ConnectionState {
|
||||
export enum ConnectionState {
|
||||
UNCONNECTED,
|
||||
CONNECTING,
|
||||
INITIALISING,
|
||||
|
@ -36,7 +46,7 @@ enum ConnectionState {
|
|||
DISCONNECTING
|
||||
}
|
||||
|
||||
enum ViewReasonId {
|
||||
export enum ViewReasonId {
|
||||
VREASON_USER_ACTION = 0,
|
||||
VREASON_MOVED = 1,
|
||||
VREASON_SYSTEM = 2,
|
||||
|
@ -51,7 +61,7 @@ enum ViewReasonId {
|
|||
VREASON_SERVER_SHUTDOWN = 11
|
||||
}
|
||||
|
||||
interface VoiceStatus {
|
||||
export interface VoiceStatus {
|
||||
input_hardware: boolean;
|
||||
input_muted: boolean;
|
||||
output_muted: boolean;
|
||||
|
@ -68,7 +78,7 @@ interface VoiceStatus {
|
|||
queries_visible: boolean;
|
||||
}
|
||||
|
||||
interface ConnectParameters {
|
||||
export interface ConnectParameters {
|
||||
nickname?: string;
|
||||
channel?: {
|
||||
target: string | number;
|
||||
|
@ -79,10 +89,10 @@ interface ConnectParameters {
|
|||
auto_reconnect_attempt?: boolean;
|
||||
}
|
||||
|
||||
class ConnectionHandler {
|
||||
export class ConnectionHandler {
|
||||
channelTree: ChannelTree;
|
||||
|
||||
serverConnection: connection.AbstractServerConnection;
|
||||
serverConnection: AbstractServerConnection;
|
||||
|
||||
fileManager: FileManager;
|
||||
|
||||
|
|
|
@ -1,21 +1,26 @@
|
|||
/// <reference path="connection/CommandHandler.ts" />
|
||||
/// <reference path="connection/ConnectionBase.ts" />
|
||||
import {ChannelEntry} from "./channel-tree/channel";
|
||||
import {AbstractCommandHandler, ServerCommand} from "./connection/ConnectionBase";
|
||||
import {ConnectionHandler} from "./ConnectionHandler";
|
||||
import {CommandResult} from "./connection/ServerConnectionDeclaration";
|
||||
import {log, LogCategory} from "./log";
|
||||
import {ClientEntry} from "./channel-tree/client";
|
||||
import {hex} from "./crypto/hex";
|
||||
|
||||
class FileEntry {
|
||||
export class FileEntry {
|
||||
name: string;
|
||||
datetime: number;
|
||||
type: number;
|
||||
size: number;
|
||||
}
|
||||
|
||||
class FileListRequest {
|
||||
export class FileListRequest {
|
||||
path: string;
|
||||
entries: FileEntry[];
|
||||
|
||||
callback: (entries: FileEntry[]) => void;
|
||||
}
|
||||
|
||||
namespace transfer {
|
||||
export namespace transfer {
|
||||
export interface TransferKey {
|
||||
client_transfer_id: number;
|
||||
server_transfer_id: number;
|
||||
|
@ -152,7 +157,7 @@ class RequestFileUpload implements transfer.UploadTransfer {
|
|||
}
|
||||
}
|
||||
|
||||
class FileManager extends connection.AbstractCommandHandler {
|
||||
class FileManager extends AbstractCommandHandler {
|
||||
handle: ConnectionHandler;
|
||||
icons: IconManager;
|
||||
avatars: AvatarManager;
|
||||
|
@ -191,7 +196,7 @@ class FileManager extends connection.AbstractCommandHandler {
|
|||
this.avatars = undefined;
|
||||
}
|
||||
|
||||
handle_command(command: connection.ServerCommand): boolean {
|
||||
handle_command(command: ServerCommand): boolean {
|
||||
switch (command.command) {
|
||||
case "notifyfilelist":
|
||||
this.notifyFileList(command.arguments);
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
namespace messages.formatter {
|
||||
import {Settings, settings} from "./settings";
|
||||
import {contextmenu} from "./ui/elements/context_menu";
|
||||
import {image_preview} from "./ui/frames/image_preview";
|
||||
import {guid} from "./crypto/uid";
|
||||
|
||||
declare const xbbcode;
|
||||
export namespace messages.formatter {
|
||||
export namespace bbcode {
|
||||
const sanitizer_escaped = (key: string) => "[-- sescaped: " + key + " --]";
|
||||
const sanitizer_escaped_regex = /\[-- sescaped: ([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}) --]/;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
enum KeyCode {
|
||||
export enum KeyCode {
|
||||
KEY_CANCEL = 3,
|
||||
KEY_HELP = 6,
|
||||
KEY_BACK_SPACE = 8,
|
||||
|
@ -118,7 +118,7 @@ enum KeyCode {
|
|||
KEY_META = 224
|
||||
}
|
||||
|
||||
namespace ppt {
|
||||
export namespace ppt {
|
||||
export enum EventType {
|
||||
KEY_PRESS,
|
||||
KEY_RELEASE,
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
namespace bookmarks {
|
||||
function guid() {
|
||||
function s4() {
|
||||
return Math
|
||||
.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1);
|
||||
}
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
|
||||
}
|
||||
import {profiles} from "./profiles/ConnectionProfile";
|
||||
|
||||
export namespace bookmarks {
|
||||
export const boorkmak_connect = (mark: Bookmark, new_tab?: boolean) => {
|
||||
const profile = profiles.find_profile(mark.connect_profile) || profiles.default_profile();
|
||||
if(profile.valid()) {
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
/// <reference path="view.ts" />
|
||||
/// <reference path="../utils/helpers.ts" />
|
||||
|
||||
enum ChannelType {
|
||||
import {ChannelTree} from "./view";
|
||||
import {ClientEntry} from "./client";
|
||||
|
||||
export enum ChannelType {
|
||||
PERMANENT,
|
||||
SEMI_PERMANENT,
|
||||
TEMPORARY
|
||||
}
|
||||
namespace ChannelType {
|
||||
export namespace ChannelType {
|
||||
export function normalize(mode: ChannelType) {
|
||||
let value: string = ChannelType[mode];
|
||||
value = value.toLowerCase();
|
||||
|
@ -14,13 +17,13 @@ namespace ChannelType {
|
|||
}
|
||||
}
|
||||
|
||||
enum ChannelSubscribeMode {
|
||||
export enum ChannelSubscribeMode {
|
||||
SUBSCRIBED,
|
||||
UNSUBSCRIBED,
|
||||
INHERITED
|
||||
}
|
||||
|
||||
class ChannelProperties {
|
||||
export class ChannelProperties {
|
||||
channel_order: number = 0;
|
||||
channel_name: string = "";
|
||||
channel_name_phonetic: string = "";
|
||||
|
@ -55,7 +58,7 @@ class ChannelProperties {
|
|||
channel_conversation_history_length: number = -1;
|
||||
}
|
||||
|
||||
class ChannelEntry {
|
||||
export class ChannelEntry {
|
||||
channelTree: ChannelTree;
|
||||
channelId: number;
|
||||
parent?: ChannelEntry;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
/// <reference path="channel.ts" />
|
||||
/// <reference path="modal/ModalChangeVolume.ts" />
|
||||
/// <reference path="client_move.ts" />
|
||||
/// <reference path="../ui/modal/ModalChangeVolume.ts" />
|
||||
/// <reference path="../ui/client_move.ts" />
|
||||
|
||||
enum ClientType {
|
||||
import {ChannelEntry} from "./channel";
|
||||
import {ChannelTree} from "./view";
|
||||
|
||||
export enum ClientType {
|
||||
CLIENT_VOICE,
|
||||
CLIENT_QUERY,
|
||||
CLIENT_INTERNAL,
|
||||
|
@ -11,7 +14,7 @@ enum ClientType {
|
|||
CLIENT_UNDEFINED
|
||||
}
|
||||
|
||||
class ClientProperties {
|
||||
export class ClientProperties {
|
||||
client_type: ClientType = ClientType.CLIENT_VOICE; //TeamSpeaks type
|
||||
client_type_exact: ClientType = ClientType.CLIENT_VOICE;
|
||||
|
||||
|
@ -57,7 +60,7 @@ class ClientProperties {
|
|||
client_is_priority_speaker: boolean = false;
|
||||
}
|
||||
|
||||
class ClientConnectionInfo {
|
||||
export class ClientConnectionInfo {
|
||||
connection_bandwidth_received_last_minute_control: number = -1;
|
||||
connection_bandwidth_received_last_minute_keepalive: number = -1;
|
||||
connection_bandwidth_received_last_minute_speech: number = -1;
|
||||
|
@ -109,7 +112,7 @@ class ClientConnectionInfo {
|
|||
connection_client_port: number = -1;
|
||||
}
|
||||
|
||||
class ClientEntry {
|
||||
export class ClientEntry {
|
||||
readonly events: events.Registry<events.channel_tree.client>;
|
||||
|
||||
protected _clientId: number;
|
||||
|
@ -1123,7 +1126,7 @@ class ClientEntry {
|
|||
}
|
||||
}
|
||||
|
||||
class LocalClientEntry extends ClientEntry {
|
||||
export class LocalClientEntry extends ClientEntry {
|
||||
handle: ConnectionHandler;
|
||||
|
||||
private renaming: boolean;
|
||||
|
@ -1232,7 +1235,7 @@ class LocalClientEntry extends ClientEntry {
|
|||
}
|
||||
}
|
||||
|
||||
class MusicClientProperties extends ClientProperties {
|
||||
export class MusicClientProperties extends ClientProperties {
|
||||
player_state: number = 0;
|
||||
player_volume: number = 0;
|
||||
|
||||
|
@ -1264,7 +1267,7 @@ class MusicClientProperties extends ClientProperties {
|
|||
}
|
||||
*/
|
||||
|
||||
class SongInfo {
|
||||
export class SongInfo {
|
||||
song_id: number = 0;
|
||||
song_url: string = "";
|
||||
song_invoker: number = 0;
|
||||
|
@ -1277,7 +1280,7 @@ class SongInfo {
|
|||
song_length: number = 0;
|
||||
}
|
||||
|
||||
class MusicClientPlayerInfo extends SongInfo {
|
||||
export class MusicClientPlayerInfo extends SongInfo {
|
||||
bot_id: number = 0;
|
||||
player_state: number = 0;
|
||||
|
||||
|
@ -1290,7 +1293,7 @@ class MusicClientPlayerInfo extends SongInfo {
|
|||
player_description: string = "";
|
||||
}
|
||||
|
||||
class MusicClientEntry extends ClientEntry {
|
||||
export class MusicClientEntry extends ClientEntry {
|
||||
private _info_promise: Promise<MusicClientPlayerInfo>;
|
||||
private _info_promise_age: number = 0;
|
||||
private _info_promise_resolve: any;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/// <reference path="channel.ts" />
|
||||
/// <reference path="modal/ModalServerEdit.ts" />
|
||||
/// <reference path="../ui/modal/ModalServerEdit.ts" />
|
||||
|
||||
class ServerProperties {
|
||||
import {ChannelTree} from "./view";
|
||||
|
||||
export class ServerProperties {
|
||||
virtualserver_host: string = "";
|
||||
virtualserver_port: number = 0;
|
||||
|
||||
|
@ -78,7 +80,7 @@ class ServerProperties {
|
|||
virtualserver_total_bytes_uploaded: number = 0;
|
||||
}
|
||||
|
||||
interface ServerConnectionInfo {
|
||||
export interface ServerConnectionInfo {
|
||||
connection_filetransfer_bandwidth_sent: number;
|
||||
connection_filetransfer_bandwidth_received: number;
|
||||
|
||||
|
@ -103,12 +105,12 @@ interface ServerConnectionInfo {
|
|||
connection_ping: number;
|
||||
}
|
||||
|
||||
interface ServerAddress {
|
||||
export interface ServerAddress {
|
||||
host: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
class ServerEntry {
|
||||
export class ServerEntry {
|
||||
remote_address: ServerAddress;
|
||||
channelTree: ChannelTree;
|
||||
properties: ServerProperties;
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
/// <reference path="client.ts" />
|
||||
/// <reference path="server.ts" />
|
||||
/// <reference path="../bookmarks.ts" />
|
||||
/// <reference path="elements/context_menu.ts" />
|
||||
/// <reference path="modal/ModalCreateChannel.ts" />
|
||||
/// <reference path="../ui/elements/context_menu.ts" />
|
||||
/// <reference path="../ui/modal/ModalCreateChannel.ts" />
|
||||
/// <reference path="../../backend/ppt.d.ts" />
|
||||
|
||||
|
||||
class ChannelTree {
|
||||
export class ChannelTree {
|
||||
client: ConnectionHandler;
|
||||
server: ServerEntry;
|
||||
|
||||
|
|
|
@ -1,8 +1,29 @@
|
|||
/// <reference path="ConnectionBase.ts" />
|
||||
|
||||
namespace connection {
|
||||
import {ConnectionHandler, DisconnectReason, ViewReasonId} from "../ConnectionHandler";
|
||||
import {
|
||||
AbstractCommandHandler,
|
||||
AbstractCommandHandlerBoss,
|
||||
AbstractServerConnection,
|
||||
CommandOptions, ServerCommand
|
||||
} from "./ConnectionBase";
|
||||
import {CommandResult, ErrorID} from "./ServerConnectionDeclaration";
|
||||
import {Sound} from "../sound/Sounds";
|
||||
import {log, LogCategory} from "../log";
|
||||
import {MessageHelper} from "../ui/frames/chat";
|
||||
import {
|
||||
ClientConnectionInfo,
|
||||
ClientEntry,
|
||||
ClientType,
|
||||
LocalClientEntry,
|
||||
MusicClientEntry, SongInfo
|
||||
} from "../channel-tree/client";
|
||||
import {ChannelEntry} from "../channel-tree/channel";
|
||||
import {chat as pchat} from "../ui/frames/side/private_conversations";
|
||||
import {Modals} from "../ui/modal/ModalPoke";
|
||||
import {chat} from "../ui/frames/side/conversations";
|
||||
import Conversation = chat.channel.Conversation;
|
||||
import MusicInfo = chat.MusicInfo;
|
||||
import {createErrorModal, createInfoModal, createInputModal, createModal} from "../ui/elements/modal";
|
||||
import {server_connections} from "../ui/frames/connection_handlers";
|
||||
import {server} from "../ui/frames/server_log";
|
||||
|
||||
export class ServerConnectionCommandBoss extends AbstractCommandHandlerBoss {
|
||||
constructor(connection: AbstractServerConnection) {
|
||||
|
@ -65,7 +86,7 @@ namespace connection {
|
|||
this["notifyplaylistsongloaded"] = this.handleNotifyPlaylistSongLoaded;
|
||||
}
|
||||
|
||||
private loggable_invoker(unique_id, client_id, name) : log.server.base.Client | undefined {
|
||||
private loggable_invoker(unique_id, client_id, name) : server.base.Client | undefined {
|
||||
const id = parseInt(client_id);
|
||||
if(typeof(client_id) === "undefined" || Number.isNaN(id))
|
||||
return undefined;
|
||||
|
@ -84,7 +105,7 @@ namespace connection {
|
|||
};
|
||||
}
|
||||
|
||||
proxy_command_promise(promise: Promise<CommandResult>, options: connection.CommandOptions) {
|
||||
proxy_command_promise(promise: Promise<CommandResult>, options: CommandOptions) {
|
||||
if(!options.process_result)
|
||||
return promise;
|
||||
|
||||
|
@ -96,18 +117,18 @@ namespace connection {
|
|||
if(res.id == ErrorID.PERMISSION_ERROR) { //Permission error
|
||||
const permission = this.connection_handler.permissions.resolveInfo(res.json["failed_permid"] as number);
|
||||
res.message = tr("Insufficient client permissions. Failed on permission ") + (permission ? permission.name : "unknown");
|
||||
this.connection_handler.log.log(log.server.Type.ERROR_PERMISSION, {
|
||||
this.connection_handler.log.log(server.Type.ERROR_PERMISSION, {
|
||||
permission: this.connection_handler.permissions.resolveInfo(res.json["failed_permid"] as number)
|
||||
});
|
||||
this.connection_handler.sound.play(Sound.ERROR_INSUFFICIENT_PERMISSIONS);
|
||||
} else if(res.id != ErrorID.EMPTY_RESULT) {
|
||||
this.connection_handler.log.log(log.server.Type.ERROR_CUSTOM, {
|
||||
this.connection_handler.log.log(server.Type.ERROR_CUSTOM, {
|
||||
message: res.extra_message.length == 0 ? res.message : res.extra_message
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if(typeof(ex) === "string") {
|
||||
this.connection_handler.log.log(log.server.Type.CONNECTION_COMMAND_ERROR, {error: ex});
|
||||
this.connection_handler.log.log(server.Type.CONNECTION_COMMAND_ERROR, {error: ex});
|
||||
} else {
|
||||
log.error(LogCategory.NETWORKING, tr("Invalid promise result type: %s. Result: %o"), typeof (ex), ex);
|
||||
}
|
||||
|
@ -190,7 +211,7 @@ namespace connection {
|
|||
if(properties.virtualserver_hostmessage_mode > 0) {
|
||||
if(properties.virtualserver_hostmessage_mode == 1) {
|
||||
/* show in log */
|
||||
this.connection_handler.log.log(log.server.Type.SERVER_HOST_MESSAGE, {
|
||||
this.connection_handler.log.log(server.Type.SERVER_HOST_MESSAGE, {
|
||||
message: properties.virtualserver_hostmessage
|
||||
});
|
||||
} else {
|
||||
|
@ -204,7 +225,7 @@ namespace connection {
|
|||
if(properties.virtualserver_hostmessage_mode == 3) {
|
||||
/* first let the client initialize his stuff */
|
||||
setTimeout(() => {
|
||||
this.connection_handler.log.log(log.server.Type.SERVER_HOST_MESSAGE_DISCONNECT, {
|
||||
this.connection_handler.log.log(server.Type.SERVER_HOST_MESSAGE_DISCONNECT, {
|
||||
message: properties.virtualserver_welcomemessage
|
||||
});
|
||||
|
||||
|
@ -218,7 +239,7 @@ namespace connection {
|
|||
|
||||
/* welcome message */
|
||||
if(properties.virtualserver_welcomemessage) {
|
||||
this.connection_handler.log.log(log.server.Type.SERVER_WELCOME_MESSAGE, {
|
||||
this.connection_handler.log.log(server.Type.SERVER_WELCOME_MESSAGE, {
|
||||
message: properties.virtualserver_welcomemessage
|
||||
});
|
||||
}
|
||||
|
@ -240,7 +261,7 @@ namespace connection {
|
|||
}, { field_placeholder: 'Enter Privilege Key' }).open();
|
||||
}
|
||||
|
||||
this.connection_handler.log.log(log.server.Type.CONNECTION_CONNECTED, {
|
||||
this.connection_handler.log.log(server.Type.CONNECTION_CONNECTED, {
|
||||
own_client: this.connection_handler.getClient().log_data()
|
||||
});
|
||||
this.connection_handler.sound.play(Sound.CONNECTION_CONNECTED);
|
||||
|
@ -414,7 +435,7 @@ namespace connection {
|
|||
|
||||
if(this.connection_handler.client_status.queries_visible || client.properties.client_type != ClientType.CLIENT_QUERY) {
|
||||
const own_channel = this.connection.client.getClient().currentChannel();
|
||||
this.connection_handler.log.log(log.server.Type.CLIENT_VIEW_ENTER, {
|
||||
this.connection_handler.log.log(server.Type.CLIENT_VIEW_ENTER, {
|
||||
channel_from: old_channel ? old_channel.log_data() : undefined,
|
||||
channel_to: channel ? channel.log_data() : undefined,
|
||||
client: client.log_data(),
|
||||
|
@ -521,7 +542,7 @@ namespace connection {
|
|||
let channel_to = tree.findChannel(entry["ctid"]);
|
||||
|
||||
const is_own_channel = channel_from == own_channel;
|
||||
this.connection_handler.log.log(log.server.Type.CLIENT_VIEW_LEAVE, {
|
||||
this.connection_handler.log.log(server.Type.CLIENT_VIEW_LEAVE, {
|
||||
channel_from: channel_from ? channel_from.log_data() : undefined,
|
||||
channel_to: channel_to ? channel_to.log_data() : undefined,
|
||||
client: client.log_data(),
|
||||
|
@ -564,7 +585,7 @@ namespace connection {
|
|||
attach: false
|
||||
});
|
||||
if(conversation) {
|
||||
conversation.set_state(chat.PrivateConversationState.DISCONNECTED);
|
||||
conversation.set_state(pchat.PrivateConversationState.DISCONNECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -635,7 +656,7 @@ namespace connection {
|
|||
}
|
||||
|
||||
const own_channel = this.connection.client.getClient().currentChannel();
|
||||
this.connection_handler.log.log(log.server.Type.CLIENT_VIEW_MOVE, {
|
||||
this.connection_handler.log.log(server.Type.CLIENT_VIEW_MOVE, {
|
||||
channel_from: channel_from ? {
|
||||
channel_id: channel_from.channelId,
|
||||
channel_name: channel_from.channelName()
|
||||
|
@ -750,7 +771,7 @@ namespace connection {
|
|||
const target_own = target_client_id === this.connection.client.getClientId();
|
||||
|
||||
if(target_own && target_client_id === json["invokerid"]) {
|
||||
log.error(LogCategory.NETWORKING, tr("Received conversation message from invalid client id. Data: %o", json));
|
||||
log.error(LogCategory.NETWORKING, tr("Received conversation message from invalid client id. Data: %o"), json);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -808,7 +829,7 @@ namespace connection {
|
|||
if(conversation.is_unread() && channel)
|
||||
channel.flag_text_unread = true;
|
||||
} else if(mode == 3) {
|
||||
this.connection_handler.log.log(log.server.Type.GLOBAL_MESSAGE, {
|
||||
this.connection_handler.log.log(server.Type.GLOBAL_MESSAGE, {
|
||||
message: json["msg"],
|
||||
sender: {
|
||||
client_unique_id: json["invokeruid"],
|
||||
|
@ -871,7 +892,7 @@ namespace connection {
|
|||
log.warn(LogCategory.GENERAL, tr("Received chat close for client, but we haven't a chat open."));
|
||||
return;
|
||||
}
|
||||
conversation.set_state(chat.PrivateConversationState.CLOSED);
|
||||
conversation.set_state(pchat.PrivateConversationState.CLOSED);
|
||||
}
|
||||
|
||||
handleNotifyClientUpdated(json) {
|
||||
|
@ -1157,4 +1178,3 @@ namespace connection {
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,17 @@
|
|||
namespace connection {
|
||||
import {
|
||||
ClientNameInfo,
|
||||
CommandResult,
|
||||
ErrorID,
|
||||
Playlist, PlaylistInfo, PlaylistSong,
|
||||
QueryList,
|
||||
QueryListEntry, ServerGroupClient
|
||||
} from "./ServerConnectionDeclaration";
|
||||
import {ChannelEntry} from "../channel-tree/channel";
|
||||
import {ChatType} from "../ui/frames/chat";
|
||||
import {ClientEntry} from "../channel-tree/client";
|
||||
import {AbstractCommandHandler, ServerCommand, SingleCommandHandler} from "./ConnectionBase";
|
||||
import {log, LogCategory} from "../log";
|
||||
|
||||
export class CommandHelper extends AbstractCommandHandler {
|
||||
private _who_am_i: any;
|
||||
private _awaiters_unique_ids: {[unique_id: string]:((resolved: ClientNameInfo) => any)[]} = {};
|
||||
|
@ -23,7 +36,7 @@ namespace connection {
|
|||
this._awaiters_unique_ids = undefined;
|
||||
}
|
||||
|
||||
handle_command(command: connection.ServerCommand): boolean {
|
||||
handle_command(command: ServerCommand): boolean {
|
||||
if(command.command == "notifyclientnamefromuid")
|
||||
this.handle_notifyclientnamefromuid(command.arguments);
|
||||
if(command.command == "notifyclientgetnamefromdbid")
|
||||
|
@ -445,4 +458,3 @@ namespace connection {
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,11 @@
|
|||
namespace connection {
|
||||
import {ConnectionHandler, ConnectionState} from "../ConnectionHandler";
|
||||
import {ServerAddress} from "../channel-tree/server";
|
||||
import {CommandResult} from "./ServerConnectionDeclaration";
|
||||
import {RecorderProfile} from "../voice/RecorderProfile";
|
||||
import {CommandHelper} from "./CommandHelper";
|
||||
import {connection} from "./HandshakeHandler";
|
||||
import HandshakeHandler = connection.HandshakeHandler;
|
||||
|
||||
export interface CommandOptions {
|
||||
flagset?: string[]; /* default: [] */
|
||||
process_result?: boolean; /* default: true */
|
||||
|
@ -213,4 +220,3 @@ namespace connection {
|
|||
return flag_consumed;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,15 @@
|
|||
namespace connection {
|
||||
import {AbstractServerConnection} from "./ConnectionBase";
|
||||
import {ConnectParameters, DisconnectReason} from "../ConnectionHandler";
|
||||
import {profiles} from "../profiles/ConnectionProfile";
|
||||
import {profiles as iprofiles} from "../profiles/Identity";
|
||||
import {profiles as tiprofiles} from "../profiles/identities/TeamSpeakIdentity";
|
||||
import {native_client} from "../main";
|
||||
import {settings} from "../settings";
|
||||
import {CommandResult} from "./ServerConnectionDeclaration";
|
||||
|
||||
export namespace connection {
|
||||
import identities = iprofiles.identities;
|
||||
|
||||
export interface HandshakeIdentityHandler {
|
||||
connection: AbstractServerConnection;
|
||||
|
||||
|
@ -48,7 +59,7 @@ namespace connection {
|
|||
|
||||
on_teamspeak() {
|
||||
const type = this.profile.selected_type();
|
||||
if(type == profiles.identities.IdentitifyType.TEAMSPEAK)
|
||||
if(type == identities.IdentitifyType.TEAMSPEAK)
|
||||
this.handshake_finished();
|
||||
else {
|
||||
|
||||
|
@ -122,8 +133,8 @@ namespace connection {
|
|||
}
|
||||
|
||||
/* required to keep compatibility */
|
||||
if(this.profile.selected_type() === profiles.identities.IdentitifyType.TEAMSPEAK) {
|
||||
data["client_key_offset"] = (this.profile.selected_identity() as profiles.identities.TeaSpeakIdentity).hash_number;
|
||||
if(this.profile.selected_type() === identities.IdentitifyType.TEAMSPEAK) {
|
||||
data["client_key_offset"] = (this.profile.selected_identity() as tiprofiles.identities.TeaSpeakIdentity).hash_number;
|
||||
}
|
||||
|
||||
this.connection.send_command("clientinit", data).catch(error => {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
enum ErrorID {
|
||||
import {LaterPromise} from "../utils/helpers";
|
||||
|
||||
export enum ErrorID {
|
||||
NOT_IMPLEMENTED = 0x2,
|
||||
COMMAND_NOT_FOUND = 0x100,
|
||||
|
||||
|
@ -15,7 +17,7 @@ enum ErrorID {
|
|||
CONVERSATION_IS_PRIVATE = 0x2202
|
||||
}
|
||||
|
||||
class CommandResult {
|
||||
export class CommandResult {
|
||||
success: boolean;
|
||||
id: number;
|
||||
message: string;
|
||||
|
@ -35,39 +37,39 @@ class CommandResult {
|
|||
}
|
||||
}
|
||||
|
||||
interface ClientNameInfo {
|
||||
export interface ClientNameInfo {
|
||||
//cluid=tYzKUryn\/\/Y8VBMf8PHUT6B1eiE= name=Exp clname=Exp cldbid=9
|
||||
client_unique_id: string;
|
||||
client_nickname: string;
|
||||
client_database_id: number;
|
||||
}
|
||||
|
||||
interface ClientNameFromUid {
|
||||
export interface ClientNameFromUid {
|
||||
promise: LaterPromise<ClientNameInfo[]>,
|
||||
keys: string[],
|
||||
response: ClientNameInfo[]
|
||||
}
|
||||
|
||||
interface ServerGroupClient {
|
||||
export interface ServerGroupClient {
|
||||
client_nickname: string;
|
||||
client_unique_identifier: string;
|
||||
client_database_id: number;
|
||||
}
|
||||
|
||||
interface QueryListEntry {
|
||||
export interface QueryListEntry {
|
||||
username: string;
|
||||
unique_id: string;
|
||||
bounded_server: number;
|
||||
}
|
||||
|
||||
interface QueryList {
|
||||
export interface QueryList {
|
||||
flag_own: boolean;
|
||||
flag_all: boolean;
|
||||
|
||||
queries: QueryListEntry[];
|
||||
}
|
||||
|
||||
interface Playlist {
|
||||
export interface Playlist {
|
||||
playlist_id: number;
|
||||
playlist_bot_id: number;
|
||||
playlist_title: string;
|
||||
|
@ -83,7 +85,7 @@ interface Playlist {
|
|||
needed_power_song_remove: number;
|
||||
}
|
||||
|
||||
interface PlaylistInfo {
|
||||
export interface PlaylistInfo {
|
||||
playlist_id: number,
|
||||
playlist_title: string,
|
||||
playlist_description: string,
|
||||
|
@ -100,7 +102,7 @@ interface PlaylistInfo {
|
|||
playlist_max_songs: number
|
||||
}
|
||||
|
||||
interface PlaylistSong {
|
||||
export interface PlaylistSong {
|
||||
song_id: number;
|
||||
song_previous_song_id: number;
|
||||
song_invoker: string;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
namespace asn1 {
|
||||
export namespace asn1 {
|
||||
declare class Int10 {
|
||||
constructor(value?: any);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class Crc32 {
|
||||
export class Crc32 {
|
||||
private static readonly lookup = [
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
||||
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace hex {
|
||||
export namespace hex {
|
||||
export function encode(buffer) {
|
||||
let hexCodes = [];
|
||||
let view = new DataView(buffer);
|
||||
|
|
|
@ -10,7 +10,7 @@ interface Window {
|
|||
}
|
||||
*/
|
||||
|
||||
namespace sha {
|
||||
export namespace sha {
|
||||
/*
|
||||
* [js-sha1]{@link https://github.com/emn178/js-sha1}
|
||||
*
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
export function guid() {
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1);
|
||||
}
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace dns {
|
||||
export namespace dns {
|
||||
export interface AddressTarget {
|
||||
target_ip: string;
|
||||
target_port?: number;
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
namespace events {
|
||||
import {guid} from "./crypto/uid";
|
||||
import {PlaylistSong} from "./connection/ServerConnectionDeclaration";
|
||||
import {MusicClientEntry, SongInfo} from "./channel-tree/client";
|
||||
|
||||
export namespace events {
|
||||
export interface EventConvert<All> {
|
||||
as<T extends keyof All>() : All[T];
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
namespace i18n {
|
||||
export namespace i18n {
|
||||
interface CountryInfo {
|
||||
name: string;
|
||||
alpha_2: string;
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
function guid() {
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1);
|
||||
}
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
|
||||
}
|
||||
import {guid} from "../crypto/uid";
|
||||
import {log, LogCategory} from "../log";
|
||||
import {MessageHelper} from "../ui/frames/chat";
|
||||
import {StaticSettings} from "../settings";
|
||||
import {createErrorModal} from "../ui/elements/modal";
|
||||
|
||||
namespace i18n {
|
||||
export namespace i18n {
|
||||
export interface TranslationKey {
|
||||
message: string;
|
||||
line?: number;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
//Used by CertAccept popup
|
||||
|
||||
enum LogCategory {
|
||||
import {settings} from "./settings";
|
||||
|
||||
export enum LogCategory {
|
||||
CHANNEL,
|
||||
CHANNEL_PROPERTIES, /* separating channel and channel properties because on channel init logging is a big bottleneck */
|
||||
CLIENT,
|
||||
|
@ -19,7 +21,7 @@ enum LogCategory {
|
|||
DNS
|
||||
}
|
||||
|
||||
namespace log {
|
||||
export namespace log {
|
||||
export enum LogType {
|
||||
TRACE,
|
||||
DEBUG,
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
/// <reference path="ui/frames/chat.ts" />
|
||||
/// <reference path="ui/modal/ModalConnect.ts" />
|
||||
/// <reference path="ui/modal/ModalCreateChannel.ts" />
|
||||
/// <reference path="ui/modal/ModalBanClient.ts" />
|
||||
/// <reference path="ui/modal/ModalYesNo.ts" />
|
||||
/// <reference path="ui/modal/ModalBanList.ts" />
|
||||
/// <reference path="settings.ts" />
|
||||
/// <reference path="log.ts" />
|
||||
/// <reference path="PPTListener.ts" />
|
||||
|
||||
import spawnYesNo = Modals.spawnYesNo;
|
||||
import {ConnectionHandler} from "./ConnectionHandler";
|
||||
import {bipc} from "./BrowserIPC";
|
||||
import {log, LogCategory} from "./log";
|
||||
import {profiles} from "./profiles/ConnectionProfile";
|
||||
import {Modals} from "./ui/modal/ModalConnect";
|
||||
import {settings, Settings} from "./settings";
|
||||
import {i18n} from "./i18n/localize";
|
||||
import {createInfoModal} from "./ui/elements/modal";
|
||||
import {MessageHelper} from "./ui/frames/chat";
|
||||
|
||||
const js_render = window.jsrender || $;
|
||||
const native_client = window.require !== undefined;
|
||||
export const js_render = window.jsrender || $;
|
||||
export const native_client = window.require !== undefined;
|
||||
|
||||
function getUserMediaFunctionPromise() : (constraints: MediaStreamConstraints) => Promise<MediaStream> {
|
||||
export function getUserMediaFunctionPromise() : (constraints: MediaStreamConstraints) => Promise<MediaStream> {
|
||||
if('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices)
|
||||
return constraints => navigator.mediaDevices.getUserMedia(constraints);
|
||||
|
||||
|
@ -24,11 +23,12 @@ function getUserMediaFunctionPromise() : (constraints: MediaStreamConstraints) =
|
|||
return constraints => new Promise<MediaStream>((resolve, reject) => _callbacked_function(constraints, resolve, reject));
|
||||
}
|
||||
|
||||
interface Window {
|
||||
export interface Window {
|
||||
open_connected_question: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
function setup_close() {
|
||||
export declare const nodeRequire: typeof require;
|
||||
export function setup_close() {
|
||||
window.onbeforeunload = event => {
|
||||
if(profiles.requires_save())
|
||||
profiles.save();
|
||||
|
@ -50,7 +50,7 @@ function setup_close() {
|
|||
}));
|
||||
|
||||
const exit = () => {
|
||||
const {remote} = require('electron');
|
||||
const {remote} = nodeRequire('electron');
|
||||
remote.getCurrentWindow().close();
|
||||
};
|
||||
|
||||
|
@ -80,8 +80,8 @@ function setup_close() {
|
|||
};
|
||||
}
|
||||
|
||||
declare function moment(...arguments) : any;
|
||||
function setup_jsrender() : boolean {
|
||||
export declare function moment(...arguments) : any;
|
||||
export function setup_jsrender() : boolean {
|
||||
if(!js_render) {
|
||||
loader.critical_error("Missing jsrender extension!");
|
||||
return false;
|
||||
|
@ -115,7 +115,7 @@ function setup_jsrender() : boolean {
|
|||
return true;
|
||||
}
|
||||
|
||||
async function initialize() {
|
||||
export async function initialize() {
|
||||
Settings.initialize();
|
||||
|
||||
try {
|
||||
|
@ -129,7 +129,7 @@ async function initialize() {
|
|||
bipc.setup();
|
||||
}
|
||||
|
||||
async function initialize_app() {
|
||||
export async function initialize_app() {
|
||||
try { //Initialize main template
|
||||
const main = $("#tmpl_main").renderTag({
|
||||
multi_session: !settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION),
|
||||
|
@ -180,7 +180,7 @@ async function initialize_app() {
|
|||
setup_close();
|
||||
}
|
||||
|
||||
function str2ab8(str) {
|
||||
export function str2ab8(str) {
|
||||
const buf = new ArrayBuffer(str.length);
|
||||
const bufView = new Uint8Array(buf);
|
||||
for (let i = 0, strLen = str.length; i < strLen; i++) {
|
||||
|
@ -190,7 +190,7 @@ function str2ab8(str) {
|
|||
}
|
||||
|
||||
/* FIXME Dont use atob, because it sucks for non UTF-8 tings */
|
||||
function arrayBufferBase64(base64: string) {
|
||||
export function arrayBufferBase64(base64: string) {
|
||||
base64 = atob(base64);
|
||||
const buf = new ArrayBuffer(base64.length);
|
||||
const bufView = new Uint8Array(buf);
|
||||
|
@ -200,7 +200,7 @@ function arrayBufferBase64(base64: string) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
function base64_encode_ab(source: ArrayBufferLike) {
|
||||
export function base64_encode_ab(source: ArrayBufferLike) {
|
||||
const encodings = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
let base64 = "";
|
||||
|
||||
|
|
|
@ -1,17 +1,24 @@
|
|||
/// <reference path="../connection/ConnectionBase.ts" />
|
||||
|
||||
enum GroupType {
|
||||
import {LaterPromise} from "../utils/helpers";
|
||||
import {PermissionManager, PermissionValue} from "./PermissionManager";
|
||||
import {AbstractCommandHandler, ServerCommand} from "../connection/ConnectionBase";
|
||||
import {ConnectionHandler} from "../ConnectionHandler";
|
||||
import {log, LogCategory} from "../log";
|
||||
import {CommandResult} from "../connection/ServerConnectionDeclaration";
|
||||
|
||||
export enum GroupType {
|
||||
QUERY,
|
||||
TEMPLATE,
|
||||
NORMAL
|
||||
}
|
||||
|
||||
enum GroupTarget {
|
||||
export enum GroupTarget {
|
||||
SERVER,
|
||||
CHANNEL
|
||||
}
|
||||
|
||||
class GroupProperties {
|
||||
export class GroupProperties {
|
||||
iconid: number = 0;
|
||||
|
||||
sortid: number = 0;
|
||||
|
@ -19,12 +26,12 @@ class GroupProperties {
|
|||
namemode: number = 0;
|
||||
}
|
||||
|
||||
class GroupPermissionRequest {
|
||||
export class GroupPermissionRequest {
|
||||
group_id: number;
|
||||
promise: LaterPromise<PermissionValue[]>;
|
||||
}
|
||||
|
||||
class Group {
|
||||
export class Group {
|
||||
properties: GroupProperties = new GroupProperties();
|
||||
|
||||
readonly handle: GroupManager;
|
||||
|
@ -63,7 +70,7 @@ class Group {
|
|||
}
|
||||
}
|
||||
|
||||
class GroupManager extends connection.AbstractCommandHandler {
|
||||
export class GroupManager extends AbstractCommandHandler {
|
||||
readonly handle: ConnectionHandler;
|
||||
|
||||
serverGroups: Group[] = [];
|
||||
|
@ -83,7 +90,7 @@ class GroupManager extends connection.AbstractCommandHandler {
|
|||
this.channelGroups = undefined;
|
||||
}
|
||||
|
||||
handle_command(command: connection.ServerCommand): boolean {
|
||||
handle_command(command: ServerCommand): boolean {
|
||||
switch (command.command) {
|
||||
case "notifyservergrouplist":
|
||||
case "notifychannelgrouplist":
|
||||
|
|
|
@ -2,7 +2,14 @@
|
|||
/// <reference path="../connection/ConnectionBase.ts" />
|
||||
/// <reference path="../i18n/localize.ts" />
|
||||
|
||||
enum PermissionType {
|
||||
import {ConnectionHandler} from "../ConnectionHandler";
|
||||
import {log, LogCategory} from "../log";
|
||||
import {LaterPromise} from "../utils/helpers";
|
||||
import {AbstractCommandHandler, ServerCommand} from "../connection/ConnectionBase";
|
||||
import LogType = log.LogType;
|
||||
import {CommandResult, ErrorID} from "../connection/ServerConnectionDeclaration";
|
||||
|
||||
export enum PermissionType {
|
||||
B_SERVERINSTANCE_HELP_VIEW = "b_serverinstance_help_view",
|
||||
B_SERVERINSTANCE_VERSION_VIEW = "b_serverinstance_version_view",
|
||||
B_SERVERINSTANCE_INFO_VIEW = "b_serverinstance_info_view",
|
||||
|
@ -352,7 +359,7 @@ enum PermissionType {
|
|||
I_FT_QUOTA_MB_UPLOAD_PER_CLIENT = "i_ft_quota_mb_upload_per_client"
|
||||
}
|
||||
|
||||
class PermissionInfo {
|
||||
export class PermissionInfo {
|
||||
name: string;
|
||||
id: number;
|
||||
description: string;
|
||||
|
@ -363,21 +370,21 @@ class PermissionInfo {
|
|||
}
|
||||
}
|
||||
|
||||
class PermissionGroup {
|
||||
export class PermissionGroup {
|
||||
begin: number;
|
||||
end: number;
|
||||
deep: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
class GroupedPermissions {
|
||||
export class GroupedPermissions {
|
||||
group: PermissionGroup;
|
||||
permissions: PermissionInfo[];
|
||||
children: GroupedPermissions[];
|
||||
parent: GroupedPermissions;
|
||||
}
|
||||
|
||||
class PermissionValue {
|
||||
export class PermissionValue {
|
||||
readonly type: PermissionInfo;
|
||||
value: number;
|
||||
flag_skip: boolean;
|
||||
|
@ -411,13 +418,13 @@ class PermissionValue {
|
|||
}
|
||||
}
|
||||
|
||||
class NeededPermissionValue extends PermissionValue {
|
||||
export class NeededPermissionValue extends PermissionValue {
|
||||
constructor(type, value) {
|
||||
super(type, value);
|
||||
}
|
||||
}
|
||||
|
||||
namespace permissions {
|
||||
export namespace permissions {
|
||||
export type PermissionRequestKeys = {
|
||||
client_id?: number;
|
||||
channel_id?: number;
|
||||
|
@ -473,13 +480,13 @@ namespace permissions {
|
|||
}
|
||||
}
|
||||
|
||||
type RequestLists =
|
||||
export type RequestLists =
|
||||
"requests_channel_permissions" |
|
||||
"requests_client_permissions" |
|
||||
"requests_client_channel_permissions" |
|
||||
"requests_playlist_permissions" |
|
||||
"requests_playlist_client_permissions";
|
||||
class PermissionManager extends connection.AbstractCommandHandler {
|
||||
export class PermissionManager extends AbstractCommandHandler {
|
||||
readonly handle: ConnectionHandler;
|
||||
|
||||
permissionList: PermissionInfo[] = [];
|
||||
|
@ -603,7 +610,7 @@ class PermissionManager extends connection.AbstractCommandHandler {
|
|||
this._cacheNeededPermissions = undefined;
|
||||
}
|
||||
|
||||
handle_command(command: connection.ServerCommand): boolean {
|
||||
handle_command(command: ServerCommand): boolean {
|
||||
switch (command.command) {
|
||||
case "notifyclientneededpermissions":
|
||||
this.onNeededPermissions(command.arguments);
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
namespace profiles {
|
||||
import {MessageHelper} from "../ui/frames/chat";
|
||||
import {createErrorModal} from "../ui/elements/modal";
|
||||
import {guid} from "../crypto/uid";
|
||||
import {decode_identity, IdentitifyType, Identity} from "./Identity";
|
||||
import {static_forum_identity} from "./identities/TeaForumIdentity";
|
||||
import {TeaSpeakIdentity} from "./identities/TeamSpeakIdentity";
|
||||
import {AbstractServerConnection} from "../connection/ConnectionBase";
|
||||
import {connection} from "../connection/HandshakeHandler";
|
||||
|
||||
import HandshakeIdentityHandler = connection.HandshakeIdentityHandler;
|
||||
|
||||
export class ConnectionProfile {
|
||||
id: string;
|
||||
|
||||
|
@ -7,7 +17,7 @@ namespace profiles {
|
|||
default_password: string;
|
||||
|
||||
selected_identity_type: string = "unset";
|
||||
identities: { [key: string]: identities.Identity } = {};
|
||||
identities: { [key: string]: Identity } = {};
|
||||
|
||||
constructor(id: string) {
|
||||
this.id = id;
|
||||
|
@ -22,31 +32,31 @@ namespace profiles {
|
|||
return name || "Another TeaSpeak user";
|
||||
}
|
||||
|
||||
selected_identity(current_type?: identities.IdentitifyType): identities.Identity {
|
||||
selected_identity(current_type?: IdentitifyType): Identity {
|
||||
if (!current_type)
|
||||
current_type = this.selected_type();
|
||||
|
||||
if (current_type === undefined)
|
||||
return undefined;
|
||||
|
||||
if (current_type == identities.IdentitifyType.TEAFORO) {
|
||||
return identities.static_forum_identity();
|
||||
} else if (current_type == identities.IdentitifyType.TEAMSPEAK || current_type == identities.IdentitifyType.NICKNAME) {
|
||||
return this.identities[identities.IdentitifyType[current_type].toLowerCase()];
|
||||
if (current_type == IdentitifyType.TEAFORO) {
|
||||
return static_forum_identity();
|
||||
} else if (current_type == IdentitifyType.TEAMSPEAK || current_type == IdentitifyType.NICKNAME) {
|
||||
return this.identities[IdentitifyType[current_type].toLowerCase()];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
selected_type?(): identities.IdentitifyType {
|
||||
return this.selected_identity_type ? identities.IdentitifyType[this.selected_identity_type.toUpperCase()] : undefined;
|
||||
selected_type?(): IdentitifyType {
|
||||
return this.selected_identity_type ? IdentitifyType[this.selected_identity_type.toUpperCase()] : undefined;
|
||||
}
|
||||
|
||||
set_identity(type: identities.IdentitifyType, identity: identities.Identity) {
|
||||
this.identities[identities.IdentitifyType[type].toLowerCase()] = identity;
|
||||
set_identity(type: IdentitifyType, identity: Identity) {
|
||||
this.identities[IdentitifyType[type].toLowerCase()] = identity;
|
||||
}
|
||||
|
||||
spawn_identity_handshake_handler?(connection: connection.AbstractServerConnection): connection.HandshakeIdentityHandler {
|
||||
spawn_identity_handshake_handler?(connection: AbstractServerConnection): HandshakeIdentityHandler {
|
||||
const identity = this.selected_identity();
|
||||
if (!identity)
|
||||
return undefined;
|
||||
|
@ -91,11 +101,11 @@ namespace profiles {
|
|||
|
||||
if (data.identity_data) {
|
||||
for (const key in data.identity_data) {
|
||||
const type = identities.IdentitifyType[key.toUpperCase() as string];
|
||||
const type = IdentitifyType[key.toUpperCase() as string];
|
||||
const _data = data.identity_data[key];
|
||||
if (type == undefined) continue;
|
||||
|
||||
const identity = await identities.decode_identity(type, _data);
|
||||
const identity = await decode_identity(type, _data);
|
||||
if (identity == undefined) continue;
|
||||
|
||||
result.identities[key.toLowerCase()] = identity;
|
||||
|
@ -153,14 +163,14 @@ namespace profiles {
|
|||
|
||||
/* generate default identity */
|
||||
try {
|
||||
const identity = await identities.TeaSpeakIdentity.generate_new();
|
||||
const identity = await TeaSpeakIdentity.generate_new();
|
||||
let active = true;
|
||||
setTimeout(() => {
|
||||
active = false;
|
||||
}, 1000);
|
||||
await identity.improve_level(8, 1, () => active);
|
||||
profile.set_identity(identities.IdentitifyType.TEAMSPEAK, identity);
|
||||
profile.selected_identity_type = identities.IdentitifyType[identities.IdentitifyType.TEAMSPEAK];
|
||||
profile.set_identity(IdentitifyType.TEAMSPEAK, identity);
|
||||
profile.selected_identity_type = IdentitifyType[IdentitifyType.TEAMSPEAK];
|
||||
} catch (error) {
|
||||
createErrorModal(tr("Failed to generate default identity"), tr("Failed to generate default identity!<br>Please manually generate the identity within your settings => profiles")).open();
|
||||
}
|
||||
|
@ -172,8 +182,8 @@ namespace profiles {
|
|||
profile.default_username = "";
|
||||
profile.profile_name = "TeaSpeak Forum profile";
|
||||
|
||||
profile.set_identity(identities.IdentitifyType.TEAFORO, identities.static_forum_identity());
|
||||
profile.selected_identity_type = identities.IdentitifyType[identities.IdentitifyType.TEAFORO];
|
||||
profile.set_identity(IdentitifyType.TEAFORO, static_forum_identity());
|
||||
profile.selected_identity_type = IdentitifyType[IdentitifyType.TEAFORO];
|
||||
}
|
||||
|
||||
save();
|
||||
|
@ -248,4 +258,3 @@ namespace profiles {
|
|||
export function delete_profile(profile: ConnectionProfile) {
|
||||
available_profiles.remove(profile);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,11 @@
|
|||
namespace profiles.identities {
|
||||
import {AbstractCommandHandler, AbstractServerConnection, ServerCommand} from "../connection/ConnectionBase";
|
||||
import {connection} from "../connection/HandshakeHandler";
|
||||
|
||||
import HandshakeIdentityHandler = connection.HandshakeIdentityHandler;
|
||||
import {NameIdentity} from "./identities/NameIdentity";
|
||||
import {TeaForumIdentity} from "./identities/TeaForumIdentity";
|
||||
import {TeaSpeakIdentity} from "./identities/TeamSpeakIdentity";
|
||||
|
||||
export enum IdentitifyType {
|
||||
TEAFORO,
|
||||
TEAMSPEAK,
|
||||
|
@ -15,7 +22,7 @@ namespace profiles.identities {
|
|||
encode?() : string;
|
||||
decode(data: string) : Promise<void>;
|
||||
|
||||
spawn_identity_handshake_handler(connection: connection.AbstractServerConnection) : connection.HandshakeIdentityHandler;
|
||||
spawn_identity_handshake_handler(connection: AbstractServerConnection) : HandshakeIdentityHandler;
|
||||
}
|
||||
|
||||
export async function decode_identity(type: IdentitifyType, data: string) : Promise<Identity> {
|
||||
|
@ -61,16 +68,16 @@ namespace profiles.identities {
|
|||
return identity;
|
||||
}
|
||||
|
||||
export class HandshakeCommandHandler<T extends AbstractHandshakeIdentityHandler> extends connection.AbstractCommandHandler {
|
||||
export class HandshakeCommandHandler<T extends AbstractHandshakeIdentityHandler> extends AbstractCommandHandler {
|
||||
readonly handle: T;
|
||||
|
||||
constructor(connection: connection.AbstractServerConnection, handle: T) {
|
||||
constructor(connection: AbstractServerConnection, handle: T) {
|
||||
super(connection);
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
|
||||
handle_command(command: connection.ServerCommand): boolean {
|
||||
handle_command(command: ServerCommand): boolean {
|
||||
if($.isFunction(this[command.command]))
|
||||
this[command.command](command.arguments);
|
||||
else if(command.command == "error") {
|
||||
|
@ -83,11 +90,11 @@ namespace profiles.identities {
|
|||
}
|
||||
|
||||
export abstract class AbstractHandshakeIdentityHandler implements connection.HandshakeIdentityHandler {
|
||||
connection: connection.AbstractServerConnection;
|
||||
connection: AbstractServerConnection;
|
||||
|
||||
protected callbacks: ((success: boolean, message?: string) => any)[] = [];
|
||||
|
||||
protected constructor(connection: connection.AbstractServerConnection) {
|
||||
protected constructor(connection: AbstractServerConnection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
|
@ -107,4 +114,3 @@ namespace profiles.identities {
|
|||
callback(false, message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,16 @@
|
|||
/// <reference path="../Identity.ts" />
|
||||
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||
import {log, LogCategory} from "../../log";
|
||||
import {AbstractServerConnection} from "../../connection/ConnectionBase";
|
||||
import {connection} from "../../connection/HandshakeHandler";
|
||||
|
||||
import HandshakeIdentityHandler = connection.HandshakeIdentityHandler;
|
||||
import {AbstractHandshakeIdentityHandler, HandshakeCommandHandler, IdentitifyType, Identity} from "../Identity";
|
||||
|
||||
namespace profiles.identities {
|
||||
class NameHandshakeHandler extends AbstractHandshakeIdentityHandler {
|
||||
readonly identity: NameIdentity;
|
||||
handler: HandshakeCommandHandler<NameHandshakeHandler>;
|
||||
|
||||
constructor(connection: connection.AbstractServerConnection, identity: profiles.identities.NameIdentity) {
|
||||
constructor(connection: AbstractServerConnection, identity: NameIdentity) {
|
||||
super(connection);
|
||||
this.identity = identity;
|
||||
|
||||
|
@ -81,8 +86,7 @@ namespace profiles.identities {
|
|||
});
|
||||
}
|
||||
|
||||
spawn_identity_handshake_handler(connection: connection.AbstractServerConnection) : connection.HandshakeIdentityHandler {
|
||||
spawn_identity_handshake_handler(connection: AbstractServerConnection) : HandshakeIdentityHandler {
|
||||
return new NameHandshakeHandler(connection, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,16 @@
|
|||
/// <reference path="../Identity.ts" />
|
||||
import {AbstractServerConnection} from "../../connection/ConnectionBase";
|
||||
import {log, LogCategory} from "../../log";
|
||||
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||
import {forum} from "./teaspeak-forum";
|
||||
import {connection} from "../../connection/HandshakeHandler";
|
||||
import HandshakeIdentityHandler = connection.HandshakeIdentityHandler;
|
||||
import {AbstractHandshakeIdentityHandler, HandshakeCommandHandler, IdentitifyType, Identity} from "../Identity";
|
||||
|
||||
namespace profiles.identities {
|
||||
class TeaForumHandshakeHandler extends AbstractHandshakeIdentityHandler {
|
||||
readonly identity: TeaForumIdentity;
|
||||
handler: HandshakeCommandHandler<TeaForumHandshakeHandler>;
|
||||
|
||||
constructor(connection: connection.AbstractServerConnection, identity: profiles.identities.TeaForumIdentity) {
|
||||
constructor(connection: AbstractServerConnection, identity: TeaForumIdentity) {
|
||||
super(connection);
|
||||
this.identity = identity;
|
||||
this.handler = new HandshakeCommandHandler(connection, this);
|
||||
|
@ -80,7 +85,7 @@ namespace profiles.identities {
|
|||
});
|
||||
}
|
||||
|
||||
spawn_identity_handshake_handler(connection: connection.AbstractServerConnection) : connection.HandshakeIdentityHandler {
|
||||
spawn_identity_handshake_handler(connection: AbstractServerConnection) : HandshakeIdentityHandler {
|
||||
return new TeaForumHandshakeHandler(connection, this);
|
||||
}
|
||||
|
||||
|
@ -88,7 +93,7 @@ namespace profiles.identities {
|
|||
return this.identity_data ? this.identity_data.name() : undefined;
|
||||
}
|
||||
|
||||
type(): profiles.identities.IdentitifyType {
|
||||
type(): IdentitifyType {
|
||||
return IdentitifyType.TEAFORO;
|
||||
}
|
||||
|
||||
|
@ -119,4 +124,3 @@ namespace profiles.identities {
|
|||
export function static_forum_identity() : TeaForumIdentity | undefined {
|
||||
return static_identity;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,14 @@
|
|||
/// <reference path="../Identity.ts" />
|
||||
import {arrayBufferBase64, base64_encode_ab, str2ab8} from "../../main";
|
||||
import {sha} from "../../crypto/sha";
|
||||
import {asn1} from "../../crypto/asn1";
|
||||
import {AbstractServerConnection} from "../../connection/ConnectionBase";
|
||||
import {log, LogCategory} from "../../log";
|
||||
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||
import {settings} from "../../settings";
|
||||
import {connection} from "../../connection/HandshakeHandler";
|
||||
import HandshakeIdentityHandler = connection.HandshakeIdentityHandler;
|
||||
import {AbstractHandshakeIdentityHandler, HandshakeCommandHandler, IdentitifyType, Identity} from "../Identity";
|
||||
|
||||
namespace profiles.identities {
|
||||
export namespace CryptoHelper {
|
||||
export function base64_url_encode(str){
|
||||
return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
|
||||
|
@ -214,7 +222,7 @@ namespace profiles.identities {
|
|||
identity: TeaSpeakIdentity;
|
||||
handler: HandshakeCommandHandler<TeaSpeakHandshakeHandler>;
|
||||
|
||||
constructor(connection: connection.AbstractServerConnection, identity: TeaSpeakIdentity) {
|
||||
constructor(connection: AbstractServerConnection, identity: TeaSpeakIdentity) {
|
||||
super(connection);
|
||||
this.identity = identity;
|
||||
this.handler = new HandshakeCommandHandler(connection, this);
|
||||
|
@ -864,8 +872,7 @@ namespace profiles.identities {
|
|||
return base64_encode_ab(buffer.subarray(0, index));
|
||||
}
|
||||
|
||||
spawn_identity_handshake_handler(connection: connection.AbstractServerConnection): connection.HandshakeIdentityHandler {
|
||||
spawn_identity_handshake_handler(connection: AbstractServerConnection): HandshakeIdentityHandler {
|
||||
return new TeaSpeakHandshakeHandler(connection, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
interface Window {
|
||||
import {Settings, settings} from "../../settings";
|
||||
import {update_forum} from "./TeaForumIdentity";
|
||||
|
||||
declare interface Window {
|
||||
grecaptcha: GReCaptcha;
|
||||
}
|
||||
|
||||
interface GReCaptcha {
|
||||
export interface GReCaptcha {
|
||||
render(container: string | HTMLElement, parameters: {
|
||||
sitekey: string;
|
||||
theme?: "dark" | "light";
|
||||
|
@ -18,10 +21,10 @@ interface GReCaptcha {
|
|||
reset(widget_id?: string);
|
||||
}
|
||||
|
||||
namespace forum {
|
||||
export namespace forum {
|
||||
export namespace gcaptcha {
|
||||
export async function initialize() {
|
||||
if(typeof(window.grecaptcha) === "undefined") {
|
||||
if(typeof((window as any).grecaptcha) === "undefined") {
|
||||
let script = document.createElement("script");
|
||||
script.async = true;
|
||||
|
||||
|
@ -50,7 +53,7 @@ namespace forum {
|
|||
}
|
||||
}
|
||||
|
||||
if(typeof(window.grecaptcha) === "undefined")
|
||||
if(typeof((window as any).grecaptcha) === "undefined")
|
||||
throw tr("failed to load recaptcha");
|
||||
}
|
||||
|
||||
|
@ -62,9 +65,9 @@ namespace forum {
|
|||
throw tr("initialisation failed");
|
||||
}
|
||||
if(container.attr("captcha-uuid"))
|
||||
window.grecaptcha.reset(container.attr("captcha-uuid"));
|
||||
(window as any).grecaptcha.reset(container.attr("captcha-uuid"));
|
||||
else {
|
||||
container.attr("captcha-uuid", window.grecaptcha.render(container[0], {
|
||||
container.attr("captcha-uuid", (window as any).grecaptcha.render(container[0], {
|
||||
"sitekey": key,
|
||||
callback: callback_data
|
||||
}));
|
||||
|
@ -206,7 +209,7 @@ namespace forum {
|
|||
localStorage.setItem("teaspeak-forum-data", response["data"]);
|
||||
localStorage.setItem("teaspeak-forum-sign", response["sign"]);
|
||||
localStorage.setItem("teaspeak-forum-auth", response["auth-key"]);
|
||||
profiles.identities.update_forum();
|
||||
update_forum();
|
||||
} catch(error) {
|
||||
console.error(tr("Failed to parse forum given data: %o"), error);
|
||||
return {
|
||||
|
@ -266,7 +269,7 @@ namespace forum {
|
|||
_data = new Data(_data.auth_key, response["data"], response["sign"]);
|
||||
localStorage.setItem("teaspeak-forum-data", response["data"]);
|
||||
localStorage.setItem("teaspeak-forum-sign", response["sign"]);
|
||||
profiles.identities.update_forum();
|
||||
update_forum();
|
||||
} catch(error) {
|
||||
console.error(tr("Failed to parse forum given data: %o"), error);
|
||||
throw tr("failed to parse data");
|
||||
|
@ -320,7 +323,7 @@ namespace forum {
|
|||
localStorage.removeItem("teaspeak-forum-data");
|
||||
localStorage.removeItem("teaspeak-forum-sign");
|
||||
localStorage.removeItem("teaspeak-forum-auth");
|
||||
profiles.identities.update_forum();
|
||||
update_forum();
|
||||
}
|
||||
|
||||
loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
//Used by CertAccept popup
|
||||
|
||||
interface Array<T> {
|
||||
remove(elem?: T): boolean;
|
||||
last?(): T;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/// <reference path="ui/elements/modal.ts" />
|
||||
//Used by CertAccept popup
|
||||
|
||||
import {log, LogCategory} from "./log";
|
||||
import {createErrorModal} from "./ui/elements/modal";
|
||||
|
||||
if(typeof(customElements) !== "undefined") {
|
||||
try {
|
||||
class X_Properties extends HTMLElement {}
|
||||
|
@ -14,7 +17,7 @@ if(typeof(customElements) !== "undefined") {
|
|||
}
|
||||
|
||||
/* T = value type */
|
||||
interface SettingsKey<T> {
|
||||
export interface SettingsKey<T> {
|
||||
key: string;
|
||||
|
||||
fallback_keys?: string | string[];
|
||||
|
@ -25,7 +28,7 @@ interface SettingsKey<T> {
|
|||
require_restart?: boolean;
|
||||
}
|
||||
|
||||
class SettingsBase {
|
||||
export class SettingsBase {
|
||||
protected static readonly UPDATE_DIRECT: boolean = true;
|
||||
|
||||
protected static transformStO?<T>(input?: string, _default?: T, default_type?: string) : T {
|
||||
|
@ -77,7 +80,7 @@ class SettingsBase {
|
|||
}
|
||||
}
|
||||
|
||||
class StaticSettings extends SettingsBase {
|
||||
export class StaticSettings extends SettingsBase {
|
||||
private static _instance: StaticSettings;
|
||||
static get instance() : StaticSettings {
|
||||
if(!this._instance)
|
||||
|
@ -139,7 +142,7 @@ class StaticSettings extends SettingsBase {
|
|||
}
|
||||
}
|
||||
|
||||
class Settings extends StaticSettings {
|
||||
export class Settings extends StaticSettings {
|
||||
static readonly KEY_USER_IS_NEW: SettingsKey<boolean> = {
|
||||
key: 'user_is_new_user',
|
||||
default_value: true
|
||||
|
@ -433,7 +436,7 @@ class Settings extends StaticSettings {
|
|||
}
|
||||
}
|
||||
|
||||
class ServerSettings extends SettingsBase {
|
||||
export class ServerSettings extends SettingsBase {
|
||||
private cacheServer = {};
|
||||
private _server_unique_id: string;
|
||||
private _server_save_worker: NodeJS.Timer;
|
||||
|
@ -511,4 +514,4 @@ class ServerSettings extends SettingsBase {
|
|||
}
|
||||
}
|
||||
|
||||
let settings: Settings;
|
||||
export let settings: Settings;
|
|
@ -1,4 +1,8 @@
|
|||
enum Sound {
|
||||
import {settings} from "../settings";
|
||||
import {log, LogCategory} from "../log";
|
||||
import {ConnectionHandler} from "../ConnectionHandler";
|
||||
|
||||
export enum Sound {
|
||||
SOUND_TEST = "sound.test",
|
||||
SOUND_EGG = "sound.egg",
|
||||
|
||||
|
@ -61,7 +65,7 @@ enum Sound {
|
|||
GROUP_CHANNEL_CHANGED_SELF = "group.channel.changed.self"
|
||||
}
|
||||
|
||||
namespace sound {
|
||||
export namespace sound {
|
||||
export interface SoundHandle {
|
||||
key: string;
|
||||
filename: string;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace stats {
|
||||
import {log, LogCategory} from "./log";
|
||||
|
||||
export namespace stats {
|
||||
const LOG_PREFIX = "[Statistics] ";
|
||||
|
||||
export enum CloseCodes {
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
.channel-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.channel-container .container-channel {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
width: 100%;
|
||||
min-height: 16px;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.channel-container .container-channel .channel-type {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.channel-container .container-channel .container-channel-name {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
justify-content: left;
|
||||
max-width: 100%;
|
||||
/* important for the repetitive channel name! */
|
||||
overflow-x: hidden;
|
||||
height: 16px;
|
||||
}
|
||||
.channel-container .container-channel .container-channel-name.align-right {
|
||||
justify-content: right;
|
||||
}
|
||||
.channel-container .container-channel .container-channel-name.align-center, .channel-container .container-channel .container-channel-name.align-repetitive {
|
||||
justify-content: center;
|
||||
}
|
||||
.channel-container .container-channel .container-channel-name .channel-name {
|
||||
align-self: center;
|
||||
color: #828282;
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.channel-container .container-channel .container-channel-name.align-repetitive .channel-name {
|
||||
text-overflow: clip;
|
||||
}
|
||||
.channel-container .container-channel .icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.channel-container .container-channel.move-selected {
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
.channel-container .container-channel .show-channel-normal-only {
|
||||
display: none;
|
||||
}
|
||||
.channel-container .container-channel .show-channel-normal-only.channel-normal {
|
||||
display: block;
|
||||
}
|
||||
.channel-container .container-channel .icon_no_sound {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
.channel-container .container-channel .icon_no_sound .background {
|
||||
width: 10px;
|
||||
height: 14px;
|
||||
background: red;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 3px;
|
||||
z-index: -1;
|
||||
}
|
||||
.channel-container .container-clients {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=channel.css.map */
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sourceRoot":"","sources":["channel.scss","colors.scss"],"names":[],"mappings":"AAEA;EACI;EACA;;AAEA;EACI;EAEA;EACA;EACA;EAEA;EACA;EAEA;EACA;;AAEA;EACI;EACA;EAEA;;AAGJ;EACI;EACA;EAEA;EACA;EAEA;EAEA;AAAiB;EACjB;EACA;;AAEA;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA,OC/CW;EDiDX;EACA;EACA;EACA;;AAIA;EACI;;AAKZ;EACI;EACA;EAEA;EACA;;AAGJ;EACI;;AAGJ;EACI;;AAEA;EACI;;AAIR;EACI;EACA;;AAEA;EACI;EACA;EAEA;EACA;EACA;EACA;EACA;;AAKZ;EACI;EACA","file":"channel.css"}
|
|
@ -0,0 +1,106 @@
|
|||
@import "colors";
|
||||
|
||||
.channel-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.container-channel {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
|
||||
width: 100%;
|
||||
min-height: 16px;
|
||||
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
.channel-type {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.container-channel-name {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
|
||||
justify-content: left;
|
||||
|
||||
max-width: 100%; /* important for the repetitive channel name! */
|
||||
overflow-x: hidden;
|
||||
height: 16px;
|
||||
|
||||
&.align-right {
|
||||
justify-content: right;
|
||||
}
|
||||
|
||||
&.align-center, &.align-repetitive {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.channel-name {
|
||||
align-self: center;
|
||||
color: $channel-tree-entry-color;
|
||||
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&.align-repetitive {
|
||||
.channel-name {
|
||||
text-overflow: clip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&.move-selected {
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
.show-channel-normal-only {
|
||||
display: none;
|
||||
|
||||
&.channel-normal {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.icon_no_sound {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
.background {
|
||||
width: 10px;
|
||||
height: 14px;
|
||||
|
||||
background: red;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 3px;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container-clients {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
import * as React from "react";
|
||||
import {ChannelEntry} from "../../channel-tree/channel";
|
||||
|
||||
const cssChannel = require("./channel.scss");
|
||||
const cssTree = require("./tree.scss");
|
||||
|
||||
class ChannelIcon extends React.Component<{ channel: ChannelEntry }, {}> {
|
||||
channel_icon_classes() {
|
||||
const class_list = [];
|
||||
const channel = this.props.channel;
|
||||
|
||||
if(channel.formattedChannelName() !== channel.channelName())
|
||||
return "channel-spacer";
|
||||
|
||||
let icon_color;
|
||||
if(channel.properties.channel_flag_password && !channel.cached_password())
|
||||
icon_color = "yellow";
|
||||
else if(channel.properties.channel_flag_maxclients_unlimited && channel.clients().length >= channel.properties.channel_maxclients)
|
||||
icon_color = "red";
|
||||
else if(channel.properties.channel_flag_maxfamilyclients_unlimited && channel.clients(true).length >= channel.properties.channel_maxfamilyclients)
|
||||
icon_color = "red";
|
||||
else
|
||||
icon_color = "green";
|
||||
|
||||
|
||||
return "channel-normal client-channel_" + icon_color + (channel.flag_subscribed ? "_subscribed" : "");
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className={this.channel_icon_classes()} />;
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelIcons extends React.Component<{channel: ChannelEntry}, {}> {
|
||||
render_icon(target: HTMLDivElement) {
|
||||
const props = this.props.channel.properties;
|
||||
if(!props.channel_icon_id) return;
|
||||
|
||||
const tag = this.props.channel.channelTree.client.fileManager.icons.generateTag(props.channel_icon_id);
|
||||
tag.appendTo($(target));
|
||||
}
|
||||
|
||||
render() {
|
||||
const icons = [];
|
||||
|
||||
const props = this.props.channel.properties;
|
||||
if(props.channel_flag_default) {
|
||||
icons.push(<div className={"show-channel-normal-only icon_entry icon_default icon client-channel_default"} title={tr("Default channel")} />);
|
||||
}
|
||||
if(props.channel_flag_password) {
|
||||
icons.push(<div className={"show-channel-normal-only icon_entry icon_password icon client-register"} title={tr("The channel is password protected")} />);
|
||||
}
|
||||
if(props.channel_codec_quality > 4) {
|
||||
icons.push(<div className={"show-channel-normal-only icon_entry icon_moderated icon client-moderated"} title={tr("Music quality")} />);
|
||||
}
|
||||
if(props.channel_needed_talk_power > 0) {
|
||||
icons.push(<div className={"show-channel-normal-only icon_entry icon_moderated icon client-moderated"} title={tr("Channel is moderated")} />);
|
||||
}
|
||||
if(props.channel_icon_id != 0) {
|
||||
icons.push(<div className={"show-channel-normal-only icon_entry channel_icon"} title={tr("Channel icon")} ref={e => this.render_icon(e) }/>)
|
||||
}
|
||||
if(!audio.codec.supported(props.channel_codec)) {
|
||||
icons.push(<div className={cssChannel.icon_no_sound}>
|
||||
<div className={cssChannel.background} />
|
||||
<div className={"icon_entry icon client-conflict-icon"} title={tr("You don't support the channel codec")} />
|
||||
</div>)
|
||||
}
|
||||
|
||||
return (<div className={cssChannel.icons}>{icons}</div>);
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelLine extends React.Component<{ channel: ChannelEntry }, {}> {
|
||||
|
||||
render() {
|
||||
let depth = 1;
|
||||
let parent = this.props.channel;
|
||||
while((parent = parent.parent))
|
||||
depth++;
|
||||
|
||||
//TODO: On handle spacer alignments in channel name!
|
||||
return (
|
||||
<div className={cssChannel.containerChannel}>
|
||||
<div className={cssTree.markerTextUnread} />
|
||||
<div className={cssTree.depthFiller} style={{ width: depth + "em" }} />
|
||||
<ChannelIcon channel={this.props.channel} />
|
||||
<div className={cssChannel.containerChannelName}>
|
||||
<a className={cssChannel.channelName}>{this.props.channel.formattedChannelName()}</a>
|
||||
</div>
|
||||
<ChannelIcons channel={this.props.channel} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelClientsView extends React.Component<{}, {}> {
|
||||
}
|
||||
|
||||
class SubChannelView extends React.Component<{ channels: ChannelEntry[] }, {}> {
|
||||
|
||||
render() {
|
||||
return this.props.channels.map(e => <ChannelLine channel={e} />);
|
||||
}
|
||||
}
|
||||
|
||||
export class Channel extends React.Component<{ channel: ChannelEntry }, {}> {
|
||||
children: ChannelEntry[];
|
||||
|
||||
channel_entry() : ChannelEntry { return this.props.channel; }
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={[cssTree.entry, cssChannel.channelContainer].join(" ")}>
|
||||
<ChannelLine channel={this.props.channel} />
|
||||
<ChannelClientsView />
|
||||
<SubChannelView channels={[]} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
/*# sourceMappingURL=colors.css.map */
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sourceRoot":"","sources":[],"names":[],"mappings":"","file":"colors.css"}
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
$channel-tree-new-message-color: #a814147F;
|
||||
$channel-tree-entry-color: #828282;
|
|
@ -0,0 +1,38 @@
|
|||
/* Some general browser helpers */
|
||||
.tree-container .tree .entry .depth-filler {
|
||||
font-size: 16px;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
.tree-container .marker-text-unread {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
background-color: #a814147F;
|
||||
opacity: 1;
|
||||
-moz-transition: opacity 0.25s;
|
||||
-o-transition: opacity 0.25s;
|
||||
-webkit-transition: opacity 0.25s;
|
||||
transition: opacity 0.25s;
|
||||
}
|
||||
.tree-container .marker-text-unread:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 24px;
|
||||
background: -moz-linear-gradient(left, rgba(168, 20, 20, 0.18) 0%, rgba(168, 20, 20, 0) 100%);
|
||||
/* FF3.6-15 */
|
||||
background: -webkit-linear-gradient(left, rgba(168, 20, 20, 0.18) 0%, rgba(168, 20, 20, 0) 100%);
|
||||
/* Chrome10-25,Safari5.1-6 */
|
||||
background: linear-gradient(to right, rgba(168, 20, 20, 0.18) 0%, rgba(168, 20, 20, 0) 100%);
|
||||
/* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
||||
}
|
||||
.tree-container .marker-text-unread.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=tree.css.map */
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sourceRoot":"","sources":["../../../css/static/mixin.scss","tree.scss"],"names":[],"mappings":"AAAA;ACQY;EACI;EAEA;EACA;;AAKZ;EACI;EACA;EACA;EACA;EAEA;EACA;EAEA;EDvBP,iBC4CO;ED3CP,eC2CO;ED1CP,oBC0CO;EDzCP,YCyCO;;AAnBA;EACI;EACA;EAEA;EACA;EACA;EAEA;EAEA;AAAyF;EACzF;AAA2F;EAC3F;AAAuF;;AAG3F;EACI","file":"tree.css"}
|
|
@ -0,0 +1,50 @@
|
|||
@import "../../../css/static/mixin";
|
||||
@import "../../../css/static/properties";
|
||||
|
||||
.tree-container {
|
||||
.tree {
|
||||
|
||||
.entry {
|
||||
|
||||
.depth-filler {
|
||||
font-size: 16px;
|
||||
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.marker-text-unread {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
width: 1px;
|
||||
background-color: #a814147F;
|
||||
|
||||
opacity: 1;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
width: 24px;
|
||||
|
||||
background: -moz-linear-gradient(left, rgba(168,20,20,.18) 0%, rgba(168,20,20,0) 100%); /* FF3.6-15 */
|
||||
background: -webkit-linear-gradient(left, rgba(168,20,20,.18) 0%,rgba(168,20,20,0) 100%); /* Chrome10-25,Safari5.1-6 */
|
||||
background: linear-gradient(to right, rgba(168,20,20,.18) 0%,rgba(168,20,20,0) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@include transition(opacity $button_hover_animation_time);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import * as React from "react";
|
||||
|
||||
export class TreeView {
|
||||
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
/// <reference path="client.ts" />
|
||||
|
||||
class ClientMover {
|
||||
export class ClientMover {
|
||||
static readonly listener_root = $(document);
|
||||
static readonly move_element = $("#mouse-move");
|
||||
readonly channel_tree: ChannelTree;
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import {settings} from "../../settings";
|
||||
import {log, LogCategory} from "../../log";
|
||||
|
||||
declare const $: any;
|
||||
interface JQuery<TElement = HTMLElement> {
|
||||
dividerfy() : this;
|
||||
}
|
||||
|
||||
if(!$.fn.dividerfy) {
|
||||
$.fn.dividerfy = function<T extends HTMLElement>(this: JQuery<T>) : JQuery<T> {
|
||||
this.find(".container-seperator").each(function (this: T) {
|
||||
(this as any).find(".container-seperator").each(function (this: T) {
|
||||
if(!this.previousElementSibling) return;
|
||||
if(!this.nextElementSibling) return;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace contextmenu {
|
||||
export namespace contextmenu {
|
||||
export interface MenuEntry {
|
||||
callback?: () => void;
|
||||
type: MenuEntryType;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/// <reference path="../../PPTListener.ts" />
|
||||
import {KeyCode} from "../../PPTListener";
|
||||
|
||||
enum ElementType {
|
||||
export enum ElementType {
|
||||
HEADER,
|
||||
BODY,
|
||||
FOOTER
|
||||
}
|
||||
|
||||
type BodyCreator = (() => JQuery | JQuery[] | string) | string | JQuery | JQuery[];
|
||||
const ModalFunctions = {
|
||||
export type BodyCreator = (() => JQuery | JQuery[] | string) | string | JQuery | JQuery[];
|
||||
export const ModalFunctions = {
|
||||
divify: function (val: JQuery) {
|
||||
if(val.length > 1)
|
||||
return $.spawn("div").append(val);
|
||||
|
@ -54,7 +54,7 @@ const ModalFunctions = {
|
|||
}
|
||||
};
|
||||
|
||||
class ModalProperties {
|
||||
export class ModalProperties {
|
||||
template?: string;
|
||||
header: BodyCreator = () => "HEADER";
|
||||
body: BodyCreator = () => "BODY";
|
||||
|
@ -89,7 +89,7 @@ class ModalProperties {
|
|||
full_size?: boolean = false;
|
||||
}
|
||||
|
||||
namespace modal {
|
||||
export namespace modal {
|
||||
export function initialize_modals() {
|
||||
register_global_events();
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ let _global_modal_count = 0;
|
|||
let _global_modal_last: HTMLElement;
|
||||
let _global_modal_last_time: number;
|
||||
|
||||
class Modal {
|
||||
export class Modal {
|
||||
private _htmlTag: JQuery;
|
||||
properties: ModalProperties;
|
||||
shown: boolean;
|
||||
|
@ -296,11 +296,11 @@ class Modal {
|
|||
}
|
||||
}
|
||||
|
||||
function createModal(data: ModalProperties | any) : Modal {
|
||||
export function createModal(data: ModalProperties | any) : Modal {
|
||||
return new Modal(ModalFunctions.warpProperties(data));
|
||||
}
|
||||
|
||||
class InputModalProperties extends ModalProperties {
|
||||
export class InputModalProperties extends ModalProperties {
|
||||
maxLength?: number;
|
||||
|
||||
field_title?: string;
|
||||
|
@ -310,7 +310,7 @@ class InputModalProperties extends ModalProperties {
|
|||
error_message?: string;
|
||||
}
|
||||
|
||||
function createInputModal(headMessage: BodyCreator, question: BodyCreator, validator: (input: string) => boolean, callback: (flag: boolean | string) => void, props: InputModalProperties | any = {}) : Modal {
|
||||
export function createInputModal(headMessage: BodyCreator, question: BodyCreator, validator: (input: string) => boolean, callback: (flag: boolean | string) => void, props: InputModalProperties | any = {}) : Modal {
|
||||
props = ModalFunctions.warpProperties(props);
|
||||
props.template_properties || (props.template_properties = {});
|
||||
props.template_properties.field_title = props.field_title;
|
||||
|
@ -370,7 +370,7 @@ function createInputModal(headMessage: BodyCreator, question: BodyCreator, valid
|
|||
return modal;
|
||||
}
|
||||
|
||||
function createErrorModal(header: BodyCreator, message: BodyCreator, props: ModalProperties | any = { footer: undefined }) {
|
||||
export function createErrorModal(header: BodyCreator, message: BodyCreator, props: ModalProperties | any = { footer: undefined }) {
|
||||
props = ModalFunctions.warpProperties(props);
|
||||
(props.template_properties || (props.template_properties = {})).header_class = "modal-header-error";
|
||||
|
||||
|
@ -382,7 +382,7 @@ function createErrorModal(header: BodyCreator, message: BodyCreator, props: Moda
|
|||
return modal;
|
||||
}
|
||||
|
||||
function createInfoModal(header: BodyCreator, message: BodyCreator, props: ModalProperties | any = { footer: undefined }) {
|
||||
export function createInfoModal(header: BodyCreator, message: BodyCreator, props: ModalProperties | any = { footer: undefined }) {
|
||||
props = ModalFunctions.warpProperties(props);
|
||||
(props.template_properties || (props.template_properties = {})).header_class = "modal-header-info";
|
||||
|
||||
|
@ -393,73 +393,3 @@ function createInfoModal(header: BodyCreator, message: BodyCreator, props: Modal
|
|||
modal.htmlTag.find(".modal-body").addClass("modal-info");
|
||||
return modal;
|
||||
}
|
||||
|
||||
/* extend jquery */
|
||||
|
||||
interface ModalElements {
|
||||
header?: BodyCreator;
|
||||
body?: BodyCreator;
|
||||
footer?: BodyCreator;
|
||||
}
|
||||
|
||||
interface JQuery<TElement = HTMLElement> {
|
||||
modalize(entry_callback?: (header: JQuery, body: JQuery, footer: JQuery) => ModalElements | void, properties?: ModalProperties | any) : Modal;
|
||||
}
|
||||
|
||||
$.fn.modalize = function (this: JQuery, entry_callback?: (header: JQuery, body: JQuery, footer: JQuery) => ModalElements | void, properties?: ModalProperties | any) : Modal {
|
||||
properties = properties || {} as ModalProperties;
|
||||
entry_callback = entry_callback || ((a,b,c) => undefined);
|
||||
|
||||
let tag_modal = this[0].tagName.toLowerCase() == "modal" ? this : undefined; /* TODO may throw exception? */
|
||||
|
||||
let tag_head = tag_modal ? tag_modal.find("modal-header") : ModalFunctions.jqueriefy(properties.header);
|
||||
let tag_body = tag_modal ? tag_modal.find("modal-body") : this;
|
||||
let tag_footer = tag_modal ? tag_modal.find("modal-footer") : ModalFunctions.jqueriefy(properties.footer);
|
||||
|
||||
const result = entry_callback(tag_head as any, tag_body, tag_footer as any) || {};
|
||||
properties.header = result.header || tag_head;
|
||||
properties.body = result.body || tag_body;
|
||||
properties.footer = result.footer || tag_footer;
|
||||
return createModal(properties);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace net.graph {
|
||||
export namespace net.graph {
|
||||
export type Entry = {
|
||||
timestamp: number;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
interface SliderOptions {
|
||||
export interface SliderOptions {
|
||||
min_value?: number;
|
||||
max_value?: number;
|
||||
initial_value?: number;
|
||||
|
@ -8,11 +8,11 @@ interface SliderOptions {
|
|||
value_field?: JQuery | JQuery[];
|
||||
}
|
||||
|
||||
interface Slider {
|
||||
export interface Slider {
|
||||
value(value?: number) : number;
|
||||
}
|
||||
|
||||
function sliderfy(slider: JQuery, options?: SliderOptions) : Slider {
|
||||
export function sliderfy(slider: JQuery, options?: SliderOptions) : Slider {
|
||||
options = Object.assign( {
|
||||
initial_value: 0,
|
||||
min_value: 0,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
function tooltip(entry: JQuery) {
|
||||
export function tooltip(entry: JQuery) {
|
||||
return tooltip.initialize(entry);
|
||||
}
|
||||
|
||||
namespace tooltip {
|
||||
export namespace tooltip {
|
||||
let _global_tooltip: JQuery;
|
||||
export type Handle = {
|
||||
show();
|
||||
|
|
|
@ -13,12 +13,27 @@
|
|||
client_away_message Value: ''
|
||||
*/
|
||||
|
||||
let control_bar: ControlBar; /* global variable to access the control bar */
|
||||
import {ConnectionHandler, DisconnectReason} from "../../ConnectionHandler";
|
||||
import {top_menu} from "./MenuBar";
|
||||
import {Settings, settings} from "../../settings";
|
||||
import {createErrorModal, createInfoModal, createInputModal} from "../elements/modal";
|
||||
import {default_recorder} from "../../voice/RecorderProfile";
|
||||
import {sound, Sound} from "../../sound/Sounds";
|
||||
import {Modals} from "../modal/ModalConnect";
|
||||
import {Modal as ModalsS} from "../modal/ModalSettings";
|
||||
import {log} from "./server_log";
|
||||
import {MessageHelper} from "./chat";
|
||||
import {CommandResult} from "../../connection/ServerConnectionDeclaration";
|
||||
import {PermissionType} from "../../permission/PermissionManager";
|
||||
import {bookmarks} from "../../bookmarks";
|
||||
import {contextmenu} from "../elements/context_menu";
|
||||
|
||||
type MicrophoneState = "disabled" | "muted" | "enabled";
|
||||
type HeadphoneState = "muted" | "enabled";
|
||||
type AwayState = "away-global" | "away" | "online";
|
||||
class ControlBar {
|
||||
export let control_bar: ControlBar; /* global variable to access the control bar */
|
||||
|
||||
export type MicrophoneState = "disabled" | "muted" | "enabled";
|
||||
export type HeadphoneState = "muted" | "enabled";
|
||||
export type AwayState = "away-global" | "away" | "online";
|
||||
export class ControlBar {
|
||||
private _button_away_active: AwayState;
|
||||
private _button_microphone: MicrophoneState;
|
||||
private _button_speakers: HeadphoneState;
|
||||
|
@ -421,7 +436,7 @@ class ControlBar {
|
|||
}
|
||||
|
||||
private on_open_settings() {
|
||||
Modals.spawnSettingsModal();
|
||||
ModalsS.spawnSettingsModal();
|
||||
}
|
||||
|
||||
private on_open_connect() {
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
namespace top_menu {
|
||||
import {bookmarks} from "../../bookmarks";
|
||||
import {Modals} from "../modal/ModalBookmarks";
|
||||
import {DisconnectReason} from "../../ConnectionHandler";
|
||||
import {control_bar} from "./ControlBar";
|
||||
import {createErrorModal} from "../elements/modal";
|
||||
import {PermissionType} from "../../permission/PermissionManager";
|
||||
import {Sound} from "../../sound/Sounds";
|
||||
|
||||
export namespace top_menu {
|
||||
export interface HRItem { }
|
||||
|
||||
export interface MenuItem {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
enum ChatType {
|
||||
import {log, LogCategory} from "../../log";
|
||||
|
||||
export enum ChatType {
|
||||
GENERAL,
|
||||
SERVER,
|
||||
CHANNEL,
|
||||
|
@ -6,7 +8,7 @@ enum ChatType {
|
|||
}
|
||||
|
||||
declare const xbbcode: any;
|
||||
namespace MessageHelper {
|
||||
export namespace MessageHelper {
|
||||
export function htmlEscape(message: string) : string[] {
|
||||
const div = document.createElement('div');
|
||||
div.innerText = message;
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
/* the bar on the right with the chats (Channel & Client) */
|
||||
namespace chat {
|
||||
import {ChannelEntry} from "../../channel-tree/channel";
|
||||
import {Modals} from "../modal/ModalMusicManage";
|
||||
import {MessageHelper} from "./chat";
|
||||
import {ServerEntry} from "../../channel-tree/server";
|
||||
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||
|
||||
export namespace chat {
|
||||
declare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import {ConnectionHandler, DisconnectReason} from "../../ConnectionHandler";
|
||||
import {Settings, settings} from "../../settings";
|
||||
import {control_bar} from "./ControlBar";
|
||||
import {top_menu} from "./MenuBar";
|
||||
|
||||
let server_connections: ServerConnectionManager;
|
||||
export let server_connections: ServerConnectionManager;
|
||||
|
||||
class ServerConnectionManager {
|
||||
export class ServerConnectionManager {
|
||||
private connection_handlers: ConnectionHandler[] = [];
|
||||
private active_handler: ConnectionHandler | undefined;
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
class Hostbanner {
|
||||
import {ConnectionHandler} from "../../ConnectionHandler";
|
||||
import {Settings, settings} from "../../settings";
|
||||
import {log, LogCategory} from "../../log";
|
||||
|
||||
export class Hostbanner {
|
||||
readonly html_tag: JQuery<HTMLElement>;
|
||||
readonly client: ConnectionHandler;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace image_preview {
|
||||
export namespace image_preview {
|
||||
let preview_overlay: JQuery<HTMLDivElement>;
|
||||
let container_image: JQuery<HTMLDivElement>;
|
||||
let button_open_in_browser: JQuery;
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
namespace log {
|
||||
import {ConnectionHandler, ViewReasonId} from "../../ConnectionHandler";
|
||||
import {PermissionInfo} from "../../permission/PermissionManager";
|
||||
import {htmltags} from "../htmltags";
|
||||
import {MessageHelper} from "./chat";
|
||||
import {i18n} from "../../i18n/localize";
|
||||
|
||||
export namespace server {
|
||||
export enum Type {
|
||||
CONNECTION_BEGIN = "connection_begin",
|
||||
|
@ -365,12 +370,13 @@ namespace log {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* impl of the parsers */
|
||||
namespace log {
|
||||
export namespace server {
|
||||
namespace impl {
|
||||
import MessageBuilders = server.MessageBuilders;
|
||||
import base = server.base;
|
||||
import tra = i18n.tra;
|
||||
const client_tag = (client: base.Client, braces?: boolean) => htmltags.generate_client_object({
|
||||
client_unique_id: client.client_unique_id,
|
||||
client_id: client.client_id,
|
||||
|
@ -384,7 +390,7 @@ namespace log {
|
|||
add_braces: braces
|
||||
});
|
||||
|
||||
MessageBuilders["connection_begin"] = (data: event.ConnectBegin, options) => {
|
||||
MessageBuilders["connection_begin"] = (data: server.event.ConnectBegin, options) => {
|
||||
return MessageHelper.formatMessage(tr("Connecting to {0}{1}"), data.address.server_hostname, data.address.server_port == 9987 ? "" : (":" + data.address.server_port));
|
||||
};
|
||||
|
||||
|
@ -563,4 +569,3 @@ namespace log {
|
|||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace chat {
|
||||
export namespace chat {
|
||||
declare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace chat {
|
||||
export namespace chat {
|
||||
export namespace helpers {
|
||||
//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;
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
namespace chat {
|
||||
import {ClientEntry, LocalClientEntry} from "../../../channel-tree/client";
|
||||
import {Modals} from "../../modal/ModalClientInfo";
|
||||
import {htmltags} from "../../htmltags";
|
||||
import {image_preview} from "../image_preview";
|
||||
import {i18n} from "../../../i18n/country";
|
||||
import {GroupManager} from "../../../permission/GroupManager";
|
||||
|
||||
export namespace chat {
|
||||
declare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
namespace chat {
|
||||
import {htmltags} from "../../htmltags";
|
||||
import {MessageHelper} from "../chat";
|
||||
import {CommandResult, ErrorID} from "../../../connection/ServerConnectionDeclaration";
|
||||
import {log, LogCategory} from "../../../log";
|
||||
import {createErrorModal} from "../../elements/modal";
|
||||
|
||||
export namespace chat {
|
||||
declare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
namespace chat {
|
||||
import PlayerState = connection.voice.PlayerState;
|
||||
import {MusicClientEntry} from "../../../channel-tree/client";
|
||||
import {image_preview} from "../image_preview";
|
||||
|
||||
export namespace chat {
|
||||
declare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
/* the bar on the right with the chats (Channel & Client) */
|
||||
namespace chat {
|
||||
import {log, LogCategory} from "../../../log";
|
||||
import {htmltags} from "../../htmltags";
|
||||
import {MessageHelper} from "../chat";
|
||||
|
||||
export namespace chat {
|
||||
declare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace htmltags {
|
||||
export namespace htmltags {
|
||||
let mouse_coordinates: {x: number, y: number} = {x: 0, y: 0};
|
||||
|
||||
function initialize() {
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
function format_date(date: number) {
|
||||
const d = new Date(date);
|
||||
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
//TODO: Test if we could render this image and not only the browser by knowing the type.
|
||||
export function spawnAvatarUpload(callback_data: (data: ArrayBuffer | undefined | null) => any) {
|
||||
const modal = createModal({
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
const avatar_to_uid = (id: string) => {
|
||||
const buffer = new Uint8Array(id.length / 2);
|
||||
for(let index = 0; index < id.length; index += 2) {
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export type BanEntry = {
|
||||
name?: string;
|
||||
unique_id: string;
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../i18n/localize.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function openBanList(client: ConnectionHandler) {
|
||||
let modal: Modal;
|
||||
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function spawnBookmarkModal() {
|
||||
let modal: Modal;
|
||||
modal = createModal({
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
let modal: Modal;
|
||||
export function spawnChangeLatency(client: ClientEntry, current: connection.voice.LatencySettings, reset: () => connection.voice.LatencySettings, apply: (settings: connection.voice.LatencySettings) => any, callback_flush?: () => any) {
|
||||
if(modal) modal.close();
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
//TODO: Use the max limit!
|
||||
|
||||
let modal: Modal;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function openChannelInfo(channel: ChannelEntry) {
|
||||
let modal: Modal;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Modals {
|
||||
export namespace Modals {
|
||||
type InfoUpdateCallback = (info: ClientConnectionInfo) => any;
|
||||
export function openClientInfo(client: ClientEntry) {
|
||||
let modal: Modal;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
|
||||
//FIXME: Move this shit out of this file!
|
||||
namespace connection_log {
|
||||
export namespace connection_log {
|
||||
//TODO: Save password data
|
||||
export type ConnectionData = {
|
||||
name: string;
|
||||
|
@ -91,7 +89,7 @@ namespace connection_log {
|
|||
});
|
||||
}
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function spawnConnectModal(options: {
|
||||
default_connect_new_tab?: boolean /* default false */
|
||||
}, defaultHost: { url: string, enforce: boolean} = { url: "ts.TeaSpeak.de", enforce: false}, connect_profile?: { profile: profiles.ConnectionProfile, enforce: boolean}) {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
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
|
||||
const modal = createModal({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Modals {
|
||||
export namespace Modals {
|
||||
let current_modal: Modal;
|
||||
export function createServerGroupAssignmentModal(client: ClientEntry, callback: (groups: number[], flag: boolean) => Promise<boolean>) {
|
||||
if(current_modal)
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function spawnIconSelect(client: ConnectionHandler, callback_icon?: (id: number) => any, selected_icon?: number) {
|
||||
selected_icon = selected_icon || 0;
|
||||
let allow_manage = client.permissions.neededPermission(PermissionType.B_ICON_MANAGE).granted(1);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function spawnTeamSpeakIdentityImprove(identity: profiles.identities.TeaSpeakIdentity, name: string): Modal {
|
||||
let modal: Modal;
|
||||
let elapsed_timer: NodeJS.Timer;
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
type URLGeneratorSettings = {
|
||||
flag_direct: boolean,
|
||||
flag_resolved: boolean
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function spawnKeySelect(callback: (key?: ppt.KeyEvent) => void) {
|
||||
let modal = createModal({
|
||||
header: tr("Select a key"),
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function openMusicManage(client: ConnectionHandler, bot: MusicClientEntry) {
|
||||
const ev_registry = new events.Registry<events.modal.music_manage>();
|
||||
ev_registry.enable_debug("music-manage");
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
const next_step: {[key: string]:string} = {
|
||||
"welcome": "microphone",
|
||||
//"microphone": app.is_web() ? "identity" : "speaker", /* speaker setup only for the native client! */
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function spawnPlaylistSongInfo(song: PlaylistSong) {
|
||||
let modal: Modal;
|
||||
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../i18n/localize.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function spawnPlaylistManage(client: ConnectionHandler) {
|
||||
{
|
||||
createErrorModal(tr("Not implemented"), tr("Playlist management hasn't yet been implemented")).open();
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
let global_modal: PokeModal;
|
||||
|
||||
interface ServerEntry {
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function spawnQueryCreate(connection: ConnectionHandler, callback_created?: (user, pass) => any) {
|
||||
let modal;
|
||||
modal = createModal({
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="../../ui/elements/modal.ts" />
|
||||
/// <reference path="../../ConnectionHandler.ts" />
|
||||
/// <reference path="../../proto.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export namespace Modals {
|
||||
/*
|
||||
export function spawnQueryManage(client: ConnectionHandler) {
|
||||
let modal: Modal;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Modals {
|
||||
export namespace Modals {
|
||||
export function createServerModal(server: ServerEntry, callback: (properties?: ServerProperties) => Promise<void>) {
|
||||
const properties = Object.assign({}, server.properties);
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue