Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
9.8 kB
4
Indexable
Never
<script>
    const layoutData = function() {
        return {
            scheduleTickNr: 0,
            adsTickNr: 0,
            lastSuccessfulAPIFetch: '',
            heapSize: '',
            loadsInProgress: 0,
            hasErrors: false,
            firstDataGet: false,
            adsLayerVisible: false,
            currentAd: -1,
            scheduleData: [],
            appSettings: {
                apiBaseUrl: '{{$device->getApiBaseUrl()}}',
                deviceID: 'bf629d6e-c34d-413f-82ff-a603234752b6',
                refreshRate: {{$device->layout->refresh_rate ?? 30}},
                displayType: '{{$device->layout->type ?? 'B'}}',
                backgroundColor: '{{$device->layout->background_color}}',
                primaryColor: '{{$device->layout->primary_color}}',
                secondaryColor: '{{$device->layout->secondary_color}}',
                lines: {{$device->layout->lines ?? 10}},
                displayMessageOnError: '{{$device->layout->display_error_message}}',
                departuresInterval: {{$device->layout->departure_interval ?? 2}},
                adInterval: {{$device->layout->ad_interval ?? 10}}
            },
            ads: [],
            newAds: false,

            mounted: function() {
                console.log('init');
                this.runApp();
            },

            isCurrentTimeBetween: function(startTime, endTime) {
                if (!startTime || !endTime || startTime === '' || endTime === '') return true;
                var currentTime = new Date();
                var currentMs = currentTime.getHours() * 60 * 60 * 1000 +
                    currentTime.getMinutes() * 60 * 1000 +
                    currentTime.getSeconds() * 1000 +
                    currentTime.getMilliseconds();

                var start = startTime.split(':');
                var end = endTime.split(':');

                var startMs = parseInt(start[0]) * 60 * 60 * 1000 + parseInt(start[1]) * 60 * 1000;
                var endMs = parseInt(end[0]) * 60 * 60 * 1000 + parseInt(end[1]) * 60 * 1000;

                if (startMs < endMs) {
                    return currentMs >= startMs && currentMs <= endMs;
                } else {
                    return currentMs >= startMs || currentMs <= endMs;
                }
            },

            getTranportIcon: function(transportClass) {
                switch (transportClass) {
                    case 'BUS':
                    case 'CITY_BUS':
                    case 'EXPRESS_BUS':
                    case 'REGIONAL_BUS':
                    case 'CALL_BUS':
                    case 'CITIZEN_BUS':
                        return 'busLogo.svg';
                    case 'TRAM':
                    case 'UNDERGROUND':
                        return 'tramLogo.svg';
                    case 'REGIONAL_TRAIN':
                    case 'NATIONAL_TRAIN':
                    case 'INTERNATIONAL_TRAIN':
                        return 'trainLogo.svg';
                    case 'SUBURBAN_TRAIN':
                        return 'sLogo.svg';
                    default:
                        return null;
                }
            },

            getTimeGerman: function(date) {
                return date.toLocaleDateString('de-DE', { hour: 'numeric', minute: 'numeric' }).split(',')[1];
            },

            parseResponse: function(response) {
                var _this = this;
                return response.map(function(entity) {
                    var departureTime = new Date(entity.departure_planned);
                    var estimatedTime = entity.departure_estimated === null ? new Date(0) : new Date(entity.departure_estimated);

                    return {
                        platform: entity.platform,
                        departureTime: departureTime,
                        estimatedTime: estimatedTime,
                        departureString: _this.getTimeGerman(departureTime),
                        estimatedString: _this.getTimeGerman(estimatedTime),
                        destination: entity.destination_name,
                        transportTitle: entity.transport_name ? entity.transport_name + ' ' + entity.transport_number : (entity.transport_full_name || null),
                        transportClass: entity.transport_class,
                        transportIcon: _this.getTranportIcon(entity.transport_class),
                        hint: entity.hints || '',
                        delay: (estimatedTime > departureTime) ? (estimatedTime.getTime() - departureTime.getTime()) / (60 * 1000) : 0
                    };
                }).sort(function(a, b) {
                    return a.departureTime.getTime() - b.departureTime.getTime();
                });
            },

            logApiUrl: function(api) {
                var requestUrl = api === 'ads' ? this.appSettings.apiBaseUrl + this.appSettings.deviceID + '/ads' : this.appSettings.apiBaseUrl + this.appSettings.deviceID + '/departures?limit=' + this.appSettings.lines;
                console.log('API URL (' + api + '):', requestUrl);
            },

            makeApiCall: function(api) {
                var _this = this;
                this.loadsInProgress++;
                var requestUrl = api === 'ads' ? this.appSettings.apiBaseUrl + this.appSettings.deviceID + '/ads' : this.appSettings.apiBaseUrl + this.appSettings.deviceID + '/departures?limit=' + this.appSettings.lines;

                return fetch(requestUrl, {
                    method: 'GET'
                }).then(function(response) {
                    if (response.headers.get("X-Force-Refresh") === "1") {
                        return window.location.reload();
                    }
                    return response.json();
                }).then(function(data) {
                    return data;
                }).catch(function(error) {
                    _this.hasErrors = true;
                    throw new Error('API fetching error' + error);
                }).finally(function() {
                    _this.loadsInProgress--;
                });
            },

            doAppTick: function() {
                var _this = this;
                this.scheduleTickNr++;
                this.logApiUrl('departures');
                this.makeApiCall('departures').then(function(departuresData) {
                    if (departuresData !== null) {
                        try {
                            _this.lastSuccessfulAPIFetch = (new Date()).toLocaleDateString('de-DE', { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' });
                            _this.firstDataGet = true;
                            _this.scheduleData = _this.parseResponse(departuresData);
                        } catch (error) {
                            _this.hasErrors = true;
                            throw new Error('Error in departures API response: ' + error);
                        }
                    }
                });
            },

            findNextAdIndex: function(ads) {
                var nextAd = ads.findIndex(function(ad) {
                    return ad.id === this.currentAd;
                }.bind(this));
                if (nextAd === -1) {
                    return 0;
                }
                return nextAd === (ads.length - 1) ? 0 : nextAd + 1;
            },

            doAdsTick: function() {
                var _this = this;
                this.adsTickNr++;
                this.logApiUrl('ads');
                this.makeApiCall('ads').then(function(adsData) {
                    if (adsData !== null) {
                        try {
                            _this.ads = adsData;
                        } catch (error) {
                            _this.hasErrors = true;
                            throw new Error('Error in ads API response: ' + error);
                        }

                        var defaultSpaceBetweenAds = _this.appSettings.departuresInterval * 1000;

                        if (_this.availableAds.length === 0) {
                            setTimeout(function() {
                                _this.doAdsTick();
                            }, defaultSpaceBetweenAds);
                            return;
                        }

                        var nextAdIndex = _this.findNextAdIndex(_this.availableAds);
                        var currentAdVisibilityTime = function() {
                            return _this.availableAds[nextAdIndex].ad_interval ? _this.availableAds[nextAdIndex].ad_interval * 1000 : _this.appSettings.adInterval * 1000;
                        }

                        _this.currentAd = _this.availableAds[nextAdIndex].id;
                        _this.adsLayerVisible = true;

                        setTimeout(function() {
                            _this.adsLayerVisible = false;
                        }, currentAdVisibilityTime());

                        setTimeout(function() {
                            _this.doAdsTick();
                        }, currentAdVisibilityTime() + defaultSpaceBetweenAds);
                    }
                });
            },

            runApp: function() {
                var _this = this;
                try {
                    this.doAppTick();
                    setInterval(function() {
                        _this.doAppTick();
                    }, this.appSettings.refreshRate * 1000);
                    setTimeout(function() {
                        _this.doAdsTick();
                    }, this.appSettings.departuresInterval * 1000);
                } catch (error) {
                    console.error('Error in runApp:', error);
                }
            }
        };
    };
</script>
Leave a Comment