Files
Homarr/src/components/modules/weather/WeatherModule.tsx

159 lines
4.1 KiB
TypeScript
Raw Normal View History

2022-05-16 12:36:35 +02:00
import { Group, Space, Title, Tooltip } from '@mantine/core';
2022-05-15 18:52:29 +02:00
import axios from 'axios';
import { useEffect, useState } from 'react';
2022-05-15 18:52:29 +02:00
import {
2022-05-16 12:36:35 +02:00
ArrowDownRight,
ArrowUpRight,
2022-05-15 18:52:29 +02:00
Cloud,
CloudFog,
CloudRain,
CloudSnow,
CloudStorm,
QuestionMark,
Snowflake,
Sun,
} from 'tabler-icons-react';
import { IModule } from '../modules';
2022-05-16 00:23:49 +02:00
import { WeatherResponse } from './WeatherInterface';
export const WeatherModule: IModule = {
2022-05-17 21:22:14 +02:00
title: 'Weather (beta)',
description: 'Look up the current weather in your location',
2022-05-16 00:23:49 +02:00
icon: Sun,
component: WeatherComponent,
};
2022-05-15 18:52:29 +02:00
// 0 Clear sky
// 1, 2, 3 Mainly clear, partly cloudy, and overcast
// 45, 48 Fog and depositing rime fog
2022-05-16 00:23:49 +02:00
// 51, 53, 55 Drizzle: Light, moderate, and dense intensity
// 56, 57 Freezing Drizzle: Light and dense intensity
// 61, 63, 65 Rain: Slight, moderate and heavy intensity
// 66, 67 Freezing Rain: Light and heavy intensity
// 71, 73, 75 Snow fall: Slight, moderate, and heavy intensity
2022-05-15 18:52:29 +02:00
// 77 Snow grains
2022-05-16 00:23:49 +02:00
// 80, 81, 82 Rain showers: Slight, moderate, and violent
// 85, 86Snow showers slight and heavy
// 95 *Thunderstorm: Slight or moderate
// 96, 99 *Thunderstorm with slight and heavy hail
2022-05-15 18:52:29 +02:00
export function WeatherIcon(props: any) {
const { code } = props;
let data: { icon: any; name: string };
switch (code) {
case 0: {
2022-05-16 00:23:49 +02:00
data = { icon: Sun, name: 'Clear' };
2022-05-15 18:52:29 +02:00
break;
}
case 1:
case 2:
case 3: {
2022-05-16 00:23:49 +02:00
data = { icon: Cloud, name: 'Mainly clear' };
2022-05-15 18:52:29 +02:00
break;
}
case 45:
case 48: {
2022-05-16 00:23:49 +02:00
data = { icon: CloudFog, name: 'Fog' };
2022-05-15 18:52:29 +02:00
break;
}
case 51:
case 53:
case 55: {
2022-05-16 00:23:49 +02:00
data = { icon: Cloud, name: 'Drizzle' };
2022-05-15 18:52:29 +02:00
break;
}
case 56:
case 57: {
2022-05-16 00:23:49 +02:00
data = { icon: Snowflake, name: 'Freezing drizzle' };
2022-05-15 18:52:29 +02:00
break;
}
case 61:
case 63:
case 65: {
2022-05-16 00:23:49 +02:00
data = { icon: CloudRain, name: 'Rain' };
2022-05-15 18:52:29 +02:00
break;
}
case 66:
case 67: {
2022-05-16 00:23:49 +02:00
data = { icon: CloudRain, name: 'Freezing rain' };
2022-05-15 18:52:29 +02:00
break;
}
case 71:
case 73:
case 75: {
2022-05-16 00:23:49 +02:00
data = { icon: CloudSnow, name: 'Snow fall' };
2022-05-15 18:52:29 +02:00
break;
}
case 77: {
2022-05-16 00:23:49 +02:00
data = { icon: CloudSnow, name: 'Snow grains' };
2022-05-15 18:52:29 +02:00
break;
}
case 80:
case 81:
case 82: {
2022-05-16 00:23:49 +02:00
data = { icon: CloudRain, name: 'Rain showers' };
2022-05-15 18:52:29 +02:00
break;
}
case 85:
case 86: {
2022-05-16 00:23:49 +02:00
data = { icon: CloudSnow, name: 'Snow showers' };
2022-05-15 18:52:29 +02:00
break;
}
case 95: {
2022-05-16 00:23:49 +02:00
data = { icon: CloudStorm, name: 'Thunderstorm' };
2022-05-15 18:52:29 +02:00
break;
}
case 96:
case 99: {
2022-05-16 00:23:49 +02:00
data = { icon: CloudStorm, name: 'Thunderstorm with hail' };
2022-05-15 18:52:29 +02:00
break;
}
default: {
2022-05-16 00:23:49 +02:00
data = { icon: QuestionMark, name: 'Unknown' };
2022-05-15 18:52:29 +02:00
}
}
2022-05-16 00:23:49 +02:00
return (
<Tooltip label={data.name}>
<data.icon size={50} />
</Tooltip>
);
2022-05-15 18:52:29 +02:00
}
export default function WeatherComponent(props: any) {
2022-05-15 18:52:29 +02:00
// Get location from browser
const [location, setLocation] = useState({ lat: 0, lng: 0 });
const [weather, setWeather] = useState({} as WeatherResponse);
if ('geolocation' in navigator && location.lat === 0 && location.lng === 0) {
navigator.geolocation.getCurrentPosition((position) => {
setLocation({ lat: position.coords.latitude, lng: position.coords.longitude });
});
}
useEffect(() => {
2022-05-15 18:52:29 +02:00
axios
.get(
`https://api.open-meteo.com/v1/forecast?latitude=${location.lat}&longitude=${location.lng}&daily=weathercode,temperature_2m_max,temperature_2m_min&current_weather=true&timezone=Europe%2FLondon`
)
.then((res) => {
setWeather(res.data);
});
}, []);
2022-05-15 18:52:29 +02:00
if (!weather.current_weather) {
return null;
}
return (
2022-05-16 00:23:49 +02:00
<Group position="left" direction="column">
2022-05-15 18:52:29 +02:00
<Title>{weather.current_weather.temperature}°C</Title>
2022-05-16 12:36:35 +02:00
<Group spacing={0}>
2022-05-16 00:23:49 +02:00
<WeatherIcon code={weather.current_weather.weathercode} />
2022-05-16 12:36:35 +02:00
<Space mx="sm" />
<span>{weather.daily.temperature_2m_max[0]}°C</span>
<ArrowUpRight size={16} style={{ right: 15 }} />
<Space mx="sm" />
<span>{weather.daily.temperature_2m_min[0]}°C</span>
<ArrowDownRight size={16} />
2022-05-16 00:23:49 +02:00
</Group>
</Group>
);
}