From f2752383f244b9aea5901fea5d1f6c4850abc273 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Thu, 26 Feb 2026 15:26:25 +0000 Subject: [PATCH] Render UK time difference server-side and simplify trip timezone JS --- templates/trip_page.html | 28 ++---------------------- web_view.py | 46 ++++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/templates/trip_page.html b/templates/trip_page.html index e772fc6..86f4064 100644 --- a/templates/trip_page.html +++ b/templates/trip_page.html @@ -114,9 +114,9 @@ {% for item in destination_times %} - {{ item.location }} ({{ item.country_name }}) {{ item.country_flag if trip.show_flags }} + {{ item.destination_label }} {{ item.timezone or "Unknown" }} - {{ item.offset_display }} + {{ item.offset_display }} {{ item.current_time or "Unknown" }} {% endfor %} @@ -490,24 +490,6 @@ var routes = {{ routes | tojson }}; build_map("map", coordinates, routes); -function timezoneOffsetLabel(offsetMinutes) { - if (offsetMinutes === 0) { - return "No difference"; - } - const sign = offsetMinutes > 0 ? "+" : "-"; - const abs = Math.abs(offsetMinutes); - const hours = String(Math.floor(abs / 60)).padStart(2, "0"); - const minutes = String(abs % 60).padStart(2, "0"); - return `${sign}${hours}:${minutes} vs Bristol`; -} - -function getOffsetMinutes(timeZone) { - const now = new Date(); - const localInZone = new Date(now.toLocaleString("en-US", { timeZone })); - const localInBristol = new Date(now.toLocaleString("en-US", { timeZone: "Europe/London" })); - return Math.round((localInZone - localInBristol) / 60000); -} - function updateDestinationTimes() { for (const el of document.querySelectorAll(".destination-time[data-timezone]")) { const tz = el.dataset.timezone; @@ -520,12 +502,6 @@ function updateDestinationTimes() { hour12: false }).format(new Date()); } - - for (const el of document.querySelectorAll(".destination-offset[data-timezone]")) { - const tz = el.dataset.timezone; - const offset = getOffsetMinutes(tz); - el.textContent = timezoneOffsetLabel(offset); - } } updateDestinationTimes(); diff --git a/web_view.py b/web_view.py index 57cb930..b6afc9a 100755 --- a/web_view.py +++ b/web_view.py @@ -781,13 +781,13 @@ def _timezone_name_from_datetime(value: typing.Any) -> str | None: return None -def _format_offset_from_bristol(offset_minutes: int) -> str: - """Format offset from Bristol in +/-HH:MM.""" +def _format_offset_from_uk(offset_minutes: int) -> str: + """Format offset from UK in +/-HH:MM.""" if offset_minutes == 0: - return "Same time as Bristol" + return "No difference" sign = "+" if offset_minutes > 0 else "-" hours, mins = divmod(abs(offset_minutes), 60) - return f"{sign}{hours:02d}:{mins:02d} vs Bristol" + return f"{sign}{hours:02d}:{mins:02d} vs UK" def _timezone_from_coordinates(latitude: float, longitude: float) -> str | None: @@ -888,7 +888,7 @@ def get_destination_timezones(trip: Trip) -> list[StrDict]: home_offset = home_now.utcoffset() if dest_offset is not None and home_offset is not None: offset_minutes = int((dest_offset - home_offset).total_seconds() // 60) - offset_display = _format_offset_from_bristol(offset_minutes) + offset_display = _format_offset_from_uk(offset_minutes) current_time = dest_now.strftime("%a %H:%M:%S") destination_times.append( @@ -902,7 +902,41 @@ def get_destination_timezones(trip: Trip) -> list[StrDict]: } ) - return destination_times + grouped: list[StrDict] = [] + grouped_index: dict[tuple[str, str, str | None], int] = {} + for item in destination_times: + key = (item["country_name"], item["country_flag"], item["timezone"]) + if key in grouped_index: + existing = grouped[grouped_index[key]] + existing_locations = typing.cast(list[str], existing["locations"]) + existing_locations.append(typing.cast(str, item["location"])) + existing["location_count"] = ( + typing.cast(int, existing["location_count"]) + 1 + ) + continue + + grouped_index[key] = len(grouped) + grouped.append( + { + **item, + "locations": [item["location"]], + "location_count": 1, + } + ) + + for item in grouped: + location_count = typing.cast(int, item["location_count"]) + country_name = typing.cast(str, item["country_name"]) + country_flag = typing.cast(str, item["country_flag"]) + if location_count > 1: + label = f"{country_name} ({location_count} locations)" + else: + label = f"{item['location']} ({country_name})" + if trip.show_flags: + label = f"{label} {country_flag}" + item["destination_label"] = label + + return grouped @app.route("/trip/")