Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
d609360
feat(notifications): integrate expo-notifications for improved push h…
diegolmello Dec 10, 2025
6fa178e
refactor(notifications): remove react-native-notifications and implem…
diegolmello Dec 10, 2025
557c45c
refactor(notifications): remove react-native-notifications and enhanc…
diegolmello Dec 10, 2025
01e6e60
feat(notifications): implement video conference notification handling
diegolmello Dec 10, 2025
8d0506c
feat(notifications): enhance video conference notification handling f…
diegolmello Dec 10, 2025
4826fbe
feat(notifications): improve video conference notification handling
diegolmello Dec 10, 2025
952068d
refactor(notifications): remove Notifee and Firebase messaging depend…
diegolmello Dec 10, 2025
d44a321
fix lint
diegolmello Dec 10, 2025
f037939
target arm64 on e2e ci
diegolmello Dec 11, 2025
3009671
Fix user agent on push.get
diegolmello Dec 11, 2025
6620a1b
refactor(notifications): migrate video conference notification handli…
diegolmello Dec 11, 2025
7f98e86
chore: format code and fix lint issues [skip ci]
diegolmello Dec 11, 2025
08e0dc4
Merge branch 'develop' into chore.expo-notifications
diegolmello Dec 15, 2025
8af4d01
fix: improve push notification handling and error management
diegolmello Dec 15, 2025
81166aa
feat: enhance notification payload handling in NotificationService
diegolmello Dec 15, 2025
e05e3bf
feat: implement video conference action listener and event emission
diegolmello Dec 16, 2025
388a5c8
Merge branch 'develop' into chore.expo-notifications
diegolmello Dec 18, 2025
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
2 changes: 0 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ android {
versionName "4.68.0"
vectorDrawables.useSupportLibrary = true
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60" // See note below!
resValue "string", "rn_config_reader_custom_package", "chat.rocket.reactnative"
}

Expand Down Expand Up @@ -144,7 +143,6 @@ dependencies {
implementation jscFlavor
}

implementation project(':react-native-notifications')
implementation "com.google.firebase:firebase-messaging:23.3.1"
implementation project(':watermelondb-jsi')

Expand Down
17 changes: 17 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<!-- Custom Firebase Messaging Service for Rocket.Chat notifications -->
<service
android:name="chat.rocket.reactnative.notification.RCFirebaseMessagingService"
android:exported="false">
<intent-filter android:priority="100">
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<receiver
android:name="chat.rocket.reactnative.notification.ReplyBroadcast"
android:enabled="true"
Expand All @@ -84,6 +92,15 @@
android:enabled="true"
android:exported="true" >
</receiver>
<receiver
android:name="chat.rocket.reactnative.notification.VideoConfBroadcast"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="chat.rocket.reactnative.ACTION_VIDEO_CONF_ACCEPT" />
<action android:name="chat.rocket.reactnative.ACTION_VIDEO_CONF_DECLINE" />
</intent-filter>
</receiver>
<meta-data
android:name="com.bugsnag.android.API_KEY"
android:value="${BugsnagAPIKey}" />
Expand Down
60 changes: 57 additions & 3 deletions android/app/src/main/java/chat/rocket/reactnative/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import com.facebook.react.defaults.DefaultReactActivityDelegate

import android.os.Bundle
import com.zoontek.rnbootsplash.RNBootSplash
import android.content.Intent;
import android.content.res.Configuration;
import android.content.Intent
import android.content.res.Configuration
import chat.rocket.reactnative.notification.VideoConfModule
import chat.rocket.reactnative.notification.VideoConfNotification
import com.google.gson.GsonBuilder

