index-app.js 51 KB

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