From bbdde5174a68207e481a3fb557c5a2a6e0b59937 Mon Sep 17 00:00:00 2001 From: Derick M <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 1 Jan 2023 15:00:53 -0500 Subject: [PATCH 1/2] fix route exporting page - Make it work lol - use convert api to handle most of it - fix up client side routes a bit - more separation when converting multiple geos to text - logout button and functionality - separate login route - make sure to fetch config for all routes --- client/src/App.tsx | 41 +++++- client/src/components/Loading.tsx | 16 ++- client/src/components/dialogs/ExportRoute.tsx | 127 ++++++++++++------ client/src/components/dialogs/Polygon.tsx | 2 +- client/src/components/drawer/manage/index.tsx | 2 +- .../src/components/drawer/settings/index.tsx | 3 +- client/src/hooks/usePersist.ts | 2 + client/src/hooks/useStatic.ts | 4 +- .../src/pages/{home/Splash.tsx => Home.tsx} | 18 ++- client/src/pages/{home => }/Login.tsx | 9 +- client/src/pages/home/index.tsx | 37 ----- client/src/services/fetches.ts | 12 +- client/vite.config.ts | 5 - server/app/src/lib.rs | 8 +- server/app/src/routes/misc.rs | 11 +- server/model/src/multi_vec.rs | 15 ++- server/model/src/point_array.rs | 2 +- server/model/src/point_struct.rs | 2 +- 18 files changed, 200 insertions(+), 116 deletions(-) rename client/src/pages/{home/Splash.tsx => Home.tsx} (82%) rename client/src/pages/{home => }/Login.tsx (94%) delete mode 100644 client/src/pages/home/index.tsx diff --git a/client/src/App.tsx b/client/src/App.tsx index 7ccdea33..73b26d15 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -3,12 +3,16 @@ import { CssBaseline, ThemeProvider } from '@mui/material' import { createBrowserRouter, RouterProvider } from 'react-router-dom' import createTheme from '@assets/theme' +import { Config } from '@assets/types' import { usePersist } from '@hooks/usePersist' +import { useStatic } from '@hooks/useStatic' +import { getData } from '@services/fetches' -import Home from '@pages/home' +import Home from '@pages/Home' import Map from '@pages/map' import AdminPanel from '@pages/admin' import ErrorPage from '@pages/Error' +import Login from '@pages/Login' const router = createBrowserRouter([ { @@ -16,6 +20,11 @@ const router = createBrowserRouter([ element: , errorElement: , }, + { + path: '/login', + element: , + errorElement: , + }, { path: '/map', element: , @@ -42,10 +51,40 @@ export default function App() { return newTheme }, [darkMode]) + const { location, setStore } = usePersist.getState() + const { setStatic } = useStatic.getState() + + const [fetched, setFetched] = React.useState(false) + const [error, setError] = React.useState('') + + React.useEffect(() => { + getData('/config/').then((res) => { + if (res) { + if (res.logged_in) { + if (location[0] === 0 && location[1] === 0) { + setStore('location', [res.start_lat, res.start_lon]) + } + setStatic('scannerType', res.scanner_type) + if (res.tile_server) { + setStatic('tileServer', res.tile_server) + } + } else { + router.navigate('/login') + } + setFetched(true) + } else { + setError('Unable to fetch config, try again later') + } + }) + }, []) + + if (!fetched) return null + return ( + {error && } ) } diff --git a/client/src/components/Loading.tsx b/client/src/components/Loading.tsx index 792c8632..be7b65d5 100644 --- a/client/src/components/Loading.tsx +++ b/client/src/components/Loading.tsx @@ -189,9 +189,19 @@ export default function Loading() { ) : ( - + {typeof value === 'boolean' ? ( + <> + Failed + + Press F12 to open the browser console to see the logged + error + + + ) : ( + + )} )} void + geojson: FeatureCollection } -export default function ExportRoute({ open, setOpen }: Props) { - const exportSettings = usePersist((s) => s.export) - const mode = usePersist((s) => s.mode) +export default function ExportRoute({ open, setOpen, geojson }: Props) { + const scannerType = useStatic((s) => s.scannerType) + const [route, setRoute] = React.useState([]) + const [stats, setStats] = React.useState<{ + max: number + total: number + count: number + }>({ max: 0, total: 0, count: 0 }) - const total = exportSettings.route.flatMap((route) => route).length + useDeepCompareEffect(() => { + if (open === 'route') { + convert(geojson, 'multiArray', false).then((newCode) => { + let max = 0 + let total = 0 + let count = 0 + const newRoute = newCode.map((eachRoute) => { + return eachRoute.map((point, j) => { + const next = j ? eachRoute[j + 1] : eachRoute.at(-1) + if (next) { + const dis = distance(point, next, { units: 'meters' }) + if (dis > max) max = dis + total += dis + } + count++ + return [+point[0].toFixed(6), +point[1].toFixed(6)] + }) + }) + setStats({ + max, + total, + count, + }) + setRoute(newRoute) + }) + } + }, [geojson, open]) return ( setOpen('')}> @@ -45,36 +82,40 @@ export default function ExportRoute({ open, setOpen }: Props) { justifyContent="center" > - {exportSettings.route.map((route, i) => ( - - - - - - navigator.clipboard.writeText( - route.map((p) => p.join(',')).join('\n'), - ) - } - > - - - - - {mode === 'cluster' ? 'Area' : 'Device'} {i + 1} + {route.map((feat, i) => { + return ( + + + + + + navigator.clipboard.writeText( + await convert( + feat, + scannerType === 'rdm' ? 'text' : 'altText', + false, + ), + ) + } + > + + + + [Geofence {i + 1}] - - - {route.map((point, j) => ( - - ))} - - ))} + + {feat.map((point, j) => ( + + ))} + + ) + })} acc + cur.length, 0)} label="Count" type="number" fullWidth @@ -96,7 +137,7 @@ export default function ExportRoute({ open, setOpen }: Props) { + {open && ( + + )} ) } diff --git a/client/src/services/fetches.ts b/client/src/services/fetches.ts index bc93041b..a4207c0e 100644 --- a/client/src/services/fetches.ts +++ b/client/src/services/fetches.ts @@ -164,9 +164,10 @@ export async function convert | object | string>( area: ToConvert, return_type: UsePersist['polygonExportMode'], simplify: UsePersist['simplifyPolygons'], + url = '/api/v1/convert/data', ): Promise { try { - const data = await fetch('/api/v1/convert/data', { + const data = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/server/app/src/lib.rs b/server/app/src/lib.rs index 4fa2658c..0e16078e 100644 --- a/server/app/src/lib.rs +++ b/server/app/src/lib.rs @@ -169,6 +169,7 @@ pub async fn main() -> io::Result<()> { .service( web::scope("/convert") .service(routes::convert::convert_data) + .service(routes::convert::merge_points) .service(routes::convert::simplify), ) .service( diff --git a/server/app/src/routes/convert.rs b/server/app/src/routes/convert.rs index 8df18d0a..c71b897d 100644 --- a/server/app/src/routes/convert.rs +++ b/server/app/src/routes/convert.rs @@ -1,4 +1,6 @@ -use models::GeometryHelpers; +use entity::sea_orm_active_enums::Type; +use geojson::{Geometry, Value}; +use models::{GeometryHelpers, ToCollection, ToFeature}; use super::*; @@ -42,3 +44,35 @@ async fn simplify(payload: web::Json) -> Result { None, )) } + +#[post("/merge_points")] +async fn merge_points(payload: web::Json) -> Result { + let ArgsUnwrapped { + area, return_type, .. + } = payload.into_inner().init(Some("simplify")); + + let mut new_multi_point: Vec> = vec![]; + + area.into_iter().for_each(|feat| { + if let Some(geometry) = feat.geometry { + match geometry.value { + Value::Point(point) => new_multi_point.push(point), + _ => {} + } + } + }); + + Ok(response::send( + Geometry { + bbox: None, + foreign_members: None, + value: Value::MultiPoint(new_multi_point), + } + .to_feature(Some(&Type::CirclePokemon)) + .to_collection(None, None), + return_type, + None, + false, + None, + )) +}