Skip to content

Commit

Permalink
Merge pull request #104 from soaringmeteo/no-popups
Browse files Browse the repository at this point in the history
Don’t show the location details in a popup
  • Loading branch information
julienrf committed Nov 10, 2023
2 parents 8e9fb07 + ac028e3 commit 40f8e9f
Show file tree
Hide file tree
Showing 21 changed files with 482 additions and 411 deletions.
24 changes: 11 additions & 13 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ export const start = (containerElement: HTMLElement): void => {
createEffect(() => {
const detailedView = props.domain.state.detailedView;
if (detailedView !== undefined) {
const selectedLocation = detailedView[0];
mapHooks.showMarker(selectedLocation.latitude, selectedLocation.longitude);
mapHooks.showMarker(detailedView.latitude, detailedView.longitude);
} else {
mapHooks.hideMarker();
}
Expand All @@ -76,17 +75,16 @@ export const start = (containerElement: HTMLElement): void => {
<span style={{ position: 'absolute', top: 0, left: 0, 'z-index': 200 /* must be above the “period selector” */ }}>
<Burger domain={props.domain} />
</span>
<PeriodSelectors
domain={props.domain}
/>
<LayerKeys
popupRequest={mapHooks.popupRequest}
openLocationDetailsPopup={mapHooks.openPopup}
closeLocationDetailsPopup={mapHooks.closePopup}
domain={props.domain}
/>
<span style={{ position: 'absolute', right: '.5em', bottom: '5em', 'text-align': 'right' }}>
<Help domain={props.domain} />
<PeriodSelectors domain={props.domain} locationClicks={mapHooks.locationClicks} />
<LayerKeys domain={props.domain} />
<span
style={{
position: 'absolute',
right: '.5rem',
bottom: '.5rem',
}}
>
<Help domain={props.domain} overMap={true} />
</span>
</>
}
Expand Down
33 changes: 15 additions & 18 deletions frontend/src/Burger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { surfaceOverMap } from "./styles/Styles";
import { Settings } from "./Settings";
import {LayersSelector} from "./LayersSelector";
import {OverlayContainer} from "./map/Overlay";
import hooks from "./css-hooks";

/**
* Burger menu with links to the other parts of the website.
Expand All @@ -22,7 +23,6 @@ export const Burger = (props: {
domain: Domain
}): JSX.Element => {

const state = props.domain.state;
const [expanded, setExpanded] = createSignal(false);
const [areSettingsVisible, makeSettingsVisible] = createSignal(false);

Expand Down Expand Up @@ -69,7 +69,7 @@ export const Burger = (props: {
cursor: 'auto', // otherwise we would inherit the value from the overlay container
'font-size': '0.9rem',
'max-height': '100%',
'overflow-y': 'scroll'
'overflow-y': 'auto'
}}
onClick={ e => e.stopPropagation() }
>
Expand All @@ -91,13 +91,13 @@ export const Burger = (props: {
</div>
<div
onClick={ () => setExpanded(false) }
style={{
...surfaceOverMap,
style={hooks({
...closeButton,
position: 'absolute',
top: '3px',
right: '3px'
}}
right: '3px',
hover: { 'background-color': 'darkgray' }
})}
>
</div>
Expand All @@ -118,17 +118,14 @@ export const Burger = (props: {
}
</div>;

// TODO Show the menu also when there is no detailed view
return <Show when={ state.detailedView === undefined }>
<Show when={ expanded() } fallback={ menuBtn }>
<OverlayContainer handleClick={ () => setExpanded(false) }>
{options}
</OverlayContainer>
<Settings
isVisible={ areSettingsVisible() }
close={ () => makeSettingsVisible(false) }
domain={ props.domain }
/>
</Show>
return <Show when={ expanded() } fallback={ menuBtn }>
<OverlayContainer handleClick={ () => setExpanded(false) }>
{options}
</OverlayContainer>
<Settings
isVisible={ areSettingsVisible() }
close={ () => makeSettingsVisible(false) }
domain={ props.domain }
/>
</Show>
};
24 changes: 24 additions & 0 deletions frontend/src/DetailedView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {LocationForecasts} from "./data/LocationForecasts";

export type DetailedView = Meteogram | Sounding | Summary
export type DetailedViewType = 'meteogram' | 'sounding' | 'summary'

export type Meteogram = {
viewType: 'meteogram'
locationForecasts: LocationForecasts
latitude: number
longitude: number
}

export type Sounding = {
viewType: 'sounding'
locationForecasts: LocationForecasts
latitude: number
longitude: number
}

type Summary = {
viewType: 'summary'
latitude: number
longitude: number
}
107 changes: 9 additions & 98 deletions frontend/src/LayerKeys.tsx
Original file line number Diff line number Diff line change
@@ -1,109 +1,20 @@
import {Domain} from "./State";
import {Accessor, createEffect, createResource, JSX, Show} from "solid-js";
import {toLonLat} from "ol/proj";
import {surfaceOverMap} from "./styles/Styles";
import {showCoordinates, showDate} from "./shared";
import {MapBrowserEvent} from "ol";
import {JSX} from "solid-js";

export const LayerKeys = (props: {
domain: Domain
popupRequest: Accessor<undefined | MapBrowserEvent<any>>
openLocationDetailsPopup: (latitude: number, longitude: number, content: HTMLElement) => void
closeLocationDetailsPopup: () => void
}): JSX.Element => {
const primaryLayerComponents = () => props.domain.primaryLayerReactiveComponents();
const windLayerComponents = () => props.domain.windLayerReactiveComponents();

const layerKeyEl =
<div style={{
return <div style={{
position: 'absolute',
bottom: '40px',
left: '5px',
'background-color': 'rgba(255, 255, 255, 0.5',
'font-size': '11px',
'padding': '5px',
'text-align': 'center'
bottom: '3rem',
right: '.5rem',
'background-color': 'rgba(255, 255, 255, 0.5',
'font-size': '11px',
'padding': '5px',
'text-align': 'center'
}}>
{primaryLayerComponents().mapKey}
</div>;

// Show a popup with a summary when the user clicks on the map (TODO move to another file)
createEffect(() => {
const event = props.popupRequest();
if (event === undefined) {
return
}

const state = props.domain.state;
const [eventLng, eventLat] = toLonLat(event.coordinate);
const maybePoint =
state.forecastMetadata.closestPoint(state.zone, eventLng, eventLat);
if (maybePoint === undefined) {
return
}

const [longitude, latitude] =
state.forecastMetadata.toLonLat(state.zone, maybePoint);

const summaryPromise =
state.windLayerEnabled ?
Promise.all([
primaryLayerComponents().summarizer().summary(latitude, longitude),
windLayerComponents().summarizer().summary(latitude, longitude)
])
.then(([primarySummary, windSummary]) => primarySummary?.concat(windSummary || [])) :
primaryLayerComponents().summarizer().summary(latitude, longitude);
const [summaryResource] =
createResource(() => summaryPromise.then(summary =>
summary !== undefined && summary.length !== 0 ? summary : undefined
));
const content =
<div style={{ ...surfaceOverMap, background: 'white', padding: '.7em', 'font-size': '0.8125rem', 'text-align': 'left', 'border-radius': '5px' }}>
<span
style={{ position: 'absolute', top: '2px', right: '8px', cursor: 'pointer', 'font-weight': 'bold' }}
onClick={ () => props.closeLocationDetailsPopup() }
title="Close"
>
×
</span>
<div>Grid point: { showCoordinates(longitude, latitude, props.domain.state.model) }</div>
<div>Forecast for {showDate(state.forecastMetadata.dateAtHourOffset(state.hourOffset), { showWeekDay: true, timeZone: props.domain.timeZone() })}</div>
<Show when={ summaryResource() }>
{ summary => table(summary) }
</Show>
<div style={{ display: 'flex', 'align-items': 'center', 'justify-content': 'space-around' }}>
<button
onClick={ () => props.domain.showLocationForecast(eventLat, eventLng, 'meteogram') }
title="Meteogram for this location"
>
Meteogram
</button>
<button
onClick={ () => props.domain.showLocationForecast(eventLat, eventLng, 'sounding') }
title="Sounding for this time and location"
>
Sounding
</button>
</div>
</div> as HTMLElement;
props.openLocationDetailsPopup(latitude, longitude, content);
});

return layerKeyEl
};

const table = (data: Array<[string, JSX.Element]>): JSX.Element => {
const rows =
data.map(([label, value]) => {
return <tr><th>{label}:</th><td>{value}</td></tr>
});
if (rows.length === 0) {
return <div></div>
} else {
return <table>
<tbody>
{ rows }
</tbody>
</table>;
}
</div>
};
Loading

0 comments on commit 40f8e9f

Please sign in to comment.