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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"dev": "vite --host",
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't belong in this commit or PR.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just to help test and can be removed before the final merge

"build": "vite build",
"preview": "vite preview",
"format": "prettier --write --plugin-search-dir . .",
Expand Down
34 changes: 19 additions & 15 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import HourlyDetails from './components/HourlyDetails.svelte';
import SettingsModal from './SettingsModal.svelte';
import AboutModal from './AboutModal.svelte';
import Precipitation from './components/scalars/Precipitation.svelte';

/* Constants */
const navbarButtonClass = 'text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg text-sm p-2.5';
Expand Down Expand Up @@ -110,29 +111,32 @@

<div class="container mx-auto">
{#if weather}
<CurrentDetails current={weather.current} />
{@const { sunset_timestamp, sunrise_timestamp, precipitation_amount, precipitation_probability } = weather.daily[0]}
<CurrentDetails current={weather.current} suntimes={{ sunset_timestamp, sunrise_timestamp }} precipitation={{ precipitation_probability, precipitation_amount }} />
<div class="mx-6 mb-6">
<HourlyDetails hourly={weather.current.hourly} />
<HourlyDetails hourly={weather.current.hourly} today />
</div>
<Accordion
multiple
activeClasses="bg-gray-100 dark:bg-gray-700 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800"
inactiveClasses="hover:bg-gray-100 hover:dark:bg-gray-700"
defaultClass="mx-2 sm:mx-0"
>
{#each weather.daily as daily}
<AccordionItem class="!p-2 md:!p-4">
<span slot="header" class="w-full">
<DailySummary
current={weather.current}
{daily}
global_low={Math.min(...weather.daily.map((d) => d.temperature_low))}
global_high={Math.max(...weather.daily.map((d) => d.temperature_high))}
/>
</span>
<DailyDetails {daily} />
<HourlyDetails hourly={daily.hourly} />
</AccordionItem>
{#each weather.daily as daily, i}
{#if ($configuration.layout === 'vertical' && i) > 0 || $configuration.layout === 'horizontal'}
<AccordionItem class="!px-2 md:!px-4 py-4 md:px-8">
<span slot="header" class="w-full">
<DailySummary
current={weather.current}
{daily}
global_low={Math.min(...weather.daily.map((d) => d.temperature_low))}
global_high={Math.max(...weather.daily.map((d) => d.temperature_high))}
/>
</span>
<DailyDetails {daily} suntimes={{ sunset_timestamp, sunrise_timestamp }}/>
<HourlyDetails hourly={daily.hourly} />
</AccordionItem>
{/if}
{/each}
</Accordion>
{:else if error}
Expand Down
7 changes: 7 additions & 0 deletions src/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface Configuration {
providerParams: object;
location: Location | undefined;
units: Units;
layout: string;
title: string;
refreshInterval: number;
}
Expand All @@ -24,6 +25,7 @@ const DEFAULT_CONFIGURATION: Configuration = {
providerParams: {},
location: undefined,
units: new Intl.Locale(window.navigator.language).region === 'US' ? Units.Imperial : Units.Metric,
layout: 'horizontal',
title: '',
refreshInterval: 2 * 3600,
};
Expand All @@ -32,6 +34,7 @@ export function decodeConfiguration(params: object): Configuration {
const providerFactory = ProviderFactories.find((e) => e.id === params['provider']) || DEFAULT_CONFIGURATION.providerFactory;
const providerParams = Object.fromEntries(providerFactory.fields.map((f: { name: string }) => [f.name, params[f.name] || undefined]));
const location = Location.fromString(params['location']) || DEFAULT_CONFIGURATION.location;
const layout = params['layout'] || DEFAULT_CONFIGURATION.layout;
const title = params['title'] || DEFAULT_CONFIGURATION.title;
const units = params['units'] === 'metric' ? Units.Metric : params['units'] === 'imperial' ? Units.Imperial : DEFAULT_CONFIGURATION.units;
const refreshInterval = parseInt(params['refresh_interval']) || DEFAULT_CONFIGURATION.refreshInterval;
Expand All @@ -40,6 +43,7 @@ export function decodeConfiguration(params: object): Configuration {
providerFactory,
providerParams,
location,
layout,
title,
units,
refreshInterval,
Expand All @@ -64,6 +68,9 @@ export function encodeConfiguration(configuration: Configuration): object {
if (configuration.title !== DEFAULT_CONFIGURATION.title) {
params['title'] = configuration.title;
}
if (configuration.layout !== DEFAULT_CONFIGURATION.layout) {
params['layout'] = configuration.layout;
}
if (configuration.refreshInterval !== DEFAULT_CONFIGURATION.refreshInterval) {
params['refresh_interval'] = configuration.refreshInterval;
}
Expand Down
15 changes: 15 additions & 0 deletions src/SettingsModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
let title: string;
let refreshInterval: number;
let valid: boolean;
let layout: string;

/* Loading State for location */
let locationLoading: boolean = false;
Expand All @@ -46,6 +47,7 @@
locationMode = currentConfiguration.location ? LocationMode.Coordinates : LocationMode.Geolocation;
location = currentConfiguration.location || new Location('', '');
units = currentConfiguration.units;
layout = currentConfiguration.layout;
title = currentConfiguration.title;
refreshInterval = currentConfiguration.refreshInterval;

Expand Down Expand Up @@ -80,6 +82,7 @@
providerParams,
location: (providerFactory.requiresLocation && locationMode === LocationMode.Coordinates && location.valid() && location) || undefined,
units,
layout,
title,
refreshInterval,
};
Expand Down Expand Up @@ -164,6 +167,18 @@
/>
</div>

<div>
<Label for="select-layout" class="mb-2">Layout</Label>
<Select
id="select-layout"
items={[
{ name: 'Horizontal', value: 'horizontal' },
{ name: 'Vertical', value: 'vertical' },
]}
bind:value={layout}
/>
</div>

<div>
<Label for="input-title" class="mb-2">Title (optional)</Label>
<Input id="input-title" bind:value={title} required />
Expand Down
19 changes: 14 additions & 5 deletions src/components/CurrentDetails.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script lang="ts">
import type { CurrentWeather } from '../providers/Provider';
import Icon from '@iconify/svelte';

import type { CurrentWeather, SunTimes, DailyPrecipitation } from '../providers/Provider';

import Conditions from './scalars/Conditions.svelte';
import ConditionsIcon from './scalars/ConditionsIcon.svelte';
Expand All @@ -9,21 +11,26 @@
import UVIndex from './scalars/UVIndex.svelte';
import Distance from './scalars/Distance.svelte';
import Pressure from './scalars/Pressure.svelte';
import DailySunDetails from './DailySunDetails.svelte';
import DailyPrecipitationDetails from './DailyPrecipitationDetails.svelte';
import Precipitation from './scalars/Precipitation.svelte';

export let current: CurrentWeather;
export let suntimes: SunTimes;
export let precipitation: DailyPrecipitation;
</script>

<div class="grid grid-rows-2 grid-flow-col justify-center items-center mt-2 mb-4">
<div class="row-span-2 mr-2"><ConditionsIcon size="large" value={current.conditions_icon} /></div>
<div><span class="text-2xl sm:text-4xl font-semibold"><Temperature value={current.temperature} /> <Conditions value={current.conditions} /></span></div>
<div class="grid grid-rows-2 grid-flow-col items-center mt-2 mb-4">
<div class="row-span-2 ml-3"><ConditionsIcon size="large" value={current.conditions_icon} /></div>
<div class="mr-[110px]"><span class="text-2xl sm:text-4xl font-semibold"><Temperature value={current.temperature} /> <Conditions value={current.conditions} /></span></div>
<div class="flex gap-2">
<div><span class="font-semibold">Feels Like: </span><Temperature value={current.feels_like_temperature} /></div>
<div><span class="font-semibold">Low: </span><Temperature value={current.temperature_low} /></div>
<div><span class="font-semibold">High: </span><Temperature value={current.temperature_high} /></div>
</div>
</div>

<div class="grid grid-cols-2 md:grid-cols-none md:grid-flow-col place-items-center md:justify-center gap-2 md:gap-8 md:mx-0 mb-6">
<div class="grid grid-cols-2 md:grid-cols-none md:grid-flow-col md:place-items-center md:justify-center gap-2 md:gap-8 md:mx-0 mx-6 mt-6 mb-10">
<div><span class="font-semibold">Wind: </span><Wind speed={current.wind_speed} direction={current.wind_direction} /></div>
<div><span class="font-semibold">Humidity: </span><RelativeHumidity value={current.relative_humidity} /></div>
<div><span class="font-semibold">Dew Point: </span><Temperature value={current.dew_point_temperature} /></div>
Expand All @@ -34,4 +41,6 @@
<div><span class="font-semibold">Visibility: </span><Distance value={current.visibility} /></div>
{/if}
<div><span class="font-semibold">Pressure: </span><Pressure value={current.pressure} /></div>
<DailySunDetails {suntimes}/>
<DailyPrecipitationDetails {precipitation}/>
</div>
33 changes: 10 additions & 23 deletions src/components/DailyDetails.svelte
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
<script lang="ts">
import type { DailyWeather } from '../providers/Provider';

import Icon from '@iconify/svelte';
import type { DailyWeather, SunTimes } from '../providers/Provider';

import Conditions from './scalars/Conditions.svelte';
import Timestamp from './scalars/Timestamp.svelte';
import Amount from './scalars/Amount.svelte';
import DailyPrecipitationDetails from './DailyPrecipitationDetails.svelte';
import DailySunDetails from './DailySunDetails.svelte';

export let daily: DailyWeather;
export let suntimes: SunTimes;
</script>

<div class="grid place-items-center mb-4">
<div><span class="text-lg sm:text-xl"><Conditions value={daily.conditions} /></span></div>
</div>

<div class="grid grid-flow-col place-items-center md:auto-cols-fr gap-4 md:gap-8 mb-6">
<div>
<Icon icon="mingcute:sunrise-line" class="inline text-2xl sm:text-3xl align-bottom" />
<span class="text-sm md:text-base"><Timestamp format="short" value={daily.sunrise_timestamp} /></span>
<Icon icon="mingcute:sunset-fill" class="inline text-2xl sm:text-3xl align-bottom" />
<span class="text-sm md:text-base"><Timestamp format="short" value={daily.sunset_timestamp} /></span>
</div>
{#if daily.precipitation_probability !== undefined}
<div>
<span class="text-sm md:text-base font-semibold">Precipitation:</span> <span class="text-sm md:text-base">{daily.precipitation_probability}%</span>
</div>
{/if}
{#if daily.precipitation_amount !== undefined}
<div>
<span class="text-sm md:text-base font-semibold">Precipitation:</span>
<span class="text-sm md:text-base"><Amount value={daily.precipitation_amount} /></span>
</div>
{/if}
<div class="grid grid-cols-2 md:grid-cols-none md:grid-flow-col md:place-items-center md:justify-center gap-2 md:gap-8 ">
<DailyPrecipitationDetails precipitation={{ precipitation_probability: daily.precipitation_probability, precipitation_amount: daily.precipitation_amount }}/>
</div>

<div class="grid grid-cols-2 md:grid-cols-none md:grid-flow-col md:place-items-center md:justify-center gap-2 md:gap-8 md:mx-0 mt-3 mb-6">
<DailySunDetails {suntimes} />
</div>
24 changes: 24 additions & 0 deletions src/components/DailyPrecipitationDetails.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import type { DailyPrecipitation } from '../providers/Provider';

import Amount from './scalars/Amount.svelte';

export let precipitation: DailyPrecipitation;
</script>

{#if precipitation.precipitation_probability !== undefined && precipitation.precipitation_amount !== undefined}
<div>
<span class="text-sm md:text-base font-semibold">Precipitation:</span> <span class="text-sm md:text-base">{precipitation.precipitation_probability}%</span>
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These line indents need to be normalized. You can run npm run format to format automatically.

</div>
<div>
<span class="text-sm md:text-base font-semibold">Amount:</span> <Amount value={precipitation.precipitation_amount} />
</div>
{:else if precipitation.precipitation_probability !== undefined}
<div>
<span class="text-sm md:text-base font-semibold">Precipitation:</span> <span class="text-sm md:text-base">{precipitation.precipitation_probability}%</span>
</div>
{:else if precipitation.precipitation_amount !== undefined}
<div>
<span class="text-sm md:text-base font-semibold">Precipitation:</span> <span class="text-sm md:text-base"><Amount value={precipitation.precipitation_amount} /></span>
</div>
{/if}
18 changes: 18 additions & 0 deletions src/components/DailySunDetails.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script lang="ts">
import type { SunTimes } from '../providers/Provider';

import Icon from '@iconify/svelte';

import Timestamp from './scalars/Timestamp.svelte';

export let suntimes: SunTimes;
</script>

<div>
<span class="inline-block" style="transform:translate(-2px,-2px)"><Icon icon="mingcute:sunrise-line" class="inline text-2xl sm:text-3xl align-bottom" /></span>
<span class="font-semibold">Sunrise: </span><Timestamp format="short" value={suntimes.sunrise_timestamp} />
</div>
<div>
<span class="inline-block" style="transform:translate(-2px,-2px)"><Icon icon="mingcute:sunset-fill" class="inline text-2xl sm:text-3xl align-bottom" /></span>
<span class="font-semibold">Sunset: </span><Timestamp format="short" value={suntimes.sunset_timestamp} />
</div>
Loading