Skip to content

Commit

Permalink
Merge pull request #1 from HoshinoSuzumi/satellites
Browse files Browse the repository at this point in the history
Satellites
  • Loading branch information
HoshinoSuzumi authored Apr 13, 2024
2 parents 3eebf06 + 4c1c001 commit 9099d1f
Show file tree
Hide file tree
Showing 14 changed files with 690 additions and 152 deletions.
13 changes: 13 additions & 0 deletions app/(standalone)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ReactNode } from 'react'

export default function ObLocationLayout({
children,
}: {
children: ReactNode
}) {
return (
<div className={ 'w-full h-full bg-white dark:bg-neutral-900' }>
{ children }
</div>
)
}
116 changes: 116 additions & 0 deletions app/(standalone)/ob-location/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
'use client'

import { useSearchParams } from 'next/navigation'
import { useEffect, useState } from 'react'
import { noto_sc, rubik } from '@/app/fonts'
import { Button } from '@douyinfe/semi-ui'
import { observerLocation } from '@/app/actions'

export default function Page() {
const searchParams = useSearchParams()
const ref = searchParams.get('ref')

const [loading, setLoading] = useState(false)
const [done, setDone] = useState(false)

const [location, setLocation] = useState<GeolocationPosition | null>(null)
useEffect(() => {
if (!ref) return
(async () => {
await observerLocation(ref, 'pending')
})()
const watcher = navigator.geolocation.watchPosition(setLocation, null, {
enableHighAccuracy: true,
})
return () => {
navigator.geolocation.clearWatch(watcher)
}
}, [ref])

const handleClick = () => {
if (!ref || !location) return
setLoading(true)
observerLocation(ref, {
longitude: location.coords.longitude,
latitude: location.coords.latitude,
altitude: location.coords.altitude,
accuracy: location.coords.accuracy,
altitudeAccuracy: location.coords.altitudeAccuracy,
})
.then(() => {
setDone(true)
})
.catch(err => {
console.error(err)
})
.finally(() => {
setLoading(false)
})
}

return !ref ? (
<div className={ 'w-full h-full flex justify-center items-center' }>
<h1>No ref provided</h1>
</div>
) : (
<div className={ `w-full h-full flex flex-col items-center p-8 ${ noto_sc.className }` }>
<svg xmlns="http://www.w3.org/2000/svg" width="3em" height="3em" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1">
<path d="M9 11a3 3 0 1 0 6 0a3 3 0 0 0-6 0"></path>
<path
d="M12.02 21.485a1.996 1.996 0 0 1-1.433-.585l-4.244-4.243a8 8 0 1 1 13.403-3.651M16 22l5-5m0 4.5V17h-4.5"></path>
</g>
</svg>
<h1 className={ 'pt-3 text-2xl font-medium' }>上传地面站位置</h1>
<p className={ 'pt-1 text-xs font-medium opacity-50' }>您正在与电脑网页端同步位置信息</p>
<div className={ 'mt-6 px-3 p-2 rounded shadow-md grid grid-cols-3 gap-6' }>
<div>
<p className={ 'text-sm font-medium opacity-50' }>经度</p>
<p className={ `text-base ${ rubik.className }` }>
{ location?.coords.longitude.toFixed(6) || 'locating...' }
</p>
</div>
<div>
<p className={ 'text-sm font-medium opacity-50' }>纬度</p>
<p className={ `text-base ${ rubik.className }` }>
{ location?.coords.latitude.toFixed(6) || 'locating...' }
</p>
</div>
<div>
<p className={ 'text-sm font-medium opacity-50' }>海拔</p>
<p className={ `text-base ${ rubik.className }` }>
{ location?.coords.altitude?.toFixed(2) || '-' }
</p>
</div>
<div>
<p className={ 'text-sm font-medium opacity-50' }>位置精度</p>
<p className={ `text-base ${ rubik.className }` }>
{ location?.coords.accuracy.toFixed(2) || '-' }
</p>
</div>
<div>
<p className={ 'text-sm font-medium opacity-50' }>海拔精度</p>
<p className={ `text-base ${ rubik.className }` }>
{ location?.coords.altitudeAccuracy?.toFixed(2) || '-' }
</p>
</div>
</div>
<div className={ 'w-full px-4' }>
<Button
block
loading={ loading }
disabled={ done || !location }
className={ 'mt-4' }
size={ 'large' }
theme={ 'solid' }
onClick={ handleClick }
>
{ !done ? '上传位置' : '已上传' }
</Button>
</div>
<p className={ 'pt-1 text-2xs font-medium opacity-50' }>
您的位置会在服务器临时存储 5 分钟
</p>
</div>
)
}
25 changes: 21 additions & 4 deletions app/actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
'use server'

import {sql} from '@vercel/postgres'
import {GeetestCaptchaSuccess, geetestValidate} from '@/app/geetest'
import { sql } from '@vercel/postgres'
import { GeetestCaptchaSuccess, geetestValidate } from '@/app/geetest'
import { UUID } from '@uniiem/uuid'
import { kv } from '@vercel/kv'
import { ObserverLocationStore } from '@/types/types'

export interface Annotation {
id: number
Expand Down Expand Up @@ -31,12 +34,12 @@ export async function newAnnotation(
}

export async function getAnnotationsByLk(lk: string): Promise<Annotation[]> {
const {rows} = await sql<Annotation>`SELECT * FROM annotations WHERE lk = ${lk} order by upvote desc, id desc`
const { rows } = await sql<Annotation>`SELECT * FROM annotations WHERE lk = ${lk} order by upvote desc, id desc`
return rows || []
}

export async function getAnnotationsList(): Promise<Annotation[]> {
const {rows} = await sql<Annotation>`SELECT * FROM annotations order by upvote desc, id desc`
const { rows } = await sql<Annotation>`SELECT * FROM annotations order by upvote desc, id desc`
return rows
}

Expand Down Expand Up @@ -103,3 +106,17 @@ export async function pastebin(
.catch(reject)
})
}

export async function observerLocation(ref: UUID, payload?: ObserverLocationStore) {
if (!payload) {
return await kv.get<ObserverLocationStore>(ref)
} else {
try {
return await kv.set(ref, payload, {
ex: 5 * 60,
})
} catch (e) {
console.error(e)
}
}
}
3 changes: 3 additions & 0 deletions app/api/satellite/satnogs/[endpoint]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ export async function GET(
data,
})
} catch (err) {
// return HTTP error
return NextResponse.json<BaseResponse<{}>>({
code: 1,
message: (err as Error).message,
data: null,
}, {
status: 500,
})
}
}
Loading

0 comments on commit 9099d1f

Please sign in to comment.