Skip to content

Add VoIP calling functionality to Fishjam - #575

Merged
Magmusacy merged 23 commits into
mainfrom
feature/voip-calls
Jul 29, 2026
Merged

Add VoIP calling functionality to Fishjam#575
Magmusacy merged 23 commits into
mainfrom
feature/voip-calls

Conversation

@Magmusacy

@Magmusacy Magmusacy commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Description

Adds VoIP calling to the Fishjam React Native SDK. Calls ring through the native call UI —
CallKit on iOS, Core Telecom on Android — even when the app is backgrounded or killed, and the
media runs over a regular Fishjam room.

SDK — @fishjam-cloud/react-native-client

  • VoIPProvider + useVoIP(): a call state machine (available → incoming | connecting → active)
    driven by native call events. The SDK owns the CallKit/Telecom session, the VoIP push token, and
    hold/mute/end-reason state; joining the room, peer tokens and media stay in the app, which reacts
    to status and reports back with reportConnected() / reportConnectFailed().
  • Also re-exports the lower-level primitives from the WebRTC fork (useVoIPEvents, useTelecom,
    fulfillIncomingCallConnected, …) for apps that want to drive the native layer themselves.
  • Config plugin: new android.enableVoIP, FCM coexistence options (voipMessagingService,
    voipFallbackMessagingService) and a voip block for the native call timeouts and notification
    icon. On Android it injects the manifest entries (IncomingCallActivity,
    EndCallNotificationReceiver, PushNotificationService + FCM intent filter), the required
    permissions and the foreground service. On iOS it writes FishjamVoIPEnabled, the timeout
    Info.plist keys and the INStartCallIntent activity types needed for Recents redial.

New package — @fishjam-cloud/ios-expo-voip

An ExpoAppDelegateSubscriber with no JS and no VoIP logic of its own. It starts the PushKit
registry at launch so a push arriving before the JS bundle loads can still ring, and routes
Siri / Phone-app Recents intents into the SDK. It is a no-op unless the config plugin enabled VoIP.
Added to the release workflow (published after the WebRTC fork, which its pod depends on) and to
bump-version.sh; excluded from typedoc.

Example — examples/mobile-client/voip-call

A two-user calling app: an Expo client plus a small Deno push + signaling server
(/register, /users, /call, /ws) that sends the APNs/FCM pushes. It exercises the whole
surface — device registration, ringing while killed, hold & accept, and Recents redial.

Motivation and Context

Fishjam could already carry the media for a call, but not the call itself. To build one-to-one
calling on top of it, an app had to write its own CallKit and Core Telecom integration, VoIP push
handling, cold-start wake-up and answer-fulfillment handshake before it could join a room — a large
amount of platform-specific native work, duplicated by every consumer.

This moves that layer into the SDK. The app keeps what is genuinely its own (rooms, peer tokens,
media, signaling between users) and reacts to a single status value, while the SDK owns the native
call session on both platforms.

Documentation impact

  • Documentation update required
  • Documentation updated in another PR
  • No documentation update required

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to
    not work as expected)

