feat: Expo mobile app scaffold (118-file structure) #80

Open
MaTriXy wants to merge 1 commits from MaTriXy/feat/mobile-scaffold into main
123 changed files with 16699 additions and 0 deletions

1
mobile/.env.example Normal file
View File

@@ -0,0 +1 @@
EXPO_PUBLIC_DEFAULT_SERVER_URL=http://192.168.1.100:8080

26
mobile/.eslintrc.js Normal file
View 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
View 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
View File

@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}

25
mobile/App.tsx Normal file
View 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
View 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
View 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"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

9
mobile/babel.config.js Normal file
View File

@@ -0,0 +1,9 @@
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
'react-native-reanimated/plugin'
]
};
};

View File

View File

View File

View File

View File

View File

View File

17
mobile/eas.json Normal file
View 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
View File

@@ -0,0 +1,4 @@
import { registerRootComponent } from 'expo';
import App from './App';
registerRootComponent(App);

8
mobile/jest.config.js Normal file
View 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
View 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

File diff suppressed because it is too large Load Diff

49
mobile/package.json Normal file
View 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
}

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

@@ -0,0 +1,5 @@
describe('placeholder', () => {
it('passes', () => {
expect(true).toBe(true);
});
});

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

Some files were not shown because too many files have changed in this diff Show More