index-app.js 41 KB

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