This document contains all the necessary information for building Calendar Notifications Plus from source.
- Java Development Kit (JDK) 21.0.6-tem or compatible version
- Android SDK
- Node.js and Yarn
- React Native development environment
- WSL2 (for Windows development)
Using SDKMAN (recommended):
# Install SDKMAN
brew tap sdkman/tap
brew install sdkman-cli
# Install and use Java
sdk install java 21.0.6-tem
sdk use java 21.0.6-tem
We encountered a critical build issue with react-native-safe-area-context
that required a custom solution. While upgrading the SDK would typically be the preferred solution, this wasn't immediately viable as SDK upgrades were breaking core notification functionality that would require extensive testing and modifications to fix.
react-native-safe-area-context
and react-native-screens
are typically used together in React Navigation implementations:
react-native-screens
optimizes the native view hierarchy using platform componentsreact-native-safe-area-context
handles device-specific UI features (notches, status bars, etc.)- React Navigation expects both as peer dependencies
We needed react-native-screens
for the Data Sync UI, but react-native-safe-area-context
was causing build failures. Simply removing it wasn't an option due to React Navigation's dependencies.
We implemented a mock version of react-native-safe-area-context
that:
- Provides dummy implementations of required components
- Allows React Navigation to function without errors
- Avoids the problematic native code entirely
The mock is automatically created during yarn install
via a postinstall script:
node scripts/setup_safe_area_mock.js
Located in scripts/safe-area-mock-templates/
:
package.json
- Package metadatamodule-index.js
- ES modules implementationcommonjs-index.js
- CommonJS implementationtypescript-index.d.ts
- TypeScript definitions
This approach allows us to:
- Keep using React Navigation without errors
- Avoid the build issues from the native implementation
- Maintain consistent behavior in development and CI
- Easily maintain the mock implementation
# Install dependencies
yarn
# Start Metro bundler
yarn start
cd C:\Users\<username>\appdata\local\android\sdk
.\emulator\emulator.exe -avd 7.6_Fold-in_with_outer_display_API_34q
Follow these steps to set up ADB in WSL:
sudo ln -s /mnt/c/Users/<username>/AppData/Local/Android/Sdk/platform-tools/adb.exe /home/<username>/android/platform-tools/adb
# Get the WSL2 IP address
WSL_VM_IP_ADDRESS=$(ifconfig eth0 | awk '/inet / {print $2}')
# Get the Windows HOST IP address (if needed)
HOST_IP_ADDRESS=$(ipconfig.exe | awk '/Ethernet adapter vEthernet \(Default Switch\):/{i=1; next} i && /IPv4 Address/{print $NF; exit}' | sed 's/^[ \t]*//')
# Open the developer menu
adb shell input keyevent 82
# Input the IP address
adb shell input text "${WSL_VM_IP_ADDRESS}:8081"
# get wsl hostname
$(wsl hostname -I)
# portforward host port to wsl vm
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 connectaddress=$(wsl hostname -I) connectport=8081
# open firewall
New-NetFirewallRule -DisplayName 'WSL Web Server' -Direction Inbound -Protocol TCP -LocalPort 8081 -Action Allow
# get your host ip address
Get-NetIPAddress | Where-Object { $_.AddressFamily -eq 'IPv4' -and $_.PrefixOrigin -eq 'Dhcp' } | Select-Object -ExpandProperty IPAddress
x# get rid of all rules when done if you want
netsh interface portproxy reset
New-NetFirewallRule -DisplayName 'WSL Web Server' -Direction Inbound -Protocol TCP -LocalPort 8081 -Action Allow
- Build the bundle:
yarn react-native bundle --platform android --dev false --entry-file index.tsx --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
- Follow Android Studio instructions for release build configuration
Refer to .github/workflows/actions.yml
for the complete CI build process.
See CR_SQLITE_BUILD.md for detailed instructions on building cr-sqlite for Android.