Skip to content

Commit f267d91

Browse files
Merge pull request #23 from MirrorFly/feature/update-2.3.0
update 2.3.0
2 parents b2b3056 + 9d5555b commit f267d91

35 files changed

+463
-273
lines changed

android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ android {
9797
minSdkVersion rootProject.ext.minSdkVersion
9898
targetSdkVersion rootProject.ext.targetSdkVersion
9999
versionCode 1
100-
versionName "3.3.3"
100+
versionName "3.3.7"
101101
/** Add this for react-native-camera */
102102
missingDimensionStrategy 'react-native-camera', 'general'
103103
multiDexEnabled true

ios/NotificationExtension/MyClass.swift

Lines changed: 87 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -30,56 +30,95 @@ class MyClass: NSObject {
3030
}
3131

3232
@objc
33-
func getMessage(messageID: String, content: String, type:String, userjid:String, completion: @escaping([String: Any]?) -> Void) {
34-
var dict = [String: Any]()
35-
removeInvalidMessage(forIDs: [messageID], onCompletion: {
36-
notification in
37-
38-
switch (type) {
39-
case "text":
40-
let val = convertToDictionary(text: self.run(messageID: messageID, content: content))
41-
let nickName:String = val?["nickName"] as? String ?? ""
42-
if let number = userjid.components(separatedBy: "@").first, !number.isEmpty {
43-
dict["nickName"] = FlyEncryption.encryptDecryptData(key: number, data: nickName, encrypt: false, isForProfileName: true)
44-
} else {
45-
dict["nickName"] = nickName // Fallback in case `number` is nil or empty
46-
}
47-
dict["message"] = val?["message"]
48-
break;
49-
case "image":
50-
dict["message"] = "📷 Image"
51-
break;
52-
case "video":
53-
dict["message"] = "📽️ Video"
54-
break;
55-
case "audio":
56-
dict["message"] = "🎵 Audio"
57-
break;
58-
case "file":
59-
dict["message"] = "📄 File"
60-
break;
61-
case "location":
62-
dict["message"] = "📌 Location"
63-
break;
64-
case "contact":
65-
dict["message"] = "👤 Contact"
66-
break;
67-
case "recall":
68-
// Need to called for recall message
69-
// removeNotification(messageId: messageID, n: notification)
70-
dict["messageID"] = messageID
71-
dict["message"] = "This message was deleted"
72-
break;
73-
default:
74-
dict["message"] = "Unknown message format"
75-
break
76-
}
33+
func getMessage(userInfo: [String: Any], completion: @escaping ([String: Any]?) -> Void) {
34+
var dict = [String: Any]()
35+
36+
// Use empty strings if the keys are not present
37+
let messageID = userInfo["message_id"] as? String ?? userInfo["notify_id"] as? String ?? ""
38+
let content = userInfo["message_content"] as? String ?? ""
39+
let chat_type = userInfo["chat_type"] as? String ?? ""
40+
let group_name = userInfo["group_name"] as? String ?? ""
41+
let type = userInfo["type"] as? String ?? ""
42+
let userjid = userInfo["from_user"] as? String ?? ""
43+
7744

78-
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(1.0 * Double(NSEC_PER_SEC)) / Double(NSEC_PER_SEC), execute: { [self] in
79-
completion(dict)
45+
if ["added", "removed"].contains(where: { content.contains($0) }) {
46+
if let aps = userInfo["aps"] as? [String: Any],
47+
let alert = aps["alert"] as? [String: Any],
48+
let body = alert["body"] as? String,
49+
let title = alert["title"] as? String,
50+
let groupName = userInfo["group_name"] as? String {
51+
52+
let trimmedGroupName = groupName.trimmingCharacters(in: .whitespacesAndNewlines)
53+
var cleanBody = body.trimmingCharacters(in: .whitespacesAndNewlines)
54+
55+
// Build a regex to match any variation like "group_name:", "group_name :", "group_name : "
56+
let regexPattern = "^" + NSRegularExpression.escapedPattern(for: trimmedGroupName) + "\\s*:\\s*"
57+
58+
if let regex = try? NSRegularExpression(pattern: regexPattern, options: [.caseInsensitive]) {
59+
let range = NSRange(location: 0, length: cleanBody.utf16.count)
60+
cleanBody = regex.stringByReplacingMatches(in: cleanBody, options: [], range: range, withTemplate: "")
61+
.trimmingCharacters(in: .whitespacesAndNewlines)
62+
}
63+
64+
dict["nickName"] = title
65+
dict["message"] = cleanBody
66+
67+
DispatchQueue.main.async {
68+
completion(dict)
69+
}
70+
return
71+
}
72+
}
73+
74+
removeInvalidMessage(forIDs: [messageID], onCompletion: { notification in
75+
switch type {
76+
case "text":
77+
let val = convertToDictionary(text: self.run(messageID: messageID, content: content))
78+
let rawNickName = val?["nickName"] as? String ?? ""
79+
let number = userjid.components(separatedBy: "@").first ?? ""
80+
81+
var decryptedNickName = rawNickName
82+
if !number.isEmpty {
83+
decryptedNickName = FlyEncryption.encryptDecryptData(key: number, data: rawNickName, encrypt: false, isForProfileName: true)
84+
}
85+
86+
// Optionally prepend group name if it's a group chat
87+
if chat_type == "normal", let groupName = userInfo["group_name"] as? String {
88+
dict["nickName"] = "\(groupName)@ \(decryptedNickName)"
89+
} else {
90+
dict["nickName"] = decryptedNickName
91+
}
92+
93+
dict["message"] = val?["message"]
94+
case "image":
95+
dict["message"] = "📷 Image"
96+
case "video":
97+
dict["message"] = "📽️ Video"
98+
case "audio":
99+
dict["message"] = "🎵 Audio"
100+
case "file":
101+
dict["message"] = "📄 File"
102+
case "location":
103+
dict["message"] = "📌 Location"
104+
case "contact":
105+
dict["message"] = "👤 Contact"
106+
case "recall":
107+
dict["messageID"] = messageID
108+
dict["message"] = "This message was deleted"
109+
default:
110+
dict["message"] = "Unknown message format"
111+
}
112+
113+
if (dict["nickName"] == nil || (dict["nickName"] as? String)?.isEmpty == true),
114+
let groupName = userInfo["group_name"] as? String {
115+
dict["nickName"] = groupName
116+
}
117+
// Call completion with the final dict
118+
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(1.0 * Double(NSEC_PER_SEC)) / Double(NSEC_PER_SEC), execute: { [self] in
119+
completion(dict)
120+
})
80121
})
81-
// completion(dict)
82-
})
83122
}
84123
}
85124

ios/NotificationExtension/NotificationService.m

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,29 @@ @implementation NotificationService
2020
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
2121
self.contentHandler = contentHandler;
2222
self.bestAttemptContent = [request.content mutableCopy];
23-
NSString *messagecontent = [self.bestAttemptContent.userInfo objectForKey:@"message_content"];
24-
NSString *messagetype = [self.bestAttemptContent.userInfo objectForKey:@"type"];
25-
NSString *userjid = [self.bestAttemptContent.userInfo objectForKey:@"from_user"];
23+
NSDictionary *userInfo = [self.bestAttemptContent userInfo];
2624
NSString *message_id = [self.bestAttemptContent.userInfo objectForKey:@"message_id"];
27-
NSString *user_name = [self.bestAttemptContent.userInfo objectForKey:@"user_name"];
25+
NSString *user_name = [self.bestAttemptContent.userInfo objectForKey:@"user_name"];;
26+
2827
@autoreleasepool {
2928
MyClass * obj = [MyClass new];
30-
[obj getMessageWithMessageID:message_id content:messagecontent type:messagetype userjid:userjid completion:^(NSDictionary<NSString *,id> * dict) {
31-
self.bestAttemptContent.threadIdentifier = dict[@"messageID"] ? dict[@"messageID"]: message_id;
32-
NSString *nickName = dict[@"nickName"];
33-
if (nickName) {
34-
self.bestAttemptContent.title = dict[@"nickName"];
35-
} else {
36-
self.bestAttemptContent.title = user_name;
29+
[obj getMessageWithUserInfo:userInfo completion:^(NSDictionary<NSString *,id> *dict){
30+
if(dict){
31+
self.bestAttemptContent.threadIdentifier = dict[@"messageID"] ? dict[@"messageID"]: message_id;
32+
NSString *nickName = dict[@"nickName"];
33+
if (nickName) {
34+
self.bestAttemptContent.title = dict[@"nickName"];
35+
} else {
36+
self.bestAttemptContent.title = user_name;
3737
// Handle the case where both nickName and user_name are nil
38-
// Optional: set a default title
38+
// Optional: set a default title
39+
}
40+
self.bestAttemptContent.sound = [UNNotificationSound defaultSound];
41+
self.bestAttemptContent.body = dict[@"message"];
42+
self.contentHandler(self.bestAttemptContent);
43+
} else{
44+
self.contentHandler(self.bestAttemptContent);
3945
}
40-
self.bestAttemptContent.body = dict[@"message"];
41-
self.contentHandler(self.bestAttemptContent);
4246
}];
4347
}
4448
}

ios/mirrorfly_rn.xcodeproj/project.pbxproj

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@
568568
"$(inherited)",
569569
"@executable_path/Frameworks",
570570
);
571-
MARKETING_VERSION = 3.3.3;
571+
MARKETING_VERSION = 3.3.7;
572572
OTHER_LDFLAGS = (
573573
"$(inherited)",
574574
"-ObjC",
@@ -601,7 +601,7 @@
601601
"$(inherited)",
602602
"@executable_path/Frameworks",
603603
);
604-
MARKETING_VERSION = 3.3.3;
604+
MARKETING_VERSION = 3.3.7;
605605
OTHER_LDFLAGS = (
606606
"$(inherited)",
607607
"-ObjC",
@@ -700,7 +700,10 @@
700700
"-DFOLLY_CFG_NO_COROUTINES=1",
701701
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
702702
);
703-
OTHER_LDFLAGS = "$(inherited) ";
703+
OTHER_LDFLAGS = (
704+
"$(inherited)",
705+
" ",
706+
);
704707
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
705708
SDKROOT = iphoneos;
706709
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
@@ -784,7 +787,10 @@
784787
"-DFOLLY_CFG_NO_COROUTINES=1",
785788
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
786789
);
787-
OTHER_LDFLAGS = "$(inherited) ";
790+
OTHER_LDFLAGS = (
791+
"$(inherited)",
792+
" ",
793+
);
788794
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
789795
SDKROOT = iphoneos;
790796
USE_HERMES = true;

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mirrorfly-uikit-react-native",
3-
"version": "2.1.0",
3+
"version": "2.3.0",
44
"description": "React-Native based UI kit for Mirrorfly",
55
"main": "dist/index.js",
66
"module": "dist/index.js",
@@ -47,7 +47,7 @@
4747
"jest": "^29.6.3",
4848
"lodash-es": "^4.17.21",
4949
"luxon": "^3.5.0",
50-
"mirrorfly-reactnative-sdk": "^2.2.0",
50+
"mirrorfly-reactnative-sdk": "^2.3.0",
5151
"moment": "^2.30.1",
5252
"patch-package": "^8.0.0",
5353
"prettier": "2.8.8",
@@ -74,7 +74,7 @@
7474
"react-native-incall-manager": "^4.1.0",
7575
"react-native-keep-awake": "4.0.0",
7676
"react-native-keyevent": "^0.3.2",
77-
"react-native-maps": "^1.20.1",
77+
"react-native-maps": "1.20.1",
7878
"react-native-material-menu": "^2.0.0",
7979
"react-native-pager-view": "6.5.1",
8080
"react-native-permissions": "^5.2.4",
@@ -83,7 +83,7 @@
8383
"react-native-reanimated": "^3.17.0",
8484
"react-native-ringer-mode": "^2.0.1",
8585
"react-native-safe-area-context": "^4.14.0",
86-
"react-native-screens": "^4.3.0",
86+
"react-native-screens": "4.3.0",
8787
"react-native-sound": "^0.11.2",
8888
"react-native-svg": "^15.9.0",
8989
"react-native-svg-transformer": "^1.3.0",

src/Helper/Calls/Utility.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { openSettings } from 'react-native-permissions';
1010
import RNVoipPushNotification from 'react-native-voip-push-notification';
1111
import SDK, { RealmKeyValueStore } from '../../SDK/SDK';
1212
import { clearIosCallListeners, muteLocalAudio, muteLocalVideo, resetCallData } from '../../SDK/sdkCallBacks';
13-
import { getUserProfileFromApi, getUserProfileFromSDK } from '../../SDK/utils';
13+
import { getUserProfileFromApi, getUserProfileFromSDK, sdkLog } from '../../SDK/utils';
1414
import { callNotifyHandler, stopForegroundServiceNotification } from '../../calls/notification/callNotifyHandler';
1515
import { getNetworkState } from '../../common/hooks';
1616
import {
@@ -858,6 +858,7 @@ const onVoipPushNotificationReceived = async data => {
858858
payload: { caller_id, caller_name },
859859
callUUID,
860860
} = data;
861+
sdkLog('VoipPushNotificationReceived', data);
861862
const activeCallUUID = store.getState().callData?.callerUUID || '';
862863
if (activeCallUUID !== '') {
863864
const calls = await RNCallKeep.getCalls();

src/Navigation/stackNavigation.js

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ import {
7373
VIEWALLMEDIA,
7474
} from '../screens/constants';
7575
import { getCurrentScreen } from '../uikitMethods';
76+
import ConnectionStatus from '../common/ConnectionStatus';
77+
import { View } from 'react-native';
7678

7779
const Stack = createNativeStackNavigator();
7880

@@ -164,28 +166,34 @@ const GroupScreenStackNavigation = () => {
164166
};
165167

166168
function StackNavigationPage() {
167-
console.log('StackNavigationPage ==>', getCurrentScreen());
168169
return (
169170
<Provider store={store}>
170-
<Stack.Navigator
171-
screenOptions={{
172-
headerShown: false,
173-
orientation: 'portrait',
174-
}}
175-
initialRouteName={getCurrentScreen()}>
176-
<Stack.Screen name={REGISTERSCREEN}>{prop => <RegisterScreen {...prop} />}</Stack.Screen>
177-
<Stack.Screen name={COUNTRY_LIST_SCREEN}>{prop => <CountryList {...prop} />}</Stack.Screen>
178-
<Stack.Screen name={RECENTCHATSCREEN}>{prop => <RecentChatScreen {...prop} />}</Stack.Screen>
179-
<Stack.Screen name={CONVERSATION_STACK}>{prop => <ChatScreen {...prop} />}</Stack.Screen>
180-
<Stack.Screen name={USERS_LIST_SCREEN}>{prop => <UsersListScreen {...prop} />}</Stack.Screen>
181-
<Stack.Screen name={SETTINGS_STACK}>{prop => <SettingsScreen {...prop} />}</Stack.Screen>
182-
<Stack.Screen name={ARCHIVED_SCREEN}>{prop => <ArchivedScreen {...prop} />}</Stack.Screen>
183-
<Stack.Screen name={GROUP_STACK}>{prop => <GroupScreenStackNavigation {...prop} />}</Stack.Screen>
184-
</Stack.Navigator>
185-
<ToastMessage />
186-
<AlertModalRoot />
171+
<View style={styles.container}>
172+
<ConnectionStatus />
173+
<Stack.Navigator
174+
screenOptions={{
175+
headerShown: false,
176+
orientation: 'portrait',
177+
}}
178+
initialRouteName={getCurrentScreen()}>
179+
<Stack.Screen name={REGISTERSCREEN}>{prop => <RegisterScreen {...prop} />}</Stack.Screen>
180+
<Stack.Screen name={COUNTRY_LIST_SCREEN}>{prop => <CountryList {...prop} />}</Stack.Screen>
181+
<Stack.Screen name={RECENTCHATSCREEN}>{prop => <RecentChatScreen {...prop} />}</Stack.Screen>
182+
<Stack.Screen name={CONVERSATION_STACK}>{prop => <ChatScreen {...prop} />}</Stack.Screen>
183+
<Stack.Screen name={USERS_LIST_SCREEN}>{prop => <UsersListScreen {...prop} />}</Stack.Screen>
184+
<Stack.Screen name={SETTINGS_STACK}>{prop => <SettingsScreen {...prop} />}</Stack.Screen>
185+
<Stack.Screen name={ARCHIVED_SCREEN}>{prop => <ArchivedScreen {...prop} />}</Stack.Screen>
186+
<Stack.Screen name={GROUP_STACK}>{prop => <GroupScreenStackNavigation {...prop} />}</Stack.Screen>
187+
</Stack.Navigator>
188+
<ToastMessage />
189+
<AlertModalRoot />
190+
</View>
187191
</Provider>
188192
);
189193
}
190194

191195
export default StackNavigationPage;
196+
197+
const styles = {
198+
container: { flex: 1, position: 'relative' },
199+
};

src/SDK/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export const CONNECTED = 'CONNECTED';
2+
export const DISCONNECTED = 'DISCONNECTED';
3+
export const RECONNECTING = 'RECONNECTING';

0 commit comments

Comments
 (0)