Skip to content

Commit 9d5555b

Browse files
Merge remote-tracking branch 'upstream/master' into feature/update-2.3.0
2 parents 2937333 + 4de2067 commit 9d5555b

34 files changed

+451
-267
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: 2 additions & 2 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",

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';

src/SDK/sdkCallBacks.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import RootNavigation from '../Navigation/rootNavigation';
6666
import { progressMap, updateProgressNotification } from '../Service/PushNotify';
6767
import { pushNotify, updateNotification } from '../Service/remoteNotifyHandle';
6868
import { callNotifyHandler, stopForegroundServiceNotification } from '../calls/notification/callNotifyHandler';
69+
import { stopAudioRecord } from '../components/ChatInput';
6970
import ActivityModule from '../customModules/ActivityModule';
7071
import BluetoothHeadsetDetectionModule from '../customModules/BluetoothHeadsetDetectionModule';
7172
import RNCallKeep from '../customModules/CallKitModule';
@@ -122,8 +123,8 @@ import {
122123
updateRecentMessageStatus,
123124
} from '../redux/recentChatDataSlice';
124125
import { getArchive, getChatMessage } from '../redux/reduxHook';
125-
import { setRoasterData, updateIsBlockedMe } from '../redux/rosterDataSlice';
126-
import { toggleArchiveSetting } from '../redux/settingDataSlice';
126+
import { setRoasterData, toggleMute, updateIsBlockedMe } from '../redux/rosterDataSlice';
127+
import { toggleArchiveSetting, toggleNotificationDisabled } from '../redux/settingDataSlice';
127128
import { resetConferencePopup, showConfrence, updateConference } from '../redux/showConfrenceSlice';
128129
import store from '../redux/store';
129130
import { resetTypingStatus, setTypingStatus } from '../redux/typingStatusDataSlice';
@@ -137,7 +138,6 @@ import {
137138
} from '../uikitMethods';
138139
import SDK from './SDK';
139140
import { fetchGroupParticipants, getUserProfileFromSDK } from './utils';
140-
import { stopAudioRecord } from '../components/ChatInput';
141141

142142
let localStream = null,
143143
localVideoMuted = false,
@@ -709,9 +709,12 @@ export const callBacks = {
709709
store.dispatch(addChatMessageItem(res));
710710
}
711711

712-
if (isShowNotification && !res?.editMessageId) {
712+
if (isShowNotification && !res?.editMessageId && !res?.profileDetails?.muteStatus) {
713713
pushNotify(res.msgId, getNotifyNickName(res), getNotifyMessage(res), res?.fromUserJid);
714714
}
715+
if (res?.profileDetails) {
716+
store.dispatch(setRoasterData(res?.profileDetails));
717+
}
715718
break;
716719
case 'delivered':
717720
case 'seen':
@@ -857,7 +860,11 @@ export const callBacks = {
857860
store.dispatch(updateMsgByLastMsgId(res));
858861
},
859862
muteChatListener: res => {
860-
console.log(res, 'muteChatListener');
863+
const { userJids, isMuted, muteNotification, muteSetting } = res || {};
864+
store.dispatch(toggleMute({ userJids, muteStatus: isMuted ? 1 : 0 }));
865+
if (muteSetting) {
866+
store.dispatch(toggleNotificationDisabled(muteNotification));
867+
}
861868
},
862869
archiveChatListener: res => {
863870
store.dispatch(toggleArchiveChatsByUserId(res));

src/SDK/utils.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,10 +523,8 @@ export const getUserSettings = async (iq = false) => {
523523

524524
export const updateNotificationSettings = async () => {
525525
let {
526-
data,
527526
data: { archive = 0, muteNotification = false, notificationSound = true, notificationVibrate = false },
528527
} = await SDK.getUserSettings();
529-
console.log('data ==>', JSON.stringify(data, null, 2));
530528
store.dispatch(toggleArchiveSetting(Number(archive)));
531529
store.dispatch(updateNotificationSetting({ muteNotification, notificationSound, notificationVibrate }));
532530
};

src/Service/PushNotify.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@ import notifee, {
66
} from '@notifee/react-native';
77
import { Platform } from 'react-native';
88
import { MISSED_CALL } from '../Helper/Calls/Constant';
9-
import { getMuteStatus } from '../SDK/utils';
109
import { onChatNotificationBackGround, onChatNotificationForeGround } from '../calls/notification/callNotifyHandler';
1110
import store from '../redux/store';
1211
import { mflog } from '../uikitMethods';
1312

1413
export const displayRemoteNotification = async (id, date, title, body, jid, importance) => {
15-
let isMute = await getMuteStatus(jid);
1614
const { muteNotification = false } = store.getState().settingsData;
17-
if (isMute === 0 && !muteNotification) {
15+
if (!muteNotification) {
1816
const channelIds = getChannelIds();
1917
let channelId = {
2018
id: channelIds.channelId,

0 commit comments

Comments
 (0)