source: js/human_3d_alignment/src/index.jsx @ 918

Last change on this file since 918 was 918, checked in by Maciej Komosinski, 4 years ago

Created global LoggerToStdout? object so that all messages emitted by SDK loggers will be printf()'ed and consequently will appear in the JS console

File size: 26.1 KB
Line 
1/*global Module*/
2"use strict";
3import http from 'http';
4import React from 'react';
5import Genotypes from './utils/genotypes';
6import TitlePanel from './viewskeleton/titlepanel';
7import WidgetsContainer from './viewskeleton/widgetscontainer';
8import TextViewer from './widgets/textviewer';
9import ParmViewer from './widgets/parmviewer';
10import SimilViewer from './widgets/similviewer';
11import FitViewer from './widgets/fitviewer';
12import SliderViewer from './widgets/sliderviewer';
13import EndViewer from './widgets/endviewer';
14
15const ROUNDS = 15;
16
17const styles = {
18    contentHeaderMenuLink: {
19        textDecoration: 'none',
20        color: 'white',
21        padding: 8,
22    },
23    content: {
24        padding: '16px',
25    },
26    sidebarLink: {
27        display: 'block',
28        padding: '16px 0px',
29        color: 'gray',
30        textDecoration: 'none',
31    },
32    divider: {
33        margin: '8px 0',
34        height: 1,
35        backgroundColor: 'gray',
36    },
37};
38
39
40/**
41 * Main class running Framsticks.JS page.
42 */
43class MainView extends React.Component {
44    /**
45     * Basic constructor holding informations about sidebar states
46     * @param {any} props component properties
47     */
48    constructor(props) {
49        super(props);
50        this.onLayoutChange = this.onLayoutChange.bind(this);
51
52        window.genetics = new Module.PreconfiguredGenetics();
53        window.logger = new Module.LoggerToStdout(Module.LoggerBase.Enable); // While this object exists, all messages emitted by SDK loggers will be printf()'ed and consequently will appear in the JS console.
54        this.layout = [
55            {name:'0,textviewer', x: 0, y: 0, w: 9, h: 1},
56            {name:'2,similviewer', x: 0, y: 1, w: 6, h: 4},
57            {name:'3,fitviewer', x: 6, y: 1, w: 6, h: 2},
58            {name:'4,sliderviewer', x: 6, y: 3, w: 6, h: 2},
59            {name:'1,parmviewer', x: 9, y: 0, w: 3, h: 1}
60        ];
61
62        this.container = <WidgetsContainer onRef={ref => (this.widgetscontainer = ref)} onLayoutChange={this.onLayoutChange} />;
63
64        this.state = {
65            genotypes: 0,
66            round: 0,
67            genotype1: '',
68            genotype2: '',
69            pairs: [],
70            id1: 0,
71            id2: 0,
72            parts1: 0,
73            parts2: 0,
74            selected1: [],
75            selected2: [],
76            position1: [0, 0, 0],
77            position2: [0, 0, 0],
78            rotation1: [0, 0, 0],
79            rotation2: [0, 0, 0],
80            userId: 0,
81            userIp: 'localhost',
82            timeStart: 0,
83            selectedGender: {value: "empty", label: " "},
84            selectedYear: {value: "empty", label: " "},
85            percent: 0,
86            sliderUpdated: true,
87            isDisable: true,
88            isFinished: false,
89            fitHeight: 2,
90            fitWidth: 6,
91            controlMode: 'translate',
92            blockView: true,
93            result: ''
94        };
95
96        this.start = this.start.bind(this);
97        this.getIp = this.getIp.bind(this);
98        this.nextRound = this.nextRound.bind(this);
99        this.saveRound = this.saveRound.bind(this);
100        this.saveFit = this.saveFit.bind(this);
101        this.refresh = this.refresh.bind(this);
102        this.sendToServer = this.sendToServer.bind(this);
103        this.finishApp = this.finishApp.bind(this);
104        this.isReady = this.isReady.bind(this);
105        this.isFitted = this.isFitted.bind(this);
106        this.browserData = this.browserData.bind(this);
107        this.loadNewGenotypes = this.loadNewGenotypes.bind(this);
108        this.handleChangeStartTime = this.handleChangeStartTime.bind(this);
109        this.handleChangeId = this.handleChangeId.bind(this);
110        this.handleChangeIp = this.handleChangeIp.bind(this);
111        this.handleChangeGender =  this.handleChangeGender.bind(this);
112        this.handleChangeYear = this.handleChangeYear.bind(this);
113        this.handleChangePercent = this.handleChangePercent.bind(this);
114        this.handleChangeStartTime = this.handleChangeStartTime.bind(this);
115        this.handleChangeFitHeight = this.handleChangeFitHeight.bind(this);
116        this.handleChangeFitWidth = this.handleChangeFitWidth.bind(this);
117        this.handleChangeControlMode = this.handleChangeControlMode.bind(this);
118        this.handleChangePosition1 = this.handleChangePosition1.bind(this);
119        this.handleChangePosition2 = this.handleChangePosition2.bind(this);
120        this.handleChangeRotation1 = this.handleChangeRotation1.bind(this);
121        this.handleChangeRotation2 = this.handleChangeRotation2.bind(this);
122        this.handleChangeBlockView = this.handleChangeBlockView.bind(this);
123        this.onClickNext = this.onClickNext.bind(this);
124        this.onClickFinish = this.onClickFinish.bind(this);
125    }
126
127    /**
128     * Uses default layout.
129    */
130    componentDidMount() {
131        window.addEventListener( 'keydown', ( event ) => {
132            switch ( event.keyCode ) {
133                case 84: // T
134                    this.handleChangeControlMode( "translate" );
135                    break;
136                case 82: // R
137                    this.handleChangeControlMode( "rotate" );
138                    break;
139            }
140        } );
141        let timeStart = new Date();
142        this.handleChangeStartTime(timeStart); //set time start
143        this.handleChangeId(  Math.round(timeStart.getTime() / 1000).toString() +  (Math.floor(Math.random() * (9999999 - 1000000 + 1) ) + 1000000).toString() + this.browserData().toString() ); //set user id = time + random + browserData_hash
144        this.getIp();   //set user ip
145        this.genotypes = new Genotypes(this, "https://raw.githubusercontent.com/arturolejnik95/human_3d_alignment/master/walking.gen");   //load text from file to this.genotypes
146        let head = "'User ID'|'User IP'|'Gender'|'Year of born'|'Start time'|'Stop time'|'Position of 1st'|'Position of 2nd'|'Rotation of 1st'|'Rotation of 2nd'|'ID 1st'|'ID 2nd'|'Fit'|'Result'\n"
147        this.handleChangeResult(head);
148    }
149
150    /**
151     * Calls resize event in order to properly set layout
152    */
153    componentDidUpdate() {
154        //window.dispatchEvent(new Event('resize'));
155        if (this.state.genotype1 != '' && this.state.genotype2 != '') {
156            this.useLayout(this.layout);
157        }
158    }
159
160
161    /**
162     * Start questionnaire if genotypes are loaded
163     */
164    start() {
165        this.setState({ genotypes: this.genotypes.id.length }, function() {
166            console.log(`Genotypes: `, this.state.genotypes);
167        });
168
169        this.loadNewGenotypes();
170        this.handleChangeBlockView(false);
171        this.useLayout(this.layout);
172    }
173
174    getIp() {
175        http.get({'host': 'api.ipify.org', 'port': 80, 'path': '/'}, (resp) => {
176            resp.on('data', ip => {
177                this.handleChangeIp(ip)
178            });
179        });
180    }
181
182    /**
183     * Save data about this round
184     */
185    saveRound() {
186        this.setState({ sliderUpdated: false }, function() {
187            console.log('Slider Updated: ' + this.state.sliderUpdated);
188        });
189        this.isReady();
190    }
191
192    /**
193     * Preset result as:
194     * user ID - IP - gender - year of born - start : end - position of 1. : position of 2.
195     * - rotation of 1. : rotation of 2. - id of 1. : id of second - pairs (1. mesh : 2. mesh) - fit result (0 - 100) ;
196     */
197    saveFit() {
198        let min = Math.min(this.state.parts1, this.state.parts2);
199        let timeStop = new Date();
200        let start = this.state.timeStart;
201        let stop = timeStop;
202        start = ("0" + start.getDate()).slice(-2) + '.' + ("0" + (start.getMonth() + 1)).slice(-2) + '.' + start.getFullYear() + ' ' + String(start.getHours()).padStart(2, '0') + ':' + String(start.getMinutes()).padStart(2, '0') + ':' + String(start.getSeconds()).padStart(2, '0');
203        stop = ("0" + stop.getDate()).slice(-2) + '.' + ("0" + (stop.getMonth() + 1)).slice(-2) + '.' + stop.getFullYear() + ' ' + String(stop.getHours()).padStart(2, '0') + ':' + String(stop.getMinutes()).padStart(2, '0') + ':' + String(stop.getSeconds()).padStart(2, '0');
204
205        let fit =   this.state.userId + '|' +
206                    this.state.userIp + '|' +
207                    this.state.selectedGender.value + '|' +
208                    this.state.selectedYear.value + '|' +
209                    start + '|' +
210                    stop + '|' +
211                    '(' + this.state.position1[0] + ',' + this.state.position1[1] + ',' + this.state.position1[2] + ')|' + 
212                    '(' + this.state.position2[0] + ',' + this.state.position2[1] + ',' + this.state.position2[2] + ')|' + 
213                    '(' + this.state.rotation1[0] + ',' + this.state.rotation1[1] + ',' + this.state.rotation1[2] + ')|' + 
214                    '(' + this.state.rotation2[0] + ',' + this.state.rotation2[1] + ',' + this.state.rotation2[2] + ')|'; 
215                   
216       
217        let pair = this.state.pairs[this.state.pairs.length - 1];
218        fit = fit + this.genotypes.id[pair[0]] + '|' + this.genotypes.id[pair[1]] + '|';
219
220        for (let i = 0; i < min; i++) {
221            fit = fit + this.state.selected1[i] + ':' + (this.state.selected2[i].charCodeAt(0) - 65 + 1);
222            if (i < min - 1) {
223                fit = fit + ';';
224            }
225        }
226        fit = fit + '|' + this.state.percent + '\n';
227
228        this.sendToServer(fit);
229
230        this.handleChangeResult(this.state.result + fit);
231        this.handleChangeStartTime(timeStop);
232    }
233
234
235
236    sendToServer(fit) {
237        let rawFile = new XMLHttpRequest();
238        rawFile.addEventListener('load', () => {
239            console.log(rawFile.responseText);
240        });
241        rawFile.addEventListener('error', () => {
242            console.log('Błąd wysyłania na serwer');
243        });
244       
245        rawFile.open("POST", 'https://ptsv2.com/t/b7nhq-1578108725/post');
246        rawFile.setRequestHeader("Content-type", 'text/plain');
247        rawFile.send(fit);
248    }
249
250    /**
251     * Load next pair of genotypes
252     */
253    nextRound() {
254        this.loadNewGenotypes();
255        this.handleChangeBlockView(false);
256    }
257
258    /**
259     * Refresh used default layout
260     */
261    refresh() {
262        this.useLayout(this.layout);
263    }
264
265    /**
266     * Load new genotypes to simulator viewer
267     */
268    loadNewGenotypes() {
269        //Firstly it chooses pair of genotypes that user doesnt used before
270        let rand1, rand2, amount1, amount2, gen1, gen2;
271
272        do {
273            rand1 = 0, rand2 = 0;
274            do  {
275                while (rand1 == rand2) {
276                    rand1 = Math.floor(Math.random() * this.state.genotypes);
277                    rand2 = Math.floor(Math.random() * this.state.genotypes);
278                }
279            } while (this.state.pairs.includes([rand1, rand2]) || this.state.pairs.includes([rand2, rand1]));
280
281            //This part load genotypes to the state
282            gen1 = this.genotypes.genotype[rand1];
283            gen2 = this.genotypes.genotype[rand2];
284            amount1 = gen1.split('').filter(function(sign){return sign === 'X'}).length;
285            amount2 = gen2.split('').filter(function(sign){return sign === 'X'}).length;
286            if (amount1 > 0) {
287                amount1++;
288            }
289            if (amount2 > 0) {
290                amount2++
291            }
292        } while (amount1 > 52 || amount2 > 52);
293
294        let newpairs = this.state.pairs;
295        if (amount1 <= amount2) {
296            newpairs.push([rand1, rand2]);
297            this.setState({ genotype1: gen1, genotype2: gen2 }, function() {
298                console.log(`Genotypes: `, this.state.genotype1, this.state.genotype2);
299            });
300            this.setState({parts1: amount1, parts2: amount2}, function() {
301                console.log(this.state.parts1 + ' ' + this.state.parts2);
302            });
303        } else {
304            newpairs.push([rand2, rand1]);
305            this.setState({ genotype1: gen2, genotype2: gen1 }, function() {
306                console.log(`Genotypes: `, this.state.genotype1, this.state.genotype2);
307            });
308            this.setState({parts1: amount2, parts2: amount1}, function() {
309                console.log(this.state.parts1 + ' ' + this.state.parts2);
310            });
311        }
312        this.setState({ pairs: newpairs }, function() {
313            console.log(`Pairs: `, this.state.pairs);
314        });
315
316        //Load tables of selected parts in fitviewer
317        let min = Math.min(amount1, amount2);
318        let s1 = [];
319        let s2 = [];
320        for (let i = 0; i < min; i++) {
321            s1.push((i+1).toString());
322            s2.push(' ');
323        }
324
325        //Start new round and load to state tables of selected and round
326        let r = this.state.round + 1;
327        this.setState({ round: r, selected1: s1, selected2: s2}, function() {
328            console.log(`Round and state `, this.state.round + '. ' + this.state.selected1 + ' ' + this.state.selected2);
329        });
330    }
331
332    /**
333     * Check is user ready to go to the next question by checking choosed gender, birth year and percent of similarity
334     */
335    isReady() {
336        if (this.state.selectedGender.value != 'empty' && this.state.selectedYear.value != 'empty' && this.state.sliderUpdated) {
337            this.setState({isDisable: false}, function() {
338                console.log(this.state.isDisable);
339            });
340        } else {
341            if (!this.state.isDisable) {
342                this.setState({isDisable: true}, function() {
343                    console.log(this.state.isDisable);
344                });
345            }
346        }
347    }
348
349    /**
350     * Check is user matched all needed sticks
351     */
352    isFitted() {
353        let index1 = this.state.selected1.indexOf(' ');
354        let index2 = this.state.selected2.indexOf(' ');
355
356        if (index1 < 0 && index2 < 0 && this.state.sliderUpdated) {
357            this.setState({sliderUpdated: false}, function() {
358                console.log(this.state.sliderUpdated);
359                this.isReady();
360            });
361        }
362    }
363
364    /**
365     * Return hash data of browser
366     */
367    browserData() {
368        let data = navigator.userAgent;
369        let hash = 0;
370        for (let i = 0; i < data.length; i++) {
371            let character = data.charCodeAt(i);
372            hash = ((hash<<5)-hash)+character;
373            hash = hash & hash; // Convert to 32bit integer
374        }
375        return hash;
376    }
377
378    /**
379     * Performed at the end of the survey
380     */
381    finishApp() {
382        this.layout = [
383            {name:'5,endviewer', x: 0, y: 0, w: 12, h: 4}
384        ];
385        this.useLayout(this.layout);
386    }
387
388    /**
389     * Allow to change gender in state
390     * @param {string} gen choosed gender by user in listbox
391     */
392    handleChangeGender(gen) {
393        this.setState({ selectedGender: gen }, function() {
394            console.log(`Gender selected:`, this.state.selectedGender);
395            console.log(this.genotypes.id.length)
396            this.isReady();
397        });
398    };
399   
400    /**
401     * Allow to change IP
402     * @param {number} ip user IP
403     */
404    handleChangeIp(ip) {
405        this.setState({ userIp: ip }, function() {
406            console.log(`IP:`, this.state.userIp);
407        });
408    }
409   
410    /**
411     * Allow to change user ID
412     * @param {number} id user ID
413     */
414    handleChangeId(id) {
415        this.setState({ userId: id }, function() {
416            console.log(`ID:`, this.state.userId);
417        });
418    }
419   
420    /**
421     * Allow to change start time
422     * @param {number} time time of begging fitting framsticks
423     */
424    handleChangeStartTime(time) {
425        this.setState({ timeStart: time }, function() {
426            console.log(`Start time:`, this.state.timeStart);
427        });
428    }
429
430    /**
431     * Allow to change birth year in state
432     * @param {number} year choosed birth year by user in listbox
433     */
434    handleChangeYear(year) {
435        this.setState({ selectedYear: year }, function() {
436            console.log(`Birth year selected:`, this.state.selectedYear);
437            this.isReady();
438        });
439    }
440
441    /**
442     * Allow to change percent in state and mark this in state.sliderUpdated
443     * @param {Integer} per choosed similarity of framsticks by user in percentage
444     */
445    handleChangePercent(per) {
446        this.setState({ percent: per, sliderUpdated: true }, function() {
447            console.log('Percent selected: ' + this.state.percent + ' ' + this.state.sliderUpdated);
448            this.isReady();
449        });
450    }
451
452    /**
453     *
454     * @param {number} nr framstick id
455     * @param {number} pos position on the match map
456     * @param {*} val id of choosed stick
457     */
458    handleChangeSelected(nr, pos, val) {
459        if (nr == 1) {
460            this.setState(state => {
461                const selected1 = state.selected1.map((item, i) => {
462                    if (pos === i) {
463                        return val;
464                    } else {
465                        return item;
466                    }
467                });
468
469                return {
470                    selected1,
471                };
472            },  function() {
473                console.log(this.state.selected1);
474                this.isFitted();
475            });
476        } else {
477            this.setState(state => {
478                const selected2 = state.selected2.map((item, i) => {
479                    if (pos === i) {
480                        let v = val.charCodeAt(0);
481                        if (v > 90) {
482                            v = v - 6;
483                        }
484                        let res = String.fromCharCode(v);
485                        return res;
486                    } else {
487                        return item;
488                    }
489                });
490
491                return {
492                    selected2,
493                };
494            }, function() {
495                console.log(this.state.selected2);
496                this.isFitted();
497            });
498        }
499    }
500   
501    /**
502     * Function to inform fitviewer about change of height to update scrollbar (for firefox)
503     * @param {number} h height
504     */
505    handleChangeFitHeight(h) {
506        this.setState({ fitHeight: h }, function() {
507            console.log(`Fit Height:`, this.state.fitHeight);
508        });
509    }
510   
511    /**
512     * Function to inform fitviewer about change of width to update scrollbar (for firefox)
513     * @param {number} w width
514     */
515    handleChangeFitWidth(w) {
516        this.setState({ fitWidth: w }, function() {
517            console.log(`Fit Width:`, this.state.fitWidth);
518        });
519    }
520
521    /**
522     * Allow to change transform controler mode
523     * @param {number} mode translate or rotation
524     */
525    handleChangeControlMode(mode) {
526        this.setState({ controlMode: mode }, function() {
527            console.log(`Control mode:`, this.state.controlMode);
528        });
529    }
530
531    /**
532     * Allow to save actural position of first genotype
533     * @param {Array} pos position [x, y, z] of first genotype
534     */
535    handleChangePosition1(pos) {
536        this.setState({ position1: pos}, function() {
537            console.log('Position1: ', this.state.position1);
538        });
539    }
540
541    /**
542     * Allow to save actural position of second genotype
543     * @param {Array} pos position [x, y, z] of second genotype
544     */
545    handleChangePosition2(pos) {
546        this.setState({ position2: pos}, function() {
547            console.log('Position2: ', this.state.position2);
548        });
549    }
550
551    /**
552     * Allow to save actural rotation of first genotype
553     * @param {Array} rot rotation [x, y, z] of first genotype
554     */
555    handleChangeRotation1(rot) {
556        this.setState({ rotation1: rot}, function() {
557            console.log('Rotation1: ', this.state.rotation1);
558        });
559    }
560
561    /**
562     * Allow to save actural rotation of second genotype
563     * @param {Array} rot rotation [x, y, z] of second genotype
564     */
565    handleChangeRotation2(rot) {
566        this.setState({ rotation2: rot}, function() {
567            console.log('Rotation2: ', this.state.rotation2);
568        });
569    }
570
571    /**
572     * Allow to block view in simviewer
573     * @param {Array} rot rotation [x, y, z] of second genotype
574     */
575    handleChangeBlockView(bool) {
576        this.setState({ blockView: bool}, function() {
577            console.log('Block View: ', this.state.blockView);
578        });
579    }
580
581    /**
582     * Allow to change finish result that will be save in the file at the end
583     * @param {string} res text to be save in file
584     */
585    handleChangeResult(res) {
586        this.setState({ result: res }, function() {
587            console.log('Result: ', this.state.result);
588        });
589    }
590
591    /**
592     * Next button function
593     */
594    onClickNext() {
595        this.handleChangeBlockView(true);
596        this.saveFit();
597        if (this.state.round == ROUNDS) {
598            this.setState({ isFinished: true }, function() {
599                console.log('Finish state: ' + this.state.isFinished);
600   
601                if (this.state.isFinished) {
602                    this.finishApp();
603                }
604            });
605        } else {
606            this.nextRound();
607        }
608    }
609
610    /**
611     * Close button function
612     */
613    onClickFinish() {
614        this.setState({ isFinished: true }, function() {
615            console.log('Finish state: ' + this.state.isFinished);
616
617            if (this.state.isFinished) {
618                this.finishApp();
619            }
620        });
621    }
622
623    /**
624     * Stores layout, for LocalStorage layout saving
625     * @param {any} layout layout to be saved
626     */
627    onLayoutChange(layout) {
628        let newlayout = [];
629        for (let i = 0; i < layout.length; i++) {
630            newlayout.push({name: layout[i].i, x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h});
631            if (newlayout[i].name == '2fitviewer') {
632                this.handleChangeFitHeight(newlayout[i].h);
633                this.handleChangeFitWidth(newlayout[i].w);
634            }
635        }
636    }
637    /**
638     * Passes layout to widgetscontainer.
639     * @param {any} layout layout to be used
640     */
641    useLayout(layout) {
642        let items = [];
643        for (let i = 0; i < layout.length; i++) {
644            let name = layout[i].name.split(',')[1];
645            switch (name) {
646                case 'textviewer':
647                    items.push({content: <TextViewer/>, i: "" + i + 'textviewer',
648                        x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h});
649                    break;
650                case 'similviewer':
651                    items.push({content: <SimilViewer
652                            genotype1 = {this.state.genotype1}
653                            genotype2 = {this.state.genotype2}
654                            selected1 = {this.state.selected1}
655                            selected2 = {this.state.selected2}
656                            blockView = {this.state.blockView}
657                            handleChangePosition1 = {(pos) => this.handleChangePosition1(pos)}
658                            handleChangePosition2 = {(pos) => this.handleChangePosition2(pos)}
659                            handleChangeRotation1 = {(rot) => this.handleChangeRotation1(rot)}
660                            handleChangeRotation2 = {(rot) => this.handleChangeRotation2(rot)}
661                            controlMode = {this.state.controlMode}
662                            round = {this.state.round}/>,
663                        i: "" + i + 'similviewer',
664                        x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h});
665                    break;
666                case 'parmviewer':
667                    items.push({content: <ParmViewer
668                            handleChangeYear = {(year) => {this.handleChangeYear(year)}}
669                            handleChangeGender = {(gen) => {this.handleChangeGender(gen)}}
670                        />,
671                        i: "" + i + 'parmviewer',
672                        x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h});
673                    break;
674                case 'fitviewer':
675                    items.push({content: <FitViewer
676                            selected1 = {this.state.selected1}
677                            selected2 = {this.state.selected2}
678                            parts1 = {this.state.parts1}
679                            parts2 = {this.state.parts2}
680                            fitHeight = {this.state.fitHeight}
681                            fitWidth = {this.state.fitWidth}
682                            handleChangeSelected = {(nr, pos, val) => {this.handleChangeSelected(nr, pos, val)}}/>,
683                        i: "" + i + 'fitviewer',
684                        x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h});
685                    break;
686                case 'sliderviewer':
687                    items.push({content: <SliderViewer
688                            isDisable = {this.state.isDisable}
689                            parts1 = {this.state.parts1}
690                            parts2 = {this.state.parts2}
691                            selected1 = {this.state.selected1}
692                            selected2 = {this.state.selected2}
693                            onClickNext = {() => {this.onClickNext()}}
694                            onClickFinish = {() => {this.onClickFinish()}}
695                            handleChangePercent = {(per) => {this.handleChangePercent(per)}}/>,
696                        i: "" + i + 'sliderviewer',
697                        x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h});
698                    break;
699                case 'endviewer':
700                    items.push({content: <EndViewer
701                            userId = {this.state.userId}
702                            result = {this.state.result}/>,
703                        i: "" + i + 'endviewer',
704                        x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h});
705                    break;
706            }
707        }
708        this.widgetscontainer.addMultipleItems(items);
709    }
710
711    /**
712     * Render function.
713     * @returns {JSX.Element} main page of Framsticks.JS
714     */
715    render() {
716       
717        const contentHeader = (
718            <span>   
719                <span style={{marginLeft: '20px', fontFamily: "'Fira Mono', Monaco, 'Andale Mono', 'Lucida Console', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace"}}>
720                    Ankieta
721                </span>
722            </span>
723        );
724
725        return (
726            <TitlePanel
727                title={contentHeader}
728            >
729                <div style={styles.content}>
730                    {this.container}
731                </div>
732            </TitlePanel>
733        );
734    }
735}
736
737export default MainView;
Note: See TracBrowser for help on using the repository browser.