FINALL JAVASCRIPT
unknown
javascript
a month ago
12 kB
1
Indexable
Never
import Alpine from 'alpinejs'; window.Alpine = Alpine; window.layoutData = ({ apiBaseUrl, deviceId, refreshRate, displayType, backgroundColor = null, primaryColor = null, secondaryColor = null, lines = null, displayMessageOnError = null, departuresInterval = null, adInterval = null, adsPath = null, }) => { return { scheduleTickNr: 0, adsTickNr: 0, lastSuccessfulAPIFetch: '', heapSize: '', loadsInProgress: 0, hasErrors: false, firstDataGet: false, adsLayerVisible: false, currentAd: -1, scheduleData: [], appSettings: { apiBaseUrl, deviceId, refreshRate, displayType, backgroundColor, primaryColor, secondaryColor, lines, displayMessageOnError, departuresInterval, adInterval, adsPath, }, ads: [ { "id": 156, "client_id": 1, "name": "Testadvert 0", "media": "adv/2020_YTP_DFI_1920x360.jpg", "media_type": null, "media_size": null, "ad_interval": 3, "visible_from": null, "visible_to": null, "visible_time_from": null, "visible_time_to": null, "created_at": "2024-06-12T19:56:51.000000Z", "updated_at": "2024-06-12T19:56:51.000000Z", "pivot": {"relation_type": "App\\Models\\Layout", "relation_id": 1, "advert_id": 1} }, { "id": 9, "client_id": 1, "name": "Testadvert 1", "media": "adv/SA_DFI_1920x360.jpg", "media_type": null, "media_size": null, "ad_interval": 3, "visible_from": null, "visible_to": null, "visible_time_from": null, "visible_time_to": null, "created_at": "2024-06-12T19:56:51.000000Z", "updated_at": "2024-06-12T19:56:51.000000Z", "pivot": {"relation_type": "App\\Models\\Layout", "relation_id": 1, "advert_id": 2} }, { "id": 1878, "client_id": 1, "name": "Testadvert 2", "media": "adv/TD_Vertrieb_VRR_TFTScreen_1920x1080px.jpg", "media_type": null, "media_size": null, "ad_interval": 6, "visible_from": null, "visible_to": null, "visible_time_from": null, "visible_time_to": null, "created_at": "2024-06-12T19:56:51.000000Z", "updated_at": "2024-06-12T19:56:51.000000Z", "pivot": {"relation_type": "App\\Models\\Layout", "relation_id": 1, "advert_id": 3} }, { "id": 33, "client_id": 1, "name": "Testadvert 3", "media": "adv/YTP_DFI_1920x360.jpg", "media_type": null, "media_size": null, "ad_interval": 7, "visible_from": null, "visible_to": null, "visible_time_from": null, "visible_time_to": null, "created_at": "2024-06-12T19:56:51.000000Z", "updated_at": "2024-06-12T19:56:51.000000Z", "pivot": {"relation_type": "App\\Models\\Layout", "relation_id": 1, "advert_id": 4} }, ], newAds: [] || false, get availableAds() { return this.ads.filter((ad) => this.isCurrentTimeBetween(ad.visible_time_from, ad.visible_time_to)); }, mounted() { this.runApp(); }, isCurrentTimeBetween(startTime, endTime) { if (!startTime || !endTime || startTime === '' || endTime === '') return true; const currentTime = new Date(); const currentMs = currentTime.getHours() * 60 * 60 * 1000 + currentTime.getMinutes() * 60 * 1000 + currentTime.getSeconds() * 1000 + currentTime.getMilliseconds(); const [startHours, startMinutes] = startTime.split(':').map(Number); const [endHours, endMinutes] = endTime.split(':').map(Number); const startMs = startHours * 60 * 60 * 1000 + startMinutes * 60 * 1000; const endMs = endHours * 60 * 60 * 1000 + endMinutes * 60 * 1000; if (startMs < endMs) { return currentMs >= startMs && currentMs <= endMs; } else { return currentMs >= startMs || currentMs <= endMs; } }, getTranportIcon(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(date) { return date.toLocaleDateString('de-DE', {hour: 'numeric', minute: 'numeric'}).split(',')[1]; }, parseResponse(response) { return response.map((entity) => { const departureTime = new Date(entity.departure_planned); const estimatedTime = entity.departure_estimated === null ? new Date(0) : new Date(entity.departure_estimated); return { platform: entity.platform, departureTime, 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((a, b) => a.departureTime.getTime() - b.departureTime.getTime()); }, async makeApiCall(api) { this.loadsInProgress++; const 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((response) => { if (response.headers.get("X-Force-Refresh") === "1") { return window.location.reload(); } return response.json(); }).then((data) => { this.loadsInProgress--; return data; }).catch((error) => { this.hasErrors = true; this.loadsInProgress--; throw new Error('API fetching error' + error); }); }, async doAppTick() { this.scheduleTickNr++; const departuresData = await this.makeApiCall('departures'); 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(ads) { const nextAd = ads.findIndex(ad => ad.id === this.currentAd); if (nextAd === -1) { return 0; } return nextAd === (ads.length - 1) ? 0 : nextAd + 1; }, async doAdsTick() { this.adsTickNr++; const adsData = await this.makeApiCall('ads'); if (adsData !== null) { try { this.ads = adsData; } catch (error) { this.hasErrors = true; throw new Error('Error in ads API response: ' + error); } let defaultSpaceBetweenAds = this.appSettings.departuresInterval * 1000; if (this.availableAds.length === 0) { setTimeout(() => { this.doAdsTick(); }, defaultSpaceBetweenAds); return; } const nextAdIndex = this.findNextAdIndex(this.availableAds); const currentAdVisibilityTime = () => { 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(() => { this.adsLayerVisible = false; }, currentAdVisibilityTime()); setTimeout(() => { this.doAdsTick(); }, currentAdVisibilityTime() + defaultSpaceBetweenAds); } }, runApp() { try { this.doAppTick(); setInterval(() => { this.doAppTick(); }, this.appSettings.refreshRate * 1000); setTimeout(() => { this.doAdsTick(); }, this.appSettings.departuresInterval * 1000); } catch (error) { console.error('Error in runApp:', error); } }, } } Alpine.start();
Leave a Comment