import page from '/lib/page.mjs';
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.parseAppInstancesData(msg)
}
socket.on('getWebAppUpdate', msg => parse.call(self, 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();
});
}
async generateFrontPage() {
let infoEl = document.createElement("div");
infoEl.setAttribute("id", "info");
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);
});
}
async initApp() {
let appEl = document.createElement("div");
appEl.setAttribute("id", "app");
let appElHTML = await _app.helpers.getHtmlText('/web/app.html');
appEl.innerHTML = appElHTML;
document.body.appendChild(appEl);
this.initUser();
this.initUserGUI();
this.initWorldsListGUI();
//this.getAppDetailsFromDB();
}
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) })
var el = document.getElementById("loginGUI");
if (el) {
el.remove();
}
_LCSUSER.get('profile').not(function (key) {
let profile = { 'alias': alias };
_LCSUSER.get('profile').put(profile);
})
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();
_app.indexApp.getAppDetailsFromDefaultDB('protos');
}
}),
window._app.widgets.buttonStroked(
{
"label": 'Default World States',
"onclick": function (e) {
e.preventDefault();
_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();
window.location.pathname = "/profile"
}
}),
{
$type: "p"
},
window._app.widgets.buttonStroked(
{
"label": 'My World protos',
"onclick": function (e) {
e.preventDefault();
let alias = _LCSUSER.is.alias;
page.redirect('/' + 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;
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]
}
);
}
parseAppInstancesData(data) {
if (data == "{}") {
var el = document.querySelector(".instance");
if (el) {
var topEl = el.parentNode;
topEl.removeChild(el);
}
// let removeElements = elms => Array.from(elms).forEach(el => el.remove());
}
let jsonObj = JSON.parse(data);
var parsed = {};
for (var prop in jsonObj) {
var name = prop.split('/')[1];
if (parsed[name]) {
parsed[name][prop] = jsonObj[prop];
} else {
parsed[name] = {};
parsed[name][prop] = jsonObj[prop];
}
}
//console.log(parsed);
if (Object.entries(this.worlds).length !== 0)
document.querySelector("#main")._emptyLists();
for (var prop in parsed) {
var name = prop;
let obj = Object.entries(parsed[prop]);
var lists = {};
obj.forEach(el => {
let sotSave = prop;
if (el[1].loadInfo['save_name']) {
let saveName = prop + '/load/' + el[1].loadInfo.save_name;
if (!lists[saveName])
lists[saveName] = {};
lists[saveName][el[0]] = el[1]
} else {
if (!lists[name])
lists[name] = {};
lists[name][el[0]] = el[1]
}
});
// console.log(lists);
Object.entries(lists).forEach(list => {
let element = document.getElementById(list[0] + 'List');
if (element) {
element._setListData(list[1]);
}
})
}
// console.log(data)
}
initWorldsListGUI() {
var self = this;
let worldsListGUI = {
$cell: true,
$type: "div",
id: "main",
_status: "",
_jsonData: {},
_emptyLists: function () {
Object.entries(this._jsonData).forEach(function (element) {
//console.log(element);
let el = document.getElementById(element[0] + 'List');
if (el)
el._setListData({});
});
},
$init: function () {
this._jsonData = {} //data//JSON.parse(data);
},
_makeWorldCard: function (m) {
let langID = localStorage.getItem('krestianstvo_locale');
var appInfo = m
if (langID) {
if (m[1][langID]) {
appInfo = [m[0], m[1][langID], m[1].user, m[1].type, m[1].created, m[1].modified]
}
}
return {
$cell: true,
$type: "div",
class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-4",
$components: [
this._worldCardDef(appInfo)
]
}
},
$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: this._status
}
]
}
]
},
{
$type: "div",
class: "mdc-layout-grid__inner",
$components: Object.entries(this._jsonData).sort(function(el1, el2){
return parseInt(el2[1].created) - parseInt(el1[1].created)
}).map(this._makeWorldCard)
}
]
},
]
},
_worldCardDef: function (desc) {
let userGUI = [];
let cardInfo = {
"title": ""
};
if (desc[3] == 'saveState') {
cardInfo.title = desc[0].split('/')[2];
}
if (desc[3] == 'proto') {
cardInfo.title = desc[0];
userGUI.push(
{
$type: "a",
class: "mdc-button mdc-button--compact mdc-card__action",
$text: "States",
onclick: function (e) {
//console.log('clone');
self.showOnlySaveStates(desc[0], desc[2]);
//self.refresh();
}
}
)
}
if (_LCSUSER.is) {
if (_LCSUSER.is.alias == desc[2]) {
userGUI.push(
{
$type: "a",
class: "mdc-button mdc-button--compact mdc-card__action",
$text: "Edit info",
//href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
onclick: function (e) {
//'/:user/:type/:name/edit/:file'
if (desc[3] == 'proto') {
window.location.pathname = "/" + desc[2] + '/proto/' + desc[0] + '/edit/info_json'
} else if (desc[3] == 'saveState') {
let names = desc[0].split('/');
let filename = ('savestate_/' + names[0] + '/' + names[2] + '_info_vwf_json').split('/').join("~");
window.location.pathname = "/" + desc[2] + '/state/' + names[0] + '/edit/' + filename;
}
//self.refresh();
}
}
);
if (desc[3] == 'proto') {
userGUI.push(
{
$type: "a",
class: "mdc-button mdc-button--compact mdc-card__action",
$text: "Edit proto",
//href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
onclick: function (e) {
window.location.pathname = "/" + desc[2] + '/proto/' + desc[0] + '/edit/index_vwf_yaml'
}
}
);
userGUI.push(
{
$type: "a",
class: "mdc-button mdc-button--compact mdc-card__action",
$text: "Delete",
//href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
onclick: function (e) {
_app.deleteWorld(desc[0], 'proto');
}
}
);
}
if(desc[3] == 'saveState'){
userGUI.push(
{
$type: "a",
class: "mdc-button mdc-button--compact mdc-card__action",
$text: "Delete",
//href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
onclick: function (e) {
_app.deleteWorld(desc[0], 'state');
}
}
);
}
}
if (desc[3] == 'proto') {
userGUI.push(
{
$type: "a",
class: "mdc-button mdc-button--compact mdc-card__action",
$text: self.language.t('clone proto'),//"clone",
onclick: function (e) {
//console.log('clone');
_app.cloneWorldPrototype(desc[0], desc[2]);
//self.refresh();
}
}
)
} else if (desc[3] == 'saveState') {
// userGUI.push(
// {
// $type: "a",
// class: "mdc-button mdc-button--compact mdc-card__action mdc-button--outlined",
// $text: "Clone",
// onclick: function (e) {
// //console.log('clone');
// //self.cloneWorldState(desc[0], desc[2]);
// //self.refresh();
// }
// })
}
}
return {
$cell: true,
$type: "div",
class: "mdc-card world-card",
_appInfo: desc,
$components: [
{
$type: "section",
class: "mdc-card__media world-card__16-9-media",
$init: function () {
if (desc[1].imgUrl !== "") {
this.style.backgroundImage = 'linear-gradient(0deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3) ), url(' + desc[1].imgUrl + ')';
}
}
},
{
$type: "section",
class: "mdc-card__primary",
$components: [
{
$type: "h1",
class: "mdc-card__title mdc-card__title--large",
$text: desc[1].title
},
{
$type: "h2",
class: "mdc-card__subtitle mdc-theme--text-secondary-on-background",
$text: desc[1].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[4])).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: [
{
$type: "a",
class: "mdc-button mdc-button--compact mdc-card__action mdc-button--outlined",
$text: self.language.t('start'),//"Start new",
target: "_blank",
href: "/" + desc[2] + '/' + desc[0],
onclick: function (e) {
self.refresh();
}
}
].concat(userGUI)
},
{
$type: "section",
class: "mdc-card__actions",
$components: [
{
$type: "ul",
_listData: {},
_setListData: function (data) {
this._listData = data;
},
class: "mdc-list mdc-list--two-line",
'aria-orientation': "vertical",
id: desc[0] + 'List',
$update: function () {
var connectText = {}
let cardListData = Object.entries(this._listData).filter(el => el[1].user == this._appInfo[2]);
if (cardListData.length !== 0) {
connectText = {
// $type: "span",
// class: "mdc-theme--text-secondary",
// $text: "...or connect to:"
}
}
this.$components = [
{
$type: "hr",
class: "mdc-list-divider"
}
].concat(cardListData.map(this._worldListItem))
// [connectText]
// }].concat(Object.entries(this._listData).map(this._worldListItem))
},
_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
}
]
}
]
}
}
}
]
}
]
}
}
}
document.querySelector("#main").$cell({
$cell: true,
$type: "div",
$components: [worldsListGUI]
})
}
async showOnlySaveStates(index, userAlias) {
let userPub = await _LCSDB.get('users').get(userAlias).get('pub').once().then();
var db = _LCSDB.user(userPub);
if (_LCSUSER.is) {
if (_LCSUSER.is.alias == userAlias)
db = _LCSUSER;
}
this.worlds = {};
document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
document.querySelector("#main")._status = "Save states of the World: " + index + ' for user: ' + userAlias;
document.querySelector("#main").$update();
//let userAlias = _LCSUSER.is.alias;
db.get('documents').get(index).once(save => {
if (save) {
let saves = Object.keys(save).filter(el => el.includes('_info_vwf_json'));
console.log(saves);
if (saves) {
saves.forEach(el => {
db.get('documents').get(index).get(el).once(res => {
if (res) {
let created = res.created ? res.created: res.modified;
let fileName = el.split('/')[2].replace('_info_vwf_json', "");
let world = JSON.parse(res.file);
let root = Object.keys(world)[0];
world[root].user = userAlias;
world[root].type = 'saveState';
world[root].created = created;
world[root].modified = res.modified;
this.worlds[index + '/load/' + fileName] = world[root];
document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
}
})
})
}
}
})
}
async getWorldsProtosFromUserDB(userAlias) {
let userPub = await _LCSDB.get('users').get(userAlias).get('pub').once().then();
console.log('get user worlds for: ' + userAlias);
this.worlds = {};
document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
if (!userPub) {
document.querySelector("#main")._status = "no such user";
document.querySelector("#main").$update();
}
if (userPub) {
document.querySelector("#main")._status = "Worlds protos for: " + userAlias;
document.querySelector("#main").$update();
var db = _LCSDB.user(userPub);
if (_LCSUSER.is) {
if (_LCSUSER.is.alias == userAlias)
db = _LCSUSER;
}
db.get('worlds').map().once((w, index) => {
if (w) {
db.get('worlds').get(index).get('info_json').once(res => {
if (res && res !== 'null') {
if (res.file && res.file !== 'null') {
let created = res.created ? res.created: res.modified;
let world = JSON.parse(res.file);
let root = Object.keys(world)[0];
world[root].user = userAlias;
world[root].type = 'proto';
world[root].created = created;
world[root].modified = res.modified;
this.worlds[index] = world[root];
document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
}
}
})
}
})
}
}
async getWorldsFromUserDB(userAlias) {
let userPub = await _LCSDB.get('users').get(userAlias).get('pub').once().then();
console.log('get user worlds for: ' + userAlias);
this.worlds = {};
document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
if (!userPub) {
document.querySelector("#main")._status = "no such user";
document.querySelector("#main").$update();
}
if (userPub) {
document.querySelector("#main")._status = "Worlds states for: " + userAlias;
document.querySelector("#main").$update();
var db = _LCSDB.user(userPub);
if (_LCSUSER.is) {
if (_LCSUSER.is.alias == userAlias)
db = _LCSUSER;
}
db.get('worlds').map().once((w, index) => {
if (w) {
db.get('documents').get(index).once(save => {
if (save) {
let saves = Object.keys(save).filter(el => el.includes('_info_vwf_json'));
console.log(saves);
if (saves) {
saves.forEach(el => {
db.get('documents').get(index).get(el).once(res => {
if (res ) {
if(res.file && res.file !== "null") {
let created = res.created ? res.created: res.modified;
let fileName = el.split('/')[2].replace('_info_vwf_json', "");
let world = JSON.parse(res.file);
let root = Object.keys(world)[0];
world[root].user = userAlias;
world[root].type = 'saveState';
world[root].created = created;
world[root].modified = res.modified;
this.worlds[index + '/load/' + fileName] = world[root];
document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
}
}
})
})
}
}
})
}
})
}
}
async getAppDetailsFromDefaultDB(type) {
let defaultUserPUB = await _LCSDB.get('lcs/app').path('pub').once().then();
var userAlias = await _LCSDB.user(defaultUserPUB).get('alias').once().then();
page.redirect('/' + userAlias + '/worlds/' + type);
}
async getAppDetailsFromDB() {
let defaultUserPUB = await _LCSDB.get('lcs/app').path('pub').once().then();
var userAlias = await _LCSDB.user(defaultUserPUB).get('alias').once().then();
if (userAlias)
this.getWorldsProtosFromUserDB(userAlias);
}
refresh() {
// socket.emit('getWebAppUpdate', "");
}
}
export { IndexApp }
//export {getAppDetails, generateFrontPage, setLanguage, initLocale};