MiloszFilimowski and others added 20 commits June 15, 2026 16:45
- Starter app for VoIP calls integration
- Starter app for VoIP calls integration
…IOS (#557)

## Description

Adds a complete iOS VoIP calling example
(examples/mobile-client/voip-call/) showing how to wire native PushKit
VoIP pushes and CallKit into a Fishjam call, end to end:

- Example app (Expo / React Native):
- VoipProvider + useVoip context that owns the call lifecycle (available
→ incoming/connecting → active), driving the Fishjam connection (join on
answer/start, leave on end) and the CallKit session. Media (mic/camera)
is acquired before joining so tracks publish reliably.
- Screens matching the fishjam-chat look & feel: Login, Directory,
Outgoing call, and an In-call screen with an audio layout and a
FaceTime-style video layout (remote full-screen + local PiP).
- Reusable UI (Avatar, InCallButton, VideoCallView), a shared theme, and
login persistence via AsyncStorage with logout.
- A minimal Deno signaling backend (server/) using certificate-based
APNs auth to send VoIP pushes, with setup docs.
- SDK: exports useVoIPEvents (and VoIPEventHandlers /
VoipIncomingPayload types) from @fishjam-cloud/mobile-client, so apps
can subscribe to PushKit/CallKit events (token registered, incoming,
answered, ended) from JS.
- Submodule bump: packages/react-native-webrtc is moved forward to pick
up the native PushKit registration + CallKit incoming-call reporting
that the example relies on.

## Motivation and Context

The mobile SDK already had CallKit primitives, but there was no
end-to-end reference for the full native VoIP flow - receiving a PushKit
push while backgrounded, presenting the system incoming-call UI via
CallKit, and connecting that to a Fishjam room. This PR provides that
reference implementation plus the useVoIPEvents bridge and a sample
backend, so developers can see and reproduce the whole path.

## Documentation impact

- [X] Documentation update required
- [ ] Documentation updated [in another PR](_)
- [ ] No documentation update required

## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to
      not work as expected)

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
## Description

Added android side of voip-calls

## Motivation and Context

Now both users from android and ios can access voip-calls functionality

## Documentation impact

- [X] Documentation update required
- [ ] Documentation updated [in another PR](_)
- [ ] No documentation update required

## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to
      not work as expected)
…waiting and Recents redial to VoIP calls (#562)

## Description

Disclaimer: for now I'm using expo plugins to configure appDelegate on
iOS but I will fix it to use our wrapper package in future PR

Builds on the Android integration from #561 with the remaining
call-lifecycle and native-call features:

- **WebSocket call signaling** (`useCallSignaling`, server support) with
an answer-to-connect handshake on iOS and Android — the native call UI
only reports the call as connected once the callee has actually joined,
with a `connecting` state in between (`fulfillIncomingCallConnected` /
`failIncomingCallConnected`, `reportOutgoingCallConnected`).
- **Native call timeouts** for incoming, outgoing, and
answer-fulfillment phases, configurable via new plugin options on iOS
and Android.
- **Hold / resume** (`setCallHeld`, `isCallHeld`) and **call waiting**
for a second incoming call (via a `react-native-webrtc` submodule bump).
- **Native mute surfaced to JS** and end-call events with reasons, so
the app stays in sync with CallKit/Telecom actions.
- **`enableCallIntents` plugin option** so calls appear in the system
Recents and can be redialed from there (iOS).
- **Example polish** — Fishjam branding (icons, splash), server-served
fish avatars, `DirectoryScreen` → `UsersScreen`, speaker toggle fixes,
and camera PIP improvements.

## Motivation and Context

#561 made basic calls work on both platforms, but the example didn't yet
behave like a real phone app: answering connected immediately even if
signaling later failed, unanswered calls rang forever, there was no hold
or second-call handling, and muting from the native call UI desynced the
app. This PR closes those gaps so the example serves as a complete
reference for production VoIP behavior on Fishjam.

## Documentation impact

- [x] Documentation update required
- [ ] Documentation updated [in another PR](_)
- [ ] No documentation update required

## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to
      not work as expected)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
## Description

Replaces the `withAppDelegate` regex block in the iOS config plugin with
a proper Expo module.

- **New package `@fishjam-cloud/expo-voip`** — glue-only, iOS-only, no
JS. One `ExpoAppDelegateSubscriber` that registers PushKit at launch and
forwards `INStart*` call intents. Both gated on the `FishjamVoipEnabled`
Info.plist flag.
- **`withFishjamIos.ts`** — regex block deleted. The plugin now just
writes `FishjamVoipEnabled` and throws if `voip` options are set without
the new package installed.
- **`react-native-webrtc` submodule bump** — `DEFINES_MODULE => YES` so
the Swift subscriber can `import FishjamReactNativeWebrtc`.

No Info.plist keys are lost. Verified on device: the subscriber runs at
launch, a VoIP token is issued, and the device registers.

## Motivation and Context

