Skip to content

Commit

Permalink
Upgrades and improvements to caching for the accessibility tool (#1318)
Browse files Browse the repository at this point in the history
* chore: package upgrade

* feat: start the switch to use the apollo client cache instead of constructing our own list

* feat: load only loos in the viewport and fix endless loop in effect

* fix: typings for marker cluster group not imported correctly from @types

* fix: fix layout of about and contact pages

* fix: the build

* feat: improve LOD selection

* feat: make the LOD better by ungrouping at higher zoomlevels

* fix: verification support submit

* feat: get filters working properly with accessibility layer

* feat: add toilet checklist and volunteer guide back

* fix: load fa css early, add icon to priority

* feat: prefetch on mouseover
  • Loading branch information
ob6160 committed Apr 17, 2022
1 parent 89bd6e4 commit c9e99ef
Show file tree
Hide file tree
Showing 22 changed files with 1,093 additions and 772 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.json
@@ -1,10 +1,10 @@
{
"parser": "@typescript-eslint/parser",
"extends": [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
"plugin:jsx-a11y/recommended",
"plugin:functional/no-mutations"
"plugin:functional/no-mutations",
"next"
],
"parserOptions": {
"ecmaFeatures": {
Expand Down
38 changes: 19 additions & 19 deletions package.json
Expand Up @@ -30,7 +30,7 @@
},
"dependencies": {
"@apollo/client": "^3.5.10",
"@artsy/fresnel": "^3.4.1",
"@artsy/fresnel": "^3.5.0",
"@auth0/nextjs-auth0": "^1.7.0",
"@emotion/is-prop-valid": "^1.1.2",
"@emotion/react": "^11.9.0",
Expand All @@ -40,8 +40,8 @@
"@fortawesome/free-regular-svg-icons": "^6.1.1",
"@fortawesome/free-solid-svg-icons": "^6.1.1",
"@fortawesome/react-fontawesome": "^0.1.18",
"@graphql-tools/schema": "^8.3.7",
"@graphql-tools/utils": "^8.6.6",
"@graphql-tools/schema": "^8.3.9",
"@graphql-tools/utils": "^8.6.8",
"@hookform/error-message": "^2.0.0",
"@rehooks/component-size": "^1.0.3",
"@styled-system/prop-types": "^5.1.5",
Expand All @@ -54,7 +54,7 @@
"deepmerge": "^4.2.2",
"downshift": "^6.1.7",
"focus-visible": "^5.2.0",
"framer-motion": "^6.2.10",
"framer-motion": "^6.3.0",
"graphql": "^15.8.0",
"graphql-iso-date": "^3.6.1",
"graphql-voyager": "^1.0.0-rc.31",
Expand All @@ -65,7 +65,7 @@
"leaflet.markercluster": "^1.5.3",
"lodash": "^4.17.21",
"micro": "^9.3.4",
"mongoose": "^6.2.10",
"mongoose": "^6.3.0",
"mongoose-paginate": "^5.0.3",
"next": "^12.1.5",
"next-plausible": "^3.1.9",
Expand Down Expand Up @@ -93,23 +93,22 @@
"@graphql-codegen/typescript-react-apollo": "^3.2.11",
"@mapbox/geojson-area": "^0.2.2",
"@mapbox/geojson-rewind": "^0.5.1",
"@storybook/addon-actions": "^6.5.0-alpha.61",
"@storybook/addon-essentials": "^6.5.0-alpha.61",
"@storybook/addon-interactions": "^6.5.0-alpha.61",
"@storybook/addon-links": "^6.5.0-alpha.61",
"@storybook/addon-actions": "^6.5.0-alpha.63",
"@storybook/addon-essentials": "^6.5.0-alpha.63",
"@storybook/addon-interactions": "^6.5.0-alpha.63",
"@storybook/addon-links": "^6.5.0-alpha.63",
"@storybook/addon-postcss": "^2.0.0",
"@storybook/builder-webpack5": "^6.5.0-alpha.61",
"@storybook/manager-webpack5": "^6.5.0-alpha.61",
"@storybook/react": "^6.5.0-alpha.61",
"@storybook/testing-library": "^0.0.9",
"@storybook/builder-webpack5": "^6.5.0-alpha.63",
"@storybook/manager-webpack5": "^6.5.0-alpha.63",
"@storybook/react": "^6.5.0-alpha.63",
"@types/jest": "^27.4.1",
"@types/leaflet": "^1.7.9",
"@types/leaflet.markercluster": "^1.4.6",
"@types/lodash": "^4.14.181",
"@types/ngeohash": "^0.6.4",
"@types/node": "^17.0.23",
"@types/react": "^18.0.3",
"@types/react-dom": "^18.0.0",
"@types/node": "^17.0.24",
"@types/react": "^18.0.5",
"@types/react-dom": "^18.0.1",
"@types/react-leaflet": "^2.8.2",
"@types/styled-system": "^5.1.15",
"@typescript-eslint/eslint-plugin": "^5.19.0",
Expand All @@ -122,20 +121,21 @@
"eslint-config-next": "^12.1.5",
"eslint-plugin-functional": "^4.2.1",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-storybook": "^0.5.8",
"eslint-plugin-react-hooks": "^4.4.0",
"eslint-plugin-storybook": "^0.5.10",
"geojson-precision": "^1.0.0",
"graphql-codegen-apollo-next-ssr": "^1.7.1",
"husky": "^7.0.4",
"jest": "^27.5.1",
"lint-staged": "^12.3.7",
"lint-staged": "^12.3.8",
"migrate-mongo": "^9.0.0",
"prettier": "^2.6.2",
"storybook-addon-apollo-client": "^4.0.11",
"storybook-addon-next": "^1.6.2",
"topojson-server": "^3.0.1",
"topojson-simplify": "^3.0.3",
"typescript": "^4.6.3",
"webpack": "^5.x.x"
"webpack": "^5.72.0"
},
"browser": {
"fs": false,
Expand Down
Binary file added public/GBPTM.Toilet.Checklist.pdf
Binary file not shown.
Binary file added public/Toilet.Map.Volunteer.Help.Guide.pdf
Binary file not shown.
209 changes: 209 additions & 0 deletions src/@types/clusterGroup.d.ts
@@ -0,0 +1,209 @@
// Type definitions for Leaflet.markercluster 1.4
// Project: https://github.com/Leaflet/Leaflet.markercluster
// Definitions by: Robert Imig <https://github.com/rimig>, Nenad Filipovic <https://github.com/nenadfilipovic>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3

declare namespace L {
class MarkerCluster extends Marker {
/*
* Recursively retrieve all child markers of this cluster.
*/
getAllChildMarkers(): Marker[];

/*
* Returns the count of how many child markers we have.
*/
getChildCount(): number;

/*
* Zoom to the minimum of showing all of the child markers, or the extents of this cluster.
*/
zoomToBounds(options?: FitBoundsOptions): void;

/*
* Returns the cluster bounds.
*/
getBounds(): LatLngBounds;

/*
* Spiderfies the child markers of this cluster.
*/
spiderfy(): void;

/*
* Unspiderfies a cluster (opposite of spiderfy).
*/
unspiderfy(): void;
}

interface MarkerClusterGroupOptions extends LayerOptions {
/*
* When you mouse over a cluster it shows the bounds of its markers.
*/
showCoverageOnHover?: boolean | undefined;

/*
* When you click a cluster we zoom to its bounds.
*/
zoomToBoundsOnClick?: boolean | undefined;

/*
* When you click a cluster at the bottom zoom level we spiderfy it
* so you can see all of its markers.
*/
spiderfyOnMaxZoom?: boolean | undefined;

/*
* Clusters and markers too far from the viewport are removed from the map
* for performance.
*/
removeOutsideVisibleBounds?: boolean | undefined;

/*
* Smoothly split / merge cluster children when zooming and spiderfying.
* If L.DomUtil.TRANSITION is false, this option has no effect (no animation is possible).
*/
animate?: boolean | undefined;

/*
* If set to true (and animate option is also true) then adding individual markers to the
* MarkerClusterGroup after it has been added to the map will add the marker and animate it
* into the cluster. Defaults to false as this gives better performance when bulk adding markers.
* addLayers does not support this, only addLayer with individual Markers.
*/
animateAddingMarkers?: boolean | undefined;

/*
* If set, at this zoom level and below markers will not be clustered. This defaults to disabled.
*/
disableClusteringAtZoom?: number | undefined;

/*
* The maximum radius that a cluster will cover from the central marker (in pixels). Default 80.
* Decreasing will make more, smaller clusters. You can also use a function that accepts
* the current map zoom and returns the maximum cluster radius in pixels
*/
maxClusterRadius?: number | ((zoom: number) => number) | undefined;

/*
* Options to pass when creating the L.Polygon(points, options) to show the bounds of a cluster.
* Defaults to empty
*/
polygonOptions?: PolylineOptions | undefined;

/*
* If set to true, overrides the icon for all added markers to make them appear as a 1 size cluster.
*/
singleMarkerMode?: boolean | undefined;

/*
* Allows you to specify PolylineOptions to style spider legs.
* By default, they are { weight: 1.5, color: '#222', opacity: 0.5 }.
*/
spiderLegPolylineOptions?: PolylineOptions | undefined;

/*
* Increase from 1 to increase the distance away from the center that spiderfied markers are placed.
* Use if you are using big marker icons (Default: 1).
*/
spiderfyDistanceMultiplier?: number | undefined;

/*
* Function used to create the cluster icon
*/
iconCreateFunction?:
| ((cluster: MarkerCluster) => Icon | DivIcon)
| undefined;

/*
* Map pane where the cluster icons will be added.
* Defaults to L.Marker's default (currently 'markerPane')
*/
clusterPane?: string | undefined;

/*
* Boolean to split the addLayers processing in to small intervals so that the page does not freeze.
*/
chunkedLoading?: boolean | undefined;

/*
* Time delay (in ms) between consecutive periods of processing for addLayers. Default to 50ms.
*/
chunkDelay?: number | undefined;

/*
* Time interval (in ms) during which addLayers works before pausing to let the rest of the page process.
* In particular, this prevents the page from freezing while adding a lot of markers. Defaults to 200ms.
*/
chunkInterval?: number | undefined;

/*
* Callback function that is called at the end of each chunkInterval.
* Typically used to implement a progress indicator. Defaults to null.
*/
chunkProgress?:
| ((
processedMarkers: number,
totalMarkers: number,
elapsedTime: number
) => void)
| undefined;
}

class MarkerClusterGroup extends FeatureGroup {
constructor(options?: MarkerClusterGroupOptions);

/*
* Bulk methods for adding and removing markers and should be favoured over the
* single versions when doing bulk addition/removal of markers.
*/
addLayers(layers: Layer[], skipLayerAddEvent?: boolean): this;

removeLayers(layers: Layer[]): this;

clearLayers(): this;

/*
* If you have a marker in your MarkerClusterGroup and you want to get the visible
* parent of it
*/
getVisibleParent(marker: Marker): Marker;

/*
* If you have customized the clusters icon to use some data from the contained markers,
* and later that data changes, use this method to force a refresh of the cluster icons.
*/
refreshClusters(
clusters?: Marker | Marker[] | LayerGroup | { [index: string]: Layer }
): this;

/*
* Returns the total number of markers contained within that cluster.
*/
getChildCount(): number;

/*
* Returns the array of total markers contained within that cluster.
*/
getAllChildMarkers(): Marker[];

/*
* Returns true if the given layer (marker) is in the cluster.
*/
hasLayer(layer: Layer): boolean;

/*
* Zooms to show the given marker (spiderfying if required),
* calls the callback when the marker is visible on the map.
*/
zoomToShowLayer(layer: Layer, callback?: () => void): void;
}

/*
* Create a marker cluster group, optionally given marker cluster group options.
*/
function markerClusterGroup(
options?: MarkerClusterGroupOptions
): MarkerClusterGroup;
}
28 changes: 3 additions & 25 deletions src/api-client/withApollo.tsx
Expand Up @@ -71,33 +71,11 @@ function createApolloClient() {

/**
* The big trick here is to merge the initialState from the pageprops with the client's current state see: https://developers.wpengine.com/blog/apollo-client-cache-rehydration-in-next-js
* When we don't do theis the accumulates apolloState gets wiped out by any incoming static page props
* When we don't do the is the accumulates apolloState gets wiped out by any incoming static page props
*/
export function getApolloClient(
initialState: NormalizedCacheObject | null = null
) {
export function getApolloClient() {
const _apolloClient = apolloClient ?? createApolloClient();

// If a page has Next.js data fetching methods that use Apollo Client, the initial state
// gets hydrated here
if (initialState) {
// Get existing cache, loaded during client side data fetching
const existingCache = _apolloClient.extract();

// Merge the existing cache into data passed from getStaticProps/getServerSideProps
// const data = merge(initialState, existingCache, {
// arrayMerge: (destinationArray, sourceArray) => [
// ...sourceArray,
// ...destinationArray.filter((d) =>
// sourceArray.every((s) => !isEqual(d, s))
// ),
// ],
// });

// Restore the cache with the merged data
_apolloClient.cache.restore(existingCache);
}

// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient;

Expand All @@ -110,7 +88,7 @@ export function getApolloClient(
export const withApollo = (Comp: NextPage) =>
function ApolloWrapper(props: unknown) {
return (
<ApolloProvider client={getApolloClient(props.apolloState)}>
<ApolloProvider client={getApolloClient()}>
<Comp {...props} />
</ApolloProvider>
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/Logo/Logo.tsx
Expand Up @@ -5,12 +5,13 @@ import Box from '../Box';
import logo from '../../../public/logo.svg';

const Logo = React.forwardRef<HTMLDivElement>((props, ref) => (
<Box width="150px" ref={ref}>
<Box width="154px" ref={ref}>
<Image
src={logo}
alt="The Great British Toilet Map"
layout="responsive"
unoptimized={!!process.env.STORYBOOK}
priority={true}
{...props}
/>
</Box>
Expand Down

0 comments on commit c9e99ef

Please sign in to comment.