world-app.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  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. class WorldApp {
  7. constructor(userAlias, worldName, saveName) {
  8. console.log("world app constructor");
  9. this.userAlias = userAlias;
  10. this.worldName = worldName;
  11. this.saveName = saveName;
  12. //this.worlds = {};
  13. this.language = _LangManager.language;
  14. let rootDoc = document.querySelector('#app');
  15. let el = document.createElement("div");
  16. el.setAttribute("id", "aboutWorld");
  17. rootDoc.appendChild(el);
  18. let el2 = document.createElement("div");
  19. el2.setAttribute("id", "worldStates");
  20. rootDoc.appendChild(el2);
  21. document.querySelector("#worldStates").$cell({
  22. id: "worldStates",
  23. $cell: true,
  24. $type: "div",
  25. _comps: [],
  26. _wcards: {},
  27. $components: [],
  28. _refresh: function (comps) {
  29. //do update;
  30. //this._userAlias = user;
  31. this._comps = comps;
  32. this.$components = this._comps;
  33. },
  34. $init: function () {
  35. console.log('init comp...');
  36. },
  37. $update: function () {
  38. //do update;
  39. console.log('update me');
  40. }
  41. });
  42. }
  43. createWorldStatesGUI() {
  44. let worldStatesGUI = {
  45. id: "worldStatesGUI",
  46. $type: "div",
  47. $components: [],
  48. _states: {},
  49. _refresh: function (data) {
  50. this._states = data
  51. },
  52. _makeWorldCard: function (data) {
  53. let cardID = data[1].userAlias + '_' + data[1].worldName + '_' + data[0];
  54. let card = _app.indexApp.createWorldCard(cardID, 'min');
  55. card._refresh(data[1]);
  56. card._updateComps();
  57. return {
  58. $cell: true,
  59. $type: "div",
  60. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-4",
  61. $components: [card]
  62. }
  63. //console.log(data);
  64. },
  65. $update: function () { },
  66. _updateComps: function () {
  67. this.$components = [
  68. {
  69. $type: "div",
  70. class: "mdc-layout-grid",
  71. $components: [
  72. {
  73. $type: "div",
  74. class: "mdc-layout-grid__inner",
  75. $components: [
  76. {
  77. $type: "div",
  78. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  79. $components: [
  80. {
  81. $type: "H3",
  82. $text: 'States'
  83. }
  84. ]
  85. }
  86. ]
  87. },
  88. {
  89. $type: "div",
  90. class: "mdc-layout-grid__inner",
  91. $components: Object.entries(this._states)
  92. .filter(el => Object.keys(el[1]).length !== 0)
  93. .sort(function (el1, el2) {
  94. return parseInt(el2[1].created) - parseInt(el1[1].created)
  95. })
  96. .map(this._makeWorldCard)
  97. }
  98. ]
  99. }
  100. ]
  101. }
  102. }
  103. return worldStatesGUI
  104. }
  105. async makeGUI(userPub) {
  106. let self = this;
  107. let user = { 'user': this.userAlias, pub: userPub };
  108. let space = this.worldName;
  109. let saveName = this.saveName;
  110. let cardID = user.user + '_' + space + '_' + (saveName ? saveName : "");
  111. let cardWorldType = saveName ? 'state' : 'proto';
  112. let worldNameInfo = saveName ? { protoName: space, stateName: saveName } : space
  113. let worldCardGUI = _app.indexApp.createWorldCard(cardWorldType, this.userAlias, userPub, worldNameInfo, cardID, "full", setWorldParameters); //createWorldCard(userAlias, userPub, worldName, id, type)
  114. let worldStatesGUI = [];
  115. //var runWorldGUI = {};
  116. function setWorldParameters(data) {
  117. console.log(data);
  118. let actionsGUI = {
  119. $cell: true,
  120. _gen: "",
  121. id: "worldActionsGUI",
  122. $type: "div",
  123. $components: [],
  124. _worldInfo: {},
  125. _refresh: function () {
  126. this._worldInfo = {
  127. 'userAlias': self.userAlias,
  128. 'worldName': self.saveName ? self.worldName + '/load/' + self.saveName : self.worldName,
  129. 'type': self.saveName ? 'saveState' : 'proto'
  130. }
  131. // let worldCard = document.querySelector('#worldCard');
  132. // if(worldCard){
  133. // this._worldInfo = worldCard._worldInfo;
  134. // }
  135. },
  136. $init: function () {
  137. //if (_LCSDB.user().is) {
  138. this._refresh();
  139. //}
  140. },
  141. $update: function () {
  142. let desc = this._worldInfo;
  143. let userGUI = [];
  144. // if(!desc){
  145. // this.$components = [];
  146. // return
  147. // }
  148. if (_LCSDB.user().is) {
  149. if (_LCSDB.user().is.alias == desc.userAlias) {
  150. userGUI.push(
  151. {
  152. $type: "div",
  153. id: "tree",
  154. _tree:[],
  155. _treeComp: {},
  156. $init: function(){
  157. let selfComp = this;
  158. _LCSDB.user().get('worlds').get(desc.worldName).load(res=>{
  159. // console.log(res);
  160. if(res){
  161. selfComp._tree = [{
  162. name: 'File sources: ',
  163. children: []
  164. }];
  165. Object.keys(res).filter(el=>el.includes('_js') || el.includes('_json')).forEach(el=>{
  166. selfComp._tree[0].children.push({
  167. name: el
  168. })
  169. })
  170. selfComp._treeComp = new TreeView(selfComp._tree, 'tree');
  171. selfComp._treeComp.on('select', function (evt) {
  172. console.log(evt);
  173. window.location.pathname = "/" + desc.userAlias + '/proto/' + desc.worldName + '/edit/' + evt.data.name
  174. });
  175. }
  176. })
  177. },
  178. $components:[
  179. ]
  180. }
  181. );
  182. // userGUI.push(
  183. // {
  184. // $type: "a",
  185. // class: "mdc-button ",
  186. // $text: "Edit info",
  187. // //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  188. // onclick: function (e) {
  189. // //'/:user/:type/:name/edit/:file'
  190. // if (desc.type == 'proto') {
  191. // window.location.pathname = "/" + desc.userAlias + '/proto/' + desc.worldName + '/edit/info_json'
  192. // } else if (desc.type == 'saveState') {
  193. // let names = desc.worldName.split('/');
  194. // let filename = ('savestate_/' + names[0] + '/' + names[2] + '_info_vwf_json').split('/').join("~");
  195. // window.location.pathname = "/" + desc.userAlias + '/state/' + names[0] + '/edit/' + filename;
  196. // }
  197. // //self.refresh();
  198. // }
  199. // },
  200. // {
  201. // $type: "a",
  202. // class: "mdc-button ",
  203. // $text: "Edit source",
  204. // //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  205. // onclick: function (e) {
  206. // //'/:user/:type/:name/edit/:file'
  207. // if (desc.type == 'proto') {
  208. // window.location.pathname = "/" + desc.userAlias + '/proto/' + desc.worldName + '/edit/index_vwf_yaml'
  209. // } else if (desc.type == 'saveState') {
  210. // let names = desc.worldName.split('/');
  211. // let filename = ('savestate_/' + names[0] + '/' + names[2] + '_vwf_json').split('/').join("~");
  212. // window.location.pathname = "/" + desc.userAlias + '/state/' + names[0] + '/edit/' + filename;
  213. // }
  214. // //self.refresh();
  215. // }
  216. // }
  217. // );
  218. if (desc.type == 'proto') {
  219. // userGUI.push(
  220. // // {
  221. // // $type: "a",
  222. // // class: "mdc-button mdc-button--raised mdc-card__action actionButton",
  223. // // $text: "Edit proto",
  224. // // //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  225. // // onclick: function (e) {
  226. // // window.location.pathname = "/" + desc.userAlias + '/proto/' + desc.worldName + '/edit/index_vwf_yaml'
  227. // // }
  228. // // },
  229. // {
  230. // $type: "a",
  231. // class: "mdc-button ",
  232. // $text: "Edit config",
  233. // //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  234. // onclick: function (e) {
  235. // window.location.pathname = "/" + desc.userAlias + '/proto/' + desc.worldName + '/edit/index_vwf_config_yaml'
  236. // }
  237. // },
  238. // { $type: "br" },
  239. // {
  240. // $type: "a",
  241. // class: "mdc-button",
  242. // $text: "Edit appui.js",
  243. // //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  244. // onclick: function (e) {
  245. // window.location.pathname = "/" + desc.userAlias + '/proto/' + desc.worldName + '/edit/appui_js'
  246. // }
  247. // },
  248. // {
  249. // $type: "a",
  250. // class: "mdc-button",
  251. // $text: "Edit assets.json",
  252. // //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  253. // onclick: function (e) {
  254. // window.location.pathname = "/" + desc.userAlias + '/proto/' + desc.worldName + '/edit/assets_json'
  255. // }
  256. // },
  257. // {
  258. // $type: "a",
  259. // class: "mdc-button",
  260. // $text: "Edit index.vwf.html",
  261. // //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  262. // onclick: function (e) {
  263. // window.location.pathname = "/" + desc.userAlias + '/proto/' + desc.worldName + '/edit/index_vwf_html'
  264. // }
  265. // }
  266. // );
  267. userGUI.push(
  268. { $type: "br" },
  269. {
  270. $type: "a",
  271. class: "mdc-button mdc-button--raised mdc-card__action actionButton",
  272. $text: "Delete",
  273. //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  274. onclick: function (e) {
  275. if (window.confirm("Do you really want to DELETE world?")) {
  276. _app.deleteWorld(desc.worldName, 'proto');
  277. }
  278. }
  279. }
  280. );
  281. let proxyID = data.proxy;
  282. userGUI.push(
  283. {
  284. $type: "div",
  285. style: "margin-top: 20px;",
  286. _proxyName: null,
  287. _proxyNameField: null,
  288. $components:
  289. [
  290. window._app.widgets.inputTextFieldOutlined({
  291. "id": 'proxyName',
  292. "label": proxyID,
  293. "value": this._proxyName,
  294. "type": "text",
  295. "init": function () {
  296. this._proxyNameField = new mdc.textField.MDCTextField(this);
  297. if (!proxyID) {
  298. //document.querySelector('#proxyName').value = res;
  299. } else {
  300. _app.helpers.getUserAlias(proxyID).then(res => {
  301. document.querySelector('#proxyName').value = res;
  302. })
  303. }
  304. }
  305. }),
  306. {
  307. $type: "a",
  308. class: "mdc-button mdc-button--raised mdc-card__action actionButton",
  309. $text: 'Set proxy', //self.language.t('set proxy'),//"clone",
  310. onclick: function (e) {
  311. //console.log('clone');
  312. let newProxyName = this._proxyNameField.value;
  313. _app.setNewProxyForWorld(desc.worldName, newProxyName);
  314. //_app.cloneWorldPrototype(desc.worldName, desc.userAlias, newProtoName);
  315. //self.refresh();
  316. }
  317. }
  318. ]
  319. }
  320. )
  321. }
  322. if (desc.type == 'saveState') {
  323. userGUI.push(
  324. { $type: "br" },
  325. {
  326. $type: "a",
  327. class: "mdc-button mdc-button--raised mdc-card__action actionButton",
  328. $text: "Delete",
  329. //href: "/" + desc[2] + '/worlds/' + desc[0] + '/edit', ///:user/worlds/:name/edit
  330. onclick: function (e) {
  331. _app.deleteWorld(desc.worldName, 'state');
  332. }
  333. }
  334. );
  335. }
  336. }
  337. if (desc.type == 'proto') {
  338. let worldID = window._app.helpers.GenerateInstanceID().toString();
  339. userGUI.push(
  340. {
  341. $type: "div",
  342. style: "margin-top: 20px;",
  343. _protoName: null,
  344. _protoNameField: null,
  345. $components:
  346. [
  347. window._app.widgets.inputTextFieldOutlined({
  348. "id": 'protoName',
  349. "label": worldID,
  350. "value": this._protoName,
  351. "type": "text",
  352. "init": function () {
  353. this._protoNameField = new mdc.textField.MDCTextField(this);
  354. }
  355. }),
  356. {
  357. $type: "a",
  358. class: "mdc-button mdc-button--raised mdc-card__action actionButton",
  359. $text: self.language.t('clone proto'),//"clone",
  360. onclick: function (e) {
  361. //console.log('clone');
  362. let newProtoName = this._protoNameField.value;
  363. _app.cloneWorld (desc.worldName, desc.userAlias, newProtoName);
  364. let appEl = document.createElement("div");
  365. appEl.setAttribute("id", 'cloneLink');
  366. let entry = document.querySelector('#worldActionsGUI');
  367. if (entry) {
  368. entry.appendChild(appEl);
  369. document.querySelector("#cloneLink").$cell({
  370. id: 'cloneLink',
  371. $cell: true,
  372. $type: "div",
  373. $components: [
  374. {
  375. $type: "a",
  376. class: "mdc-button mdc-button--raised mdc-card__action",
  377. $text: "Go to new cloned World!",
  378. onclick: function (e) {
  379. let myName = _LCSDB.user().is.alias;
  380. window.location.pathname = '/' + myName + '/' + newProtoName + '/about'
  381. }
  382. }
  383. ]
  384. })
  385. }
  386. // _app.cloneWorldPrototype(desc.worldName, desc.userAlias, newProtoName);
  387. //self.refresh();
  388. }
  389. }
  390. ]
  391. }
  392. );
  393. } else if (desc.type == 'saveState') {
  394. // userGUI.push(
  395. // {
  396. // $type: "a",
  397. // class: "mdc-button mdc-button--compact mdc-card__action mdc-button--outlined",
  398. // $text: "Clone",
  399. // onclick: function (e) {
  400. // //console.log('clone');
  401. // //self.cloneWorldState(desc[0], desc[2]);
  402. // //self.refresh();
  403. // }
  404. // })
  405. }
  406. }
  407. userGUI.push(
  408. window._app.widgets.p,
  409. {
  410. $type: "div",
  411. id: "tree_states",
  412. _tree:[],
  413. _treeComp: {},
  414. $init: function(){
  415. let selfComp = this;
  416. let userPub = new Promise( res=> res(_app.helpers.getUserPub(desc.userAlias)));
  417. userPub.then(pub=>{
  418. console.log(pub);
  419. _LCSDB.user(pub).get('documents').get(desc.worldName).load(res=>{
  420. // console.log(res);
  421. if(res){
  422. selfComp._tree = [{
  423. name: 'States',
  424. children: []
  425. }];
  426. Object.keys(res).filter(el=>el.includes('savestate_/' + desc.worldName + '/')).forEach(el=>{
  427. let genLink = _app.helpers.replaceSubStringALL(el.split('/')[2], '_vwf_json', '');
  428. selfComp._tree[0].children.push({
  429. name: genLink
  430. })
  431. })
  432. selfComp._treeComp = new TreeView(selfComp._tree, 'tree_states');
  433. selfComp._treeComp.on('select', function (evt) {
  434. console.log(evt);
  435. window.location.pathname = "/" + desc.userAlias + "/" + desc.worldName + "/load/" + evt.data.name;
  436. //window.location.pathname = "/" + desc.userAlias + '/proto/' + desc.worldName + '/edit/' + evt.data.name
  437. });
  438. }
  439. })
  440. })
  441. },
  442. $components:[
  443. ]
  444. }
  445. );
  446. this.$components = [
  447. {
  448. $type: "h3",
  449. $text: "World details:"
  450. }
  451. ].concat(userGUI)
  452. }
  453. }
  454. document.querySelector("#aboutWorld")._actionsGUI = actionsGUI;
  455. ///settings
  456. let settings = data.settings;
  457. if (settings) {
  458. if (settings.ar) {
  459. let runWorldGUI = {
  460. id: "runWorldGUI",
  461. $type: "div",
  462. $init: function () {
  463. console.log(worldCardGUI);
  464. },
  465. _arSwitch: null,
  466. _turnArOnSwitch: null,
  467. $components: [
  468. {
  469. $type: "div",
  470. $text: "Settings for start:"
  471. },
  472. _cellWidgets.switch({
  473. 'id': 'arjsView',
  474. 'init': function () {
  475. this._switch = new mdc.switchControl.MDCSwitch(this);
  476. this._switch.checked = false;
  477. this._arSwitch = this._switch;
  478. }
  479. }
  480. ),
  481. {
  482. $type: 'label',
  483. for: 'input-forceReplace',
  484. $text: 'Edit mode'
  485. },
  486. { $type: "div", style: "margin-top: 20px" },
  487. _cellWidgets.switch({
  488. 'id': 'arOnView',
  489. 'init': function () {
  490. this._turnArOn = new mdc.switchControl.MDCSwitch(this);
  491. this._turnArOn.checked = false;
  492. this._turnArOnSwitch = this._turnArOn;
  493. }
  494. }
  495. ),
  496. {
  497. $type: 'label',
  498. for: 'input-forceReplace',
  499. $text: 'Ar mode'
  500. }
  501. ]
  502. }
  503. document.querySelector("#aboutWorld")._runWorldGUI = runWorldGUI;
  504. //document.querySelector("#aboutWorld")._refresh(worldCardGUI);
  505. }
  506. }
  507. }
  508. document.querySelector("#aboutWorld").$cell({
  509. id: 'aboutWorld',
  510. $cell: true,
  511. $type: "div",
  512. _actionsGUI: {},
  513. _runWorldGUI: {},
  514. _worldsComps: {},
  515. _refresh: function (comps) {
  516. this._worldsComps = comps
  517. },
  518. $init: function () {
  519. //this._worldsComps = worldCardGUI;
  520. },
  521. $update: function () {
  522. this.$components = [
  523. {
  524. $type: "div",
  525. class: "mdc-layout-grid",
  526. $components: [
  527. {
  528. $type: "div",
  529. class: "mdc-layout-grid__inner",
  530. $components: [
  531. {
  532. $type: "div",
  533. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  534. $components: [
  535. {
  536. $type: "h1",
  537. class: "mdc-typography--headline4",
  538. $text: self.worldName + ' by ' + self.userAlias
  539. }
  540. ]
  541. },
  542. {
  543. $type: "div",
  544. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-4",
  545. $components: [
  546. //worldCardGUI,
  547. this._worldsComps,
  548. { $type: 'p' },
  549. this._runWorldGUI
  550. ]
  551. },
  552. {
  553. $type: "div",
  554. class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  555. $components: [
  556. this._actionsGUI
  557. ]
  558. },
  559. // {
  560. // $type: "div",
  561. // class: "mdc-layout-grid__cell mdc-layout-grid__cell--span-12",
  562. // $components: [
  563. // ].concat(worldStatesGUI)
  564. // },
  565. ]
  566. }
  567. ]
  568. }
  569. ]
  570. }
  571. })
  572. document.querySelector("#aboutWorld")._refresh(worldCardGUI);
  573. var info = {};
  574. // if (!saveName) {
  575. // _app.indexApp.allWorldsStatesForUser(user.user, space, 'worldStates')
  576. // }
  577. }
  578. }
  579. export { WorldApp }