· 5 years ago · Dec 25, 2020, 09:06 PM
1import React, { Component } from "react";
2// import Radium from 'radium';
3// import Styles from './styles.jsx';
4import ModalStyles from "./StylesModal.jsx";
5import classNames from "classnames";
6// import LogoIcon from "../assets/logo.png";
7// import
8// import ArrowIcon from '../css/arrow-left.svg';
9// import TextIcon from '../assets/text.png';
10// import PaintIcon from "../assets/paint.png";
11// import EditorIcon from "../assets/editor.png";
12// import TetrisIcon from "../assets/tetris.png";
13// import ControlIcon from "../assets/joystick.png";
14// import PickSceneIcon from "../assets/scenepicker.png";
15import ProjectorIcon from "../assets/projector.png";
16// import Fonts from '../assets/tetris.png';
17
18import ImageEditor from "./ImageEditor/ImageEditor.jsx";
19import ScenePicker from "./ScenePicker.jsx";
20import ProjectToggler from "./ProjectToggler.jsx";
21import Settings from "./Settings.jsx";
22import helpers from "./shared/common.jsx";
23import Progressbar from "./Progressbar.jsx";
24import Modal from "react-modal";
25
26import FetchPlease from "fetch-please"; //yeah
27
28//todo - fiksme - dodelat centranlni API object import API from './Api.jsx';
29
30const fetchParams = { credentials: "same-origin" };
31const INITIAL_PROJECTOR_TIME = 70;
32const ONE_GB = Math.pow(1024,3);
33
34class Intro extends Component {
35 state = {
36 access: "",
37
38 public: false,
39 publicRights: -1,
40
41 modalIsOpen: false, //refactor - at se to jmenuje spravne
42 scenesModalIsOpen: false,
43 settingsModalIsOpen: false,
44 projectorModalIsOpen: false,
45
46 projectorIsInTransition: false,
47 projectorCurrentCountdown: null,
48 objectTransparency: false,
49 appApiUrl: "",
50 appWsUrl: "",
51 flashMessage: "",
52 sceneHash: null,
53 filters: [],
54 sources: [],
55 sceneId: "",
56 loaded: false, //window.public_debug ? true : false, //debug true
57 lastProjectorRequestTime: 0,
58 lastSceneRequestTime: 0,
59 allAppSources: [],
60 sourcesInScene: [],
61 sceneName: "",
62 lastSourcesString: "",
63 controllableAppsInScene: [],
64 waitingForResponse: false,
65 fitNewObjects: false,
66 firstProjectorRequest: true,
67 groupMaster: false,
68 lastSynchro: null,
69 operator: false,
70 newSourcesNeeded: true,
71 lastSourcesTime: 0,
72 // projector:{
73 // name: "",
74 // division: "",
75 // ip: "",
76 // online: false
77 // },
78 projector: false,
79 releases: [],
80 currentRelease: '',
81 storage: {},
82 projectorRequestPending: false,
83 refreshSceneInfoRequestPending: false,
84 sceneDelayTime: null,
85 //sceneRequestPending: false,
86 installed: false,
87 // public_mode: false,
88 running: false,
89 synchro: false,
90 hasUserChangedSynchro: false,
91 userChosenSynchro: null,
92 switchable: false,
93 webGL: false,
94
95 outlines2: true,
96
97 corrections: {}
98 };
99
100 projectorReqCount = 0;
101
102 api = new FetchPlease("", {
103 cors: window.config.APIUrl.indexOf(window.location.hostname) >= 0
104 }); //, {
105 api2 = new FetchPlease("", {
106 cors: window.config.APIUrl.indexOf(window.location.hostname) >= 0
107 }); //, {
108 api3 = new FetchPlease("", {
109 cors: window.config.APIUrl.indexOf(window.location.hostname) >= 0
110 }); //, {
111 api4 = new FetchPlease("", {
112 cors: window.config.APIUrl.indexOf(window.location.hostname) >= 0
113 }); //, {
114 api5 = new FetchPlease("", {
115 cors: window.config.APIUrl.indexOf(window.location.hostname) >= 0
116 }); //, {
117
118 cancalebleXHRs = {};
119
120 autoUpdateTimeout = false;
121
122 refreshSceneInfoRequest = false;
123 refreshSceneInfo2Request = false;
124 refreshProjectorInfoRequest = false;
125 refreshProjectorStateRequest = false;
126 refreshSourcesStateRequest = false;
127
128 countDownInterval = false;
129
130 storageUpdateCounter = 0;
131
132 componentWillMount() {
133 // console.log("initiali state",this.state);
134 this.fetchProjectorInfo();
135 this.fetchProjectorReleases();
136 //this.fetchSceneName();
137 this.fetchSceneInfo();
138 this.resetCursor();
139
140 // this.projectorStartTransition(); //test
141 }
142
143 // componentWillReceiveProps(nextProps){
144 // console.log("intro Will receive props",nextProps.outlinesForever);
145 // this.setState({outlinesForever: nextProps.outlinesForever});
146 // }
147
148 resetCursor() {
149 document.documentElement.style.cursor = null;
150 }
151
152 storageShouldSync(){
153 return this.state.unsyncedCount > 0 && !this.isBigSyncInProgress();
154 }
155
156 isStorageFull(){
157 return this.state.storage.freespace < ONE_GB;
158 }
159
160 isBigSyncInProgress(){
161 return !!this.state.storage.sync_big;
162 }
163
164 majorUpdateNeeded(){
165 const {releases,release} = this.state;
166
167 const majors = [...(releases || [])].filter((r)=>(!!r.major));
168 const minors = [...(releases || [])].filter((r)=>(!r.major));
169
170 return !!majors.length;
171 }
172
173 settingsHasNotification(){
174 return this.storageShouldSync() || this.isStorageFull() || this.majorUpdateNeeded();
175
176 // unsyncedCount={this.props.unsyncedCount}
177 // freespace={this.props.storage.freespace}//0*1024*1024*1024}//
178 // disabled={!this.props.storage.online}
179 // syncBig={this.props.storage.sync_big}
180
181 }
182
183
184 componentWillUnmount() {
185 console.log("unmounting INTRO component");
186 this.abortAutoRefresh(false);
187 }
188
189 abortAutoRefresh(resetRefresh = true) {
190 console.log(
191 "aborting intro refresh" + (!resetRefresh ? " for good" : " and reseting")
192 );
193 const self = this;
194
195 if (self.refreshRequest) {
196 self.refreshRequest.abort();
197 }
198
199 if (self.refreshSceneInfoRequest) {
200 self.refreshSceneInfoRequest.abort();
201 }
202
203 if (self.refreshSceneInfo2Request) {
204 self.refreshSceneInfo2Request.abort();
205 }
206
207 if (self.refreshProjectorStateRequest) {
208 self.refreshProjectorStateRequest.abort();
209 }
210
211 if (self.refreshSourcesStateRequest) {
212 self.refreshSourcesStateRequest.abort();
213 }
214
215 if (self.refreshProjectorInfoRequest) {
216 self.refreshProjectorInfoRequest.abort();
217 }
218
219 if (self.refreshProjectorInfoRequest) {
220 self.refreshProjectorInfoRequest.abort();
221 }
222
223 if (self.autoUpdateTimeout) {
224 clearTimeout(self.autoUpdateTimeout);
225 }
226
227 // self.resetRefresh();
228 // if(self.api) self.api.abort();
229 // if (self.refreshRequest) self.refreshRequest.abort();
230 if (resetRefresh) {
231 self.resetRefresh();
232 }
233 }
234
235 resetRefresh() {
236 // return;
237 const self = this;
238 // console.log("setting refresh to 5s");
239 if (this.refreshRequest) this.refreshRequest.abort();
240 if (this.refreshSceneInfoRequest) this.refreshSceneInfoRequest.abort();
241 if (this.refreshSceneInfo2Request) this.refreshSceneInfo2Request.abort();
242
243 if (self.autoUpdateTimeout) {
244 clearTimeout(self.autoUpdateTimeout);
245 console.log("rqd: === clearing fetchSceneRestrictions call ===");
246 }
247
248 self.autoUpdateTimeout = setTimeout(function() {
249 console.log("rqd: === autofetching fetchSceneRestrictions ===");
250 // if (self.state.isMounted){
251 self.fetchSceneInfo();
252 // }
253 }, 4 * 1000); //self.state.refresh
254 }
255
256 //href={window.config.APILogoutUrl}
257 HelpLink() {
258 const links = [
259 "http://lumitrix.eu/indoor/support",
260 "http://lumitrix.eu/outdoor/support",
261 "http://lumitrix.eu"
262 ];
263 const installationName = this.props.installationName;
264 const showHelp = installationName.match(/^(tph|lb)/);
265 const link =
266 installationName.toString().indexOf("lb") == 0
267 ? links[0]
268 : installationName.toString().indexOf("tph") == 0 ? links[1] : links[2];
269
270 if (this.isGroupMode()) {
271 // && showHelp
272 return "http://lumitrix.eu/indoor/support";
273 }
274
275 // return (showHelp) ? (<a target="_blank" className="white_link" href={link}>Help</a>) : ""
276 return showHelp ? link : "";
277 }
278
279 HelpLinkHTML() {
280 const helpLink = this.HelpLink();
281 return helpLink ? (
282 <a target="_blank" className="white_link" href={helpLink}>
283 Help
284 </a>
285 ) : (
286 ""
287 );
288 }
289
290 projectionOffText() {
291 if (this.state.running == false && this.state.manual == true) {
292 return "manual mode on";
293 }
294 return "off";
295 }
296
297 projectionOnText() {
298 if (this.state.running == true && this.state.manual == true) {
299 // if (true){
300 return "Lumiverse on";
301 }
302 if (this.state.running == true && this.state.manual == false) {
303 // if (true){
304 return "on";
305 }
306
307 return "on";
308 }
309
310 schedulerExclamationIcon() {
311 if (
312 // (true) ||
313 (this.state.running == true && this.state.manual == true) ||
314 (this.state.running == false && this.state.manual == true)
315 ) {
316 return (
317 <span
318 onClick={this.showExclamationConfirm.bind(this)}
319 className={"icon_exclamation"}
320 />
321 );
322 } else {
323 return "";
324 }
325 }
326
327 changeCorrection(which, value){
328 const self = this;
329 console.log('changeCorrection called',which, value);
330 // /xxx/corrections?brightness=&contrast=&gamma=&r=&g=&b=&
331 // /xxx/corrections?brightness=0&/
332 let params = {brightness:'',contrast:'',gamma:'',r:'',g:'',b:''};
333 params[which] = value;
334 const paramString = Object.keys(params).map(function(key) {
335 return key + '=' + params[key];
336 }).join('&') + '&';
337
338 let currentCorrections = {...this.state.corrections};
339 currentCorrections[which] = value;
340
341 self.setState({corrections: currentCorrections});
342
343 if (self.cancalebleXHRs["corrections"]) {
344 self.cancalebleXHRs["corrections"].abort();
345 }
346 const fetchUrl = window.config.APIUrl + '/corrections?'+paramString;
347
348 const api = new FetchPlease("", {
349 cors: window.config.APIUrl.indexOf(window.location.hostname) >= 0
350 });
351
352 let { xhr, promise } = api.getRequest(fetchUrl, {}, fetchParams);
353
354 self.cancalebleXHRs["corrections"] = xhr;
355 promise
356 .then(data => {
357 self.setState({corrections: data.corrections});
358 })
359 .catch(function(err) {
360 // self.processAjaxError(err);
361 });
362
363
364 }
365
366 changeCorrection_(which, value){
367 const self = this;
368 console.log('changeCorrection called',which, value);
369 // /xxx/corrections?brightness=&contrast=&gamma=&r=&g=&b=&
370 // /xxx/corrections?brightness=0&/
371 let params = {brightness:'',contrast:'',gamma:'',r:'',g:'',b:''};
372 params[which] = value;
373 const paramString = Object.keys(params).map(function(key) {
374 return key + '=' + params[key];
375 }).join('&') + '&';
376
377 let currentCorrections = {...this.state.corrections};
378 currentCorrections[which] = value;
379
380 self.setState({corrections: currentCorrections});
381
382 helpers.api('/corrections?'+paramString,'',function(data){
383 self.setState({corrections: data.corrections});
384 // console.log("return from corrections set",'/corrections?'+paramString,data.corrections);
385 });
386 // function api(path,objectId="",callback = function(){},before = function(){},fetchParams = {credentials: 'same-origin'}){
387 }
388
389 restoreDefaultCorrections(){
390 const self = this;
391 const params = {brightness:0,contrast:0,gamma:'1.0',r:0,g:0,b:0};
392 const paramString = Object.keys(params).map(function(key) {
393 return key + '=' + params[key];
394 }).join('&') + "&";
395 helpers.api('/corrections?'+paramString,'',function(data){
396 self.setState({corrections: data.corrections});
397 });
398 }
399
400
401 showExclamationConfirm() {
402 this.props.changeConfirm({
403 type: "confirm",
404 isOpen: true,
405 okText: "Fix",
406 title: "Fix Scheduler",
407 text:
408 "Projection Scheduler is disabled because projector is now playing content in manual mode.<br><br> Use Fix to end current manual playback and activate Projection Scheduler.",
409 cancel: this.confirmHide.bind(this),
410 callback: this.fixScheduler.bind(this)
411 });
412 }
413
414 fixScheduler() {
415 console.log("fix scheduler");
416 const self = this;
417 helpers.api("/projector/auto/1", "", function() {
418 self.fetchProjectorState();
419 });
420 }
421
422 allFiltersWithSources(){
423 const filters = this.state.filters || [];
424 const sources = this.state.sources || [];
425 const filtersWithSources = filters.map((f)=>({...f,source: sources.find((s)=>(s.id == f.sourceId))})).filter((f)=>(f.source && f.source.control));
426 // console.log("allFiltersWithSources",filtersWithSources);
427 return filtersWithSources;
428 }
429
430 projectionExclamationIcon() {
431 if (
432 // true ||
433 (this.state.running == true && this.state.manual == true) ||
434 (this.state.running == false && this.state.manual == true)
435 ) {
436 return (
437 <span
438 onClick={this.showExclamationConfirm.bind(this)}
439 className={"icon_exclamation"}
440 />
441 );
442 }
443 if (this.state.running == true && this.state.manual == false) {
444 // if (true){
445 return <span className={"right_text blue_text"}>Now Playing</span>;
446 }
447 if (this.state.running == false && this.state.manual == false) {
448 return <span className={"right_text blue_text"}>Ready</span>;
449 }
450 }
451
452 switchable() {
453 if (this.state.running == true && this.state.manual == false) {
454 //running == true && manual == false
455 //velká switchable vyjímka: ať je v tomto stavu switchable cokoliv, ber, že je switchable false a neumožni přepnout lumiverse. Smysl je takový, že tento stav se dá změnit ze scheduleru změnou tasku. Kvůli kompatibilitě z old_demo zde ale tuším vracím switchable true.
456 return false;
457 }
458 return this.state.switchable;
459 }
460
461 ProjectorActions() {
462 //style={Object.assign({},this.logoutStyles())}
463 //Help bude odkazovat na nějakou stránku v manualu, zatím to uděláme tak, že pokud:
464
465 // název instalace začíná na lb, např lb1015, odkažte na http://lumitrix.eu/indoor/support
466 // pokud na tph, např tphXXX, odkažte na http://lumitrix.eu/outdoor/support
467 // jinak help schovejte a vypište jen offline
468 if (this.state.projector.loading){
469 return (<div className="right_text"><span className="spinner"></span></div>);
470 }
471
472
473 if (this.state.projectorIsInTransition) {
474 return <div className="right_text">{this.state.flashMessage}</div>;
475 }
476 // if ( (this.state.projector && this.state.projector.offline) || !this.state.projector ){
477 if (!this.isProjectorActive()) {
478 return (
479 <div className="right_text">
480 <span className="red">Offline. </span>
481 {this.HelpLinkHTML()}
482 </div>
483 );
484 }
485
486 if (!this.isProjectorHidden()) {
487 return (
488 <span
489 onClick={this.toggleProjectorModal.bind(this)}
490 className="icon power_of"
491 key="projectorToggler"
492 title=""
493 />
494 );
495 }
496 }
497
498 stripGroupModeName(name = "") {
499 if (!this.isGroupMode()){
500 return name;
501 }
502 const splits = ("" + name + "").split("-");
503 return splits[splits.length - 1];
504 }
505
506 getInstallationName() {
507 return helpers.upcase(this.stripGroupModeName(this.props.installationName));
508 }
509
510 render() {
511 return (
512 <div id="intro_wrapper">
513 <div className="main_header" ref="main">
514 <div className="head_wrapper">
515 <div
516 className={classNames("left-arr back_to_editor",{blank: this.isEditorHidden()})}
517 onClick={
518 this.isEditorActive()
519 ? this.props.toggleIntro
520 : function(e) {
521 e.preventDefault();
522 }
523 }
524 />
525 <div className="logo_text">Lumiverse</div>
526 </div>
527 </div>
528
529 {this.state.loaded ? (
530 <div className="main_content_wrapper">
531 <div className="narrow_content">
532 <div
533 className={classNames("row interactive", {
534 hidden: this.isProjectorHidden()
535 })}
536 >
537 <div className="pagewidth">
538 <div
539 className={classNames("projector", "blue", {
540 tph: this.isProjectorTPH(),
541 group_mode: this.isGroupMode()
542 })}
543 >
544 <a href={window.se_root_url} className="icon20" />
545 <div className="text">
546 <span>{this.getInstallationName()}</span>
547 {/*this.props.projectorRelease ? ('Release: ' + this.props.projectorRelease) : ""*/}
548 {this.ProjectorActions()}
549 </div>
550 </div>
551 </div>
552 <a className="overlay" href={window.se_root_url} />
553 </div>
554
555 <div className="row interactive">
556 <div className="pagewidth">
557 <div
558 className={classNames("scenes", "blue", {
559 disabled: !this.isScenePickerActive(),
560 hidden: this.isScenePickerHidden()
561 })}
562 >
563 <div className="icon20" />
564 <div className="text">{this.state.sceneName}</div>
565 </div>
566 </div>
567 <a
568 className="overlay"
569 href="#"
570 onClick={this.openScenesModal.bind(this)}
571 />
572 </div>
573
574 <div
575 className={classNames("row", {
576 hidden: this.isGroupMode(),
577 interactive: this.isControlActive()
578 })}
579 >
580 <div className="pagewidth">
581 <div
582 className={classNames("app_controller", {
583 disabled: (!this.isControlActive() || !this.isProjectorActive())
584 })}
585 >
586 <div className="icon20" />
587 <div className="text">
588 App controller ({
589 this.state.controllableAppsInScene.length + this.allFiltersWithSources().length
590 })
591 </div>
592 </div>
593 </div>
594 {(this.isControlActive() && this.isProjectorActive()) ? (
595 <a
596 className="overlay"
597 href="#"
598 onClick={this.toggleControl.bind(this)}
599 />
600 ) : (
601 ""
602 )}
603 </div>
604
605 <div
606 className={classNames("row interactive", {
607 hidden: this.isEditorHidden()
608 })}
609 >
610 <div className="pagewidth">
611 <div
612 className={classNames("editor", {
613 disabled: !this.isEditorActive()
614 })}
615 >
616 <div className="icon20" />
617 <div className="text">Editor</div>
618 </div>
619 </div>
620 <a
621 className="overlay"
622 href="#"
623 onClick={
624 this.isEditorActive()
625 ? this.props.toggleIntro
626 : function(e) {
627 e.preventDefault();
628 }
629 }
630 />
631 </div>
632
633 {this.isSettingsVisible() ? (
634 <div className={"row interactive "}>
635 <a
636 onClick={this.showSettingsModal.bind(this)}
637 className="pagewidth"
638 key="settingsDialogTrigger"
639 >
640 <div className={classNames("settings",{notification: this.settingsHasNotification()})}>
641 <div className="icon20" />
642 <div className="text">Settings</div>
643 </div>
644 </a>
645 </div>
646 ) : (
647 ""
648 )}
649
650 <div
651 className="row last interactive"
652 style={Object.assign({}, this.logoutStyles())}
653 >
654 <a
655 onClick={this.confirmLogout.bind(this)}
656 className="pagewidth"
657 key="sceneLogout"
658 >
659 <div className="logoutrow">
660 <div className="icon20" />
661 <div className="text">Logout</div>
662 </div>
663 </a>
664 </div>
665
666 {/*
667 <div className={classNames("item",{active: this.isProjectorActive(),hidden: this.isProjectorHidden()})}>
668 <a onClick={this.toggleProjector.bind(this)}>
669 <img src={ProjectorIcon} alt="Control icon" />
670 <p>Projector</p>
671 </a>
672 </div> */}
673 </div>
674 </div>
675 ) : (
676 ""
677 )}
678
679 <Modal
680 key="scenesPickerModal"
681 isOpen={this.state.scenesModalIsOpen}
682 // <div key="modalClose" style={styles.modalClose} onClick={this.closeModal.bind(this)}>×</div>
683 // <div key="scenesPickerClose" style={styles.modalClose} onClick={this.closeScenesModal.bind(this,false)}>×</div>
684 // onAfterOpen={this.afterOpenModal.bind(this)}
685 onRequestClose={this.closeScenesModal.bind(this, true)}
686 contentLabel=""
687 style={ModalStyles.modalISE}
688 >
689 <ScenePicker
690 abortAutoRefresh={function() {}}
691 isGroupMode={this.isGroupMode()}
692 isFeatureEnabled={this.props.isFeatureEnabled}
693 isFeatureBeta={this.props.isFeatureBeta}
694 betaText={this.props.betaText}
695 isOperatorMode={this.isOperatorMode()}
696 refreshSceneInfo={this.refreshSceneInfo.bind(this)}
697 closeModal={this.closeScenesModal.bind(this, false)}
698 closeModalAndRefresh={this.closeScenesModal.bind(this, true)}
699 changeConfirm={this.props.changeConfirm}
700 updateSceneName={this.updateSceneName.bind(this)}
701 startUpload={this.startUpload.bind(this)}
702 processAjaxError={this.processAjaxError.bind(this)}
703 />
704 </Modal>
705
706 <Modal
707 isOpen={this.state.modalIsOpen && !!this.state.sceneHash}
708 // onAfterOpen={this.afterOpenModal.bind(this)}
709 // onRequestClose={this.closeModal.bind(this)}
710 contentLabel={""}
711 style={ModalStyles.modalISE}
712 >
713 <ImageEditor
714 ref="imageEditorInstance"
715 showEdit={false}
716 forceAllControllers={true}
717 activeObject={{id: -1,name:'z',controllableFilters: this.allFiltersWithSources()}}
718 types={{ control: true }}
719 abortAutoRefresh={function() {}}
720 changeTab={function() {}}
721 imagesInScene={[]}
722 isControlActive={this.isControlActive()}
723 controllableAppsInScene={this.state.controllableAppsInScene} //
724 loadingFinished={this.loadingFinished.bind(this)}
725 logoutShown={this.logoutShown()}
726 publicRights={this.state.publicRights}
727 public={this.state.public}
728 access={this.state.access}
729 sceneHash={this.state.sceneHash}
730 appApiUrl={this.state.appApiUrl}
731 appWsUrl={this.state.appWsUrl}
732 upload={false}
733 projector={this.state.projector}
734 sources={[]}
735 tabIndex={0}
736 setNewData={function() {}}
737 closeModal={this.closeModal.bind(this)}
738 />
739 </Modal>
740
741 <Modal
742 isOpen={this.state.projectorModalIsOpen}
743 // onAfterOpen={this.afterOpenModal.bind(this)}
744 contentLabel={""}
745 onAfterOpen={this.fetchProjectorState.bind(this)}
746 onRequestClose={this.closeProjectorModal.bind(this)}
747 style={ModalStyles.modalISE}
748 >
749 <ProjectToggler
750 isGroupMode={this.isGroupMode()}
751 isOperatorMode={this.isOperatorMode()}
752 lastSynchro={this.state.lastSynchro}
753 projectorIsInTransition={this.state.projectorIsInTransition}
754 projectorStartTransition={this.projectorStartTransition.bind(this)}
755 projectorCurrentCountdown={this.state.projectorCurrentCountdown}
756 projectorInitial={INITIAL_PROJECTOR_TIME}
757 projectionOnText={this.projectionOnText()}
758 projectionOffText={this.projectionOffText()}
759 fetchProjectorState={this.fetchProjectorState.bind(this)}
760 projectionExclamationIcon={this.projectionExclamationIcon()}
761 toggleProjector={this.toggleProjector.bind(this)}
762 toggleProjectorOn={this.toggleProjectorOn.bind(this)}
763 toggleProjectorOff={this.toggleProjectorOff.bind(this)}
764 toggleSynchroMode={this.toggleProjectorSynchroMode.bind(this)}
765 schedulerExclamationIcon={this.schedulerExclamationIcon()}
766
767 changeConfirm={this.props.changeConfirm}
768 running={this.state.running}
769 switchable={this.switchable()}
770 userChosenSynchro={this.initialSynchroState()} //nastavuje se z API, ale je menitelne userem
771 helpLink={this.HelpLink()}
772 togglerActive={this.projectorTogglerActive()}
773 offActive={this.projectorOffActive()}
774 onActive={this.projectorOnActive()}
775 synchroModeSwitchable={this.projectorSynchroModeSwitchable()}
776 flashMessage={this.state.flashMessage}
777 processAjaxErrorWithoutLogout={this.processAjaxErrorWithoutLogout.bind(
778 this
779 )}
780 closeModal={this.closeProjectorModal.bind(this)}
781
782 isFeatureEnabled={this.props.isFeatureEnabled}
783 isFeatureBeta={this.props.isFeatureBeta}
784 betaText={this.props.betaText}
785
786 />
787 </Modal>
788
789 <Modal
790 isOpen={this.state.settingsModalIsOpen}
791 // onAfterOpen={this.afterOpenModal.bind(this)}
792 contentLabel={""}
793 //onAfterOpen={this.fetchProjectorState.bind(this)}
794 onAfterOpen={this.fetchProjectorState.bind(this)}
795 onRequestClose={this.closeSettingsModal.bind(this)}
796 style={ModalStyles.modalISE}
797 >
798 <Settings
799 abortAutoRefresh={this.abortAutoRefresh.bind(this)}
800 toggleIntro={this.props.toggleIntro}
801 toggleIntroWithImageEditor={this.props.toggleIntroWithImageEditor}
802 hasNotification={this.settingsHasNotification()}
803 isProjectorTPH={this.isProjectorTPH()}
804 unsyncedCount={this.state.unsyncedCount}
805 storage={this.state.storage}
806 updateStorageData={this.updateStorageData.bind(this)}
807 setResolution={this.setResolution.bind(this)}
808 setAdvanced={this.setAdvanced.bind(this)}
809 sceneName={this.state.sceneName}
810 sceneId={this.state.sceneId}
811 scenePublicRights={this.state.publicRights}
812
813 sceneDelayedStart={this.state.sceneDelayedStart}
814 sceneDelayTime={this.state.sceneDelayTime}
815 loadingInSceneForm={this.state.loadingInSceneForm}
816 sceneOperatorHide={this.state.sceneOperatorHide}
817 sceneThumbnail={this.state.thumbnail}
818 sceneSize={this.state.sceneSize}
819 scenePublic={this.state.publicScene}
820 changePublic={this.changeSceneSetting.bind(
821 this,
822 "public",
823 this.state.publicScene ? 0 : 1
824 )}
825 changePublicRights={this.changeSceneSetting.bind(
826 this,
827 "public_rights",
828 null
829 )}
830 changeDelayedStart={this.changeSceneSetting.bind(
831 this,
832 "delayed",
833 (this.state.sceneDelayedStart || this.state.sceneDelayedStart > 0) ? 0 : 1
834 )}
835 changeOperatorHide={this.changeSceneSetting.bind(
836 this,
837 "operator_hide",
838 this.state.sceneOperatorHide ? 0 : 1
839 )}
840
841 waitingForResponse={this.state.waitingForResponse}
842 setWaitingForResponse={this.setWaitingForResponse.bind(this)}
843 changeSceneName={this.changeSceneSetting.bind(this, "name")}
844 projectName={this.props.installationName}
845 startUpload={this.startUpload.bind(this)}
846 thumbnail={this.state.thumbnail}
847 setCalibrationOwner={this.props.setCalibrationOwner}
848 isCalibrationOwner={this.props.isCalibrationOwner}
849 unsetCalibrationOwner={this.props.unsetCalibrationOwner}
850 // camera calibration props
851 projectorOffline={!(this.state.projector) || !this.state.projector.online}
852 lumiverseStateSwitchable={this.switchable()}
853 runningLumiverse={this.state.running_lumiverse}
854 // /camera calibration props
855 corrections={this.state.corrections}
856 restoreDefaultCorrections={this.restoreDefaultCorrections.bind(this)}
857
858 changeConfirm={this.props.changeConfirm}
859
860 firmware={this.props.projectorRelease || false}
861 releases={this.state.releases}
862 release={this.state.currentRelease}
863
864 closeModal={this.closeSettingsModal.bind(this)}
865 outlinesForever={this.props.outlinesForever}
866 webGL={this.state.webGL}
867 toggleGL={this.toggleGL.bind(this)}
868
869 isFeatureEnabled={this.props.isFeatureEnabled}
870 isFeatureBeta={this.props.isFeatureBeta}
871 betaText={this.props.betaText}
872 changeCorrection={this.changeCorrection.bind(this)}
873
874 toggleOutlinesForever={this.props.toggleOutlinesForever}
875 toggleFitNewObjects={this.toggleFitNewObjects.bind(this)}
876 fitNewObjects={this.state.fitNewObjects}
877 toggleObjectTransparency={this.toggleObjectTransparency.bind(this)}
878 objectTransparency={this.state.objectTransparency}
879 />
880 </Modal>
881
882 <div
883 id="flashMessage"
884 style={{
885 position: "fixed",
886 left: "10%",
887 right: "10%",
888 bottom: "5%",
889 color: "#fff",
890 textAlign: "center"
891 }}
892 />
893 {this.loader()}
894 </div>
895 );
896 }
897 // <Progressbar title={'Projector is turning on'} unit='s' total={INITIAL_PROJECTOR_TIME} current={this.state.projectorCurrentCountdown} />
898 loadingFinished(isPublicMode) {
899 if (!isPublicMode) {
900 this.setState({ loaded: true });
901 this.props.unsetFirstLoad();
902 }
903 }
904
905 setWaitingForResponse() {
906 this.setState({ waitingForResponse: true });
907 }
908
909 loader() {
910 if (!this.state.loaded && (this.props.firstLoad || this.publicModeOne())) {
911 // if (this.publicModeOne() && !this.state.loaded){
912 return <div id="splash_screen" />;
913 }
914 }
915
916 toggleFitNewObjects() {
917 const newVal = !this.state.fitNewObjects; // zmenime stavajici stav
918 const self = this;
919 helpers.api("/fitNewObjects/" + (!!newVal ? 1 : 0), "", function(data) {
920 self.setState({ fitNewObjects: data.fit_new_objects });
921 });
922 }
923
924 toggleObjectTransparency() {
925 const newVal = !this.state.objectTransparency; // zmenime stavajici stav
926 const self = this;
927 helpers.api("/objectTransparency/" + (!!newVal ? 1 : 0), "", function(
928 data
929 ) {
930 self.setState({ objectTransparency: data.object_transparency });
931 });
932 }
933
934 toggleGL() {
935 // helpers.API(
936 // cancalebleXHRs["outlinesForever"],
937 // "/resolution",
938 // {checked:checked},
939 // function(data){
940 // this.setState({outlinesForever: data.outlines_forever});
941 // }
942 // );
943
944 const checked = !this.state.webGL; // zmenime stavajici stav
945
946 const self = this,
947 url = "/useWebgl",
948 fetchUrl = window.config.APIUrl + url + (checked ? "/1" : "");
949
950 let api = new FetchPlease("", {
951 cors: window.config.APIUrl.indexOf(window.location.hostname) >= 0
952 });
953
954 console.log(
955 "sending request to toggle outlines",
956 checked,
957 self.cancalebleXHRs
958 );
959
960 // return;
961
962 if (self.cancalebleXHRs["useWebgl"]) {
963 self.cancalebleXHRs["useWebgl"].abort();
964 }
965
966 let { xhr, promise } = api.getRequest(fetchUrl, {}, fetchParams);
967
968 self.cancalebleXHRs["useWebgl"] = xhr;
969 promise
970 .then(data => {
971 self.setState({
972 webGL: data.use_webgl
973 });
974 self.processAjaxSuccess();
975 })
976 .catch(function(err) {
977 self.processAjaxError(err);
978 });
979 }
980
981 projectorTogglerActive() {
982 return !this.state.projectorIsInTransition && this.switchable();
983 }
984
985 projectorOnActive() {
986 return (
987 !this.state.projectorIsInTransition &&
988 this.switchable() &&
989 !this.state.running
990 );
991 }
992
993 projectorOffActive() {
994 return (
995 !this.state.projectorIsInTransition &&
996 this.switchable() &&
997 this.state.running
998 );
999 }
1000
1001 projectorSynchroModeSwitchable() {
1002 return !this.state.projectorIsInTransition && this.switchable();
1003 }
1004
1005 projectorStartTransition() {
1006 if (this.state.projectorIsInTransition) return;
1007
1008 this.setState({
1009 projectorCurrentCountdown: INITIAL_PROJECTOR_TIME,
1010 projectorIsInTransition: true,
1011 flashMessage: "lumiverse starting..."
1012 });
1013
1014 // this.startProjectorInterval();
1015 }
1016
1017 // startProjectorInterval(){
1018 // const self = this;
1019 // if (this.countDownInterval) clearInterval(this.countDownInterval);
1020 // this.countDownInterval = setInterval(function(){
1021 // if (self.state.projectorCurrentCountdown > 0){
1022 // self.setState({projectorIsInTransition: true,projectorCurrentCountdown: self.state.projectorCurrentCountdown - 1});
1023 // }
1024 // else{
1025 // clearInterval(self.countDownInterval);
1026 // self.setState({projectorIsInTransition: false,projectorCurrentCountdown: null});
1027 // self.closeProjectorModal();
1028 // self.fetchProjectorInfo();
1029 // }
1030 // },1000);
1031 // }
1032
1033 logoutShownNew() {
1034 console.log("logoutShown?", this.state.access, this.state.public);
1035 //v lumiversu tlacitko odhlasit ma chybet pouze v situacich:
1036
1037 if (this.state.access == "public" && !this.state.public) {
1038 return false;
1039 }
1040
1041 if (this.state.access == "public_free" && this.state.public) {
1042 //- pristupuju jako public user (pres public url) a instalace ma pravo public_free
1043 return false;
1044 }
1045
1046 if (!this.state.public) {
1047 if (this.state.access == "free") {
1048 //- pristupuju jako normalni user (tedy nikoliv pres public url) a instalace ma prava free (tedy v private, public, ale i public_free se odlhasovaci tlacitko zobrazuje)
1049 return false;
1050 } else {
1051 return true;
1052 }
1053 } else {
1054 return false;
1055 }
1056
1057 return true;
1058 }
1059
1060 logoutShown__() {
1061 //return {display:'block'};
1062
1063 if (this.state.access == "" || this.state.access == "free") return false;
1064 else if (this.state.access == "public_free") {
1065 if (this.state.public) {
1066 return false; //jsem user v public free modu (nevim ze jsem prihlasen)
1067 } else {
1068 return true; //jsem admin v public free modu
1069 }
1070 } else {
1071 //private access a public access
1072 // console.log("logou button is visible, because - access: "+this.state.access + ", public: "+(this.state.public ? 'true' : 'false'));
1073 if (this.state.public && this.state.access == "public") return true;
1074 else return false;
1075 }
1076 }
1077
1078 logoutShown() {
1079 //return {display:'block'};
1080
1081 switch (true) {
1082 case this.isGroupMode() || this.isOperatorMode():
1083 return true;
1084 case this.state.access == "" || this.state.access == "free":
1085 return false;
1086 case this.state.access == "public_free" && this.state.public:
1087 return false;
1088 case this.state.access == "public_free" && !this.state.public:
1089 return true;
1090 case this.state.access == "private":
1091 return true;
1092 case this.state.access == "public":
1093 return true;
1094 default:
1095 return false;
1096 }
1097 }
1098
1099 logoutStyles() {
1100 return { display: this.logoutShown() ? "block" : "none" };
1101 }
1102
1103 openScenesModal() {
1104 if (!this.isScenePickerActive()) return false;
1105 this.setState({ scenesModalIsOpen: true });
1106 }
1107
1108 closeScenesModal(refreshWindow) {
1109 const self = this;
1110 this.setState({ scenesModalIsOpen: false });
1111 if (refreshWindow) {
1112 // window.location.reload(true);
1113 self.unsetControl();
1114 self.abortAutoRefresh(true);
1115 self.fetchSceneInfo();
1116 }
1117 }
1118
1119 refreshSceneInfo() {
1120 this.unsetControl();
1121 this.abortAutoRefresh(true);
1122 this.fetchSceneInfo();
1123 }
1124
1125 closeProjectorModal() {
1126 this.setState({ projectorModalIsOpen: false });
1127 }
1128
1129 closeSettingsModal() {
1130 this.setState({ settingsModalIsOpen: false });
1131 }
1132
1133 showSettingsModal() {
1134 this.setState({ settingsModalIsOpen: true });
1135 }
1136
1137 //*******************//
1138 //projector controlls//
1139 //*******************//
1140
1141 isProjectorTPH() {
1142 return /^TPH/.test(this.props.installationName.toString());
1143 }
1144
1145 toggleProjector() {
1146 if (this.projectorOnActive()) {
1147 this.toggleProjectorOn();
1148 return;
1149 }
1150 if (this.projectorOffActive()) {
1151 this.toggleProjectorOff();
1152 return;
1153 }
1154 }
1155
1156 toggleProjectorOn() {
1157 if (!this.projectorOnActive()) return;
1158 this.projectorStartTransition();
1159 const self = this,
1160 fetchUrl =
1161 window.config.APIUrl +
1162 "/projector/lumiverse/on?synchro=" +
1163 (this.initialSynchroState() ? 1 : 0);
1164 // console.log("fetchUrl",fetchUrl);
1165 // return;
1166 fetch(fetchUrl, fetchParams)
1167 .then(response => {
1168 return response.json();
1169 })
1170 .then(data => {
1171 if (!self.refs.main) return;
1172 console.log("Got projector data from on");
1173 console.log(data);
1174 // self.setState({...data.projector.lumiverse});
1175 self.fetchProjectorState();
1176 self.setState({ flashMessage: "", projectorIsInTransition: false });
1177 self.closeProjectorModal();
1178 // self.fetchProjectorInfo();
1179 // self.props.closeModal();
1180 });
1181 self.closeProjectorModal();
1182 }
1183
1184 toggleProjectorOff() {
1185 if (!this.projectorOffActive()) return;
1186 const self = this,
1187 fetchUrl =
1188 window.config.APIUrl +
1189 "/projector/lumiverse/off?synchro=" +
1190 (this.initialSynchroState() ? 1 : 0);
1191 // console.log("fetchUrl",fetchUrl);
1192 // return;
1193 fetch(fetchUrl, fetchParams)
1194 .then(response => {
1195 return response.json();
1196 })
1197 .then(data => {
1198 console.log("Got projector data from off");
1199 console.log(data);
1200 // self.setState({...data.projector.lumiverse});
1201 self.setState({ flashMessage: "", projectorIsInTransition: false });
1202 self.fetchProjectorState();
1203 self.closeProjectorModal();
1204 });
1205
1206 this.closeProjectorModal();
1207 this.setState({
1208 flashMessage: "lumiverse turning off...",
1209 projectorIsInTransition: true
1210 });
1211 }
1212
1213 initialSynchroState(){
1214 if (this.state.hasUserChangedSynchro){
1215 return !!this.state.userChosenSynchro;
1216 }else{
1217 return !!this.state.lastSynchro;
1218 }
1219 }
1220
1221 toggleProjectorSynchroMode() {
1222 console.log(
1223 "toggleProjectorSynchroMode call",
1224 this.projectorSynchroModeSwitchable()
1225 );
1226 // pokud lumiverse nehraje (running: false), zaškrtávatko synchronized mode je zaškrtávatelné, ale nedělá žádnou akci. Tedy můžu ho zaškrtávat, odškrtávat, ale dokud nekliknu na ON, nic se nestane. Defaultní stav zaškrtávatka je, že je odškrtlé.
1227 // Pokud ho nechám odškrtlé a dám projector ON, zavolá se lumiverse/on jako doteď (nebo lumiverse/on/?synchro=0), pokud bude zašrktlé, zavolá se lumiverse/on/?synchro=1. Po kliknutí na On se jako nyní skočí na úvodní obrazovku a dole běží nějakou dobu nápis "lumiverse starting" - jak to je teď
1228 // pokud lumiverse hraje a dám off, zavolá se klasicky lumiverse/off a skočí se na úvodní stránku s nápisem "lumiverse turning off" jak je to teď
1229 // pokud lumiverse hraje a kliknu na zaškrtávatko sychronized_mode, podle toho zda bylo či nebylo zaškrtlé se vždy zavolá lumiverse/change_synchro/?synchro=1|0 a jde se na úvodní stránku, kde se zobrazí nápis "lumiverse reconfiguring" ve stejné délce jako starting či tak něco...
1230 //userChosenSynchro se vzdy s objevenim dialogu nastavi dle API
1231
1232 if (!this.projectorSynchroModeSwitchable()) return;
1233
1234 const newSynchroState = !(this.initialSynchroState());
1235 this.setState({ userChosenSynchro: newSynchroState, hasUserChangedSynchro: true});
1236 if (!this.state.running) {
1237 //nedela nic, jen nastavi docasny synchro state
1238 } else {
1239 const self = this,
1240 fetchUrl =
1241 window.config.APIUrl +
1242 "/projector/lumiverse/change_synchro/?synchro=" +
1243 (newSynchroState ? 1 : 0);
1244 // console.log("fetchUrl",fetchUrl);
1245 // return;
1246 fetch(fetchUrl, fetchParams)
1247 .then(response => {
1248 return response.json();
1249 })
1250 .then(data => {
1251 console.log("Got projector synchro toggle");
1252 console.log(data);
1253 // self.setState({...data.projector.lumiverse});
1254 self.setState({ flashMessage: "", projectorIsInTransition: false });
1255 self.fetchProjectorState();
1256 self.closeProjectorModal();
1257 });
1258
1259 this.closeProjectorModal();
1260 this.setState({
1261 flashMessage: "lumiverse reconfiguring...",
1262 projectorIsInTransition: true
1263 });
1264 }
1265 }
1266
1267 fetchProjectorState() {
1268 const self = this;
1269 // return;
1270 // self.props.abortAutoRefresh();
1271 let fetchUrl = window.config.APIUrl + "/projector/lumiverse/state";
1272
1273 let { xhr, promise } = this.api3.getRequest(fetchUrl, {}, fetchParams);
1274 if (self.refreshProjectorStateRequest)
1275 self.refreshProjectorStateRequest.abort();
1276
1277 self.refreshProjectorStateRequest = xhr;
1278
1279 promise
1280
1281 // fetch(fetchUrl,fetchParams)
1282 // .then((response) => {
1283 // return response.json();
1284 // })
1285
1286 .then(data => {
1287 console.log(
1288 "got data.projector.lumiverse",
1289 data,
1290 data.projector.lumiverse
1291 );
1292 self.setState({
1293 ...data.projector.lumiverse,
1294 userChosenSynchro: this.state.hasUserChangedSynchro ? this.initialSynchroState() : (data.projector.lumiverse
1295 ? data.projector.lumiverse.synchro
1296 : this.initialSynchroState())
1297 });
1298 self.processAjaxSuccess();
1299 })
1300 .catch(function(err) {
1301 self.processAjaxErrorWithoutLogout(err);
1302 // self.resetRefresh();
1303 });
1304 }
1305
1306 evaluateLumiverseState() {
1307 if (this.state.switchable == false) {
1308 // switchable == false
1309 // přepínač Projection je zašedlý, nedá se přepínat.
1310 // to stejné přepínač Network Playback Sync
1311 }
1312 }
1313 //*******************//
1314 ///projector controlls//
1315 //*******************//
1316
1317 isLastProjectorRequestDelayedEnough(){
1318 const now = Date.now();
1319 const last = this.state.lastProjectorRequestTime;
1320 console.log("rqd: ==== isLastProjectorRequestDelayedEnough === ",(now - last));
1321 return (now - last) > 5000;
1322 }
1323 isLastSceneRequestDelayedEnough(){
1324 const now = Date.now();
1325 const last = this.state.lastSceneRequestTime;
1326 console.log("rqd: ==== isLastSceneRequestDelayedEnough === ",(now - last));
1327 return (now - last) > 5000;
1328 }
1329
1330
1331 updateStorageData(data){
1332 // this.storageUpdateCounter = this.storageUpdateCounter+1;
1333 // console.log("updateStorageData",this.storageUpdateCounter);
1334 this.setState({projector: data.projector,storage: data.projector,unsyncedCount: data.sync.count_of_unsynced});
1335 }
1336
1337
1338
1339
1340
1341 fetchProjectorReleases_(){
1342 const self = this;
1343 setTimeout(function(){
1344 // const release = 'Pepa1';
1345 const data = {
1346 "projector":{
1347 "release":"RSM18B1",
1348 "releases":[
1349 {
1350 "name":"RSM18B2",
1351 "changelog":"- fixed bug in scheduling Lumiverse scenes",
1352 "latest":false,
1353 "major":!true
1354 },
1355 {
1356 "name":"RSM18B3",
1357 "changelog":"- fixed bug in networking",
1358 "latest":false,
1359 "major":false
1360 },
1361 {
1362 "name":"RSM18B4",
1363 "changelog":"- improved scanner\r\n- more reliable camera\r\n- fixed bug in network playback synchronization\r\n- fixed networking bug",
1364 "latest":false,
1365 "major":false
1366 },
1367 {
1368 "name":"RSM18B5",
1369 "changelog":"- improved scanner\r\n- fixed bug that projection was stopped in winter (problem has only T2, not T2S* or T1)\r\n- programmable playlist works in the network synchronize playback now",
1370 "latest":false,
1371 "major":false
1372 },
1373 {
1374 "name":"RSM18B6",
1375 "changelog":"- support of the NTP synchronization in the scheduler\r\n- support of disabling tasks per day in the scheduler\r\n- fixed bug that the Lumibox cannot show Wifi Networks\r\n",
1376 "latest":false,
1377 "major":false
1378 },
1379 {
1380 "name":"RSM18B7",
1381 "changelog":"- switching Lumiverse projects in scheduler tasks is more stable\r\n- fixed bug in the scheduler that a task shows \"now playing\" sometime when task doesn't play\r\n- T2 (not T2S(X) or T2SU model) could poorly counts number of lamp hours - bug is fixed",
1382 "latest":true,
1383 "major":false
1384 }
1385 ]
1386 }
1387};
1388 // console.log("setting relesae",data.projector.release);
1389 self.setState({releases: data.projector.releases,currentRelease:data.projector.release});
1390
1391 },500);
1392 }
1393
1394 fetchProjectorReleases(){
1395 const self = this;
1396 helpers.api('/projector/releases','',function(data){
1397 self.setState({releases: data.projector.releases,currentRelease:data.projector.release});
1398 });
1399 }
1400
1401 fetchProjectorInfo() {
1402 const self = this;
1403 // console.log("rqd: ==== fetchProjectorInfo ====");
1404
1405 if (self.state.projectorRequestPending) { //|| !self.isLastProjectorRequestDelayedEnough()
1406 // console.log("rqd: ==== fetchProjectorInfo - canceled, because last is still pending ====");
1407 this.setState({firstProjectorRequest:false});
1408 return;
1409 }
1410 if ((self.state.firstProjectorRequest)) {
1411 if (self.props.projectorData){
1412 self.setState({ projector: self.props.projectorData});
1413 self.fetchSources();
1414 }
1415 self.setState({firstProjectorRequest: false});
1416 return;
1417 }
1418
1419 let fetchUrl;
1420
1421 // if (this.projectorReqCount < 3){
1422
1423 fetchUrl = window.config.APIUrl + "/projector/default";
1424 // fetchUrl = "https://reqres.in/api/users?delay=12";
1425
1426 // }
1427 // else{
1428 // fetchUrl = "https://reqres.in/api/users?delay=12";
1429 // fetchUrl = "https://reqres.in/api/unknown/23?delay=12";
1430 // }
1431 // console.log("incremenenting projector req count",this.projectorReqCount);
1432 // this.projectorReqCount = this.projectorReqCount + 1;
1433
1434 // fetchUrl = 'http://httpstat.us/500';
1435
1436
1437 let { xhr, promise } = this.api2.getRequest(fetchUrl, {}, fetchParams);
1438
1439 if (self.refreshProjectorInfoRequest){
1440 self.refreshProjectorInfoRequest.abort();
1441 self.setState({projectorRequestPending:false});
1442 }
1443
1444 self.refreshProjectorInfoRequest = xhr;
1445
1446 self.setState({projectorRequestPending:true,lastProjectorRequestTime: Date.now()});
1447
1448 promise
1449 // .then((response) => {
1450 // self.processAjaxError(response);
1451 // return response.json();
1452 // })
1453 .then(data => {
1454 if (!self.refs.main) return;
1455 self.setState({ projector: data.projector,projectorRequestPending:false});
1456 self.setState({storage: data.projector});
1457
1458
1459
1460
1461 if (
1462 (data.projector && data.projector.online) ||
1463 window.projector_debug
1464 ) {
1465
1466 //pokud projektor neni online, zdorje me nezajimaji
1467 self.fetchSources();
1468 // if(self.state.projectorModalIsOpen){
1469 // self.fetchProjectorState();
1470 // }
1471 }
1472 self.processAjaxSuccess();
1473 })
1474 .catch(function(err) {
1475 if (!!self.refs.main){
1476 self.setState({projectorRequestPending:false});
1477 }
1478 self.processAjaxErrorWithoutLogout(err);
1479 });
1480 }
1481
1482 startUpload(formData) {
1483 window.fd = formData;
1484 // return;
1485 const self = this;
1486 const fetchUrl = window.config.APIUrl + "/scenes/edit";
1487 // console.log("starting upload");
1488
1489 let fetchObject = {
1490 method: "POST",
1491 body: formData
1492 };
1493
1494 fetch(fetchUrl, Object.assign({}, fetchObject, fetchParams))
1495 .then(response => {
1496 // self.fetchCurrentProgress();
1497 return response.json();
1498 })
1499 .then(data => {
1500 // if ((typeof(formData.get) == "function" && !!formData.get("file"))){
1501 // //upload jen posleme, nepotrebujeme result
1502 // console.log("UPLOAD: got progress and wont wait for response",data);
1503 // return;
1504 // }
1505
1506 if (data) {
1507 console.log("got upload data", data);
1508 // self.setStateByScenes(data.scenes);
1509 // }else{
1510 //self.fetchSceneInfo()
1511 this.setState({
1512 access: this.parseAccess(data),
1513 sceneName: data.name,
1514 public: this.parsePublic(data), //debug true
1515 publicScene: data.public_scene, //debug true
1516 publicRights: this.parsePublicRights(data),
1517 sceneSize: data.size || {},
1518 sceneId: data.id,
1519 thumbnail: data.thumbnail,
1520 // outlinesForever: data.borders_forever,
1521 webGL: data.use_webgl,
1522 // fitNewObjects: data.fit_new_objects,
1523 // objectTransparency: data.object_transparency,
1524 waitingForResponse: false
1525 });
1526 }
1527
1528 // const progress = data.progress;
1529 // console.log("got progress data",progress.status);
1530 })
1531 .catch(function(err) {
1532 console.log("error in thumbnail upload", err);
1533 // self.processAjaxError(err);
1534 });
1535 }
1536
1537 changeSceneSetting(type, newValue, e) {
1538 // const scene = this.activeScene();
1539 console.log("chagning scene settings", this.state.sceneDelayedStart);
1540 if (newValue == null) {
1541 newValue = e.target.value;
1542 }
1543
1544 const id = this.state.sceneId,
1545 self = this,
1546 fetchUrl =
1547 window.config.APIUrl +
1548 "/scenes/edit/" +
1549 id +
1550 "/?" +
1551 type +
1552 "=" +
1553 newValue;
1554
1555 // return console.log("changed scene type "+type,fetchUrl);
1556
1557 this.setWaitingForResponse();
1558 this.setState({loadingInSceneForm: true});
1559
1560
1561 fetch(fetchUrl, fetchParams)
1562 .then(response => {
1563 return response.json();
1564 })
1565 .then(data => {
1566 console.log("changed scene type " + type, newValue, {
1567 access: this.parseAccess(data),
1568 sceneName: data.name,
1569 public: this.parsePublic(data), //debug true
1570 publicRights: this.parsePublicRights(data),
1571 sceneDelayedStart: data.delayed,
1572 sceneOperatorHide: data.operator_hide,
1573 sceneSize: data.size || {},
1574 sceneId: data.id,
1575 // outlinesForever: data.borders_forever,
1576 webGL: data.use_webgl,
1577 fitNewObjects: data.fit_new_objects,
1578 objectTransparency: data.object_transparency,
1579 waitingForResponse: false
1580 });
1581 this.setState({loadingInSceneForm: false});
1582 if (data) {
1583 // self.setStateByScenes(data.scenes);
1584 // }else{
1585 //self.fetchSceneInfo()
1586 this.setState({
1587 access: this.parseAccess(data),
1588 sceneName: data.name,
1589 public: this.parsePublic(data), //debug true
1590 publicScene: data.public_scene, //debug true
1591 publicRights: this.parsePublicRights(data),
1592 sceneDelayedStart: data.delayed,
1593 sceneOperatorHide: data.operator_hide,
1594 sceneSize: data.size || {},
1595 sceneId: data.id,
1596 thumbnail: data.thumbnail,
1597 // outlinesForever: data.borders_forever,
1598 webGL: data.use_webgl,
1599 // fitNewObjects: data.fit_new_objects,
1600 // objectTransparency: data.object_transparency,
1601 waitingForResponse: false
1602 });
1603 }
1604 // self.props.closeModalAndRefresh();
1605 });
1606 }
1607
1608 isGroupMode() {
1609 return this.state.groupMaster;
1610 }
1611
1612 isOperatorMode() {
1613 // return true;
1614 return this.state.operator;
1615 }
1616
1617 getDelayInfo(data){
1618 return data.scene_delay_time;
1619 }
1620
1621 fetchSceneInfo() {
1622 console.log("call fetchSceneInfo");
1623 // return; //tmp
1624 if (this.state.refreshSceneInfoRequestPending) {
1625 console.log("ommitting scene request since one is already pending");
1626 if (this.props.offline){
1627 this.resetRefresh();
1628 }
1629 return;
1630 };
1631 const self = this,
1632 url = "/scene/",
1633 fetchUrl = window.config.APIUrl + url;
1634
1635 let { xhr, promise } = this.api4.getRequest(fetchUrl, {}, fetchParams);
1636 self.refreshSceneInfo2Request = xhr;
1637 self.setState({refreshSceneInfoRequestPending:true});
1638 // fetch(fetchUrl,fetchParams)
1639 promise
1640 // .then((response) => {
1641 // self.processAjaxError(response);
1642 // return response.json();
1643 // })
1644 //{"name":"trololo2","public_name":"huhuhux","devel":true,"size":{"width":"1200","height":"700","out":1},"borders_forever":false,"use_webgl":false}
1645 .then(data => {
1646 this.setState({
1647 lastSourcesTime: data.sources_updated_at,
1648 newSourcesNeeded: self.state.newSourcesNeeded || self.newSourcesNeeded(data.sources_updated_at),
1649 unsyncedCount: data.sync.count_of_unsynced,
1650 refreshSceneInfoRequestPending: false,
1651 groupMaster: data.group_master,
1652 operator: data.operator,
1653 lastSynchro: data.last_synchro,
1654 filters: data.filters,
1655 sceneDelayTime: this.getDelayInfo(data),
1656 access: this.parseAccess(data),
1657 sceneName: data.name,
1658 public: this.parsePublic(data), //debug true
1659 publicRights: this.parsePublicRights(data),
1660 sceneDelayedStart: data.delayed,
1661 sceneOperatorHide: data.operator_hide,
1662 publicScene: data.public_scene, //debug true
1663 sceneSize: data.size || {},
1664 sceneId: data.id,
1665 fitNewObjects: data.fit_new_objects,
1666 objectTransparency: data.object_transparency,
1667 thumbnail: data.thumbnail,
1668 corrections: data.corrections,
1669 // outlinesForever: data.borders_forever, //tohle endpoint nevraci
1670 webGL: data.webgl // je spravne ze je to jine nez ve zmenach - API se v tomhle lisi a z endpointu /
1671 });
1672
1673 this.props.setFeatures(data.features);
1674
1675 this.setControl(this.state.allAppSources,data);
1676
1677 this.checkPublicRights(
1678 this.parsePublic(data),
1679 this.parsePublicRights(data)
1680 ); //debug || true
1681 // console.log("fetched scene info","reseting refresh");
1682 self.applySceneRestriction(data);
1683 self.processAjaxSuccess();
1684 self.resetRefresh();
1685 })
1686 .catch(function(err) {
1687 // console.log("fuck ",err);
1688 self.setState({refreshSceneInfoRequestPending:false}); //pri chybe resetovat
1689 self.processAjaxErrorWithoutLogout(err);
1690 if (self.props.offline){
1691 self.resetRefresh();
1692 }
1693 });
1694 }
1695
1696 setResolution(size) {
1697 const self = this,
1698 url = "/resolution", //?width=1280&height=720&',
1699 fetchUrl = window.config.APIUrl + url;
1700
1701 let api = new FetchPlease("", {
1702 cors: window.config.APIUrl.indexOf(window.location.hostname) >= 0
1703 });
1704 console.log("sending request", size);
1705 let { xhr, promise } = api.getRequest(fetchUrl, size, fetchParams);
1706 promise
1707 .then(data => {
1708 this.setState({
1709 sceneSize: data.size || {}
1710 });
1711 self.processAjaxSuccess();
1712 })
1713 .catch(function(err) {
1714 self.processAjaxError(err);
1715 });
1716 }
1717 setAdvanced(delay) {
1718 const self = this,
1719 url = "/sceneDelayTime/"+(delay.delayTime), //?width=1280&height=720&',
1720 fetchUrl = window.config.APIUrl + url;
1721
1722 let api = new FetchPlease("", {
1723 cors: window.config.APIUrl.indexOf(window.location.hostname) >= 0
1724 });
1725 console.log("sending request", delay);
1726 let { xhr, promise } = api.getRequest(fetchUrl, {}, fetchParams);
1727 promise
1728 .then(data => {
1729 this.setState({
1730 sceneDelayTime: data.scene_delay_time || {}
1731 });
1732 self.processAjaxSuccess();
1733 })
1734 .catch(function(err) {
1735 self.processAjaxError(err);
1736 });
1737 }
1738
1739 newSourcesNeeded(sources_updated_at){
1740 // console.log("newSourcesNeeded",sources_updated_at);
1741 const now = Math.floor(new Date().getTime() / 1000);
1742 const lastSourcesTime = this.state.lastSourcesTime;
1743 // console.log("chcek,",sources_updated_at,lastSourcesTime,sources_updated_at - lastSourcesTime);
1744
1745 if (sources_updated_at > lastSourcesTime){ //!=
1746 console.log("NEW SOURCES NEEDED!",sources_updated_at,lastSourcesTime);
1747 return true;
1748 }else{
1749 console.log("NEW SOURCES NOT NEEDED!",sources_updated_at,lastSourcesTime);
1750 return false;
1751 }
1752 }
1753
1754 applySceneRestriction(data){
1755 console.log("applySceneRestriction",data);
1756 const self = this;
1757 self.setState({
1758 // access: self.parseAccess(data),
1759 // public: self.parsePublic(data), //debug true
1760 // publicRights: self.parsePublicRights(data),
1761 lastSourcesTime: data.sources_updated_at,
1762 newSourcesNeeded: !!self.state.newSourcesNeeded || self.newSourcesNeeded(data.sources_updated_at),
1763
1764
1765 access: this.parseAccess(data),
1766 sceneName: data.name,
1767 public: this.parsePublic(data), //debug true
1768 publicRights: this.parsePublicRights(data),
1769 sceneDelayedStart: data.delayed,
1770 sceneOperatorHide: data.operator_hide,
1771 publicScene: data.public_scene, //debug true
1772 sceneSize: data.size || {},
1773 sceneId: data.id,
1774 fitNewObjects: data.fit_new_objects,
1775 objectTransparency: data.object_transparency,
1776 thumbnail: data.thumbnail,
1777 // outlinesForever: data.borders_forever, //tohle endpoint nevraci
1778 webGL: data.webgl // je spravne ze je to jine nez ve zmenach - API se v tomhle lisi a z endpointu /
1779 });
1780 self.fetchProjectorInfo();
1781 self.checkPublicRights(
1782 self.parsePublic(data),
1783 self.parsePublicRights(data)
1784 );
1785 }
1786
1787 fetchSceneRestrictions(){
1788 this.fetchSceneInfo();
1789 return; //nove - vse se bere z infa
1790
1791 // const self = this,
1792 // url = "/scene/",
1793 // fetchUrl = window.config.APIUrl + url;
1794
1795 // // fetch(fetchUrl,fetchParams)
1796 // // .then((response) => {
1797 // // self.processAjaxError(response);
1798 // // return response.json();
1799 // // })
1800 // // .then((data) => {
1801 // if (self.refreshSceneInfoRequest) self.refreshSceneInfoRequest.abort();
1802
1803 // let { xhr, promise } = self.api.getRequest(fetchUrl, {}, fetchParams);
1804
1805 // self.refreshSceneInfoRequest = xhr;
1806
1807 // promise
1808 // .then(data => {
1809 // if (!self.refs.main) return;
1810 // self.applySceneRestriction(data)
1811 // //debug true
1812 // self.processAjaxSuccess();
1813 // self.resetRefresh();
1814 // })
1815 // .catch(function(err) {
1816 // self.resetRefresh();
1817 // self.processAjaxErrorWithoutLogout(err);
1818 // });
1819 }
1820
1821 parsePublic(data) {
1822 return window.public_debug ? true : data.public;
1823 }
1824
1825 parsePublicRights(data) {
1826 // return 1;
1827 return window.public_debug ? 2 : data.public_rights;
1828 }
1829
1830 parseAccess(data) {
1831 return window.public_debug ? "public_free" : data.access;
1832 }
1833
1834 fetchSources() {
1835 // fiksme udelat jako cancaleble promise xhr v abortable timeout
1836
1837 const self = this;
1838 let fetchUrl = window.config.APIUrl + "/sources";
1839 // fetch(fetchUrl,fetchParams)
1840 if (!this.state.newSourcesNeeded){
1841 console.log("skipping sources fetch");
1842 return;
1843 }
1844
1845 let { xhr, promise } = this.api3.getRequest(fetchUrl, {}, fetchParams);
1846 if (self.refreshSourcesStateRequest)
1847 self.refreshSourcesStateRequest.abort();
1848
1849 self.refreshSourcesStateRequest = xhr;
1850
1851 promise
1852
1853 // .then((response) => {
1854 // self.processAjaxError(response);
1855 // return response.json();
1856 // })
1857 .then(images => {
1858 // console.log("images.sources", images.sources);
1859 if (images && images.sources) {
1860 // self.setState({sources: images.sources});
1861 const allAppSources = images.sources.filter(img => img.type == "app");
1862 self.setState({sources: images.sources,allAppSources: allAppSources,newSourcesNeeded: false,lastSourcesTime: (Math.round(new Date().getTime() / 1000)) });
1863 // sources.filter((img) => (img.type == "app"));
1864 self.setControl(allAppSources);
1865 } else {
1866 self.unsetControl();
1867 }
1868 self.processAjaxSuccess();
1869 })
1870 .catch(function(err) {
1871 self.processAjaxErrorWithoutLogout(err);
1872 });
1873 }
1874
1875 isSettingsVisible() {
1876 if (this.isGroupMode() || this.isOperatorMode()) return false;
1877 return !this.publicModeOne() && !this.publicModeTwo();
1878 }
1879
1880 publicModeOne(
1881 ispublic = this.state.public,
1882 publicRights = this.state.publicRights
1883 ) {
1884 // return true;
1885 return ispublic && publicRights == 1;
1886 }
1887
1888 publicModeTwo(
1889 ispublic = this.state.public,
1890 publicRights = this.state.publicRights
1891 ) {
1892 // return true;
1893 return ispublic && (publicRights == 2 || publicRights == 3); //3 zatim stejna jako 2
1894 }
1895
1896 checkPublicRights(
1897 ispublic = this.state.public,
1898 publicRights = this.state.publicRights
1899 ) {
1900 // console.log("intro: checkPublicRights",ispublic,publicRights); //debug || true
1901 const isPublicMode = this.publicModeOne(ispublic, publicRights);
1902 if (isPublicMode) {
1903 //debug || true
1904 // auto otevreni controll okna?
1905 this.setState({ modalIsOpen: true });
1906 // this.props.toggleIntro();
1907 } else {
1908 }
1909 this.loadingFinished(isPublicMode);
1910 }
1911
1912 isEditorHidden() {
1913 if (this.isGroupMode()) {
1914 return true;
1915 }
1916 if (this.isOperatorMode()) {
1917 //editor se bude řídit public_rights právy stejně jako public mode.
1918 //První nutná podmínka, aby se zobrazil je to, že v /scene či /scene/info bude flag public_scene: true (nikoliv public, ale public_scene (warning) , public flag zde nic neovlivňuje, ten se týká výhradně public modu), pokud bude false, tak se nezobrazí.
1919 if (this.state.publicScene == true) {
1920 // První nutná podmínka, aby se zobrazil je to, že v /scene či /scene/info bude flag public_scene: true
1921 // (nikoliv public, ale public_scene (warning) , public flag zde nic neovlivňuje, ten se týká
1922 // výhradně public modu), pokud bude false, tak se nezobrazí.
1923 if (this.state.publicRights == 1){
1924 //A teď, pokud jsou public rights app (1), nezobrazí se v menu.
1925 return true;
1926 }
1927
1928 if (this.state.publicRights >= 2){
1929 //Pokud budou editor (2), zobrazí se v menu, ale bez uploadu,
1930 //pokud budou editor_upload (3), zobrazí se v menu a s uploadem pouze obrázku.
1931 //Pozor, public_rights i public_scene se mění po přepnutí scény a podle toho se musí zobrazovat/schovávat i editor.
1932 return false;
1933 }
1934
1935 } else {
1936 return true;
1937 }
1938 }
1939 return false;
1940 }
1941 isEditorActive() {
1942 // console.log(ispublic,publicRights);
1943
1944 if (this.isEditorHidden()){
1945 return false;
1946 }
1947
1948 if (this.publicModeOne()) {
1949 // console.log("returning false");
1950 return false;
1951 }
1952 return true;
1953 }
1954
1955 isScenePickerHidden() {
1956 return (
1957 !this.isScenePickerActive() &&
1958 (this.publicModeOne() || this.publicModeTwo())
1959 );
1960 }
1961
1962 isScenePickerActive() {
1963 if (this.publicModeOne() || this.publicModeTwo()) {
1964 return false;
1965 }
1966 return true;
1967 }
1968
1969 editorVisible() {
1970 // console.log(ispublic,publicRights);
1971
1972 if (this.publicModeOne()) {
1973 // console.log("returning false");
1974 return false;
1975 }
1976
1977 if (1) {
1978 }
1979 // console.log("returning true");
1980
1981 return true;
1982 }
1983 processAjaxErrorWithoutLogout(err, fn = "") {
1984 this.processLogin(err, true, false);
1985 if (window.debug) {
1986 // console.log('ajax error:',
1987 // "status: "+err.status,
1988 // "fn.status: " + fn.status,
1989 // "err.statusCode: " + err.statusCode,
1990 // "fn.statusCode: " + fn.statusCode,
1991 // "err.toString(): " + err.toString(),
1992 // "fn.toString(): " + fn.toString(),
1993 // "err:",err);
1994
1995 console.log("ajaxErr", err);
1996 }
1997 // window.lastAjaxError = err;
1998 if (err.toString() == "Error: Resource failed to load") {
1999 // this.setState({offline: true});
2000 this.props.setOffline();
2001 this.resetRefresh();
2002 }
2003 }
2004
2005 processAjaxError(err, fn = "") {
2006 this.processLogin(err, true, true);
2007 if (window.debug) {
2008 // console.log('ajax error:',
2009 // "status: "+err.status,
2010 // "fn.status: " + fn.status,
2011 // "err.statusCode: " + err.statusCode,
2012 // "fn.statusCode: " + fn.statusCode,
2013 // "err.toString(): " + err.toString(),
2014 // "fn.toString(): " + fn.toString(),
2015 // "err:",err);
2016
2017 console.log("ajaxErr", err);
2018 }
2019 // window.lastAjaxError = err;
2020 if (err.toString() == "Error: Resource failed to load") {
2021 this.props.setOffline();
2022 this.resetRefresh();
2023 }
2024 }
2025
2026 processAjaxSuccess() {
2027 this.props.setOnline();
2028 }
2029
2030 processLogin(response, processResponseBody = true, andLogout = true) {
2031 // return;
2032 // return;
2033 // window.r = window.r || [];
2034 // console.log('processLogin',processResponseBody,response);
2035 // let newStatus = {};
2036 const self = this;
2037 let code = "";
2038
2039 if (response) {
2040 code = response.error
2041 ? response.error.code
2042 : response.status || response.statusCode || response;
2043 }
2044
2045 if (response) {
2046 console.log("got response data", code);
2047 window.last_error = response;
2048 switch (code) {
2049 case 200:
2050 break;
2051 case 401:
2052 // newStatus = {logged}
2053 console.log("Sign in, please!", code);
2054 window.location = window.config.APIUrl + "/sign";
2055 break;
2056 case 403:
2057 console.log("Shouldnt be here, back off!", code);
2058 window.location = window.config.APILogoutUrl;
2059 break;
2060 default:
2061 //500 a jine nespecifikovane kody
2062 if (
2063 response.message &&
2064 response.message == "Resource has been aborted"
2065 ) {
2066 console.log("just aborted request, no big deal");
2067 break;
2068 }
2069 console.log("sth went terribly wrong, status:", code);
2070
2071 if (processResponseBody) {
2072 window.rr = response;
2073 console.log("response in 500", response);
2074 try {
2075 if (response && response.json) {
2076 response.json().then(function(data) {
2077 window.dd = data;
2078 // console.log("we have json response",data);
2079 self.processLogin(data, false, andLogout);
2080 });
2081 } else {
2082 this.props.setOffline();
2083 }
2084 } catch (e) {
2085 console.log(
2086 "err on code " + code + ": response could not be double parsed",
2087 e
2088 );
2089 }
2090 } else {
2091 console.log("err 500, with no responseBody");
2092 if (andLogout) window.location = window.config.APILogoutUrl;
2093 }
2094 break;
2095 // this.processAjaxSuccess();
2096 }
2097 } else {
2098 console.log("no response?");
2099 // this.setState({offline: true});
2100 }
2101 }
2102
2103 setControl(allApps, data = false) {
2104 console.log("set controll call",allApps,data);
2105 // return; //tmp
2106 if (!allApps.length) {
2107 this.setState({ sourcesInScene: [] });
2108 // return;
2109 }
2110 const self = this;
2111
2112 const newSourcesString = allApps.map(function(el){return el.id}).join("-");
2113
2114
2115 if (data){
2116 if (!self.refs.main) return;
2117 self.setState({
2118 refreshSceneInfoRequestPending:false,
2119 sceneName: data.scene_name,
2120 sceneHash: data.scene_hash,
2121 appApiUrl: data.app_api_url,
2122 appWsUrl: data.app_ws_url
2123 });
2124 self.checkCalibrationLock(data);
2125 self.setControllableApps(data.objects, allApps);
2126 }
2127 else{
2128 return;
2129
2130 // if (this.state.lastSourcesString == newSourcesString){
2131 // return;
2132 // }
2133
2134 this.setState({lastSourcesString: newSourcesString});
2135
2136
2137
2138
2139 let fetchUrl = window.config.APIUrl + "/scene/";
2140 this.setState({refreshSceneInfoRequestPending:true});
2141 fetch(fetchUrl, fetchParams)
2142 .then(response => {
2143 self.processAjaxErrorWithoutLogout(response.status);
2144 return response.json();
2145 })
2146 .then(data => {
2147 if (!self.refs.main) return;
2148 self.setState({
2149 refreshSceneInfoRequestPending:false,
2150 sceneName: data.scene_name,
2151 sceneHash: data.scene_hash,
2152 appApiUrl: data.app_api_url,
2153 appWsUrl: data.app_ws_url
2154 });
2155 self.props.setFeatures(data.features);
2156 self.checkCalibrationLock(data);
2157 self.setControllableApps(data.objects, allApps);
2158 self.processAjaxSuccess();
2159 })
2160 .catch(function(err) {
2161 // self.processAjaxError(err);
2162 })
2163 .catch(function(err) {
2164 self.processAjaxErrorWithoutLogout(err);
2165 });
2166 }
2167 }
2168
2169 checkCalibrationLock(data) {
2170 // if (this.props.isCalibrationOwner && data.mode == null){
2171 // this.setState({
2172 // settingsModalIsOpen: false,
2173 // });
2174
2175 // this.props.changeConfirm({
2176 // type: "dialog",
2177 // isOpen: true,
2178 // okText: 'Ok',
2179 // title: "Timeout",
2180 // text: "Timeout. Calibration ended.",
2181 // hideCancel: true,
2182 // cancel: this.stopCalibration.bind(this,true),
2183 // callback: this.stopCalibration.bind(this,true)
2184 // });
2185 // this.props.unsetCalibrationOwner();
2186 // }
2187
2188 this.props.checkCalibrationLock(data, this.stopCalibration.bind(this));
2189 }
2190
2191 stopCalibration() {
2192 this.setState({ settingsModalIsOpen: false });
2193 }
2194
2195 fetchSceneName() {
2196 // return; //tmp
2197 // nepouziva se (po zmene api)
2198 const self = this;
2199
2200 let fetchUrl = window.config.APIUrl + "/scene/";
2201 fetch(fetchUrl, fetchParams)
2202 .then(response => {
2203 self.processAjaxErrorWithoutLogout(response);
2204 return response.json();
2205 })
2206 .then(data => {
2207 if (!self.refs.main) return;
2208 self.setState({
2209 sceneName: data.scene_name,
2210 sceneHash: data.scene_hash,
2211 appApiUrl: data.app_api_url,
2212 appWsUrl: data.app_ws_url
2213 });
2214 self.processAjaxSuccess();
2215 })
2216 .catch(function(err) {
2217 // self.processAjaxError(err);
2218 })
2219 .catch(function(err) {
2220 self.processAjaxErrorWithoutLogout(err);
2221 });
2222 }
2223
2224 updateSceneName(newSceneName) {
2225 if (newSceneName) this.setState({ sceneName: newSceneName });
2226 }
2227
2228 setControllableApps(objects, allApps) {
2229 const sourcesInSceneWithIds = objects.map(img => ({
2230 sourceId: img.sourceId,
2231 id: img.id
2232 }));
2233 const sourcesInScene = objects.map(img => img.sourceId);
2234 // console.log("inSceneIds",sourcesInScene);
2235 // console.log("allApps",allApps.map((src)=>(Object.assign({},src,{folder: null}))));
2236
2237 //stare - nove se to bere primo z images -
2238 // let controllableAppsInScene = allApps.map((src)=>(Object.assign({},src,{folder: null}))).filter((src) => (src.type == "app" && src.control == true && sourcesInScene.indexOf(src.id) >= 0));
2239
2240 let controllableAppsInScene = objects.filter(app => app.control);
2241
2242 // controllableAppsInScene = controllableAppsInScene.map((app)=>{
2243 // // const id = sourcesInSceneWithIds.find((src)=>(src.sourceId == app.id)).id;
2244 // // return {...app,inSceneId: id}
2245 // return app;
2246 // });
2247
2248 // console.log("controllableApps",controllableApps);
2249
2250 this.setState({
2251 sourcesInScene: sourcesInScene,
2252 controllableAppsInScene: controllableAppsInScene,
2253 loaded: true
2254 });
2255 this.props.unsetFirstLoad();
2256 }
2257
2258 unsetControl() {
2259 this.setState({
2260 allAppSources: [],
2261 sourcesInScene: [],
2262 controllableAppsInScene: []
2263 });
2264 }
2265
2266 // ****** State alterning functions (like reducers) ****** //
2267
2268 closeModal(evt, appProps) {
2269 // console.log("close modal intro called");
2270 // console.log("evt",evt);
2271 // console.log("appProps",appProps);
2272
2273 this.setState({ modalIsOpen: false });
2274 }
2275
2276 isControlActive() {
2277 //pokud je public mode je aktivni i kdyz nejsou splneny ostatni podminky
2278 //protoze je to jedina viditelna ikona
2279
2280 if (this.publicModeOne()) return true;
2281
2282 //return this.state.controllableAppsInScene.length > 0;
2283 return (this.state.controllableAppsInScene.length + this.allFiltersWithSources().length) > 0;
2284 }
2285
2286 isProjectorHidden() {
2287 //{"projector":{"sync_blocked":false,"sync_big":false,"sync_checker":null,"division":"lumitrix","name":"ktkpc","ip":"172.16.0.32","release":"","online":false}}
2288
2289 // console.log("is proj hidden",!this.isProjectorActive() && (this.publicModeOne() || this.publicModeTwo()));
2290 return (
2291 !this.isProjectorActive() &&
2292 (this.publicModeOne() || this.publicModeTwo())
2293 );
2294 }
2295
2296 isProjectorActive() {
2297 // console.log("isProjectorActive");
2298 if (this.publicModeOne() || this.publicModeTwo()) {
2299 // console.log("projector not active, because public mode one or two");
2300 return false;
2301 }
2302
2303 const result =
2304 !!this.state.projector &&
2305 this.state.projector.online &&
2306 !this.state.projectorIsInTransition;
2307 // console.log("projector active check", result,!!this.state.projector,this.state.projector.online);
2308 // console.log("returning ",result);
2309 return result;
2310 }
2311
2312 toggleProjectorModal(e) {
2313 if (this.isProjectorActive()) {
2314 //projector condition
2315 this.setState({ projectorModalIsOpen: true });
2316 } else {
2317 e.preventDefault();
2318 return false;
2319 }
2320 }
2321
2322 toggleControl(e) {
2323 // Aplikace by měly vypadat stejně jako v galerii, takže reprezentované náhledy. Když na apku kliknu, zobrazí se edit stránka stejně jako v editoru, akorát to nebude edit.html, ale control.html. Pokud žádná spuštěná aplikace nebude, tlačítko bude zašedlé. Spuštěné aplikace detekujete tak, že si projedete /scene a zjistíte, kolik aplikací se nachází ve scéně a zároveň má flag control. Navíc pro funkčnost tohoto tlačítka musí být projektor online .
2324 if (this.isControlActive()) {
2325 this.setState({ modalIsOpen: true });
2326 } else {
2327 e.preventDefault();
2328 return false;
2329 }
2330 }
2331
2332 confirmHide() {
2333 this.props.changeConfirm({ isOpen: false });
2334 }
2335
2336 confirmLogout() {
2337 // window.location.href = config.APILogoutUrl;
2338 // return;
2339 this.props.changeConfirm({
2340 type: "confirm",
2341 isOpen: true,
2342 title: "Logout",
2343 text: "Logout from Lumiverse?",
2344 cancel: this.confirmHide.bind(this),
2345 callback: function() {
2346 window.location.href = config.APILogoutUrl;
2347 }
2348 });
2349 }
2350}
2351
2352// module.exports = Radium(Intro);
2353module.exports = Intro;
2354