-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.config.ts
More file actions
131 lines (127 loc) · 3.79 KB
/
Copy pathapp.config.ts
File metadata and controls
131 lines (127 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Load environment variables with proper priority (system > .env)
import "./scripts/load-env.js";
import type { ExpoConfig } from "expo/config";
// Bundle ID format: space.manus.<project_name_dots>.<timestamp>
// e.g., "my-app" created at 2024-01-15 10:30:45 -> "space.manus.my.app.t20240115103045"
// Bundle ID can only contain letters, numbers, and dots
// Android requires each dot-separated segment to start with a letter
const rawBundleId = "space.manus.study.planner.t20260319100047";
const bundleId =
rawBundleId
.replace(/[-_]/g, ".") // Replace hyphens/underscores with dots
.replace(/[^a-zA-Z0-9.]/g, "") // Remove invalid chars
.replace(/\.+/g, ".") // Collapse consecutive dots
.replace(/^\.+|\.+$/g, "") // Trim leading/trailing dots
.toLowerCase()
.split(".")
.map((segment) => {
// Android requires each segment to start with a letter
// Prefix with 'x' if segment starts with a digit
return /^[a-zA-Z]/.test(segment) ? segment : "x" + segment;
})
.join(".") || "space.manus.app";
// Extract timestamp from bundle ID and prefix with "manus" for deep link scheme
// e.g., "space.manus.my.app.t20240115103045" -> "manus20240115103045"
const timestamp = bundleId.split(".").pop()?.replace(/^t/, "") ?? "";
const schemeFromBundleId = `manus${timestamp}`;
const env = {
// App branding - update these values directly (do not use env vars)
appName: "学习计划",
appSlug: "study-planner",
// S3 URL of the app logo - set this to the URL returned by generate_image when creating custom logo
// Leave empty to use the default icon from assets/images/icon.png
logoUrl: "https://d2xsxph8kpxj0f.cloudfront.net/310519663455625790/nAenurpZZFtu6kkY8G8o38/icon-cExv8ugojCHBXJyrz6Kp5d.png",
scheme: schemeFromBundleId,
iosBundleId: bundleId,
androidPackage: bundleId,
};
const config: ExpoConfig = {
name: env.appName,
slug: env.appSlug,
version: "1.0.0",
orientation: "portrait",
icon: "./assets/images/icon.png",
scheme: env.scheme,
userInterfaceStyle: "automatic",
newArchEnabled: true,
ios: {
supportsTablet: true,
bundleIdentifier: env.iosBundleId,
"infoPlist": {
"ITSAppUsesNonExemptEncryption": false
}
},
android: {
adaptiveIcon: {
backgroundColor: "#E6F4FE",
foregroundImage: "./assets/images/android-icon-foreground.png",
backgroundImage: "./assets/images/android-icon-background.png",
monochromeImage: "./assets/images/android-icon-monochrome.png",
},
edgeToEdgeEnabled: true,
predictiveBackGestureEnabled: false,
package: env.androidPackage,
permissions: ["POST_NOTIFICATIONS"],
intentFilters: [
{
action: "VIEW",
autoVerify: true,
data: [
{
scheme: env.scheme,
host: "*",
},
],
category: ["BROWSABLE", "DEFAULT"],
},
],
},
web: {
bundler: "metro",
output: "static",
favicon: "./assets/images/favicon.png",
},
plugins: [
"expo-router",
"react-native-adapty",
[
"expo-audio",
{
microphonePermission: "Allow $(PRODUCT_NAME) to access your microphone.",
},
],
[
"expo-video",
{
supportsBackgroundPlayback: true,
supportsPictureInPicture: true,
},
],
[
"expo-splash-screen",
{
image: "./assets/images/splash-icon.png",
imageWidth: 200,
resizeMode: "contain",
backgroundColor: "#ffffff",
dark: {
backgroundColor: "#000000",
},
},
],
[
"expo-build-properties",
{
android: {
buildArchs: ["armeabi-v7a", "arm64-v8a"],
minSdkVersion: 24,
},
},
],
],
experiments: {
typedRoutes: true,
reactCompiler: true,
},
};
export default config;