TeaWeb/shared/js/proto.ts

313 lines
9.7 KiB
TypeScript
Raw Normal View History

2018-02-27 17:20:49 +01:00
interface Array<T> {
remove(elem?: T): boolean;
last?(): T;
pop_front(): T | undefined;
}
2018-08-10 21:30:58 +02:00
interface JSON {
map_to<T>(object: T, json: any, variables?: string | string[], validator?: (map_field: string, map_value: string) => boolean, variable_direction?: number) : T;
map_field_to<T>(object: T, value: any, field: string) : T;
}
2019-04-04 21:47:52 +02:00
type JQueryScrollType = "height" | "width";
2018-12-04 18:48:54 +01:00
interface JQuery<TElement = HTMLElement> {
render(values?: any) : string;
2018-12-04 18:48:54 +01:00
renderTag(values?: any) : JQuery<TElement>;
2019-04-04 21:47:52 +02:00
hasScrollBar(direction?: JQueryScrollType) : boolean;
Implemented the Material Design and fixed some bugs (#33) * cleaned up some files * Fundamental style update * Redesigned some style * fixed hostbanner popup * Removed old identity stuff * fixed close listener * Fixed changelog date * fixed release chat icons * fixed url * Fixed hostbanner * Uploaded missing images * Improved update handling * Improved script files * Fixed loading error and icon error * fixed Yes/No modal * Fixed loader issues with MS Edge * fixed modal style bug * Fixed control bar overflow for small devices * Improved error handling on identity creation * Logging generate error to terminal * fixed possible php error * fixed some possible loading errors when other files have'nt been already loaded. * removed debug message * Changed emsrcypten flags * Improved codec error handling * removed webassembly as required dependency * Improved and fixed channel tree issues * Improved the sliders * Removed unneeded files * fixed loader versions cache * second slight performance improved (dont animate elements anymore if they are not shown) * Fixed query visibility setting * not showing useless client infos for query clients * Added an auto reconnect system * Added a canceled message and increased reconnect interval * removed implemented todo * fixed repetitive channel names * Reworked the channel tree selected lines * Fixed channel tree names * Fixed name alignment * fixed the native client * added min width to the server select groups to avoid a disappearing effect on shrink * fixed bugged downloaded icons
2019-02-17 16:08:10 +01:00
visible_height() : number;
visible_width() : number;
/* bootstrap */
alert() : JQuery<TElement>;
modal(properties: any) : this;
bootstrapMaterialDesign() : this;
2019-08-21 10:00:01 +02:00
/* first element which matches the selector, could be the element itself or a parent */
firstParent(selector: string) : JQuery;
2018-02-27 17:20:49 +01:00
}
interface JQueryStatic<TElement extends Node = HTMLElement> {
spawn<K extends keyof HTMLElementTagNameMap>(tagName: K): JQuery<HTMLElementTagNameMap[K]>;
views: any;
2018-02-27 17:20:49 +01:00
}
interface String {
format(...fmt): string;
2018-04-11 17:56:09 +02:00
format(arguments: string[]): string;
2018-02-27 17:20:49 +01:00
}
2018-08-10 21:30:58 +02:00
if(!JSON.map_to) {
2018-09-30 21:50:59 +02:00
JSON.map_to = function <T>(object: T, json: any, variables?: string | string[], validator?: (map_field: string, map_value: string) => boolean, variable_direction?: number): T {
if (!validator) validator = (a, b) => true;
2018-08-10 21:30:58 +02:00
2018-09-30 21:50:59 +02:00
if (!variables) {
2018-08-10 21:30:58 +02:00
variables = [];
2018-09-30 21:50:59 +02:00
if (!variable_direction || variable_direction == 0) {
for (let field in json)
2018-08-10 21:30:58 +02:00
variables.push(field);
2018-09-30 21:50:59 +02:00
} else if (variable_direction == 1) {
for (let field in object)
2018-08-10 21:30:58 +02:00
variables.push(field);
}
2018-09-30 21:50:59 +02:00
} else if (!Array.isArray(variables)) {
2018-08-10 21:30:58 +02:00
variables = [variables];
}
2018-09-30 21:50:59 +02:00
for (let field of variables) {
if (!json[field]) {
console.trace(tr("Json does not contains %s"), field);
2018-08-10 21:30:58 +02:00
continue;
}
2018-09-30 21:50:59 +02:00
if (!validator(field, json[field])) {
console.trace(tr("Validator results in false for %s"), field);
2018-08-10 21:30:58 +02:00
continue;
}
JSON.map_field_to(object, json[field], field);
}
return object;
}
}
if(!JSON.map_field_to) {
JSON.map_field_to = function<T>(object: T, value: any, field: string) : T {
let field_type = typeof(object[field]);
if(field_type == "string" || field_type == "object" || field_type == "undefined")
object[field as string] = value;
else if(field_type == "number")
object[field as string] = parseFloat(value);
else if(field_type == "boolean")
object[field as string] = value == "1" || value == "true";
else console.warn(tr("Invalid object type %s for entry %s"), field_type, field);
2018-08-10 21:30:58 +02:00
return object;
}
}
2018-02-27 17:20:49 +01:00
if (!Array.prototype.remove) {
Array.prototype.remove = function<T>(elem?: T): boolean {
2018-03-24 23:38:01 +01:00
const index = this.indexOf(elem, 0);
2018-02-27 17:20:49 +01:00
if (index > -1) {
this.splice(index, 1);
return true;
}
return false;
}
}
if (!Array.prototype.pop_front) {
Array.prototype.pop_front = function<T>(): T {
if(this.length == 0) return undefined;
return this.splice(0, 1)[0];
}
}
2018-04-16 20:38:35 +02:00
2018-02-27 17:20:49 +01:00
if (!Array.prototype.last){
Array.prototype.last = function(){
if(this.length == 0) return undefined;
return this[this.length - 1];
};
}
2018-04-11 17:56:09 +02:00
if(typeof ($) !== "undefined") {
if(!$.spawn) {
$.spawn = function<K extends keyof HTMLElementTagNameMap>(tagName: K): JQuery<HTMLElementTagNameMap[K]> {
return $(document.createElement(tagName) as any);
2018-04-11 17:56:09 +02:00
}
2018-02-27 17:20:49 +01:00
}
2018-12-23 17:41:14 +01:00
if(!$.fn.renderTag) {
$.fn.renderTag = function (this: JQuery, values?: any) : JQuery {
let result;
if(this.render) {
result = $(this.render(values));
} else {
const template = window.jsrender.render[this.attr("id")];
if(!template) {
console.error("Tried to render template %o, but template is not available!", this.attr("id"));
throw "missing template " + this.attr("id");
}
/*
result = window.jsrender.templates("tmpl_permission_entry", $("#tmpl_permission_entry").html());
result = window.jsrender.templates("xxx", this.html());
*/
result = template(values);
result = $(result);
}
2018-09-30 22:36:17 +02:00
result.find("node").each((index, element) => {
2018-11-04 00:39:29 +01:00
$(element).replaceWith(values[$(element).attr("key")] || (values[0] || [])[$(element).attr("key")]);
2018-09-30 22:36:17 +02:00
});
2018-09-30 21:50:59 +02:00
return result;
}
}
2018-12-23 17:41:14 +01:00
if(!$.fn.hasScrollBar)
2019-04-04 21:47:52 +02:00
$.fn.hasScrollBar = function(direction?: "height" | "width") {
if(this.length <= 0)
return false;
const scroll_height = this.get(0).scrollHeight > this.height();
const scroll_width = this.get(0).scrollWidth > this.width();
if(typeof(direction) === "string") {
if(direction === "height")
return scroll_height;
if(direction === "width")
return scroll_width;
}
return scroll_width || scroll_height;
};
2018-12-23 17:41:14 +01:00
Implemented the Material Design and fixed some bugs (#33) * cleaned up some files * Fundamental style update * Redesigned some style * fixed hostbanner popup * Removed old identity stuff * fixed close listener * Fixed changelog date * fixed release chat icons * fixed url * Fixed hostbanner * Uploaded missing images * Improved update handling * Improved script files * Fixed loading error and icon error * fixed Yes/No modal * Fixed loader issues with MS Edge * fixed modal style bug * Fixed control bar overflow for small devices * Improved error handling on identity creation * Logging generate error to terminal * fixed possible php error * fixed some possible loading errors when other files have'nt been already loaded. * removed debug message * Changed emsrcypten flags * Improved codec error handling * removed webassembly as required dependency * Improved and fixed channel tree issues * Improved the sliders * Removed unneeded files * fixed loader versions cache * second slight performance improved (dont animate elements anymore if they are not shown) * Fixed query visibility setting * not showing useless client infos for query clients * Added an auto reconnect system * Added a canceled message and increased reconnect interval * removed implemented todo * fixed repetitive channel names * Reworked the channel tree selected lines * Fixed channel tree names * Fixed name alignment * fixed the native client * added min width to the server select groups to avoid a disappearing effect on shrink * fixed bugged downloaded icons
2019-02-17 16:08:10 +01:00
if(!$.fn.visible_height)
$.fn.visible_height = function (this: JQuery<HTMLElement>) {
const original_style = this.attr("style");
this.css({
position: 'absolute!important',
visibility: 'hidden!important',
display: 'block!important'
});
const result = this.height();
this.attr("style", original_style || "");
return result;
}
if(!$.fn.visible_width)
$.fn.visible_width = function (this: JQuery<HTMLElement>) {
const original_style = this.attr("style");
this.css({
position: 'absolute!important',
visibility: 'hidden!important',
display: 'block!important'
});
const result = this.width();
this.attr("style", original_style || "");
return result;
}
2019-08-21 10:00:01 +02:00
if(!$.fn.firstParent)
$.fn.firstParent = function (this: JQuery<HTMLElement>, selector: string) {
if(this.is(selector))
return this;
return this.parent(selector);
}
2018-02-27 17:20:49 +01:00
}
if (!String.prototype.format) {
String.prototype.format = function() {
2018-03-24 23:38:01 +01:00
const args = arguments;
2018-04-11 17:56:09 +02:00
let array = args.length == 1 && $.isArray(args[0]);
2018-02-27 17:20:49 +01:00
return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) {
if (m == "{{") { return "{"; }
if (m == "}}") { return "}"; }
2018-04-11 17:56:09 +02:00
return array ? args[0][n] : args[n];
2018-02-27 17:20:49 +01:00
});
};
}
function concatenate(resultConstructor, ...arrays) {
let totalLength = 0;
for (const arr of arrays) {
totalLength += arr.length;
}
const result = new resultConstructor(totalLength);
let offset = 0;
for (const arr of arrays) {
result.set(arr, offset);
offset += arr.length;
}
return result;
}
function formatDate(secs: number) : string {
let years = Math.floor(secs / (60 * 60 * 24 * 365));
let days = Math.floor(secs / (60 * 60 * 24)) % 365;
let hours = Math.floor(secs / (60 * 60)) % 24;
let minutes = Math.floor(secs / 60) % 60;
let seconds = Math.floor(secs % 60);
let result = "";
if(years > 0)
result += years + " " + tr("years") + " ";
2018-02-27 17:20:49 +01:00
if(years > 0 || days > 0)
result += days + " " + tr("days") + " ";
2018-02-27 17:20:49 +01:00
if(years > 0 || days > 0 || hours > 0)
result += hours + " " + tr("hours") + " ";
2018-02-27 17:20:49 +01:00
if(years > 0 || days > 0 || hours > 0 || minutes > 0)
result += minutes + " " + tr("minutes") + " ";
2018-02-27 17:20:49 +01:00
if(years > 0 || days > 0 || hours > 0 || minutes > 0 || seconds > 0)
result += seconds + " " + tr("seconds") + " ";
2018-02-27 17:20:49 +01:00
else
result = tr("now") + " ";
2018-02-27 17:20:49 +01:00
return result.substr(0, result.length - 1);
2018-08-10 21:30:58 +02:00
}
function calculate_width(text: string) : number {
let element = $.spawn("div");
element.text(text)
.css("display", "none")
.css("margin", 0);
$("body").append(element);
let size = element.width();
element.detach();
return size;
2018-09-26 15:30:22 +02:00
}
2019-08-21 10:00:01 +02:00
interface Twemoji {
parse(message: string) : string;
}
declare let twemoji: Twemoji;
interface HighlightJS {
listLanguages() : string[];
getLanguage(name: string) : any | undefined;
highlight(language: string, text: string, ignore_illegals?: boolean) : HighlightJSResult;
highlightAuto(text: string) : HighlightJSResult;
}
interface HighlightJSResult {
language: string;
relevance: number;
value: string;
second_best?: any;
}
interface DOMPurify {
sanitize(html: string, config?: {
ADD_ATTR?: string[]
}) : string;
}
declare let DOMPurify: DOMPurify;
declare let remarkable: typeof window.remarkable;
2018-09-26 15:30:22 +02:00
declare class webkitAudioContext extends AudioContext {}
declare class webkitOfflineAudioContext extends OfflineAudioContext {}
2019-08-21 10:00:01 +02:00
2018-09-26 15:30:22 +02:00
interface Window {
readonly webkitAudioContext: typeof webkitAudioContext;
readonly AudioContext: typeof webkitAudioContext;
readonly OfflineAudioContext: typeof OfflineAudioContext;
readonly webkitOfflineAudioContext: typeof webkitOfflineAudioContext;
readonly RTCPeerConnection: typeof RTCPeerConnection;
2018-09-30 21:50:59 +02:00
readonly Pointer_stringify: any;
readonly jsrender: any;
2019-08-21 10:00:01 +02:00
twemoji: Twemoji;
hljs: HighlightJS;
remarkable: any;
2018-10-02 18:38:58 +02:00
require(id: string): any;
2018-09-30 21:50:59 +02:00
}
interface Navigator {
browserSpecs: {
name: string,
version: string
};
2018-02-27 17:20:49 +01:00
}