Skip to content
Merged
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
16 changes: 16 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"permissions": {
"allow": [
"WebSearch",
"WebFetch(domain:docs.expo.dev)",
"Bash(npm test:*)",
"Bash(powershell.exe -ExecutionPolicy Bypass -File \"C:\\\\Users\\\\Justin\\\\workspace\\\\scorepad-react-native\\\\setup-node.ps1\")",
"Bash(npm --version)",
"Bash(npm install:*)",
"Bash(env)",
"Bash(npx expo:*)",
"Bash(ip route:*)",
"Bash(npx patch-package:*)"
]
}
}
11 changes: 6 additions & 5 deletions .github/workflows/beta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 14.x
- uses: expo/expo-github-action@8.2.1
node-version: 20.x
cache: 'npm'
- uses: expo/expo-github-action@v8
with:
expo-version: 4.x
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- run: yarn install
- run: expo publish --release-channel=beta
- run: npm ci
- run: eas update --channel preview --message "Beta push from CI"
2 changes: 1 addition & 1 deletion .github/workflows/node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

strategy:
matrix:
node-version: [18.x]
node-version: [20.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
*.orig.*
*.ipa
*.apk
*.app
*.tar.gz
*.tgz

coverage

# Ignore iOS and Android builds
ios/
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
legacy-peer-deps=true
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.18
20.19.4
260 changes: 260 additions & 0 deletions Contributing.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,263 @@
## Setup

### Prerequisites

| Tool | Version | Notes |
|------|---------|-------|
| nvm | latest | Node version manager |
| Node.js | 20.18 (via `.nvmrc`) | Installed via `nvm` |
| npm | (bundled with Node) | Used for all JS dependencies |
| EAS CLI | latest | Required for building and submitting |
| JDK | 17 | Android builds only |
| Xcode | latest stable | iOS builds only (macOS required) |
| Android Studio | latest stable | Android builds only (includes Android SDK) |
| CocoaPods | latest | iOS native code after `expo prebuild` |

### Install nvm & Node

```zsh
# Install nvm — https://github.com/nvm-sh/nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

# From the project root — installs and activates the version in .nvmrc (20.18)
nvm install
nvm use
```

### Install project dependencies

```zsh
npm install --legacy-peer-deps
```

> `--legacy-peer-deps` is required because some packages (e.g. `@reduxjs/toolkit`) have not yet declared React 19 peer dependency support, though they are compatible.

### Install EAS CLI

```zsh
npm install -g eas-cli
eas login # authenticate with your Expo account
eas whoami # verify login
```

### iOS — Xcode & CocoaPods

- Install Xcode from the Mac App Store and accept the license agreement
- Install CocoaPods:

```zsh
sudo gem install cocoapods
```

- After running `expo prebuild`, install native iOS dependencies:

```zsh
cd ios && pod install && cd ..
```

### Android — JDK 17 & Android Studio

- Install JDK 17 (e.g. via Homebrew: `brew install --cask temurin@17`)
- Install [Android Studio](https://developer.android.com/studio) and open the SDK Manager to install:
- Android SDK Platform (target API level)
- Android SDK Build-Tools
- Android Emulator
- Ensure `JAVA_HOME` points to your JDK 17 installation

---

## Windows (WSL) Setup

When developing on Windows, the recommended setup is to keep your code and terminal inside WSL2
while running Android Studio and the emulator natively on Windows. Three things need to be wired
up: the Android SDK path, the ADB server connection, and Metro bundler port access.

### 1. Point WSL to the Windows Android SDK

Add to `~/.bashrc` or `~/.zshrc`, replacing `<YourUsername>` with your Windows username:

```zsh
export ANDROID_HOME=/mnt/c/Users/<YourUsername>/AppData/Local/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin

# Points WSL's adb client at the Windows ADB server via the WSL gateway IP
export ANDROID_ADB_SERVER_HOST=$(ip route | grep default | awk '{print $3}')
```

Reload your shell:

```zsh
source ~/.bashrc
```

### 2. Install JDK 17 in WSL

Required for `--local` builds. Install JDK 17 inside WSL (do not rely on the Windows JDK):

```zsh
sudo apt update && sudo apt install -y openjdk-17-jdk
```

Add to `~/.bashrc` or `~/.zshrc`:

```zsh
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=$PATH:$JAVA_HOME/bin
```

### 3. ADB Connectivity

#### Windows Prerequisites

**A. Fix PowerShell execution policy**

Windows blocks all scripts by default. Run this once in PowerShell (no admin required):

```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```

This allows local scripts to run. Restart PowerShell after running it.

**B. Add `adb` to the Windows PATH**

Android Studio does not add `adb` to the PATH automatically. Add the `platform-tools` directory:

*Via PowerShell (one-liner):*
```powershell
$sdkPath = "$env:LOCALAPPDATA\Android\Sdk\platform-tools"
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";$sdkPath", "User")
```

*Or via System Settings:*
1. Open Start → search "Edit the system environment variables"
2. Click "Environment Variables"
3. Under "User variables", select `Path` → Edit → New
4. Add: `C:\Users\<YourUsername>\AppData\Local\Android\Sdk\platform-tools`
5. Click OK

Restart PowerShell, then verify:

```powershell
adb --version
```

---

WSL2 uses NAT networking — WSL's `adb` cannot reach the Windows ADB server on `localhost` by
default. The fix is a Windows port proxy that forwards the ADB port from the Windows gateway IP
to the local ADB server.

**Connect WSL ADB to the Windows ADB server**

Run once from **Windows PowerShell as Administrator**:

```powershell
# Start the Windows ADB server (daemonized)
adb start-server

# Forward the ADB port from the WSL-facing gateway IP to localhost
netsh interface portproxy add v4tov4 listenaddress=172.18.192.1 listenport=5037 connectaddress=127.0.0.1 connectport=5037

# Allow the connection through the firewall
netsh advfirewall firewall add rule name="WSL ADB" dir=in action=allow protocol=TCP localport=5037
```

> The `listenaddress` (`172.18.192.1`) is the default WSL2 gateway IP. If your gateway is
> different, check it from WSL with: `ip route | grep default`

Verify from WSL (with an emulator running):

```zsh
adb devices # should list the running emulator
```

### 4. Metro Bundler Port Forwarding

`npx expo start --dev-client` runs Metro inside WSL on port 8081. The Android emulator on Windows
cannot reach WSL's `localhost` by default. Choose one of the following options:

**Option A — Windows port proxy** (works on any Windows/WSL2 version)

Run from a **Windows PowerShell window as Administrator** (re-run after each WSL restart, since
the WSL IP changes):

```powershell
$wslIp = (wsl hostname -I).Trim().Split(" ")[0]
netsh interface portproxy add v4tov4 listenport=8081 listenaddress=0.0.0.0 connectport=8081 connectaddress=$wslIp
netsh interface portproxy add v4tov4 listenport=19000 listenaddress=0.0.0.0 connectport=19000 connectaddress=$wslIp
```

**Option B — Expo Tunnel** (simplest, no port forwarding needed)

```zsh
npx expo start --dev-client --tunnel
```

Requires a free Expo account. Routes traffic through ngrok.

**Option C — WSL Mirrored Networking** (Windows 11, see step 3 above)

With `networkingMode=mirrored` no port forwarding is needed.

### 5. Run on Android Emulator

**1. Start an emulator in Android Studio (Windows)**

- Open Android Studio → Device Manager (from the toolbar or View menu)
- Click the play (▶) button next to a virtual device and wait for it to fully boot

**2. Verify ADB sees the emulator from WSL**

```zsh
adb devices
```

Expected output:
```
List of devices attached
emulator-5554 device
```

If nothing appears, ensure the Windows ADB server is running (`adb start-server` from a Windows
terminal) and that the port proxy from step 3 is active.

**3. Build the development app (from WSL project root)**

```zsh
nvm use
npx expo prebuild --platform android
eas build --profile development --platform android --local
```

> Use `--platform android` with `expo prebuild` to skip iOS. The `@react-native-firebase` iOS
> plugin is incompatible with the Swift AppDelegate in Expo 53 and will error if you prebuild
> for both platforms on a non-Mac machine.

> The project includes a `.npmrc` with `legacy-peer-deps=true` so the build's internal
> `npm ci` step resolves correctly with React 19.

This compiles the APK using the Android SDK at `$ANDROID_HOME`. The first build takes several
minutes; subsequent builds are faster.

**4. Install on the running emulator**

```zsh
npx eas build:run -p android # select the build from the list
```

**5. Start Metro**

```zsh
npx expo start --dev-client
```

Ensure Windows port forwarding from step 4 above is active so the emulator can reach Metro.

---

## Build

Run any build command remotely by removing `--local` flag.
Expand Down
5 changes: 5 additions & 0 deletions app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export default {
buildNumber: '86',
infoPlist: {
RCTAsyncStorageExcludeFromBackup: false,
ITSAppUsesNonExemptEncryption: false,
},
googleServicesFile: './GoogleService-Info.plist',
},
Expand Down Expand Up @@ -106,13 +107,17 @@ export default {
githubUrl: 'https://github.com/wyne/scorepad-react-native',
owner: 'wyne',
plugins: [
'./plugins/firebase-mods',
'@react-native-firebase/app',
'@react-native-firebase/crashlytics',
'expo-image',
'expo-sharing',
[
'expo-build-properties',
{
ios: {
useFrameworks: 'static',
forceStaticLinking: ['RNFBApp', 'RNFBAnalytics', 'RNFBAuth', 'RNFBCrashlytics'],
},
},
],
Expand Down
8 changes: 4 additions & 4 deletions eas.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
},
"build": {
"development-simulator": {
"node": "18.18.2",
"node": "20.18.2",
"developmentClient": true,
"distribution": "internal",
"ios": {
Expand All @@ -17,7 +17,7 @@
}
},
"development": {
"node": "18.18.2",
"node": "20.18.2",
"developmentClient": true,
"distribution": "internal",
"ios": {
Expand All @@ -32,7 +32,7 @@
}
},
"preview": {
"node": "18.18.2",
"node": "20.18.2",
"distribution": "internal",
"ios": {
"resourceClass": "m-medium"
Expand All @@ -47,7 +47,7 @@
}
},
"production": {
"node": "18.18.2",
"node": "20.18.2",
"ios": {
"resourceClass": "m-medium"
},
Expand Down
4 changes: 3 additions & 1 deletion metro.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const { getDefaultConfig } = require('@expo/metro-config');

const defaultConfig = getDefaultConfig(__dirname);
defaultConfig.resolver.assetExts.push('cjs');
// NOTE: do NOT add 'cjs' to assetExts — it prevents Metro from executing
// .cjs files as JavaScript (e.g. superstruct/dist/index.cjs gets treated as
// a binary asset instead of a module).

module.exports = defaultConfig;
Loading
Loading