feat: add local time and peak temp time to city list sidebar
This commit is contained in:
+41
-14
@@ -119,11 +119,18 @@ function buildCityList(cities) {
|
|||||||
sorted.forEach((city) => {
|
sorted.forEach((city) => {
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
div.className = "city-item";
|
div.className = "city-item";
|
||||||
div.id = `city-item-${city.name.replace(/\s/g, "-")}`;
|
const cityId = city.name.replace(/\s/g, "-");
|
||||||
|
div.id = `city-item-${cityId}`;
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<span class="risk-dot ${city.risk_level}"></span>
|
<div class="city-item-main">
|
||||||
<span class="city-name-text">${city.display_name}</span>
|
<span class="risk-dot ${city.risk_level}"></span>
|
||||||
<span class="city-temp" id="temp-${city.name.replace(/\s/g, "-")}">—</span>
|
<span class="city-name-text">${city.display_name}</span>
|
||||||
|
<span class="city-temp" id="temp-${cityId}">—</span>
|
||||||
|
</div>
|
||||||
|
<div class="city-item-info">
|
||||||
|
<span class="city-local-time" id="time-${cityId}"></span>
|
||||||
|
<span class="city-max-info" id="max-${cityId}"></span>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
div.addEventListener("click", () => {
|
div.addEventListener("click", () => {
|
||||||
loadCityDetail(city.name);
|
loadCityDetail(city.name);
|
||||||
@@ -145,12 +152,32 @@ function setActiveCityItem(cityName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCityListTemp(cityName, temp, symbol) {
|
function updateCityListInfo(cityData) {
|
||||||
const id = `temp-${cityName.replace(/\s/g, "-")}`;
|
const cityName = cityData.name;
|
||||||
const el = document.getElementById(id);
|
const cityId = cityName.replace(/\s/g, "-");
|
||||||
if (el) {
|
const temp =
|
||||||
el.textContent = `${temp}${symbol}`;
|
cityData.current?.max_so_far != null &&
|
||||||
el.classList.add("loaded");
|
cityData.current.max_so_far >= (cityData.current.temp || -999)
|
||||||
|
? cityData.current.max_so_far
|
||||||
|
: cityData.current.temp;
|
||||||
|
|
||||||
|
// Update Temperature
|
||||||
|
const tempEl = document.getElementById(`temp-${cityId}`);
|
||||||
|
if (tempEl && temp != null) {
|
||||||
|
tempEl.textContent = `${temp}${cityData.temp_symbol}`;
|
||||||
|
tempEl.classList.add("loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Local Time
|
||||||
|
const timeEl = document.getElementById(`time-${cityId}`);
|
||||||
|
if (timeEl && cityData.local_time) {
|
||||||
|
timeEl.textContent = `🕐 ${cityData.local_time}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Max Temp Time
|
||||||
|
const maxEl = document.getElementById(`max-${cityId}`);
|
||||||
|
if (maxEl && cityData.current?.max_temp_time) {
|
||||||
|
maxEl.textContent = `峰值 @${cityData.current.max_temp_time}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +215,7 @@ async function loadCityDetail(cityName) {
|
|||||||
const data = await fetchCityDetail(cityName);
|
const data = await fetchCityDetail(cityName);
|
||||||
cityDataCache[cityName] = data;
|
cityDataCache[cityName] = data;
|
||||||
renderPanel(data);
|
renderPanel(data);
|
||||||
// Update marker temperature
|
// Update marker and list
|
||||||
if (data.current?.temp != null) {
|
if (data.current?.temp != null) {
|
||||||
const displayTemp =
|
const displayTemp =
|
||||||
data.current.max_so_far != null &&
|
data.current.max_so_far != null &&
|
||||||
@@ -196,7 +223,7 @@ async function loadCityDetail(cityName) {
|
|||||||
? data.current.max_so_far
|
? data.current.max_so_far
|
||||||
: data.current.temp;
|
: data.current.temp;
|
||||||
updateMarkerTemp(cityName, displayTemp);
|
updateMarkerTemp(cityName, displayTemp);
|
||||||
updateCityListTemp(cityName, displayTemp, data.temp_symbol);
|
updateCityListInfo(data);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Failed to load ${cityName}:`, e);
|
console.error(`Failed to load ${cityName}:`, e);
|
||||||
@@ -695,7 +722,7 @@ function startAutoRefresh() {
|
|||||||
? data.current.max_so_far
|
? data.current.max_so_far
|
||||||
: data.current.temp;
|
: data.current.temp;
|
||||||
updateMarkerTemp(selectedCity, displayTemp);
|
updateMarkerTemp(selectedCity, displayTemp);
|
||||||
updateCityListTemp(selectedCity, displayTemp, data.temp_symbol);
|
updateCityListInfo(data);
|
||||||
}
|
}
|
||||||
flashLiveBadge();
|
flashLiveBadge();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -738,7 +765,7 @@ async function loadAllCitiesProgressively(cities) {
|
|||||||
? data.current.max_so_far
|
? data.current.max_so_far
|
||||||
: data.current.temp;
|
: data.current.temp;
|
||||||
updateMarkerTemp(city.name, displayTemp);
|
updateMarkerTemp(city.name, displayTemp);
|
||||||
updateCityListTemp(city.name, displayTemp, data.temp_symbol);
|
updateCityListInfo(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果恰好在这个时候用户选中了这个城市,顺便刷新面板
|
// 如果恰好在这个时候用户选中了这个城市,顺便刷新面板
|
||||||
|
|||||||
+41
-7
@@ -281,28 +281,62 @@ body {
|
|||||||
|
|
||||||
.city-item {
|
.city-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 4px;
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: var(--transition);
|
transition: var(--transition);
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: var(--text-secondary);
|
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
.city-item:hover {
|
.city-item:hover {
|
||||||
background: rgba(99, 102, 241, 0.08);
|
background: rgba(99, 102, 241, 0.08);
|
||||||
color: var(--text-primary);
|
|
||||||
border-color: var(--border-glass);
|
border-color: var(--border-glass);
|
||||||
}
|
}
|
||||||
.city-item.active {
|
.city-item.active {
|
||||||
background: rgba(99, 102, 241, 0.15);
|
background: rgba(99, 102, 241, 0.15);
|
||||||
color: var(--text-primary);
|
|
||||||
border-color: var(--accent-blue);
|
border-color: var(--accent-blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.city-item-main {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.city-item .city-name-text {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.city-item .city-temp {
|
||||||
|
margin-left: auto;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--accent-cyan);
|
||||||
|
opacity: 0;
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
.city-item .city-temp.loaded {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.city-item-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 16px; /* Align with name text, after the dot */
|
||||||
|
font-size: 10px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.city-item .city-max-info {
|
||||||
|
color: var(--accent-blue);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
.city-item .risk-dot {
|
.city-item .risk-dot {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
|
|||||||
Reference in New Issue
Block a user