Compare commits
4 Commits
start-a-ne
...
develop
Author | SHA1 | Date |
---|---|---|
Gleidson Daniel Silva | 4dfc9c70f3 | |
Piyush Gupta | 513e8ee636 | |
Mister-H | aa57237004 | |
Diego Mello | 58391964cb |
File diff suppressed because one or more lines are too long
|
@ -62,11 +62,6 @@ allprojects {
|
||||||
url "$rootDir/../node_modules/detox/Detox-android"
|
url "$rootDir/../node_modules/detox/Detox-android"
|
||||||
}
|
}
|
||||||
|
|
||||||
maven {
|
|
||||||
// expo-camera bundles a custom com.google.android:cameraview
|
|
||||||
url "$rootDir/../node_modules/expo-camera/android/maven"
|
|
||||||
}
|
|
||||||
|
|
||||||
mavenCentral {
|
mavenCentral {
|
||||||
content {
|
content {
|
||||||
excludeGroup "com.facebook.react"
|
excludeGroup "com.facebook.react"
|
||||||
|
|
|
@ -84,10 +84,3 @@ export const ENCRYPTION = createRequestTypes('ENCRYPTION', ['INIT', 'STOP', 'DEC
|
||||||
|
|
||||||
export const PERMISSIONS = createRequestTypes('PERMISSIONS', ['SET', 'UPDATE']);
|
export const PERMISSIONS = createRequestTypes('PERMISSIONS', ['SET', 'UPDATE']);
|
||||||
export const ROLES = createRequestTypes('ROLES', ['SET', 'UPDATE', 'REMOVE']);
|
export const ROLES = createRequestTypes('ROLES', ['SET', 'UPDATE', 'REMOVE']);
|
||||||
export const VIDEO_CONF = createRequestTypes('VIDEO_CONF', [
|
|
||||||
'HANDLE_INCOMING_WEBSOCKET_MESSAGES',
|
|
||||||
'SET',
|
|
||||||
'REMOVE',
|
|
||||||
'CLEAR',
|
|
||||||
'INIT_CALL'
|
|
||||||
]);
|
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
import { Action } from 'redux';
|
|
||||||
|
|
||||||
import { ICallInfo } from '../reducers/videoConf';
|
|
||||||
import { VIDEO_CONF } from './actionsTypes';
|
|
||||||
|
|
||||||
interface IHandleVideoConfIncomingWebsocketMessages extends Action {
|
|
||||||
data: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TCallProps = { mic: boolean; cam: boolean; direct: boolean; roomId: string };
|
|
||||||
|
|
||||||
export interface IVideoConfGenericAction extends Action {
|
|
||||||
payload: ICallInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TActionVideoConf = IHandleVideoConfIncomingWebsocketMessages & IVideoConfGenericAction & Action;
|
|
||||||
|
|
||||||
export function handleVideoConfIncomingWebsocketMessages(data: any): IHandleVideoConfIncomingWebsocketMessages {
|
|
||||||
return {
|
|
||||||
type: VIDEO_CONF.HANDLE_INCOMING_WEBSOCKET_MESSAGES,
|
|
||||||
data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setVideoConfCall(payload: ICallInfo): IVideoConfGenericAction {
|
|
||||||
return {
|
|
||||||
type: VIDEO_CONF.SET,
|
|
||||||
payload
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function removeVideoConfCall(payload: ICallInfo): IVideoConfGenericAction {
|
|
||||||
return {
|
|
||||||
type: VIDEO_CONF.REMOVE,
|
|
||||||
payload
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearVideoConfCalls(): Action {
|
|
||||||
return {
|
|
||||||
type: VIDEO_CONF.CLEAR
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function initVideoCall(payload: TCallProps): Action & { payload: TCallProps } {
|
|
||||||
return {
|
|
||||||
type: VIDEO_CONF.INIT_CALL,
|
|
||||||
payload
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,34 +1,31 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useWindowDimensions } from 'react-native';
|
|
||||||
import { FlatList } from 'react-native-gesture-handler';
|
import { FlatList } from 'react-native-gesture-handler';
|
||||||
|
|
||||||
import { EMOJI_BUTTON_SIZE } from './styles';
|
|
||||||
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
|
|
||||||
import { IEmoji } from '../../definitions/IEmoji';
|
import { IEmoji } from '../../definitions/IEmoji';
|
||||||
|
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
|
||||||
import { PressableEmoji } from './PressableEmoji';
|
import { PressableEmoji } from './PressableEmoji';
|
||||||
|
import { EMOJI_BUTTON_SIZE } from './styles';
|
||||||
|
|
||||||
interface IEmojiCategoryProps {
|
interface IEmojiCategoryProps {
|
||||||
emojis: IEmoji[];
|
emojis: IEmoji[];
|
||||||
onEmojiSelected: (emoji: IEmoji) => void;
|
onEmojiSelected: (emoji: IEmoji) => void;
|
||||||
tabLabel?: string; // needed for react-native-scrollable-tab-view only
|
tabLabel?: string; // needed for react-native-scrollable-tab-view only
|
||||||
|
parentWidth: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EmojiCategory = ({ onEmojiSelected, emojis }: IEmojiCategoryProps): React.ReactElement | null => {
|
const EmojiCategory = ({ onEmojiSelected, emojis, parentWidth }: IEmojiCategoryProps): React.ReactElement | null => {
|
||||||
const { width } = useWindowDimensions();
|
if (!parentWidth) {
|
||||||
|
|
||||||
const numColumns = Math.trunc(width / EMOJI_BUTTON_SIZE);
|
|
||||||
const marginHorizontal = (width % EMOJI_BUTTON_SIZE) / 2;
|
|
||||||
|
|
||||||
const renderItem = ({ item }: { item: IEmoji }) => <PressableEmoji emoji={item} onPress={onEmojiSelected} />;
|
|
||||||
|
|
||||||
if (!width) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const numColumns = Math.trunc(parentWidth / EMOJI_BUTTON_SIZE);
|
||||||
|
const marginHorizontal = (parentWidth % EMOJI_BUTTON_SIZE) / 2;
|
||||||
|
|
||||||
|
const renderItem = ({ item }: { item: IEmoji }) => <PressableEmoji emoji={item} onPress={onEmojiSelected} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlatList
|
<FlatList
|
||||||
// needed to update the numColumns when the width changes
|
key={`emoji-category-${parentWidth}`}
|
||||||
key={`emoji-category-${width}`}
|
|
||||||
keyExtractor={item => (typeof item === 'string' ? item : item.name)}
|
keyExtractor={item => (typeof item === 'string' ? item : item.name)}
|
||||||
data={emojis}
|
data={emojis}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import ScrollableTabView from 'react-native-scrollable-tab-view';
|
import ScrollableTabView from 'react-native-scrollable-tab-view';
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ const EmojiPicker = ({
|
||||||
searchedEmojis = []
|
searchedEmojis = []
|
||||||
}: IEmojiPickerProps): React.ReactElement | null => {
|
}: IEmojiPickerProps): React.ReactElement | null => {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
|
const [parentWidth, setParentWidth] = useState(0);
|
||||||
|
|
||||||
const { frequentlyUsed, loaded } = useFrequentlyUsedEmoji();
|
const { frequentlyUsed, loaded } = useFrequentlyUsedEmoji();
|
||||||
|
|
||||||
const allCustomEmojis: ICustomEmojis = useAppSelector(
|
const allCustomEmojis: ICustomEmojis = useAppSelector(
|
||||||
|
@ -50,7 +52,14 @@ const EmojiPicker = ({
|
||||||
if (!emojis.length) {
|
if (!emojis.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return <EmojiCategory emojis={emojis} onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)} tabLabel={label} />;
|
return (
|
||||||
|
<EmojiCategory
|
||||||
|
parentWidth={parentWidth}
|
||||||
|
emojis={emojis}
|
||||||
|
onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)}
|
||||||
|
tabLabel={label}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
|
@ -58,9 +67,13 @@ const EmojiPicker = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.emojiPickerContainer}>
|
<View style={styles.emojiPickerContainer} onLayout={e => setParentWidth(e.nativeEvent.layout.width)}>
|
||||||
{searching ? (
|
{searching ? (
|
||||||
<EmojiCategory emojis={searchedEmojis} onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)} />
|
<EmojiCategory
|
||||||
|
emojis={searchedEmojis}
|
||||||
|
onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)}
|
||||||
|
parentWidth={parentWidth}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ScrollableTabView
|
<ScrollableTabView
|
||||||
renderTabBar={() => <TabBar />}
|
renderTabBar={() => <TabBar />}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { Camera, CameraType } from 'expo-camera';
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
import Touchable from 'react-native-platform-touchable';
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
@ -8,6 +7,7 @@ import { getSubscriptionByRoomId } from '../../../../lib/database/services/Subsc
|
||||||
import { useAppSelector } from '../../../../lib/hooks';
|
import { useAppSelector } from '../../../../lib/hooks';
|
||||||
import { getRoomAvatar, getUidDirectMessage } from '../../../../lib/methods/helpers';
|
import { getRoomAvatar, getUidDirectMessage } from '../../../../lib/methods/helpers';
|
||||||
import { useTheme } from '../../../../theme';
|
import { useTheme } from '../../../../theme';
|
||||||
|
import { useActionSheet } from '../../../ActionSheet';
|
||||||
import AvatarContainer from '../../../Avatar';
|
import AvatarContainer from '../../../Avatar';
|
||||||
import Button from '../../../Button';
|
import Button from '../../../Button';
|
||||||
import { CustomIcon } from '../../../CustomIcon';
|
import { CustomIcon } from '../../../CustomIcon';
|
||||||
|
@ -15,20 +15,16 @@ import { BUTTON_HIT_SLOP } from '../../../message/utils';
|
||||||
import StatusContainer from '../../../Status';
|
import StatusContainer from '../../../Status';
|
||||||
import useStyle from './styles';
|
import useStyle from './styles';
|
||||||
|
|
||||||
const CAM_SIZE = { height: 220, width: 148 };
|
|
||||||
// fixed colors, do not change with theme change.
|
|
||||||
const gray300 = '#5f656e';
|
|
||||||
const gray100 = '#CBCED1';
|
|
||||||
|
|
||||||
export default function StartACallActionSheet({ rid, initCall }: { rid: string; initCall: Function }): React.ReactElement {
|
export default function StartACallActionSheet({ rid, initCall }: { rid: string; initCall: Function }): React.ReactElement {
|
||||||
const style = useStyle();
|
const style = useStyle();
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const [user, setUser] = useState({ username: '', avatar: '', uid: '' });
|
const [user, setUser] = useState({ username: '', avatar: '', uid: '' });
|
||||||
const [mic, setMic] = useState(true);
|
const [mic, setMic] = useState(true);
|
||||||
const [cam, setCam] = useState(false);
|
const [cam, setCam] = useState(false);
|
||||||
const [calling, setCalling] = useState(true);
|
|
||||||
const username = useAppSelector(state => state.login.user.username);
|
const username = useAppSelector(state => state.login.user.username);
|
||||||
|
|
||||||
|
const { hideActionSheet } = useActionSheet();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const room = await getSubscriptionByRoomId(rid);
|
const room = await getSubscriptionByRoomId(rid);
|
||||||
|
@ -38,37 +34,26 @@ export default function StartACallActionSheet({ rid, initCall }: { rid: string;
|
||||||
})();
|
})();
|
||||||
}, [rid]);
|
}, [rid]);
|
||||||
|
|
||||||
const handleColors = (enabled: boolean) => {
|
const handleColor = (enabled: boolean) => (enabled ? colors.conferenceCallEnabledIcon : colors.conferenceCallDisabledIcon);
|
||||||
if (calling) {
|
|
||||||
if (enabled) {
|
|
||||||
return { button: colors.conferenceCallCallBackButton, icon: gray300 };
|
|
||||||
}
|
|
||||||
return { button: 'transparent', icon: gray100 };
|
|
||||||
}
|
|
||||||
if (enabled) {
|
|
||||||
return { button: colors.conferenceCallEnabledIconBackground, icon: colors.conferenceCallEnabledIcon };
|
|
||||||
}
|
|
||||||
return { button: 'transparent', icon: colors.conferenceCallDisabledIcon };
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={style.actionSheetContainer}>
|
<View style={style.actionSheetContainer}>
|
||||||
<View style={style.actionSheetHeader}>
|
<View style={style.actionSheetHeader}>
|
||||||
<Text style={style.actionSheetHeaderTitle}>{calling ? i18n.t('Calling') : i18n.t('Start_a_call')}</Text>
|
<Text style={style.actionSheetHeaderTitle}>{i18n.t('Start_a_call')}</Text>
|
||||||
<View style={style.actionSheetHeaderButtons}>
|
<View style={style.actionSheetHeaderButtons}>
|
||||||
<Touchable
|
<Touchable
|
||||||
onPress={() => setCam(!cam)}
|
onPress={() => setCam(!cam)}
|
||||||
style={[style.iconCallContainer, { backgroundColor: handleColors(cam).button }, { marginRight: 6 }]}
|
style={[style.iconCallContainer, cam && style.enabledBackground, { marginRight: 6 }]}
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
>
|
>
|
||||||
<CustomIcon name={cam ? 'camera' : 'camera-disabled'} size={20} color={handleColors(cam).icon} />
|
<CustomIcon name={cam ? 'camera' : 'camera-disabled'} size={20} color={handleColor(cam)} />
|
||||||
</Touchable>
|
</Touchable>
|
||||||
<Touchable
|
<Touchable
|
||||||
onPress={() => setMic(!mic)}
|
onPress={() => setMic(!mic)}
|
||||||
style={[style.iconCallContainer, { backgroundColor: handleColors(mic).button }]}
|
style={[style.iconCallContainer, mic && style.enabledBackground]}
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
>
|
>
|
||||||
<CustomIcon name={mic ? 'microphone' : 'microphone-disabled'} size={20} color={handleColors(mic).icon} />
|
<CustomIcon name={mic ? 'microphone' : 'microphone-disabled'} size={20} color={handleColor(mic)} />
|
||||||
</Touchable>
|
</Touchable>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
@ -79,27 +64,17 @@ export default function StartACallActionSheet({ rid, initCall }: { rid: string;
|
||||||
{user.username}
|
{user.username}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View
|
<View style={style.actionSheetPhotoContainer}>
|
||||||
style={[
|
<AvatarContainer size={62} text={username} />
|
||||||
style.actionSheetPhotoContainer,
|
|
||||||
CAM_SIZE,
|
|
||||||
{ backgroundColor: cam ? undefined : colors.conferenceCallPhotoBackground }
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
{cam ? <Camera style={CAM_SIZE} type={CameraType.front} /> : <AvatarContainer size={62} text={username} />}
|
|
||||||
</View>
|
</View>
|
||||||
<Button
|
<Button
|
||||||
backgroundColor={calling ? colors.conferenceCallCallBackButton : colors.actionTintColor}
|
|
||||||
color={calling ? gray300 : colors.conferenceCallEnabledIcon}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
if (!calling) {
|
hideActionSheet();
|
||||||
setCalling(true);
|
setTimeout(() => {
|
||||||
initCall({ cam, mic });
|
initCall({ cam, mic });
|
||||||
} else {
|
}, 100);
|
||||||
setCalling(false);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
title={calling ? i18n.t('Cancel') : i18n.t('Call')}
|
title={i18n.t('Call')}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
|
@ -116,12 +116,12 @@ export default function useStyle() {
|
||||||
actionSheetPhotoContainer: {
|
actionSheetPhotoContainer: {
|
||||||
height: 220,
|
height: 220,
|
||||||
width: 148,
|
width: 148,
|
||||||
|
backgroundColor: colors.conferenceCallPhotoBackground,
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
margin: 24,
|
margin: 24,
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center'
|
||||||
overflow: 'hidden'
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ const Content = React.memo(
|
||||||
content = (
|
content = (
|
||||||
<Markdown
|
<Markdown
|
||||||
msg={props.msg}
|
msg={props.msg}
|
||||||
md={props.md}
|
md={props.type !== 'e2e' ? props.md : undefined}
|
||||||
getCustomEmoji={props.getCustomEmoji}
|
getCustomEmoji={props.getCustomEmoji}
|
||||||
enableMessageParser={user.enableMessageParserEarlyAdoption}
|
enableMessageParser={user.enableMessageParserEarlyAdoption}
|
||||||
username={user.username}
|
username={user.username}
|
||||||
|
|
|
@ -18,7 +18,7 @@ const MessageAvatar = React.memo(({ isHeader, avatar, author, small, navToRoomIn
|
||||||
style={small ? styles.avatarSmall : styles.avatar}
|
style={small ? styles.avatarSmall : styles.avatar}
|
||||||
text={avatar ? '' : author.username}
|
text={avatar ? '' : author.username}
|
||||||
size={small ? 20 : 36}
|
size={small ? 20 : 36}
|
||||||
borderRadius={small ? 2 : 4}
|
borderRadius={4}
|
||||||
onPress={author._id === user.id ? undefined : () => navToRoomInfo(navParam)}
|
onPress={author._id === user.id ? undefined : () => navToRoomInfo(navParam)}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji}
|
||||||
avatar={avatar}
|
avatar={avatar}
|
||||||
|
|
|
@ -247,6 +247,8 @@ const Reply = React.memo(
|
||||||
>
|
>
|
||||||
<View style={styles.attachmentContainer}>
|
<View style={styles.attachmentContainer}>
|
||||||
<Title attachment={attachment} timeFormat={timeFormat} theme={theme} />
|
<Title attachment={attachment} timeFormat={timeFormat} theme={theme} />
|
||||||
|
<Description attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
||||||
|
<UrlImage image={attachment.thumb_url} />
|
||||||
<Attachments
|
<Attachments
|
||||||
attachments={attachment.attachments}
|
attachments={attachment.attachments}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji}
|
||||||
|
@ -255,8 +257,6 @@ const Reply = React.memo(
|
||||||
isReply
|
isReply
|
||||||
id={messageId}
|
id={messageId}
|
||||||
/>
|
/>
|
||||||
<UrlImage image={attachment.thumb_url} />
|
|
||||||
<Description attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
|
||||||
<Fields attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
<Fields attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<View style={[styles.backdrop]}>
|
<View style={[styles.backdrop]}>
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import database from '..';
|
import database from '..';
|
||||||
import { TSubscriptionModel } from '../../../definitions';
|
|
||||||
import { TAppDatabase } from '../interfaces';
|
import { TAppDatabase } from '../interfaces';
|
||||||
import { SUBSCRIPTIONS_TABLE } from '../model/Subscription';
|
import { SUBSCRIPTIONS_TABLE } from '../model/Subscription';
|
||||||
|
|
||||||
const getCollection = (db: TAppDatabase) => db.get(SUBSCRIPTIONS_TABLE);
|
const getCollection = (db: TAppDatabase) => db.get(SUBSCRIPTIONS_TABLE);
|
||||||
|
|
||||||
export const getSubscriptionByRoomId = async (rid: string): Promise<TSubscriptionModel | null> => {
|
export const getSubscriptionByRoomId = async (rid: string) => {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const subCollection = getCollection(db);
|
const subCollection = getCollection(db);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
import { TypedUseSelectorHook, useSelector } from 'react-redux';
|
import { TypedUseSelectorHook, useSelector } from 'react-redux';
|
||||||
import { select } from 'redux-saga/effects';
|
|
||||||
|
|
||||||
import { IApplicationState } from '../../definitions';
|
import { IApplicationState } from '../../definitions';
|
||||||
|
|
||||||
export const useAppSelector: TypedUseSelectorHook<IApplicationState> = useSelector;
|
export const useAppSelector: TypedUseSelectorHook<IApplicationState> = useSelector;
|
||||||
|
|
||||||
export function* appSelector<TSelected>(selector: (state: IApplicationState) => TSelected): Generator<any, TSelected, TSelected> {
|
|
||||||
return yield select(selector);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useWindowDimensions } from 'react-native';
|
import { useDimensions } from '@react-native-community/hooks';
|
||||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
|
|
||||||
// Not sure if it's worth adding this here in the context of the actionSheet
|
// Not sure if it's worth adding this here in the context of the actionSheet
|
||||||
|
@ -8,7 +8,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
*/
|
*/
|
||||||
export const useSnaps = (snaps: number[]): string[] => {
|
export const useSnaps = (snaps: number[]): string[] => {
|
||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
const { height, scale } = useWindowDimensions();
|
const { screen } = useDimensions();
|
||||||
const percentage = insets.bottom + insets.top > 75 ? 110 : 100;
|
const percentage = insets.bottom + insets.top > 75 ? 110 : 100;
|
||||||
return snaps.map(snap => `${((percentage * snap) / (height * scale)).toFixed(2)}%`);
|
return snaps.map(snap => `${((percentage * snap) / (screen.height * screen.scale)).toFixed(2)}%`);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { Q } from '@nozbe/watermelondb';
|
|
||||||
import { Camera } from 'expo-camera';
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { Q } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
import { useActionSheet } from '../../containers/ActionSheet';
|
import { useActionSheet } from '../../containers/ActionSheet';
|
||||||
import StartACallActionSheet from '../../containers/UIKit/VideoConferenceBlock/components/StartACallActionSheet';
|
import StartACallActionSheet from '../../containers/UIKit/VideoConferenceBlock/components/StartACallActionSheet';
|
||||||
|
@ -11,7 +10,7 @@ import database from '../database';
|
||||||
import { getSubscriptionByRoomId } from '../database/services/Subscription';
|
import { getSubscriptionByRoomId } from '../database/services/Subscription';
|
||||||
import { callJitsi } from '../methods';
|
import { callJitsi } from '../methods';
|
||||||
import { compareServerVersion, showErrorAlert } from '../methods/helpers';
|
import { compareServerVersion, showErrorAlert } from '../methods/helpers';
|
||||||
import { handleAndroidBltPermission, videoConfStartAndJoin } from '../methods/videoConf';
|
import { videoConfStartAndJoin } from '../methods/videoConf';
|
||||||
import { Services } from '../services';
|
import { Services } from '../services';
|
||||||
import { useAppSelector } from './useAppSelector';
|
import { useAppSelector } from './useAppSelector';
|
||||||
import { useSnaps } from './useSnaps';
|
import { useSnaps } from './useSnaps';
|
||||||
|
@ -36,8 +35,6 @@ export const useVideoConf = (rid: string): { showInitCallActionSheet: () => Prom
|
||||||
const jitsiEnableChannels = useAppSelector(state => state.settings.Jitsi_Enable_Channels);
|
const jitsiEnableChannels = useAppSelector(state => state.settings.Jitsi_Enable_Channels);
|
||||||
const user = useAppSelector(state => getUserSelector(state));
|
const user = useAppSelector(state => getUserSelector(state));
|
||||||
|
|
||||||
const [permission, requestPermission] = Camera.useCameraPermissions();
|
|
||||||
|
|
||||||
const isServer5OrNewer = compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '5.0.0');
|
const isServer5OrNewer = compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '5.0.0');
|
||||||
|
|
||||||
const { showActionSheet } = useActionSheet();
|
const { showActionSheet } = useActionSheet();
|
||||||
|
@ -90,10 +87,6 @@ export const useVideoConf = (rid: string): { showInitCallActionSheet: () => Prom
|
||||||
children: <StartACallActionSheet rid={rid} initCall={initCall} />,
|
children: <StartACallActionSheet rid={rid} initCall={initCall} />,
|
||||||
snaps
|
snaps
|
||||||
});
|
});
|
||||||
if (!permission?.granted) {
|
|
||||||
requestPermission();
|
|
||||||
handleAndroidBltPermission();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ import { E2E_MESSAGE_TYPE } from '../../constants';
|
||||||
import { getRoom } from '../getRoom';
|
import { getRoom } from '../getRoom';
|
||||||
import { merge } from '../helpers/mergeSubscriptionsRooms';
|
import { merge } from '../helpers/mergeSubscriptionsRooms';
|
||||||
import { getRoomAvatar, getRoomTitle, getSenderName, random } from '../helpers';
|
import { getRoomAvatar, getRoomTitle, getSenderName, random } from '../helpers';
|
||||||
import { handleVideoConfIncomingWebsocketMessages } from '../../../actions/videoConf';
|
|
||||||
|
|
||||||
const removeListener = (listener: { stop: () => void }) => listener.stop();
|
const removeListener = (listener: { stop: () => void }) => listener.stop();
|
||||||
|
|
||||||
|
@ -403,11 +402,6 @@ export default function subscribeRooms() {
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (/video-conference/.test(ev)) {
|
|
||||||
const [action, params] = ddpMessage.fields.args;
|
|
||||||
store.dispatch(handleVideoConfIncomingWebsocketMessages({ action, params }));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const stop = () => {
|
const stop = () => {
|
||||||
|
|
|
@ -19,17 +19,18 @@ const handleBltPermission = async (): Promise<Permission[]> => {
|
||||||
return [PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION];
|
return [PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleAndroidBltPermission = async (): Promise<void> => {
|
|
||||||
if (isAndroid) {
|
|
||||||
const bltPermission = await handleBltPermission();
|
|
||||||
await PermissionsAndroid.requestMultiple(bltPermission);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const videoConfJoin = async (callId: string, cam?: boolean, mic?: boolean): Promise<void> => {
|
export const videoConfJoin = async (callId: string, cam?: boolean, mic?: boolean): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const result = await Services.videoConferenceJoin(callId, cam, mic);
|
const result = await Services.videoConferenceJoin(callId, cam, mic);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
|
if (isAndroid) {
|
||||||
|
const bltPermission = await handleBltPermission();
|
||||||
|
await PermissionsAndroid.requestMultiple([
|
||||||
|
PermissionsAndroid.PERMISSIONS.CAMERA,
|
||||||
|
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
|
||||||
|
...bltPermission
|
||||||
|
]);
|
||||||
|
}
|
||||||
const { url, providerName } = result;
|
const { url, providerName } = result;
|
||||||
if (providerName === 'jitsi') {
|
if (providerName === 'jitsi') {
|
||||||
navigation.navigate('JitsiMeetView', { url, onlyAudio: !cam, videoConf: true });
|
navigation.navigate('JitsiMeetView', { url, onlyAudio: !cam, videoConf: true });
|
||||||
|
|
|
@ -21,7 +21,6 @@ import enterpriseModules from './enterpriseModules';
|
||||||
import encryption from './encryption';
|
import encryption from './encryption';
|
||||||
import permissions from './permissions';
|
import permissions from './permissions';
|
||||||
import roles from './roles';
|
import roles from './roles';
|
||||||
import videoConf from './videoConf';
|
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
settings,
|
settings,
|
||||||
|
@ -44,6 +43,5 @@ export default combineReducers({
|
||||||
enterpriseModules,
|
enterpriseModules,
|
||||||
encryption,
|
encryption,
|
||||||
permissions,
|
permissions,
|
||||||
roles,
|
roles
|
||||||
videoConf
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
import { clearVideoConfCalls, removeVideoConfCall, setVideoConfCall } from '../actions/videoConf';
|
|
||||||
import { mockedStore } from './mockedStore';
|
|
||||||
import { initialState, ICallInfo } from './videoConf';
|
|
||||||
|
|
||||||
describe('test videoConf reducer', () => {
|
|
||||||
it('should return initial state', () => {
|
|
||||||
const state = mockedStore.getState().settings;
|
|
||||||
expect(state).toEqual(initialState);
|
|
||||||
});
|
|
||||||
|
|
||||||
const call1: ICallInfo = {
|
|
||||||
callId: '123',
|
|
||||||
rid: '123',
|
|
||||||
type: 'accepted',
|
|
||||||
uid: '123'
|
|
||||||
};
|
|
||||||
|
|
||||||
const call2: ICallInfo = {
|
|
||||||
callId: '321',
|
|
||||||
rid: '321',
|
|
||||||
type: 'accepted',
|
|
||||||
uid: '321'
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should return call1 after call addSettings action with call1 as parameter', () => {
|
|
||||||
mockedStore.dispatch(setVideoConfCall(call1));
|
|
||||||
const state = mockedStore.getState().videoConf;
|
|
||||||
expect(state[call1.callId]).toEqual(call1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return call2 after call addSettings action with call2 as parameter', () => {
|
|
||||||
mockedStore.dispatch(setVideoConfCall(call2));
|
|
||||||
const state = mockedStore.getState().videoConf;
|
|
||||||
expect(state[call2.callId]).toEqual(call2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove call1 after call removeVideoConfCall action with call1 as parameter', () => {
|
|
||||||
mockedStore.dispatch(removeVideoConfCall(call1));
|
|
||||||
const state = mockedStore.getState().videoConf;
|
|
||||||
expect(state[call1.callId]).toEqual(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return initial state after clearSettings', () => {
|
|
||||||
mockedStore.dispatch(clearVideoConfCalls());
|
|
||||||
const state = mockedStore.getState().videoConf;
|
|
||||||
expect(state).toEqual({});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,33 +0,0 @@
|
||||||
import { VIDEO_CONF } from '../actions/actionsTypes';
|
|
||||||
import { TActionVideoConf } from '../actions/videoConf';
|
|
||||||
|
|
||||||
export type TSupportedCallStatus = 'call' | 'canceled' | 'accepted' | 'rejected' | 'confirmed' | 'join' | 'end';
|
|
||||||
|
|
||||||
export interface ICallInfo {
|
|
||||||
callId: string;
|
|
||||||
rid: string;
|
|
||||||
uid: string;
|
|
||||||
type: TSupportedCallStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ICallInfoRecord {
|
|
||||||
[key: string]: ICallInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const initialState: ICallInfoRecord = {};
|
|
||||||
|
|
||||||
export default (state = initialState, action: TActionVideoConf): ICallInfoRecord => {
|
|
||||||
switch (action.type) {
|
|
||||||
case VIDEO_CONF.SET:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
[action.payload.callId]: action.payload
|
|
||||||
};
|
|
||||||
case VIDEO_CONF.REMOVE:
|
|
||||||
return Object.fromEntries(Object.entries(state).filter(([key]) => key !== action.payload.callId));
|
|
||||||
case VIDEO_CONF.CLEAR:
|
|
||||||
return initialState;
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -13,7 +13,6 @@ import deepLinking from './deepLinking';
|
||||||
import inviteLinks from './inviteLinks';
|
import inviteLinks from './inviteLinks';
|
||||||
import createDiscussion from './createDiscussion';
|
import createDiscussion from './createDiscussion';
|
||||||
import encryption from './encryption';
|
import encryption from './encryption';
|
||||||
import videoConf from './videoConf';
|
|
||||||
|
|
||||||
const root = function* root() {
|
const root = function* root() {
|
||||||
yield all([
|
yield all([
|
||||||
|
@ -29,8 +28,7 @@ const root = function* root() {
|
||||||
inviteLinks(),
|
inviteLinks(),
|
||||||
createDiscussion(),
|
createDiscussion(),
|
||||||
inquiry(),
|
inquiry(),
|
||||||
encryption(),
|
encryption()
|
||||||
videoConf()
|
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,120 +0,0 @@
|
||||||
import { Action } from 'redux';
|
|
||||||
import { call, takeLatest } from 'typed-redux-saga';
|
|
||||||
|
|
||||||
import { VIDEO_CONF } from '../actions/actionsTypes';
|
|
||||||
import { IVideoConfGenericAction, TCallProps } from '../actions/videoConf';
|
|
||||||
import i18n from '../i18n';
|
|
||||||
import { getSubscriptionByRoomId } from '../lib/database/services/Subscription';
|
|
||||||
import { appSelector } from '../lib/hooks';
|
|
||||||
import { callJitsi } from '../lib/methods';
|
|
||||||
import { compareServerVersion, showErrorAlert } from '../lib/methods/helpers';
|
|
||||||
import log from '../lib/methods/helpers/log';
|
|
||||||
import { videoConfJoin } from '../lib/methods/videoConf';
|
|
||||||
import { Services } from '../lib/services';
|
|
||||||
import { ICallInfo } from '../reducers/videoConf';
|
|
||||||
|
|
||||||
type TGenerator = Generator<IVideoConfGenericAction>;
|
|
||||||
|
|
||||||
function* onDirectCall(payload: ICallInfo): TGenerator {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* onDirectCallCanceled(payload: ICallInfo): TGenerator {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* onDirectCallAccepted(payload: ICallInfo): TGenerator {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* onDirectCallRejected(payload: ICallInfo): TGenerator {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* onDirectCallConfirmed(payload: ICallInfo): TGenerator {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* onDirectCallJoined(payload: ICallInfo): TGenerator {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* onDirectCallEnded(payload: ICallInfo): TGenerator {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* handleVideoConfIncomingWebsocketMessages({ data }: { data: any }) {
|
|
||||||
const { action, params } = data.action;
|
|
||||||
|
|
||||||
if (!action || typeof action !== 'string') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!params || typeof params !== 'object' || !params.callId || !params.uid || !params.rid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const prop = { ...params, action };
|
|
||||||
switch (action) {
|
|
||||||
case 'call':
|
|
||||||
yield call(onDirectCall, prop);
|
|
||||||
break;
|
|
||||||
case 'canceled':
|
|
||||||
yield call(onDirectCallCanceled, prop);
|
|
||||||
break;
|
|
||||||
case 'accepted':
|
|
||||||
yield call(onDirectCallAccepted, prop);
|
|
||||||
break;
|
|
||||||
case 'rejected':
|
|
||||||
yield call(onDirectCallRejected, prop);
|
|
||||||
break;
|
|
||||||
case 'confirmed':
|
|
||||||
yield call(onDirectCallConfirmed, prop);
|
|
||||||
break;
|
|
||||||
case 'join':
|
|
||||||
yield call(onDirectCallJoined, prop);
|
|
||||||
break;
|
|
||||||
case 'end':
|
|
||||||
yield call(onDirectCallEnded, prop);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function* initCall({ payload: { mic, cam, direct, roomId } }: { payload: TCallProps }) {
|
|
||||||
const serverVersion = yield* appSelector(state => state.server.version);
|
|
||||||
const isServer5OrNewer = compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '5.0.0');
|
|
||||||
if (isServer5OrNewer) {
|
|
||||||
try {
|
|
||||||
const videoConfResponse = yield* call(Services.videoConferenceStart, roomId);
|
|
||||||
if (videoConfResponse.success) {
|
|
||||||
if (direct) {
|
|
||||||
// callUser({ uid: data.calleeId, rid: roomId, callId: data.callId });
|
|
||||||
} else {
|
|
||||||
videoConfJoin(videoConfResponse.data.callId, cam, mic);
|
|
||||||
}
|
|
||||||
// setCalling(false);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// setCalling(false);
|
|
||||||
showErrorAlert(i18n.t('error-init-video-conf'));
|
|
||||||
log(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const sub = yield* call(getSubscriptionByRoomId, roomId);
|
|
||||||
if (sub) {
|
|
||||||
callJitsi({ room: sub, cam });
|
|
||||||
// setCalling(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IGenericAction extends Action {
|
|
||||||
type: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function* root(): Generator {
|
|
||||||
yield takeLatest<
|
|
||||||
IGenericAction & {
|
|
||||||
data: any;
|
|
||||||
}
|
|
||||||
>(VIDEO_CONF.HANDLE_INCOMING_WEBSOCKET_MESSAGES, handleVideoConfIncomingWebsocketMessages);
|
|
||||||
yield takeLatest<IGenericAction & { payload: TCallProps }>(VIDEO_CONF.INIT_CALL, initCall);
|
|
||||||
}
|
|
|
@ -47,7 +47,7 @@
|
||||||
"@react-native-community/blur": "^4.1.0",
|
"@react-native-community/blur": "^4.1.0",
|
||||||
"@react-native-community/cameraroll": "4.1.2",
|
"@react-native-community/cameraroll": "4.1.2",
|
||||||
"@react-native-community/datetimepicker": "3.5.2",
|
"@react-native-community/datetimepicker": "3.5.2",
|
||||||
"@react-native-community/hooks": "3.0.0",
|
"@react-native-community/hooks": "2.6.0",
|
||||||
"@react-native-community/netinfo": "6.0.0",
|
"@react-native-community/netinfo": "6.0.0",
|
||||||
"@react-native-community/picker": "^1.8.1",
|
"@react-native-community/picker": "^1.8.1",
|
||||||
"@react-native-community/slider": "4.2.2",
|
"@react-native-community/slider": "4.2.2",
|
||||||
|
@ -73,7 +73,6 @@
|
||||||
"expo": "^46.0.9",
|
"expo": "^46.0.9",
|
||||||
"expo-apple-authentication": "4.2.1",
|
"expo-apple-authentication": "4.2.1",
|
||||||
"expo-av": "11.2.3",
|
"expo-av": "11.2.3",
|
||||||
"expo-camera": "12.5.0",
|
|
||||||
"expo-file-system": "14.0.0",
|
"expo-file-system": "14.0.0",
|
||||||
"expo-haptics": "11.2.0",
|
"expo-haptics": "11.2.0",
|
||||||
"expo-keep-awake": "10.1.1",
|
"expo-keep-awake": "10.1.1",
|
||||||
|
@ -146,7 +145,6 @@
|
||||||
"rn-fetch-blob": "^0.12.0",
|
"rn-fetch-blob": "^0.12.0",
|
||||||
"rn-root-view": "RocketChat/rn-root-view",
|
"rn-root-view": "RocketChat/rn-root-view",
|
||||||
"semver": "^7.3.8",
|
"semver": "^7.3.8",
|
||||||
"typed-redux-saga": "^1.5.0",
|
|
||||||
"ua-parser-js": "^1.0.32",
|
"ua-parser-js": "^1.0.32",
|
||||||
"uri-js": "^4.4.1",
|
"uri-js": "^4.4.1",
|
||||||
"url-parse": "1.5.10",
|
"url-parse": "1.5.10",
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
/* Basic Options */
|
/* Basic Options */
|
||||||
// "incremental": true, /* Enable incremental compilation */
|
// "incremental": true, /* Enable incremental compilation */
|
||||||
"target": "ESNEXT" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
|
"target": "esnext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
|
||||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
||||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||||
"allowJs": true /* Allow javascript files to be compiled. */,
|
"allowJs": true /* Allow javascript files to be compiled. */,
|
||||||
|
|
53
yarn.lock
53
yarn.lock
|
@ -801,13 +801,6 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types" "^7.14.5"
|
"@babel/types" "^7.14.5"
|
||||||
|
|
||||||
"@babel/helper-module-imports@^7.14.5", "@babel/helper-module-imports@^7.18.6":
|
|
||||||
version "7.18.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
|
|
||||||
integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
|
|
||||||
dependencies:
|
|
||||||
"@babel/types" "^7.18.6"
|
|
||||||
|
|
||||||
"@babel/helper-module-imports@^7.16.7":
|
"@babel/helper-module-imports@^7.16.7":
|
||||||
version "7.16.7"
|
version "7.16.7"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
|
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
|
||||||
|
@ -815,6 +808,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types" "^7.16.7"
|
"@babel/types" "^7.16.7"
|
||||||
|
|
||||||
|
"@babel/helper-module-imports@^7.18.6":
|
||||||
|
version "7.18.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
|
||||||
|
integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.18.6"
|
||||||
|
|
||||||
"@babel/helper-module-transforms@^7.10.4":
|
"@babel/helper-module-transforms@^7.10.4":
|
||||||
version "7.10.4"
|
version "7.10.4"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz#ca1f01fdb84e48c24d7506bb818c961f1da8805d"
|
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz#ca1f01fdb84e48c24d7506bb818c961f1da8805d"
|
||||||
|
@ -4831,13 +4831,6 @@
|
||||||
"@jridgewell/resolve-uri" "^3.0.3"
|
"@jridgewell/resolve-uri" "^3.0.3"
|
||||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||||
|
|
||||||
"@koale/useworker@^4.0.2":
|
|
||||||
version "4.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@koale/useworker/-/useworker-4.0.2.tgz#cb540a2581cd6025307c3ca6685bc60748773e58"
|
|
||||||
integrity sha512-xPIPADtom8/3/4FLNj7MvNcBM/Z2FleH85Fdx2O869eoKW8+PoEgtSVvoxWjCWMA46Sm9A5/R1TyzNGc+yM0wg==
|
|
||||||
dependencies:
|
|
||||||
dequal "^1.0.0"
|
|
||||||
|
|
||||||
"@mdx-js/mdx@^1.6.22":
|
"@mdx-js/mdx@^1.6.22":
|
||||||
version "1.6.22"
|
version "1.6.22"
|
||||||
resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba"
|
resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba"
|
||||||
|
@ -5183,10 +5176,10 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
invariant "^2.2.4"
|
invariant "^2.2.4"
|
||||||
|
|
||||||
"@react-native-community/hooks@3.0.0":
|
"@react-native-community/hooks@2.6.0":
|
||||||
version "3.0.0"
|
version "2.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/@react-native-community/hooks/-/hooks-3.0.0.tgz#af5f2ca32eea59b792ce9e3d9a4cf0354f9b195f"
|
resolved "https://registry.yarnpkg.com/@react-native-community/hooks/-/hooks-2.6.0.tgz#dd5f19601eb3684c6bcdd3df3d0c04cf44c24cff"
|
||||||
integrity sha512-g2OyxXHfwIytXUJitBR6Z/ISoOfp0WKx5FOv+NqJ/CrWjRDcTw6zXE5I1C9axfuh30kJqzWchVfCDrkzZYTxqg==
|
integrity sha512-emBGKvhJ0h++lLJQ5ejsj+od9G67nEaihjvfSx7/JWvNrQGAhP9U0OZqgb9dkKzor9Ufaj9SGt8RNY97cGzttw==
|
||||||
|
|
||||||
"@react-native-community/netinfo@6.0.0":
|
"@react-native-community/netinfo@6.0.0":
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
|
@ -7705,7 +7698,7 @@ babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.8.0:
|
||||||
cosmiconfig "^6.0.0"
|
cosmiconfig "^6.0.0"
|
||||||
resolve "^1.12.0"
|
resolve "^1.12.0"
|
||||||
|
|
||||||
babel-plugin-macros@^3.0.1, babel-plugin-macros@^3.1.0:
|
babel-plugin-macros@^3.0.1:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1"
|
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1"
|
||||||
integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==
|
integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==
|
||||||
|
@ -9769,11 +9762,6 @@ deprecated-react-native-prop-types@^2.3.0:
|
||||||
invariant "*"
|
invariant "*"
|
||||||
prop-types "*"
|
prop-types "*"
|
||||||
|
|
||||||
dequal@^1.0.0:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/dequal/-/dequal-1.0.1.tgz#dbbf9795ec626e9da8bd68782f4add1d23700d8b"
|
|
||||||
integrity sha512-Fx8jxibzkJX2aJgyfSdLhr9tlRoTnHKrRJuu2XHlAgKioN2j19/Bcbe0d4mFXYZ3+wpE2KVobUVTfDutcD17xQ==
|
|
||||||
|
|
||||||
dequal@^2.0.2:
|
dequal@^2.0.2:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d"
|
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d"
|
||||||
|
@ -10890,15 +10878,6 @@ expo-av@11.2.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
"@expo/config-plugins" "^4.0.14"
|
"@expo/config-plugins" "^4.0.14"
|
||||||
|
|
||||||
expo-camera@12.5.0:
|
|
||||||
version "12.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-12.5.0.tgz#aac8441ea661ed21becf064e715dd50d5448aaae"
|
|
||||||
integrity sha512-oiQccJ9d2FnGdlLKaRphZ2DpwI9C1yD4HUZDacsAR+8904xv3Mhf6u78mh9yBPs6Z7dbtgSjOFtFu5s29PeTxA==
|
|
||||||
dependencies:
|
|
||||||
"@expo/config-plugins" "~5.0.0"
|
|
||||||
"@koale/useworker" "^4.0.2"
|
|
||||||
invariant "^2.2.4"
|
|
||||||
|
|
||||||
expo-constants@~13.2.2, expo-constants@~13.2.4:
|
expo-constants@~13.2.2, expo-constants@~13.2.4:
|
||||||
version "13.2.4"
|
version "13.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-13.2.4.tgz#eab4a553f074b2c60ad7a158d3b82e3484a94606"
|
resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-13.2.4.tgz#eab4a553f074b2c60ad7a158d3b82e3484a94606"
|
||||||
|
@ -20135,14 +20114,6 @@ type-is@~1.6.17, type-is@~1.6.18:
|
||||||
media-typer "0.3.0"
|
media-typer "0.3.0"
|
||||||
mime-types "~2.1.24"
|
mime-types "~2.1.24"
|
||||||
|
|
||||||
typed-redux-saga@^1.5.0:
|
|
||||||
version "1.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/typed-redux-saga/-/typed-redux-saga-1.5.0.tgz#f70b47c92c6e29e0184d0c30d563c18d6ad0ae54"
|
|
||||||
integrity sha512-XHKliNtRNUegYAAztbVDb5Q+FMqYNQPaed6Xq2N8kz8AOmiOCVxW3uIj7TEptR1/ms6M9u3HEDfJr4qqz/PYrw==
|
|
||||||
optionalDependencies:
|
|
||||||
"@babel/helper-module-imports" "^7.14.5"
|
|
||||||
babel-plugin-macros "^3.1.0"
|
|
||||||
|
|
||||||
typedarray-to-buffer@^3.1.5:
|
typedarray-to-buffer@^3.1.5:
|
||||||
version "3.1.5"
|
version "3.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
||||||
|
|
Loading…
Reference in New Issue