+
+
{ transmitter.uplink_low || '--' }
-
-
+
+
{ transmitter.downlink_low || '--' }
diff --git a/app/satellites/styles.scss b/app/satellites/styles.scss
index c8115fe..f64a4e4 100644
--- a/app/satellites/styles.scss
+++ b/app/satellites/styles.scss
@@ -5,3 +5,19 @@
table {
@apply text-nowrap;
}
+
+dt {
+ @apply opacity-80;
+}
+
+dd {
+ @apply font-medium;
+}
+
+@media (max-width: 448px) {
+ .semi-sidesheet-inner,
+ .semi-sidesheet-inner-wrap,
+ .semi-sidesheet-size-small {
+ width: 100% !important;
+ }
+}
diff --git a/app/swr-provider.tsx b/app/swr-provider.tsx
index 8923c1a..4430aae 100644
--- a/app/swr-provider.tsx
+++ b/app/swr-provider.tsx
@@ -1,6 +1,6 @@
'use client';
-import {SWRConfig} from 'swr'
-import {ReactNode} from 'react';
+import { SWRConfig } from 'swr'
+import { ReactNode } from 'react'
export const SWRProvider = ({
children,
@@ -9,5 +9,7 @@ export const SWRProvider = ({
}) => {
return
fetch(resource, init).then(res => res.json()),
- }}>{children}
+ } }>
+ { children }
+
};
\ No newline at end of file
diff --git a/app/utils/sat.ts b/app/utils/sat.ts
deleted file mode 100644
index ac9ac0e..0000000
--- a/app/utils/sat.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-'use client'
-
-import { getVisibleSatellites, TLE } from 'tle.js'
-
-export const getPasses = (
- tle: TLE,
- startMS: number,
- endMS: number,
- stepMS: number = 1000,
-) => {
- const passes = []
-
- let ms = startMS
- let prevElevation = 0
-
- while (ms <= endMS) {
- try {
- const pass = getVisibleSatellites({
- tles: [tle],
- observerLat: 29.590509292552934,
- observerLng: 106.31482098268704,
- observerHeight: 240,
- elevationThreshold: 20,
- timestampMS: ms / 1000,
- })
- if (pass && pass.length > 0) {
- passes.push(pass[0])
- }
- } catch (e) {
- console.error(e)
- }
- ms += stepMS
- }
-
- return passes
-}
\ No newline at end of file
diff --git a/next.config.mjs b/next.config.mjs
index d595690..a3ebe82 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1,6 +1,11 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
- transpilePackages: ['@douyinfe/semi-ui', '@douyinfe/semi-icons', '@douyinfe/semi-illustrations']
+ transpilePackages: ['@douyinfe/semi-ui', '@douyinfe/semi-icons', '@douyinfe/semi-illustrations'],
+ images: {
+ domains: [
+ 'db-satnogs.freetls.fastly.net'
+ ]
+ }
};
export default nextConfig;
diff --git a/package-lock.json b/package-lock.json
index 3e3cda1..e662f46 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
"@douyinfe/semi-ui": "^2.55.0",
"@hamset/maidenhead-locator": "^0.2.1",
"@uiw/react-amap": "^6.0.3",
+ "@uniiem/uuid": "^0.2.1",
"@vercel/analytics": "^1.2.2",
"@vercel/blob": "^0.22.1",
"@vercel/kv": "^1.0.1",
@@ -22,12 +23,12 @@
"react": "^18",
"react-dom": "^18",
"react-markdown": "^9.0.1",
+ "react-qr-code": "^2.0.12",
"react-transition-group": "^4.4.5",
"rehype-katex": "^7.0.0",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
- "swr": "^2.2.5",
- "tle.js": "^4.9.0"
+ "swr": "^2.2.5"
},
"devDependencies": {
"@iconify-icon/react": "^2.0.1",
@@ -1500,6 +1501,11 @@
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
},
+ "node_modules/@uniiem/uuid": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@uniiem/uuid/-/uuid-0.2.1.tgz",
+ "integrity": "sha512-p8DOA3BTkZgvgtOCtK5x7Y2l+GRTFhYrOua70YPiEEUomQFirwxpWrQBst+7oB/iPTeY1zHuF6MKl+mxi0R00A=="
+ },
"node_modules/@upstash/redis": {
"version": "1.25.1",
"resolved": "https://registry.npmjs.org/@upstash/redis/-/redis-1.25.1.tgz",
@@ -6141,6 +6147,11 @@
"node": ">=6"
}
},
+ "node_modules/qr.js": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz",
+ "integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ=="
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -6227,6 +6238,24 @@
"react": ">=18"
}
},
+ "node_modules/react-qr-code": {
+ "version": "2.0.12",
+ "resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.12.tgz",
+ "integrity": "sha512-k+pzP5CKLEGBRwZsDPp98/CAJeXlsYRHM2iZn1Sd5Th/HnKhIZCSg27PXO58zk8z02RaEryg+60xa4vyywMJwg==",
+ "dependencies": {
+ "prop-types": "^15.8.1",
+ "qr.js": "0.0.0"
+ },
+ "peerDependencies": {
+ "react": "^16.x || ^17.x || ^18.x",
+ "react-native-svg": "*"
+ },
+ "peerDependenciesMeta": {
+ "react-native-svg": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-resizable": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-3.0.5.tgz",
@@ -6585,11 +6614,6 @@
"node": ">=14.0.0"
}
},
- "node_modules/satellite.js": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/satellite.js/-/satellite.js-4.1.4.tgz",
- "integrity": "sha512-OGUrs1GoGKjy9FYbW2ZaM5slaPfJaYrcxjE3YQTeR/OGyFPCxb6HK22Chao55POU06pdmNAdW5rtKJURse0+XA=="
- },
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@@ -7105,17 +7129,6 @@
"node": ">=0.8"
}
},
- "node_modules/tle.js": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/tle.js/-/tle.js-4.9.0.tgz",
- "integrity": "sha512-W3pLz/hvmo8LfACbXZqW86Q1DmdfD87xv5VGjONilZMzHDz29p3k3YW4exEz+SueDn1O+vByk/sFbO4/jIbaOg==",
- "dependencies": {
- "satellite.js": "^4.1.3"
- },
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
diff --git a/package.json b/package.json
index 42660f3..1081495 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"@douyinfe/semi-ui": "^2.55.0",
"@hamset/maidenhead-locator": "^0.2.1",
"@uiw/react-amap": "^6.0.3",
+ "@uniiem/uuid": "^0.2.1",
"@vercel/analytics": "^1.2.2",
"@vercel/blob": "^0.22.1",
"@vercel/kv": "^1.0.1",
@@ -24,12 +25,12 @@
"react": "^18",
"react-dom": "^18",
"react-markdown": "^9.0.1",
+ "react-qr-code": "^2.0.12",
"react-transition-group": "^4.4.5",
"rehype-katex": "^7.0.0",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
- "swr": "^2.2.5",
- "tle.js": "^4.9.0"
+ "swr": "^2.2.5"
},
"devDependencies": {
"@iconify-icon/react": "^2.0.1",
diff --git a/types/types.ts b/types/types.ts
index e69de29..8d833a9 100644
--- a/types/types.ts
+++ b/types/types.ts
@@ -0,0 +1,23 @@
+export type ObserverLocationStore = {
+ longitude: number,
+ latitude: number,
+ altitude?: number | null,
+ accuracy: number,
+ altitudeAccuracy?: number | null,
+} | 'pending'
+
+export interface SatelliteSighting {
+ rise: SightingDetail;
+ culminate: SightingDetail;
+ set: SightingDetail;
+}
+
+export interface SightingDetail {
+ time: Date;
+ lat: number;
+ lon: number;
+ elevation: number;
+ azimuth: number;
+ distance: number;
+}
+