279 lines
9.2 KiB
JavaScript
279 lines
9.2 KiB
JavaScript
"use strict";
|
|
|
|
import {RE} from "../Utils/Patterns.ecma.js";
|
|
import {Common} from "../Utils/Common.ecma.js";
|
|
import {Check} from "../Utils/Checks.ecma.js";
|
|
import {
|
|
Div, Span, A, Img, Header, Footer, Main, H1, Nav, UL, LI
|
|
} from "../Utils/HTMLDSL.ecma.js";
|
|
|
|
/**
|
|
* @typedef {import("../Application/AnP.ecma.js").AnP} AnP
|
|
*/
|
|
|
|
/**
|
|
* @class BaseComponent
|
|
* @constructor
|
|
* @param {!AnP} anp
|
|
* @return {void}
|
|
* @access public
|
|
* @static
|
|
*/
|
|
export const BaseComponent = (function(){
|
|
|
|
/**
|
|
* @constructs BaseComponent
|
|
* @param {!AnP} anp
|
|
* @return {void}
|
|
* @access private
|
|
* @static
|
|
*/
|
|
const BaseComponent = function(anp){
|
|
|
|
/** @type {BaseComponent} */
|
|
const self = this,
|
|
/** @type {Object.<number, Object.<string, number>>} */
|
|
caches = {};
|
|
/** @type {integer|null} */
|
|
let thread = null,
|
|
/** @type {Array.<number>} */
|
|
zooms = [.25, .5, .75, 1.0, 1.5, 2.0];
|
|
|
|
/**
|
|
* @returns {void}
|
|
* @access private
|
|
*/
|
|
const constructor = () => {
|
|
|
|
thread = anp.threads.add(thread_method, {
|
|
autostart : true,
|
|
bucle : true
|
|
});
|
|
|
|
};
|
|
|
|
/**
|
|
* @returns {void}
|
|
* @access private
|
|
*/
|
|
const thread_method = () => {
|
|
Object.entries(caches).forEach(([i, cache]) => {
|
|
|
|
/** @type {HTMLDivElement} */
|
|
const base = document.querySelector(".anp[data-i='" + i + "']"),
|
|
date = Date.now();
|
|
|
|
if(!base){
|
|
delete caches[i];
|
|
return;
|
|
};
|
|
|
|
/** @type {number} */
|
|
const cells = Number(base.getAttribute("data-cells")),
|
|
/** @type {number} */
|
|
zoom = Number(base.getAttribute("data-zoom"));
|
|
|
|
if(
|
|
cache.x != base.offsetWidth ||
|
|
cache.y != base.offsetHeight ||
|
|
cache.cells != cells ||
|
|
cache.zoom != zoom ||
|
|
false){
|
|
cache.x = base.offsetWidth;
|
|
cache.y = base.offsetHeight;
|
|
cache.cells = cells;
|
|
cache.zoom = zoom;
|
|
base.style.fontSize = ((cache.x < cache.y ? cache.x : cache.y) / (cells / zoom)) + "px";
|
|
};
|
|
|
|
if(date - cache.last_time > 2000){
|
|
|
|
/** @type {string} */
|
|
const gui_mode = Check.is_dark_mode() ? "dark" : "light",
|
|
/** @type {boolean} */
|
|
is_mobile = Check.is_mobile();
|
|
|
|
cache.last_time = date;
|
|
|
|
if(cache.gui_mode != gui_mode || cache.mobile != is_mobile){
|
|
cache.gui_mode = gui_mode;
|
|
cache.mobile = is_mobile;
|
|
base.setAttribute("data-gui-mode", gui_mode);
|
|
base.setAttribute("data-is-mobile", is_mobile);
|
|
};
|
|
|
|
};
|
|
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
|
|
* @return {Array.<any|null>}
|
|
* @access public
|
|
*/
|
|
this.build = (inputs = null) => {
|
|
|
|
/** @type {string} */
|
|
const name = anp.settings.get(["application_name", "name"], inputs, "AnP"),
|
|
/** @type {string} */
|
|
link = anp.settings.get(["application_link", "link"], inputs, "https://anp.k3y.pw/"),
|
|
/** @type {string} */
|
|
git = anp.settings.get(["application_git", "git"], inputs, "https://git.k3y.pw/KyMAN/AnP/"),
|
|
/** @type {string} */
|
|
logo = anp.settings.get(["application_logo", "logo"], inputs, "images/logo.webp"),
|
|
/** @type {string} */
|
|
id = anp.unique_keys.create(),
|
|
/** @type {string} */
|
|
gui_mode = Check.is_dark_mode() ? "dark" : "light",
|
|
/** @type {boolean} */
|
|
is_mobile = Check.is_mobile();
|
|
/** @type {number} */
|
|
let i;
|
|
|
|
while(caches[i = Math.random() * (1 << 28) | 0]);
|
|
|
|
caches[i] = {
|
|
x : 0,
|
|
y : 0,
|
|
cells : anp.settings.get(["application_cells", "cells"], inputs, 40),
|
|
zoom : anp.settings.get(["application_zoom", "zoom"], inputs, 1.0),
|
|
gui_mode : gui_mode,
|
|
mobile : is_mobile,
|
|
last_time : Date.now()
|
|
};
|
|
|
|
return Div({
|
|
id : id,
|
|
class : Common.unique(["anp", id].concat(anp.settings.get([
|
|
"application_class", "class"
|
|
], inputs, "").split(RE.WHITE_SPACES))).join(" ").trim(),
|
|
data_hash : id,
|
|
data_i : i,
|
|
data_cells : caches[i].cells,
|
|
data_zoom : caches[i].zoom,
|
|
data_forced_gui_mode : anp.settings.get(["application_gui_mode", "gui_mode"], inputs, "default"), // default, light, dark
|
|
data_gui_mode : gui_mode, // default, light, dark
|
|
data_is_mobile : is_mobile,
|
|
data_name : name,
|
|
data_link : link,
|
|
data_git : git,
|
|
data_logo : logo
|
|
}, [
|
|
Header(null, [
|
|
H1({title : name}, [
|
|
A({href : link, target : "_blank"}, [
|
|
anp.components.image({sources : [logo], alt : name}),
|
|
Span({class : "text"}, name)
|
|
])
|
|
]),
|
|
Nav({class : "top-menu"}, [
|
|
UL(null, anp.settings.get("main_menu", inputs, [
|
|
["home", "#"],
|
|
["git", git, "_blank"]
|
|
]).map(([name, link, target]) => LI({
|
|
data_i18n : name,
|
|
data_i18n_without : true,
|
|
title : anp.i18n.get(name, inputs)
|
|
}, [
|
|
A({
|
|
href : link,
|
|
target : target || "_self"
|
|
}, [
|
|
anp.components.icon(name),
|
|
anp.components.i18n(name)
|
|
])
|
|
])))
|
|
]),
|
|
anp.components.session_mini.build()
|
|
]),
|
|
Main(null, [
|
|
anp.components.aichat.build(inputs)
|
|
]),
|
|
Footer(null, [
|
|
anp.components.buttons([
|
|
["zoom", change_zoom],
|
|
["reset_zoom", reset_zoom],
|
|
["gui_mode", change_gui_mode]
|
|
], {class : "gui-controls"}),
|
|
anp.components.licenses.build(anp.settings.get(["application_licenses", "licenses"], inputs, {
|
|
copyright : [[2019, 2027], "KyMAN"],
|
|
cc_by_nc_sa_4 : []
|
|
})),
|
|
anp.components.i18n_selector.build()
|
|
]),
|
|
Div({class : "preloader"})
|
|
]);
|
|
};
|
|
|
|
/**
|
|
* @param {!HTMLElement} item
|
|
* @returns {HTMLDivElement|null}
|
|
* @access public
|
|
*/
|
|
this.get_from = item => {
|
|
|
|
if(item)
|
|
while(
|
|
!item.classList.contains("anp") &&
|
|
(item = item.parentElement)
|
|
);
|
|
|
|
return item;
|
|
};
|
|
|
|
/**
|
|
* @param {!HTMLElement} item
|
|
* @param {!Event} event
|
|
* @return {void}
|
|
* @access private
|
|
*/
|
|
const change_zoom = (item, event) => {
|
|
|
|
/** @type {HTMLDivElement} */
|
|
const base = self.get_from(item),
|
|
/** @type {number} */
|
|
i = zooms.indexOf(Number(base.getAttribute("data-zoom")));
|
|
|
|
if(isNaN(i))
|
|
base.setAttribute("data-zoom", 1.0);
|
|
else
|
|
base.setAttribute("data-zoom", zooms[(i + 1) % zooms.length]);
|
|
|
|
};
|
|
|
|
/**
|
|
* @param {!HTMLElement} item
|
|
* @param {!Event} event
|
|
* @return {void}
|
|
* @access private
|
|
*/
|
|
const reset_zoom = (item, event) => {
|
|
self.get_from(item).setAttribute("data-zoom", 1.0);
|
|
};
|
|
|
|
/**
|
|
* @param {!HTMLElement} item
|
|
* @param {!Event} event
|
|
* @return {void}
|
|
* @access private
|
|
*/
|
|
const change_gui_mode = (item, event) => {
|
|
|
|
/** @type {HTMLDivElement} */
|
|
const base = self.get_from(item);
|
|
|
|
base.setAttribute("data-forced-gui-mode", {
|
|
default : "light",
|
|
light : "dark",
|
|
dark : "default"
|
|
}[base.getAttribute("data-forced-gui-mode")]);
|
|
|
|
};
|
|
|
|
constructor();
|
|
|
|
};
|
|
|
|
return BaseComponent;
|
|
})(); |