{"version":3,"sources":["components/map/ol-map/OLMap.jsx","components/map/ol-controls/time-slider/TimeSliderControl.jsx","components/map/ol-progressbar/OlProgressBar.jsx","components/map/ol-controls/time-slider/play.svg","components/map/ol-controls/time-slider/pause.svg"],"names":["OLMap","Component","constructor","props","super","this","map","addMapLayer","bind","addMapControl","setMapLayerVisible","addOverlayToMap","moveOverlay","mapClick","updateTimeDimensions","panTo","addCameras","showStationTextOnHover","showStationTextOnTouch","updateSize","parser","WMTSCapabilities","progressBarHandler","lastStationHover","componentDidMount","proj4","defs","register","center","Array","isArray","zoom","parseInt","target","detachWindow","retrieveDetachDiv","Map","moveTolerance","layers","interactions","defaults","mouseWheelZoom","disableMouseWheelZoom","view","View","projection","transform","minZoom","on","componentWillUnmount","un","layername","visible","getLayers","getArray","forEach","layer","get","setVisible","evt","pointerEvent","pointerType","container","overlay","Overlay","element","offset","stopEvent","positioning","autoPanAnimation","duration","setPosition","undefined","addOverlay","coordinates","addStationTextStyle","text","Text","font","offsetY","backgroundFill","Fill","color","e","dragging","pixel","getEventPixel","originalEvent","feature","forEachFeatureAtPixel","f","hitTolerance","station","name","showName","set","getStyle","setText","showInsteadOfContinue","generateStationFeature","Feature","geometry","Point","longitude","latitude","concat","eoi","type","originalColor","latestAQI","style","Style","image","Icon","anchor","anchorXUnits","anchorYUnits","scale","src","window","location","origin","setStyle","addStationsToMap","list","features","stationComponents","latestAQIComponents","Object","entries","_ref","key","value","c","push","vs","SourceVector","stationVectorLayer","LayerVector","source","zIndex","timeLoaded","Date","_ref2","sv","component","toLowerCase","replace","lv","cameras","camera","road","description","cameraUrl","url","cameraVectorLayer","addGeoDataWmts","wmts","result","read","options","optionsFromCapabilities","matrixSet","TileLayer","opacity","WMTS","addMetsWms","layernames","wms","WMSCapabilities","newLayer","TileWMS","crossOrigin","params","LAYERS","TIME","TRANSPARENT","serverType","getSource","addLoading","addDone","addMetsWmts","dims","Contents","Layer","Dimension","today","Value","length","show","useInterimTilesOnError","default","Default","values","addLayer","control","addControl","setVisibleLayers","activeLayers","filter","l","includes","time","updateDimensions","updateParams","isNow","now","timeDate","getHours","getDate","getFeatures","lat","long","arguments","getView","setCenter","setZoom","render","React","createElement","id","className","TimeSliderControl","weekday","Localization","timeSliderSunday","timeSliderMonday","timeSliderTuesday","timeSliderWednesday","timeSliderThursday","timeSliderFriday","timeSliderSaturday","index","totalPins","px","intervalWidth","times","day","date","getDay","timesThisDay","t","Math","floor","dayName","substring","timelist","cutArray","days","wdDict","WeekdayDictionaryNOR","indexOf","hour","dayNames","d","sliderDates","timeobj","timeParam","answer","i","doublecheckDate","getUTCDate","getUTCMonth","getUTCFullYear","setLanguage","sliderOnChange","togglePlay","setupTimeslider","writeCleanTime","state","isLoading","newTimes","sliderValue","isPlaying","playingIntervalId","componentDidUpdate","prevProps","prevState","onTimeSliderChange","clearInterval","newIntervalId","setInterval","setState","_objectSpread","restructureTime","getSliderNow","toString","console","log","returnText","Spinner","numPins","Pause","Play","onClick","position","left","pinOffset","dayLabel","width","data-t","classes","htmlFor","timesliderName","step","min","max","onChange","OlProgressBar","loading","done","progressBar","createRef","update","current","visibility","toFixed","setTimeout","ref","module","exports"],"mappings":"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","file":"static/js/1.d453c7ba.chunk.js","sourcesContent":["import React, { Component } from 'react';\nimport { Map, View } from 'ol';\nimport { transform } from 'ol/proj';\nimport proj4 from 'proj4/dist/proj4-src';\nimport { register } from 'ol/proj/proj4';\nimport WMTS, { optionsFromCapabilities } from 'ol/source/WMTS';\nimport TileWMS from 'ol/source/TileWMS';\nimport TileLayer from 'ol/layer/Tile';\nimport LayerVector from 'ol/layer/Vector';\nimport SourceVector from 'ol/source/Vector';\nimport Point from 'ol/geom/Point';\nimport Feature from 'ol/Feature';\nimport Style from 'ol/style/Style';\nimport Icon from 'ol/style/Icon';\nimport Text from 'ol/style/Text';\nimport Fill from 'ol/style/Fill';\nimport Overlay from 'ol/Overlay';\nimport {defaults} from 'ol/interaction';\n\nimport WMTSCapabilities from 'ol/format/WMTSCapabilities';\nimport WMSCapabilities from 'ol/format/WMSCapabilities';\n\nexport default class OLMap extends Component {\n constructor(props) {\n super(props);\n this.map = null;\n this.addMapLayer = this.addMapLayer.bind(this);\n this.addMapControl = this.addMapControl.bind(this);\n this.setMapLayerVisible = this.setMapLayerVisible.bind(this);\n this.addOverlayToMap = this.addOverlayToMap.bind(this);\n this.moveOverlay = this.moveOverlay.bind(this);\n this.mapClick = this.mapClick.bind(this);\n this.updateTimeDimensions = this.updateTimeDimensions.bind(this);\n this.panTo = this.panTo.bind(this);\n this.addCameras = this.addCameras.bind(this);\n this.showStationTextOnHover = this.showStationTextOnHover.bind(this);\n this.showStationTextOnTouch = this.showStationTextOnTouch.bind(this);\n this.updateSize = this.updateSize.bind(this);\n this.parser = new WMTSCapabilities();\n this.progressBarHandler = props.progressBarHandler;\n this.lastStationHover = null;\n }\n\n componentDidMount() {\n proj4.defs(\n 'EPSG:32633',\n '+proj=utm +zone=33 +ellps=WGS84 +datum=WGS84 +units=m +no_defs',\n );\n\n register(proj4);\n let center = this.props.center;\n if (!Array.isArray(center)) {\n center = [0, 0];\n }\n\n let zoom = 14;\n if (this.props.zoom) {\n zoom = parseInt(this.props.zoom, 10);\n }\n\n let target = null;\n if (this.props.detachWindow && this.props.retrieveDetachDiv) {\n target = this.props.retrieveDetachDiv('olmap');\n }\n\n if (target === null) {\n target = 'olmap';\n }\n\n this.map = new Map({\n target: 'olmap',\n moveTolerance: 5,\n layers: [],\n interactions: defaults({ mouseWheelZoom: !!!this.props.disableMouseWheelZoom}),\n view: new View({\n projection: 'EPSG:32633',\n center: transform([center[0], center[1]], 'EPSG:4326', 'EPSG:32633'),\n minZoom: 6,\n zoom,\n }),\n });\n\n this.map.on('click', this.mapClick, false);\n\n // Hover should show the station name.\n this.map.on('pointermove', this.showStationTextOnHover);\n }\n\n componentWillUnmount() {\n this.map.un('click', this.mapClick, false);\n this.map = null;\n }\n\n setMapLayerVisible(layername, visible) {\n this.map\n .getLayers()\n .getArray()\n .forEach((layer) => {\n if (layer.get('name') === layername) {\n layer.setVisible(visible);\n }\n });\n }\n\n updateSize() {\n this.map.updateSize();\n }\n\n mapClick(evt) {\n // Show station name on click for touch first.\n if (\n evt.pointerEvent.pointerType === 'touch'\n && this.showStationTextOnTouch(evt)\n ) {\n return;\n }\n\n if (this.props.mapClick) {\n this.props.mapClick(evt, this.map);\n }\n }\n\n addOverlayToMap(container) {\n const overlay = new Overlay({\n element: container,\n offset: [0, 10],\n // autoPan: true,\n stopEvent: false,\n positioning: 'top-center',\n autoPanAnimation: {\n duration: 250,\n },\n });\n\n overlay.setPosition(undefined);\n\n this.map.addOverlay(overlay);\n\n return overlay;\n }\n\n moveOverlay(overlay, coordinates) {\n overlay.setPosition(coordinates);\n }\n\n addStationTextStyle(text) {\n return new Text({\n text,\n font: '16px sans-serif',\n offsetY: 9,\n backgroundFill: new Fill({\n color: '#ffffff',\n }),\n });\n }\n\n showStationTextOnHover(e) {\n if (e.dragging) return;\n // Don't do this for touch.\n if (e.pointerEvent.pointerType === 'touch') return;\n\n const pixel = this.map.getEventPixel(e.originalEvent);\n const feature = this.map.forEachFeatureAtPixel(pixel, f => f, {\n hitTolerance: 3,\n });\n\n if (feature && feature.get('type') === 'station') {\n const station = {\n name: feature.get('name'),\n showName: feature.get('showName'),\n feature,\n };\n if (\n this.lastStationHover !== null\n && feature !== this.lastStationHover.feature\n ) {\n this.lastStationHover.feature.set('showName', false);\n this.lastStationHover.feature\n .getStyle()\n .setText(this.addStationTextStyle(''));\n this.lastStationHover = null;\n }\n\n if (!station.showName) {\n feature.set('showName', true);\n feature.getStyle().setText(this.addStationTextStyle(station.name));\n this.lastStationHover = station;\n }\n } else if (this.lastStationHover) {\n this.lastStationHover.feature.set('showName', false);\n this.lastStationHover.feature\n .getStyle()\n .setText(this.addStationTextStyle(''));\n this.lastStationHover = null;\n }\n }\n\n showStationTextOnTouch(e) {\n if (e.dragging) return;\n\n const pixel = this.map.getEventPixel(e.originalEvent);\n const feature = this.map.forEachFeatureAtPixel(pixel, f => f, {\n hitTolerance: 3,\n });\n let showInsteadOfContinue = false;\n if (feature && feature.get('type') === 'station') {\n const station = {\n name: feature.get('name'),\n showName: feature.get('showName'),\n feature,\n };\n if (\n this.lastStationHover !== null\n && feature !== this.lastStationHover.feature\n ) {\n this.lastStationHover.feature.set('showName', false);\n this.lastStationHover.feature\n .getStyle()\n .setText(this.addStationTextStyle(''));\n this.lastStationHover = null;\n }\n if (!station.showName) {\n feature.set('showName', true);\n feature.getStyle().setText(this.addStationTextStyle(station.name));\n this.lastStationHover = station;\n showInsteadOfContinue = true;\n } else {\n showInsteadOfContinue = false;\n }\n } else if (this.lastStationHover) {\n this.lastStationHover.feature.set('showName', false);\n this.lastStationHover.feature\n .getStyle()\n .setText(this.addStationTextStyle(''));\n this.lastStationHover = null;\n showInsteadOfContinue = false;\n }\n\n return showInsteadOfContinue;\n }\n\n generateStationFeature(station, color) {\n const feature = new Feature({\n // http://lyzidiamond.com/posts/4326-vs-3857\n geometry: new Point(\n transform(\n [station.longitude, station.latitude],\n 'EPSG:4326',\n 'EPSG:32633',\n ),\n ),\n name: `${station.station}`,\n\n eoi: `${station.eoi}`,\n showName: false,\n type: 'station',\n latitude: station.latitude,\n longitude: station.longitude,\n originalColor: station.latestAQI.color\n ? station.latestAQI.color\n : '#cfd8dc',\n });\n const style = new Style({\n text: this.addStationTextStyle(''),\n image: new Icon(\n /** @type {olx.style.IconOptions} */ ({\n anchor: [0.5, 1], // Hopefully middle bottom of icon\n anchorXUnits: 'fraction',\n anchorYUnits: 'fraction',\n scale: 0.2,\n color,\n src: `${window.location.origin}/icons/icon.png`, // Relative link to the public folder.\n }),\n ),\n });\n feature.setStyle(style);\n return feature;\n }\n\n addStationsToMap(list, visible) {\n const features = [];\n const stationComponents = {};\n list.forEach((station) => {\n if (station.latestAQIComponents) {\n Object.entries(station.latestAQIComponents).forEach(([key, value]) => {\n let c = stationComponents[key];\n if (!c) {\n c = [];\n stationComponents[key] = c;\n }\n c.push(this.generateStationFeature(station, value.color));\n });\n }\n\n features.push(this.generateStationFeature(station, station.latestAQI.color\n ? station.latestAQI.color\n : '#cfd8dc'));\n });\n const vs = new SourceVector({\n features,\n });\n\n const stationVectorLayer = new LayerVector({\n source: vs,\n name: 'stations_aqi',\n zIndex: 20000,\n timeLoaded: new Date(),\n visible,\n // declutter: true,\n });\n\n this.addMapLayer(stationVectorLayer);\n\n Object.entries(stationComponents).forEach(([key, value]) => {\n const sv = new SourceVector({ features: value });\n const component = key.toLowerCase().replace('.', ''); // Handle components like PM2.5\n const lv = new LayerVector({\n source: sv,\n name: `stations_${component}_concentration`,\n zIndex: 20000,\n timeLoaded: new Date(),\n visible,\n // declutter: true,\n });\n this.addMapLayer(lv);\n });\n }\n\n addCameras(cameras) {\n const features = [];\n cameras.forEach((camera) => {\n const feature = new Feature({\n // http://lyzidiamond.com/posts/4326-vs-3857\n geometry: new Point(\n transform(\n [camera.longitude, camera.latitude],\n 'EPSG:4326',\n 'EPSG:32633',\n ),\n ),\n name: `${camera.road}, ${camera.description}`,\n cameraUrl: camera.url,\n camera: true,\n });\n const style = new Style({\n image: new Icon(\n /** @type {olx.style.IconOptions} */ ({\n anchor: [0.5, 1], // Hopefully middle bottom of icon\n anchorXUnits: 'fraction',\n anchorYUnits: 'fraction',\n scale: 0.4,\n color: '#885EAD',\n src: `${window.location.origin}/icons/camera.png`, // Relative link to the public folder.\n }),\n ),\n });\n feature.setStyle(style);\n features.push(feature);\n });\n const vs = new SourceVector({\n features,\n });\n\n const cameraVectorLayer = new LayerVector({\n source: vs,\n name: 'Cameras',\n zIndex: 10000,\n timeLoaded: new Date(),\n visible: false,\n });\n\n this.addMapLayer(cameraVectorLayer);\n }\n\n addGeoDataWmts(wmts) {\n const result = this.parser.read(wmts);\n const options = optionsFromCapabilities(result, {\n layer: 'Geocache_UTM33_WGS84_GeocacheGraatone',\n matrixSet: 'default028mm',\n });\n\n this.addMapLayer(\n new TileLayer({\n opacity: 1,\n zIndex: -1,\n source: new WMTS(\n /** @type {!module:ol/source/WMTS~Options} */ (options),\n ),\n name: 'base',\n }),\n );\n }\n\n addMetsWms(layernames, wms) {\n const parser = new WMSCapabilities();\n\n const result = parser.read(wms);\n\n layernames.forEach((layer) => {\n const newLayer = new TileLayer({\n name: layer.name,\n zIndex: 100,\n source: new TileWMS({\n url: 'https://halo-wms.met.no/halo/default.map',\n crossOrigin: 'anonymous',\n params: {\n LAYERS: layer.name,\n TIME: '2017-12-09T00%3A00%3A00.000Z',\n TRANSPARENT: 'true',\n },\n serverType: 'mapserver',\n }),\n visible: false,\n });\n newLayer.getSource().on('tileloadstart', () => {\n try {\n this.progressBarHandler.addLoading();\n } catch (e) {\n // This error occurs when we leave the page before tiles have loaded properly. Ignore.\n // console.log(e);\n }\n });\n newLayer.getSource().on('tileloadend', () => {\n try {\n this.progressBarHandler.addDone();\n } catch (e) {\n // This error occurs when we leave the page before tiles have loaded properly. Ignore.\n // console.log(e);\n }\n });\n newLayer.getSource().on('tileloaderror', () => {\n try {\n this.progressBarHandler.addDone();\n } catch (e) {\n // This error occurs when we leave the page before tiles have loaded properly. Ignore.\n // console.log(e);\n }\n });\n this.addMapLayer(newLayer);\n });\n return {\n // default: dims.Default,\n // // values: dims.Value,\n };\n }\n\n addMetsWmts(layernames, wmts) {\n const parser = new WMTSCapabilities();\n const result = parser.read(wmts);\n\n const dims = result.Contents.Layer[0].Dimension[0];\n\n const today = new Date();\n if (\n new Date(dims.Value[0]) > today\n || today > new Date(dims.Value[dims.Value.length - 1])\n ) {\n // Bad today date. Data out of range. Return null.\n return null;\n }\n\n layernames.forEach((layer) => {\n const options = optionsFromCapabilities(result, {\n layer: layer.name,\n matrixSet: 'utm33_norway',\n });\n const newLayer = new TileLayer({\n opacity: 0.7,\n source: new WMTS(\n /** @type {!module:ol/source/WMTS~Options} */ (options),\n ),\n name: layer.name,\n visible: layer.show,\n useInterimTilesOnError: false,\n });\n newLayer.getSource().on('tileloadstart', () => {\n try {\n this.progressBarHandler.addLoading();\n } catch (e) {\n // This error occurs when we leave the page before tiles have loaded properly. Ignore.\n // console.log(e);\n }\n });\n newLayer.getSource().on('tileloadend', () => {\n try {\n this.progressBarHandler.addDone();\n } catch (e) {\n // This error occurs when we leave the page before tiles have loaded properly. Ignore.\n // console.log(e);\n }\n });\n newLayer.getSource().on('tileloaderror', () => {\n try {\n this.progressBarHandler.addDone();\n } catch (e) {\n // This error occurs when we leave the page before tiles have loaded properly. Ignore.\n // console.log(e);\n }\n });\n this.addMapLayer(newLayer);\n });\n return {\n default: dims.Default,\n values: dims.Value,\n };\n }\n\n // Call this by:\n // (constructor) this.map = React.createRef();\n // (render) <OLMap ref=[this.map] ...\n // (function) this.map.current.addMapLayer(layer);\n addMapLayer(layer) {\n this.map.addLayer(layer);\n }\n\n addMapControl(control) {\n this.map.addControl(control);\n }\n\n setVisibleLayers(activeLayers) {\n this.map\n .getLayers()\n .getArray()\n .filter(l => l.get('name') !== 'base')\n .forEach((layer) => {\n layer.setVisible(activeLayers.includes(layer.get('name')));\n });\n }\n\n updateTimeDimensions(time) {\n this.map\n .getLayers()\n .getArray()\n .forEach((layer) => {\n if (layer.get('name') !== 'base' && layer.get('name') !== 'Stations') {\n try {\n layer.getSource().updateDimensions({ time });\n } catch (e) {\n try {\n layer.getSource().updateParams({ TIME: time });\n } catch (e) {\n // console.log(\"WMS :'(\")\n }\n }\n }\n if (layer.get('name') === 'Stations') {\n let isNow = false;\n const now = layer.get('timeLoaded') || new Date();\n const timeDate = new Date(time);\n\n if (\n now.getHours() === timeDate.getHours()\n && now.getDate() === timeDate.getDate()\n ) {\n isNow = true;\n }\n\n layer\n .getSource()\n .getFeatures()\n .forEach((feature) => {\n const style = new Style({\n image: new Icon(\n /** @type {olx.style.IconOptions} */ ({\n anchor: [0.5, 1], // Hopefully middle bottom of icon\n anchorXUnits: 'fraction',\n anchorYUnits: 'fraction',\n scale: 0.2,\n color: isNow ? feature.get('originalColor') : '#cfd8dc',\n src: `${window.location.origin}/icons/icon.png`, // Relative link to the public folder.\n }),\n ),\n });\n feature.setStyle(style);\n });\n }\n });\n }\n\n panTo(lat, long, zoom = -1) {\n this.map\n .getView()\n .setCenter(transform([long, lat], 'EPSG:4326', 'EPSG:32633'));\n if (zoom > -1) {\n this.map.getView().setZoom(zoom);\n }\n }\n\n render() {\n return <div id=\"olmap\" className=\"ol-map-wrapper\" />;\n }\n}\n","import React, { Component } from 'react';\nimport Spinner from 'components/elements/spinner/Spinner';\nimport './TimeSliderControl.scss';\nimport Play from './play.svg'\nimport Pause from './pause.svg'\nimport Localization, { setLanguage } from 'languages/components/map/MapLan';\nimport { isMobile } from 'react-device-detect';\n\nclass TimeSliderControl extends Component {\n static WeekdayDictionaryNOR() {\n const weekday = new Array(7);\n weekday[0] = Localization.timeSliderSunday;\n weekday[1] = Localization.timeSliderMonday;\n weekday[2] = Localization.timeSliderTuesday;\n weekday[3] = Localization.timeSliderWednesday;\n weekday[4] = Localization.timeSliderThursday;\n weekday[5] = Localization.timeSliderFriday;\n weekday[6] = Localization.timeSliderSaturday;\n\n return weekday;\n }\n\n static pinOffset(index, totalPins, px) {\n const intervalWidth = 100.0 / totalPins;\n\n const temp = (intervalWidth * index) - (intervalWidth);\n return `calc(${temp}% - ${px}px)`;\n }\n\n static dayLabel(time, times) {\n const day = new Date(time.date).getDay();\n const timesThisDay = times.filter(t => new Date(t.date).getDay() === day);\n if (timesThisDay.length > 4) {\n const middleIndex = Math.floor(timesThisDay.length / 2);\n\n const middleDay = timesThisDay[middleIndex];\n\n if (middleDay === time) {\n if (timesThisDay.length < 12) {\n return time.dayName.substring(0, 3);\n }\n\n return time.dayName;\n }\n }\n return '';\n }\n\n\n static restructureTime(times) {\n const timelist = [];\n const cutArray = [];\n const days = [];\n\n const wdDict = TimeSliderControl.WeekdayDictionaryNOR();\n\n times.forEach((t) => {\n const date = new Date(t);\n const day = date.getDay();\n\n cutArray.push(t);\n if (days.indexOf(day) === -1) {\n days.push(date.getDay());\n }\n\n timelist.push({\n date: t,\n hour: date.getHours(),\n day,\n dayName: wdDict[day],\n });\n });\n const dayNames = [];\n days.forEach((d) => {\n dayNames.push(wdDict[d]);\n });\n\n const obj = {\n days: dayNames,\n sliderDates: cutArray,\n timelist,\n };\n\n return obj;\n }\n\n static getSliderNow(timeobj, timeParam) {\n let now = new Date();\n\n // Override if we get date from url\n if (timeParam) {\n try {\n const paramDate = new Date(timeParam);\n now = paramDate;\n } catch (e) {\n // Bad date, ignore param\n }\n }\n\n const day = now.getDay();\n const hour = now.getHours();\n\n // Index for the slider.\n let index = 0;\n\n let answer = null;\n for (let i = 0; i < timeobj.timelist.length; i++) {\n if (timeobj.timelist[i].day === day\n && timeobj.timelist[i].hour === hour) {\n // We know that day number (0 = sunday) matches and the hour matches.\n // But we need to check that the date is the same as well.\n // The time set we have may be for a week or more ago. Doublecheck that we are up to speed.\n const doublecheckDate = new Date(timeobj.timelist[i].date);\n if (doublecheckDate.getUTCDate() === now.getUTCDate()\n && doublecheckDate.getUTCMonth() === now.getUTCMonth()\n && doublecheckDate.getUTCFullYear() === now.getUTCFullYear()) {\n answer = i;\n break;\n }\n }\n }\n\n // If we found it, send back the index. Otherwise start slider at first value.\n if (answer !== null) {\n index = answer;\n }\n\n return index;\n }\n\n\n constructor(props) {\n super(props);\n\n setLanguage();\n this.sliderOnChange = this.sliderOnChange.bind(this);\n this.togglePlay = this.togglePlay.bind(this);\n this.setupTimeslider = this.setupTimeslider.bind(this);\n this.writeCleanTime = this.writeCleanTime.bind(this);\n\n this.state = {\n isLoading: true,\n timeobj: {},\n newTimes: [],\n sliderValue: -1,\n isPlaying: false,\n playingIntervalId: undefined\n };\n\n }\n\n\n\n componentDidUpdate(prevProps, prevState) {\n if (prevProps.times.length !== this.props.times.length) {\n this.setupTimeslider();\n }\n if (this.props.times.length > 0\n && this.props.map\n && prevState.sliderValue !== this.state.sliderValue) {\n this.props.map.updateTimeDimensions(this.state.newTimes[this.state.sliderValue]);\n if (this.props.onTimeSliderChange) {\n this.props.onTimeSliderChange(this.state.newTimes[this.state.sliderValue]);\n }\n }\n }\n componentDidMount() {\n // MET has complained of too high ressource usage of this feature - so we do not enable auto play per default\n // if (!isMobile) {\n // this.togglePlay();\n // }\n }\n \n componentWillUnmount() {\n if (this.state.playingIntervalId) {\n clearInterval(this.state.playingIntervalId);\n }\n }\n\n togglePlay() {\n let newIntervalId = undefined;\n if (this.state.isPlaying) {\n clearInterval(this.state.playingIntervalId);\n }\n else {\n newIntervalId = \n setInterval(() => {\n if (this.state.sliderValue < this.state.newTimes.length - 1) {\n this.setState(prevState => ({ \n ...prevState,\n sliderValue: prevState.sliderValue < prevState.newTimes.length - 1 ? prevState.sliderValue + 1 : prevState.sliderValue\n }));\n }\n else {\n if (this.state.isPlaying) {\n this.togglePlay();\n }\n }\n \n }, 1000 ); \n }\n this.setState({\n ...this.state,\n playingIntervalId: newIntervalId, \n isPlaying: !this.state.isPlaying\n });\n }\n setupTimeslider() {\n const timeobj = TimeSliderControl.restructureTime(this.props.times);\n const newTimes = timeobj.sliderDates;\n this.setState({ isLoading: false, timeobj, newTimes });\n\n const now = TimeSliderControl.getSliderNow(timeobj, this.props.timeParam);\n this.sliderOnChange(now.toString());\n }\n\n\n sliderOnChange(index) {\n console.log(index);\n this.setState({ sliderValue: parseInt(index, 10) });\n }\n\n writeCleanTime(hour, index) {\n let returnText = '';\n if (index === this.state.sliderValue) {\n returnText = hour < 10 ? `0${hour}` : `${hour}`;\n }\n return returnText;\n }\n\n render() {\n if (this.state.isLoading) {\n return <Spinner />;\n }\n const numPins = this.state.timeobj.timelist.length;\n const intervalWidth = 100.0 / numPins;\n\n return (\n <div className=\"c_timeline\">\n <img className=\"c_play\" src={this.state.isPlaying ? Pause : Play} onClick={this.togglePlay}/>\n <div className=\"c_timeline__days\">\n {this.state.timeobj.timelist.map((t, i) => <span key={t.date} style={{ position: 'absolute', left: TimeSliderControl.pinOffset(i + 1, numPins, 3) }}>{TimeSliderControl.dayLabel(t, this.state.timeobj.timelist)}</span>)}\n </div>\n <div className=\"c_timeline__pins\" style={{ width: `calc(88% + ${intervalWidth}%)` }}>\n <div className=\"pins__big\">\n {this.state.timeobj.timelist.map((t, i) => <span style={{ left: TimeSliderControl.pinOffset(i + 1, numPins, 3) }} data-t={t.date} key={t.date} className={t.hour === 0 ? 'active' : ''} />)}\n </div>\n <div className=\"pins__progress\">\n {this.state.timeobj.timelist.map((t, i) => \n {\n let classes = i === this.state.sliderValue ? 'active' : '';\n if (i < this.state.sliderValue) {\n classes = `${classes} past`\n }\n return (<span style={{ left: TimeSliderControl.pinOffset(i + 1, numPins, 1) }} data-t={t.date} key={t.date} className={classes}><span>{this.writeCleanTime(t.hour, i)}</span></span>)\n })}\n </div>\n <div className=\"pins__now_marker\">\n {this.state.timeobj.timelist.map((t, i) => \n {\n let classes = i === this.state.sliderValue ? 'active' : '';\n return (<span style={{ left: TimeSliderControl.pinOffset(i + 1, numPins, 9) }} data-t={t.date} key={t.date} className={classes}><span></span></span>)\n })}\n </div>\n\n <div className=\"pins__small\">\n {this.state.timeobj.timelist.map((t, i) => \n {\n let classes = i === this.state.sliderValue ? 'active' : '';\n if (i % 2 == 1) {\n classes = `${classes} unequal`\n }\n return (<span style={{ left: TimeSliderControl.pinOffset(i + 1, numPins, 1) }} data-t={t.date} key={t.date} className={classes}><span>{this.writeCleanTime(t.hour, i)}</span></span>)\n })}\n </div>\n <div className=\"pins__intervals\">\n {this.state.timeobj.timelist.map((t, i) => {\n const style = { left: TimeSliderControl.pinOffset(i + 1, numPins, 13) };\n if (t.hour % 2 === 0) {\n return <span style={style} data-t={t.date} key={t.date}>{t.hour < 10 ? `0${t.hour}` : t.hour}</span>;\n }\n return <span style={style} data-t={t.date} key={t.date} />;\n })}\n </div>\n </div>\n <div className=\"c_timeline__slider\">\n <label id=\"c_timeslider__label\" htmlFor=\"c_timeslider__id\">\n {Localization.timesliderName}\n </label>\n <input\n id=\"c_timeslider__id\"\n className=\"slider__range\"\n type=\"range\"\n step=\"1\"\n min=\"0\"\n value={this.state.sliderValue}\n max={this.state.newTimes.length - 1}\n onChange={e => this.sliderOnChange(e.target.value)}\n />\n </div>\n </div>\n );\n }\n}\n\nexport default TimeSliderControl;\n","import React, { Component } from 'react';\nimport './OlProgressBar.scss';\n\nclass OlProgressBar extends Component {\n constructor(props) {\n super(props);\n this.loading = 0;\n this.done = 0;\n\n this.progressBar = React.createRef();\n this.addLoading = this.addLoading.bind(this);\n this.addDone = this.addDone.bind(this);\n this.update = this.update.bind(this);\n }\n\n addLoading() {\n try {\n if (this.loading === 0) {\n this.progressBar.current.style.visibility = 'visible';\n }\n this.loading += 1;\n this.update();\n } catch (e) {\n // Ignore\n }\n }\n\n addDone() {\n try {\n this.done += 1;\n this.update();\n } catch (e) {\n // Ignore\n }\n }\n\n update() {\n const width = `${(this.done / this.loading * 100).toFixed(1)}%`;\n this.progressBar.current.style.width = width;\n\n if (this.loading === this.done) {\n this.loading = 0;\n this.done = 0;\n setTimeout(() => {\n if (this.progressBar.current) {\n this.progressBar.current.style.visibility = 'hidden';\n this.progressBar.current.style.width = 0;\n }\n }, 750);\n }\n }\n\n render() {\n return <div id=\"progressbar\" className=\"c_ol-progressbar\" ref={this.progressBar} />;\n }\n}\n\nexport default OlProgressBar;\n","module.exports = __webpack_public_path__ + \"static/media/play.438abd6d.svg\";","module.exports = __webpack_public_path__ + \"static/media/pause.73b23d49.svg\";"],"sourceRoot":""}