class MainActivity : ReactActivity() {

Expand All @@ -25,9 +28,60 @@ class MainActivity : ReactActivity() {
override fun createReactActivityDelegate(): ReactActivityDelegate =
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)

override fun onCreate(savedInstanceState: Bundle?) {
override fun onCreate(savedInstanceState: Bundle?) {
RNBootSplash.init(this, R.style.BootTheme)
super.onCreate(null)

// Handle video conf action from notification
intent?.let { handleVideoConfIntent(it) }
}

public override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
// Handle video conf action when activity is already running
handleVideoConfIntent(intent)
}

private fun handleVideoConfIntent(intent: Intent) {
if (intent.getBooleanExtra("videoConfAction", false)) {
val notificationId = intent.getIntExtra("notificationId", 0)
val event = intent.getStringExtra("event") ?: return
val rid = intent.getStringExtra("rid") ?: ""
val callerId = intent.getStringExtra("callerId") ?: ""
val callerName = intent.getStringExtra("callerName") ?: ""
val host = intent.getStringExtra("host") ?: ""
val callId = intent.getStringExtra("callId") ?: ""

android.util.Log.d("RocketChat.MainActivity", "Handling video conf intent - event: $event, rid: $rid, host: $host, callId: $callId")

// Cancel the notification
if (notificationId != 0) {
VideoConfNotification.cancelById(this, notificationId)
}

// Store action for JS to pick up - include all required fields
val data = mapOf(
"notificationType" to "videoconf",
"rid" to rid,
"event" to event,
"host" to host,
"callId" to callId,
"caller" to mapOf(
"_id" to callerId,
"name" to callerName
)
)

val gson = GsonBuilder().create()
val jsonData = gson.toJson(data)

android.util.Log.d("RocketChat.MainActivity", "Storing video conf action: $jsonData")

VideoConfModule.storePendingAction(this, jsonData)

// Clear the video conf flag to prevent re-processing
intent.removeExtra("videoConfAction")
}
}

override fun invokeDefaultOnBackPressed() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package chat.rocket.reactnative

import android.app.Application
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
Expand All @@ -18,26 +16,35 @@ import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader
import com.nozbe.watermelondb.jsi.WatermelonDBJSIPackage;
import com.wix.reactnativenotifications.core.AppLaunchHelper
import com.wix.reactnativenotifications.core.AppLifecycleFacade
import com.wix.reactnativenotifications.core.JsIOHelper
import com.wix.reactnativenotifications.core.notification.INotificationsApplication
import com.wix.reactnativenotifications.core.notification.IPushNotification
import com.bugsnag.android.Bugsnag
import expo.modules.ApplicationLifecycleDispatcher
import chat.rocket.reactnative.networking.SSLPinningTurboPackage;
import chat.rocket.reactnative.storage.MMKVKeyManager;
import chat.rocket.reactnative.storage.SecureStoragePackage;
import chat.rocket.reactnative.notification.CustomPushNotification;
import chat.rocket.reactnative.notification.VideoConfTurboPackage

open class MainApplication : Application(), ReactApplication, INotificationsApplication {
/**
* Main Application class.
*
* NOTIFICATION ARCHITECTURE:
* - JS layer uses expo-notifications for token registration and event handling
* - Native layer uses RCFirebaseMessagingService + CustomPushNotification for:
* - FCM message handling
* - Notification display with MessagingStyle
* - E2E encrypted message decryption
* - Direct reply functionality
* - Message-id-only notification loading
*/
open class MainApplication : Application(), ReactApplication {

override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
add(SSLPinningTurboPackage())
add(WatermelonDBJSIPackage())
add(VideoConfTurboPackage())
add(SecureStoragePackage())
}

Expand Down Expand Up @@ -78,19 +85,4 @@ open class MainApplication : Application(), ReactApplication, INotificationsAppl
super.onConfigurationChanged(newConfig)
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
}

override fun getPushNotification(
context: Context,
bundle: Bundle,
defaultFacade: AppLifecycleFacade,
defaultAppLaunchHelper: AppLaunchHelper
): IPushNotification {
return CustomPushNotification(
context,
bundle,
defaultFacade,
defaultAppLaunchHelper,
JsIOHelper()
)
}
}
Loading
Loading