Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 34 additions & 28 deletions bun.lock

Large diffs are not rendered by default.

92 changes: 48 additions & 44 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,64 +11,68 @@
reference-width="1920"
reference-height="1080"
orientation="auto"
padding="0"
>
<div id="app">
<app-header class="header" show-date></app-header>
<main class="weather" id="weather">
<header class="weather-header">
<p class="weather-date" data-date></p>
<div class="weather-brand">
<span class="weather-clock" data-clock>--:--</span>
<img class="weather-logo" data-logo alt="" />
</div>
</header>

<main class="content">
<section class="current-weather">
<div class="city" data-location>--</div>
<div class="temperature-display" data-temperature>--°</div>
<div class="status-pill">
<span class="weather-description" data-weather-description></span>
<div class="hi-lo">
<span class="hi">↑ <span data-temp-high>--°</span></span>
<span class="lo">↓ <span data-temp-low>--°</span></span>
</div>
</div>
<div class="middle">
<section class="now">
<p class="now-place" data-location>--</p>
<p class="now-temp" data-temperature>--°</p>
<p class="now-condition">
<span class="now-description" data-weather-description></span>
<span class="now-range">
<span class="now-high" data-temp-high>--°</span>
<span class="now-low" data-temp-low>--°</span>
</span>
</p>
</section>

<section class="forecast-card" data-forecast-card>
<div class="forecast-header">
<img
class="forecast-header-icon"
data-forecast-header-icon
alt=""
/>
<span>Forecast by Hour</span>
</div>
<div class="forecast-divider"></div>
<div class="forecast-items" data-forecast-items></div>
</section>
</main>

<div id="error-screen" style="display: none">
<div class="error-card">
<div class="error-card-left">
<h2>Something went wrong</h2>
<p>
The weather data could not be loaded. Please check your
configuration or contact your administrator.
<section class="trend" data-trend>
<div class="trend-plot">
<svg
class="trend-chart"
data-trend-chart
viewBox="0 0 100 40"
role="img"
aria-label="Temperature through the day"
></svg>
<p class="trend-scale">
<span class="trend-scale-high" data-trend-high></span>
<span class="trend-scale-low" data-trend-low></span>
</p>
</div>
<div class="error-card-right">
<div class="error-detail-label">Error details</div>
<p id="error-message" class="error-detail-message"></p>
</div>
</div>
</section>
</div>
</div>

<section class="forecast" data-forecast-card>
<h2 class="forecast-label">Next hours</h2>
<ul class="forecast-items" data-forecast-items></ul>
</section>

<section class="weather-error" data-error-screen>
<h2>Weather unavailable</h2>
<p data-error-message></p>
</section>
</main>
</auto-scaler>

<template id="forecast-item-template">
<div class="forecast-item">
<span class="forecast-item-temp"></span>
<img class="forecast-item-icon" alt="" />
<li class="forecast-item">
<span class="forecast-item-time">
<span class="forecast-item-time-value"></span>
<span class="forecast-item-time-period"></span>
</span>
</div>
<img class="forecast-item-icon" alt="" />
<span class="forecast-item-temp"></span>
</li>
</template>

<script type="module" src="/src/main.ts"></script>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"dependencies": {},
"prettier": "./.prettierrc.json",
"devDependencies": {
"@screenly/edge-apps": "^1.2.1",
"@screenly/edge-apps": "^1.5.0",
"@playwright/test": "^1.60.0",
"@types/bun": "^1.3.14",
"@types/jsdom": "^28.0.3",
Expand Down
Binary file added screenshots/1080x1920.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/1280x720.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/1920x1080.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/2160x3840.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/2160x4096.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/3840x2160.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/4096x2160.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/480x800.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/720x1280.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/800x480.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/no-api-key-2160x3840.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/no-api-key-3840x2160.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions src/background.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, test } from 'bun:test'
import { getBackgroundForWeatherId } from './background'

describe('getBackgroundForWeatherId', () => {
test('treats thunderstorm, drizzle and rain as rainy', () => {
expect(getBackgroundForWeatherId(200)).toBe('rainy')
expect(getBackgroundForWeatherId(300)).toBe('rainy')
expect(getBackgroundForWeatherId(500)).toBe('rainy')
expect(getBackgroundForWeatherId(599)).toBe('rainy')
})

test('treats the 6xx range as snow', () => {
expect(getBackgroundForWeatherId(600)).toBe('snow')
expect(getBackgroundForWeatherId(699)).toBe('snow')
})

test('treats a clear sky as sunny', () => {
expect(getBackgroundForWeatherId(800)).toBe('sunny')
})

test('falls back to cloudy for atmosphere, clouds and anything unknown', () => {
expect(getBackgroundForWeatherId(701)).toBe('cloudy')
expect(getBackgroundForWeatherId(804)).toBe('cloudy')
expect(getBackgroundForWeatherId(0)).toBe('cloudy')
})
})
44 changes: 14 additions & 30 deletions src/background.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,24 @@
import bgSunny from '../static/images/bg-sunny.webp'
import bgCloudy from '../static/images/bg-cloudy.webp'
import bgRainy from '../static/images/bg-rainy.webp'
import bgSnow from '../static/images/bg-snow.webp'

// OpenWeatherMap weather condition codes:
// https://openweathermap.org/weather-conditions
//
// 2xx: Thunderstorm
// 3xx: Drizzle
// 5xx: Rain
// 6xx: Snow
// 7xx: Atmosphere (mist, fog, etc.)
// 800: Clear
// 80x: Clouds
function getBackgroundForWeatherId(weatherId: number): string {
if (weatherId >= 200 && weatherId < 600) {
return bgRainy
}

if (weatherId >= 600 && weatherId < 700) {
return bgSnow
}
// 2xx: Thunderstorm, 3xx: Drizzle, 5xx: Rain, 6xx: Snow,
// 7xx: Atmosphere (mist, fog), 800: Clear, 80x: Clouds
export const BACKGROUNDS = ['sunny', 'cloudy', 'rainy', 'snow'] as const

if (weatherId >= 700 && weatherId < 800) {
return bgCloudy
}
export type Background = (typeof BACKGROUNDS)[number]

if (weatherId === 800) {
return bgSunny
}
export function getBackgroundForWeatherId(weatherId: number): Background {
if (weatherId >= 200 && weatherId < 600) return 'rainy'
if (weatherId >= 600 && weatherId < 700) return 'snow'
if (weatherId === 800) return 'sunny'

// 80x: Clouds
return bgCloudy
return 'cloudy'
}

export function updateBackground(weatherId: number): void {
const bg = getBackgroundForWeatherId(weatherId)
document.body.style.backgroundImage = `url('${bg}')`
const background = getBackgroundForWeatherId(weatherId)

BACKGROUNDS.forEach((candidate) =>
document.body.classList.toggle(`bg-${candidate}`, candidate === background),
)
}
Loading