Skip to content

Commit

Permalink
Merge pull request #76 from TurtIeSocks/push-to-project-apis
Browse files Browse the repository at this point in the history
Push to project apis / scanner database
  • Loading branch information
TurtIeSocks authored Feb 3, 2023
2 parents 5ac2a69 + f1d9a98 commit d1cc12f
Show file tree
Hide file tree
Showing 126 changed files with 3,992 additions and 1,881 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": "0.3.5",
"version": "0.4.0",
"description": "Tool to make RDM routes",
"main": "server/dist/index.js",
"author": "TurtIeSocks <[email protected]>",
Expand Down
6 changes: 3 additions & 3 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { CssBaseline, ThemeProvider } from '@mui/material'
import { createBrowserRouter, RouterProvider } from 'react-router-dom'

import createTheme from '@assets/theme'
import { Config } from '@assets/types'
import type { Config } from '@assets/types'
import { usePersist } from '@hooks/usePersist'
import { useStatic } from '@hooks/useStatic'
import { getData } from '@services/fetches'
import { fetchWrapper } from '@services/fetches'

import Home from '@pages/Home'
import Map from '@pages/map'
Expand Down Expand Up @@ -64,7 +64,7 @@ export default function App() {
const [error, setError] = React.useState<string>('')

React.useEffect(() => {
getData<Config>('/config/').then((res) => {
fetchWrapper<Config>('/config/').then((res) => {
if (res) {
if (location[0] === 0 && location[1] === 0) {
setStore('location', [res.start_lat, res.start_lon])
Expand Down
26 changes: 26 additions & 0 deletions client/src/assets/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,32 @@ export const UNOWN_ROUTES = [
'ManualQuest',
] as const

export const ALL_FENCES = [...new Set([...RDM_FENCES, ...UNOWN_FENCES])]

export const ALL_ROUTES = [...new Set([...RDM_ROUTES, ...UNOWN_ROUTES])]

export const CONVERSION_TYPES = [
'array',
'multiArray',
'geometry',
'geometry_vec',
'feature',
'feature_vec',
'featureCollection',
'struct',
'multiStruct',
'text',
'altText',
'poracle',
] as const

export const GEOMETRY_CONVERSION_TYPES = [
'Point',
'MultiPoint',
'Polygon',
'MultiPolygon',
] as const

export const COLORS = [
'#F0F8FF',
'#FAEBD7',
Expand Down
253 changes: 161 additions & 92 deletions client/src/assets/types.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,170 @@
/* eslint-disable @typescript-eslint/ban-types */
import type {
Feature,
FeatureCollection,
Feature as BaseFeature,
FeatureCollection as BaseFc,
GeoJsonProperties,
GeoJsonTypes,
Geometry,
LineString,
MultiPoint,
MultiPolygon,
Point,
Polygon,
} from 'geojson'

import type { UsePersist } from '@hooks/usePersist'
import type { UseStatic } from '@hooks/useStatic'
import { TABS } from './constants'

export type SpecificValueType<T, U> = {
[k in keyof T]: T[k] extends U ? k : never
import { CONVERSION_TYPES, RDM_FENCES, RDM_ROUTES, TABS } from './constants'

// UTILITY TYPES ==================================================================================

export type SpecificValueType<T, U, V> = {
[k in keyof T]: T[k] extends U
? V extends true
? k
: never
: V extends true
? never
: k
}[keyof T]

export type OnlyType<T, U> = { [k in SpecificValueType<T, U>]: U }
/*
* OnlyType<T, U, V> - returns a type with only the keys of T that have a value of U
*/
export type OnlyType<T, U, V = true> = { [k in SpecificValueType<T, U, V>]: U }

export type StoreNoFn<T> = keyof OnlyType<T, Function, false>

// ================================================================================================

// GEOJSON TYPES ==================================================================================

export type Properties<G extends Geometry | null = Geometry> =
GeoJsonProperties & {
__leafletId?: number
__forward?: G extends Point ? number : undefined
__backward?: G extends Point ? number : undefined
__start?: G extends LineString ? number : undefined
__end?: G extends LineString ? number : undefined
__multipoint_id?: G extends Point ? KojiKey : undefined
__name?: string
__id?: number
__geofence_id?: number
__mode?: KojiModes
__projects?: number[]
}

export interface Data {
gyms: PixiMarker[]
pokestops: PixiMarker[]
spawnpoints: PixiMarker[]
export interface Feature<G extends Geometry | null = Geometry, P = Properties>
extends Omit<BaseFeature<G, P>, 'id'> {
id: G extends Point
? number
: G extends LineString
? `${number}__${number}`
: KojiKey | string
}

export interface PixiMarker {
i: `${'p' | 'g' | 'v' | 'u'}${number}` & { [0]: 'p' | 'g' | 'v' | 'u' }
p: [number, number]
export interface FeatureCollection<
G extends Geometry | null = Geometry,
P = Properties,
> extends BaseFc<G, P> {
features: Feature<G, P>[]
}

export interface Instance {
export type GeometryTypes = Exclude<
GeoJsonTypes,
'Feature' | 'FeatureCollection' | 'GeometryCollection'
>

// ================================================================================================

// KOJI TYPES =====================================================================================

export type KojiModes =
| typeof RDM_FENCES[number]
| typeof RDM_ROUTES[number]
| 'Unset'

export type KojiKey = `${number}__${KojiModes}__${
| 'KOJI'
| 'SCANNER'
| 'CLIENT'}`

export type BasicKojiEntry = {
id: number
name: string
type: string
data: FeatureCollection
created_at: Date | string
updated_at: Date | string
}

export interface KojiGeofence extends BasicKojiEntry {
mode?: KojiModes
area: Feature<Polygon | MultiPolygon>
}

export interface KojiProject extends BasicKojiEntry {
api_endpoint?: string
api_key?: string
scanner: boolean
}

export interface KojiRoute extends BasicKojiEntry {
geofence_id: number
mode: KojiModes
description?: string
geometry: MultiPoint
}

export interface AdminGeofence extends KojiGeofence {
properties: { key: string; value: string | number | boolean }[]
related: number[]
}

export interface AdminProject extends KojiProject {
related: number[]
}

export interface KojiStats {
best_clusters: [number, number][]
best_cluster_point_count: number
cluster_time: number
total_points: number
points_covered: number
total_clusters: number
total_distance: number
longest_distance: number
fetch_time: number
}

export interface KojiResponse<T = FeatureCollection> {
data: T
status_code: number
status: string
message: string
stats?: {
best_clusters: [number, number][]
best_cluster_point_count: number
cluster_time: number
total_points: number
points_covered: number
total_clusters: number
total_distance: number
longest_distance: number
}
stats?: KojiStats
}

export interface DbOption
extends Omit<BasicKojiEntry, 'created_at' | 'updated_at'> {
mode: KojiModes
geo_type?: GeometryTypes
geofence_id?: number
}

// ================================================================================================

// GENERAL TYPES ==================================================================================

export type TabOption = typeof TABS[number]

export interface Data {
gyms: PixiMarker[]
pokestops: PixiMarker[]
spawnpoints: PixiMarker[]
}

export interface PixiMarker {
i: `${'p' | 'g' | 'v' | 'u'}${number}` & { [0]: 'p' | 'g' | 'v' | 'u' }
p: [number, number]
}

export interface Config {
Expand All @@ -58,23 +176,13 @@ export interface Config {
dangerous: boolean
}

export interface Circle {
id: string
lat: number
lng: number
radius: number
type: 'circle'
}
export type CombinedState = Partial<UsePersist> & Partial<UseStatic>

export interface Polygon {
id: string
positions: [number, number][]
type: 'polygon'
}
export type Category = 'pokestop' | 'gym' | 'spawnpoint'

export type Shape = Circle | Polygon
// ================================================================================================

export type CombinedState = Partial<UsePersist> & Partial<UseStatic>
// DATA TYPES =====================================================================================

export type ObjectInput = { lat: number; lon: number }[]
export type MultiObjectInput = ObjectInput[]
Expand All @@ -94,68 +202,29 @@ export interface Poracle {
display_in_matches?: boolean
}

export type ToConvert =
export type Conversions =
| ObjectInput
| MultiObjectInput
| ArrayInput
| MultiArrayInput
| Geometry
| Geometry[]
| Feature
| Feature[]
| FeatureCollection
| string
| Poracle
| Feature[]
| Poracle[]

export type ConversionOptions = typeof CONVERSION_TYPES[number]
// ================================================================================================

// PROPS ==========================================================================================

export interface PopupProps {
id: Feature['id']
properties: Feature['properties']
dbRef: DbOption | null
}

export interface KojiGeofence {
id: number
name: string
mode: string
area: Feature
}

export interface ClientGeofence extends KojiGeofence {
properties: { key: string; value: string | number | boolean }[]
related: number[]
}

export interface KojiProject {
id: number
name: string
}

export interface ClientProject extends KojiProject {
related: number[]
}

export interface KojiRoute {
id: number
geofence_id: number
name: string
mode: string
geometry: MultiPoint
}

export interface KojiStats {
best_clusters: [number, number][]
best_cluster_point_count: number
cluster_time: number
total_points: number
points_covered: number
total_clusters: number
total_distance: number
longest_distance: number
fetch_time: number
}

export interface Option {
id: number
type: string
name: string
geoType?: Exclude<GeoJsonTypes, 'Feature' | 'FeatureCollection'>
}

export type TabOption = typeof TABS[number]
// ================================================================================================
4 changes: 2 additions & 2 deletions client/src/components/Code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { json, jsonParseLinter } from '@codemirror/lang-json'
import { linter } from '@codemirror/lint'

import { usePersist } from '@hooks/usePersist'
import { getData } from '@services/fetches'
import { fetchWrapper } from '@services/fetches'

interface EditProps extends ReactCodeMirrorProps {
code?: string
Expand Down Expand Up @@ -42,7 +42,7 @@ export function Code({
if (setCode) {
const newValue = value.state.doc.toString()
if (newValue.startsWith('http')) {
const remoteValue = await getData<object>(newValue)
const remoteValue = await fetchWrapper<object>(newValue)
setCode(JSON.stringify(remoteValue, null, 2))
} else {
setCode(newValue)
Expand Down
Loading

0 comments on commit d1cc12f

Please sign in to comment.