Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM node:24-alpine

# Match the web container's lightweight base setup.
RUN apk add \
git \
tini \
bash

RUN npm install -g @expo/ngrok

WORKDIR /shared

# Copy entrypoint script first and verify it exists
COPY ./entrypoint.sh /entrypoint.sh
RUN ls -la /entrypoint.sh && chmod +x /entrypoint.sh

COPY ./.env /

EXPOSE 8081 19000 19001 19002 19006

ENTRYPOINT ["tini", "--", "/entrypoint.sh"]
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
npx expo start -c
```

## API configuration

Development builds default to the local API instead of production.

- iOS simulator and Expo web use `http://localhost:3000`
- Android emulator uses `http://10.0.2.2:3000`
- Physical devices should set `API_URL=http://<your-machine-ip>:3000` in `dev/rp-mobile/.env`

In the output, you'll find options to open the app in a

- [development build](https://docs.expo.dev/develop/development-builds/introduction/)
Expand Down
2 changes: 1 addition & 1 deletion app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ export default {
typedRoutes: true,
},
extra: {
appEnv: process.env.ENV,
googleClientId: process.env.OAUTH_GOOGLE_CLIENT_ID,
apiUrl: process.env.API_URL || 'https://api.reflectionsprojections.org',
},
},
};
5 changes: 3 additions & 2 deletions app/(auth)/sign-in.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import ReflectionsProjections from '@/assets/images/rp_2025.svg';
import LoginIcon from '@/assets/icons/logos/rp_signin_logo.svg';
import Background from '@/assets/background/rp_background.svg';
import { googleAuth } from '@/lib/auth';
import { OAUTH_CONFIG } from '@/lib/config';

export default function SignInScreen() {
const router = useRouter();
Expand All @@ -33,8 +34,8 @@ export default function SignInScreen() {
setIsLoading(true);

const redirectUri = AuthSession.makeRedirectUri({
scheme: 'com.googleusercontent.apps.693438449476-tmppq76n7cauru3l0gvk32mufrd7eoq0',
path: '/(auth)/callback',
scheme: OAUTH_CONFIG.REDIRECT_SCHEME,
path: OAUTH_CONFIG.REDIRECT_PATH,
});

const authResult = await googleAuth();
Expand Down
29 changes: 29 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash
set -euo pipefail

echo -e "\033[1m\033[36mStarting RP Mobile Container 🚀\033[0m"

cd /shared

if [ ! -f package.json ]; then
echo "Mobile app not found at /shared"
exit 1
fi

echo -e "\033[1mInstalling mobile dependencies...\033[0m"
yarn install

case "${MOBILE_COMMAND:-start}" in
start)
exec npx expo start --port 8081 --tunnel
;;
start-clear)
exec npx expo start -c --port 8081 --tunnel
;;
start-web)
exec npx expo start --web --port 19006
;;
*)
exec "$@"
;;
esac
4 changes: 2 additions & 2 deletions lib/auth.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as SecureStore from 'expo-secure-store';
import * as AuthSession from 'expo-auth-session';
import * as WebBrowser from 'expo-web-browser';
import { OAUTH_CONFIG } from './config';
import { API_CONFIG, OAUTH_CONFIG } from './config';

// Complete the auth session
WebBrowser.maybeCompleteAuthSession();

export async function validateAuthToken(): Promise<boolean> {
try {
const response = await fetch('https://api.reflectionsprojections.org/auth/info', {
const response = await fetch(`${API_CONFIG.BASE_URL}/auth/info`, {
method: 'GET',
headers: {
Authorization: (await SecureStore.getItemAsync('jwt')) || '',
Expand Down
14 changes: 12 additions & 2 deletions lib/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import Constants from 'expo-constants';
import { Platform } from 'react-native';

const PRODUCTION_API_URL = 'https://api.reflectionsprojections.org';

const DEVELOPMENT_API_URL =
Platform.OS === 'android' ? 'http://10.0.2.2:3000' : 'http://localhost:3000';

const configuredApiUrl = Constants.expoConfig?.extra?.apiUrl || process.env.API_URL;
const configuredAppEnv = Constants.expoConfig?.extra?.appEnv || process.env.ENV;

export const OAUTH_CONFIG = {
IOS_GOOGLE_CLIENT_ID:
Expand All @@ -11,8 +20,9 @@ export const OAUTH_CONFIG = {

export const API_CONFIG = {
BASE_URL:
//Constants.expoConfig?.extra?.apiUrl ||
process.env.API_URL || 'https://api.reflectionsprojections.org',
configuredAppEnv === 'PRODUCTION'
? PRODUCTION_API_URL
: configuredApiUrl || DEVELOPMENT_API_URL,
TIMEOUT: 10000,
};

Expand Down
Loading