Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v0.8.0 #53

Merged
merged 55 commits into from
Mar 7, 2025
Merged
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
ceef12f
Create CleverSignedCall Turbo Module for old arch
gupta-shrinath-ct Jan 15, 2025
d4a7643
Fix NativeModules constants
gupta-shrinath-ct Jan 20, 2025
969ed95
Support RN New Arch.
gupta-shrinath-ct Jan 20, 2025
7366551
Remove unnecessary module clevertap-signedcall
gupta-shrinath-ct Jan 20, 2025
05591f8
Set SDK versions for voximplant_react-native-foreground-service lib i…
gupta-shrinath-ct Jan 21, 2025
610833f
Remove unnecessary firebase-crashlytics dependencies from example app…
gupta-shrinath-ct Jan 21, 2025
6b2ff71
Run iOS app on old arch
gupta-shrinath-ct Jan 25, 2025
542bb28
Wrote TurboModule in iOS
gupta-shrinath-ct Jan 29, 2025
1f693e9
Fix issue of Class Not found in Clevertap react native
gupta-shrinath-ct Jan 30, 2025
48814ed
Add corelocation to clevertap ios via Podfile
gupta-shrinath-ct Jan 30, 2025
fa3a7e6
Fix Native Module method signature in iOS
gupta-shrinath-ct Jan 30, 2025
210e41b
Remove react navigation lib due to new arch incompatiability
gupta-shrinath-ct Jan 30, 2025
e806944
Remove explict clevertap core dependency & Use android core dep to fi…
gupta-shrinath-ct Jan 30, 2025
91b314b
Remove unnecessary InitProperties class in IOS NativeModule
gupta-shrinath-ct Jan 30, 2025
76ccf9e
Update build bundle version to 133
gupta-shrinath-ct Feb 5, 2025
4fa9355
Add encryption flag to avoid missing compliance issue
gupta-shrinath-ct Feb 5, 2025
3d02718
Update package version and android sdk version to 0.7.7
gupta-shrinath-ct Feb 7, 2025
d35c13b
Add scrollview to screens
gupta-shrinath-ct Feb 7, 2025
708f40b
Update build bundle version to 134
gupta-shrinath-ct Feb 7, 2025
e787350
Upgrade to RN 0.77 due to RN Github issue 49115
gupta-shrinath-ct Feb 8, 2025
c1397ca
Expose SignedCall as gradle api
gupta-shrinath-ct Feb 10, 2025
7caf9da
Add script for android bundle creation
gupta-shrinath-ct Feb 10, 2025
ffa1c7e
Strongly type NativeModule methods
gupta-shrinath-ct Feb 10, 2025
52f2ff6
Add dismiss missed call notification button
gupta-shrinath-ct Feb 10, 2025
7dc2b44
Cleanup
gupta-shrinath-ct Feb 10, 2025
4744114
Fix button tap issue when keyboard is visible
gupta-shrinath-ct Feb 11, 2025
289613d
Fix local branding handling in ios
gupta-shrinath-ct Feb 11, 2025
6f435d6
Align example app toggle buttons
gupta-shrinath-ct Feb 11, 2025
cc4ea78
Hide non required ui element in iOS
gupta-shrinath-ct Feb 11, 2025
a8a906c
Add missed call notification action click handler
gupta-shrinath-ct Feb 11, 2025
5ddc732
Add NativeModule addListeneer and removeListeners methods
gupta-shrinath-ct Feb 12, 2025
899ccae
chore: Remove unused native method in old arch
gupta-shrinath-ct Feb 12, 2025
5818918
Disable bridgelessEnabled to enable event emitter in new arch
gupta-shrinath-ct Feb 12, 2025
47f0684
Add ReactContext handling in android
gupta-shrinath-ct Feb 13, 2025
778bcd3
Update Build number
gupta-shrinath-ct Feb 13, 2025
62acafd
Revert "Expose SignedCall as gradle api" after review
gupta-shrinath-ct Feb 14, 2025
82c02e0
Inline SC Android SDK version in example app
gupta-shrinath-ct Feb 16, 2025
f542983
Fix issue of call ui reshown after cancel call
gupta-shrinath-ct Feb 16, 2025
f2dca02
Remove deactivateHandlers() as it caused no listener trigger after lo…
gupta-shrinath-ct Feb 17, 2025
f56a949
chore: Remove unwanted files from .gitignore
gupta-shrinath-ct Feb 17, 2025
67904c9
Remove packageManager field in package.json
gupta-shrinath-ct Feb 17, 2025
1853382
Review: Make use of promiseHandler wherever needed
gupta-shrinath-ct Feb 17, 2025
e04d027
Merge branch 'feature/VC-1007/RN_New_Arch' into feature/VC-1007/RN_Ne…
gupta-shrinath-ct Feb 17, 2025
92ee470
Implement Review changes
gupta-shrinath-ct Feb 18, 2025
1251566
Fix handling missed call notification
gupta-shrinath-ct Feb 18, 2025
7f06411
Implement Review changes
gupta-shrinath-ct Feb 19, 2025
73e4aa2
chore: Update bundle & lock file
gupta-shrinath-ct Feb 19, 2025
de5cd29
Implement auto navigate to dialer after first initialization
gupta-shrinath-ct Feb 19, 2025
c6fd266
Update Changelog
gupta-shrinath-ct Mar 6, 2025
022ce00
Update ChangeLog
gupta-shrinath-ct Mar 6, 2025
225d634
Merge pull request #52 from CleverTap/feature/VC-1007/RN_New_Arch_Update
gupta-shrinath-ct Mar 6, 2025
075cf0c
Merge pull request #51 from CleverTap/feature/VC-1007/RN_New_Arch
gupta-shrinath-ct Mar 7, 2025
9040327
Fix tags in README
gupta-shrinath-ct Mar 7, 2025
e9bd9ee
Update node version to 18 in nvmrc
gupta-shrinath-ct Mar 7, 2025
05439e1
Merge pull request #54 from CleverTap/fix/README
gupta-shrinath-ct Mar 7, 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: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,4 @@ android/keystores/debug.keystore
.turbo/

