index-app.js 37 KB

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