diff --git a/client/package.json b/client/package.json
index 9f9be47a..463ee731 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "koji",
- "version": "1.3.11",
+ "version": "1.3.12",
"description": "Tool to make RDM routes",
"main": "server/dist/index.js",
"author": "TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com>",
diff --git a/client/src/pages/map/markers/Polygon.tsx b/client/src/pages/map/markers/Polygon.tsx
index 004814df..9ccbb460 100644
--- a/client/src/pages/map/markers/Polygon.tsx
+++ b/client/src/pages/map/markers/Polygon.tsx
@@ -22,8 +22,6 @@ export function KojiPolygon({
}) {
const { setStatic } = useStatic.getState()
- const [loadData, setLoadData] = React.useState(false)
-
const color = getPolygonColor(`${feature.id}`)
return (
@@ -32,7 +30,6 @@ export function KojiPolygon({
color={color}
eventHandlers={{
click({ latlng }) {
- if (!loadData) setLoadData(true)
const { lat, lng } = latlng
setStatic('clickedLocation', [lng, lat])
},
@@ -145,7 +142,7 @@ export function KojiPolygon({
pane="polygons"
>
-
+
)
diff --git a/client/src/pages/map/popups/Polygon.tsx b/client/src/pages/map/popups/Polygon.tsx
index c851458a..a82a6f4b 100644
--- a/client/src/pages/map/popups/Polygon.tsx
+++ b/client/src/pages/map/popups/Polygon.tsx
@@ -10,7 +10,9 @@ import {
Select,
TextField,
Typography,
+ capitalize,
} from '@mui/material'
+import RefreshIcon from '@mui/icons-material/Refresh'
import useDeepCompareEffect from 'use-deep-compare-effect'
import type { MultiPolygon, Polygon } from 'geojson'
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
@@ -22,6 +24,7 @@ import type {
Feature,
DbOption,
KojiModes,
+ Category,
} from '@assets/types'
import { useShapes } from '@hooks/useShapes'
import { useStatic } from '@hooks/useStatic'
@@ -36,7 +39,6 @@ import {
removeThisPolygon,
splitMultiPolygons,
} from '@services/utils'
-import { shallow } from 'zustand/shallow'
import { useImportExport } from '@hooks/useImportExport'
import { filterPoints, filterPolys } from '@services/geoUtils'
import { usePersist } from '@hooks/usePersist'
@@ -44,33 +46,79 @@ import { usePersist } from '@hooks/usePersist'
const { add, remove, updateProperty } = useShapes.getState().setters
const { setRecord } = useDbCache.getState()
+const MemoStat = React.memo(
+ ({ category, id }: { category: Category; id: Feature['id'] }) => {
+ const [stats, setStats] = React.useState(null)
+ const [loading, setLoading] = React.useState(false)
+ const tth = usePersist((s) => s.tth)
+ const raw = usePersist((s) => s.last_seen)
+ const feature = useShapes((s) => ({ ...s.Polygon, ...s.MultiPolygon }[id]))
+
+ const getStats = React.useCallback(() => {
+ setLoading(true)
+ setStats((prev) => (prev === null ? 0 : null))
+ const last_seen = typeof raw === 'string' ? new Date(raw) : raw
+ fetchWrapper<{ total: number }>(`/internal/data/area_stats/${category}`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ area: feature,
+ last_seen: Math.floor((last_seen?.getTime?.() || 0) / 1000),
+ tth,
+ }),
+ })
+ .then((data) => setStats(data?.total ?? 0))
+ .finally(() => setLoading(false))
+ }, [tth, raw, feature])
+
+ React.useEffect(() => {
+ if (stats !== null && !loading) getStats()
+ }, [tth, raw, feature])
+
+ return (
+
+ {capitalize(category)}s: {stats?.toLocaleString() || ''}
+
+ }
+ startIcon={
+
+ }
+ >
+ {typeof stats === 'number' || loading ? '' : 'Get'}
+
+
+ )
+ },
+)
+
export function PolygonPopup({
feature: refFeature,
- loadData,
dbRef,
}: {
feature: Feature
- loadData: boolean
dbRef: DbOption | null
}) {
const feature =
- useShapes(
- (s) => ({ ...s.Polygon, ...s.MultiPolygon }[refFeature.id]),
- shallow,
- ) || refFeature
- const raw = usePersist((s) => s.last_seen)
- const tth = usePersist((s) => s.tth)
+ useShapes((s) => ({ ...s.Polygon, ...s.MultiPolygon }[refFeature.id])) ||
+ refFeature
const geofence = useDbCache((s) => s.geofence)
- const [active, setActive] = React.useState<{
- spawnpoint: number | null | string
- gym: number | null | string
- pokestop: number | null | string
- }>({
- spawnpoint: null,
- gym: null,
- pokestop: null,
- })
const [name, setName] = React.useState(
dbRef?.name ||
feature.properties?.__name ||
@@ -103,21 +151,8 @@ export function PolygonPopup({
setDbAnchorEl(null)
}
- const getState = (category: keyof typeof active) => {
- switch (typeof active[category]) {
- case 'number':
- return active[category]?.toLocaleString()
- case 'string':
- return active[category]
- case 'object':
- return
- default:
- return 'Loading'
- }
- }
-
useDeepCompareEffect(() => {
- if (feature.geometry.coordinates.length && loadData) {
+ if (feature.geometry.coordinates.length) {
fetchWrapper>('/api/v1/calc/area', {
method: 'POST',
headers: {
@@ -125,33 +160,8 @@ export function PolygonPopup({
},
body: JSON.stringify({ area: feature }),
}).then((res) => res && setArea(res.data.area))
- const last_seen = typeof raw === 'string' ? new Date(raw) : raw
-
- Promise.allSettled(
- ['pokestop', 'gym', 'spawnpoint'].map((category) =>
- fetchWrapper<{ total: number }>(
- `/internal/data/area_stats/${category}`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- area: feature,
- last_seen: Math.floor((last_seen?.getTime?.() || 0) / 1000),
- tth,
- }),
- },
- ).then((data) =>
- setActive((prev) => ({
- ...prev,
- [category]: data?.total ?? (data || 0),
- })),
- ),
- ),
- )
}
- }, [feature, loadData, raw, tth])
+ }, [feature])
const isKoji = feature.id.toString().endsWith('KOJI')
// const isScanner = feature.id.endsWith('SCANNER')
@@ -228,13 +238,9 @@ export function PolygonPopup({
-
- Pokestops: {getState('pokestop')}
-
- Gyms: {getState('gym')}
-
- Spawnpoints: {getState('spawnpoint')}
-
+
+
+
@@ -470,7 +476,6 @@ export function PolygonPopup({
export const MemoPolyPopup = React.memo(
PolygonPopup,
(prev, next) =>
- prev.loadData === next.loadData &&
prev.feature.geometry.type === next.feature.geometry.type &&
prev.feature.geometry.coordinates.length ===
next.feature.geometry.coordinates.length,