added typescript files converted from js files
This commit is contained in:
@@ -15,7 +15,7 @@ import toggleButton from "./components/toggleButton";
|
||||
import helper from "./utils/helper";
|
||||
import { translate as t, translatePlural as n } from "@nextcloud/l10n";
|
||||
import Http from "./lib/http";
|
||||
import nctable from "./lib/ncTable";
|
||||
import contentTable from "./lib/contentTable";
|
||||
|
||||
const successCallback = (data, element) => {
|
||||
if (!data) {
|
||||
@@ -83,7 +83,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
helper.enabledPolling = 0;
|
||||
nctable.getInstance().loading();
|
||||
contentTable.getInstance().loading();
|
||||
|
||||
let url = formWrapper.getAttribute("action");
|
||||
Http.getInstance(url)
|
||||
@@ -91,7 +91,7 @@ export default {
|
||||
.setHandler(function (data) {
|
||||
if (data && data.title) {
|
||||
vm.$data.loading = 0;
|
||||
const tableInst = nctable.getInstance(data.title, data.row);
|
||||
const tableInst = contentTable.getInstance(data.title, data.row);
|
||||
tableInst.actionLink = false;
|
||||
tableInst.rowClass = "table-row-search";
|
||||
tableInst.create();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Http from '../lib/http'
|
||||
import helper from '../utils/helper'
|
||||
import eventHandler from '../lib/eventHandler'
|
||||
import Clipboard from '../utils/clipboard'
|
||||
import Clipboard from '../lib/clipboard'
|
||||
import '../css/clipboard.scss';
|
||||
|
||||
const buttonHandler = (event, type) => {
|
||||
|
||||
64
src/lib/clipboard.ts
Normal file
64
src/lib/clipboard.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import Tooltip from "./tooltip";
|
||||
|
||||
class Clipboard {
|
||||
text: string;
|
||||
element: string | Element | HTMLElement;
|
||||
|
||||
constructor(element:string | Element | HTMLElement, text:string) {
|
||||
this.element = typeof element == 'object' ? element : document.querySelector(element);
|
||||
this.text = text || this.element.getAttribute("data-text");
|
||||
}
|
||||
|
||||
_copy(text:string) {
|
||||
let textArea = document.createElement("textarea");
|
||||
textArea.value = text;
|
||||
|
||||
textArea.style.top = "0";
|
||||
textArea.style.left = "0";
|
||||
textArea.style.position = "fixed";
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
let result;
|
||||
try {
|
||||
result = document.execCommand('copy');
|
||||
//console.log('copied using exceCommand');
|
||||
|
||||
} catch (err) {
|
||||
console.error('failed to copy', err);
|
||||
result = false;
|
||||
} finally {
|
||||
document.body.removeChild(textArea);
|
||||
}
|
||||
if (result) {
|
||||
this.ShowMsg("Copied!");
|
||||
}
|
||||
}
|
||||
|
||||
ShowMsg(msg:string) {
|
||||
let tip = new Tooltip(this.element, msg);
|
||||
let html = tip.create('copy-alert').html();
|
||||
document.body.appendChild(html);
|
||||
const callback = (element:Element) => {
|
||||
element.remove()
|
||||
}
|
||||
setTimeout(() => {
|
||||
callback(html)
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
Copy() {
|
||||
if (!navigator.clipboard) {
|
||||
return this._copy(this.text);
|
||||
}
|
||||
return navigator.clipboard.writeText(this.text).then(() => {
|
||||
this.ShowMsg("Copied!");
|
||||
}, function (err) {
|
||||
console.error('failed to copy text: ', err);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Clipboard;
|
||||
162
src/lib/contentTable.ts
Normal file
162
src/lib/contentTable.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
import helper from '../utils/helper'
|
||||
interface Map {
|
||||
[key: string]: string | {} | Array<any>
|
||||
}
|
||||
type rowData = Array<Map>
|
||||
|
||||
class contentTable {
|
||||
actionLink: boolean = true;
|
||||
bodyClass: string = "ncdownloader-table-data";
|
||||
rowClass: string = "table-row";
|
||||
headingClass: string = "table-heading";
|
||||
cellClass: string = "table-cell";
|
||||
//this is the parent element the table is going to append to
|
||||
tableContainer: string = 'ncdownloader-table-wrapper';
|
||||
numRow: number;
|
||||
table: HTMLElement;
|
||||
rows: rowData
|
||||
heading: Array<string>
|
||||
actionButtons: Array<{}>
|
||||
|
||||
constructor(heading: Array<string>, rows: rowData) {
|
||||
this.table = document.getElementById(this.tableContainer) as HTMLElement;
|
||||
if (heading && rows) {
|
||||
this.table.innerHTML = '';
|
||||
this.rows = rows;
|
||||
this.heading = heading;
|
||||
}
|
||||
}
|
||||
static getInstance(heading: Array<string>, rows: rowData) {
|
||||
return new contentTable(heading, rows);
|
||||
}
|
||||
create(): contentTable {
|
||||
let thead = this.createHeading()
|
||||
let tbody = this.createRow();
|
||||
this.table.appendChild(thead);
|
||||
this.table.appendChild(tbody);
|
||||
return this;
|
||||
}
|
||||
clear() {
|
||||
this.table.innerHTML = '';
|
||||
}
|
||||
loading() {
|
||||
let htmlStr = '<div class="text-center"><div class="spinner-border" role="status"> <span class="visually-hidden">Loading...</span></div></div>'
|
||||
this.table.innerHTML = htmlStr;
|
||||
return this;
|
||||
}
|
||||
noData() {
|
||||
this.clear();
|
||||
let div = document.createElement('div');
|
||||
div.classList.add("no-items");
|
||||
div.appendChild(document.createTextNode(helper.t('No items')));
|
||||
this.table.appendChild(div);
|
||||
}
|
||||
createHeading(prefix = "table-heading") {
|
||||
let thead = document.createElement("section");
|
||||
thead.classList.add(this.headingClass);
|
||||
let headRow = document.createElement("header");
|
||||
headRow.classList.add(this.rowClass);
|
||||
thead.classList.add(this.headingClass);
|
||||
this.heading.forEach(name => {
|
||||
let rowItem = document.createElement("div");
|
||||
rowItem.classList.add(prefix + "-" + name.toLowerCase());
|
||||
rowItem.classList.add(this.cellClass);
|
||||
let text = document.createTextNode(helper.t(helper.ucfirst(name)));
|
||||
rowItem.appendChild(text);
|
||||
headRow.appendChild(rowItem);
|
||||
})
|
||||
thead.appendChild(headRow);
|
||||
return thead;
|
||||
}
|
||||
createRow() {
|
||||
let tbody = document.createElement("section");
|
||||
tbody.classList.add(this.bodyClass);
|
||||
tbody.classList.add("table-body");
|
||||
let row;
|
||||
for (const element of this.rows) {
|
||||
if (element === null) {
|
||||
continue;
|
||||
}
|
||||
row = document.createElement("div");
|
||||
row.classList.add(this.rowClass);
|
||||
let text;
|
||||
for (let key in element) {
|
||||
if (key.substring(0, 4) == 'data') {
|
||||
let name = key.replace("_", "-");
|
||||
if (typeof element[key] == "string") {
|
||||
row.setAttribute(name, (<string>element[key]));
|
||||
row.setAttribute("id", (<string>element[key]));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
let rowItem = document.createElement("div");
|
||||
rowItem.classList.add(this.cellClass);
|
||||
if (key === 'actions' && Array.isArray(element[key])) {
|
||||
let tmp = element[key] as Array<any>;
|
||||
rowItem.classList.add([this.cellClass, "action-item"].join("-"));
|
||||
let container = document.createElement("div");
|
||||
container.classList.add("button-container");
|
||||
tmp.forEach(value => {
|
||||
if (!value.name) {
|
||||
return;
|
||||
}
|
||||
let data = value.data || '';
|
||||
container.appendChild(this.createActionButton(value.name, value.path, data));
|
||||
})
|
||||
rowItem.appendChild(container);
|
||||
row.appendChild(rowItem);
|
||||
} else if (Array.isArray(element[key])) {
|
||||
let child = element[key] as any[];
|
||||
let div;
|
||||
child.forEach(ele => {
|
||||
div = document.createElement('div');
|
||||
if (helper.isHtml(ele)) {
|
||||
div.innerHTML = ele;
|
||||
} else {
|
||||
text = document.createTextNode(ele);
|
||||
div.appendChild(text);
|
||||
}
|
||||
rowItem.appendChild(div);
|
||||
})
|
||||
rowItem.setAttribute("id", [this.cellClass, key].join("-"));
|
||||
row.appendChild(rowItem);
|
||||
continue;
|
||||
} else if (typeof element[key] === "string") {
|
||||
text = document.createTextNode(element[key] as string);
|
||||
rowItem.appendChild(text);
|
||||
rowItem.setAttribute("id", [this.cellClass, key].join("-"));
|
||||
row.appendChild(rowItem);
|
||||
}
|
||||
}
|
||||
tbody.appendChild(row);
|
||||
}
|
||||
return tbody;
|
||||
|
||||
}
|
||||
|
||||
createActionButton(name: string, path: string, data: string) {
|
||||
let button = document.createElement("button");
|
||||
button.classList.add("icon-" + name);
|
||||
button.setAttribute("path", path);
|
||||
button.setAttribute("data", data);
|
||||
if (name == 'refresh') {
|
||||
name = helper.t('Redownload');
|
||||
}
|
||||
button.setAttribute("data-tippy-content", helper.ucfirst(name));
|
||||
button.setAttribute("title", helper.ucfirst(name));
|
||||
return button;
|
||||
}
|
||||
|
||||
createActionCell(cell: HTMLElement) {
|
||||
let div = document.createElement("div");
|
||||
let button = document.createElement("button");
|
||||
button.classList.add("icon-more", "action-button");
|
||||
button.setAttribute("id", "action-links-button");
|
||||
div.classList.add("action-item");
|
||||
div.appendChild(button);
|
||||
//div.appendChild(actionLinks);
|
||||
cell.appendChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
export default contentTable;
|
||||
40
src/lib/eventHandler.ts
Normal file
40
src/lib/eventHandler.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
type callback = (event: any) => void;
|
||||
type target = string | Element | HTMLElement
|
||||
|
||||
const eventHandler = {
|
||||
add: function (eventType: string, target: target, selector: string | callback | Element, callback?: callback) {
|
||||
if (typeof selector === 'function' && !callback) {
|
||||
callback = selector;
|
||||
selector = target;
|
||||
}
|
||||
if (typeof target === 'object') {
|
||||
|
||||
target.addEventListener(eventType, function (e) {
|
||||
callback.call(target, e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
let el = document.querySelector(target);
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
el.addEventListener(eventType, function (e) {
|
||||
let element = e.target as HTMLElement;
|
||||
if (element === this && selector === target) {
|
||||
callback.call(element, e);
|
||||
return;
|
||||
}
|
||||
for (; element && element != this; element = element.parentElement) {
|
||||
if (typeof selector === "string" && element.matches(selector)) {
|
||||
callback.call(element, e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
remove: function (element: target, eventType: string, callback: callback) {
|
||||
|
||||
(<Element>element).removeEventListener(eventType, callback);
|
||||
}
|
||||
}
|
||||
export default eventHandler;
|
||||
79
src/lib/http.ts
Normal file
79
src/lib/http.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
type httpData = {
|
||||
[key: string]: any
|
||||
}
|
||||
type httpMethod = "POST" | "HEAD" | "GET";
|
||||
type handler = (data: any) => void;
|
||||
const Http = class {
|
||||
data: httpData;
|
||||
url: string;
|
||||
method: httpMethod;
|
||||
dataType: string;
|
||||
xhr: XMLHttpRequest;
|
||||
handler: handler;
|
||||
errorHandler: handler;
|
||||
|
||||
constructor(url: string) {
|
||||
this.url = url;
|
||||
this.method = 'POST';
|
||||
this.data = null;
|
||||
this.dataType = 'application/json';
|
||||
this.xhr = new XMLHttpRequest();
|
||||
}
|
||||
static getInstance(url: string) {
|
||||
return new Http(url);
|
||||
}
|
||||
setData(data: httpData) {
|
||||
this.data = data
|
||||
return this
|
||||
}
|
||||
setDataType(value: string) {
|
||||
this.dataType = value;
|
||||
}
|
||||
send() {
|
||||
let token = this.getToken();
|
||||
this.xhr.open(this.method, this.url);
|
||||
this.xhr.setRequestHeader('requesttoken', token)
|
||||
this.xhr.setRequestHeader('OCS-APIREQUEST', 'true')
|
||||
if (this.dataType)
|
||||
this.xhr.setRequestHeader('Content-Type', this.dataType);
|
||||
let callback = this.handler;
|
||||
this.xhr.onload = () => {
|
||||
if (typeof callback === 'function')
|
||||
callback(JSON.parse(this.xhr.response));
|
||||
}
|
||||
this.xhr.onerror = this.errorHandler;
|
||||
this.xhr.send(JSON.stringify(this.data));
|
||||
}
|
||||
getToken() {
|
||||
return document.getElementsByTagName('head')[0].getAttribute('data-requesttoken')
|
||||
}
|
||||
setUrl(url: string) {
|
||||
this.url = url
|
||||
return this
|
||||
}
|
||||
setMethod(method: httpMethod) {
|
||||
this.method = method
|
||||
return this
|
||||
}
|
||||
setHandler(handler: handler) {
|
||||
this.handler = handler || function (data) { };
|
||||
return this;
|
||||
}
|
||||
setErrorHandler(handler: handler) {
|
||||
this.errorHandler = handler
|
||||
return this;
|
||||
}
|
||||
upload(file: File) {
|
||||
const fd = new FormData();
|
||||
this.xhr.open(this.method, this.url, true);
|
||||
let callback = this.handler;
|
||||
this.xhr.onload = () => {
|
||||
if (typeof callback === 'function')
|
||||
callback(JSON.parse(this.xhr.response));
|
||||
}
|
||||
fd.append('torrentfile', file);
|
||||
return this.xhr.send(fd);
|
||||
}
|
||||
}
|
||||
|
||||
export default Http
|
||||
77
src/lib/msg.ts
Normal file
77
src/lib/msg.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
type Response = {
|
||||
data: { message: string };
|
||||
status: string;
|
||||
}
|
||||
export default {
|
||||
startSaving(selector: string) {
|
||||
this.startAction(selector, t('core', 'Saving …'))
|
||||
},
|
||||
|
||||
startAction(selector: string, message: string) {
|
||||
let el = document.querySelector(selector) as HTMLElement;
|
||||
el.style.removeProperty("display")
|
||||
el.textContent = message;
|
||||
},
|
||||
|
||||
finishedSaving(selector: string, response: Response) {
|
||||
this.finishedAction(selector, response)
|
||||
},
|
||||
|
||||
finishedAction(selector: string, response: Response) {
|
||||
if (response.status === 'success') {
|
||||
this.finishedSuccess(selector, response.data.message)
|
||||
} else {
|
||||
this.finishedError(selector, response.data.message)
|
||||
}
|
||||
},
|
||||
|
||||
finishedSuccess(selector: string, message: string) {
|
||||
let el = document.querySelector(selector);
|
||||
el.textContent = message;
|
||||
if (el.classList.contains("error")) el.classList.remove("error");
|
||||
el.classList.add("success");
|
||||
this.fadeOut(el);
|
||||
},
|
||||
|
||||
finishedError(selector: string, message: string) {
|
||||
let el = document.querySelector(selector);
|
||||
el.textContent = message;
|
||||
if (el.classList.contains("success")) el.classList.remove("success");
|
||||
el.classList.add("error");
|
||||
},
|
||||
fadeIn(element: HTMLElement, duration = 1000) {
|
||||
(function increment() {
|
||||
element.style.opacity = String(0);
|
||||
element.style.removeProperty("display")
|
||||
let opacity = parseFloat(element.style.opacity);
|
||||
if (opacity !== 1) {
|
||||
setTimeout(() => {
|
||||
opacity += 0.1
|
||||
increment();
|
||||
}, duration / 10);
|
||||
}
|
||||
})();
|
||||
},
|
||||
|
||||
fadeOut(element: HTMLElement, duration = 1000) {
|
||||
let opacity = parseFloat(element.style.opacity) || 1;
|
||||
(function decrement() {
|
||||
if ((opacity -= 0.1) < 0) {
|
||||
element.style.display = 'none'
|
||||
element.style.removeProperty('opacity');
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
decrement();
|
||||
}, duration / 10);
|
||||
}
|
||||
})();
|
||||
},
|
||||
show(el: HTMLElement) {
|
||||
el.style.display = '';
|
||||
},
|
||||
hide(el: HTMLElement) {
|
||||
el.style.display = 'none';
|
||||
}
|
||||
}
|
||||
101
src/lib/settingsForm.ts
Normal file
101
src/lib/settingsForm.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
type dataItems = {
|
||||
name: string;
|
||||
value: any;
|
||||
id: string;
|
||||
type?: "text" | "button" | "radio" | "checkbox";
|
||||
placeholder?: string;
|
||||
}
|
||||
type data = Array<dataItems>
|
||||
|
||||
class settingsForm {
|
||||
parent = "custom-aria2-settings-container";
|
||||
constructor() {
|
||||
|
||||
}
|
||||
static getInstance() {
|
||||
return new this();
|
||||
}
|
||||
setParent(selector: string) {
|
||||
this.parent = selector;
|
||||
return this;
|
||||
}
|
||||
create(parent: HTMLElement, element: dataItems) {
|
||||
let label = this._createLabel(element.name, element.id)
|
||||
let input = this._createInput(element);
|
||||
//let saveBtn = this._createSaveBtn(element.id);
|
||||
let cancelBtn = this._createCancelBtn("has-content");
|
||||
let container = this._createContainer(element.id);
|
||||
[label, input, cancelBtn].forEach(ele => {
|
||||
container.appendChild(ele);
|
||||
})
|
||||
|
||||
return parent.prepend(container);
|
||||
}
|
||||
|
||||
createCustomInput(keyId:string, valueId:string) {
|
||||
let div = this._createContainer(keyId + "-container")
|
||||
let items:dataItems = {
|
||||
id:keyId,
|
||||
name:'',
|
||||
value:''
|
||||
}
|
||||
div.appendChild(this._createInput(items));
|
||||
items.id = valueId
|
||||
div.appendChild(this._createInput(items));
|
||||
div.appendChild(this._createCancelBtn());
|
||||
return div;
|
||||
}
|
||||
|
||||
_createContainer(id: string) {
|
||||
let div = document.createElement("div");
|
||||
div.classList.add(id);
|
||||
return div;
|
||||
}
|
||||
_createCancelBtn(className = '') {
|
||||
let button = document.createElement("button");
|
||||
if (className)
|
||||
button.classList.add(className);
|
||||
//button.setAttribute("type",'button')
|
||||
button.classList.add("icon-close");
|
||||
return button;
|
||||
}
|
||||
_createSaveBtn(id: string) {
|
||||
let button = document.createElement("input");
|
||||
button.setAttribute('type', 'button');
|
||||
button.setAttribute('value', 'save');
|
||||
button.setAttribute("data-rel", id + "-container");
|
||||
return button;
|
||||
}
|
||||
_createLabel(name: string, id: string) {
|
||||
name = name.replace('_', '-');
|
||||
let label = document.createElement("lable");
|
||||
label.setAttribute("for", id);
|
||||
let text = document.createTextNode(name);
|
||||
label.appendChild(text);
|
||||
return label;
|
||||
}
|
||||
_createInput(data: dataItems) {
|
||||
let input = document.createElement('input');
|
||||
let type = data.type || "text";
|
||||
let placeholder = data.placeholder || 'Leave empty if no value needed';
|
||||
let value = data.value || '';
|
||||
input.setAttribute('type', type);
|
||||
input.setAttribute('id', data.id);
|
||||
input.setAttribute("name", data.name || data.id);
|
||||
if (type === 'text') {
|
||||
input.setAttribute('value', value);
|
||||
input.setAttribute('placeholder', placeholder);
|
||||
}
|
||||
input.classList.add('form-input-' + type);
|
||||
return input;
|
||||
}
|
||||
|
||||
render(data: data) {
|
||||
let parent = document.getElementById(this.parent)
|
||||
for (const element of data) {
|
||||
this.create(parent, element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default settingsForm
|
||||
50
src/lib/tooltip.ts
Normal file
50
src/lib/tooltip.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
class Tooltip {
|
||||
id = "ncdownloader-tooltip";
|
||||
messageNode: HTMLDivElement;
|
||||
style = {
|
||||
display: '',
|
||||
position: ''
|
||||
};
|
||||
text: string;
|
||||
element: string | Element | HTMLElement;
|
||||
|
||||
constructor(element: string | HTMLElement | Element, text: string) {
|
||||
this.element = typeof element == 'object' ? element : document.querySelector(element);
|
||||
this.style = {
|
||||
position: 'fixed',
|
||||
display: 'block',
|
||||
}
|
||||
this.text = text || this.element.getAttribute("data-text");
|
||||
}
|
||||
create(id: string) {
|
||||
this.messageNode = document.createElement("div");
|
||||
this.messageNode.classList.add(this.id);
|
||||
this.messageNode.setAttribute("id", this.id);
|
||||
this.messageNode.style.display = this.style.display;
|
||||
this.messageNode.style.position = this.style.position;
|
||||
this.messageNode.style.zIndex = "10000";
|
||||
let div = document.createElement('div');
|
||||
div.setAttribute("id", id);
|
||||
let text = document.createTextNode(this.text);
|
||||
div.appendChild(text);
|
||||
this.messageNode.appendChild(div);
|
||||
this.setPosition();
|
||||
return this;
|
||||
}
|
||||
render() {
|
||||
document.body.appendChild(this.messageNode);
|
||||
}
|
||||
html() {
|
||||
return this.messageNode;
|
||||
}
|
||||
setPosition(bottomMargin: number = 20, leftMargin: number = 0) {
|
||||
let element = this.element as Element;
|
||||
let rect = element.getBoundingClientRect();
|
||||
let top = (rect['top'] + bottomMargin) + "px";
|
||||
let left = (rect['left'] - leftMargin) + "px";
|
||||
this.messageNode.style.top = top;
|
||||
this.messageNode.style.left = left
|
||||
}
|
||||
}
|
||||
|
||||
export default Tooltip;
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
import Toastify from 'toastify-js'
|
||||
import "toastify-js/src/toastify.css"
|
||||
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
|
||||
import nctable from '../lib/ncTable';
|
||||
import contentTable from '../lib/contentTable';
|
||||
import Http from '../lib/http'
|
||||
|
||||
const helper = {
|
||||
@@ -120,9 +120,9 @@ const helper = {
|
||||
let url = helper.generateUrl(path);
|
||||
Http.getInstance(url).setHandler(function (data) {
|
||||
if (data && data.row) {
|
||||
nctable.getInstance(data.title, data.row).create();
|
||||
contentTable.getInstance(data.title, data.row).create();
|
||||
} else {
|
||||
nctable.getInstance().noData();
|
||||
contentTable.getInstance().noData();
|
||||
}
|
||||
if (data.counter)
|
||||
helper.updateCounter(data.counter);
|
||||
@@ -190,7 +190,7 @@ const helper = {
|
||||
},
|
||||
showDownload() {
|
||||
helper.showElement('download');
|
||||
nctable.getInstance().clear();
|
||||
contentTable.getInstance().clear();
|
||||
helper.enabledPolling = 0;
|
||||
},
|
||||
hideDownload() {
|
||||
|
||||
Reference in New Issue
Block a user