diff --git a/.vscode/settings.json b/.vscode/settings.json
index d1c54d0..799580a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -5,6 +5,7 @@
"colours",
"contactez",
"defaulticon",
+ "Depfu",
"Échecs",
"Fédération",
"Florifourchette",
diff --git a/README.md b/README.md
index 439ebe2..4fc7413 100644
--- a/README.md
+++ b/README.md
@@ -26,4 +26,4 @@ and is deployed on [Vercel](https://vercel.com/)
## Contributions
Contributions are encouraged. Please open an issue to discuss your ideas.
-Add your code into a feature branch such as `feature/feature-name`. We utilise a [GitHub Flow](https://www.gitkraken.com/learn/git/best-practices/git-branch-strategy#github-flow-considerations) branching strategy.
+Add your code into a feature branch such as `feature/feature-name`. We use the [GitHub Flow](https://www.gitkraken.com/learn/git/best-practices/git-branch-strategy#github-flow-considerations) branching strategy.
diff --git a/app/[lang]/tournois/Legend.tsx b/app/[lang]/tournois/Legend.tsx
index ec0b588..99811f3 100644
--- a/app/[lang]/tournois/Legend.tsx
+++ b/app/[lang]/tournois/Legend.tsx
@@ -6,6 +6,7 @@ import { useAtomValue } from "jotai";
import { TimeControl } from "@/types";
import { filteredTournamentsByTimeControlAtom } from "@/app/atoms";
+import { TimeControlColours } from "@/app/constants";
const Legend = () => {
const t = useTranslations("Tournaments");
@@ -15,11 +16,11 @@ const Legend = () => {
const timeControls = useMemo(
() =>
[
- { tc: TimeControl.Classic, colour: "#00ac39" },
- { tc: TimeControl.Rapid, colour: "#0086c7" },
- { tc: TimeControl.Blitz, colour: "#cec348" },
- { tc: TimeControl.Other, colour: "#d10c3e" },
- ].filter(({ tc }) => tournaments.some((t) => t.timeControl === tc)),
+ TimeControl.Classic,
+ TimeControl.Rapid,
+ TimeControl.Blitz,
+ TimeControl.Other,
+ ].filter((tc) => tournaments.some((t) => t.timeControl === tc)),
[tournaments],
);
@@ -39,12 +40,11 @@ const Legend = () => {
${timeControls
.map(
- ({ tc, colour }) => `
+ (tc) => `
-
- ${t(
- "timeControlEnum",
- { tc },
- )}
+ ${t("timeControlEnum", { tc })}
`,
)
diff --git a/app/[lang]/tournois/TournamentMap.tsx b/app/[lang]/tournois/TournamentMap.tsx
index c646c29..ccb44b2 100644
--- a/app/[lang]/tournois/TournamentMap.tsx
+++ b/app/[lang]/tournois/TournamentMap.tsx
@@ -26,10 +26,11 @@ import {
filteredTournamentsByTimeControlAtom,
normsOnlyAtom,
} from "@/app/atoms";
-import { pie } from "@/lib/pie";
+import { generatePieSVG } from "@/lib/pie";
+import { TimeControlColours } from "@/app/constants";
import Legend from "./Legend";
-import { TournamentMarker } from "./TournamentMarker";
+import { TournamentMarker, TournamentMarkerRef } from "./TournamentMarker";
import TimeControlFilters from "./TimeControlFilters";
// Declare a class type that adds in methods etc. defined by leaflet.smooth_marker_bouncing
@@ -99,7 +100,7 @@ export default function TournamentMap() {
debouncedHoveredListTournamentIdAtom,
);
- const markerRefs = useRef | null>>({});
+ const markerRefs = useRef>({});
const clusterRef = useRef(null);
const expandedClusterMarkerRef = useRef(null);
@@ -133,7 +134,9 @@ export default function TournamentMap() {
const markerRef = markerRefs.current[tournament.groupId];
if (markerRef) {
if (clusterRef.current) {
- const visibleMarker = clusterRef.current.getVisibleParent(markerRef);
+ const visibleMarker = clusterRef.current.getVisibleParent(
+ markerRef.getMarker(),
+ );
if (!visibleMarker) return;
// @ts-ignore
@@ -162,7 +165,7 @@ export default function TournamentMap() {
if (!marker.isBouncing()) {
stopBouncingMarkers();
- marker.bounce();
+ markerRef.bounce();
}
}
@@ -185,11 +188,9 @@ export default function TournamentMap() {
if (!tournament) return;
expandedClusterMarkerRef.current = e.cluster;
- const markerRef = markerRefs.current[
- tournament.groupId
- ] as BouncingMarker;
+ const markerRef = markerRefs.current[tournament.groupId];
- if (markerRef && e.markers.includes(markerRef)) {
+ if (markerRef && e.markers.includes(markerRef.getMarker())) {
stopBouncingMarkers();
markerRef.bounce();
}
@@ -234,37 +235,30 @@ export default function TournamentMap() {
}, [expandAndBounceIfNeeded, hoveredListTournamentId]);
const createClusterCustomIcon = useCallback((cluster: any) => {
- let childCount = cluster.getChildCount();
-
+ const childCount = cluster.getChildCount();
const children = cluster.getAllChildMarkers();
- // We added the time control to the icon options when creating the marker
+ // We added the time control as the class name when creating the marker
const timeControlCounts = countBy(
children,
- (child: any) => child.options.icon.options.timeControl,
+ (child: any) => child.options.icon.options.className,
);
const html = `
-
- ${pie("absolute w-[30px] -z-10", 15, [
- {
- value: timeControlCounts[TimeControl.Classic] ?? 0,
- colour: "#00ac39",
- },
- {
- value: timeControlCounts[TimeControl.Rapid] ?? 0,
- colour: "#0086c7",
- },
- {
- value: timeControlCounts[TimeControl.Blitz] ?? 0,
- colour: "#cec348",
- },
- {
- value: timeControlCounts[TimeControl.Other] ?? 0,
- colour: "#d10c3e",
- },
- ])}
+ ${generatePieSVG(
+ "absolute w-[30px]",
+ 15,
+ [
+ TimeControl.Classic,
+ TimeControl.Rapid,
+ TimeControl.Blitz,
+ TimeControl.Other,
+ ].map((tc) => ({
+ value: timeControlCounts[tc] ?? 0,
+ colour: TimeControlColours[tc],
+ })),
+ )}
${childCount}
`;
@@ -290,10 +284,11 @@ export default function TournamentMap() {
return (
(markerRefs.current[groupId] = ref)}
+ ref={(ref) => {
+ markerRefs.current[groupId] = ref!;
+ }}
key={groupId}
tournamentGroup={tournamentGroup}
- colour={colours[timeControl]}
/>
);
}),
diff --git a/app/[lang]/tournois/TournamentMarker.tsx b/app/[lang]/tournois/TournamentMarker.tsx
index a701c7c..ab3e1bf 100644
--- a/app/[lang]/tournois/TournamentMarker.tsx
+++ b/app/[lang]/tournois/TournamentMarker.tsx
@@ -1,7 +1,7 @@
"use client";
-import { forwardRef, useMemo, useRef } from "react";
-import { TimeControl, Tournament } from "@/types";
+import { forwardRef, useMemo, useImperativeHandle, useRef } from "react";
+import { Tournament } from "@/types";
import L from "leaflet";
import { Marker, Popup, MarkerProps } from "react-leaflet";
import { useTranslations } from "next-intl";
@@ -9,18 +9,38 @@ import { useSetAtom } from "jotai";
import { FaTrophy } from "react-icons/fa";
import { last } from "lodash";
+import type { BouncingMarker } from "@/leafletTypes";
import { debouncedHoveredMapTournamentGroupIdAtom } from "@/app/atoms";
+import { TimeControlColours } from "@/app/constants";
+
+export type TournamentMarkerRef = {
+ getMarker: () => L.Marker;
+ bounce: () => void;
+};
type TournamentMarkerProps = {
tournamentGroup: Tournament[];
- colour: string;
} & Omit;
export const TournamentMarker = forwardRef<
- L.Marker | null,
+ TournamentMarkerRef,
TournamentMarkerProps
->(({ tournamentGroup, colour, ...markerProps }, ref) => {
+>(({ tournamentGroup, ...markerProps }, ref) => {
const t = useTranslations("Tournaments");
+ const markerRef = useRef | null>(null);
+
+ useImperativeHandle(
+ ref,
+ () => ({
+ getMarker: () => markerRef.current!,
+ bounce: () => {
+ const bouncingMarker = markerRef.current as BouncingMarker;
+ bouncingMarker.setBouncingOptions({ contractHeight: 0 });
+ bouncingMarker.bounce();
+ },
+ }),
+ [],
+ );
const { date, latLng, groupId, timeControl } = tournamentGroup[0];
@@ -30,16 +50,18 @@ export const TournamentMarker = forwardRef<
const iconOptions = useMemo(
() =>
- new L.Icon({
- iconUrl: `/images/leaflet/marker-icon-2x-${colour}.png`,
- shadowUrl: "/images/leaflet/marker-shadow.png",
- iconSize: [25, 41],
- iconAnchor: [12, 41],
- popupAnchor: [1, -34],
- shadowSize: [41, 41],
- timeControl,
+ new L.DivIcon({
+ html: `
+
+ `,
+ className: timeControl,
+ iconSize: [24, 40],
+ iconAnchor: [12, 40],
+ popupAnchor: [1, -40],
}),
- [colour, timeControl],
+ [timeControl],
);
const startDate = date;
@@ -47,7 +69,7 @@ export const TournamentMarker = forwardRef<
return (
);
+}
+
+// Declare a class type that adds in methods etc. defined by leaflet.smooth_marker_bouncing
+// to keep Typescript happy
+export declare class BouncingMarker extends Marker {
+ isBouncing(): boolean;
+ bounce(): void;
+ stopBouncing(): void;
+ getBouncingMarkers(): Marker[];
+ setBouncingOptions(options: BouncingOptions | Partial): void;
+ stopAllBouncingMarkers(): void;
+
+ _icon: HTMLElement;
+ _bouncingMotion?: {
+ bouncingAnimationPlaying: boolean;
+ };
+}
diff --git a/lib/pie.ts b/lib/pie.ts
index 5ec9010..bd67be7 100644
--- a/lib/pie.ts
+++ b/lib/pie.ts
@@ -6,32 +6,30 @@ function polarToCartesian(radius: number, angleInDegrees: number) {
var radians = (angleInDegrees - 90) * Math.PI / 180;
return {
- x: round(radius + (radius * Math.cos(radians))),
- y: round(radius + (radius * Math.sin(radians)))
+ x: round(radius + (radius * Math.cos(radians))),
+ y: round(radius + (radius * Math.sin(radians)))
};
}
function getDAttribute(radius: number, startAngle: number, endAngle: number) {
const isCircle = endAngle - startAngle === 360;
- if (isCircle) {
- endAngle--;
- }
+ if (isCircle) endAngle--;
const start = polarToCartesian(radius, startAngle);
const end = polarToCartesian(radius, endAngle);
const largeArcFlag = endAngle - startAngle <= 180 ? 0 : 1;
const d = [
- "M", start.x, start.y,
- "A", radius, radius, 0, largeArcFlag, 1, end.x, end.y];
+ "M", start.x, start.y,
+ "A", radius, radius, 0, largeArcFlag, 1, end.x, end.y
+ ];
if (isCircle) {
d.push("Z");
} else {
d.push("L", radius, radius, "L", start.x, start.y, "Z");
}
-
return d.join(" ");
}
@@ -43,35 +41,28 @@ function svg(className: string, width: number, content: string ) {
return ``;
}
-type PieSector = {
+type PieSlice = {
value: number;
colour: string;
}
-export function pie(className: string, radius: number, values: PieSector[]) {
-
+export function generatePieSVG(className: string, radius: number, values: PieSlice[]) {
type Sector = {
colour: string;
degrees: number;
from?: number;
to?: number;
- path?: string;
}
const total = values.reduce((a, b) => a + b.value, 0);
const data: Sector[] = values.map(({ value, colour }) => ({ colour, degrees: value / total * 360 }));
- data.forEach((value, i, arr) => {
- if (i === 0) {
- value.from = 0;
- value.to = value.degrees;
- } else {
- value.from = arr[i - 1].to!;
- value.to = value.from + value.degrees;
- }
+ const paths = data.reduce<[number, string][]>((prev, value, i) => {
+ const from = i === 0 ? 0 : prev[i - 1][0];
+ const to = from + value.degrees;
- value.path = path(getDAttribute(radius, value.from, value.to ), value.colour);
- });
+ return [...prev, [to, path(getDAttribute(radius, from, to ), value.colour)]];
+ }, []);
- return svg(className, radius * 2, data.map(o => o.path).join(''));
+ return svg(className, radius * 2, paths.map(([to, path]) => path) .join(''));
}
diff --git a/public/images/leaflet/marker-icon-2x-black.png b/public/images/leaflet/marker-icon-2x-black.png
deleted file mode 100644
index 23c94cf..0000000
Binary files a/public/images/leaflet/marker-icon-2x-black.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-2x-blue.png b/public/images/leaflet/marker-icon-2x-blue.png
deleted file mode 100644
index 0015b64..0000000
Binary files a/public/images/leaflet/marker-icon-2x-blue.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-2x-gold.png b/public/images/leaflet/marker-icon-2x-gold.png
deleted file mode 100644
index 6992d65..0000000
Binary files a/public/images/leaflet/marker-icon-2x-gold.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-2x-green.png b/public/images/leaflet/marker-icon-2x-green.png
deleted file mode 100644
index c359abb..0000000
Binary files a/public/images/leaflet/marker-icon-2x-green.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-2x-grey.png b/public/images/leaflet/marker-icon-2x-grey.png
deleted file mode 100644
index 43b3eb4..0000000
Binary files a/public/images/leaflet/marker-icon-2x-grey.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-2x-orange.png b/public/images/leaflet/marker-icon-2x-orange.png
deleted file mode 100644
index c3c8632..0000000
Binary files a/public/images/leaflet/marker-icon-2x-orange.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-2x-red.png b/public/images/leaflet/marker-icon-2x-red.png
deleted file mode 100644
index 1c26e9f..0000000
Binary files a/public/images/leaflet/marker-icon-2x-red.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-2x-violet.png b/public/images/leaflet/marker-icon-2x-violet.png
deleted file mode 100644
index ea748aa..0000000
Binary files a/public/images/leaflet/marker-icon-2x-violet.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-2x-yellow.png b/public/images/leaflet/marker-icon-2x-yellow.png
deleted file mode 100644
index 8b677d9..0000000
Binary files a/public/images/leaflet/marker-icon-2x-yellow.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-black.png b/public/images/leaflet/marker-icon-black.png
deleted file mode 100644
index d262ae4..0000000
Binary files a/public/images/leaflet/marker-icon-black.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-blue.png b/public/images/leaflet/marker-icon-blue.png
deleted file mode 100644
index e2e9f75..0000000
Binary files a/public/images/leaflet/marker-icon-blue.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-gold.png b/public/images/leaflet/marker-icon-gold.png
deleted file mode 100644
index 162fada..0000000
Binary files a/public/images/leaflet/marker-icon-gold.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-green.png b/public/images/leaflet/marker-icon-green.png
deleted file mode 100644
index 56db5ea..0000000
Binary files a/public/images/leaflet/marker-icon-green.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-grey.png b/public/images/leaflet/marker-icon-grey.png
deleted file mode 100644
index ebbab8e..0000000
Binary files a/public/images/leaflet/marker-icon-grey.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-orange.png b/public/images/leaflet/marker-icon-orange.png
deleted file mode 100644
index fbbce7b..0000000
Binary files a/public/images/leaflet/marker-icon-orange.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-red.png b/public/images/leaflet/marker-icon-red.png
deleted file mode 100644
index 3e64e06..0000000
Binary files a/public/images/leaflet/marker-icon-red.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-violet.png b/public/images/leaflet/marker-icon-violet.png
deleted file mode 100644
index 28efc3c..0000000
Binary files a/public/images/leaflet/marker-icon-violet.png and /dev/null differ
diff --git a/public/images/leaflet/marker-icon-yellow.png b/public/images/leaflet/marker-icon-yellow.png
deleted file mode 100644
index b011eea..0000000
Binary files a/public/images/leaflet/marker-icon-yellow.png and /dev/null differ
diff --git a/public/images/leaflet/marker-shadow.png b/public/images/leaflet/marker-shadow.png
deleted file mode 100644
index 84c5808..0000000
Binary files a/public/images/leaflet/marker-shadow.png and /dev/null differ