Skip to content

Commit

Permalink
getting rid of any
Browse files Browse the repository at this point in the history
  • Loading branch information
zdila committed Oct 25, 2024
1 parent 32ea84d commit 39dee02
Show file tree
Hide file tree
Showing 25 changed files with 181 additions and 97 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@turf/line-offset": "^7.1.0",
"@turf/line-slice": "^7.1.0",
"@turf/simplify": "^7.1.0",
"@types/pannellum": "^2.5.0",
"bootstrap": "^5.3.3",
"color": "^4.2.3",
"enzyme": "^3.11.0",
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 30 additions & 12 deletions src/components/AsyncComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import { useLazy } from 'fm3/hooks/useLazy';
import { ComponentType, ReactElement } from 'react';
import {
ComponentType,
ReactElement,
FunctionComponent,
ComponentClass,
Attributes,
} from 'react';

type Props<T extends ComponentType<any> = ComponentType<any>> =
T extends ComponentType<infer P>
? {
factory: () => Promise<{ default: T }>;
} & P
: never;
type Factory<T> = () => Promise<{ default: T }>;

export function AsyncComponent<
T extends ComponentType<any> = ComponentType<any>,
>({ factory, ...rest }: Props<T>): ReactElement | null {
const Component = useLazy(factory) as any; // TODO type
// This madness has been created with help of ChatGPT: https://chatgpt.com/share/671bee06-98f0-8007-9924-8c153485614e

return Component ? <Component {...rest} /> : null;
/* Overload for FunctionComponent with specific props */
export function AsyncComponent<P>(
props: { factory: Factory<FunctionComponent<P>> } & P & Attributes,
): ReactElement | null;

/* Overload for ComponentClass with specific props */
export function AsyncComponent<P>(
props: { factory: Factory<ComponentClass<P>> } & P & Attributes,
): ReactElement | null;

/* Implementation */
export function AsyncComponent<P>(
props: { factory: Factory<ComponentType<P>> } & P & Attributes,
): ReactElement | null {
const { factory, ...rest } = props;

const Component = useLazy(factory);

return !Component ? null : (
<Component {...(rest as unknown as P & Attributes)} />
);
}
20 changes: 15 additions & 5 deletions src/components/DrawingPointsResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { selectFeature } from 'fm3/actions/mainActions';
import { colors } from 'fm3/constants';
import { useAppSelector } from 'fm3/hooks/reduxSelectHook';
import { selectingModeSelector } from 'fm3/selectors/mainSelectors';
import { DragEndEvent } from 'leaflet';
import { DragEndEvent, LeafletEvent } from 'leaflet';
import { ReactElement, useCallback, useMemo } from 'react';
import { Tooltip } from 'react-leaflet';
import { useDispatch } from 'react-redux';
import { RichMarker } from './RichMarker';
import { is } from 'typia';

export function DrawingPointsResult(): ReactElement {
const dispatch = useDispatch();
Expand All @@ -25,10 +26,19 @@ export function DrawingPointsResult(): ReactElement {
);

const handleMove = useCallback(
// see https://github.com/PaulLeCam/react-leaflet/issues/981
({ latlng: { lat, lng: lon } }: any) => {
if (activeIndex !== null) {
dispatch(drawingPointChangePosition({ index: activeIndex, lat, lon }));
(e: LeafletEvent) => {
if (
activeIndex !== null &&
// see https://github.com/PaulLeCam/react-leaflet/issues/981
is<{ latlng: { lat: number; lng: number } }>(e)
) {
dispatch(
drawingPointChangePosition({
index: activeIndex,
lat: e.latlng.lat,
lon: e.latlng.lng,
}),
);

dispatch(drawingMeasure({ elevation: false }));
}
Expand Down
4 changes: 3 additions & 1 deletion src/components/DrawingPropertiesModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,9 @@ export function DrawingEditLabelModal({ show }: Props): ReactElement {
<Form.Control
as="select"
value={editedType}
onChange={(e) => setEditedType(e.currentTarget.value as any)}
onChange={(e) =>
setEditedType(e.currentTarget.value as 'polygon' | 'line')
}
>
<option value="line">{m?.selections.drawLines}</option>
<option value="polygon">{m?.selections.drawPolygons}</option>
Expand Down
10 changes: 6 additions & 4 deletions src/components/Hotline.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { createPathComponent, PathProps } from '@react-leaflet/core';
import { LatLngExpression } from 'leaflet';
import { Polyline } from 'leaflet';
import 'leaflet-hotline';

interface Props extends PathProps {
positions: (readonly [number, number, number])[];
positions: LatLngExpression[];
outlineWidth: number;
outlineColor?: string;
palette: Record<number, string>;
Expand All @@ -11,17 +13,17 @@ interface Props extends PathProps {
weight?: number; // TODO inherited from PathProps; should we actually extend from Path?
}

export const Hotline = createPathComponent<any, Props>(
export const Hotline = createPathComponent<Polyline, Props>(
(props, context) => {
return {
instance: (window['L'] as any).hotline(props.positions, props),
instance: (window.L as any).hotline(props.positions, props),
context,
};
},

(instance, props, prevProps) => {
if (props.positions !== prevProps.positions) {
(instance as any).setLatLngs(props.positions);
instance.setLatLngs(props.positions);
}
},
);
6 changes: 4 additions & 2 deletions src/components/Layers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { AsyncComponent } from './AsyncComponent';

const galleryLayerFactory = () => import('fm3/components/gallery/GalleryLayer');

const maplibreLayerFactory = () => import('./MaplibreLayer') as any;
const maplibreLayerFactory = () => import('./MaplibreLayer');

export function Layers(): ReactElement | null {
const overlays = useAppSelector((state) => state.map.overlays);
Expand Down Expand Up @@ -140,7 +140,9 @@ export function Layers(): ReactElement | null {
.filter(({ adminOnly }) => user?.isAdmin || !adminOnly)
.map((item) => getTileLayer(item))}
{customLayers
.filter(({ type }) => overlays.includes(type as any))
.filter(({ type }) =>
overlays.includes(type as (typeof overlays)[number]),
)
.map((cm) => getTileLayer(cm))}
</>
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/MapSettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,9 @@ export function MapSettingsModal({ show }: Props): ReactElement {
}}
/>

{(overlayLetters.includes(selectedLayer as any) ||
{(overlayLetters.includes(
selectedLayer as (typeof overlayLetters)[number],
) ||
selectedLayer.charAt(0) === ':') && (
<Form.Group className="mt-2">
<Form.Label>{m?.settings.overlayOpacity}</Form.Label>
Expand Down
5 changes: 4 additions & 1 deletion src/components/MaplibreLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import '@maplibre/maplibre-gl-leaflet';
import { createTileLayerComponent, LayerProps } from '@react-leaflet/core';
import 'fm3/maplibre-language';
import * as L from 'leaflet';
import { Map } from 'maplibre-gl';

class MaplibreWithLang extends L.MaplibreGL {
_language?: string | null;
Expand All @@ -17,7 +18,9 @@ class MaplibreWithLang extends L.MaplibreGL {
setLanguage(lang: string) {
// this._language = lang; // unnnecessary

(this.getMaplibreMap() as any).setLanguage(lang);
(
this.getMaplibreMap() as Map & { setLanguage: (lang: string) => void }
).setLanguage(lang);
}

onAdd(map: L.Map) {
Expand Down
17 changes: 12 additions & 5 deletions src/components/RichMarker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { MarkerType } from 'fm3/actions/objectsActions';
import { colors } from 'fm3/constants';
import Leaflet, { BaseIconOptions, Icon } from 'leaflet';
import { CSSProperties, ReactElement, useEffect, useMemo, useRef } from 'react';
import { createRoot } from 'react-dom/client';
import { createRoot, Root } from 'react-dom/client';
import { Marker, MarkerProps } from 'react-leaflet';
import { assertGuard } from 'typia';

const textStyle: CSSProperties = {
fill: 'rgba(0, 0, 0, 0.5)',
Expand Down Expand Up @@ -71,13 +72,19 @@ export function RichMarker({
export class MarkerLeafletIcon extends Icon<
BaseIconOptions & { icon: ReactElement }
> {
createIcon(oldIcon?: HTMLElement): HTMLElement {
createIcon(oldIcon?: HTMLElement & { _fm_root?: HTMLElement }): HTMLElement {
const reuse = oldIcon?.tagName === 'DIV';

const div = (reuse ? oldIcon : document.createElement('div')) as any;
const div = (
reuse ? oldIcon : document.createElement('div')
) as HTMLElement & { _fm_root?: Root };

if (!div._fm_root) {
(this as any)._setIconStyles(div, 'icon');
assertGuard<{ _setIconStyles: (el: HTMLElement, str: string) => void }>(
this,
);

this._setIconStyles(div, 'icon');

div._fm_root = createRoot(div);

Expand All @@ -90,7 +97,7 @@ export class MarkerLeafletIcon extends Icon<
}

createShadow(oldIcon?: HTMLElement): HTMLElement {
return oldIcon || (null as any as HTMLElement);
return oldIcon ?? document.createElement('div');
}
}

Expand Down
23 changes: 17 additions & 6 deletions src/components/RoutePlannerMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ import { TransportType, transportTypeDefs } from 'fm3/transportTypeDefs';
import {
ChangeEvent,
Children,
CSSProperties,
FormEvent,
forwardRef,
Fragment,
ReactElement,
ReactNode,
SyntheticEvent,
useCallback,
useState,
Expand Down Expand Up @@ -300,20 +302,28 @@ function IsochroneSettings() {
);
}

const GraphopperModeMenu = forwardRef<HTMLDivElement, any>(
type Props = { children: ReactNode; style: CSSProperties; className: string };

const GraphopperModeMenu = forwardRef<HTMLDivElement, Props>(
({ children, style, className }, ref) => {
return (
<div ref={ref} style={style} className={className}>
{children}

{Children.toArray(children)
.filter((item) => (item as any).props.active)
.filter(
(item): item is ReactElement =>
item &&
typeof item === 'object' &&
'props' in item &&
item.props.active,
)
.map((item) => {
return (
<Fragment key={'m-' + (item as any).props.eventKey}>
{(item as any).props.eventKey === 'roundtrip' ? (
<Fragment key={'m-' + item.props.eventKey}>
{item.props.eventKey === 'roundtrip' ? (
<TripSettings />
) : (item as any).props.eventKey === 'isochrone' ? (
) : item.props.eventKey === 'isochrone' ? (
<IsochroneSettings />
) : null}
</Fragment>
Expand Down Expand Up @@ -379,7 +389,7 @@ export function RoutePlannerMenu(): ReactElement {

break;

case 'convert-to-drawing':
case 'convert-to-drawing': {
const tolerance = window.prompt(m?.general.simplifyPrompt, '50');

if (tolerance !== null) {
Expand All @@ -392,6 +402,7 @@ export function RoutePlannerMenu(): ReactElement {
}

break;
}

case 'toggle-milestones-km':
dispatch(routePlannerToggleMilestones({ type: 'abs', toggle: true }));
Expand Down
14 changes: 6 additions & 8 deletions src/components/TrackViewerResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useNumberFormat } from 'fm3/hooks/useNumberFormat';
import { useStartFinishPoints } from 'fm3/hooks/useStartFinishPoints';
import { selectingModeSelector } from 'fm3/selectors/mainSelectors';
import { Feature, FeatureCollection, LineString, Point } from 'geojson';
import { Point as LPoint } from 'leaflet';
import { LatLngExpression, Point as LPoint } from 'leaflet';
import { Fragment, ReactElement, useState } from 'react';
import { FaFlag, FaInfo, FaPlay, FaStop } from 'react-icons/fa';
import { Polyline, Tooltip } from 'react-leaflet';
Expand Down Expand Up @@ -52,9 +52,7 @@ export function TrackViewerResult({
const [infoDistanceKm] = useState<number>();

const getFeatures: GetFeatures = (type: 'LineString' | 'Point') =>
turfFlatten(trackGeojson as any).features.filter(
(f) => f.geometry?.type === type,
) as any;
turfFlatten(trackGeojson).features.filter((f) => f.geometry?.type === type);

const getColorLineDataForElevation = () =>
getFeatures('LineString').map((feature) => {
Expand All @@ -66,10 +64,10 @@ export function TrackViewerResult({

const minEle = Math.min(...eles);

return smoothed.map((coord) => {
return smoothed.map((coord): LatLngExpression => {
const color = (coord[2] - minEle) / (maxEle - minEle);

return [coord[1], coord[0], color || 0] as const;
return [coord[1], coord[0], color || 0];
});
});

Expand All @@ -79,7 +77,7 @@ export function TrackViewerResult({

let prevCoord = smoothed[0];

return smoothed.map((coord) => {
return smoothed.map((coord): LatLngExpression => {
const [lon, lat, ele] = coord;

const d = distance([lon, lat], prevCoord, { units: 'meters' });
Expand All @@ -94,7 +92,7 @@ export function TrackViewerResult({

const color = angle / 0.5 + 0.5;

return [lat, lon, color || 0] as const;
return [lat, lon, color || 0];
});
});

Expand Down
Loading

0 comments on commit 39dee02

Please sign in to comment.