Skip to content

Commit

Permalink
refactor: load stats on demand
Browse files Browse the repository at this point in the history
  • Loading branch information
TurtIeSocks committed Dec 3, 2023
1 parent 4c9c85c commit 8fc1203
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 71 deletions.
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>",
Expand Down
5 changes: 1 addition & 4 deletions client/src/pages/map/markers/Polygon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ export function KojiPolygon({
}) {
const { setStatic } = useStatic.getState()

const [loadData, setLoadData] = React.useState(false)

const color = getPolygonColor(`${feature.id}`)

return (
Expand All @@ -32,7 +30,6 @@ export function KojiPolygon({
color={color}
eventHandlers={{
click({ latlng }) {
if (!loadData) setLoadData(true)
const { lat, lng } = latlng
setStatic('clickedLocation', [lng, lat])
},
Expand Down Expand Up @@ -145,7 +142,7 @@ export function KojiPolygon({
pane="polygons"
>
<Popup>
<MemoPolyPopup feature={feature} loadData={loadData} dbRef={dbRef} />
<MemoPolyPopup feature={feature} dbRef={dbRef} />
</Popup>
</Polygon>
)
Expand Down
137 changes: 71 additions & 66 deletions client/src/pages/map/popups/Polygon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -22,6 +24,7 @@ import type {
Feature,
DbOption,
KojiModes,
Category,
} from '@assets/types'
import { useShapes } from '@hooks/useShapes'
import { useStatic } from '@hooks/useStatic'
Expand All @@ -36,41 +39,86 @@ 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'

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<number | null>(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 (
<Typography variant="subtitle2">
{capitalize(category)}s: {stats?.toLocaleString() || ''}
<Button
size="small"
onClick={getStats}
disableRipple
sx={{ minWidth: 0 }}
endIcon={
<RefreshIcon
fontSize="small"
sx={{
display: typeof stats === 'number' ? 'block' : 'none',
}}
/>
}
startIcon={
<CircularProgress
size={20}
sx={{ display: loading ? 'block' : 'none' }}
/>
}
>
{typeof stats === 'number' || loading ? '' : 'Get'}
</Button>
</Typography>
)
},
)

export function PolygonPopup({
feature: refFeature,
loadData,
dbRef,
}: {
feature: Feature<Polygon | MultiPolygon>
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 ||
Expand Down Expand Up @@ -103,55 +151,17 @@ 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 <CircularProgress size={10} />
default:
return 'Loading'
}
}

useDeepCompareEffect(() => {
if (feature.geometry.coordinates.length && loadData) {
if (feature.geometry.coordinates.length) {
fetchWrapper<KojiResponse<{ area: number }>>('/api/v1/calc/area', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
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')
Expand Down Expand Up @@ -228,13 +238,9 @@ export function PolygonPopup({
</Grid2>
<Divider flexItem sx={{ my: 1, color: 'black', width: '90%' }} />
<Grid2 xs={12}>
<Typography variant="subtitle2">
Pokestops: {getState('pokestop')}
</Typography>
<Typography variant="subtitle2">Gyms: {getState('gym')}</Typography>
<Typography variant="subtitle2">
Spawnpoints: {getState('spawnpoint')}
</Typography>
<MemoStat category="pokestop" id={refFeature.id} />
<MemoStat category="gym" id={refFeature.id} />
<MemoStat category="spawnpoint" id={refFeature.id} />
</Grid2>
<Divider flexItem sx={{ my: 1, color: 'black', width: '90%' }} />
<Grid2 xs={12}>
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 8fc1203

Please sign in to comment.