@talkjs/react-native
Version:
Official TalkJS SDK for React Native
209 lines (208 loc) • 7.38 kB
JavaScript
;
import { getToken, getMessaging, onTokenRefresh, setBackgroundMessageHandler } from '@react-native-firebase/messaging';
import Notifee, { EventType } from '@notifee/react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { AndroidImportance, AndroidVisibility } from './Notification';
import { TokenHandler } from './Notification';
var AndroidStyle = /*#__PURE__*/function (AndroidStyle) {
AndroidStyle[AndroidStyle["BIGPICTURE"] = 0] = "BIGPICTURE";
AndroidStyle[AndroidStyle["BIGTEXT"] = 1] = "BIGTEXT";
AndroidStyle[AndroidStyle["INBOX"] = 2] = "INBOX";
AndroidStyle[AndroidStyle["MESSAGING"] = 3] = "MESSAGING";
return AndroidStyle;
}(AndroidStyle || {});
export class AndroidNotificationHandler extends TokenHandler {
#channelIdStorageKey = 'TalkJS_channel_id';
#activeNotifications = {};
#wasStopped = true;
constructor() {
super('fcm');
}
#onBackgroundMessage = async firebaseMessage => {
const channelId = await AsyncStorage.getItem(this.#channelIdStorageKey);
if (!channelId) {
return;
}
const data = firebaseMessage.data;
if (typeof data?.talkjs === 'string') {
let notification;
const androidSettings = {
channelId,
importance: AndroidImportance.HIGH,
sound: 'default',
showTimestamp: true,
pressAction: {
id: 'default'
}
};
const talkjsData = JSON.parse(data.talkjs);
if (talkjsData.sender.photoUrl) {
androidSettings['largeIcon'] = talkjsData.sender.photoUrl;
}
const notificationId = talkjsData.conversation.id;
const commonData = {
id: notificationId,
data: {
talkjs: data.talkjs
},
android: {
timestamp: talkjsData.timestamp,
...androidSettings
}
};
let sender = {
id: talkjsData.sender.id,
name: talkjsData.sender.name
};
if (talkjsData.sender.photoUrl) {
sender['icon'] = talkjsData.sender.photoUrl;
}
let activeNotifications = this.#activeNotifications[notificationId];
if (!activeNotifications) {
const attachment = talkjsData.message.attachment;
if (attachment) {
commonData.android.style = {
type: AndroidStyle.BIGPICTURE,
picture: attachment.url
};
} else {
const participants = talkjsData.conversation.participants;
commonData.android.style = {
type: AndroidStyle.MESSAGING,
person: {
name: 'me'
},
group: Object.keys(participants).length > 2,
messages: [{
person: sender,
text: talkjsData.message.text,
timestamp: talkjsData.timestamp
}]
};
}
notification = {
title: data.title,
body: data.message,
...commonData
};
this.#activeNotifications[notificationId] = [{
sender: talkjsData.sender,
message: talkjsData.message
}];
} else {
const messages = [];
for (let {
sender,
message
} of activeNotifications) {
let person = {
id: sender.id,
name: sender.name
};
if (sender.photoUrl) {
person['icon'] = sender.photoUrl;
}
messages.push({
person,
text: message.text,
timestamp: message.createdAt
});
}
messages.push({
person: sender,
text: talkjsData.message.text,
timestamp: talkjsData.timestamp
});
const participants = talkjsData.conversation.participants;
commonData.android.style = {
type: AndroidStyle.MESSAGING,
person: {
name: 'me'
},
group: Object.keys(participants).length > 2,
messages
};
notification = {
...commonData
};
activeNotifications.push({
sender: talkjsData.sender,
message: talkjsData.message
});
}
Notifee.displayNotification(notification);
}
};
removeActiveNotification = talkjsString => {
if (talkjsString) {
const talkjsData = JSON.parse(talkjsString);
delete this.#activeNotifications[talkjsData.conversation.id];
}
};
async setup(androidSettings, _) {
const messaging = getMessaging();
onTokenRefresh(messaging, token => this.setPushRegistrationId(token));
setBackgroundMessageHandler(messaging, this.#onBackgroundMessage);
Notifee.onBackgroundEvent(async event => {
const talkjsString = event.detail.notification?.data?.talkjs;
if (event.type === EventType.PRESS) {
this.removeActiveNotification(talkjsString);
this.notificationPressed(event, false);
} else if (event.type === EventType.DISMISSED) {
this.removeActiveNotification(talkjsString);
}
});
Notifee.onForegroundEvent(async event => {
const talkjsString = event.detail.notification?.data?.talkjs;
if (event.type === EventType.PRESS) {
this.removeActiveNotification(talkjsString);
this.notificationPressed(event, true);
} else if (event.type === EventType.DISMISSED) {
this.removeActiveNotification(talkjsString);
}
});
this.setPushRegistrationId(await getToken(messaging));
const channelId = await AsyncStorage.getItem(this.#channelIdStorageKey);
if (androidSettings && androidSettings.channelId !== channelId) {
await Notifee.createChannel({
id: androidSettings.channelId,
name: androidSettings.channelName,
badge: androidSettings.badge ?? true,
description: androidSettings.channelDescription ?? '',
lights: androidSettings.lights ?? true,
lightColor: androidSettings.lightColor ?? 'white',
bypassDnd: androidSettings.bypassDnd ?? false,
sound: androidSettings.playSound ?? 'default',
importance: androidSettings.importance ?? AndroidImportance.HIGH,
visibility: androidSettings.visibility ?? AndroidVisibility.PRIVATE,
vibration: androidSettings.vibrate ?? true,
vibrationPattern: androidSettings.vibrationPattern
});
await AsyncStorage.setItem(this.#channelIdStorageKey, androidSettings.channelId);
}
if (this.#wasStopped) {
const notifications = await Notifee.getDisplayedNotifications();
for (let displayedNotification of notifications) {
const notification = displayedNotification.notification;
if (JSON.stringify(notification.data) !== '{}') {
let activeNotifications = this.#activeNotifications[notification.id];
if (!activeNotifications) {
activeNotifications = [];
this.#activeNotifications[notification.id] = activeNotifications;
}
const data = notification.data;
if (data.talkjs) {
const talkjs = JSON.parse(data.talkjs);
activeNotifications.push({
sender: talkjs.sender,
message: talkjs.message
});
}
}
}
this.#wasStopped = false;
}
return this;
}
}
//# sourceMappingURL=AndroidNotification.js.map