The old approach string-spliced generated Swift in `AppDelegate.swift`.
It silently no-ops whenever Expo changes its template or the regex stops
matching — and the failure mode is an app that builds and launches fine
but can never receive a call. It also forced consumers to hand-add a
bridging-header import and an early `registerForVoIPPushes()` call.

`ExpoAppDelegateSubscriber` is the supported extension point for this.
It's re-applied by autolinking instead of patching generated code, so it
survives prebuild, and both manual steps go away.

## Documentation impact

- [x] Documentation update required
- [ ] Documentation updated [in another PR](_)
- [ ] No documentation update required

The VoIP README still documents the old flow (hand-editing
`AppDelegate.swift`, bridging header) and wrongly claims
`aps-environment` is already present and should be set in Xcode.

## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to
      not work as expected)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…to the app's other notification library (#564)

## Description

Android delivers each FCM message to exactly one `MESSAGING_EVENT`
service per app, so
our VoIP `PushNotificationService` used to swallow every push — apps
also using
expo-notifications or `@react-native-firebase/messaging` silently lost
all their
notifications and token callbacks (repro'd on baseline: builds clean,
expo receives
nothing).

This PR makes the two coexist:

- **Explicit payload discriminator** — a data message is a call iff it
carries
`fishjam: "voip-incoming"` (namespaced key, typed value so future kinds
like a cancel
  push fit the same key). The example server now sends it.
- **Native relay** — non-VoIP messages, token callbacks (`onNewToken` +
`onRegistered`),
and `onDeletedMessages` are handed to the app's other messaging service,
configured via
`VoipFallbackMessagingService` manifest meta-data. The fallback class is
instantiated
reflectively (`attachBaseContext` injected, same pattern Braze uses in
production), so
its real native code runs — killed-state behavior preserved, no JS
required.
- **Config plugin** — new `android.voipFallbackMessagingService` option
(`"expo-notifications"`, `"@react-native-firebase/messaging"`, or a
class name):
writes the meta-data, strips the library's own service with
`tools:node="remove"`,
and gives ours `android:priority="1"`. New
`android.voipMessagingService: false`
  opt-out for apps bringing their own dispatcher.
- **Escape hatch** — public
`PushNotificationService.handleVoipMessage(context, message):
Boolean` / `handleNewToken(token)` for apps that own their messaging
service.

## Motivation and Context

A host app cannot currently use any other push-notification library
alongside Fishjam
VoIP on Android: our service claims the single FCM slot and drops
everything that isn't a
call — with no error anywhere (the manifest merges fine;
expo-notifications even ships its
service at priority −1, so ours always wins and theirs is dead code).
This is a hard
blocker for real apps, which virtually always have non-VoIP
notifications.
## Documentation impact

- [ ] Documentation update required
- [ ] Documentation updated [in another PR](_)
- [x] No documentation update required

(README §9.6 "Coexisting with other push-notification libraries" —
setup, wire format,
bare-RN recipe, dispatcher example — is included in this PR.)

## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to
      not work as expected)

### ✅ Runtime-tested (Pixel 9 emulator, real FCM v1 sends,
expo-notifications 0.32.17 as fallback)

| Test | Result |
|---|---|
| Merged manifest / `dumpsys`: our service sole `MESSAGING_EVENT`
handler, expo's removed | ✅ |
| Token relay → expo's `onNewToken` (its token listeners keep working) |
✅ |
| Non-VoIP push → relayed → expo JS listener received full payload (25
ms e2e) | ✅ |
| Non-VoIP push, **app killed** (`pidof` empty) → native relay, expo
shows notification | ✅ |
| VoIP push (`fishjam: "voip-incoming"`) rings in fg / bg / killed | ✅ |
| Foreign payload containing `roomName` but no/wrong `fishjam` key →
relayed, no phantom call | ✅ |
| Baseline (no relay) + expo-notifications: builds fine, but expo
silently receives **nothing** — the bug this PR fixes | ✅ repro'd |

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
# Conflicts:
#	.github/workflows/release.yaml
#	package.json
#	packages/mobile-client/src/index.ts
#	packages/react-native-webrtc
#	release-automation/bump-version.sh
## Description

