Contributing to Ham2K PoLo
July 21, 2026 ยท View on GitHub
Thanks for helping improve PoLo.
Before You Start
Using mise is the easiest way to satisfy some of the local environment setup. Check it out here: https://mise.jdx.dev.
- Complete the React Native environment setup for your platform: https://reactnative.dev/docs/set-up-your-environment
- Ensure these required tools are available:
- Xcode + CocoaPods (for iOS work)
- Android Studio SDK/NDK (for Android work)
- If not using
mise, you will have to manually manage these dependencies:- Node.js 22
- Ruby 3.2
Initial Setup
# Recommended:
mise install
npm install
bundle install
bundle exec pod install --project-directory=ios
This installs:
- npm dependencies
- iOS pods
Environment Variables
.env controls app version/build and API keys.
At minimum, set MAPBOX_ACCESS_TOKEN:
MAPBOX_ACCESS_TOKEN=...
This token is required for local development, and local native builds need a token with downloads:read scope.
Other external services may also need API keys depending on the feature area you are working in.
Use the placeholders in .env for:
WWFF_API_KEYLLOTA_API_KEYTOTA_API_KEY
Daily Development
npm start # Metro
npm run ios # iOS simulator
npm run android # Android emulator/device
Quality checks:
npm run lint
npm test
If your local environment gets into a bad state:
npm run clean:all
npm start -- --reset-cache
Debug Menu
- iOS:
Cmd + D - Android:
Cmd + M(macOS) orCtrl + M(Windows/Linux)
iOS Simulator Tips
- Reference: https://www.iosdev.recipes/simctl/
xcrun simctl listapps bootedto list installed simulator apps.open \xcrun simctl get_app_container booted com.ham2k.polo data`/Documents` to open PoLo's Documents folder.open \xcrun simctl get_app_container booted com.apple.DocumentsApp groups |grep FileProvider.LocalStorage|sed "s/group.com.apple.FileProvider.LocalStorage//g"`/File\ Provider\ Storage` to open simulator Files local storage.
Resources
- Icons: https://pictogrammers.com/library/mdi/
- Icon tooling: https://icon.kitchen/
Translations (Crowdin)
Install the CLI:
brew tap crowdin/crowdin
brew install crowdin
Push base English source strings:
crowdin push sources
Pull translated strings:
crowdin pull translations
String suffix conventions:
-mdfor Markdown-formatted strings-a11yfor spoken accessibility labels_zero,_one,_otherfor pluralization
In-app translation testing:
- Create a personal access token at https://crowdin.com/settings#api-key
- In PoLo, enable Developer Mode and set the token in Developer Settings.
- Enter
CROWDINin the home screen quick lookup field to refresh language data.
Deep Linking
To test deep linking, you can use the following commands. The command is the URL
path, so use three slashes (com.ham2k:///qso?...); the host is reserved. Any
reserved character in a value (e.g. the / in a SOTA ref or a portable callsign)
must be percent-encoded.
export POLO_URL="com.ham2k:///qso?their.call=W1WC&mode=CW&freq=7200"
# iOS
xcrun simctl openurl booted "$POLO_URL"
# Android
adb shell am start -W -a android.intent.action.VIEW -d "$POLO_URL" com.ham2k.polo.alpha
Splash Screen Updates
- Start with a
2048x2048source image. - Generate image sets at https://www.appicon.co/#image-sets
- Replace
launch_screenassets in:android/app/src/main/res/*ios/polo/Images.xcassets/LaunchScreen.imagesetsrc/screens/StartScreen/img
Troubleshooting
Clean Build
npm run clean:js
npm run clean:android
npm run clean:ios
npm run clean:watchman
# or
npm run clean:all
# then
npm start -- --reset-cache
npm run ios
npm run android
"Unable to boot simulator" error for iOS Simulator
- Go to
About this Mac > Storage > Manage > Developer - Delete Xcode caches
- See: https://github.com/shinydevelopment/SimulatorStatusMagic
"unable to resolve module redux-persist/integration/react"
If redux-persist did not install correctly, run:
npm install redux-persist
Additional References
- React Native troubleshooting: https://reactnative.dev/docs/troubleshooting
Pull Requests
- Keep changes focused and small where possible.
- Include tests if you can, especially when behavior changes.
- Run lint/tests before opening a PR.
- In the PR description, include:
- What changed
- Why it changed
- Any migration or QA notes