# generated by bob
lib/
lib/
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
# Change Log

### Version 0.8.0 (March 07, 2025)

---
**What's new**
* **[Android Platform]**
* Supports Signed Call Android SDK [v0.0.7.7](https://repo1.maven.org/maven2/com/clevertap/android/clevertap-signedcall-sdk/0.0.7.7/) which is compatible with CleverTap Android SDK [v7.0.2](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-702-october-10-2024).
* Adds new public API `SignedCall.isInitialized()` to retrieve the initialization status.
* Adds new public API `SignedCall.dismissMissedCallNotification()` to dismiss the missed call notification.

* **[iOS Platform]**
* Supports [Signed Call iOS SDK v0.0.9](https://github.com/CleverTap/clevertap-signedcall-ios-sdk/blob/main/CHANGELOG.md#version-009-november-19-2024) which is compatible with [CleverTap iOS SDK v7.0.2](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-702-october-10-2024) and higher.

* **[Android and iOS Platform]**
* Migrates the bridge to a backwards-compatible New Architecture Turbo Module.
* The CleverTap SignedCall ReactNative SDK continues to be compatible with both the Old and the New Architecture.

**Bug Fixes**
* **[Android Platform]**
* Addresses the [Notification trampoline restrictions](https://developer.android.com/about/versions/12/behavior-changes-12#notification-trampolines), introduced in Android 12 and above, which blocks the activity launches from the `SignedCall.SignedCallOnMissedCallActionClicked` callback triggered upon clicking the missed call CTA.
* Fixes an issue where the call notification would disappear upon pressing the back button on certain devices.

**Enhancements**
* **[Android Platform]**
* Addresses limitations related to microphone access during ongoing calls when user moves the app to the background.The Google Play Console will prompt you to declare the usage of this permission, for which you need to provide a demo video link. Please refer to the SDK documentation for guidance on how to address this.
* Enforces the network quality checks during call initiation and reception, and capturing the network latency.

### Version 0.7.6 (June 06, 2025)

---
Expand Down
15 changes: 13 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}

sourceSets {
main {
if (isNewArchitectureEnabled()) {
java.srcDirs += [
"src/newarch",
]
} else {
java.srcDirs += ["src/oldarch"]
}
}
}
}

repositories {
Expand All @@ -73,8 +84,8 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
//Required dependencies for Signed Call Android SDK
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
compileOnly "com.clevertap.android:clevertap-android-sdk:6.2.1"
compileOnly "com.clevertap.android:clevertap-signedcall-sdk:0.0.7.6"
compileOnly "com.clevertap.android:clevertap-android-sdk:7.0.2"
compileOnly "com.clevertap.android:clevertap-signedcall-sdk:0.0.7.7"
compileOnly 'androidx.work:work-runtime:2.7.1'
compileOnly('io.socket:socket.io-client:2.1.0') {
exclude group: 'org.json', module: 'json'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,51 +22,38 @@ import com.clevertap.rnsignedcallandroid.internal.util.toJson
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.ReadableMap

class CleverTapSignedCallModule(private val reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {

class CleverTapSignedCallModuleImpl(private val reactContext: ReactApplicationContext) {

private var mSignedCall: SignedCallAPI? = null
private var cleverTapAPI: CleverTapAPI? = null
private lateinit var outgoingCallResponse: OutgoingCallResponse

init {
cleverTapAPI = CleverTapAPI.getDefaultInstance(reactContext)
registerListeners(reactContext)
}

companion object {
/**
* Exports the Name of the Android module. TypeScript/Javascript part of the package used this
* name to communicate with this NativeModule class.
*/
const val NAME = "CleverTapSignedCall"
const val ERROR_CLEVERTAP_INSTANCE_NOT_INITIALIZED = "CleverTap Instance is not initialized"
}

/**
* Exports the Name of the Android module. TypeScript/Javascript part of the package used this
* name to communicate with this NativeModule class.
*/
override fun getName(): String {
return NAME
init {
cleverTapAPI = CleverTapAPI.getDefaultInstance(reactContext)
registerListeners(reactContext)
}

@ReactMethod

fun addListener(eventName: String?) {
// Keep: Required for RN built in Event Emitter Calls.
}

@ReactMethod
fun removeListeners(count: Int?) {
// Keep: Required for RN built in Event Emitter Calls.
}

/** Exports constants for Typescript or Javascript part of this package. */
override fun getConstants(): MutableMap<String, String> =
hashMapOf(
ON_CALL_STATUS_CHANGED to ON_CALL_STATUS_CHANGED,
ON_MISSED_CALL_ACTION_CLICKED to ON_MISSED_CALL_ACTION_CLICKED
)

private fun getSignedCallAPI(): SignedCallAPI {
if (mSignedCall == null) {
mSignedCall = SignedCallAPI.getInstance()
Expand All @@ -75,7 +62,7 @@ class CleverTapSignedCallModule(private val reactContext: ReactApplicationContex
}

@SuppressLint("RestrictedApi")
private fun registerListeners(context: ReactContext) {
fun registerListeners(context: ReactContext) {
if (!SignedCallUtils.isAppInBackground()) {
SignedCallAPI.getInstance().registerVoIPCallStatusListener { data ->
log(message = "SignedCallOnCallStatusListener is invoked in foreground or background: $data")
Expand All @@ -90,41 +77,43 @@ class CleverTapSignedCallModule(private val reactContext: ReactApplicationContex
}

@SuppressLint("RestrictedApi")
@ReactMethod
fun trackSdkVersion(sdkName: String, sdkVersion: Int) {
cleverTapAPI?.let { cleverTapAPI!!.setCustomSdkVersion(sdkName, sdkVersion) }
?: run {
log(message = "$ERROR_CLEVERTAP_INSTANCE_NOT_INITIALIZED to track the SDK Version")
}
fun trackSdkVersion(sdkName: String, sdkVersion: Int, promise: Promise) {
cleverTapAPI?.let {
cleverTapAPI!!.setCustomSdkVersion(sdkName, sdkVersion)
promise.resolve(null)
}
?: run {
log(message = "$ERROR_CLEVERTAP_INSTANCE_NOT_INITIALIZED to track the SDK Version")
promise.reject("$ERROR_CLEVERTAP_INSTANCE_NOT_INITIALIZED to track the SDK Version")
}
}

@ReactMethod
fun setDebugLevel(logLevel: Int) {
SignedCallAPI.setDebugLevel(logLevel.toSignedCallLogLevel())
}

/**
* Retrieves the init-properties from the readableMap and initializes the Signed Call Android SDK
*/
@ReactMethod
fun initialize(initProperties: ReadableMap?, promise: Promise) {
val signedCallAPI: SignedCallAPI = getSignedCallAPI()
initProperties?.let {
try {
val initConfiguration: SignedCallInitConfiguration? = getInitConfigFromReadableMap(it, reactContext.applicationContext)
val initConfiguration: SignedCallInitConfiguration? =
getInitConfigFromReadableMap(it, reactContext.applicationContext)
signedCallAPI.init(
reactContext.applicationContext,
initConfiguration,
cleverTapAPI,
object : SignedCallInitResponse {
override fun onSuccess() {
promise.resolve(signedCallResponseToWritableMap(exception = null))
}

override fun onFailure(initException: InitException) {
promise.resolve(signedCallResponseToWritableMap(initException))
}
reactContext.applicationContext,
initConfiguration,
cleverTapAPI,
object : SignedCallInitResponse {
override fun onSuccess() {
promise.resolve(signedCallResponseToWritableMap(exception = null))
}

override fun onFailure(initException: InitException) {
promise.resolve(signedCallResponseToWritableMap(initException))
}
}
)
} catch (throwable: Throwable) {
val errorMessage = "Exception while initializing the Signed Call native module"
Expand All @@ -135,18 +124,17 @@ class CleverTapSignedCallModule(private val reactContext: ReactApplicationContex
}

/** Sends the call-details to initiate a VoIP call */
@ReactMethod
fun call(
receiverCuid: String,
callContext: String,
callProperties: ReadableMap?,
promise: Promise
receiverCuid: String,
callContext: String,
callProperties: ReadableMap?,
promise: Promise
) {
val signedCallAPI: SignedCallAPI = getSignedCallAPI()
try {
val callOptions = callProperties?.toJson()

outgoingCallResponse = object: OutgoingCallResponse {
outgoingCallResponse = object : OutgoingCallResponse {
override fun onSuccess() {
promise.resolve(signedCallResponseToWritableMap(exception = null))
}
Expand All @@ -157,11 +145,11 @@ class CleverTapSignedCallModule(private val reactContext: ReactApplicationContex
}

signedCallAPI.call(
reactContext,
receiverCuid,
callContext,
callOptions,
outgoingCallResponse
reactContext,
receiverCuid,
callContext,
callOptions,
outgoingCallResponse
)
} catch (throwable: Throwable) {
val errorMessage = "Exception while initiating the VoIP Call"
Expand All @@ -176,35 +164,77 @@ class CleverTapSignedCallModule(private val reactContext: ReactApplicationContex
* This method checks if there is an active call and if the client is on VoIP call.
* If both conditions are met, it starts the call screen activity.
*/
@ReactMethod
fun getBackToCall(promise: Promise) {
promise.resolve(getSignedCallAPI().callController?.getBackToCall(reactContext))
promiseHandler(getSignedCallAPI().callController?.getBackToCall(reactContext), promise)
}

/**
* Retrieves the current call state.
* @return The current call state.
*/
@ReactMethod
fun getCallState(promise: Promise) {
promise.resolve(getSignedCallAPI().callController?.callState?.formattedCallState())
promiseHandler(getSignedCallAPI().callController?.callState?.formattedCallState(), promise)
}

/** Logs out the Signed Call SDK session */
@ReactMethod
fun logout() {
getSignedCallAPI().logout(reactContext)
fun logout(promise: Promise) {
getSignedCallAPI().logout(reactContext.applicationContext)
promiseHandler(true, promise)
}

/** Ends the active call, if any. */
@ReactMethod
fun hangupCall() {
getSignedCallAPI().callController?.endCall()
fun hangupCall(promise: Promise) {
promiseHandler(getSignedCallAPI().callController?.endCall(), promise)
}

/** Disconnects the signalling socket */
@ReactMethod
fun disconnectSignallingSocket() {
getSignedCallAPI().disconnectSignallingSocket(reactContext)
fun disconnectSignallingSocket(promise: Promise) {
promiseHandler(
getSignedCallAPI().disconnectSignallingSocket(reactContext.applicationContext),
promise
)
}

/** Exports constants for Typescript or Javascript part of this package. */
fun getConstants(): MutableMap<String, String> {
return mutableMapOf(
ON_CALL_STATUS_CHANGED to ON_CALL_STATUS_CHANGED,
ON_MISSED_CALL_ACTION_CLICKED to ON_MISSED_CALL_ACTION_CLICKED
)
}

/**
* Checks if the Signed Call SDK is initialized.
*
*/
fun isInitialized(promise: Promise) {
promiseHandler(getSignedCallAPI().isInitialized(reactContext.applicationContext), promise)
}

/**
* Dismisses the missed call notification.
*
* This method is intended to be called after a VoIP call use case is completed
*
*/
fun dismissMissedCallNotification(promise: Promise) {
promiseHandler(
getSignedCallAPI().dismissMissedCallNotification(reactContext.applicationContext),
promise
)
}


private fun promiseHandler(promiseFunction: Any?, promise: Promise) {
try {
when (promiseFunction) {
is Unit -> promise.resolve(null)
else -> promise.resolve(promiseFunction)
}

} catch (e: Throwable) {
promise.reject(e)
}
}

}
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
package com.clevertap.rnsignedcallandroid

import com.facebook.react.ReactPackage
import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
import com.facebook.react.module.model.ReactModuleInfo
import com.facebook.react.module.model.ReactModuleInfoProvider

class CleverTapSignedCallPackage : ReactPackage {
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return listOf(CleverTapSignedCallModule(reactContext))
class CleverTapSignedCallPackage : TurboReactPackage() {
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
return if (name == CleverTapSignedCallModuleImpl.NAME) {
CleverTapSignedCallModule(reactContext)
} else {
null
}
}

override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
return ReactModuleInfoProvider {
val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
moduleInfos[CleverTapSignedCallModuleImpl.NAME] = ReactModuleInfo(
CleverTapSignedCallModuleImpl.NAME,
CleverTapSignedCallModuleImpl.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
true, // hasConstants
false,// isCxxModule
isTurboModule // isTurboModule
)
moduleInfos
}
}

}
Loading
Loading