forked from Rockachopa/Timmy-time-dashboard
- Single-screen chat interface with Timmy's sovereign AI personality - Text messaging with real-time AI responses via server chat API - Voice recording and playback with waveform visualization - Image sharing (camera + photo library) with full-screen viewer - File attachments via document picker - Dark arcane theme matching the Timmy Time dashboard - Custom app icon with glowing T circuit design - Timmy system prompt ported from dashboard prompts.py - Unit tests for chat utilities and message types
131 lines
3.7 KiB
TypeScript
131 lines
3.7 KiB
TypeScript
// 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.timmy.chat.t20260226211148";
|
|
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: "Timmy Chat",
|
|
appSlug: "timmy-chat",
|
|
// 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://files.manuscdn.com/user_upload_by_module/session_file/310519663286296482/kuSmtQpNVBtvECMG.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: "#080412",
|
|
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",
|
|
[
|
|
"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: "#080412",
|
|
dark: {
|
|
backgroundColor: "#080412",
|
|
},
|
|
},
|
|
],
|
|
[
|
|
"expo-build-properties",
|
|
{
|
|
android: {
|
|
buildArchs: ["armeabi-v7a", "arm64-v8a"],
|
|
minSdkVersion: 24,
|
|
},
|
|
},
|
|
],
|
|
],
|
|
experiments: {
|
|
typedRoutes: true,
|
|
reactCompiler: true,
|
|
},
|
|
};
|
|
|
|
export default config;
|