Moves `VoipProvider` and `useVoip` out of the `voip-call` example app
and into
`@fishjam-cloud/react-native-client` as public SDK API.

- `VoipProvider` is an **opt-in wrapper component**, mounted inside
`FishjamProvider`,
whose connection it drives. It registers the native CallKit/Telecom
listeners and
tracks the state of the current call. Apps that don't need native calls
simply don't
  mount it — no listeners, no cost for plain video apps.
- New public exports: `VoipProvider`, `VoipProviderProps`, `useVoip`,
`VoipCallStatus`,
`CurrentCall`, `VoipContextValue`. `useVoip` is the single hook for the
call
lifecycle (`status`, `currentCall`, `voipToken`, `lastEndedReason`,
`isOnHold`,
  `startCall`, `answerCall`, `endCall`, `setCallHeld`).
- App-specific glue stays in the app and is injected as props on
`VoipProvider`:
`getPeerToken`, `requestCall`, `onWaitingCallDeclined`, plus the
`isVideo` and
  `canStartOutgoingCall` switches.
- **Behaviour change** — accepted waiting calls: `onIncoming` now treats
a payload for
a different room while already joined as an accepted waiting call, and
tears the old
room down inline before joining the new one, so the client can never sit
in two rooms
at once. A guard stops the "no remote peers" watchdog from mistaking the
brief
  peerless window during the swap for the remote hanging up.
- Example updated to consume the SDK API: `App.tsx` reordered so
`UserProvider` sits
above `FishjamProvider`, the wrapper renamed `VoipWrapper` →
`FishjamWithVoip`, and
  the local `src/voip/` folder deleted.
- `withFishjamIos.ts` drops a now-unused `withAppDelegate` import — the
AppDelegate
  glue lives in `@fishjam-cloud/ios-expo-voip`.
- Bumps the `packages/react-native-webrtc` submodule.

## Motivation and Context

We need native VoIP calls supported by the SDK itself. The only working
implementation
lived in the `voip-call` example, so any app that wanted CallKit/Telecom
calls had to
copy the provider out of the example and maintain its own fork of it.
Promoting it into
`@fishjam-cloud/react-native-client` makes it a clear, supported API
that ships and
versions with the SDK.

## Documentation impact

- [x] Documentation update required
- [ ] Documentation updated [in another PR](_)
- [ ] No documentation update required

## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to
  not work as expected)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
## Description

`VoipProvider` is now only the native CallKit / Core-Telecom call state
machine.
Joining and leaving the room, peer tokens and camera/mic lifecycle move
to the app.

- Props reduced to `isVideo` and `onWaitingCallDeclined`. Removed
`getPeerToken`,
  `requestCall`, `canStartOutgoingCall`.
- `useVoip()` gains `reportConnected()` / `reportConnectFailed()`, which
the app calls
when its own join succeeds or fails. This fulfills CallKit's answer
action.
- `useVoip()` also gains `isMuted` and `pendingCallIntent` /
`clearCallIntent()`.
- `answerCall` removed — an answer can only originate from the system
call UI. (we only supported it anyway because we always shown the
ssystem notification)
- `startCall(to, roomName)` only reports the call to CallKit; it no
longer signals or joins.
- Hold and mute are reported as state instead of applied to tracks the
SDK doesn't own.

Example app gains `src/voip/useVoipRoomConnection.ts` (join/leave,
report connected,
apply hold and mute) and `src/voip/usePlaceCall.ts` (room name,
signaling, `startCall`).

## Motivation and Context

Adopting VoIP previously meant handing your connection to the SDK:
`VoipProvider` had to
live inside `FishjamProvider`, took over join/leave, and only offered a
`getPeerToken`
hole to fill. Now a VoIP call connects through the same code as any
other Fishjam session.

