index-app.js 44 KB

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