import page from '/lib/page.mjs'; import { Header } from '/web/header.js'; class IndexApp { constructor() { console.log("app constructor"); this.worlds = {}; this.language = _LangManager.language; this.options = { query: 'pathname=' + window.location.pathname.slice(1, window.location.pathname.lastIndexOf("/")), secure: window.location.protocol === "https:", reconnection: false, path: '', transports: ['websocket'] } //window.location.host var socket = io.connect(window._app.reflectorHost, this.options); const parse = (msg) => { this.parseOnlineData(msg) } socket.on('getWebAppUpdate', msg => parse.call(this, msg)); socket.on("connect", function () { let noty = new Noty({ text: 'Connected to Reflector!', timeout: 2000, theme: 'mint', layout: 'bottomRight', type: 'success' }); noty.show(); }) socket.on('connect_error', function (err) { console.log(err); var errDiv = document.createElement("div"); errDiv.innerHTML = "
Connection error to Reflector!" + err + "
"; document.querySelector('body').appendChild(errDiv); let noty = new Noty({ text: 'Connection error to Reflector! ' + err, theme: 'mint', layout: 'bottomRight', type: 'error' }); noty.show(); }); } initHTML() { let self = this; //first init from _app document.querySelector('head').innerHTML += ''; let headerGUI = new Header(); headerGUI.init(); //add HTML let entry = document.createElement("div"); entry.setAttribute("id", 'app'); document.body.appendChild(entry); let divs = ['appGUI', 'userLobby', 'main', 'worldsGUI']; divs.forEach(el => { let appEl = document.createElement("div"); appEl.setAttribute("id", el); entry.appendChild(appEl); }) //init CELL document.querySelector("#userLobby").$cell({ id: "userLobby", $cell: true, $type: "div", $components: [], $update: function () { this.$components = self.initUserGUI() } }); document.querySelector("#worldsGUI").$cell({ id: 'worldsGUI', $cell: true, $type: "div", $components: [], _comps: [], _refresh: async function (data, fn) { _app.showProgressBar(); this._comps = await fn.call(self, data); this.$update(); _app.hideProgressBar(); }, $update: async function () { this.$components = this._comps } }); } async generateFrontPage() { let infoEl = document.createElement("div"); infoEl.setAttribute("id", "indexPage"); let lang = _LangManager.locale; let infoElHTML = await _app.helpers.getHtmlText('/web/locale/' + lang + '/index.html'); infoEl.innerHTML = infoElHTML; document.body.appendChild(infoEl); document.querySelector('#ruLang').addEventListener('click', function (e) { _LangManager.locale = 'ru'; window.location.reload(true); }); document.querySelector('#enLang').addEventListener('click', function (e) { _LangManager.locale = 'en'; window.location.reload(true); }); } initApp() { // let appElHTML = await _app.helpers.getHtmlText('/web/app.html'); // appEl.innerHTML = appElHTML; // document.body.appendChild(appEl); this.initUser(); document.querySelector("#userLobby").$update(); //this.initWorldsListGUI(); //this.getAppDetailsFromDB(); } async initWorldsProtosListForUser(userAlias) { document.querySelector("#worldsGUI").$components = []; await document.querySelector("#worldsGUI")._refresh(userAlias, this.getWorldsProtosListForUser); } async initWorldsStatesListForUser(userAlias) { document.querySelector("#worldsGUI").$components = []; await document.querySelector("#worldsGUI")._refresh(userAlias, this.getWorldsStatesListForUser); } async getWorldsStatesListForUser(userAlias) { let self = this; let worldsGUI = []; let worlds = self.createWorldsGUI(userAlias, 'allStates' ); await _app.getAllStateWorldsInfoForUser(userAlias, function (data) { let doc = document.querySelector("#allStates_" + userAlias); if (doc) { Object.assign(doc._states, data); doc.$update(); } } ); worldsGUI.push(worlds); // Object.entries(data).forEach(el => { // let worlds = this.createWorldsGUI(userAlias, el[0]); // worlds._states = el[1]; // worlds.$update(); // worldsGUI.push(worlds); // }) return [ { $type: "div", class: "mdc-layout-grid", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ { $type: "h1", class: "mdc-typography--headline4", $text: 'States for ' + userAlias } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [].concat(worldsGUI) } ] } ] } ] } async getWorldsProtosListForUser(userAlias) { let worldsGUI = []; //let data = await _app.getAllProtoWorldsInfoForUser(userAlias); let worlds = this.createWorldsGUI(userAlias); await _app.getAllProtoWorldsInfoForUser(userAlias, function (data) { let doc = document.querySelector("#allWorlds_" + userAlias); if (doc) { Object.assign(doc._states, data); doc.$update(); } }) //worlds._states = data; //worlds.$update(); worldsGUI.push(worlds); return [ { $type: "div", class: "mdc-layout-grid", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ { $type: "h1", class: "mdc-typography--headline4", $text: 'Worlds for ' + userAlias } ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [].concat(worldsGUI) }, ] } ] } ] } initUser() { _LCSDB.on('auth', (ack) => { if (ack.pub) { let alias = _LCSUSER.is.alias; let userEl = document.querySelector('#userGUI'); userEl._status = 'Welcome ' + alias + '!'; //userEl.style.backgroundColor = '#e6e6e6'; userEl.$update(); // document.querySelector('#worldGUI').$update(); // document.querySelector('#main').$update(); _LCSUSER.get('profile').once(function (data) { console.log(data) }) let el = document.getElementById("loginGUI"); if (el) { el.remove(); } _LCSUSER.get('profile').not(function (key) { let profile = { 'alias': alias }; _LCSUSER.get('profile').put(profile); }) let actionsGUI = document.querySelector('#worldActionsGUI'); if (actionsGUI) actionsGUI._refresh(); new Noty({ text: alias + ' is succesfully authenticated!', timeout: 2000, theme: 'mint', layout: 'bottomRight', type: 'success' }).show(); //this.getAppDetailsFromUserDB(); } console.log(_LCSUSER.is); }); } initUserGUI() { let worldGUI = { $type: "div", id: "worldGUI", class: "mdc-layout-grid mdc-layout-grid--align-left", _status: '', $init: function () { this._status = "init"; }, $update: function () { let guiForAll = [ window._app.widgets.buttonStroked( { "label": 'Default World Protos', "onclick": function (e) { e.preventDefault(); page("/app/worlds/protos") //window.location.pathname = "/app/worlds/protos" //_app.indexApp.getAppDetailsFromDefaultDB('protos'); } }), window._app.widgets.buttonStroked( { "label": 'Default World States', "onclick": function (e) { e.preventDefault(); page("/app/worlds/states") // window.location.pathname = "/app/worlds/states" //_app.indexApp.getAppDetailsFromDefaultDB('states'); } }) ]; var guiUser = []; if (_LCSUSER.is) { guiUser = [] } this.$components = [ { $type: "h1", class: "mdc-typography--headline4", $text: "Worlds list" } ].concat(guiForAll).concat(guiUser) } } let userGUI = { $type: "div", id: "userGUI", // style:"background-color: #ffeb3b", class: "mdc-layout-grid mdc-layout-grid--align-left", _status: "", $init: function () { this._status = "Welcome!" }, $update: function () { var gui = {}; if (_LCSUSER.is) { gui = [ window._app.widgets.buttonRaised( { "label": 'Sign OUT', "onclick": function (e) { _LCSUSER.leave().then(ack => { if (ack.ok == 0) { window.sessionStorage.removeItem('alias'); window.sessionStorage.removeItem('tmp'); window.location.reload(true); } }); } }), { $type: "p" }, window._app.widgets.buttonStroked( { "label": 'PROFILE', "onclick": function (e) { e.preventDefault(); //page("/profile") window.location.pathname = "/profile" } }), { $type: "p" }, window._app.widgets.buttonStroked( { "label": 'My World protos', "onclick": function (e) { e.preventDefault(); let alias = _LCSUSER.is.alias; //window.location.pathname = '/' + alias + '/worlds/protos' page('/' + alias + '/worlds/protos'); //_app.indexApp.getWorldsProtosFromUserDB(alias); } }), window._app.widgets.buttonStroked( { "label": 'My World states', "onclick": function (e) { e.preventDefault(); let alias = _LCSUSER.is.alias; // window.location.pathname = '/' + alias + '/worlds/states' page('/' + alias + '/worlds/states'); // page.redirect('/' + alias + '/worlds/states'); //_app.indexApp.getWorldsFromUserDB(alias); } }) ] } this.$components = [ window._app.widgets.buttonRaised( { "label": 'Connection settings', "onclick": function (e) { e.preventDefault(); window.location.pathname = '/settings'; } }), { $type: "h1", class: "mdc-typography--headline3", $text: this._status } ].concat(gui) } } let loginGUI = { $type: "div", id: "loginGUI", //style:"background-color: #efefef", class: "mdc-layout-grid mdc-layout-grid--align-left", _alias: null, _pass: null, _passField: null, _aliasField: null, _initData: function () { this._alias = ''; this._pass = ''; // if (window.sessionStorage.getItem('alias')) { // this._alias = window.sessionStorage.getItem('alias') // } // if (window.sessionStorage.getItem('tmp')) { // this._pass = window.sessionStorage.getItem('tmp') // } }, $init: function () { this._initData(); }, $update: function () { this.$components = [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ { $type: "span", class: "mdc-typography--headline5", $text: "Login: " }, window._app.widgets.inputTextFieldOutlined({ "id": 'aliasInput', "label": "Login", "value": this._alias, "type": "text", "init": function () { this._aliasField = new mdc.textField.MDCTextField(this); } }), ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ { $type: "span", class: "mdc-typography--headline5", $text: "Password: " }, window._app.widgets.inputTextFieldOutlined({ "id": 'passwordInput', "label": "Password", "value": this._pass, "type": "password", "init": function () { this._passField = new mdc.textField.MDCTextField(this); } }), ] }, { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ window._app.widgets.buttonRaised( { "label": 'Sign UP', "onclick": function (e) { e.preventDefault(); let alias = this._aliasField.value; let pass = this._passField.value if (pass.length < 7) { new Noty({ text: "Your passphrase needs to be longer than 7 letters", timeout: 2000, theme: 'mint', layout: 'bottomRight', type: 'error' }).show(); } else { // _LCSUSER.create(alias, pass, (ack) => { if (!ack.wait) { } if (ack.err) { console.log(ack.err) return ack.err }; if (ack.pub) { _LCSUSER.auth(alias, pass); _LCSDB.get('users').get(alias).put({ 'alias': alias, 'pub': ack.pub }); } }); } } }), { $type: "span", $text: " " }, window._app.widgets.buttonRaised( { "label": 'Sign IN', "onclick": function (e) { e.preventDefault(); _LCSUSER.auth(this._aliasField.value, this._passField.value, ack => { if (ack.err) { new Noty({ text: ack.err, timeout: 2000, theme: 'mint', layout: 'bottomRight', type: 'error' }).show(); } }); } }) ] } ] } ] } } // document.querySelector("#userLobby").$cell({ // id: "userLobby", // $cell: true, // $type: "div", // $components: [ // userGUI, loginGUI, _app.widgets.divider, worldGUI] // } // ); return [userGUI, loginGUI, _app.widgets.divider, worldGUI] } refresh() { // socket.emit('getWebAppUpdate', ""); } parseOnlineData(data) { let parcedData = _app.parseAppInstancesData(data); //if (Object.entries(parcedData).length !== 0) let onlineGUIs = document.querySelectorAll('.online'); onlineGUIs.forEach(function (item) { item._refresh(parcedData) }); } createWorldCard(id, type) { let self = this; let onlineGUI = { $cell: true, id: "onlineGUI_" + id, class: "online", $type: "div", _instances: {}, _worldListItem: function (m) { return { $type: "li", class: "mdc-list-item", $components: [ { $type: "span", class: "world-link mdc-list-item__text", $components: [ { $type: "span", class: "mdc-list-item__primary-text", $components: [ { $type: "a", $text: m[0], target: "_blank", href: window.location.protocol + "//" + window.location.host + "/" + m[1].user + m[0], onclick: function (e) { //self.refresh(); } }, ] }, { $type: "span", class: "mdc-list-item__secondary-text", $text: self.language.t('users') + m[1].clients } ] } ] } }, $components: [], _refresh: function (data) { if (data) { if (Object.entries(data).length !== 0) { if (this._worldInfo) { let insts = Object.entries(data).filter(el => el[0] == this._worldInfo.worldName); if (insts.length !== 0) this._instances = insts[0][1]; } } else { this._instances = {} } } }, $init: function () { this._refresh(); }, $update: function () { if (this._instances) { let cardListData = Object.entries(this._instances).filter(el => el[1].user == this._worldInfo.userAlias); this.$components = [ { $type: "hr", class: "mdc-list-divider" } ].concat(cardListData.map(this._worldListItem)) } } } return { $cell: true, id: 'worldCard_' + id, $type: "div", _worldInfo: {}, _refresh: function (data) { this._worldInfo = data }, // _getWorldInfo: async function () { // //get space for user // let info = await _app.getWorldInfo(user, space); // this._refresh(info); // }, // _getStateInfo: async function () { // //get space for user // let info = await _app.getStateInfo(user, space, saveName); // this._refresh(info); // }, $init: function () { //get space for user // if (!saveName) { // this._getWorldInfo(); // } else { // this._getStateInfo(); // } }, $update: function () { //console.log(this._worldInfo); this.$components = [this._updateCard()] }, $components: [], _updateCard: function () { let desc = this._worldInfo; if (!desc || Object.keys(desc).length == 0) { return { $type: "h1", class: "mdc-typography--headline4", $text: "ERROR: NO WORLD!" } } let userGUI = []; let online = []; let cardInfo = { "title": "" }; if (type == "full") { } else { userGUI.push({ $type: "a", class: "mdc-button mdc-button--compact mdc-card__action mdc-button--outlined", $text: "Details", onclick: function (e) { e.preventDefault(); window.location.pathname = "/" + desc.userAlias + '/' + desc.worldName + '/about' } }); } userGUI.push({ $type: "a", class: "mdc-button mdc-button--raised mdc-card__action ", $text: self.language.t('start'),//"Start new", target: "_blank", href: "/" + desc.userAlias + '/' + desc.worldName, onclick: function (e) { //self.refresh(); } }); if (desc.type == 'saveState') { cardInfo.title = desc.worldName.split('/')[2]; } if (desc.type == 'proto') { cardInfo.title = desc.worldName; // userGUI.push( // { // $type: "a", // class: "mdc-button mdc-button--compact mdc-card__action", // $text: "States", // onclick: async function (e) { // e.preventDefault(); // window.location.pathname = "/" + desc.userAlias + '/' + desc.worldName +'/about' // //console.log('clone'); // // document.querySelector('#worldStatesGUI')._refresh({}); // // let data = await _app.getSaveStates(desc.userAlias, desc.worldName); // // document.querySelector('#worldStatesGUI')._refresh(data); // } // } // ) } online.push(onlineGUI); return { $cell: true, $type: "div", class: "mdc-card world-card", $components: [ { $type: "section", class: "mdc-card__media world-card__16-9-media", $init: function () { if (desc.info.imgUrl !== "") { this.style.backgroundImage = 'linear-gradient(0deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3) ), url(' + desc.info.imgUrl + ')'; } } }, { $type: "section", class: "mdc-card__primary", $components: [ { $type: "h1", class: "mdc-card__title mdc-card__title--large", $text: desc.info.title }, { $type: "h2", class: "mdc-card__subtitle mdc-theme--text-secondary-on-background", $text: desc.info.text }, { $type: "span", class: "mdc-card__subtitle mdc-theme--text-secondary-on-background", $text: 'id: ' }, { $type: "input", type: "text", disabled: "", style: "font-size:18px", value: cardInfo.title }, { $type: "p", }, { $type: "span", class: "mdc-card__subtitle mdc-theme--text-secondary-on-background", $text: 'created: ' + (new Date(desc.created)).toUTCString() }, { $type: "p", } // ,{ // $type: "span", // class: "mdc-card__subtitle mdc-theme--text-secondary-on-background", // $text: 'modified: ' + (new Date(desc[5])).toUTCString() // } ] }, { $type: "section", class: "mdc-card__actions", $components: [ ].concat(userGUI) }, { $type: "section", class: "mdc-card__actions", $components: [ { $type: 'div', $text: 'online now: ' } ].concat(online) } ] } } } } createWorldsGUI(userAlias, worldName) { let self = this; let id = worldName ? worldName + '_' + userAlias : "allWorlds_" + userAlias let headerText = worldName ? 'States for ' + worldName : 'All Worlds Protos' let worldCards = { $cell: true, id: id, $type: "div", $components: [], _states: {}, _refresh: function (data) { this._states = data }, $init: async function () { //this._refresh(); }, _makeWorldCard: function (data) { let cardID = data[1].userAlias + '_' + data[1].worldName + '_' + data[0]; let card = self.createWorldCard(cardID, 'min'); card._worldInfo = data[1]; card.$update(); return { $cell: true, $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-4", $components: [ card //self.createWorldCard(data[1].userAlias, data[1].worldName, data[0]) //this._worldCardDef(appInfo) ] } //console.log(data); }, $update: function () { this.$components = [ { $type: "div", class: "mdc-layout-grid", $components: [ { $type: "div", class: "mdc-layout-grid__inner", $components: [ { $type: "div", class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12", $components: [ { $type: "H3", $text: headerText } ] } ] }, { $type: "div", class: "mdc-layout-grid__inner", $components: Object.entries(this._states) .filter(el => Object.keys(el[1]).length !== 0) .sort(function (el1, el2) { return parseInt(el2[1].created) - parseInt(el1[1].created) }) .map(this._makeWorldCard) } ] } ] } } return worldCards } } export { IndexApp } //export {getAppDetails, generateFrontPage, setLanguage, initLocale};