feat (Android): mobile ringer (#5286)
This commit is contained in:
parent
bd17ee55bf
commit
31ed940426
Binary file not shown.
|
@ -97,10 +97,14 @@ public class CustomPushNotification extends PushNotification {
|
|||
bundle.putString("senderId", hasSender ? loadedEjson.sender._id : "1");
|
||||
bundle.putString("avatarUri", loadedEjson.getAvatarUri());
|
||||
|
||||
if (loadedEjson.notificationType.equals("videoconf")) {
|
||||
notifyReceivedToJS();
|
||||
} else {
|
||||
notificationMessages.get(notId).add(bundle);
|
||||
postNotification(Integer.parseInt(notId));
|
||||
notifyReceivedToJS();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpened() {
|
||||
|
|
|
@ -65,7 +65,7 @@ export const METEOR = createRequestTypes('METEOR_CONNECT', [...defaultTypes, 'DI
|
|||
export const LOGOUT = 'LOGOUT'; // logout is always success
|
||||
export const DELETE_ACCOUNT = 'DELETE_ACCOUNT';
|
||||
export const SNIPPETED_MESSAGES = createRequestTypes('SNIPPETED_MESSAGES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED']);
|
||||
export const DEEP_LINKING = createRequestTypes('DEEP_LINKING', ['OPEN']);
|
||||
export const DEEP_LINKING = createRequestTypes('DEEP_LINKING', ['OPEN', 'OPEN_VIDEO_CONF']);
|
||||
export const SORT_PREFERENCES = createRequestTypes('SORT_PREFERENCES', ['SET_ALL', 'SET']);
|
||||
export const SET_CUSTOM_EMOJIS = 'SET_CUSTOM_EMOJIS';
|
||||
export const ACTIVE_USERS = createRequestTypes('ACTIVE_USERS', ['SET', 'CLEAR']);
|
||||
|
|
|
@ -22,3 +22,10 @@ export function deepLinkingOpen(params: Partial<IParams>): IDeepLinkingOpen {
|
|||
params
|
||||
};
|
||||
}
|
||||
|
||||
export function deepLinkingClickCallPush(params: any): IDeepLinkingOpen {
|
||||
return {
|
||||
type: DEEP_LINKING.OPEN_VIDEO_CONF,
|
||||
params
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,8 +8,6 @@ export enum ERingerSounds {
|
|||
}
|
||||
|
||||
const Ringer = React.memo(({ ringer }: { ringer: ERingerSounds }) => {
|
||||
console.log('Ringer', ringer);
|
||||
|
||||
const sound = useRef<Audio.Sound | null>(null);
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
|
|
|
@ -749,6 +749,7 @@
|
|||
"Continue": "Continue",
|
||||
"Message_has_been_shared": "Message has been shared",
|
||||
"No_channels_in_team": "No Channels on this team",
|
||||
"conference_call": "Conference call",
|
||||
"Room_not_found": "Room not found",
|
||||
"The_room_does_not_exist": "The room does not exist or you may not have access permission",
|
||||
"Supported_versions_expired_title": "{{workspace_name}} is running an unsupported version of Rocket.Chat",
|
||||
|
@ -758,5 +759,6 @@
|
|||
"The_user_will_be_able_to_type_in_roomName": "The user will be able to type in {{roomName}}",
|
||||
"Enable_writing_in_room": "Enable writing in room",
|
||||
"Disable_writing_in_room": "Disable writing in room",
|
||||
"Pinned_a_message": "Pinned a message:"
|
||||
"Pinned_a_message": "Pinned a message:",
|
||||
"Missed_call": "Missed call"
|
||||
}
|
||||
|
|
|
@ -747,7 +747,6 @@
|
|||
"decline": "Recusar",
|
||||
"accept": "Aceitar",
|
||||
"Incoming_call_from": "Chamada recebida de",
|
||||
"Call_started": "Chamada Iniciada",
|
||||
"Room_not_found": "Sala não encontrada",
|
||||
"The_room_does_not_exist": "A sala não existe ou você pode não ter permissão de acesso",
|
||||
"Call_started": "Chamada iniciada",
|
||||
|
@ -757,5 +756,6 @@
|
|||
"The_user_wont_be_able_to_type_in_roomName": "O usuário não poderá digitar em {{roomName}}",
|
||||
"The_user_will_be_able_to_type_in_roomName": "O usuário poderá digitar em {{roomName}}",
|
||||
"Enable_writing_in_room": "Permitir escrita na sala",
|
||||
"Disable_writing_in_room": "Desabilitar escrita na sala"
|
||||
"Disable_writing_in_room": "Desabilitar escrita na sala",
|
||||
"Missed_call": "Chamada perdida"
|
||||
}
|
|
@ -1,30 +1,26 @@
|
|||
import React from 'react';
|
||||
import { Dimensions, Linking } from 'react-native';
|
||||
import { initialWindowMetrics, SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
import RNScreens from 'react-native-screens';
|
||||
import { Provider } from 'react-redux';
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||
import Orientation from 'react-native-orientation-locker';
|
||||
import { SafeAreaProvider, initialWindowMetrics } from 'react-native-safe-area-context';
|
||||
import RNScreens from 'react-native-screens';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import AppContainer from './AppContainer';
|
||||
import { appInit, appInitLocalSettings, setMasterDetail as setMasterDetailAction } from './actions/app';
|
||||
import { deepLinkingOpen } from './actions/deepLinking';
|
||||
import AppContainer from './AppContainer';
|
||||
import { ActionSheetProvider } from './containers/ActionSheet';
|
||||
import InAppNotification from './containers/InAppNotification';
|
||||
import Loading from './containers/Loading';
|
||||
import Toast from './containers/Toast';
|
||||
import TwoFactor from './containers/TwoFactor';
|
||||
import Loading from './containers/Loading';
|
||||
import { IThemePreference } from './definitions/ITheme';
|
||||
import { DimensionsContext } from './dimensions';
|
||||
import { colors, isFDroidBuild, MIN_WIDTH_MASTER_DETAIL_LAYOUT, themes } from './lib/constants';
|
||||
import { MIN_WIDTH_MASTER_DETAIL_LAYOUT, colors, isFDroidBuild, themes } from './lib/constants';
|
||||
import { getAllowAnalyticsEvents, getAllowCrashReport } from './lib/methods';
|
||||
import parseQuery from './lib/methods/helpers/parseQuery';
|
||||
import { initializePushNotifications, onNotification } from './lib/notifications';
|
||||
import store from './lib/store';
|
||||
import { initStore } from './lib/store/auxStore';
|
||||
import { ThemeContext, TSupportedThemes } from './theme';
|
||||
import { debounce, isTablet } from './lib/methods/helpers';
|
||||
import { toggleAnalyticsEventsReport, toggleCrashErrorsReport } from './lib/methods/helpers/log';
|
||||
import parseQuery from './lib/methods/helpers/parseQuery';
|
||||
import {
|
||||
getTheme,
|
||||
initialTheme,
|
||||
|
@ -33,6 +29,11 @@ import {
|
|||
subscribeTheme,
|
||||
unsubscribeTheme
|
||||
} from './lib/methods/helpers/theme';
|
||||
import { initializePushNotifications, onNotification } from './lib/notifications';
|
||||
import { getInitialNotification } from './lib/notifications/videoConf/getInitialNotification';
|
||||
import store from './lib/store';
|
||||
import { initStore } from './lib/store/auxStore';
|
||||
import { TSupportedThemes, ThemeContext } from './theme';
|
||||
import ChangePasscodeView from './views/ChangePasscodeView';
|
||||
import ScreenLockedView from './views/ScreenLockedView';
|
||||
|
||||
|
@ -126,6 +127,8 @@ export default class Root extends React.Component<{}, IState> {
|
|||
return;
|
||||
}
|
||||
|
||||
await getInitialNotification();
|
||||
|
||||
// Open app from deep linking
|
||||
const deepLinking = await Linking.getInitialURL();
|
||||
const parsedDeepLinkingURL = parseDeepLinking(deepLinking!);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
export const BACKGROUND_PUSH_COLOR = '#F5455C';
|
||||
|
||||
export const STATUS_COLORS: any = {
|
||||
online: '#2de0a5',
|
||||
busy: '#f5455c',
|
||||
|
|
|
@ -118,3 +118,5 @@ export const goRoom = async ({
|
|||
|
||||
return navigate({ item, isMasterDetail, popToRoot, ...props });
|
||||
};
|
||||
|
||||
export const navigateToRoom = navigate;
|
||||
|
|
|
@ -26,7 +26,7 @@ export const handleAndroidBltPermission = async (): Promise<void> => {
|
|||
}
|
||||
};
|
||||
|
||||
export const videoConfJoin = async (callId: string, cam?: boolean, mic?: boolean): Promise<void> => {
|
||||
export const videoConfJoin = async (callId: string, cam?: boolean, mic?: boolean, fromPush?: boolean): Promise<void> => {
|
||||
try {
|
||||
const result = await Services.videoConferenceJoin(callId, cam, mic);
|
||||
if (result.success) {
|
||||
|
@ -38,7 +38,11 @@ export const videoConfJoin = async (callId: string, cam?: boolean, mic?: boolean
|
|||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (fromPush) {
|
||||
showErrorAlert(i18n.t('Missed_call'));
|
||||
} else {
|
||||
showErrorAlert(i18n.t('error-init-video-conf'));
|
||||
}
|
||||
log(e);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import EJSON from 'ejson';
|
||||
|
||||
import { store } from '../store/auxStore';
|
||||
import { deepLinkingOpen } from '../../actions/deepLinking';
|
||||
import { isFDroidBuild } from '../constants';
|
||||
import { deviceToken, pushNotificationConfigure, setNotificationsBadgeCount, removeAllNotifications } from './push';
|
||||
import { INotification, SubscriptionType } from '../../definitions';
|
||||
import { isFDroidBuild } from '../constants';
|
||||
import { store } from '../store/auxStore';
|
||||
import { deviceToken, pushNotificationConfigure, removeAllNotifications, setNotificationsBadgeCount } from './push';
|
||||
|
||||
interface IEjson {
|
||||
rid: string;
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
import notifee, { AndroidCategory, AndroidImportance, AndroidVisibility, Event } from '@notifee/react-native';
|
||||
import messaging from '@react-native-firebase/messaging';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import ejson from 'ejson';
|
||||
|
||||
import { deepLinkingClickCallPush } from '../../../actions/deepLinking';
|
||||
import i18n from '../../../i18n';
|
||||
import { BACKGROUND_PUSH_COLOR } from '../../constants';
|
||||
import { store } from '../../store/auxStore';
|
||||
|
||||
const VIDEO_CONF_CHANNEL = 'video-conf-call';
|
||||
const VIDEO_CONF_TYPE = 'videoconf';
|
||||
|
||||
interface Caller {
|
||||
_id?: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
interface NotificationData {
|
||||
notificationType?: string;
|
||||
status?: number;
|
||||
rid?: string;
|
||||
caller?: Caller;
|
||||
}
|
||||
|
||||
const createChannel = () =>
|
||||
notifee.createChannel({
|
||||
id: VIDEO_CONF_CHANNEL,
|
||||
name: 'Video Call',
|
||||
lights: true,
|
||||
vibration: true,
|
||||
importance: AndroidImportance.HIGH,
|
||||
sound: 'ringtone'
|
||||
});
|
||||
|
||||
const handleBackgroundEvent = async (event: Event) => {
|
||||
const { pressAction, notification } = event.detail;
|
||||
const notificationData = notification?.data;
|
||||
if (
|
||||
typeof notificationData?.caller === 'object' &&
|
||||
(notificationData.caller as Caller)?._id &&
|
||||
(event.type === 1 || event.type === 2)
|
||||
) {
|
||||
if (store?.getState()?.app.ready) {
|
||||
store.dispatch(deepLinkingClickCallPush({ ...notificationData, event: pressAction?.id }));
|
||||
} else {
|
||||
AsyncStorage.setItem('pushNotification', JSON.stringify({ ...notificationData, event: pressAction?.id }));
|
||||
}
|
||||
await notifee.cancelNotification(
|
||||
`${notificationData.rid}${(notificationData.caller as Caller)._id}`.replace(/[^A-Za-z0-9]/g, '')
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const backgroundNotificationHandler = () => {
|
||||
notifee.onBackgroundEvent(handleBackgroundEvent);
|
||||
};
|
||||
|
||||
const displayVideoConferenceNotification = async (notification: NotificationData) => {
|
||||
const id = `${notification.rid}${notification.caller?._id}`.replace(/[^A-Za-z0-9]/g, '');
|
||||
const actions = [
|
||||
{
|
||||
title: i18n.t('accept'),
|
||||
pressAction: {
|
||||
id: 'accept',
|
||||
launchActivity: 'default'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: i18n.t('decline'),
|
||||
pressAction: {
|
||||
id: 'decline',
|
||||
launchActivity: 'default'
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
await notifee.displayNotification({
|
||||
id,
|
||||
title: i18n.t('conference_call'),
|
||||
body: `${i18n.t('Incoming_call_from')} ${notification.caller?.name}`,
|
||||
data: notification as { [key: string]: string | number | object },
|
||||
android: {
|
||||
channelId: VIDEO_CONF_CHANNEL,
|
||||
category: AndroidCategory.CALL,
|
||||
visibility: AndroidVisibility.PUBLIC,
|
||||
importance: AndroidImportance.HIGH,
|
||||
smallIcon: 'ic_notification',
|
||||
color: BACKGROUND_PUSH_COLOR,
|
||||
actions,
|
||||
lightUpScreen: true,
|
||||
loopSound: true,
|
||||
sound: 'ringtone',
|
||||
autoCancel: false,
|
||||
ongoing: true,
|
||||
pressAction: {
|
||||
id: 'default',
|
||||
launchActivity: 'default'
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const setBackgroundNotificationHandler = () => {
|
||||
createChannel();
|
||||
messaging().setBackgroundMessageHandler(async message => {
|
||||
const notification: NotificationData = ejson.parse(message?.data?.ejson as string);
|
||||
if (notification?.notificationType === VIDEO_CONF_TYPE) {
|
||||
if (notification.status === 0) {
|
||||
await displayVideoConferenceNotification(notification);
|
||||
} else if (notification.status === 4) {
|
||||
const id = `${notification.rid}${notification.caller?._id}`.replace(/[^A-Za-z0-9]/g, '');
|
||||
await notifee.cancelNotification(id);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
};
|
||||
|
||||
setBackgroundNotificationHandler();
|
||||
backgroundNotificationHandler();
|
|
@ -0,0 +1,15 @@
|
|||
import { deepLinkingClickCallPush } from '../../../actions/deepLinking';
|
||||
import { isAndroid } from '../../methods/helpers';
|
||||
import { store } from '../../store/auxStore';
|
||||
|
||||
export const getInitialNotification = async (): Promise<void> => {
|
||||
if (isAndroid) {
|
||||
const notifee = require('@notifee/react-native').default;
|
||||
const initialNotification = await notifee.getInitialNotification();
|
||||
if (initialNotification?.notification?.data?.notificationType === 'videoconf') {
|
||||
store.dispatch(
|
||||
deepLinkingClickCallPush({ ...initialNotification?.notification?.data, event: initialNotification?.pressAction?.id })
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,20 +1,21 @@
|
|||
import { all, delay, put, select, take, takeLatest } from 'redux-saga/effects';
|
||||
import { all, call, delay, put, select, take, takeLatest } from 'redux-saga/effects';
|
||||
|
||||
import UserPreferences from '../lib/methods/userPreferences';
|
||||
import * as types from '../actions/actionsTypes';
|
||||
import { selectServerRequest, serverInitAdd } from '../actions/server';
|
||||
import { inviteLinksRequest, inviteLinksSetToken } from '../actions/inviteLinks';
|
||||
import database from '../lib/database';
|
||||
import EventEmitter from '../lib/methods/helpers/events';
|
||||
import { appInit, appStart } from '../actions/app';
|
||||
import { localAuthenticate } from '../lib/methods/helpers/localAuthentication';
|
||||
import { goRoom } from '../lib/methods/helpers/goRoom';
|
||||
import { getUidDirectMessage } from '../lib/methods/helpers';
|
||||
import { inviteLinksRequest, inviteLinksSetToken } from '../actions/inviteLinks';
|
||||
import { loginRequest } from '../actions/login';
|
||||
import log from '../lib/methods/helpers/log';
|
||||
import { selectServerRequest, serverInitAdd } from '../actions/server';
|
||||
import { RootEnum } from '../definitions';
|
||||
import { CURRENT_SERVER, TOKEN_KEY } from '../lib/constants';
|
||||
import database from '../lib/database';
|
||||
import { canOpenRoom, getServerInfo } from '../lib/methods';
|
||||
import { getUidDirectMessage } from '../lib/methods/helpers';
|
||||
import EventEmitter from '../lib/methods/helpers/events';
|
||||
import { goRoom, navigateToRoom } from '../lib/methods/helpers/goRoom';
|
||||
import { localAuthenticate } from '../lib/methods/helpers/localAuthentication';
|
||||
import log from '../lib/methods/helpers/log';
|
||||
import UserPreferences from '../lib/methods/userPreferences';
|
||||
import { videoConfJoin } from '../lib/methods/videoConf';
|
||||
import { Services } from '../lib/services';
|
||||
|
||||
const roomTypes = {
|
||||
|
@ -168,7 +169,90 @@ const handleOpen = function* handleOpen({ params }) {
|
|||
}
|
||||
};
|
||||
|
||||
const handleNavigateCallRoom = function* handleNavigateCallRoom({ params }) {
|
||||
yield put(appStart({ root: RootEnum.ROOT_INSIDE }));
|
||||
const db = database.active;
|
||||
const subsCollection = db.get('subscriptions');
|
||||
const room = yield subsCollection.find(params.rid);
|
||||
if (room) {
|
||||
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
||||
yield navigateToRoom({ item: room, isMasterDetail, popToRoot: true });
|
||||
const uid = params.caller._id;
|
||||
const { rid, callId, event } = params;
|
||||
if (event === 'accept') {
|
||||
yield call(Services.notifyUser, `${uid}/video-conference`, {
|
||||
action: 'accepted',
|
||||
params: { uid, rid, callId }
|
||||
});
|
||||
yield videoConfJoin(callId, true, false, true);
|
||||
} else if (event === 'decline') {
|
||||
yield call(Services.notifyUser, `${uid}/video-conference`, {
|
||||
action: 'rejected',
|
||||
params: { uid, rid, callId }
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleClickCallPush = function* handleOpen({ params }) {
|
||||
const serversDB = database.servers;
|
||||
const serversCollection = serversDB.get('servers');
|
||||
|
||||
let { host } = params;
|
||||
|
||||
if (host.slice(-1) === '/') {
|
||||
host = host.slice(0, host.length - 1);
|
||||
}
|
||||
|
||||
const [server, user] = yield all([
|
||||
UserPreferences.getString(CURRENT_SERVER),
|
||||
UserPreferences.getString(`${TOKEN_KEY}-${host}`)
|
||||
]);
|
||||
|
||||
if (server === host && user) {
|
||||
const connected = yield select(state => state.server.connected);
|
||||
if (!connected) {
|
||||
yield localAuthenticate(host);
|
||||
yield put(selectServerRequest(host));
|
||||
yield take(types.LOGIN.SUCCESS);
|
||||
}
|
||||
yield handleNavigateCallRoom({ params });
|
||||
} else {
|
||||
// search if deep link's server already exists
|
||||
try {
|
||||
const hostServerRecord = yield serversCollection.find(host);
|
||||
if (hostServerRecord && user) {
|
||||
yield localAuthenticate(host);
|
||||
yield put(selectServerRequest(host, hostServerRecord.version, true, true));
|
||||
yield take(types.LOGIN.SUCCESS);
|
||||
yield handleNavigateCallRoom({ params });
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
// do nothing?
|
||||
}
|
||||
// if deep link is from a different server
|
||||
const result = yield Services.getServerInfo(host);
|
||||
if (!result.success) {
|
||||
// Fallback to prevent the app from being stuck on splash screen
|
||||
yield fallbackNavigation();
|
||||
return;
|
||||
}
|
||||
yield put(appStart({ root: RootEnum.ROOT_OUTSIDE }));
|
||||
yield put(serverInitAdd(server));
|
||||
yield delay(1000);
|
||||
EventEmitter.emit('NewServer', { server: host });
|
||||
if (params.token) {
|
||||
yield take(types.SERVER.SELECT_SUCCESS);
|
||||
yield put(loginRequest({ resume: params.token }, true));
|
||||
yield take(types.LOGIN.SUCCESS);
|
||||
yield handleNavigateCallRoom({ params });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const root = function* root() {
|
||||
yield takeLatest(types.DEEP_LINKING.OPEN, handleOpen);
|
||||
yield takeLatest(types.DEEP_LINKING.OPEN_VIDEO_CONF, handleClickCallPush);
|
||||
};
|
||||
export default root;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { put, takeLatest } from 'redux-saga/effects';
|
||||
import { call, put, takeLatest } from 'redux-saga/effects';
|
||||
import RNBootSplash from 'react-native-bootsplash';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
import { BIOMETRY_ENABLED_KEY, CURRENT_SERVER, TOKEN_KEY } from '../lib/constants';
|
||||
import UserPreferences from '../lib/methods/userPreferences';
|
||||
|
@ -12,6 +13,7 @@ import { localAuthenticate } from '../lib/methods/helpers/localAuthentication';
|
|||
import { appReady, appStart } from '../actions/app';
|
||||
import { RootEnum } from '../definitions';
|
||||
import { getSortPreferences } from '../lib/methods';
|
||||
import { deepLinkingClickCallPush } from '../actions/deepLinking';
|
||||
|
||||
export const initLocalSettings = function* initLocalSettings() {
|
||||
const sortPreferences = getSortPreferences();
|
||||
|
@ -70,6 +72,11 @@ const restore = function* restore() {
|
|||
}
|
||||
|
||||
yield put(appReady({}));
|
||||
const pushNotification = yield call(AsyncStorage.getItem, 'pushNotification');
|
||||
if (pushNotification) {
|
||||
const pushNotification = yield call(AsyncStorage.removeItem, 'pushNotification');
|
||||
yield call(deepLinkingClickCallPush, JSON.parse(pushNotification));
|
||||
}
|
||||
} catch (e) {
|
||||
log(e);
|
||||
yield put(appStart({ root: RootEnum.ROOT_OUTSIDE }));
|
||||
|
|
7
index.js
7
index.js
|
@ -3,6 +3,8 @@ import 'react-native-console-time-polyfill';
|
|||
import { AppRegistry } from 'react-native';
|
||||
|
||||
import { name as appName, share as shareName } from './app.json';
|
||||
import { isFDroidBuild } from './app/lib/constants';
|
||||
import { isAndroid } from './app/lib/methods/helpers';
|
||||
|
||||
if (__DEV__) {
|
||||
require('./app/ReactotronConfig');
|
||||
|
@ -18,6 +20,11 @@ if (__DEV__) {
|
|||
console.info = () => {};
|
||||
}
|
||||
|
||||
if (!isFDroidBuild && isAndroid) {
|
||||
require('./app/lib/notifications/videoConf/backgroundNotificationHandler');
|
||||
}
|
||||
|
||||
|
||||
AppRegistry.registerComponent(appName, () => require('./app/index').default);
|
||||
AppRegistry.registerComponent(shareName, () => require('./app/share').default);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"@codler/react-native-keyboard-aware-scroll-view": "^2.0.1",
|
||||
"@gorhom/bottom-sheet": "^4.3.1",
|
||||
"@hookform/resolvers": "^2.9.10",
|
||||
"@notifee/react-native": "^7.8.0",
|
||||
"@nozbe/watermelondb": "0.23.0",
|
||||
"@react-native-async-storage/async-storage": "^1.17.11",
|
||||
"@react-native-camera-roll/camera-roll": "5.6.1",
|
||||
|
@ -46,6 +47,7 @@
|
|||
"@react-native-firebase/analytics": "^14.11.0",
|
||||
"@react-native-firebase/app": "^14.11.0",
|
||||
"@react-native-firebase/crashlytics": "^14.11.0",
|
||||
"@react-native-firebase/messaging": "^18.5.0",
|
||||
"@react-native-masked-view/masked-view": "^0.2.8",
|
||||
"@react-navigation/drawer": "6.4.1",
|
||||
"@react-navigation/elements": "^1.3.6",
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
--- a/node_modules/@notifee/react-native/android/src/main/java/io/invertase/notifee/NotifeeApiModule.java
|
||||
+++ b/node_modules/@notifee/react-native/android/src/main/java/io/invertase/notifee/NotifeeApiModule.java
|
||||
@@ -238,7 +238,7 @@ public class NotifeeApiModule extends ReactContextBaseJavaModule implements Perm
|
||||
@ReactMethod
|
||||
public void requestPermission(Promise promise) {
|
||||
// For Android 12 and below, we return the notification settings
|
||||
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||
+ if (Build.VERSION.SDK_INT < 33) {
|
||||
Notifee.getInstance()
|
||||
.getNotificationSettings(
|
||||
(e, aBundle) -> NotifeeReactUtils.promiseResolver(promise, e, aBundle));
|
||||
@@ -265,7 +265,7 @@ public class NotifeeApiModule extends ReactContextBaseJavaModule implements Perm
|
||||
(e, aBundle) -> NotifeeReactUtils.promiseResolver(promise, e, aBundle));
|
||||
|
||||
activity.requestPermissions(
|
||||
- new String[] {Manifest.permission.POST_NOTIFICATIONS},
|
||||
+ new String[] {"android.permission.POST_NOTIFICATIONS"},
|
||||
Notifee.REQUEST_CODE_NOTIFICATION_PERMISSION,
|
||||
this);
|
||||
}
|
|
@ -14,6 +14,16 @@ module.exports = {
|
|||
platforms: {
|
||||
android: null
|
||||
}
|
||||
},
|
||||
'@react-native-firebase/messaging': {
|
||||
platforms: {
|
||||
ios: null
|
||||
}
|
||||
},
|
||||
'@notifee/react-native': {
|
||||
platforms: {
|
||||
ios: null
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -5153,6 +5153,11 @@
|
|||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@notifee/react-native@^7.8.0":
|
||||
version "7.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@notifee/react-native/-/react-native-7.8.0.tgz#2990883753990f3585aa0cb5becc5cbdbcd87a43"
|
||||
integrity sha512-sx8h62U4FrR4pqlbN1rkgPsdamDt9Tad0zgfO6VtP6rNJq/78k8nxUnh0xIX3WPDcCV8KAzdYCE7+UNvhF1CpQ==
|
||||
|
||||
"@nozbe/simdjson@0.9.6-fix2":
|
||||
version "0.9.6-fix2"
|
||||
resolved "https://registry.yarnpkg.com/@nozbe/simdjson/-/simdjson-0.9.6-fix2.tgz#00d1c8ec76bfac25c022b07511c8fff4568b2973"
|
||||
|
@ -5488,6 +5493,11 @@
|
|||
"@expo/config-plugins" "^4.1.5"
|
||||
stacktrace-js "^2.0.0"
|
||||
|
||||
"@react-native-firebase/messaging@^18.5.0":
|
||||
version "18.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-firebase/messaging/-/messaging-18.5.0.tgz#2a80b25816470e9843682e031a3a113566067ce6"
|
||||
integrity sha512-y1FApYxBMcygmbWBqUPFC+fCfvx6Yf6TdZewun7kPwx+S+tkYzoKx1IsXtxOXtqyJjCNEYirjFgNrs5SSd02zA==
|
||||
|
||||
"@react-native-masked-view/masked-view@^0.2.8":
|
||||
version "0.2.8"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-masked-view/masked-view/-/masked-view-0.2.8.tgz#34405a4361882dae7c81b1b771fe9f5fbd545a97"
|
||||
|
|
Loading…
Reference in New Issue