index-app.js 57 KB

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