From b1aa29e87733b7d7718e74031beefa34768b7854 Mon Sep 17 00:00:00 2001 From: Brian Rogers Date: Fri, 9 Jan 2026 15:53:39 -0700 Subject: [PATCH] background now updates to reflect weather --- app/Http/Controllers/WeatherController.php | 76 ++++++++++++++++++++++ resources/js/pages/Weather.vue | 27 +++++++- 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/WeatherController.php b/app/Http/Controllers/WeatherController.php index 72f21bd..92035c4 100644 --- a/app/Http/Controllers/WeatherController.php +++ b/app/Http/Controllers/WeatherController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Models\WeatherReport; +use Illuminate\Support\Facades\File; use Inertia\Inertia; use Inertia\Response; @@ -52,6 +53,11 @@ class WeatherController extends Controller 'detailedForecast' => $period->detailed_forecast, ]); + $background = $this->getBackgroundForForecast( + $currentPeriod?->short_forecast, + $currentPeriod?->is_daytime ?? true + ); + return Inertia::render('Weather', [ 'current' => $currentPeriod ? [ 'temperature' => $currentPeriod->temperature, @@ -74,9 +80,79 @@ class WeatherController extends Controller 'name' => 'Utah County', ], 'reportedAt' => $latestHourly?->reported_at?->format('M d, Y H:i'), + 'background' => $background, ]); } + /** + * @return array{imageUrl: string|null, licenseHtml: string|null} + */ + private function getBackgroundForForecast(?string $forecast, bool $isDaytime): array + { + $folder = $this->mapForecastToFolder($forecast); + $timeOfDay = $isDaytime ? 'day' : 'night'; + $basePath = storage_path('app/public/backgrounds/'.$folder); + + if (! File::isDirectory($basePath)) { + return ['imageUrl' => null, 'licenseHtml' => null]; + } + + $files = File::files($basePath); + $pattern = '/^'.$timeOfDay.'_[a-zA-Z0-9_-]+\.jpg$/'; + + $imageFiles = collect($files) + ->filter(fn ($file) => preg_match($pattern, $file->getFilename())) + ->values(); + + if ($imageFiles->isEmpty()) { + $fallbackPattern = '/^(day|night)_[a-zA-Z0-9_-]+\.jpg$/'; + $imageFiles = collect($files) + ->filter(fn ($file) => preg_match($fallbackPattern, $file->getFilename())) + ->values(); + } + + if ($imageFiles->isEmpty()) { + return ['imageUrl' => null, 'licenseHtml' => null]; + } + + $selectedImage = $imageFiles->random(); + $imageFilename = $selectedImage->getFilename(); + $imageUrl = '/storage/backgrounds/'.$folder.'/'.$imageFilename; + + $licenseFilename = preg_replace('/\.jpg$/', '_license.html', $imageFilename); + $licensePath = $basePath.'/'.$licenseFilename; + $licenseHtml = null; + + if (File::exists($licensePath)) { + $licenseHtml = trim(File::get($licensePath)); + } + + return [ + 'imageUrl' => $imageUrl, + 'licenseHtml' => $licenseHtml, + ]; + } + + private function mapForecastToFolder(?string $forecast): string + { + if (! $forecast) { + return 'cloudy'; + } + + $forecast = strtolower($forecast); + + return match (true) { + str_contains($forecast, 'thunder') || str_contains($forecast, 'storm') => 'stormy', + str_contains($forecast, 'snow') => 'snowy', + str_contains($forecast, 'rain') || str_contains($forecast, 'shower') || str_contains($forecast, 'drizzle') => 'rainy', + str_contains($forecast, 'wind') => 'windy', + str_contains($forecast, 'sunny') || str_contains($forecast, 'clear') => 'clear', + str_contains($forecast, 'cloud') || str_contains($forecast, 'overcast') => 'cloudy', + str_contains($forecast, 'fog') || str_contains($forecast, 'mist') => 'cloudy', + default => 'cloudy', + }; + } + private function mapIconToEmoji(?string $forecast): string { if (! $forecast) { diff --git a/resources/js/pages/Weather.vue b/resources/js/pages/Weather.vue index e7e3a5d..ffb0ef5 100644 --- a/resources/js/pages/Weather.vue +++ b/resources/js/pages/Weather.vue @@ -44,12 +44,18 @@ interface Location { name: string; } +interface Background { + imageUrl: string | null; + licenseHtml: string | null; +} + const props = defineProps<{ current: CurrentWeather | null; hourlyForecast: HourlyForecast[]; weeklyForecast: WeeklyForecast[]; location: Location; reportedAt: string | null; + background: Background; }>(); const weatherIcons: Record = { @@ -88,9 +94,16 @@ function parseWindSpeed(windSpeed: string | null): number {
- -
-
+ +
+ +
+ +
@@ -277,5 +290,13 @@ function parseWindSpeed(windSpeed: string | null): number { Last updated: {{ reportedAt }}
+ + +
+ +