penguin-new-tab/lib/data-context.ts

66 lines
1.8 KiB
TypeScript
Raw Normal View History

2025-01-07 02:48:56 -05:00
import { createContext } from "react";
import wmocodes from "./wmocodes.json";
interface Weather {
temperature: number;
description: string;
image: string;
}
interface WhoisUpdate {
name: string;
time: number;
}
export type Data = {
weather?: Weather;
whois?: WhoisUpdate[];
};
export const DataContext = createContext<Data>({});
export const fetchWeather = async (): Promise<Weather> => {
const [latitude, longitude] = await new Promise<[number, number]>((res) =>
navigator.geolocation.getCurrentPosition((position) => {
res([position.coords.latitude, position.coords.longitude]);
})
);
const params = new URLSearchParams({
latitude: latitude.toString(),
longitude: longitude.toString(),
current: ["temperature_2m", "weather_code", "is_day"].join(","),
}).toString();
const url = `https://api.open-meteo.com/v1/forecast?${params}`;
return fetch(url)
.then((r) => r.json())
.then(({ current: { temperature_2m: temp, is_day, weather_code } }) => ({
temp,
wmo: wmocodes[weather_code as keyof typeof wmocodes][
is_day ? "day" : "night"
],
}))
.then(({ wmo, temp }) => ({
temperature: temp as number,
description: wmo.description,
image: wmo.image,
}));
};
export const fetchWhois = async (): Promise<WhoisUpdate[]> =>
fetch("https://whois.simponic.xyz/updates")
.then((response) => response.json())
.then(
(data) =>
data
.map((data: WhoisUpdate) => ({
...data,
time: new Date(data.time).getTime(),
}))
.sort((a: WhoisUpdate, b: WhoisUpdate) => a.time - b.time) // time should go positive from left to right
.filter((x: WhoisUpdate, i: number, arr: WhoisUpdate[]) =>
i > 0 ? x.name !== arr[i - 1].name : true
) // dedupe updates with the same name
);