Fulfilling CallKit's answer action can't move, since the `requestId` is
a native handle
only the SDK sees — hence the `reportConnected()` acknowledgement.

## Documentation impact

- [x] Documentation update required
- [ ] Documentation updated [in another PR](_)
- [ ] No documentation update required

## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to
      not work as expected)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…ce fixes (#574)

## Description

- **`reportConnected`'s failure branches end only their own call.** The
fulfil-failed and catch branches ended whatever call was current after
the native await, so a call-waiting swap mid-fulfil tore down the
freshly accepted call. They now end the call only if the one captured at
entry is still current — the same identity re-check the success path
already does.
- **Submodule bump** to `fishjam-react-native-webrtc@9636038` — the
CallKitManager/CallManager/VoipManager race fixes
(fishjam-cloud/fishjam-react-native-webrtc#77). Merge that PR first so
the pointer lands on `feature/voip-calls`.

## Motivation and Context

Found in a deep review of the VoIP call flow: an internal race between a
call-waiting swap and an in-flight `reportConnected`, not avoidable by
the app. Verified with `tsc --noEmit`, eslint, prettier, and an
adversarial review pass.

## Documentation impact

- [ ] Documentation update required
- [ ] Documentation updated [in another PR](_)
- [x] No documentation update required

## Types of changes

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to
      not work as expected)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class VoIP calling support to the Fishjam React Native SDK, including native call UI integration (CallKit on iOS / Telecom on Android), Expo config-plugin automation for required native configuration, and a full end-to-end example app + push/signaling server.

Changes:

  • Introduces a VoIPProvider + useVoIP() call state machine in @fishjam-cloud/react-native-client, plus re-exports of lower-level VoIP primitives from the WebRTC fork.
  • Extends the Expo config plugin to support Android VoIP manifest injection and iOS VoIP Info.plist/intents configuration; adds the new @fishjam-cloud/ios-expo-voip package for AppDelegate glue.
  • Adds a voip-call example (Expo app + Deno server) and updates release/versioning automation to publish/version the new package.

Reviewed changes

Copilot reviewed 54 out of 67 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
yarn.lock Adds workspace + example dependencies for VoIP packages/apps
typedoc.json Excludes packages/ios-expo-voip from Typedoc
spelling.txt Adds “Recents” to allowlist
release-automation/bump-version.sh Versions the new @fishjam-cloud/ios-expo-voip workspace
packages/mobile-client/src/voip/VoIPProvider.tsx Implements VoIP call state machine driven by native events
packages/mobile-client/src/voip/VoIPContext.ts Defines VoIP context types + useVoIP() hook
packages/mobile-client/src/index.ts Re-exports VoIP APIs and primitives from the SDK entrypoint
packages/mobile-client/README.md Documents Android VoIP setup + timeouts for Expo/bare RN
packages/mobile-client/plugin/src/withFishjamVoIPAndroid.ts Adds Android VoIP manifest + permissions + timeout metadata injection
packages/mobile-client/plugin/src/withFishjamVoIP.ts Duplicate/unused Android VoIP plugin implementation (see comment)
packages/mobile-client/plugin/src/withFishjamIos.ts Adds iOS VoIP timeout keys, enables iOS Expo VoIP glue, declares Recents intents
packages/mobile-client/plugin/src/withFishjamAndroid.ts Wires VoIP plugin into Android config flow + foreground service gating
packages/mobile-client/plugin/src/types.ts Adds VoIP-related plugin options (enableVoIP, timeouts, FCM routing)
packages/ios-expo-voip/README.md Documents purpose and installation/entitlement requirements
packages/ios-expo-voip/package.json Defines new package metadata + peer deps
packages/ios-expo-voip/ios/VoIPAppDelegateSubscriber.swift Starts PushKit registry at launch + forwards call intents when enabled
packages/ios-expo-voip/ios/FishjamExpoVoip.podspec Podspec for the Expo iOS glue package
packages/ios-expo-voip/expo-module.config.json Registers the AppDelegate subscriber for Expo Modules
package.json Adds new workspace package + example app workspace path
examples/mobile-client/voip-call/server/README.md Documents running server + APNs/FCM credentials + payloads
examples/mobile-client/voip-call/server/main.ts Deno push + signaling server implementation
examples/mobile-client/voip-call/server/deno.lock Locks Deno dependencies
examples/mobile-client/voip-call/server/deno.json Defines tasks/imports for the Deno server
examples/mobile-client/voip-call/server/.gitignore Ignores local DB and credential files
examples/mobile-client/voip-call/server/.env.example Placeholder env file for server setup
examples/mobile-client/voip-call/README.md Top-level instructions for running the example
examples/mobile-client/voip-call/app/tsconfig.json TypeScript config for the Expo example app
examples/mobile-client/voip-call/app/src/user/UserProvider.tsx User session persistence + users list retrieval
examples/mobile-client/voip-call/app/src/user/UserContext.ts User context types + hook
examples/mobile-client/voip-call/app/src/theme/colors.ts Example UI theme colors
examples/mobile-client/voip-call/app/src/screens/UsersScreen.tsx User list UI + call initiation UI
examples/mobile-client/voip-call/app/src/screens/OutgoingCallView.tsx Outgoing ringing UI
examples/mobile-client/voip-call/app/src/screens/LoginScreen.tsx Simple login UI
examples/mobile-client/voip-call/app/src/screens/InCallView.tsx In-call UI (audio/video) + hold/mute/audio-route sync
examples/mobile-client/voip-call/app/src/screens/CallScreen.tsx Owns room join/leave lifecycle and connect/hangup reporting
examples/mobile-client/voip-call/app/src/hooks/useRequestPermissions.ts Requests mic/camera/notifications permissions
examples/mobile-client/voip-call/app/src/hooks/useRecentsRedial.ts Handles iOS Recents redial intents
examples/mobile-client/voip-call/app/src/hooks/usePlaceCall.ts Calls server to ring callee then starts native call UI
examples/mobile-client/voip-call/app/src/hooks/useDeviceRegistration.ts Registers VoIP push token with the server
examples/mobile-client/voip-call/app/src/hooks/useCallSignaling.ts WebSocket signaling for cancel/reject while ringing
examples/mobile-client/voip-call/app/src/hooks/useCallRoom.ts Joins/leaves Fishjam room tied to call lifetime
examples/mobile-client/voip-call/app/src/components/VideoCallView.tsx FaceTime-style video layout with PiP
examples/mobile-client/voip-call/app/src/components/index.ts Component barrel export
examples/mobile-client/voip-call/app/src/components/InCallButton.tsx Call control button component
examples/mobile-client/voip-call/app/src/components/Avatar.tsx Avatar image/initials component with error fallback
examples/mobile-client/voip-call/app/README.md Example app run notes + iOS native registration note
examples/mobile-client/voip-call/app/prettier.config.js Prettier config for example app
examples/mobile-client/voip-call/app/package.json Example app dependencies/scripts
examples/mobile-client/voip-call/app/index.js Expo entrypoint + crypto polyfill
examples/mobile-client/voip-call/app/babel.config.js Babel config for Expo app
examples/mobile-client/voip-call/app/App.tsx Wires providers + VoIP signaling/registration hooks + screens
examples/mobile-client/voip-call/app/app.json Expo config enabling VoIP plugin options + app identifiers
examples/mobile-client/voip-call/app/.gitignore Ignores generated native folders + google-services.json
examples/mobile-client/voip-call/app/.eslintrc.js ESLint config for example app
examples/mobile-client/voip-call/app/.env.example Example app env var template
.github/workflows/release.yaml Publishes @fishjam-cloud/ios-expo-voip in release workflow

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/mobile-client/plugin/src/withFishjamVoIP.ts Outdated
@Magmusacy
Magmusacy merged commit 8510835 into main Jul 29, 2026
2 checks passed
@Magmusacy
Magmusacy deleted the feature/voip-calls branch July 29, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants