Skip to content

Commit 19cf2fb

Browse files
authored
Merge pull request #4 from Oreolion/mobile-app
feat: add React Native mobile app (Expo + NativeWind + Reown AppKit)
2 parents 589f77f + e51f15b commit 19cf2fb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+22670
-0
lines changed

mobile/.gitignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2+
3+
# dependencies
4+
node_modules/
5+
6+
# Expo
7+
.expo/
8+
dist/
9+
web-build/
10+
expo-env.d.ts
11+
12+
# Native
13+
.kotlin/
14+
*.orig.*
15+
*.jks
16+
*.p8
17+
*.p12
18+
*.key
19+
*.mobileprovision
20+
21+
# Metro
22+
.metro-health-check*
23+
24+
# debug
25+
npm-debug.*
26+
yarn-debug.*
27+
yarn-error.*
28+
29+
# macOS
30+
.DS_Store
31+
*.pem
32+
33+
# local env files
34+
.env*.local
35+
36+
# typescript
37+
*.tsbuildinfo
38+
39+
# generated native folders
40+
/ios
41+
/android

mobile/app.config.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { ExpoConfig, ConfigContext } from "expo/config";
2+
3+
export default ({ config }: ConfigContext): ExpoConfig => ({
4+
...config,
5+
name: "e-Story",
6+
slug: "estory-mobile",
7+
version: "1.0.0",
8+
orientation: "portrait",
9+
icon: "./assets/icon.png",
10+
userInterfaceStyle: "automatic",
11+
newArchEnabled: true,
12+
splash: {
13+
image: "./assets/splash-icon.png",
14+
resizeMode: "contain",
15+
backgroundColor: "#0f172a",
16+
},
17+
ios: {
18+
supportsTablet: true,
19+
bundleIdentifier: "com.estory.mobile",
20+
infoPlist: {
21+
NSMicrophoneUsageDescription:
22+
"e-Story needs microphone access to record voice journals.",
23+
NSSpeechRecognitionUsageDescription:
24+
"e-Story uses speech recognition to transcribe your stories.",
25+
NSCameraUsageDescription:
26+
"e-Story needs camera access to update your profile photo.",
27+
},
28+
},
29+
android: {
30+
adaptiveIcon: {
31+
foregroundImage: "./assets/adaptive-icon.png",
32+
backgroundColor: "#0f172a",
33+
},
34+
package: "com.estory.mobile",
35+
permissions: [
36+
"RECORD_AUDIO",
37+
"CAMERA",
38+
"POST_NOTIFICATIONS",
39+
"VIBRATE",
40+
],
41+
},
42+
web: {
43+
favicon: "./assets/favicon.png",
44+
},
45+
scheme: "estory",
46+
plugins: [
47+
"expo-router",
48+
"expo-secure-store",
49+
[
50+
"expo-notifications",
51+
{
52+
icon: "./assets/icon.png",
53+
color: "#7c3aed",
54+
},
55+
],
56+
[
57+
"expo-av",
58+
{
59+
microphonePermission:
60+
"Allow e-Story to access your microphone for voice recording.",
61+
},
62+
],
63+
],
64+
extra: {
65+
API_BASE_URL: process.env.API_BASE_URL || "https://istory.vercel.app",
66+
SUPABASE_URL: process.env.SUPABASE_URL || "",
67+
SUPABASE_ANON_KEY: process.env.SUPABASE_ANON_KEY || "",
68+
WALLETCONNECT_PROJECT_ID: process.env.WALLETCONNECT_PROJECT_ID || "",
69+
GOOGLE_CLIENT_ID_IOS: process.env.GOOGLE_CLIENT_ID_IOS || "",
70+
GOOGLE_CLIENT_ID_ANDROID: process.env.GOOGLE_CLIENT_ID_ANDROID || "",
71+
eas: {
72+
projectId: process.env.EAS_PROJECT_ID || "",
73+
},
74+
},
75+
});

mobile/app.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"expo": {
3+
"name": "e-Story",
4+
"slug": "estory-mobile",
5+
"version": "1.0.0",
6+
"orientation": "portrait",
7+
"icon": "./assets/icon.png",
8+
"userInterfaceStyle": "automatic",
9+
"scheme": "estory",
10+
"newArchEnabled": true,
11+
"splash": {
12+
"image": "./assets/splash-icon.png",
13+
"resizeMode": "contain",
14+
"backgroundColor": "#0f172a"
15+
},
16+
"ios": {
17+
"supportsTablet": true,
18+
"bundleIdentifier": "com.estory.mobile"
19+
},
20+
"android": {
21+
"adaptiveIcon": {
22+
"foregroundImage": "./assets/adaptive-icon.png",
23+
"backgroundColor": "#0f172a"
24+
},
25+
"package": "com.estory.mobile",
26+
"edgeToEdgeEnabled": true
27+
},
28+
"web": {
29+
"favicon": "./assets/favicon.png"
30+
},
31+
"plugins": [
32+
"expo-router",
33+
"expo-secure-store",
34+
"expo-web-browser",
35+
[
36+
"expo-notifications",
37+
{
38+
"icon": "./assets/icon.png",
39+
"color": "#7c3aed"
40+
}
41+
]
42+
]
43+
}
44+
}

mobile/app/(tabs)/_layout.tsx

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Tab Layout - Bottom navigation with 5 tabs
2+
import React from "react";
3+
import { Tabs } from "expo-router";
4+
import { View, Text } from "react-native";
5+
import {
6+
Home,
7+
Mic,
8+
Archive,
9+
Users,
10+
User,
11+
} from "lucide-react-native";
12+
import { useAuthStore } from "../../stores/authStore";
13+
14+
export default function TabLayout() {
15+
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
16+
17+
return (
18+
<Tabs
19+
screenOptions={{
20+
headerShown: false,
21+
tabBarStyle: {
22+
backgroundColor: "#0f172a",
23+
borderTopColor: "#1e293b",
24+
borderTopWidth: 1,
25+
height: 80,
26+
paddingBottom: 20,
27+
paddingTop: 8,
28+
},
29+
tabBarActiveTintColor: "#a78bfa",
30+
tabBarInactiveTintColor: "#64748b",
31+
tabBarLabelStyle: {
32+
fontSize: 11,
33+
fontWeight: "600",
34+
},
35+
}}
36+
>
37+
<Tabs.Screen
38+
name="index"
39+
options={{
40+
title: "Home",
41+
tabBarIcon: ({ color, size }) => (
42+
<Home size={size} color={color} />
43+
),
44+
}}
45+
/>
46+
<Tabs.Screen
47+
name="record"
48+
options={{
49+
title: "Record",
50+
tabBarIcon: ({ color, size }) => (
51+
<View
52+
className="rounded-full bg-primary p-2"
53+
style={
54+
isAuthenticated
55+
? { backgroundColor: "#7c3aed" }
56+
: { backgroundColor: "#374151" }
57+
}
58+
>
59+
<Mic size={size - 4} color="#fff" />
60+
</View>
61+
),
62+
}}
63+
/>
64+
<Tabs.Screen
65+
name="library"
66+
options={{
67+
title: "Archive",
68+
tabBarIcon: ({ color, size }) => (
69+
<Archive size={size} color={color} />
70+
),
71+
}}
72+
/>
73+
<Tabs.Screen
74+
name="social"
75+
options={{
76+
title: "Community",
77+
tabBarIcon: ({ color, size }) => (
78+
<Users size={size} color={color} />
79+
),
80+
}}
81+
/>
82+
<Tabs.Screen
83+
name="profile"
84+
options={{
85+
title: "Profile",
86+
tabBarIcon: ({ color, size }) => (
87+
<User size={size} color={color} />
88+
),
89+
}}
90+
/>
91+
</Tabs>
92+
);
93+
}

0 commit comments

Comments
 (0)