| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import { UIEventSource } from "../../Logic/UIEventSource" | 
					
						
							|  |  |  | import Combine from "../Base/Combine" | 
					
						
							|  |  |  | import { FixedUiElement } from "../Base/FixedUiElement" | 
					
						
							|  |  |  | import { OH } from "./OpeningHours" | 
					
						
							|  |  |  | import Translations from "../i18n/Translations" | 
					
						
							|  |  |  | import Constants from "../../Models/Constants" | 
					
						
							|  |  |  | import BaseUIElement from "../BaseUIElement" | 
					
						
							|  |  |  | import Toggle from "../Input/Toggle" | 
					
						
							|  |  |  | import { VariableUiElement } from "../Base/VariableUIElement" | 
					
						
							|  |  |  | import Table from "../Base/Table" | 
					
						
							|  |  |  | import { Translation } from "../i18n/Translation" | 
					
						
							|  |  |  | import { OsmConnection } from "../../Logic/Osm/OsmConnection" | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-28 00:45:49 +02:00
										 |  |  | export default class OpeningHoursVisualization extends Toggle { | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     private static readonly weekdays: Translation[] = [ | 
					
						
							|  |  |  |         Translations.t.general.weekdays.abbreviations.monday, | 
					
						
							|  |  |  |         Translations.t.general.weekdays.abbreviations.tuesday, | 
					
						
							|  |  |  |         Translations.t.general.weekdays.abbreviations.wednesday, | 
					
						
							|  |  |  |         Translations.t.general.weekdays.abbreviations.thursday, | 
					
						
							|  |  |  |         Translations.t.general.weekdays.abbreviations.friday, | 
					
						
							|  |  |  |         Translations.t.general.weekdays.abbreviations.saturday, | 
					
						
							|  |  |  |         Translations.t.general.weekdays.abbreviations.sunday, | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     constructor( | 
					
						
							|  |  |  |         tags: UIEventSource<any>, | 
					
						
							|  |  |  |         state: { osmConnection?: OsmConnection }, | 
					
						
							|  |  |  |         key: string, | 
					
						
							|  |  |  |         prefix = "", | 
					
						
							|  |  |  |         postfix = "" | 
					
						
							|  |  |  |     ) { | 
					
						
							|  |  |  |         const ohTable = new VariableUiElement( | 
					
						
							|  |  |  |             tags | 
					
						
							|  |  |  |                 .map((tags) => { | 
					
						
							|  |  |  |                     const value: string = tags[key] | 
					
						
							|  |  |  |                     if (value === undefined) { | 
					
						
							|  |  |  |                         return undefined | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     if (value.startsWith(prefix) && value.endsWith(postfix)) { | 
					
						
							|  |  |  |                         return value.substring(prefix.length, value.length - postfix.length).trim() | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     return value | 
					
						
							|  |  |  |                 }) // This mapping will absorb all other changes to tags in order to prevent regeneration
 | 
					
						
							|  |  |  |                 .map((ohtext) => { | 
					
						
							|  |  |  |                     if (ohtext === undefined) { | 
					
						
							|  |  |  |                         return new FixedUiElement( | 
					
						
							|  |  |  |                             "No opening hours defined with key " + key | 
					
						
							|  |  |  |                         ).SetClass("alert") | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     try { | 
					
						
							|  |  |  |                         return OpeningHoursVisualization.CreateFullVisualisation( | 
					
						
							|  |  |  |                             OH.CreateOhObject(tags.data, ohtext) | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                     } catch (e) { | 
					
						
							|  |  |  |                         console.warn(e, e.stack) | 
					
						
							|  |  |  |                         return new Combine([ | 
					
						
							|  |  |  |                             Translations.t.general.opening_hours.error_loading, | 
					
						
							|  |  |  |                             new Toggle( | 
					
						
							|  |  |  |                                 new FixedUiElement(e).SetClass("subtle"), | 
					
						
							|  |  |  |                                 undefined, | 
					
						
							|  |  |  |                                 state?.osmConnection?.userDetails.map( | 
					
						
							|  |  |  |                                     (userdetails) => | 
					
						
							|  |  |  |                                         userdetails.csCount >= | 
					
						
							|  |  |  |                                         Constants.userJourney.tagsVisibleAndWikiLinked | 
					
						
							|  |  |  |                                 ) | 
					
						
							|  |  |  |                             ), | 
					
						
							|  |  |  |                         ]) | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 00:05:51 +02:00
										 |  |  |         super( | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             ohTable, | 
					
						
							| 
									
										
										
										
											2021-06-21 03:12:43 +02:00
										 |  |  |             Translations.t.general.opening_hours.loadingCountry.Clone(), | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             tags.map((tgs) => tgs._country !== undefined) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static CreateFullVisualisation(oh: any): BaseUIElement { | 
					
						
							|  |  |  |         /** First, we determine which range of dates we want to visualize: this week or next week?**/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const today = new Date() | 
					
						
							|  |  |  |         today.setHours(0, 0, 0, 0) | 
					
						
							|  |  |  |         const lastMonday = OH.getMondayBefore(today) | 
					
						
							|  |  |  |         const nextSunday = new Date(lastMonday) | 
					
						
							|  |  |  |         nextSunday.setDate(nextSunday.getDate() + 7) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!oh.getState() && !oh.getUnknown()) { | 
					
						
							|  |  |  |             // POI is currently closed
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const nextChange: Date = oh.getNextChange() | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             if ( | 
					
						
							|  |  |  |                 // Shop isn't gonna open anymore in this timerange
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 nextSunday < nextChange && | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |                 // And we are already in the weekend to show next week
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 (today.getDay() == 0 || today.getDay() == 6) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             ) { | 
					
						
							|  |  |  |                 // We move the range to next week!
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 lastMonday.setDate(lastMonday.getDate() + 7) | 
					
						
							|  |  |  |                 nextSunday.setDate(nextSunday.getDate() + 7) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* We calculate the ranges when it is opened! */ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const ranges = OH.GetRanges(oh, lastMonday, nextSunday) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* First, a small sanity check. The business might be permanently closed, 24/7 opened or something other special | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |          * So, we have to handle the case that ranges is completely empty*/ | 
					
						
							|  |  |  |         if (ranges.filter((range) => range.length > 0).length === 0) { | 
					
						
							|  |  |  |             return OpeningHoursVisualization.ShowSpecialCase(oh).SetClass( | 
					
						
							|  |  |  |                 "p-4 rounded-full block bg-gray-200" | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** With all the edge cases handled, we can actually construct the table! **/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return OpeningHoursVisualization.ConstructVizTable(oh, ranges, lastMonday) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private static ConstructVizTable( | 
					
						
							|  |  |  |         oh: any, | 
					
						
							|  |  |  |         ranges: { | 
					
						
							|  |  |  |             isOpen: boolean | 
					
						
							|  |  |  |             isSpecial: boolean | 
					
						
							|  |  |  |             comment: string | 
					
						
							|  |  |  |             startDate: Date | 
					
						
							|  |  |  |             endDate: Date | 
					
						
							|  |  |  |         }[][], | 
					
						
							|  |  |  |         rangeStart: Date | 
					
						
							|  |  |  |     ): BaseUIElement { | 
					
						
							|  |  |  |         const isWeekstable: boolean = oh.isWeekStable() | 
					
						
							|  |  |  |         let [changeHours, changeHourText] = OH.allChangeMoments(ranges) | 
					
						
							|  |  |  |         const today = new Date() | 
					
						
							|  |  |  |         today.setHours(0, 0, 0, 0) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // @ts-ignore
 | 
					
						
							|  |  |  |         const todayIndex = Math.ceil((today - rangeStart) / (1000 * 60 * 60 * 24)) | 
					
						
							|  |  |  |         // By default, we always show the range between 8 - 19h, in order to give a stable impression
 | 
					
						
							|  |  |  |         // Ofc, a bigger range is used if needed
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const earliestOpen = Math.min(8 * 60 * 60, ...changeHours) | 
					
						
							|  |  |  |         let latestclose = Math.max(...changeHours) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         // We always make sure there is 30m of leeway in order to give enough room for the closing entry
 | 
					
						
							|  |  |  |         latestclose = Math.max(19 * 60 * 60, latestclose + 30 * 60) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const availableArea = latestclose - earliestOpen | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |          * The OH-visualisation is a table, consisting of 8 rows and 2 columns: | 
					
						
							|  |  |  |          * The first row is a header row (which is NOT passed as header but just as a normal row!) containing empty for the first column and one object giving all the end times | 
					
						
							|  |  |  |          * The other rows are one for each weekday: the first element showing 'mo', 'tu', ..., the second element containing the bars. | 
					
						
							|  |  |  |          * Note that the bars are actually an embedded <div> spanning the full width, containing multiple sub-elements | 
					
						
							|  |  |  |          * */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const [header, headerHeight] = OpeningHoursVisualization.ConstructHeaderElement( | 
					
						
							|  |  |  |             availableArea, | 
					
						
							|  |  |  |             changeHours, | 
					
						
							|  |  |  |             changeHourText, | 
					
						
							|  |  |  |             earliestOpen | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const weekdays = [] | 
					
						
							|  |  |  |         const weekdayStyles = [] | 
					
						
							|  |  |  |         for (let i = 0; i < 7; i++) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const day = OpeningHoursVisualization.weekdays[i].Clone() | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             day.SetClass("w-full h-full block") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const rangesForDay = ranges[i].map((range) => | 
					
						
							|  |  |  |                 OpeningHoursVisualization.CreateRangeElem( | 
					
						
							|  |  |  |                     availableArea, | 
					
						
							|  |  |  |                     earliestOpen, | 
					
						
							|  |  |  |                     latestclose, | 
					
						
							|  |  |  |                     range, | 
					
						
							|  |  |  |                     isWeekstable | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             ) | 
					
						
							|  |  |  |             const allRanges = new Combine([ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 ...OpeningHoursVisualization.CreateLinesAtChangeHours( | 
					
						
							|  |  |  |                     changeHours, | 
					
						
							|  |  |  |                     availableArea, | 
					
						
							|  |  |  |                     earliestOpen | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |                 ...rangesForDay, | 
					
						
							|  |  |  |             ]).SetClass("w-full block") | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             let extraStyle = "" | 
					
						
							|  |  |  |             if (todayIndex == i) { | 
					
						
							|  |  |  |                 extraStyle = "background-color: var(--subtle-detail-color);" | 
					
						
							|  |  |  |                 allRanges.SetClass("ohviz-today") | 
					
						
							|  |  |  |             } else if (i >= 5) { | 
					
						
							|  |  |  |                 extraStyle = "background-color: rgba(230, 231, 235, 1);" | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             weekdays.push([day, allRanges]) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             weekdayStyles.push([ | 
					
						
							|  |  |  |                 "padding-left: 0.5em;" + extraStyle, | 
					
						
							|  |  |  |                 `position: relative;` + extraStyle, | 
					
						
							|  |  |  |             ]) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return new Table(undefined, [[" ", header], ...weekdays], { | 
					
						
							|  |  |  |             contentStyle: [ | 
					
						
							|  |  |  |                 ["width: 5%", `position: relative; height: ${headerHeight}`], | 
					
						
							|  |  |  |                 ...weekdayStyles, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |             .SetClass("w-full") | 
					
						
							|  |  |  |             .SetStyle( | 
					
						
							|  |  |  |                 "border-collapse: collapse; word-break; word-break: normal; word-wrap: normal" | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private static CreateRangeElem( | 
					
						
							|  |  |  |         availableArea: number, | 
					
						
							|  |  |  |         earliestOpen: number, | 
					
						
							|  |  |  |         latestclose: number, | 
					
						
							|  |  |  |         range: { | 
					
						
							|  |  |  |             isOpen: boolean | 
					
						
							|  |  |  |             isSpecial: boolean | 
					
						
							|  |  |  |             comment: string | 
					
						
							|  |  |  |             startDate: Date | 
					
						
							|  |  |  |             endDate: Date | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         isWeekstable: boolean | 
					
						
							|  |  |  |     ): BaseUIElement { | 
					
						
							|  |  |  |         const textToShow = | 
					
						
							|  |  |  |             range.comment ?? (isWeekstable ? "" : range.startDate.toLocaleDateString()) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!range.isOpen && !range.isSpecial) { | 
					
						
							|  |  |  |             return new FixedUiElement(textToShow).SetClass("ohviz-day-off") | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const startOfDay: Date = new Date(range.startDate) | 
					
						
							|  |  |  |         startOfDay.setHours(0, 0, 0, 0) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const startpoint = (range.startDate - startOfDay) / 1000 - earliestOpen | 
					
						
							| 
									
										
										
										
											2022-09-03 18:00:54 +02:00
										 |  |  |         // prettier-ignore
 | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         // @ts-ignore
 | 
					
						
							|  |  |  |         const width = (100 * (range.endDate - range.startDate) / 1000) / (latestclose - earliestOpen); | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const startPercentage = (100 * startpoint) / availableArea | 
					
						
							|  |  |  |         return new FixedUiElement(textToShow) | 
					
						
							|  |  |  |             .SetStyle(`left:${startPercentage}%; width:${width}%`) | 
					
						
							|  |  |  |             .SetClass("ohviz-range") | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private static CreateLinesAtChangeHours( | 
					
						
							|  |  |  |         changeHours: number[], | 
					
						
							|  |  |  |         availableArea: number, | 
					
						
							|  |  |  |         earliestOpen: number | 
					
						
							|  |  |  |     ): BaseUIElement[] { | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         const allLines: BaseUIElement[] = [] | 
					
						
							|  |  |  |         for (const changeMoment of changeHours) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const offset = (100 * (changeMoment - earliestOpen)) / availableArea | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             if (offset < 0 || offset > 100) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const el = new FixedUiElement("").SetStyle(`left:${offset}%;`).SetClass("ohviz-line") | 
					
						
							|  |  |  |             allLines.push(el) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return allLines | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The OH-Visualization header element, a single bar with hours | 
					
						
							|  |  |  |      * @param availableArea | 
					
						
							|  |  |  |      * @param changeHours | 
					
						
							|  |  |  |      * @param changeHourText | 
					
						
							|  |  |  |      * @param earliestOpen | 
					
						
							|  |  |  |      * @constructor | 
					
						
							|  |  |  |      * @private | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private static ConstructHeaderElement( | 
					
						
							|  |  |  |         availableArea: number, | 
					
						
							|  |  |  |         changeHours: number[], | 
					
						
							|  |  |  |         changeHourText: string[], | 
					
						
							|  |  |  |         earliestOpen: number | 
					
						
							|  |  |  |     ): [BaseUIElement, string] { | 
					
						
							|  |  |  |         let header: BaseUIElement[] = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         header.push( | 
					
						
							|  |  |  |             ...OpeningHoursVisualization.CreateLinesAtChangeHours( | 
					
						
							|  |  |  |                 changeHours, | 
					
						
							|  |  |  |                 availableArea, | 
					
						
							|  |  |  |                 earliestOpen | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         let showHigher = false | 
					
						
							|  |  |  |         let showHigherUsed = false | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         for (let i = 0; i < changeHours.length; i++) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             let changeMoment = changeHours[i] | 
					
						
							|  |  |  |             const offset = (100 * (changeMoment - earliestOpen)) / availableArea | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             if (offset < 0 || offset > 100) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             if (i > 0 && (changeMoment - changeHours[i - 1]) / (60 * 60) < 2) { | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |                 // Quite close to the previous value
 | 
					
						
							|  |  |  |                 // We alternate the heights
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 showHigherUsed = true | 
					
						
							|  |  |  |                 showHigher = !showHigher | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 showHigher = false | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const el = new Combine([ | 
					
						
							|  |  |  |                 new FixedUiElement(changeHourText[i]) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     .SetClass( | 
					
						
							|  |  |  |                         "relative bg-white pl-1 pr-1 h-3 font-sm rounded-xl border-2 border-black  border-opacity-50" | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                     .SetStyle("left: -50%; word-break:initial"), | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             ]) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 .SetStyle(`left:${offset}%;margin-top: ${showHigher ? "1.4rem;" : "0.1rem"}`) | 
					
						
							|  |  |  |                 .SetClass("block absolute top-0 m-0 h-full box-border ohviz-time-indication") | 
					
						
							|  |  |  |             header.push(el) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const headerElem = new Combine(header) | 
					
						
							|  |  |  |             .SetClass(`w-full absolute block ${showHigherUsed ? "h-16" : "h-8"}`) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             .SetStyle("margin-top: -1rem") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const headerHeight = showHigherUsed ? "4rem" : "2rem" | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         return [headerElem, headerHeight] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |      * Visualizes any special case: e.g. not open for a long time, 24/7 open, ... | 
					
						
							|  |  |  |      * */ | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     private static ShowSpecialCase(oh: any) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const opensAtDate = oh.getNextChange() | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |         if (opensAtDate === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const comm = oh.getComment() ?? oh.getUnknown() | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |             if (!!comm) { | 
					
						
							|  |  |  |                 return new FixedUiElement(comm) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (oh.getState()) { | 
					
						
							|  |  |  |                 return Translations.t.general.opening_hours.open_24_7.Clone() | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return Translations.t.general.opening_hours.closed_permanently.Clone() | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const willOpenAt = `${opensAtDate.getDate()}/${opensAtDate.getMonth() + 1} ${OH.hhmm( | 
					
						
							|  |  |  |             opensAtDate.getHours(), | 
					
						
							|  |  |  |             opensAtDate.getMinutes() | 
					
						
							|  |  |  |         )}`
 | 
					
						
							| 
									
										
										
										
											2022-09-03 18:00:54 +02:00
										 |  |  |         return Translations.t.general.opening_hours.closed_until.Subs({ date: willOpenAt }) | 
					
						
							| 
									
										
										
										
											2021-06-16 14:23:53 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-03 18:00:54 +02:00
										 |  |  | } |