index-app.js 61 KB

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