index-app.js 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. import page from '/lib/page.mjs';
  2. class IndexApp {
  3. constructor() {
  4. console.log("app constructor");
  5. this.worlds = {};
  6. this.language = _LangManager.language;
  7. this.options = {
  8. query: 'pathname=' + window.location.pathname.slice(1,
  9. window.location.pathname.lastIndexOf("/")),
  10. secure: window.location.protocol === "https:",
  11. reconnection: false,
  12. path: '',
  13. transports: ['websocket']
  14. }
  15. //window.location.host
  16. var socket = io.connect(window._app.reflectorHost, this.options);
  17. const parse = (msg) => {
  18. this.parseAppInstancesData(msg)
  19. }
  20. socket.on('getWebAppUpdate', msg => parse.call(this, msg));
  21. socket.on("connect", function () {
  22. let noty = new Noty({
  23. text: 'Connected to Reflector!',
  24. timeout: 2000,
  25. theme: 'mint',
  26. layout: 'bottomRight',
  27. type: 'success'
  28. });
  29. noty.show();
  30. })
  31. socket.on('connect_error', function (err) {
  32. console.log(err);
  33. var errDiv = document.createElement("div");
  34. errDiv.innerHTML = "<div class='vwf-err' style='z-index: 10; position: absolute; top: 80px; right: 50px'>Connection error to Reflector!" + err + "</div>";
  35. document.querySelector('body').appendChild(errDiv);
  36. let noty = new Noty({
  37. text: 'Connection error to Reflector! ' + err,
  38. theme: 'mint',
  39. layout: 'bottomRight',
  40. type: 'error'
  41. });
  42. noty.show();
  43. });
  44. }
  45. async generateFrontPage() {
  46. let infoEl = document.createElement("div");
  47. infoEl.setAttribute("id", "info");
  48. let lang = _LangManager.locale;
  49. let infoElHTML = await _app.helpers.getHtmlText('/web/locale/' + lang + '/index.html');
  50. infoEl.innerHTML = infoElHTML;
  51. document.body.appendChild(infoEl);
  52. document.querySelector('#ruLang').addEventListener('click', function (e) {
  53. _LangManager.locale = 'ru';
  54. window.location.reload(true);
  55. });
  56. document.querySelector('#enLang').addEventListener('click', function (e) {
  57. _LangManager.locale = 'en';
  58. window.location.reload(true);
  59. });
  60. }
  61. async initApp() {
  62. let appEl = document.createElement("div");
  63. appEl.setAttribute("id", "app");
  64. let appElHTML = await _app.helpers.getHtmlText('/web/app.html');
  65. appEl.innerHTML = appElHTML;
  66. document.body.appendChild(appEl);
  67. this.initUser();
  68. this.initUserGUI();
  69. this.initWorldsListGUI();
  70. //this.getAppDetailsFromDB();
  71. }
  72. initUser() {
  73. _LCSDB.on('auth', (ack) => {
  74. if (ack.pub) {
  75. let alias = _LCSUSER.is.alias;
  76. let userEl = document.querySelector('#userGUI');
  77. userEl._status = 'Welcome ' + alias + '!';
  78. //userEl.style.backgroundColor = '#e6e6e6';
  79. userEl.$update();
  80. document.querySelector('#worldGUI').$update();
  81. document.querySelector('#main').$update();
  82. _LCSUSER.get('profile').once(function (data) { console.log(data) })
  83. var el = document.getElementById("loginGUI");
  84. if (el) {
  85. el.remove();
  86. }
  87. _LCSUSER.get('profile').not(function (key) {
  88. let profile = { 'alias': alias };
  89. _LCSUSER.get('profile').put(profile);
  90. })
  91. new Noty({
  92. text: alias + ' is succesfully authenticated!',
  93. timeout: 2000,
  94. theme: 'mint',
  95. layout: 'bottomRight',
  96. type: 'success'
  97. }).show();
  98. //this.getAppDetailsFromUserDB();
  99. }
  100. console.log(_LCSUSER.is);
  101. });
  102. }
  103. initUserGUI() {
  104. let worldGUI =
  105. {
  106. $type: "div",
  107. id: "worldGUI",
  108. class: "mdc-layout-grid mdc-layout-grid--align-left",
  109. _status: '',
  110. $init: function () {
  111. this._status = "init";
  112. },
  113. $update: function () {
  114. let guiForAll = [
  115. window._app.widgets.buttonStroked(
  116. {
  117. "label": 'Default World Protos',
  118. "onclick": function (e) {
  119. e.preventDefault();
  120. _app.indexApp.getAppDetailsFromDefaultDB('protos');
  121. }
  122. }),
  123. window._app.widgets.buttonStroked(
  124. {
  125. "label": 'Default World States',
  126. "onclick": function (e) {
  127. e.preventDefault();
  128. _app.indexApp.getAppDetailsFromDefaultDB('states');
  129. }
  130. })
  131. ];
  132. var guiUser = [];
  133. if (_LCSUSER.is) {
  134. guiUser = []
  135. }
  136. this.$components = [
  137. {
  138. $type: "h1",
  139. class: "mdc-typography--headline4",
  140. $text: "Worlds list"
  141. }
  142. ].concat(guiForAll).concat(guiUser)
  143. }
  144. }
  145. let userGUI =
  146. {
  147. $type: "div",
  148. id: "userGUI",
  149. // style:"background-color: #ffeb3b",
  150. class: "mdc-layout-grid mdc-layout-grid--align-left",
  151. _status: "",
  152. $init: function () {
  153. this._status = "Welcome!"
  154. },
  155. $update: function () {
  156. var gui = {};
  157. if (_LCSUSER.is) {
  158. gui = [
  159. window._app.widgets.buttonRaised(
  160. {
  161. "label": 'Sign OUT',
  162. "onclick": function (e) {
  163. _LCSUSER.leave().then(ack => {
  164. if (ack.ok == 0) {
  165. window.sessionStorage.removeItem('alias');
  166. window.sessionStorage.removeItem('tmp');
  167. window.location.reload(true);
  168. }
  169. });
  170. }
  171. }),
  172. {
  173. $type: "p"
  174. },
  175. window._app.widgets.buttonStroked(
  176. {
  177. "label": 'PROFILE',
  178. "onclick": function (e) {
  179. e.preventDefault();
  180. window.location.pathname = "/profile"
  181. }
  182. }),
  183. {
  184. $type: "p"
  185. },
  186. window._app.widgets.buttonStroked(
  187. {
  188. "label": 'My World protos',
  189. "onclick": function (e) {
  190. e.preventDefault();
  191. let alias = _LCSUSER.is.alias;
  192. page.redirect('/' + alias + '/worlds/protos');
  193. //_app.indexApp.getWorldsProtosFromUserDB(alias);
  194. }
  195. }),
  196. window._app.widgets.buttonStroked(
  197. {
  198. "label": 'My World states',
  199. "onclick": function (e) {
  200. e.preventDefault();
  201. let alias = _LCSUSER.is.alias;
  202. page.redirect('/' + alias + '/worlds/states');
  203. //_app.indexApp.getWorldsFromUserDB(alias);
  204. }
  205. })
  206. ]
  207. }
  208. this.$components = [
  209. window._app.widgets.buttonRaised(
  210. {
  211. "label": 'Connection settings',
  212. "onclick": function (e) {
  213. e.preventDefault();
  214. window.location.pathname = '/settings';
  215. }
  216. }),
  217. {
  218. $type: "h1",
  219. class: "mdc-typography--headline3",
  220. $text: this._status
  221. }
  222. ].concat(gui)
  223. }
  224. }
  225. let loginGUI =
  226. {
  227. $type: "div",
  228. id: "loginGUI",
  229. //style:"background-color: #efefef",
  230. class: "mdc-layout-grid mdc-layout-grid--align-left",
  231. _alias: null,
  232. _pass: null,
  233. _passField: null,
  234. _aliasField: null,
  235. _initData: function () {
  236. this._alias = '';
  237. this._pass = '';
  238. // if (window.sessionStorage.getItem('alias')) {
  239. // this._alias = window.sessionStorage.getItem('alias')
  240. // }
  241. // if (window.sessionStorage.getItem('tmp')) {
  242. // this._pass = window.sessionStorage.getItem('tmp')
  243. // }
  244. },
  245. $init: function () {
  246. this._initData();
  247. },
  248. $update: function () {
  249. this.$components = [
  250. {
  251. $type: "div",
  252. class: "mdc-layout-grid__inner",
  253. $components: [
  254. {
  255. $type: "div",
  256. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  257. $components: [
  258. {
  259. $type: "span",
  260. class: "mdc-typography--headline5",
  261. $text: "Login: "
  262. },
  263. window._app.widgets.inputTextFieldOutlined({
  264. "id": 'aliasInput',
  265. "label": "Login",
  266. "value": this._alias,
  267. "type": "text",
  268. "init": function() {
  269. this._aliasField = new mdc.textField.MDCTextField(this);
  270. }
  271. }),
  272. ]
  273. },
  274. {
  275. $type: "div",
  276. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  277. $components: [
  278. {
  279. $type: "span",
  280. class: "mdc-typography--headline5",
  281. $text: "Password: "
  282. },
  283. window._app.widgets.inputTextFieldOutlined({
  284. "id": 'passwordInput',
  285. "label": "Password",
  286. "value": this._pass,
  287. "type": "password",
  288. "init": function() {
  289. this._passField = new mdc.textField.MDCTextField(this);
  290. }
  291. }),
  292. ]
  293. },
  294. {
  295. $type: "div",
  296. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  297. $components: [
  298. window._app.widgets.buttonRaised(
  299. {
  300. "label": 'Sign UP',
  301. "onclick": function (e) {
  302. e.preventDefault();
  303. let alias = this._aliasField.value;
  304. let pass = this._passField.value
  305. if (pass.length < 7) {
  306. new Noty({
  307. text: "Your passphrase needs to be longer than 7 letters",
  308. timeout: 2000,
  309. theme: 'mint',
  310. layout: 'bottomRight',
  311. type: 'error'
  312. }).show();
  313. } else {
  314. //
  315. _LCSUSER.create(alias, pass,
  316. (ack) => {
  317. if (!ack.wait) { }
  318. if (ack.err) {
  319. console.log(ack.err)
  320. return ack.err
  321. };
  322. if (ack.pub) {
  323. _LCSUSER.auth(alias, pass);
  324. _LCSDB.get('users').get(alias).put({
  325. 'alias': alias,
  326. 'pub': ack.pub
  327. });
  328. }
  329. });
  330. }
  331. }
  332. }),
  333. {
  334. $type: "span",
  335. $text: " "
  336. },
  337. window._app.widgets.buttonRaised(
  338. {
  339. "label": 'Sign IN',
  340. "onclick": function (e) {
  341. e.preventDefault();
  342. _LCSUSER.auth(this._aliasField.value, this._passField.value, ack => {
  343. if (ack.err) {
  344. new Noty({
  345. text: ack.err,
  346. timeout: 2000,
  347. theme: 'mint',
  348. layout: 'bottomRight',
  349. type: 'error'
  350. }).show();
  351. }
  352. });
  353. }
  354. })
  355. ]
  356. }
  357. ]
  358. }
  359. ]
  360. }
  361. }
  362. document.querySelector("#userLobby").$cell({
  363. id: "userLobby",
  364. $cell: true,
  365. $type: "div",
  366. $components: [
  367. userGUI, loginGUI, _app.widgets.divider, worldGUI]
  368. }
  369. );
  370. }
  371. initWorldsListGUI() {
  372. var self = this;
  373. let worldsListGUI = {
  374. $cell: true,
  375. $type: "div",
  376. id: "main",
  377. _status: "",
  378. _jsonData: {},
  379. _emptyLists: function () {
  380. Object.entries(this._jsonData).forEach(function (element) {
  381. //console.log(element);
  382. let el = document.getElementById(element[0] + 'List');
  383. if (el)
  384. el._setListData({});
  385. });
  386. },
  387. $init: function () {
  388. this._jsonData = {} //data//JSON.parse(data);
  389. },
  390. _makeWorldCard: function (m) {
  391. let langID = localStorage.getItem('krestianstvo_locale');
  392. var appInfo = m
  393. if (langID) {
  394. if (m[1][langID]) {
  395. appInfo = [m[0], m[1][langID], m[1].user, m[1].type, m[1].created, m[1].modified]
  396. }
  397. }
  398. return {
  399. $cell: true,
  400. $type: "div",
  401. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-4",
  402. $components: [
  403. this._worldCardDef(appInfo)
  404. ]
  405. }
  406. },
  407. $update: function () {
  408. this.$components = [
  409. {
  410. $type: "div",
  411. class: "mdc-layout-grid",
  412. $components: [
  413. {
  414. $type: "div",
  415. class: "mdc-layout-grid__inner",
  416. $components: [
  417. {
  418. $type: "div",
  419. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  420. $components: [
  421. {
  422. $type: "H3",
  423. $text: this._status
  424. }
  425. ]
  426. }
  427. ]
  428. },
  429. {
  430. $type: "div",
  431. class: "mdc-layout-grid__inner",
  432. $components: Object.entries(this._jsonData).sort(function(el1, el2){
  433. return parseInt(el2[1].created) - parseInt(el1[1].created)
  434. }).map(this._makeWorldCard)
  435. }
  436. ]
  437. },
  438. ]
  439. },
  440. _worldCardDef: function (desc) {
  441. let userGUI = [];
  442. let cardInfo = {
  443. "title": ""
  444. };
  445. if (desc[3] == 'saveState') {
  446. cardInfo.title = desc[0].split('/')[2];
  447. }
  448. if (desc[3] == 'proto') {
  449. cardInfo.title = desc[0];
  450. userGUI.push(
  451. {
  452. $type: "a",
  453. class: "mdc-button mdc-button--compact mdc-card__action",
  454. $text: "States",
  455. onclick: function (e) {
  456. //console.log('clone');
  457. self.showOnlySaveStates(desc[0], desc[2]);
  458. //self.refresh();
  459. }
  460. }
  461. )
  462. }
  463. if (_LCSUSER.is) {
  464. if (_LCSUSER.is.alias == desc[2]) {
  465. userGUI.push(
  466. {
  467. $type: "a",
  468. class: "mdc-button mdc-button--compact mdc-card__action",
  469. $text: "Edit info",
  470. //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  471. onclick: function (e) {
  472. //'/:user/:type/:name/edit/:file'
  473. if (desc[3] == 'proto') {
  474. window.location.pathname = "/" + desc[2] + '/proto/' + desc[0] + '/edit/info_json'
  475. } else if (desc[3] == 'saveState') {
  476. let names = desc[0].split('/');
  477. let filename = ('savestate_/' + names[0] + '/' + names[2] + '_info_vwf_json').split('/').join("~");
  478. window.location.pathname = "/" + desc[2] + '/state/' + names[0] + '/edit/' + filename;
  479. }
  480. //self.refresh();
  481. }
  482. }
  483. );
  484. if (desc[3] == 'proto') {
  485. userGUI.push(
  486. {
  487. $type: "a",
  488. class: "mdc-button mdc-button--compact mdc-card__action",
  489. $text: "Edit proto",
  490. //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  491. onclick: function (e) {
  492. window.location.pathname = "/" + desc[2] + '/proto/' + desc[0] + '/edit/index_vwf_yaml'
  493. }
  494. }
  495. );
  496. userGUI.push(
  497. {
  498. $type: "a",
  499. class: "mdc-button mdc-button--compact mdc-card__action",
  500. $text: "Delete",
  501. //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  502. onclick: function (e) {
  503. _app.deleteWorld(desc[0], 'proto');
  504. }
  505. }
  506. );
  507. }
  508. if(desc[3] == 'saveState'){
  509. userGUI.push(
  510. {
  511. $type: "a",
  512. class: "mdc-button mdc-button--compact mdc-card__action",
  513. $text: "Delete",
  514. //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  515. onclick: function (e) {
  516. _app.deleteWorld(desc[0], 'state');
  517. }
  518. }
  519. );
  520. }
  521. }
  522. if (desc[3] == 'proto') {
  523. userGUI.push(
  524. {
  525. $type: "a",
  526. class: "mdc-button mdc-button--compact mdc-card__action",
  527. $text: self.language.t('clone proto'),//"clone",
  528. onclick: function (e) {
  529. //console.log('clone');
  530. _app.cloneWorldPrototype(desc[0], desc[2]);
  531. //self.refresh();
  532. }
  533. }
  534. )
  535. } else if (desc[3] == 'saveState') {
  536. // userGUI.push(
  537. // {
  538. // $type: "a",
  539. // class: "mdc-button mdc-button--compact mdc-card__action mdc-button--outlined",
  540. // $text: "Clone",
  541. // onclick: function (e) {
  542. // //console.log('clone');
  543. // //self.cloneWorldState(desc[0], desc[2]);
  544. // //self.refresh();
  545. // }
  546. // })
  547. }
  548. }
  549. return {
  550. $cell: true,
  551. $type: "div",
  552. class: "mdc-card world-card",
  553. _appInfo: desc,
  554. $components: [
  555. {
  556. $type: "section",
  557. class: "mdc-card__media world-card__16-9-media",
  558. $init: function () {
  559. if (desc[1].imgUrl !== "") {
  560. this.style.backgroundImage = 'linear-gradient(0deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3) ), url(' + desc[1].imgUrl + ')';
  561. }
  562. }
  563. },
  564. {
  565. $type: "section",
  566. class: "mdc-card__primary",
  567. $components: [
  568. {
  569. $type: "h1",
  570. class: "mdc-card__title mdc-card__title--large",
  571. $text: desc[1].title
  572. },
  573. {
  574. $type: "h2",
  575. class: "mdc-card__subtitle mdc-theme--text-secondary-on-background",
  576. $text: desc[1].text
  577. },
  578. {
  579. $type: "span",
  580. class: "mdc-card__subtitle mdc-theme--text-secondary-on-background",
  581. $text: 'id: '
  582. },
  583. {
  584. $type: "input",
  585. type: "text",
  586. disabled: "",
  587. style: "font-size:18px",
  588. value: cardInfo.title
  589. },
  590. {
  591. $type: "p",
  592. },
  593. {
  594. $type: "span",
  595. class: "mdc-card__subtitle mdc-theme--text-secondary-on-background",
  596. $text: 'created: ' + (new Date(desc[4])).toUTCString()
  597. },
  598. {
  599. $type: "p",
  600. }
  601. // ,{
  602. // $type: "span",
  603. // class: "mdc-card__subtitle mdc-theme--text-secondary-on-background",
  604. // $text: 'modified: ' + (new Date(desc[5])).toUTCString()
  605. // }
  606. ]
  607. },
  608. {
  609. $type: "section",
  610. class: "mdc-card__actions",
  611. $components: [
  612. {
  613. $type: "a",
  614. class: "mdc-button mdc-button--compact mdc-card__action mdc-button--outlined",
  615. $text: self.language.t('start'),//"Start new",
  616. target: "_blank",
  617. href: "/" + desc[2] + '/' + desc[0],
  618. onclick: function (e) {
  619. self.refresh();
  620. }
  621. },
  622. {
  623. $type: "a",
  624. class: "mdc-button mdc-button--compact mdc-card__action",
  625. $text: "Details",//"clone",
  626. //href: "/" + desc[2] + '/' + desc[0] +'/about',
  627. onclick: function (e) {
  628. e.preventDefault();
  629. window.location.pathname = "/" + desc[2] + '/' + desc[0] +'/about'
  630. //console.log('clone');
  631. // _app.cloneWorldPrototype(desc[0], desc[2]);
  632. //self.refresh();
  633. }
  634. }
  635. ].concat(userGUI)
  636. },
  637. {
  638. $type: "section",
  639. class: "mdc-card__actions",
  640. $components: [
  641. {
  642. $type: "ul",
  643. _listData: {},
  644. _setListData: function (data) {
  645. this._listData = data;
  646. },
  647. class: "mdc-list mdc-list--two-line",
  648. 'aria-orientation': "vertical",
  649. id: desc[0] + 'List',
  650. $update: function () {
  651. var connectText = {}
  652. let cardListData = Object.entries(this._listData).filter(el => el[1].user == this._appInfo[2]);
  653. if (cardListData.length !== 0) {
  654. connectText = {
  655. // $type: "span",
  656. // class: "mdc-theme--text-secondary",
  657. // $text: "...or connect to:"
  658. }
  659. }
  660. this.$components = [
  661. {
  662. $type: "hr",
  663. class: "mdc-list-divider"
  664. }
  665. ].concat(cardListData.map(this._worldListItem))
  666. // [connectText]
  667. // }].concat(Object.entries(this._listData).map(this._worldListItem))
  668. },
  669. _worldListItem: function (m) {
  670. return {
  671. $type: "li",
  672. class: "mdc-list-item",
  673. $components: [
  674. {
  675. $type: "span",
  676. class: "world-link mdc-list-item__text",
  677. $components: [
  678. {
  679. $type: "span",
  680. class: "mdc-list-item__primary-text",
  681. $components: [
  682. {
  683. $type: "a",
  684. $text: m[0],
  685. target: "_blank",
  686. href: window.location.protocol + "//" + window.location.host + "/" + m[1].user + m[0],
  687. onclick: function (e) {
  688. //self.refresh();
  689. }
  690. },
  691. ]
  692. },
  693. {
  694. $type: "span",
  695. class: "mdc-list-item__secondary-text",
  696. $text: self.language.t('users') + m[1].clients
  697. }
  698. ]
  699. }
  700. ]
  701. }
  702. }
  703. }
  704. ]
  705. }
  706. ]
  707. }
  708. }
  709. }
  710. document.querySelector("#main").$cell({
  711. $cell: true,
  712. $type: "div",
  713. $components: [worldsListGUI]
  714. })
  715. }
  716. async showOnlySaveStates(index, userAlias) {
  717. let userPub = await _LCSDB.get('users').get(userAlias).get('pub').once().then();
  718. var db = _LCSDB.user(userPub);
  719. if (_LCSUSER.is) {
  720. if (_LCSUSER.is.alias == userAlias)
  721. db = _LCSUSER;
  722. }
  723. this.worlds = {};
  724. document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
  725. document.querySelector("#main")._status = "Save states of the World: " + index + ' for user: ' + userAlias;
  726. document.querySelector("#main").$update();
  727. //let userAlias = _LCSUSER.is.alias;
  728. db.get('documents').get(index).once(save => {
  729. if (save) {
  730. let saves = Object.keys(save).filter(el => el.includes('_info_vwf_json'));
  731. console.log(saves);
  732. if (saves) {
  733. saves.forEach(el => {
  734. db.get('documents').get(index).get(el).once(res => {
  735. if (res) {
  736. let created = res.created ? res.created: res.modified;
  737. let fileName = el.split('/')[2].replace('_info_vwf_json', "");
  738. let world = JSON.parse(res.file);
  739. let root = Object.keys(world)[0];
  740. world[root].user = userAlias;
  741. world[root].type = 'saveState';
  742. world[root].created = created;
  743. world[root].modified = res.modified;
  744. this.worlds[index + '/load/' + fileName] = world[root];
  745. document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
  746. }
  747. })
  748. })
  749. }
  750. }
  751. })
  752. }
  753. async getWorldsProtosFromUserDB(userAlias) {
  754. let userPub = await _LCSDB.get('users').get(userAlias).get('pub').once().then();
  755. console.log('get user worlds for: ' + userAlias);
  756. this.worlds = {};
  757. document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
  758. if (!userPub) {
  759. document.querySelector("#main")._status = "no such user";
  760. document.querySelector("#main").$update();
  761. }
  762. if (userPub) {
  763. document.querySelector("#main")._status = "Worlds protos for: " + userAlias;
  764. document.querySelector("#main").$update();
  765. var db = _LCSDB.user(userPub);
  766. if (_LCSUSER.is) {
  767. if (_LCSUSER.is.alias == userAlias)
  768. db = _LCSUSER;
  769. }
  770. db.get('worlds').map().once((w, index) => {
  771. if (w) {
  772. db.get('worlds').get(index).get('info_json').once(res => {
  773. if (res && res !== 'null') {
  774. if (res.file && res.file !== 'null') {
  775. let created = res.created ? res.created: res.modified;
  776. let world = JSON.parse(res.file);
  777. let root = Object.keys(world)[0];
  778. world[root].user = userAlias;
  779. world[root].type = 'proto';
  780. world[root].created = created;
  781. world[root].modified = res.modified;
  782. this.worlds[index] = world[root];
  783. document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
  784. }
  785. }
  786. })
  787. }
  788. })
  789. }
  790. }
  791. async getWorldsFromUserDB(userAlias) {
  792. let userPub = await _LCSDB.get('users').get(userAlias).get('pub').once().then();
  793. console.log('get user worlds for: ' + userAlias);
  794. this.worlds = {};
  795. document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
  796. if (!userPub) {
  797. document.querySelector("#main")._status = "no such user";
  798. document.querySelector("#main").$update();
  799. }
  800. if (userPub) {
  801. document.querySelector("#main")._status = "Worlds states for: " + userAlias;
  802. document.querySelector("#main").$update();
  803. var db = _LCSDB.user(userPub);
  804. if (_LCSUSER.is) {
  805. if (_LCSUSER.is.alias == userAlias)
  806. db = _LCSUSER;
  807. }
  808. db.get('worlds').map().once((w, index) => {
  809. if (w) {
  810. db.get('documents').get(index).once(save => {
  811. if (save) {
  812. let saves = Object.keys(save).filter(el => el.includes('_info_vwf_json'));
  813. console.log(saves);
  814. if (saves) {
  815. saves.forEach(el => {
  816. db.get('documents').get(index).get(el).once(res => {
  817. if (res ) {
  818. if(res.file && res.file !== "null") {
  819. let created = res.created ? res.created: res.modified;
  820. let fileName = el.split('/')[2].replace('_info_vwf_json', "");
  821. let world = JSON.parse(res.file);
  822. let root = Object.keys(world)[0];
  823. world[root].user = userAlias;
  824. world[root].type = 'saveState';
  825. world[root].created = created;
  826. world[root].modified = res.modified;
  827. this.worlds[index + '/load/' + fileName] = world[root];
  828. document.querySelector("#main")._jsonData = Object.assign({}, this.worlds);
  829. }
  830. }
  831. })
  832. })
  833. }
  834. }
  835. })
  836. }
  837. })
  838. }
  839. }
  840. async getAppDetailsFromDefaultDB(type) {
  841. let defaultUserPUB = await _LCSDB.get('lcs/app').path('pub').once().then();
  842. var userAlias = await _LCSDB.user(defaultUserPUB).get('alias').once().then();
  843. page.redirect('/' + userAlias + '/worlds/' + type);
  844. }
  845. async getAppDetailsFromDB() {
  846. let defaultUserPUB = await _LCSDB.get('lcs/app').path('pub').once().then();
  847. var userAlias = await _LCSDB.user(defaultUserPUB).get('alias').once().then();
  848. if (userAlias)
  849. this.getWorldsProtosFromUserDB(userAlias);
  850. }
  851. refresh() {
  852. // socket.emit('getWebAppUpdate', "");
  853. }
  854. parseAppInstancesData(data) {
  855. if (data == "{}") {
  856. var el = document.querySelector(".instance");
  857. if (el) {
  858. var topEl = el.parentNode;
  859. topEl.removeChild(el);
  860. }
  861. // let removeElements = elms => Array.from(elms).forEach(el => el.remove());
  862. }
  863. let jsonObj = JSON.parse(data);
  864. var parsed = {};
  865. for (var prop in jsonObj) {
  866. var name = prop.split('/')[1];
  867. if (parsed[name]) {
  868. parsed[name][prop] = jsonObj[prop];
  869. } else {
  870. parsed[name] = {};
  871. parsed[name][prop] = jsonObj[prop];
  872. }
  873. }
  874. //console.log(parsed);
  875. if (Object.entries(this.worlds).length !== 0)
  876. document.querySelector("#main")._emptyLists();
  877. for (var prop in parsed) {
  878. var name = prop;
  879. let obj = Object.entries(parsed[prop]);
  880. var lists = {};
  881. obj.forEach(el => {
  882. let sotSave = prop;
  883. if (el[1].loadInfo['save_name']) {
  884. let saveName = prop + '/load/' + el[1].loadInfo.save_name;
  885. if (!lists[saveName])
  886. lists[saveName] = {};
  887. lists[saveName][el[0]] = el[1]
  888. } else {
  889. if (!lists[name])
  890. lists[name] = {};
  891. lists[name][el[0]] = el[1]
  892. }
  893. });
  894. // console.log(lists);
  895. Object.entries(lists).forEach(list => {
  896. let element = document.getElementById(list[0] + 'List');
  897. if (element) {
  898. element._setListData(list[1]);
  899. }
  900. })
  901. }
  902. // console.log(data)
  903. }
  904. }
  905. export { IndexApp }
  906. //export {getAppDetails, generateFrontPage, setLanguage, initLocale};