feat: Expo mobile app scaffold (118-file structure) #80
1
mobile/.env.example
Normal file
1
mobile/.env.example
Normal file
@@ -0,0 +1 @@
|
|||||||
|
EXPO_PUBLIC_DEFAULT_SERVER_URL=http://192.168.1.100:8080
|
||||||
26
mobile/.eslintrc.js
Normal file
26
mobile/.eslintrc.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: ['@typescript-eslint', 'react', 'react-hooks'],
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'plugin:react-hooks/recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
],
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'react/react-in-jsx-scope': 'off',
|
||||||
|
},
|
||||||
|
};
|
||||||
41
mobile/.gitignore
vendored
Normal file
41
mobile/.gitignore
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Expo
|
||||||
|
.expo/
|
||||||
|
dist/
|
||||||
|
web-build/
|
||||||
|
expo-env.d.ts
|
||||||
|
|
||||||
|
# Native
|
||||||
|
.kotlin/
|
||||||
|
*.orig.*
|
||||||
|
*.jks
|
||||||
|
*.p8
|
||||||
|
*.p12
|
||||||
|
*.key
|
||||||
|
*.mobileprovision
|
||||||
|
|
||||||
|
# Metro
|
||||||
|
.metro-health-check*
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.*
|
||||||
|
yarn-debug.*
|
||||||
|
yarn-error.*
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# generated native folders
|
||||||
|
/ios
|
||||||
|
/android
|
||||||
4
mobile/.prettierrc
Normal file
4
mobile/.prettierrc
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
||||||
25
mobile/App.tsx
Normal file
25
mobile/App.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
|
import { StatusBar } from 'expo-status-bar';
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.title}>WiFi-DensePose</Text>
|
||||||
|
<StatusBar style="dark" />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: '600',
|
||||||
|
},
|
||||||
|
});
|
||||||
12
mobile/app.config.ts
Normal file
12
mobile/app.config.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
export default {
|
||||||
|
name: 'WiFi-DensePose',
|
||||||
|
slug: 'wifi-densepose',
|
||||||
|
version: '1.0.0',
|
||||||
|
ios: {
|
||||||
|
bundleIdentifier: 'com.ruvnet.wifidensepose',
|
||||||
|
},
|
||||||
|
android: {
|
||||||
|
package: 'com.ruvnet.wifidensepose',
|
||||||
|
},
|
||||||
|
// Use expo-env and app-level defaults from the project configuration when available.
|
||||||
|
};
|
||||||
30
mobile/app.json
Normal file
30
mobile/app.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"expo": {
|
||||||
|
"name": "mobile",
|
||||||
|
"slug": "mobile",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"orientation": "portrait",
|
||||||
|
"icon": "./assets/icon.png",
|
||||||
|
"userInterfaceStyle": "light",
|
||||||
|
"splash": {
|
||||||
|
"image": "./assets/splash-icon.png",
|
||||||
|
"resizeMode": "contain",
|
||||||
|
"backgroundColor": "#ffffff"
|
||||||
|
},
|
||||||
|
"ios": {
|
||||||
|
"supportsTablet": true
|
||||||
|
},
|
||||||
|
"android": {
|
||||||
|
"adaptiveIcon": {
|
||||||
|
"backgroundColor": "#E6F4FE",
|
||||||
|
"foregroundImage": "./assets/android-icon-foreground.png",
|
||||||
|
"backgroundImage": "./assets/android-icon-background.png",
|
||||||
|
"monochromeImage": "./assets/android-icon-monochrome.png"
|
||||||
|
},
|
||||||
|
"predictiveBackGestureEnabled": false
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"favicon": "./assets/favicon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
mobile/assets/android-icon-background.png
Normal file
BIN
mobile/assets/android-icon-background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
mobile/assets/android-icon-foreground.png
Normal file
BIN
mobile/assets/android-icon-foreground.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
BIN
mobile/assets/android-icon-monochrome.png
Normal file
BIN
mobile/assets/android-icon-monochrome.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
BIN
mobile/assets/favicon.png
Normal file
BIN
mobile/assets/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
mobile/assets/icon.png
Normal file
BIN
mobile/assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 384 KiB |
BIN
mobile/assets/splash-icon.png
Normal file
BIN
mobile/assets/splash-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
9
mobile/babel.config.js
Normal file
9
mobile/babel.config.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
module.exports = function (api) {
|
||||||
|
api.cache(true);
|
||||||
|
return {
|
||||||
|
presets: ['babel-preset-expo'],
|
||||||
|
plugins: [
|
||||||
|
'react-native-reanimated/plugin'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
};
|
||||||
0
mobile/e2e/.maestro/config.yaml
Normal file
0
mobile/e2e/.maestro/config.yaml
Normal file
0
mobile/e2e/live_screen.yaml
Normal file
0
mobile/e2e/live_screen.yaml
Normal file
0
mobile/e2e/mat_screen.yaml
Normal file
0
mobile/e2e/mat_screen.yaml
Normal file
0
mobile/e2e/offline_fallback.yaml
Normal file
0
mobile/e2e/offline_fallback.yaml
Normal file
0
mobile/e2e/settings_screen.yaml
Normal file
0
mobile/e2e/settings_screen.yaml
Normal file
0
mobile/e2e/vitals_screen.yaml
Normal file
0
mobile/e2e/vitals_screen.yaml
Normal file
0
mobile/e2e/zones_screen.yaml
Normal file
0
mobile/e2e/zones_screen.yaml
Normal file
17
mobile/eas.json
Normal file
17
mobile/eas.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"cli": {
|
||||||
|
"version": ">= 4.0.0"
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"development": {
|
||||||
|
"developmentClient": true,
|
||||||
|
"distribution": "internal"
|
||||||
|
},
|
||||||
|
"preview": {
|
||||||
|
"distribution": "internal"
|
||||||
|
},
|
||||||
|
"production": {
|
||||||
|
"autoIncrement": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
mobile/index.ts
Normal file
4
mobile/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { registerRootComponent } from 'expo';
|
||||||
|
import App from './App';
|
||||||
|
|
||||||
|
registerRootComponent(App);
|
||||||
8
mobile/jest.config.js
Normal file
8
mobile/jest.config.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
preset: 'jest-expo',
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
||||||
|
testPathIgnorePatterns: ['/src/__tests__/'],
|
||||||
|
transformIgnorePatterns: [
|
||||||
|
'node_modules/(?!(expo|expo-.+|react-native|@react-native|react-native-webview|react-native-reanimated|react-native-svg|react-native-safe-area-context|react-native-screens|@react-navigation|@expo|@unimodules|expo-modules-core)/)',
|
||||||
|
],
|
||||||
|
};
|
||||||
11
mobile/jest.setup.ts
Normal file
11
mobile/jest.setup.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
jest.mock('@react-native-async-storage/async-storage', () =>
|
||||||
|
require('@react-native-async-storage/async-storage/jest/async-storage-mock')
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.mock('react-native-wifi-reborn', () => ({
|
||||||
|
loadWifiList: jest.fn(async () => []),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('react-native-reanimated', () =>
|
||||||
|
require('react-native-reanimated/mock')
|
||||||
|
);
|
||||||
16327
mobile/package-lock.json
generated
Normal file
16327
mobile/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
49
mobile/package.json
Normal file
49
mobile/package.json
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "mobile",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.ts",
|
||||||
|
"scripts": {
|
||||||
|
"start": "expo start",
|
||||||
|
"android": "expo start --android",
|
||||||
|
"ios": "expo start --ios",
|
||||||
|
"web": "expo start --web",
|
||||||
|
"test": "jest",
|
||||||
|
"lint": "eslint ."
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@expo/vector-icons": "^15.0.2",
|
||||||
|
"@react-native-async-storage/async-storage": "2.2.0",
|
||||||
|
"@react-navigation/bottom-tabs": "^7.15.3",
|
||||||
|
"@react-navigation/native": "^7.1.31",
|
||||||
|
"axios": "^1.13.6",
|
||||||
|
"expo": "~55.0.4",
|
||||||
|
"expo-status-bar": "~55.0.4",
|
||||||
|
"react": "19.2.0",
|
||||||
|
"react-native": "0.83.2",
|
||||||
|
"react-native-gesture-handler": "~2.30.0",
|
||||||
|
"react-native-reanimated": "4.2.1",
|
||||||
|
"react-native-safe-area-context": "~5.6.2",
|
||||||
|
"react-native-screens": "~4.23.0",
|
||||||
|
"react-native-svg": "15.15.3",
|
||||||
|
"react-native-webview": "13.16.0",
|
||||||
|
"react-native-wifi-reborn": "^4.13.6",
|
||||||
|
"victory-native": "^41.20.2",
|
||||||
|
"zustand": "^5.0.11"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@testing-library/jest-native": "^5.4.3",
|
||||||
|
"@testing-library/react-native": "^13.3.3",
|
||||||
|
"@types/jest": "^30.0.0",
|
||||||
|
"@types/react": "~19.2.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
||||||
|
"@typescript-eslint/parser": "^8.56.1",
|
||||||
|
"babel-preset-expo": "^55.0.10",
|
||||||
|
"eslint": "^10.0.2",
|
||||||
|
"jest": "^30.2.0",
|
||||||
|
"jest-expo": "^55.0.9",
|
||||||
|
"prettier": "^3.8.1",
|
||||||
|
"react-native-worklets": "^0.7.4",
|
||||||
|
"typescript": "~5.9.2"
|
||||||
|
},
|
||||||
|
"private": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/components/GaugeArc.test.tsx
Normal file
5
mobile/src/__tests__/components/GaugeArc.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/components/HudOverlay.test.tsx
Normal file
5
mobile/src/__tests__/components/HudOverlay.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/components/OccupancyGrid.test.tsx
Normal file
5
mobile/src/__tests__/components/OccupancyGrid.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/components/SignalBar.test.tsx
Normal file
5
mobile/src/__tests__/components/SignalBar.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/components/SparklineChart.test.tsx
Normal file
5
mobile/src/__tests__/components/SparklineChart.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/components/StatusDot.test.tsx
Normal file
5
mobile/src/__tests__/components/StatusDot.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/hooks/usePoseStream.test.ts
Normal file
5
mobile/src/__tests__/hooks/usePoseStream.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/hooks/useRssiScanner.test.ts
Normal file
5
mobile/src/__tests__/hooks/useRssiScanner.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/hooks/useServerReachability.test.ts
Normal file
5
mobile/src/__tests__/hooks/useServerReachability.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/screens/LiveScreen.test.tsx
Normal file
5
mobile/src/__tests__/screens/LiveScreen.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/screens/MATScreen.test.tsx
Normal file
5
mobile/src/__tests__/screens/MATScreen.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/screens/SettingsScreen.test.tsx
Normal file
5
mobile/src/__tests__/screens/SettingsScreen.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/screens/VitalsScreen.test.tsx
Normal file
5
mobile/src/__tests__/screens/VitalsScreen.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/screens/ZonesScreen.test.tsx
Normal file
5
mobile/src/__tests__/screens/ZonesScreen.test.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/services/api.service.test.ts
Normal file
5
mobile/src/__tests__/services/api.service.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/services/rssi.service.test.ts
Normal file
5
mobile/src/__tests__/services/rssi.service.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/services/simulation.service.test.ts
Normal file
5
mobile/src/__tests__/services/simulation.service.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/services/ws.service.test.ts
Normal file
5
mobile/src/__tests__/services/ws.service.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/stores/matStore.test.ts
Normal file
5
mobile/src/__tests__/stores/matStore.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/stores/poseStore.test.ts
Normal file
5
mobile/src/__tests__/stores/poseStore.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/stores/settingsStore.test.ts
Normal file
5
mobile/src/__tests__/stores/settingsStore.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/utils/colorMap.test.ts
Normal file
5
mobile/src/__tests__/utils/colorMap.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/utils/ringBuffer.test.ts
Normal file
5
mobile/src/__tests__/utils/ringBuffer.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
5
mobile/src/__tests__/utils/urlValidator.test.ts
Normal file
5
mobile/src/__tests__/utils/urlValidator.test.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
describe('placeholder', () => {
|
||||||
|
it('passes', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
0
mobile/src/assets/images/wifi-icon.png
Normal file
0
mobile/src/assets/images/wifi-icon.png
Normal file
0
mobile/src/assets/webview/gaussian-splats.html
Normal file
0
mobile/src/assets/webview/gaussian-splats.html
Normal file
0
mobile/src/assets/webview/mat-dashboard.html
Normal file
0
mobile/src/assets/webview/mat-dashboard.html
Normal file
0
mobile/src/components/ConnectionBanner.tsx
Normal file
0
mobile/src/components/ConnectionBanner.tsx
Normal file
0
mobile/src/components/ErrorBoundary.tsx
Normal file
0
mobile/src/components/ErrorBoundary.tsx
Normal file
0
mobile/src/components/GaugeArc.tsx
Normal file
0
mobile/src/components/GaugeArc.tsx
Normal file
0
mobile/src/components/HudOverlay.tsx
Normal file
0
mobile/src/components/HudOverlay.tsx
Normal file
0
mobile/src/components/LoadingSpinner.tsx
Normal file
0
mobile/src/components/LoadingSpinner.tsx
Normal file
0
mobile/src/components/ModeBadge.tsx
Normal file
0
mobile/src/components/ModeBadge.tsx
Normal file
0
mobile/src/components/OccupancyGrid.tsx
Normal file
0
mobile/src/components/OccupancyGrid.tsx
Normal file
0
mobile/src/components/SignalBar.tsx
Normal file
0
mobile/src/components/SignalBar.tsx
Normal file
0
mobile/src/components/SparklineChart.tsx
Normal file
0
mobile/src/components/SparklineChart.tsx
Normal file
0
mobile/src/components/StatusDot.tsx
Normal file
0
mobile/src/components/StatusDot.tsx
Normal file
0
mobile/src/components/ThemedText.tsx
Normal file
0
mobile/src/components/ThemedText.tsx
Normal file
0
mobile/src/components/ThemedView.tsx
Normal file
0
mobile/src/components/ThemedView.tsx
Normal file
0
mobile/src/constants/api.ts
Normal file
0
mobile/src/constants/api.ts
Normal file
0
mobile/src/constants/simulation.ts
Normal file
0
mobile/src/constants/simulation.ts
Normal file
0
mobile/src/constants/websocket.ts
Normal file
0
mobile/src/constants/websocket.ts
Normal file
0
mobile/src/hooks/usePoseStream.ts
Normal file
0
mobile/src/hooks/usePoseStream.ts
Normal file
0
mobile/src/hooks/useRssiScanner.ts
Normal file
0
mobile/src/hooks/useRssiScanner.ts
Normal file
0
mobile/src/hooks/useServerReachability.ts
Normal file
0
mobile/src/hooks/useServerReachability.ts
Normal file
0
mobile/src/hooks/useTheme.ts
Normal file
0
mobile/src/hooks/useTheme.ts
Normal file
0
mobile/src/hooks/useWebViewBridge.ts
Normal file
0
mobile/src/hooks/useWebViewBridge.ts
Normal file
0
mobile/src/navigation/MainTabs.tsx
Normal file
0
mobile/src/navigation/MainTabs.tsx
Normal file
0
mobile/src/navigation/RootNavigator.tsx
Normal file
0
mobile/src/navigation/RootNavigator.tsx
Normal file
0
mobile/src/navigation/types.ts
Normal file
0
mobile/src/navigation/types.ts
Normal file
0
mobile/src/screens/LiveScreen/LiveHUD.tsx
Normal file
0
mobile/src/screens/LiveScreen/LiveHUD.tsx
Normal file
0
mobile/src/screens/LiveScreen/index.tsx
Normal file
0
mobile/src/screens/LiveScreen/index.tsx
Normal file
0
mobile/src/screens/LiveScreen/useGaussianBridge.ts
Normal file
0
mobile/src/screens/LiveScreen/useGaussianBridge.ts
Normal file
0
mobile/src/screens/MATScreen/AlertCard.tsx
Normal file
0
mobile/src/screens/MATScreen/AlertCard.tsx
Normal file
0
mobile/src/screens/MATScreen/AlertList.tsx
Normal file
0
mobile/src/screens/MATScreen/AlertList.tsx
Normal file
0
mobile/src/screens/MATScreen/MatWebView.tsx
Normal file
0
mobile/src/screens/MATScreen/MatWebView.tsx
Normal file
0
mobile/src/screens/MATScreen/SurvivorCounter.tsx
Normal file
0
mobile/src/screens/MATScreen/SurvivorCounter.tsx
Normal file
0
mobile/src/screens/MATScreen/index.tsx
Normal file
0
mobile/src/screens/MATScreen/index.tsx
Normal file
0
mobile/src/screens/MATScreen/useMatBridge.ts
Normal file
0
mobile/src/screens/MATScreen/useMatBridge.ts
Normal file
0
mobile/src/screens/SettingsScreen/RssiToggle.tsx
Normal file
0
mobile/src/screens/SettingsScreen/RssiToggle.tsx
Normal file
0
mobile/src/screens/SettingsScreen/ThemePicker.tsx
Normal file
0
mobile/src/screens/SettingsScreen/ThemePicker.tsx
Normal file
0
mobile/src/screens/SettingsScreen/index.tsx
Normal file
0
mobile/src/screens/SettingsScreen/index.tsx
Normal file
0
mobile/src/screens/VitalsScreen/BreathingGauge.tsx
Normal file
0
mobile/src/screens/VitalsScreen/BreathingGauge.tsx
Normal file
0
mobile/src/screens/VitalsScreen/HeartRateGauge.tsx
Normal file
0
mobile/src/screens/VitalsScreen/HeartRateGauge.tsx
Normal file
0
mobile/src/screens/VitalsScreen/MetricCard.tsx
Normal file
0
mobile/src/screens/VitalsScreen/MetricCard.tsx
Normal file
0
mobile/src/screens/VitalsScreen/index.tsx
Normal file
0
mobile/src/screens/VitalsScreen/index.tsx
Normal file
0
mobile/src/screens/ZonesScreen/FloorPlanSvg.tsx
Normal file
0
mobile/src/screens/ZonesScreen/FloorPlanSvg.tsx
Normal file
0
mobile/src/screens/ZonesScreen/ZoneLegend.tsx
Normal file
0
mobile/src/screens/ZonesScreen/ZoneLegend.tsx
Normal file
0
mobile/src/screens/ZonesScreen/index.tsx
Normal file
0
mobile/src/screens/ZonesScreen/index.tsx
Normal file
0
mobile/src/screens/ZonesScreen/useOccupancyGrid.ts
Normal file
0
mobile/src/screens/ZonesScreen/useOccupancyGrid.ts
Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user