Merge branch 'develop' into fix.share-extension-not-logged-in

This commit is contained in:
Reinaldo Neto 2022-06-13 11:16:38 -03:00
commit 363b89756e
50 changed files with 936 additions and 383 deletions

View File

@ -1,7 +1,3 @@
export default { import mockDeviceInfo from 'react-native-device-info/jest/react-native-device-info-mock';
getModel: () => '',
getReadableVersion: () => '', export default mockDeviceInfo;
getBundleId: () => '',
isTablet: () => false,
hasNotch: () => false
};

View File

@ -46,12 +46,22 @@ import { withActionSheet } from '../ActionSheet';
import { sanitizeLikeString } from '../../lib/database/utils'; import { sanitizeLikeString } from '../../lib/database/utils';
import { CustomIcon } from '../CustomIcon'; import { CustomIcon } from '../CustomIcon';
import { forceJpgExtension } from './forceJpgExtension'; import { forceJpgExtension } from './forceJpgExtension';
import { IBaseScreen, IPreviewItem, IUser, TGetCustomEmoji, TSubscriptionModel, TThreadModel, IMessage } from '../../definitions'; import {
IApplicationState,
IBaseScreen,
IPreviewItem,
IUser,
TGetCustomEmoji,
TSubscriptionModel,
TThreadModel,
IMessage
} from '../../definitions';
import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types'; import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types';
import { getPermalinkMessage, search, sendFileMessage } from '../../lib/methods'; import { getPermalinkMessage, search, sendFileMessage } from '../../lib/methods';
import { hasPermission, debounce, isAndroid, isTablet } from '../../lib/methods/helpers'; import { hasPermission, debounce, isAndroid, isTablet } from '../../lib/methods/helpers';
import { Services } from '../../lib/services'; import { Services } from '../../lib/services';
import { TSupportedThemes } from '../../theme'; import { TSupportedThemes } from '../../theme';
import { ChatsStackParamList } from '../../stacks/types';
if (isAndroid) { if (isAndroid) {
require('./EmojiKeyboard'); require('./EmojiKeyboard');
@ -75,7 +85,7 @@ const videoPickerConfig: Options = {
mediaType: 'video' mediaType: 'video'
}; };
export interface IMessageBoxProps extends IBaseScreen<MasterDetailInsideStackParamList, any> { export interface IMessageBoxProps extends IBaseScreen<ChatsStackParamList & MasterDetailInsideStackParamList, any> {
rid: string; rid: string;
baseUrl: string; baseUrl: string;
message: IMessage; message: IMessage;
@ -107,6 +117,7 @@ export interface IMessageBoxProps extends IBaseScreen<MasterDetailInsideStackPar
usedCannedResponse: string; usedCannedResponse: string;
uploadFilePermission: string[]; uploadFilePermission: string[];
serverVersion: string; serverVersion: string;
goToCannedResponses: () => void | null;
} }
interface IMessageBoxState { interface IMessageBoxState {
@ -305,7 +316,17 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
permissionToUpload permissionToUpload
} = this.state; } = this.state;
const { roomType, replying, editing, isFocused, message, theme, usedCannedResponse, uploadFilePermission } = this.props; const {
roomType,
replying,
editing,
isFocused,
message,
theme,
usedCannedResponse,
uploadFilePermission,
goToCannedResponses
} = this.props;
if (nextProps.theme !== theme) { if (nextProps.theme !== theme) {
return true; return true;
} }
@ -357,12 +378,15 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
if (nextProps.usedCannedResponse !== usedCannedResponse) { if (nextProps.usedCannedResponse !== usedCannedResponse) {
return true; return true;
} }
if (nextProps.goToCannedResponses !== goToCannedResponses) {
return true;
}
return false; return false;
} }
componentDidUpdate(prevProps: IMessageBoxProps) { componentDidUpdate(prevProps: IMessageBoxProps) {
const { uploadFilePermission } = this.props; const { uploadFilePermission, goToCannedResponses } = this.props;
if (!dequal(prevProps.uploadFilePermission, uploadFilePermission)) { if (!dequal(prevProps.uploadFilePermission, uploadFilePermission) || prevProps.goToCannedResponses !== goToCannedResponses) {
this.setOptions(); this.setOptions();
} }
} }
@ -783,9 +807,16 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
showMessageBoxActions = () => { showMessageBoxActions = () => {
logEvent(events.ROOM_SHOW_BOX_ACTIONS); logEvent(events.ROOM_SHOW_BOX_ACTIONS);
const { permissionToUpload } = this.state; const { permissionToUpload } = this.state;
const { showActionSheet } = this.props; const { showActionSheet, goToCannedResponses } = this.props;
const options = []; const options = [];
if (goToCannedResponses) {
options.push({
title: I18n.t('Canned_Responses'),
icon: 'canned-response',
onPress: () => goToCannedResponses()
});
}
if (permissionToUpload) { if (permissionToUpload) {
options.push( options.push(
{ {
@ -1170,7 +1201,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
} }
} }
const mapStateToProps = (state: any) => ({ const mapStateToProps = (state: IApplicationState) => ({
isMasterDetail: state.app.isMasterDetail, isMasterDetail: state.app.isMasterDetail,
baseUrl: state.server.server, baseUrl: state.server.server,
threadsEnabled: state.settings.Threads_enabled, threadsEnabled: state.settings.Threads_enabled,

View File

@ -52,7 +52,8 @@ const RoomItem = ({
autoJoin, autoJoin,
showAvatar, showAvatar,
displayMode, displayMode,
sourceType sourceType,
hideMentionStatus
}: IRoomItemProps) => ( }: IRoomItemProps) => (
<Touchable <Touchable
onPress={onPress} onPress={onPress}
@ -117,6 +118,8 @@ const RoomItem = ({
tunread={tunread} tunread={tunread}
tunreadUser={tunreadUser} tunreadUser={tunreadUser}
tunreadGroup={tunreadGroup} tunreadGroup={tunreadGroup}
hideMentionStatus={hideMentionStatus}
hideUnreadStatus={hideUnreadStatus}
/> />
</View> </View>
</> </>
@ -143,6 +146,8 @@ const RoomItem = ({
tunread={tunread} tunread={tunread}
tunreadUser={tunreadUser} tunreadUser={tunreadUser}
tunreadGroup={tunreadGroup} tunreadGroup={tunreadGroup}
hideMentionStatus={hideMentionStatus}
hideUnreadStatus={hideUnreadStatus}
/> />
</View> </View>
</View> </View>

View File

@ -167,6 +167,7 @@ class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
prid={item.prid} prid={item.prid}
status={status} status={status}
hideUnreadStatus={item.hideUnreadStatus} hideUnreadStatus={item.hideUnreadStatus}
hideMentionStatus={item.hideMentionStatus}
alert={alert} alert={alert}
lastMessage={item.lastMessage} lastMessage={item.lastMessage}
showLastMessage={showLastMessage} showLastMessage={showLastMessage}

View File

@ -132,6 +132,7 @@ export interface IRoomItemProps {
showAvatar: boolean; showAvatar: boolean;
displayMode: string; displayMode: string;
sourceType: IOmnichannelSource; sourceType: IOmnichannelSource;
hideMentionStatus?: boolean;
} }
export interface ILastMessageProps { export interface ILastMessageProps {

View File

@ -38,16 +38,38 @@ export interface IUnreadBadge {
tunreadUser?: []; tunreadUser?: [];
tunreadGroup?: []; tunreadGroup?: [];
small?: boolean; small?: boolean;
hideUnreadStatus?: boolean;
hideMentionStatus?: boolean;
} }
const UnreadBadge = React.memo( const UnreadBadge = React.memo(
({ unread, userMentions, groupMentions, style, tunread, tunreadUser, tunreadGroup, small }: IUnreadBadge) => { ({
unread,
userMentions,
groupMentions,
style,
tunread,
tunreadUser,
tunreadGroup,
small,
hideMentionStatus,
hideUnreadStatus
}: IUnreadBadge) => {
const { theme } = useTheme(); const { theme } = useTheme();
if ((!unread || unread <= 0) && !tunread?.length) { if ((!unread || unread <= 0) && !tunread?.length) {
return null; return null;
} }
if (hideUnreadStatus && hideMentionStatus) {
return null;
}
// Return null when hideUnreadStatus is true and isn't a direct mention
if (hideUnreadStatus && !((userMentions && userMentions > 0) || tunreadUser?.length)) {
return null;
}
const { backgroundColor, color } = getUnreadStyle({ const { backgroundColor, color } = getUnreadStyle({
theme, theme,
unread, unread,

View File

@ -1,10 +1,16 @@
import React from 'react'; import React from 'react';
import { StyleProp, Text, TextStyle } from 'react-native'; import { StyleProp, Text, TextStyle } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
import { themes } from '../../lib/constants'; import { themes } from '../../lib/constants';
import { useTheme } from '../../theme'; import { useTheme } from '../../theme';
import { IUserChannel } from './interfaces'; import { IUserChannel } from './interfaces';
import styles from './styles'; import styles from './styles';
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
import { ChatsStackParamList } from '../../stacks/types';
import { useAppSelector } from '../../lib/hooks';
import { goRoom } from '../../lib/methods/helpers/goRoom';
interface IHashtag { interface IHashtag {
hashtag: string; hashtag: string;
@ -15,15 +21,22 @@ interface IHashtag {
const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IHashtag) => { const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IHashtag) => {
const { theme } = useTheme(); const { theme } = useTheme();
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
const navigation = useNavigation<StackNavigationProp<ChatsStackParamList, 'RoomView'>>();
const handlePress = () => { const handlePress = async () => {
const index = channels?.findIndex(channel => channel.name === hashtag); const index = channels?.findIndex(channel => channel.name === hashtag);
if (typeof index !== 'undefined' && navToRoomInfo) { if (typeof index !== 'undefined' && navToRoomInfo) {
const navParam = { const navParam = {
t: 'c', t: 'c',
rid: channels?.[index]._id rid: channels?.[index]._id
}; };
navToRoomInfo(navParam); const room = navParam.rid && (await getSubscriptionByRoomId(navParam.rid));
if (room) {
goRoom({ item: room, isMasterDetail, navigationMethod: isMasterDetail ? navigation.replace : navigation.push });
} else {
navToRoomInfo(navParam);
}
} }
}; };

View File

@ -198,7 +198,7 @@ export interface IServerRoom extends IRocketChatRecord {
unread?: number; unread?: number;
alert?: boolean; alert?: boolean;
hideUnreadStatus?: boolean; hideUnreadStatus?: boolean;
status?: string;
sysMes?: string[]; sysMes?: string[];
muted?: string[]; muted?: string[];
unmuted?: string[]; unmuted?: string[];

View File

@ -100,6 +100,7 @@ export interface ISubscription {
separator?: boolean; separator?: boolean;
onHold?: boolean; onHold?: boolean;
source?: IOmnichannelSource; source?: IOmnichannelSource;
hideMentionStatus?: boolean;
// https://nozbe.github.io/WatermelonDB/Relation.html#relation-api // https://nozbe.github.io/WatermelonDB/Relation.html#relation-api
messages: RelationModified<TMessageModel>; messages: RelationModified<TMessageModel>;
threads: RelationModified<TThreadModel>; threads: RelationModified<TThreadModel>;

View File

@ -421,7 +421,6 @@
"Reset_password": "إعادة تعيين كلمة المرور", "Reset_password": "إعادة تعيين كلمة المرور",
"resetting_password": "إعادة تعيين كلمة المرور", "resetting_password": "إعادة تعيين كلمة المرور",
"RESET": "إعادة", "RESET": "إعادة",
"Return": "العودة",
"Review_app_title": "هل أنت مستمتع بهذا التطبيق؟", "Review_app_title": "هل أنت مستمتع بهذا التطبيق؟",
"Review_app_desc": "قم بإعطائنا 5 نجوم {{store}}", "Review_app_desc": "قم بإعطائنا 5 نجوم {{store}}",
"Review_app_yes": "أكيد!", "Review_app_yes": "أكيد!",
@ -490,8 +489,6 @@
"Share_Link": "مشاركة رابط", "Share_Link": "مشاركة رابط",
"Share_this_app": "مشاركة هذا البرنامج", "Share_this_app": "مشاركة هذا البرنامج",
"Show_more": "إظهار أكثر..", "Show_more": "إظهار أكثر..",
"Show_Unread_Counter": "عرض عدد الرسائل غير المقروءة",
"Show_Unread_Counter_Info": "يتم عرض العدد غير المقروء كشارة على يمين القناة في القائمة",
"Sign_in_your_server": "تسجيل الدخول إلى الخادم الخاص بك", "Sign_in_your_server": "تسجيل الدخول إلى الخادم الخاص بك",
"Sign_Up": "تسجيل جديد", "Sign_Up": "تسجيل جديد",
"Some_field_is_invalid_or_empty": "بعض الحقول غير صالحة أو فارغة", "Some_field_is_invalid_or_empty": "بعض الحقول غير صالحة أو فارغة",

View File

@ -427,7 +427,6 @@
"Reset_password": "Passwort zurücksetzen", "Reset_password": "Passwort zurücksetzen",
"resetting_password": "Passwort zurücksetzen", "resetting_password": "Passwort zurücksetzen",
"RESET": "ZURÜCKSETZEN", "RESET": "ZURÜCKSETZEN",
"Return": "Zurück",
"Review_app_title": "Gefällt Ihnen diese App?", "Review_app_title": "Gefällt Ihnen diese App?",
"Review_app_desc": "Geben Sie uns 5 Sterne im {{store}}", "Review_app_desc": "Geben Sie uns 5 Sterne im {{store}}",
"Review_app_yes": "Sicher!", "Review_app_yes": "Sicher!",
@ -496,8 +495,6 @@
"Share_Link": "Link teilen", "Share_Link": "Link teilen",
"Share_this_app": "App teilen", "Share_this_app": "App teilen",
"Show_more": "Mehr anzeigen …", "Show_more": "Mehr anzeigen …",
"Show_Unread_Counter": "Zähler anzeigen",
"Show_Unread_Counter_Info": "Anzahl der ungelesenen Nachrichten anzeigen",
"Sign_in_your_server": "Melden Sie sich bei Ihrem Server an", "Sign_in_your_server": "Melden Sie sich bei Ihrem Server an",
"Sign_Up": "Anmelden", "Sign_Up": "Anmelden",
"Some_field_is_invalid_or_empty": "Ein Feld ist ungültig oder leer", "Some_field_is_invalid_or_empty": "Ein Feld ist ungültig oder leer",

View File

@ -431,7 +431,7 @@
"Reset_password": "Reset password", "Reset_password": "Reset password",
"resetting_password": "resetting password", "resetting_password": "resetting password",
"RESET": "RESET", "RESET": "RESET",
"Return": "Return", "Return_to_waiting_line": "Return to waiting line",
"Review_app_title": "Are you enjoying this app?", "Review_app_title": "Are you enjoying this app?",
"Review_app_desc": "Give us 5 stars on {{store}}", "Review_app_desc": "Give us 5 stars on {{store}}",
"Review_app_yes": "Sure!", "Review_app_yes": "Sure!",
@ -504,8 +504,6 @@
"Share_Link": "Share Link", "Share_Link": "Share Link",
"Share_this_app": "Share this app", "Share_this_app": "Share this app",
"Show_more": "Show more..", "Show_more": "Show more..",
"Show_Unread_Counter": "Show Unread Counter",
"Show_Unread_Counter_Info": "Unread counter is displayed as a badge on the right of the channel, in the list",
"Sign_in_your_server": "Sign in your server", "Sign_in_your_server": "Sign in your server",
"Sign_Up": "Sign Up", "Sign_Up": "Sign Up",
"Some_field_is_invalid_or_empty": "Some field is invalid or empty", "Some_field_is_invalid_or_empty": "Some field is invalid or empty",
@ -825,5 +823,9 @@
"Omnichannel_placed_chat_on_hold": "Chat On Hold: {{comment}}", "Omnichannel_placed_chat_on_hold": "Chat On Hold: {{comment}}",
"Omnichannel_on_hold_chat_resumed": "On Hold Chat Resumed: {{comment}}", "Omnichannel_on_hold_chat_resumed": "On Hold Chat Resumed: {{comment}}",
"Omnichannel_queue": "Omnichannel queue", "Omnichannel_queue": "Omnichannel queue",
"Empty": "Empty" "Empty": "Empty",
"Mark_as_unread": "Mark as unread",
"Mark_as_unread_Info": "Display room as unread when there are unread messages",
"Show_badge_for_mentions": "Show badge for mentions",
"Show_badge_for_mentions_Info": "Display badge for direct mentions only"
} }

View File

@ -344,8 +344,6 @@
"Settings_succesfully_changed": "¡Configuración cambiada correctamente!", "Settings_succesfully_changed": "¡Configuración cambiada correctamente!",
"Share": "Compartir", "Share": "Compartir",
"Share_this_app": "Compartir esta aplicación", "Share_this_app": "Compartir esta aplicación",
"Show_Unread_Counter": "Mostrar contador de no leídos",
"Show_Unread_Counter_Info": "El contador de no leídos se muestra como una insignia a la derecha del canal, en la lista",
"Sign_in_your_server": "Accede a tu servidor", "Sign_in_your_server": "Accede a tu servidor",
"Sign_Up": "Registrarse", "Sign_Up": "Registrarse",
"Some_field_is_invalid_or_empty": "Algún campo no es correcto o está vacío", "Some_field_is_invalid_or_empty": "Algún campo no es correcto o está vacío",

View File

@ -427,7 +427,6 @@
"Reset_password": "Réinitialiser le mot de passe", "Reset_password": "Réinitialiser le mot de passe",
"resetting_password": "réinitialisation du mot de passe", "resetting_password": "réinitialisation du mot de passe",
"RESET": "RÉINITIALISER", "RESET": "RÉINITIALISER",
"Return": "Retour",
"Review_app_title": "Appréciez-vous cette application ?", "Review_app_title": "Appréciez-vous cette application ?",
"Review_app_desc": "Donnez-nous 5 étoiles sur {{store}}", "Review_app_desc": "Donnez-nous 5 étoiles sur {{store}}",
"Review_app_yes": "Bien sûr !", "Review_app_yes": "Bien sûr !",
@ -496,8 +495,6 @@
"Share_Link": "Partager le lien", "Share_Link": "Partager le lien",
"Share_this_app": "Partager cette application", "Share_this_app": "Partager cette application",
"Show_more": "Afficher plus..", "Show_more": "Afficher plus..",
"Show_Unread_Counter": "Afficher le compteur non lu",
"Show_Unread_Counter_Info": "Le compteur non lu est affiché sous forme de badge à droite du canal, dans la liste",
"Sign_in_your_server": "Connectez-vous à votre serveur", "Sign_in_your_server": "Connectez-vous à votre serveur",
"Sign_Up": "S'inscrire", "Sign_Up": "S'inscrire",
"Some_field_is_invalid_or_empty": "Certains champs sont invalides ou vides", "Some_field_is_invalid_or_empty": "Certains champs sont invalides ou vides",

View File

@ -416,7 +416,6 @@
"Reset_password": "Ripristina password", "Reset_password": "Ripristina password",
"resetting_password": "ripristinando password", "resetting_password": "ripristinando password",
"RESET": "RIPRISTINA", "RESET": "RIPRISTINA",
"Return": "Ritorno",
"Review_app_title": "Ti piace questa app?", "Review_app_title": "Ti piace questa app?",
"Review_app_desc": "Dacci 5 stesse su {{store}}", "Review_app_desc": "Dacci 5 stesse su {{store}}",
"Review_app_yes": "Certo!", "Review_app_yes": "Certo!",
@ -484,8 +483,6 @@
"Share_Link": "Condividi link", "Share_Link": "Condividi link",
"Share_this_app": "Condividi questa app", "Share_this_app": "Condividi questa app",
"Show_more": "Mostra altri..", "Show_more": "Mostra altri..",
"Show_Unread_Counter": "Mostra contatore messaggi non letti",
"Show_Unread_Counter_Info": "Il contatore viene mostrato come un'etichetta alla destra del canale, nella lista",
"Sign_in_your_server": "Accedi al tuo server", "Sign_in_your_server": "Accedi al tuo server",
"Sign_Up": "Registrati", "Sign_Up": "Registrati",
"Some_field_is_invalid_or_empty": "Un campo non è valido o è vuoto", "Some_field_is_invalid_or_empty": "Un campo non è valido o è vuoto",

View File

@ -452,8 +452,6 @@
"Share_Link": "リンクをシェアする", "Share_Link": "リンクをシェアする",
"Share_this_app": "このアプリをシェアする", "Share_this_app": "このアプリをシェアする",
"Show_more": "Show more..", "Show_more": "Show more..",
"Show_Unread_Counter": "未読件数を表示する",
"Show_Unread_Counter_Info": "未読件数はリスト上で、チャンネルの右側にバッジで表示されます。",
"Sign_in_your_server": "サーバーに接続", "Sign_in_your_server": "サーバーに接続",
"Sign_Up": "登録", "Sign_Up": "登録",
"Some_field_is_invalid_or_empty": "不正、または空の入力欄があります。", "Some_field_is_invalid_or_empty": "不正、または空の入力欄があります。",

View File

@ -427,7 +427,6 @@
"Reset_password": "Wachtwoord resetten", "Reset_password": "Wachtwoord resetten",
"resetting_password": "wachtwoord aan het resetten", "resetting_password": "wachtwoord aan het resetten",
"RESET": "RESET", "RESET": "RESET",
"Return": "Terug",
"Review_app_title": "Geniet je van deze app?", "Review_app_title": "Geniet je van deze app?",
"Review_app_desc": "Geef ons 5 sterren op {{store}}", "Review_app_desc": "Geef ons 5 sterren op {{store}}",
"Review_app_yes": "Zeker!", "Review_app_yes": "Zeker!",
@ -496,8 +495,6 @@
"Share_Link": "Deel link", "Share_Link": "Deel link",
"Share_this_app": "Deel deze app", "Share_this_app": "Deel deze app",
"Show_more": "Meer tonen..", "Show_more": "Meer tonen..",
"Show_Unread_Counter": "Toon ongelezen teller",
"Show_Unread_Counter_Info": "Ongelezen teller wordt weergegeven als een badge aan de rechterkant van het kanaal, in de lijst",
"Sign_in_your_server": "Log in op je server", "Sign_in_your_server": "Log in op je server",
"Sign_Up": "Registreren", "Sign_Up": "Registreren",
"Some_field_is_invalid_or_empty": "Sommige velden zijn ongeldig of leeg", "Some_field_is_invalid_or_empty": "Sommige velden zijn ongeldig of leeg",

View File

@ -403,7 +403,6 @@
"Reset_password": "Resetar senha", "Reset_password": "Resetar senha",
"resetting_password": "redefinindo senha", "resetting_password": "redefinindo senha",
"RESET": "RESETAR", "RESET": "RESETAR",
"Return": "Retornar",
"Review_app_title": "Você está gostando do app?", "Review_app_title": "Você está gostando do app?",
"Review_app_desc": "Nos dê 5 estrelas na {{store}}", "Review_app_desc": "Nos dê 5 estrelas na {{store}}",
"Review_app_yes": "Claro!", "Review_app_yes": "Claro!",
@ -464,8 +463,6 @@
"Share": "Compartilhar", "Share": "Compartilhar",
"Share_Link": "Share Link", "Share_Link": "Share Link",
"Show_more": "Mostrar mais..", "Show_more": "Mostrar mais..",
"Show_Unread_Counter": "Mostrar contador não lido",
"Show_Unread_Counter_Info": "O contador não lido é exibido como um emblema à direita do canal, na lista",
"Sign_in_your_server": "Entrar no seu servidor", "Sign_in_your_server": "Entrar no seu servidor",
"Sign_Up": "Registrar", "Sign_Up": "Registrar",
"Some_field_is_invalid_or_empty": "Algum campo está inválido ou vazio", "Some_field_is_invalid_or_empty": "Algum campo está inválido ou vazio",

View File

@ -427,7 +427,6 @@
"Reset_password": "Сброс пароля", "Reset_password": "Сброс пароля",
"resetting_password": "сброс пароля", "resetting_password": "сброс пароля",
"RESET": "СБРОС", "RESET": "СБРОС",
"Return": "Возврат",
"Review_app_title": "Нравится ли вам это приложение?", "Review_app_title": "Нравится ли вам это приложение?",
"Review_app_desc": "Поставьте нам 5 звезд в {{store}}", "Review_app_desc": "Поставьте нам 5 звезд в {{store}}",
"Review_app_yes": "Конечно!", "Review_app_yes": "Конечно!",
@ -496,8 +495,6 @@
"Share_Link": "Ссылка, чтобы Поделиться", "Share_Link": "Ссылка, чтобы Поделиться",
"Share_this_app": "Рассказать о приложении", "Share_this_app": "Рассказать о приложении",
"Show_more": "Показать больше..", "Show_more": "Показать больше..",
"Show_Unread_Counter": "Показать счетчик непрочитанных",
"Show_Unread_Counter_Info": "Счетчик непрочитанных отображается в виде значка справа от канала в списке каналов",
"Sign_in_your_server": "Войдите на ваш сервер", "Sign_in_your_server": "Войдите на ваш сервер",
"Sign_Up": "Регистрация", "Sign_Up": "Регистрация",
"Some_field_is_invalid_or_empty": "Некоторые поля недопустимы или пусты", "Some_field_is_invalid_or_empty": "Некоторые поля недопустимы или пусты",

View File

@ -417,7 +417,6 @@
"Reset_password": "Şifre sıfırla", "Reset_password": "Şifre sıfırla",
"resetting_password": "şifre sıfırlanıyor", "resetting_password": "şifre sıfırlanıyor",
"RESET": "SIFIRLA", "RESET": "SIFIRLA",
"Return": "Geri dön",
"Review_app_title": "Uygulama hoşunuza gitti mi?", "Review_app_title": "Uygulama hoşunuza gitti mi?",
"Review_app_desc": "{{store}} üzerinde bize 5 yıldız verin", "Review_app_desc": "{{store}} üzerinde bize 5 yıldız verin",
"Review_app_yes": "Elbette!", "Review_app_yes": "Elbette!",
@ -484,8 +483,6 @@
"Share_Link": "Bağlantı paylaş", "Share_Link": "Bağlantı paylaş",
"Share_this_app": "Bu uygulamayı paylaş", "Share_this_app": "Bu uygulamayı paylaş",
"Show_more": "Daha fazla göster..", "Show_more": "Daha fazla göster..",
"Show_Unread_Counter": "Okunmamış Sayacını Göster",
"Show_Unread_Counter_Info": "Okunmamış sayacı, listede kanalın sağ tarafında bir rozet olarak görüntülenir",
"Sign_in_your_server": "Sunucunuzda oturum açın", "Sign_in_your_server": "Sunucunuzda oturum açın",
"Sign_Up": "Kaydol", "Sign_Up": "Kaydol",
"Some_field_is_invalid_or_empty": "Bazı alanlar geçersiz veya boş", "Some_field_is_invalid_or_empty": "Bazı alanlar geçersiz veya boş",

View File

@ -414,7 +414,6 @@
"Reset_password": "重置密码", "Reset_password": "重置密码",
"resetting_password": "正在重置密码", "resetting_password": "正在重置密码",
"RESET": "重置", "RESET": "重置",
"Return": "返回",
"Review_app_title": "对此 App 满意吗?", "Review_app_title": "对此 App 满意吗?",
"Review_app_desc": "请在 {{store}} 给予我们 5 星好评", "Review_app_desc": "请在 {{store}} 给予我们 5 星好评",
"Review_app_yes": "没问题", "Review_app_yes": "没问题",
@ -482,8 +481,6 @@
"Share_Link": "分享链接", "Share_Link": "分享链接",
"Share_this_app": "分享此 app", "Share_this_app": "分享此 app",
"Show_more": "显示更多", "Show_more": "显示更多",
"Show_Unread_Counter": "显示未读信息数量",
"Show_Unread_Counter_Info": "显示未读信息数量资讯",
"Sign_in_your_server": "登录你的服务器", "Sign_in_your_server": "登录你的服务器",
"Sign_Up": "注册", "Sign_Up": "注册",
"Some_field_is_invalid_or_empty": "某些字段无效或为空", "Some_field_is_invalid_or_empty": "某些字段无效或为空",

View File

@ -416,7 +416,6 @@
"Reset_password": "重置密碼", "Reset_password": "重置密碼",
"resetting_password": "正在重置密碼", "resetting_password": "正在重置密碼",
"RESET": "重置", "RESET": "重置",
"Return": "返回",
"Review_app_title": "對此 App 滿意嗎?", "Review_app_title": "對此 App 滿意嗎?",
"Review_app_desc": "請在 {{store}} 給予我們 5 星好評", "Review_app_desc": "請在 {{store}} 給予我們 5 星好評",
"Review_app_yes": "沒問題", "Review_app_yes": "沒問題",
@ -484,8 +483,6 @@
"Share_Link": "分享連結", "Share_Link": "分享連結",
"Share_this_app": "分享此 app", "Share_this_app": "分享此 app",
"Show_more": "顯示更多", "Show_more": "顯示更多",
"Show_Unread_Counter": "顯示未讀訊息數量",
"Show_Unread_Counter_Info": "顯示未讀訊息數量資訊",
"Sign_in_your_server": "登錄你的伺服器", "Sign_in_your_server": "登錄你的伺服器",
"Sign_Up": "註冊", "Sign_Up": "註冊",
"Some_field_is_invalid_or_empty": "某些字段無效或為空", "Some_field_is_invalid_or_empty": "某些字段無效或為空",

View File

@ -1,11 +1,5 @@
import { NativeModules } from 'react-native'; import { NativeModules, Platform } from 'react-native';
import { isIOS } from '../methods/helpers/deviceInfo';
const { AppGroup } = NativeModules; const { AppGroup } = NativeModules;
const appGroup: { path: string } = { export const appGroupPath: string = Platform.OS === 'ios' ? AppGroup.path : '';
path: isIOS ? AppGroup.path : ''
};
export default appGroup;

View File

@ -2,8 +2,7 @@ import { Database } from '@nozbe/watermelondb';
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite'; import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite';
import logger from '@nozbe/watermelondb/utils/common/logger'; import logger from '@nozbe/watermelondb/utils/common/logger';
import { isIOS } from '../methods/helpers/deviceInfo'; import { appGroupPath } from './appGroup';
import appGroup from './appGroup';
import { isOfficial } from '../constants'; import { isOfficial } from '../constants';
import Subscription from './model/Subscription'; import Subscription from './model/Subscription';
import Room from './model/Room'; import Room from './model/Room';
@ -27,10 +26,8 @@ import migrations from './model/migrations';
import serversMigrations from './model/servers/migrations'; import serversMigrations from './model/servers/migrations';
import { TAppDatabase, TServerDatabase } from './interfaces'; import { TAppDatabase, TServerDatabase } from './interfaces';
const appGroupPath = isIOS ? appGroup.path : ''; if (__DEV__) {
console.log(`📂 ${appGroupPath}`);
if (__DEV__ && isIOS) {
console.log(appGroupPath);
} }
const getDatabasePath = (name: string) => `${appGroupPath}${name}${isOfficial ? '' : '-experimental'}.db`; const getDatabasePath = (name: string) => `${appGroupPath}${name}${isOfficial ? '' : '-experimental'}.db`;

View File

@ -103,6 +103,8 @@ export default class Subscription extends Model {
@field('hide_unread_status') hideUnreadStatus; @field('hide_unread_status') hideUnreadStatus;
@field('hide_mention_status') hideMentionStatus;
@json('sys_mes', sanitizer) sysMes; @json('sys_mes', sanitizer) sysMes;
@json('uids', sanitizer) uids; @json('uids', sanitizer) uids;

View File

@ -230,6 +230,15 @@ export default schemaMigrations({
columns: [{ name: 'comment', type: 'string', isOptional: true }] columns: [{ name: 'comment', type: 'string', isOptional: true }]
}) })
] ]
},
{
toVersion: 18,
steps: [
addColumns({
table: 'subscriptions',
columns: [{ name: 'hide_mention_status', type: 'boolean', isOptional: true }]
})
]
} }
] ]
}); });

View File

@ -1,7 +1,7 @@
import { appSchema, tableSchema } from '@nozbe/watermelondb'; import { appSchema, tableSchema } from '@nozbe/watermelondb';
export default appSchema({ export default appSchema({
version: 17, version: 18,
tables: [ tables: [
tableSchema({ tableSchema({
name: 'subscriptions', name: 'subscriptions',
@ -61,7 +61,8 @@ export default appSchema({
{ name: 'team_id', type: 'string', isIndexed: true }, { name: 'team_id', type: 'string', isIndexed: true },
{ name: 'team_main', type: 'boolean', isOptional: true }, // Use `Q.notEq(true)` to get false or null { name: 'team_main', type: 'boolean', isOptional: true }, // Use `Q.notEq(true)` to get false or null
{ name: 'on_hold', type: 'boolean', isOptional: true }, { name: 'on_hold', type: 'boolean', isOptional: true },
{ name: 'source', type: 'string', isOptional: true } { name: 'source', type: 'string', isOptional: true },
{ name: 'hide_mention_status', type: 'boolean', isOptional: true }
] ]
}), }),
tableSchema({ tableSchema({

View File

@ -193,6 +193,7 @@ export default {
ROOM_AUDIO_FINISH_F: 'room_audio_finish_f', ROOM_AUDIO_FINISH_F: 'room_audio_finish_f',
ROOM_AUDIO_CANCEL: 'room_audio_cancel', ROOM_AUDIO_CANCEL: 'room_audio_cancel',
ROOM_AUDIO_CANCEL_F: 'room_audio_cancel_f', ROOM_AUDIO_CANCEL_F: 'room_audio_cancel_f',
ROOM_SHOW_MORE_ACTIONS: 'room_show_more_actions',
ROOM_SHOW_BOX_ACTIONS: 'room_show_box_actions', ROOM_SHOW_BOX_ACTIONS: 'room_show_box_actions',
ROOM_BOX_ACTION_PHOTO: 'room_box_action_photo', ROOM_BOX_ACTION_PHOTO: 'room_box_action_photo',
ROOM_BOX_ACTION_PHOTO_F: 'room_box_action_photo_f', ROOM_BOX_ACTION_PHOTO_F: 'room_box_action_photo_f',

View File

@ -97,6 +97,8 @@ export const merge = (
mergedSubscription.blocker = !!mergedSubscription.blocker; mergedSubscription.blocker = !!mergedSubscription.blocker;
mergedSubscription.blocked = !!mergedSubscription.blocked; mergedSubscription.blocked = !!mergedSubscription.blocked;
mergedSubscription.hideMentionStatus = !!mergedSubscription.hideMentionStatus;
return mergedSubscription; return mergedSubscription;
}; };

View File

@ -103,7 +103,8 @@ const createOrUpdateSubscription = async (subscription: ISubscription, room: ISe
e2eKeyId: s.e2eKeyId, e2eKeyId: s.e2eKeyId,
E2EKey: s.E2EKey, E2EKey: s.E2EKey,
avatarETag: s.avatarETag, avatarETag: s.avatarETag,
onHold: s.onHold onHold: s.onHold,
hideMentionStatus: s.hideMentionStatus
} as ISubscription; } as ISubscription;
} catch (error) { } catch (error) {
try { try {

View File

@ -32,6 +32,12 @@ export type ModalStackParamList = {
rid: string; rid: string;
t: SubscriptionType; t: SubscriptionType;
joined: boolean; joined: boolean;
omnichannelPermissions?: {
canForwardGuest: boolean;
canReturnQueue: boolean;
canViewCannedResponse: boolean;
canPlaceLivechatOnHold: boolean;
};
}; };
RoomInfoView: { RoomInfoView: {
room: ISubscription; room: ISubscription;

View File

@ -34,6 +34,7 @@ export type ChatsStackParamList = {
jumpToThreadId?: string; jumpToThreadId?: string;
roomUserId?: string | null; roomUserId?: string | null;
usedCannedResponse?: string; usedCannedResponse?: string;
status?: string;
} }
| undefined; // Navigates back to RoomView already on stack | undefined; // Navigates back to RoomView already on stack
RoomActionsView: { RoomActionsView: {
@ -42,6 +43,12 @@ export type ChatsStackParamList = {
rid: string; rid: string;
t: SubscriptionType; t: SubscriptionType;
joined: boolean; joined: boolean;
omnichannelPermissions?: {
canForwardGuest: boolean;
canReturnQueue: boolean;
canViewCannedResponse: boolean;
canPlaceLivechatOnHold: boolean;
};
}; };
SelectListView: { SelectListView: {
data?: TDataSelect[]; data?: TDataSelect[];

View File

@ -28,7 +28,7 @@ const SelectUsers = ({
try { try {
const res = await search({ text: keyword, filterRooms: false }); const res = await search({ text: keyword, filterRooms: false });
const selectedUsers = users.filter((u: IUser) => selected.includes(u.name)); const selectedUsers = users.filter((u: IUser) => selected.includes(u.name));
const filteredUsers = res.filter(r => !users.find((u: IUser) => u.name === r.name)); const filteredUsers = res.filter(r => !selectedUsers.find((u: IUser) => u.name === r.name));
const items = [...selectedUsers, ...filteredUsers]; const items = [...selectedUsers, ...filteredUsers];
setUsers(items); setUsers(items);
} catch { } catch {

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,7 @@ import { StyleSheet, Switch, Text } from 'react-native';
import { RouteProp } from '@react-navigation/core'; import { RouteProp } from '@react-navigation/core';
import { StackNavigationProp } from '@react-navigation/stack'; import { StackNavigationProp } from '@react-navigation/stack';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { connect } from 'react-redux';
import database from '../../lib/database'; import database from '../../lib/database';
import { SWITCH_TRACK_COLOR, themes } from '../../lib/constants'; import { SWITCH_TRACK_COLOR, themes } from '../../lib/constants';
@ -16,8 +17,9 @@ import log, { events, logEvent } from '../../lib/methods/helpers/log';
import sharedStyles from '../Styles'; import sharedStyles from '../Styles';
import { IOptionsField, OPTIONS } from './options'; import { IOptionsField, OPTIONS } from './options';
import { ChatsStackParamList } from '../../stacks/types'; import { ChatsStackParamList } from '../../stacks/types';
import { IRoomNotifications, TRoomNotificationsModel } from '../../definitions'; import { IApplicationState, IRoomNotifications, TRoomNotificationsModel } from '../../definitions';
import { Services } from '../../lib/services'; import { Services } from '../../lib/services';
import { compareServerVersion } from '../../lib/methods/helpers/compareServerVersion';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
pickerText: { pickerText: {
@ -30,6 +32,7 @@ interface INotificationPreferencesViewProps {
navigation: StackNavigationProp<ChatsStackParamList, 'NotificationPrefView'>; navigation: StackNavigationProp<ChatsStackParamList, 'NotificationPrefView'>;
route: RouteProp<ChatsStackParamList, 'NotificationPrefView'>; route: RouteProp<ChatsStackParamList, 'NotificationPrefView'>;
theme: TSupportedThemes; theme: TSupportedThemes;
serverVersion: string | null;
} }
interface INotificationPreferencesViewState { interface INotificationPreferencesViewState {
@ -155,6 +158,7 @@ class NotificationPreferencesView extends React.Component<INotificationPreferenc
}; };
render() { render() {
const { serverVersion } = this.props;
const { room } = this.state; const { room } = this.state;
return ( return (
<SafeAreaView testID='notification-preference-view'> <SafeAreaView testID='notification-preference-view'>
@ -185,14 +189,27 @@ class NotificationPreferencesView extends React.Component<INotificationPreferenc
<List.Section> <List.Section>
<List.Separator /> <List.Separator />
<List.Item <List.Item
title='Show_Unread_Counter' title='Mark_as_unread'
testID='notification-preference-view-unread-count' testID='notification-preference-view-mark-as-unread'
right={() => this.renderSwitch('hideUnreadStatus')} right={() => this.renderSwitch('hideUnreadStatus')}
/> />
<List.Separator /> <List.Separator />
<List.Info info='Show_Unread_Counter_Info' /> <List.Info info='Mark_as_unread_Info' />
</List.Section> </List.Section>
{room.hideUnreadStatus && compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '4.8.0') ? (
<List.Section>
<List.Separator />
<List.Item
title='Show_badge_for_mentions'
testID='notification-preference-view-badge-for-mentions'
right={() => this.renderSwitch('hideMentionStatus')}
/>
<List.Separator />
<List.Info info='Show_badge_for_mentions_Info' />
</List.Section>
) : null}
<List.Section title='In_App_And_Desktop'> <List.Section title='In_App_And_Desktop'>
<List.Separator /> <List.Separator />
<List.Item <List.Item
@ -258,4 +275,8 @@ class NotificationPreferencesView extends React.Component<INotificationPreferenc
} }
} }
export default withTheme(NotificationPreferencesView); const mapStateToProps = (state: IApplicationState) => ({
serverVersion: state.server.version
});
export default connect(mapStateToProps)(withTheme(NotificationPreferencesView));

View File

@ -64,12 +64,10 @@ interface IRoomActionsViewProps extends IBaseScreen<ChatsStackParamList, 'RoomAc
editRoomPermission?: string[]; editRoomPermission?: string[];
toggleRoomE2EEncryptionPermission?: string[]; toggleRoomE2EEncryptionPermission?: string[];
viewBroadcastMemberListPermission?: string[]; viewBroadcastMemberListPermission?: string[];
transferLivechatGuestPermission?: string[];
createTeamPermission?: string[]; createTeamPermission?: string[];
addTeamChannelPermission?: string[]; addTeamChannelPermission?: string[];
convertTeamPermission?: string[]; convertTeamPermission?: string[];
viewCannedResponsesPermission?: string[]; viewCannedResponsesPermission?: string[];
livechatAllowManualOnHold?: boolean;
} }
interface IRoomActionsViewState { interface IRoomActionsViewState {
@ -81,16 +79,11 @@ interface IRoomActionsViewState {
canAutoTranslate: boolean; canAutoTranslate: boolean;
canAddUser: boolean; canAddUser: boolean;
canInviteUser: boolean; canInviteUser: boolean;
canForwardGuest: boolean;
canReturnQueue: boolean;
canEdit: boolean; canEdit: boolean;
canToggleEncryption: boolean; canToggleEncryption: boolean;
canCreateTeam: boolean; canCreateTeam: boolean;
canAddChannelToTeam: boolean; canAddChannelToTeam: boolean;
canConvertTeam: boolean; canConvertTeam: boolean;
canViewCannedResponse: boolean;
canPlaceLivechatOnHold: boolean;
isOnHold: boolean;
} }
class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomActionsViewState> { class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomActionsViewState> {
@ -98,6 +91,12 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
private rid: string; private rid: string;
private t: string; private t: string;
private joined: boolean; private joined: boolean;
private omnichannelPermissions?: {
canForwardGuest: boolean;
canReturnQueue: boolean;
canViewCannedResponse: boolean;
canPlaceLivechatOnHold: boolean;
};
private roomObservable?: Observable<TSubscriptionModel>; private roomObservable?: Observable<TSubscriptionModel>;
private subscription?: Subscription; private subscription?: Subscription;
@ -122,6 +121,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
this.rid = props.route.params?.rid; this.rid = props.route.params?.rid;
this.t = props.route.params?.t; this.t = props.route.params?.t;
this.joined = props.route.params?.joined; this.joined = props.route.params?.joined;
this.omnichannelPermissions = props.route.params?.omnichannelPermissions;
this.state = { this.state = {
room: room || { rid: this.rid, t: this.t }, room: room || { rid: this.rid, t: this.t },
membersCount: 0, membersCount: 0,
@ -131,22 +131,17 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
canAutoTranslate: false, canAutoTranslate: false,
canAddUser: false, canAddUser: false,
canInviteUser: false, canInviteUser: false,
canForwardGuest: false,
canReturnQueue: false,
canEdit: false, canEdit: false,
canToggleEncryption: false, canToggleEncryption: false,
canCreateTeam: false, canCreateTeam: false,
canAddChannelToTeam: false, canAddChannelToTeam: false,
canConvertTeam: false, canConvertTeam: false
canViewCannedResponse: false,
canPlaceLivechatOnHold: false,
isOnHold: false
}; };
if (room && room.observe && room.rid) { if (room && room.observe && room.rid) {
this.roomObservable = room.observe(); this.roomObservable = room.observe();
this.subscription = this.roomObservable.subscribe(changes => { this.subscription = this.roomObservable.subscribe(changes => {
if (this.mounted) { if (this.mounted) {
this.setState({ room: changes, isOnHold: !!changes?.onHold }); this.setState({ room: changes });
} else { } else {
// @ts-ignore // @ts-ignore
this.state.room = changes; this.state.room = changes;
@ -214,28 +209,6 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
canAddChannelToTeam, canAddChannelToTeam,
canConvertTeam canConvertTeam
}); });
// livechat permissions
if (room.t === 'l') {
const canForwardGuest = await this.canForwardGuest();
const canReturnQueue = await this.canReturnQueue();
const canViewCannedResponse = await this.canViewCannedResponse();
const canPlaceLivechatOnHold = this.canPlaceLivechatOnHold();
this.setState({ canForwardGuest, canReturnQueue, canViewCannedResponse, canPlaceLivechatOnHold });
}
}
}
componentDidUpdate(prevProps: IRoomActionsViewProps, prevState: IRoomActionsViewState) {
const { livechatAllowManualOnHold } = this.props;
const { room, isOnHold } = this.state;
if (
room.t === 'l' &&
(isOnHold !== prevState.isOnHold || prevProps.livechatAllowManualOnHold !== livechatAllowManualOnHold)
) {
const canPlaceLivechatOnHold = this.canPlaceLivechatOnHold();
this.setState({ canPlaceLivechatOnHold });
} }
} }
@ -372,38 +345,6 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
return result; return result;
}; };
canForwardGuest = async () => {
const { room } = this.state;
const { transferLivechatGuestPermission } = this.props;
const { rid } = room;
const permissions = await hasPermission([transferLivechatGuestPermission], rid);
return permissions[0];
};
canViewCannedResponse = async () => {
const { room } = this.state;
const { viewCannedResponsesPermission } = this.props;
const { rid } = room;
const permissions = await hasPermission([viewCannedResponsesPermission], rid);
return permissions[0];
};
canPlaceLivechatOnHold = (): boolean => {
const { livechatAllowManualOnHold } = this.props;
const { room } = this.state;
return !!(livechatAllowManualOnHold && !room?.lastMessage?.token && room?.lastMessage?.u && !room.onHold);
};
canReturnQueue = async () => {
try {
const { returnQueue } = await Services.getRoutingConfig();
return returnQueue;
} catch {
return false;
}
};
renderEncryptedSwitch = () => { renderEncryptedSwitch = () => {
const { room, canToggleEncryption, canEdit } = this.state; const { room, canToggleEncryption, canEdit } = this.state;
const { encrypted } = room; const { encrypted } = room;
@ -1047,20 +988,86 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
); );
}; };
renderOmnichannelSection = () => {
const { room } = this.state;
const { rid, t } = room;
const { theme } = this.props;
if (t !== 'l' || this.isOmnichannelPreview) {
return null;
}
return (
<List.Section>
{this.omnichannelPermissions?.canForwardGuest ? (
<>
<List.Item
title='Forward'
onPress={() =>
this.onPressTouchable({
route: 'ForwardLivechatView',
params: { rid }
})
}
left={() => <List.Icon name='chat-forward' color={themes[theme].titleText} />}
showActionIndicator
/>
<List.Separator />
</>
) : null}
{this.omnichannelPermissions?.canPlaceLivechatOnHold ? (
<>
<List.Item
title='Place_chat_on_hold'
onPress={() =>
this.onPressTouchable({
event: this.placeOnHoldLivechat
})
}
left={() => <List.Icon name='pause' color={themes[theme].titleText} />}
showActionIndicator
/>
<List.Separator />
</>
) : null}
{this.omnichannelPermissions?.canReturnQueue ? (
<>
<List.Item
title='Return_to_waiting_line'
onPress={() =>
this.onPressTouchable({
event: this.returnLivechat
})
}
left={() => <List.Icon name='move-to-the-queue' color={themes[theme].titleText} />}
showActionIndicator
/>
<List.Separator />
</>
) : null}
<>
<List.Item
title='Close'
color={themes[theme].dangerColor}
onPress={() =>
this.onPressTouchable({
event: this.closeLivechat
})
}
left={() => <List.Icon name='chat-close' color={themes[theme].dangerColor} />}
showActionIndicator
/>
<List.Separator />
</>
</List.Section>
);
};
render() { render() {
const { const { room, membersCount, canViewMembers, canAddUser, canInviteUser, joined, canAutoTranslate } = this.state;
room,
membersCount,
canViewMembers,
canAddUser,
canInviteUser,
joined,
canAutoTranslate,
canForwardGuest,
canReturnQueue,
canViewCannedResponse,
canPlaceLivechatOnHold
} = this.state;
const { rid, t, prid } = room; const { rid, t, prid } = room;
const isGroupChatHandler = isGroupChat(room); const isGroupChatHandler = isGroupChat(room);
@ -1149,6 +1156,18 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
</> </>
) : null} ) : null}
{['l'].includes(t) && !this.isOmnichannelPreview && this.omnichannelPermissions?.canViewCannedResponse ? (
<>
<List.Item
title='Canned_Responses'
onPress={() => this.onPressTouchable({ route: 'CannedResponsesListView', params: { rid } })}
left={() => <List.Icon name='canned-response' />}
showActionIndicator
/>
<List.Separator />
</>
) : null}
{['c', 'p', 'd'].includes(t) ? ( {['c', 'p', 'd'].includes(t) ? (
<> <>
<List.Item <List.Item
@ -1276,85 +1295,8 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
{this.teamChannelActions(t, room)} {this.teamChannelActions(t, room)}
{this.teamToChannelActions(t, room)} {this.teamToChannelActions(t, room)}
{['l'].includes(t) && !this.isOmnichannelPreview && canViewCannedResponse ? (
<>
<List.Item
title='Canned_Responses'
onPress={() => this.onPressTouchable({ route: 'CannedResponsesListView', params: { rid } })}
left={() => <List.Icon name='canned-response' />}
showActionIndicator
/>
<List.Separator />
</>
) : null}
{['l'].includes(t) && !this.isOmnichannelPreview ? (
<>
<List.Item
title='Close'
onPress={() =>
this.onPressTouchable({
event: this.closeLivechat
})
}
left={() => <List.Icon name='close' />}
showActionIndicator
/>
<List.Separator />
</>
) : null}
{['l'].includes(t) && !this.isOmnichannelPreview && canForwardGuest ? (
<>
<List.Item
title='Forward'
onPress={() =>
this.onPressTouchable({
route: 'ForwardLivechatView',
params: { rid }
})
}
left={() => <List.Icon name='user-forward' />}
showActionIndicator
/>
<List.Separator />
</>
) : null}
{['l'].includes(t) && !this.isOmnichannelPreview && canPlaceLivechatOnHold ? (
<>
<List.Item
title='Place_chat_on_hold'
onPress={() =>
this.onPressTouchable({
event: this.placeOnHoldLivechat
})
}
left={() => <List.Icon name='pause' />}
showActionIndicator
/>
<List.Separator />
</>
) : null}
{['l'].includes(t) && !this.isOmnichannelPreview && canReturnQueue ? (
<>
<List.Item
title='Return'
onPress={() =>
this.onPressTouchable({
event: this.returnLivechat
})
}
left={() => <List.Icon name='undo' />}
showActionIndicator
/>
<List.Separator />
</>
) : null}
</List.Section> </List.Section>
{this.renderOmnichannelSection()}
{this.renderLastSection()} {this.renderLastSection()}
</List.Container> </List.Container>
</SafeAreaView> </SafeAreaView>
@ -1377,12 +1319,9 @@ const mapStateToProps = (state: IApplicationState) => ({
editRoomPermission: state.permissions['edit-room'], editRoomPermission: state.permissions['edit-room'],
toggleRoomE2EEncryptionPermission: state.permissions['toggle-room-e2e-encryption'], toggleRoomE2EEncryptionPermission: state.permissions['toggle-room-e2e-encryption'],
viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'], viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'],
transferLivechatGuestPermission: state.permissions['transfer-livechat-guest'],
createTeamPermission: state.permissions['create-team'], createTeamPermission: state.permissions['create-team'],
addTeamChannelPermission: state.permissions['add-team-channel'], addTeamChannelPermission: state.permissions['add-team-channel'],
convertTeamPermission: state.permissions['convert-team'], convertTeamPermission: state.permissions['convert-team']
viewCannedResponsesPermission: state.permissions['view-canned-responses'],
livechatAllowManualOnHold: state.settings.Livechat_allow_manual_on_hold as boolean
}); });
export default connect(mapStateToProps)(withTheme(withDimensions(RoomActionsView))); export default connect(mapStateToProps)(withTheme(withDimensions(RoomActionsView)));

View File

@ -6,7 +6,6 @@ import isEmpty from 'lodash/isEmpty';
import { Alert, Keyboard, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native'; import { Alert, Keyboard, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native';
import ImagePicker, { Image } from 'react-native-image-crop-picker'; import ImagePicker, { Image } from 'react-native-image-crop-picker';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Subscription } from 'rxjs';
import { deleteRoom } from '../../actions/room'; import { deleteRoom } from '../../actions/room';
import { themes } from '../../lib/constants'; import { themes } from '../../lib/constants';
@ -86,7 +85,6 @@ interface IRoomInfoEditViewProps extends IBaseScreen<ChatsStackParamList | Modal
class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfoEditViewState> { class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfoEditViewState> {
randomValue = random(15); randomValue = random(15);
private querySubscription: Subscription | undefined;
private room: TSubscriptionModel; private room: TSubscriptionModel;
private name: TextInput | null | undefined; private name: TextInput | null | undefined;
private description: TextInput | null | undefined; private description: TextInput | null | undefined;
@ -123,12 +121,6 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
this.loadRoom(); this.loadRoom();
} }
componentWillUnmount() {
if (this.querySubscription && this.querySubscription.unsubscribe) {
this.querySubscription.unsubscribe();
}
}
loadRoom = async () => { loadRoom = async () => {
const { const {
route, route,
@ -147,12 +139,8 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
try { try {
const db = database.active; const db = database.active;
const sub = await db.get('subscriptions').find(rid); const sub = await db.get('subscriptions').find(rid);
const observable = sub.observe(); this.room = sub;
this.init(this.room);
this.querySubscription = observable.subscribe(data => {
this.room = data;
this.init(this.room);
});
const result = await hasPermission( const result = await hasPermission(
[ [

View File

@ -325,16 +325,11 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
goRoom = () => { goRoom = () => {
logEvent(events.RI_GO_ROOM_USER); logEvent(events.RI_GO_ROOM_USER);
const { roomUser, room } = this.state; const { room } = this.state;
const { name, username } = roomUser;
const { rooms, navigation, isMasterDetail } = this.props; const { rooms, navigation, isMasterDetail } = this.props;
const params = { const params = {
rid: room.rid, rid: room.rid,
name: getRoomTitle({ name: getRoomTitle(room),
t: room.t,
fname: name,
name: username
}),
t: room.t, t: room.t,
roomUserId: getUidDirectMessage(room) roomUserId: getUidDirectMessage(room)
}; };

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { dequal } from 'dequal'; import { dequal } from 'dequal';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { Dispatch } from 'redux';
import { StackNavigationProp } from '@react-navigation/stack'; import { StackNavigationProp } from '@react-navigation/stack';
import * as HeaderButton from '../../containers/HeaderButton'; import * as HeaderButton from '../../containers/HeaderButton';
@ -11,19 +12,33 @@ import { events, logEvent } from '../../lib/methods/helpers/log';
import { isTeamRoom } from '../../lib/methods/helpers/room'; import { isTeamRoom } from '../../lib/methods/helpers/room';
import { IApplicationState, SubscriptionType, TMessageModel, TSubscriptionModel } from '../../definitions'; import { IApplicationState, SubscriptionType, TMessageModel, TSubscriptionModel } from '../../definitions';
import { ChatsStackParamList } from '../../stacks/types'; import { ChatsStackParamList } from '../../stacks/types';
import { TActionSheetOptions, TActionSheetOptionsItem, withActionSheet } from '../../containers/ActionSheet';
import i18n from '../../i18n';
import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers';
import { closeRoom } from '../../actions/room';
import { onHoldLivechat, returnLivechat } from '../../lib/services/restApi';
interface IRightButtonsProps { interface IRightButtonsProps {
userId?: string; userId?: string;
threadsEnabled: boolean; threadsEnabled: boolean;
rid?: string; rid: string;
t: string; t: string;
tmid?: string; tmid?: string;
teamId?: string; teamId?: string;
isMasterDetail: boolean; isMasterDetail: boolean;
toggleFollowThread: Function; toggleFollowThread: Function;
joined: boolean; joined: boolean;
status?: string;
dispatch: Dispatch;
encrypted?: boolean; encrypted?: boolean;
showActionSheet: (item: TActionSheetOptions) => void;
transferLivechatGuestPermission: boolean;
navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>; navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>;
omnichannelPermissions: {
canForwardGuest: boolean;
canReturnQueue: boolean;
canPlaceLivechatOnHold: boolean;
};
} }
interface IRigthButtonsState { interface IRigthButtonsState {
@ -71,13 +86,22 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
shouldComponentUpdate(nextProps: IRightButtonsProps, nextState: IRigthButtonsState) { shouldComponentUpdate(nextProps: IRightButtonsProps, nextState: IRigthButtonsState) {
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state; const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
const { teamId } = this.props; const { teamId, status, joined, omnichannelPermissions } = this.props;
if (nextProps.teamId !== teamId) { if (nextProps.teamId !== teamId) {
return true; return true;
} }
if (nextProps.status !== status) {
return true;
}
if (nextProps.joined !== joined) {
return true;
}
if (nextState.isFollowingThread !== isFollowingThread) { if (nextState.isFollowingThread !== isFollowingThread) {
return true; return true;
} }
if (!dequal(nextProps.omnichannelPermissions, omnichannelPermissions)) {
return true;
}
if (!dequal(nextState.tunread, tunread)) { if (!dequal(nextState.tunread, tunread)) {
return true; return true;
} }
@ -157,6 +181,82 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
} }
}; };
returnLivechat = () => {
const { rid } = this.props;
showConfirmationAlert({
message: i18n.t('Would_you_like_to_return_the_inquiry'),
confirmationText: i18n.t('Yes'),
onPress: async () => {
try {
await returnLivechat(rid);
} catch (e: any) {
showErrorAlert(e.reason, i18n.t('Oops'));
}
}
});
};
placeOnHoldLivechat = () => {
const { navigation, rid } = this.props;
showConfirmationAlert({
title: i18n.t('Are_you_sure_question_mark'),
message: i18n.t('Would_like_to_place_on_hold'),
confirmationText: i18n.t('Yes'),
onPress: async () => {
try {
await onHoldLivechat(rid);
navigation.navigate('RoomsListView');
} catch (e: any) {
showErrorAlert(e.data?.error, i18n.t('Oops'));
}
}
});
};
closeLivechat = () => {
const { dispatch, rid } = this.props;
dispatch(closeRoom(rid));
};
showMoreActions = () => {
logEvent(events.ROOM_SHOW_MORE_ACTIONS);
const { showActionSheet, rid, navigation, omnichannelPermissions } = this.props;
const options = [] as TActionSheetOptionsItem[];
if (omnichannelPermissions.canPlaceLivechatOnHold) {
options.push({
title: i18n.t('Place_chat_on_hold'),
icon: 'pause',
onPress: () => this.placeOnHoldLivechat()
});
}
if (omnichannelPermissions.canForwardGuest) {
options.push({
title: i18n.t('Forward_Chat'),
icon: 'chat-forward',
onPress: () => navigation.navigate('ForwardLivechatView', { rid })
});
}
if (omnichannelPermissions.canReturnQueue) {
options.push({
title: i18n.t('Return_to_waiting_line'),
icon: 'move-to-the-queue',
onPress: () => this.returnLivechat()
});
}
options.push({
title: i18n.t('Close'),
icon: 'chat-close',
onPress: () => this.closeLivechat(),
danger: true
});
showActionSheet({ options });
};
goSearchView = () => { goSearchView = () => {
logEvent(events.ROOM_GO_SEARCH); logEvent(events.ROOM_GO_SEARCH);
const { rid, t, navigation, isMasterDetail, encrypted } = this.props; const { rid, t, navigation, isMasterDetail, encrypted } = this.props;
@ -183,10 +283,23 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
} }
}; };
isOmnichannelPreview = () => {
const { status } = this.props;
return status === 'queued';
};
render() { render() {
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state; const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
const { t, tmid, threadsEnabled, teamId, joined } = this.props; const { t, tmid, threadsEnabled, teamId, joined } = this.props;
if (t === 'l') { if (t === 'l') {
if (!this.isOmnichannelPreview()) {
return (
<HeaderButton.Container>
<HeaderButton.Item iconName='kebab' onPress={this.showMoreActions} testID='room-view-header-omnichannel-kebab' />
</HeaderButton.Container>
);
}
return null; return null;
} }
if (tmid) { if (tmid) {
@ -225,4 +338,4 @@ const mapStateToProps = (state: IApplicationState) => ({
isMasterDetail: state.app.isMasterDetail isMasterDetail: state.app.isMasterDetail
}); });
export default connect(mapStateToProps)(RightButtonsContainer); export default connect(mapStateToProps)(withActionSheet(RightButtonsContainer));

View File

@ -9,6 +9,7 @@ import { dequal } from 'dequal';
import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context'; import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { getRoutingConfig } from '../../lib/services/restApi';
import Touch from '../../lib/methods/helpers/touch'; import Touch from '../../lib/methods/helpers/touch';
import { replyBroadcast } from '../../actions/messages'; import { replyBroadcast } from '../../actions/messages';
import database from '../../lib/database'; import database from '../../lib/database';
@ -63,6 +64,7 @@ import {
IApplicationState, IApplicationState,
IAttachment, IAttachment,
IBaseScreen, IBaseScreen,
ILastMessage,
ILoggedUser, ILoggedUser,
IMessage, IMessage,
IOmnichannelSource, IOmnichannelSource,
@ -94,7 +96,8 @@ import {
canAutoTranslate as canAutoTranslateMethod, canAutoTranslate as canAutoTranslateMethod,
debounce, debounce,
isIOS, isIOS,
isTablet isTablet,
hasPermission
} from '../../lib/methods/helpers'; } from '../../lib/methods/helpers';
import { Services } from '../../lib/services'; import { Services } from '../../lib/services';
@ -112,7 +115,10 @@ const stateAttrsUpdate = [
'reacting', 'reacting',
'readOnly', 'readOnly',
'member', 'member',
'showingBlockingLoader' 'showingBlockingLoader',
'canForwardGuest',
'canReturnQueue',
'canViewCannedResponse'
] as TStateAttrsUpdate[]; ] as TStateAttrsUpdate[];
type TRoomUpdate = keyof TSubscriptionModel; type TRoomUpdate = keyof TSubscriptionModel;
@ -138,6 +144,8 @@ const roomAttrsUpdate = [
'joinCodeRequired', 'joinCodeRequired',
'teamMain', 'teamMain',
'teamId', 'teamId',
'status',
'lastMessage',
'onHold' 'onHold'
] as TRoomUpdate[]; ] as TRoomUpdate[];
@ -158,6 +166,9 @@ interface IRoomViewProps extends IBaseScreen<ChatsStackParamList, 'RoomView'> {
width: number; width: number;
height: number; height: number;
insets: EdgeInsets; insets: EdgeInsets;
transferLivechatGuestPermission?: string[]; // TODO: Check if its the correct type
viewCannedResponsesPermission?: string[]; // TODO: Check if its the correct type
livechatAllowManualOnHold?: boolean;
} }
interface IRoomViewState { interface IRoomViewState {
@ -165,7 +176,18 @@ interface IRoomViewState {
joined: boolean; joined: boolean;
room: room:
| TSubscriptionModel | TSubscriptionModel
| { rid: string; t: string; name?: string; fname?: string; prid?: string; joinCodeRequired?: boolean; sysMes?: boolean }; | {
rid: string;
t: string;
name?: string;
fname?: string;
prid?: string;
joinCodeRequired?: boolean;
status?: boolean;
lastMessage?: ILastMessage;
sysMes?: boolean;
onHold?: boolean;
};
roomUpdate: { roomUpdate: {
[K in TRoomUpdate]?: any; [K in TRoomUpdate]?: any;
}; };
@ -197,6 +219,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
private flatList: TListRef; private flatList: TListRef;
private mounted: boolean; private mounted: boolean;
private offset = 0; private offset = 0;
private subObserveQuery?: Subscription;
private subSubscription?: Subscription; private subSubscription?: Subscription;
private queryUnreads?: Subscription; private queryUnreads?: Subscription;
private retryInit = 0; private retryInit = 0;
@ -256,8 +279,14 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
reacting: false, reacting: false,
readOnly: false, readOnly: false,
unreadsCount: null, unreadsCount: null,
roomUserId roomUserId,
canViewCannedResponse: false,
canForwardGuest: false,
canReturnQueue: false,
canPlaceLivechatOnHold: false,
isOnHold: false
}; };
this.setHeader(); this.setHeader();
if ('id' in room) { if ('id' in room) {
@ -275,6 +304,10 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
this.flatList = React.createRef(); this.flatList = React.createRef();
this.mounted = false; this.mounted = false;
if (this.t === 'l') {
this.updateOmnichannel();
}
// we don't need to subscribe to threads // we don't need to subscribe to threads
if (this.rid && !this.tmid) { if (this.rid && !this.tmid) {
this.sub = new RoomClass(this.rid); this.sub = new RoomClass(this.rid);
@ -314,7 +347,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
shouldComponentUpdate(nextProps: IRoomViewProps, nextState: IRoomViewState) { shouldComponentUpdate(nextProps: IRoomViewProps, nextState: IRoomViewState) {
const { state } = this; const { state } = this;
const { roomUpdate, member } = state; const { roomUpdate, member, isOnHold } = state;
const { appState, theme, insets, route } = this.props; const { appState, theme, insets, route } = this.props;
if (theme !== nextProps.theme) { if (theme !== nextProps.theme) {
return true; return true;
@ -325,7 +358,9 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
if (member.statusText !== nextState.member.statusText) { if (member.statusText !== nextState.member.statusText) {
return true; return true;
} }
if (isOnHold !== nextState.isOnHold) {
return true;
}
const stateUpdated = stateAttrsUpdate.some(key => nextState[key] !== state[key]); const stateUpdated = stateAttrsUpdate.some(key => nextState[key] !== state[key]);
if (stateUpdated) { if (stateUpdated) {
return true; return true;
@ -340,7 +375,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
} }
componentDidUpdate(prevProps: IRoomViewProps, prevState: IRoomViewState) { componentDidUpdate(prevProps: IRoomViewProps, prevState: IRoomViewState) {
const { roomUpdate } = this.state; const { roomUpdate, joined } = this.state;
const { appState, insets, route } = this.props; const { appState, insets, route } = this.props;
if (route?.params?.jumpToMessageId && route?.params?.jumpToMessageId !== prevProps.route?.params?.jumpToMessageId) { if (route?.params?.jumpToMessageId && route?.params?.jumpToMessageId !== prevProps.route?.params?.jumpToMessageId) {
@ -365,8 +400,13 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
} }
// If it's a livechat room // If it's a livechat room
if (this.t === 'l') { if (this.t === 'l') {
if (!dequal(prevState.roomUpdate.visitor, roomUpdate.visitor)) { if (
this.setHeader(); !dequal(prevState.roomUpdate.lastMessage?.token, roomUpdate.lastMessage?.token) ||
!dequal(prevState.roomUpdate.visitor, roomUpdate.visitor) ||
!dequal(prevState.roomUpdate.status, roomUpdate.status) ||
prevState.joined !== joined
) {
this.updateOmnichannel();
} }
} }
if (roomUpdate.teamMain !== prevState.roomUpdate.teamMain || roomUpdate.teamId !== prevState.roomUpdate.teamId) { if (roomUpdate.teamMain !== prevState.roomUpdate.teamMain || roomUpdate.teamId !== prevState.roomUpdate.teamId) {
@ -387,6 +427,17 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
this.setReadOnly(); this.setReadOnly();
} }
updateOmnichannel = async () => {
const canForwardGuest = await this.canForwardGuest();
const canPlaceLivechatOnHold = this.canPlaceLivechatOnHold();
const canReturnQueue = await this.canReturnQueue();
const canViewCannedResponse = await this.canViewCannedResponse();
this.setState({ canForwardGuest, canReturnQueue, canViewCannedResponse, canPlaceLivechatOnHold });
if (this.mounted) {
this.setHeader();
}
};
async componentWillUnmount() { async componentWillUnmount() {
const { editing, room } = this.state; const { editing, room } = this.state;
const db = database.active; const db = database.active;
@ -424,15 +475,16 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
if (this.subSubscription && this.subSubscription.unsubscribe) { if (this.subSubscription && this.subSubscription.unsubscribe) {
this.subSubscription.unsubscribe(); this.subSubscription.unsubscribe();
} }
if (this.subObserveQuery && this.subObserveQuery.unsubscribe) {
this.subObserveQuery.unsubscribe();
}
if (this.queryUnreads && this.queryUnreads.unsubscribe) { if (this.queryUnreads && this.queryUnreads.unsubscribe) {
this.queryUnreads.unsubscribe(); this.queryUnreads.unsubscribe();
} }
if (this.retryInitTimeout) { if (this.retryInitTimeout) {
clearTimeout(this.retryInitTimeout); clearTimeout(this.retryInitTimeout);
} }
if (this.retryFindTimeout) {
clearTimeout(this.retryFindTimeout);
}
EventEmitter.removeListener('connected', this.handleConnected); EventEmitter.removeListener('connected', this.handleConnected);
if (isTablet) { if (isTablet) {
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands); EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
@ -441,13 +493,61 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
console.countReset(`${this.constructor.name}.render calls`); console.countReset(`${this.constructor.name}.render calls`);
} }
canForwardGuest = async () => {
const { transferLivechatGuestPermission } = this.props;
const permissions = await hasPermission([transferLivechatGuestPermission], this.rid);
return permissions[0] as boolean;
};
canPlaceLivechatOnHold = () => {
const { livechatAllowManualOnHold } = this.props;
const { room } = this.state;
return !!(livechatAllowManualOnHold && !room?.lastMessage?.token && room?.lastMessage?.u && !room.onHold);
};
canViewCannedResponse = async () => {
const { viewCannedResponsesPermission } = this.props;
const permissions = await hasPermission([viewCannedResponsesPermission], this.rid);
return permissions[0] as boolean;
};
canReturnQueue = async () => {
try {
const { returnQueue } = await getRoutingConfig();
return returnQueue;
} catch {
return false;
}
};
observeSubscriptions = () => {
try {
const db = database.active;
const observeSubCollection = db
.get('subscriptions')
.query(Q.where('rid', this.rid as string))
.observe();
this.subObserveQuery = observeSubCollection.subscribe(data => {
if (data[0]) {
if (this.subObserveQuery && this.subObserveQuery.unsubscribe) {
this.observeRoom(data[0]);
this.setState({ room: data[0] });
this.subObserveQuery.unsubscribe();
}
}
});
} catch (e) {
console.log("observeSubscriptions: Can't find subscription to observe");
}
};
get isOmnichannel() { get isOmnichannel() {
const { room } = this.state; const { room } = this.state;
return room.t === 'l'; return room.t === 'l';
} }
setHeader = () => { setHeader = () => {
const { room, unreadsCount, roomUserId, joined } = this.state; const { room, unreadsCount, roomUserId, joined, canForwardGuest, canReturnQueue, canPlaceLivechatOnHold } = this.state;
const { navigation, isMasterDetail, theme, baseUrl, user, route } = this.props; const { navigation, isMasterDetail, theme, baseUrl, user, route } = this.props;
const { rid, tmid } = this; const { rid, tmid } = this;
if (!room.rid) { if (!room.rid) {
@ -474,6 +574,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
let token: string | undefined; let token: string | undefined;
let avatar: string | undefined; let avatar: string | undefined;
let visitor: IVisitor | undefined; let visitor: IVisitor | undefined;
let status: string | undefined;
let sourceType: IOmnichannelSource | undefined; let sourceType: IOmnichannelSource | undefined;
if ('id' in room) { if ('id' in room) {
subtitle = room.topic; subtitle = room.topic;
@ -484,6 +585,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
({ id: userId, token } = user); ({ id: userId, token } = user);
avatar = room.name; avatar = room.name;
visitor = room.visitor; visitor = room.visitor;
status = room.status;
} }
if ('source' in room) { if ('source' in room) {
@ -493,11 +595,13 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
} }
let numIconsRight = 2; let numIconsRight = 2;
if (tmid) { if (tmid || (status && joined)) {
numIconsRight = 1; numIconsRight = 1;
} else if (teamId && isTeamRoom({ teamId, joined })) { } else if (teamId && isTeamRoom({ teamId, joined })) {
numIconsRight = 3; numIconsRight = 3;
} }
const omnichannelPermissions = { canForwardGuest, canReturnQueue, canPlaceLivechatOnHold };
const paddingRight = this.getPaddingLeft(numIconsRight, isMasterDetail); const paddingRight = this.getPaddingLeft(numIconsRight, isMasterDetail);
navigation.setOptions({ navigation.setOptions({
headerShown: true, headerShown: true,
@ -542,6 +646,8 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
tmid={tmid} tmid={tmid}
teamId={teamId} teamId={teamId}
joined={joined} joined={joined}
status={room.status}
omnichannelPermissions={omnichannelPermissions}
t={this.t || t} t={this.t || t}
encrypted={encrypted} encrypted={encrypted}
navigation={navigation} navigation={navigation}
@ -560,7 +666,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
goRoomActionsView = (screen?: keyof ModalStackParamList) => { goRoomActionsView = (screen?: keyof ModalStackParamList) => {
logEvent(events.ROOM_GO_RA); logEvent(events.ROOM_GO_RA);
const { room, member, joined } = this.state; const { room, member, joined, canForwardGuest, canReturnQueue, canViewCannedResponse, canPlaceLivechatOnHold } = this.state;
const { navigation, isMasterDetail } = this.props; const { navigation, isMasterDetail } = this.props;
if (isMasterDetail) { if (isMasterDetail) {
// @ts-ignore // @ts-ignore
@ -572,7 +678,8 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
room: room as ISubscription, room: room as ISubscription,
member, member,
showCloseModal: !!screen, showCloseModal: !!screen,
joined joined,
omnichannelPermissions: { canForwardGuest, canReturnQueue, canViewCannedResponse, canPlaceLivechatOnHold }
} }
}); });
} else if (this.rid && this.t) { } else if (this.rid && this.t) {
@ -581,7 +688,8 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
t: this.t as SubscriptionType, t: this.t as SubscriptionType,
room: room as TSubscriptionModel, room: room as TSubscriptionModel,
member, member,
joined joined,
omnichannelPermissions: { canForwardGuest, canReturnQueue, canViewCannedResponse, canPlaceLivechatOnHold }
}); });
} }
}; };
@ -669,15 +777,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
this.internalSetState({ joined: false }); this.internalSetState({ joined: false });
} }
if (this.rid) { if (this.rid) {
// We navigate to RoomView before the Room is inserted to the local db this.observeSubscriptions();
// So we retry just to make sure we have the right content
this.retryFindCount = this.retryFindCount + 1 || 1;
if (this.retryFindCount <= 3) {
this.retryFindTimeout = setTimeout(() => {
this.findAndObserveRoom(rid);
this.init();
}, 300);
}
} }
} }
}; };
@ -697,7 +797,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
return ret; return ret;
}, {}); }, {});
if (this.mounted) { if (this.mounted) {
this.internalSetState({ room: changes, roomUpdate }); this.internalSetState({ room: changes, roomUpdate, isOnHold: !!changes?.onHold });
} else { } else {
// @ts-ignore // @ts-ignore
this.state.room = changes; this.state.room = changes;
@ -1186,6 +1286,11 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}); });
}; };
goToCannedResponses = () => {
const { room } = this.state;
Navigation.navigate('CannedResponsesListView', { rid: room.rid });
};
renderItem = (item: TAnyMessageModel, previousItem: TAnyMessageModel, highlightedMessage?: string) => { renderItem = (item: TAnyMessageModel, previousItem: TAnyMessageModel, highlightedMessage?: string) => {
const { room, lastOpen, canAutoTranslate } = this.state; const { room, lastOpen, canAutoTranslate } = this.state;
const { user, Message_GroupingPeriod, Message_TimeFormat, useRealName, baseUrl, Message_Read_Receipt_Enabled, theme } = const { user, Message_GroupingPeriod, Message_TimeFormat, useRealName, baseUrl, Message_Read_Receipt_Enabled, theme } =
@ -1203,7 +1308,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
dateSeparator = item.ts; dateSeparator = item.ts;
} }
} }
let content = null; let content = null;
if (item.t && MESSAGE_TYPE_ANY_LOAD.includes(item.t as MessageTypeLoad)) { if (item.t && MESSAGE_TYPE_ANY_LOAD.includes(item.t as MessageTypeLoad)) {
content = ( content = (
@ -1271,7 +1375,8 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}; };
renderFooter = () => { renderFooter = () => {
const { joined, room, selectedMessage, editing, replying, replyWithMention, readOnly, loading } = this.state; const { joined, room, selectedMessage, editing, replying, replyWithMention, readOnly, loading, canViewCannedResponse } =
this.state;
const { navigation, theme, route } = this.props; const { navigation, theme, route } = this.props;
const usedCannedResponse = route?.params?.usedCannedResponse; const usedCannedResponse = route?.params?.usedCannedResponse;
@ -1338,9 +1443,11 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
return ( return (
<MessageBox <MessageBox
ref={this.messagebox} ref={this.messagebox}
goToCannedResponses={canViewCannedResponse ? this.goToCannedResponses : null}
onSubmit={this.handleSendMessage} onSubmit={this.handleSendMessage}
rid={this.rid} rid={this.rid}
tmid={this.tmid} tmid={this.tmid}
joined={joined}
roomType={room.t} roomType={room.t}
isFocused={navigation.isFocused} isFocused={navigation.isFocused}
theme={theme} theme={theme}
@ -1454,7 +1561,10 @@ const mapStateToProps = (state: IApplicationState) => ({
baseUrl: state.server.server, baseUrl: state.server.server,
serverVersion: state.server.version, serverVersion: state.server.version,
Message_Read_Receipt_Enabled: state.settings.Message_Read_Receipt_Enabled as boolean, Message_Read_Receipt_Enabled: state.settings.Message_Read_Receipt_Enabled as boolean,
Hide_System_Messages: state.settings.Hide_System_Messages as string[] Hide_System_Messages: state.settings.Hide_System_Messages as string[],
transferLivechatGuestPermission: state.permissions['transfer-livechat-guest'],
viewCannedResponsesPermission: state.permissions['view-canned-responses'],
livechatAllowManualOnHold: state.settings.Livechat_allow_manual_on_hold as boolean
}); });
export default connect(mapStateToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomView)))); export default connect(mapStateToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomView))));

File diff suppressed because one or more lines are too long

View File

@ -287,7 +287,7 @@ describe('Room actions screen', () => {
}); });
it('should have show unread count option', async () => { it('should have show unread count option', async () => {
await expect(element(by.id('notification-preference-view-unread-count'))).toExist(); await expect(element(by.id('notification-preference-view-mark-as-unread'))).toExist();
}); });
it('should have notification alert option', async () => { it('should have notification alert option', async () => {

7
jest.preset.js Normal file
View File

@ -0,0 +1,7 @@
const jestRN = require('react-native/jest-preset');
const jestExpo = require('jest-expo/jest-preset.js');
module.exports = {
...jestRN,
...jestExpo
};

View File

@ -1,4 +1,7 @@
import mockClipboard from '@react-native-clipboard/clipboard/jest/clipboard-mock.js'; import mockClipboard from '@react-native-clipboard/clipboard/jest/clipboard-mock.js';
import mockAsyncStorage from '@react-native-community/async-storage/jest/async-storage-mock';
jest.mock('@react-native-community/async-storage', () => mockAsyncStorage);
require('react-native-reanimated/lib/reanimated2/jestUtils').setUpTests(); require('react-native-reanimated/lib/reanimated2/jestUtils').setUpTests();
@ -35,3 +38,24 @@ jest.mock('react-native-file-viewer', () => ({
jest.mock('expo-haptics', () => jest.fn(() => null)); jest.mock('expo-haptics', () => jest.fn(() => null));
jest.mock('./app/lib/database', () => jest.fn(() => null)); jest.mock('./app/lib/database', () => jest.fn(() => null));
const mockedNavigate = jest.fn();
jest.mock('@react-navigation/native', () => ({
...jest.requireActual('@react-navigation/native'),
useNavigation: () => mockedNavigate
}));
jest.mock('react-native-notifications', () => ({
Notifications: {
getInitialNotification: jest.fn(() => Promise.resolve()),
registerRemoteNotifications: jest.fn(),
events: () => ({
registerRemoteNotificationsRegistered: jest.fn(),
registerRemoteNotificationsRegistrationFailed: jest.fn(),
registerNotificationReceivedForeground: jest.fn(),
registerNotificationReceivedBackground: jest.fn(),
registerNotificationOpened: jest.fn()
})
}
}));

View File

@ -188,6 +188,7 @@
"identity-obj-proxy": "^3.0.0", "identity-obj-proxy": "^3.0.0",
"jest": "^27.0.6", "jest": "^27.0.6",
"jest-cli": "^27.0.6", "jest-cli": "^27.0.6",
"jest-expo": "^45.0.1",
"metro-react-native-babel-preset": "^0.64.0", "metro-react-native-babel-preset": "^0.64.0",
"mocha": "9.0.1", "mocha": "9.0.1",
"otp.js": "1.2.0", "otp.js": "1.2.0",
@ -207,7 +208,7 @@
"transformIgnorePatterns": [ "transformIgnorePatterns": [
"node_modules/(?!(jest-)?@?react-native|@react-native-community|@react-navigation)" "node_modules/(?!(jest-)?@?react-native|@react-native-community|@react-navigation)"
], ],
"preset": "react-native", "preset": "./jest.preset.js",
"coverageDirectory": "./coverage/", "coverageDirectory": "./coverage/",
"collectCoverage": true, "collectCoverage": true,
"moduleNameMapper": { "moduleNameMapper": {

View File

@ -2,12 +2,14 @@
import React from 'react'; import React from 'react';
import { StyleSheet, View } from 'react-native'; import { StyleSheet, View } from 'react-native';
import { storiesOf } from '@storybook/react-native'; import { storiesOf } from '@storybook/react-native';
import { Provider } from 'react-redux';
import NewMarkdown from '../../app/containers/markdown/new'; import NewMarkdown from '../../app/containers/markdown/new';
import { themes } from '../../app/lib/constants'; import { themes } from '../../app/lib/constants';
import { longText } from '../utils'; import { longText } from '../utils';
import { store } from './index';
const stories = storiesOf('NewMarkdown', module); const stories = storiesOf('NewMarkdown', module).addDecorator(story => <Provider store={store}>{story()}</Provider>);
const theme = 'light'; const theme = 'light';
@ -16,10 +18,6 @@ const styles = StyleSheet.create({
marginHorizontal: 15, marginHorizontal: 15,
backgroundColor: themes[theme].backgroundColor, backgroundColor: themes[theme].backgroundColor,
marginVertical: 50 marginVertical: 50
},
separator: {
marginHorizontal: 10,
marginVertical: 10
} }
}); });

View File

@ -1,31 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots Avatar Avatar by path 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/diego.mello?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Avatar by path 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/diego.mello?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Avatar by roomId 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/room/devWBbYr7inwupPqK?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Avatar by roomId 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/room/devWBbYr7inwupPqK?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Avatar by text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Avatar by text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Avatar by url 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://user-images.githubusercontent.com/29778115/89444446-14738480-d728-11ea-9412-75fd978d95fb.jpg\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Avatar by url 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://user-images.githubusercontent.com/29778115/89444446-14738480-d728-11ea-9412-75fd978d95fb.jpg\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Channel 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/@general?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Channel 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/@general?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Children 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"theme\\":\\"light\\",\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":24,\\"color\\":\\"#cbced1\\"},[{\\"width\\":24,\\"height\\":24,\\"textAlignVertical\\":\\"center\\"},[{\\"position\\":\\"absolute\\",\\"bottom\\":-2,\\"right\\":-2,\\"borderRadius\\":10},null]],{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}"`; exports[`Storyshots Avatar Children 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"theme\\":\\"light\\",\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":24,\\"color\\":\\"#cbced1\\"},[{\\"width\\":24,\\"height\\":24,\\"textAlignVertical\\":\\"center\\"},[{\\"position\\":\\"absolute\\",\\"bottom\\":-2,\\"right\\":-2,\\"borderRadius\\":10},null]],{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}"`;
exports[`Storyshots Avatar Custom borderRadius 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":28},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":28}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Custom borderRadius 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":28},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":28}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Custom style 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},{\\"padding\\":16}],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Custom style 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},{\\"padding\\":16}],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Direct 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/diego.mello?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Direct 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/diego.mello?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Emoji 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},[{\\"width\\":30,\\"height\\":30},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/emoji-custom/troll.jpg\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"contain\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Emoji 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},[{\\"width\\":30,\\"height\\":30},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/emoji-custom/troll.jpg\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"contain\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Static 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://user-images.githubusercontent.com/29778115/89444446-14738480-d728-11ea-9412-75fd978d95fb.jpg\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Static 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://user-images.githubusercontent.com/29778115/89444446-14738480-d728-11ea-9412-75fd978d95fb.jpg\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Touchable 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"focusable\\":true,\\"style\\":{\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}]}"`; exports[`Storyshots Avatar Touchable 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"focusable\\":true,\\"style\\":{\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}]}"`;
exports[`Storyshots Avatar With ETag 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/djorkaeff.alexandre?format=png&size=56&etag=5ag8KffJcZj9m5rCv\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar With ETag 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/djorkaeff.alexandre?format=png&size=56&etag=5ag8KffJcZj9m5rCv\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Without ETag 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/djorkaeff.alexandre?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Without ETag 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/djorkaeff.alexandre?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Wrong server 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://google.com/avatar/Avatar?format=png&size=56\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`; exports[`Storyshots Avatar Wrong server 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://google.com/avatar/Avatar?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;

File diff suppressed because one or more lines are too long

335
yarn.lock
View File

@ -2865,6 +2865,27 @@
xcode "^3.0.1" xcode "^3.0.1"
xml2js "^0.4.23" xml2js "^0.4.23"
"@expo/config-plugins@4.1.5":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-4.1.5.tgz#9d357d2cda9c095e511b51583ede8a3b76174068"
integrity sha512-RVvU40RtZt12HavuDAe+LDIq9lHj7sheOfMEHdmpJ/uTA8pgvkbc56XF6JHQD+yRr6+uhhb+JnAasGq49dsQbw==
dependencies:
"@expo/config-types" "^45.0.0"
"@expo/json-file" "8.2.36"
"@expo/plist" "0.0.18"
"@expo/sdk-runtime-versions" "^1.0.0"
"@react-native/normalize-color" "^2.0.0"
chalk "^4.1.2"
debug "^4.3.1"
find-up "~5.0.0"
getenv "^1.0.0"
glob "7.1.6"
resolve-from "^5.0.0"
semver "^7.3.5"
slash "^3.0.0"
xcode "^3.0.1"
xml2js "0.4.23"
"@expo/config-plugins@^3.0.0": "@expo/config-plugins@^3.0.0":
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-3.1.0.tgz#0752ff33c5eab21cf42034a44e79df97f0f867f8" resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-3.1.0.tgz#0752ff33c5eab21cf42034a44e79df97f0f867f8"
@ -2895,6 +2916,11 @@
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-42.0.0.tgz#3e3e125ec092c0c34dbfaf19be5480402de3d677" resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-42.0.0.tgz#3e3e125ec092c0c34dbfaf19be5480402de3d677"
integrity sha512-Rj02OMZke2MrGa/1Y/EScmR7VuWbDEHPJyvfFyyLbadUt+Yv6isCdeFzDt71I7gJlPR9T4fzixeYLrtXXOTq0w== integrity sha512-Rj02OMZke2MrGa/1Y/EScmR7VuWbDEHPJyvfFyyLbadUt+Yv6isCdeFzDt71I7gJlPR9T4fzixeYLrtXXOTq0w==
"@expo/config-types@^45.0.0":
version "45.0.0"
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-45.0.0.tgz#963c2fdce8fbcbd003758b92ed8a25375f437ef6"
integrity sha512-/QGhhLWyaGautgEyU50UJr5YqKJix5t77ePTwreOVAhmZH+ff3nrrtYTTnccx+qF08ZNQmfAyYMCD3rQfzpiJA==
"@expo/config@^4.0.0": "@expo/config@^4.0.0":
version "4.0.4" version "4.0.4"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-4.0.4.tgz#48686c2b83bc00db469e01592e396e973e91e11d" resolved "https://registry.yarnpkg.com/@expo/config/-/config-4.0.4.tgz#48686c2b83bc00db469e01592e396e973e91e11d"
@ -2915,6 +2941,23 @@
semver "7.3.2" semver "7.3.2"
slugify "^1.3.4" slugify "^1.3.4"
"@expo/config@^6.0.14":
version "6.0.24"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-6.0.24.tgz#3602da8fdfa817e290a52fb328fc8ed9d6bc61e7"
integrity sha512-OcACI1md1Yo5TQmUxxueJ/RaTlR2Mgl6KswTFOYCL1XJERF/jjAx95zhWXH+JQGdlM0yB0vqM6vB6GbUFRvLxA==
dependencies:
"@babel/code-frame" "~7.10.4"
"@expo/config-plugins" "4.1.5"
"@expo/config-types" "^45.0.0"
"@expo/json-file" "8.2.36"
getenv "^1.0.0"
glob "7.1.6"
require-from-string "^2.0.2"
resolve-from "^5.0.0"
semver "7.3.2"
slugify "^1.3.4"
sucrase "^3.20.0"
"@expo/json-file@8.2.30": "@expo/json-file@8.2.30":
version "8.2.30" version "8.2.30"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.30.tgz#bd855b6416b5c3af7e55b43f6761c1e7d2b755b0" resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.30.tgz#bd855b6416b5c3af7e55b43f6761c1e7d2b755b0"
@ -2934,6 +2977,15 @@
json5 "^1.0.1" json5 "^1.0.1"
write-file-atomic "^2.3.0" write-file-atomic "^2.3.0"
"@expo/json-file@8.2.36":
version "8.2.36"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.36.tgz#62a505cb7f30a34d097386476794680a3f7385ff"
integrity sha512-tOZfTiIFA5KmMpdW9KF7bc6CFiGjb0xnbieJhTGlHrLL+ps2G0OkqmuZ3pFEXBOMnJYUVpnSy++52LFxvpa5ZQ==
dependencies:
"@babel/code-frame" "~7.10.4"
json5 "^1.0.1"
write-file-atomic "^2.3.0"
"@expo/plist@0.0.13": "@expo/plist@0.0.13":
version "0.0.13" version "0.0.13"
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.0.13.tgz#700a48d9927aa2b0257c613e13454164e7371a96" resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.0.13.tgz#700a48d9927aa2b0257c613e13454164e7371a96"
@ -2952,6 +3004,20 @@
base64-js "^1.2.3" base64-js "^1.2.3"
xmlbuilder "^14.0.0" xmlbuilder "^14.0.0"
"@expo/plist@0.0.18":
version "0.0.18"
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.0.18.tgz#9abcde78df703a88f6d9fa1a557ee2f045d178b0"
integrity sha512-+48gRqUiz65R21CZ/IXa7RNBXgAI/uPSdvJqoN9x1hfL44DNbUoWHgHiEXTx7XelcATpDwNTz6sHLfy0iNqf+w==
dependencies:
"@xmldom/xmldom" "~0.7.0"
base64-js "^1.2.3"
xmlbuilder "^14.0.0"
"@expo/sdk-runtime-versions@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz#d7ebd21b19f1c6b0395e50d78da4416941c57f7c"
integrity sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==
"@gorhom/bottom-sheet@^4": "@gorhom/bottom-sheet@^4":
version "4.1.5" version "4.1.5"
resolved "https://registry.yarnpkg.com/@gorhom/bottom-sheet/-/bottom-sheet-4.1.5.tgz#35341d45799de28082c380db6639537b04fa0b26" resolved "https://registry.yarnpkg.com/@gorhom/bottom-sheet/-/bottom-sheet-4.1.5.tgz#35341d45799de28082c380db6639537b04fa0b26"
@ -3040,6 +3106,18 @@
jest-util "^27.0.6" jest-util "^27.0.6"
slash "^3.0.0" slash "^3.0.0"
"@jest/console@^27.5.1":
version "27.5.1"
resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba"
integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==
dependencies:
"@jest/types" "^27.5.1"
"@types/node" "*"
chalk "^4.0.0"
jest-message-util "^27.5.1"
jest-util "^27.5.1"
slash "^3.0.0"
"@jest/core@^27.0.6": "@jest/core@^27.0.6":
version "27.0.6" version "27.0.6"
resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.6.tgz#c5f642727a0b3bf0f37c4b46c675372d0978d4a1" resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.6.tgz#c5f642727a0b3bf0f37c4b46c675372d0978d4a1"
@ -3075,7 +3153,7 @@
slash "^3.0.0" slash "^3.0.0"
strip-ansi "^6.0.0" strip-ansi "^6.0.0"
"@jest/create-cache-key-function@^27.0.2": "@jest/create-cache-key-function@^27.0.1", "@jest/create-cache-key-function@^27.0.2":
version "27.5.1" version "27.5.1"
resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz#7448fae15602ea95c828f5eceed35c202a820b31" resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz#7448fae15602ea95c828f5eceed35c202a820b31"
integrity sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ== integrity sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==
@ -3189,6 +3267,16 @@
"@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-lib-coverage" "^2.0.0"
collect-v8-coverage "^1.0.0" collect-v8-coverage "^1.0.0"
"@jest/test-result@^27.5.1":
version "27.5.1"
resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb"
integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==
dependencies:
"@jest/console" "^27.5.1"
"@jest/types" "^27.5.1"
"@types/istanbul-lib-coverage" "^2.0.0"
collect-v8-coverage "^1.0.0"
"@jest/test-sequencer@^27.0.6": "@jest/test-sequencer@^27.0.6":
version "27.0.6" version "27.0.6"
resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz#80a913ed7a1130545b1cd777ff2735dd3af5d34b" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz#80a913ed7a1130545b1cd777ff2735dd3af5d34b"
@ -3221,6 +3309,27 @@
source-map "^0.6.1" source-map "^0.6.1"
write-file-atomic "2.4.1" write-file-atomic "2.4.1"
"@jest/transform@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b"
integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==
dependencies:
"@babel/core" "^7.1.0"
"@jest/types" "^26.6.2"
babel-plugin-istanbul "^6.0.0"
chalk "^4.0.0"
convert-source-map "^1.4.0"
fast-json-stable-stringify "^2.0.0"
graceful-fs "^4.2.4"
jest-haste-map "^26.6.2"
jest-regex-util "^26.0.0"
jest-util "^26.6.2"
micromatch "^4.0.2"
pirates "^4.0.1"
slash "^3.0.0"
source-map "^0.6.1"
write-file-atomic "^3.0.0"
"@jest/transform@^27.0.6": "@jest/transform@^27.0.6":
version "27.0.6" version "27.0.6"
resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.6.tgz#189ad7107413208f7600f4719f81dd2f7278cc95" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.6.tgz#189ad7107413208f7600f4719f81dd2f7278cc95"
@ -3919,6 +4028,11 @@
resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-1.0.0.tgz#c52a99d4fe01049102d47dc45d40cbde4f720ab6" resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-1.0.0.tgz#c52a99d4fe01049102d47dc45d40cbde4f720ab6"
integrity sha512-xUNRvNmCl3UGCPbbHvfyFMnpvLPoOjDCcp5bT9m2k+TF/ZBklEQwhPZlkrxRx2NhgFh1X3a5uL7mJ7ZR+8G7Qg== integrity sha512-xUNRvNmCl3UGCPbbHvfyFMnpvLPoOjDCcp5bT9m2k+TF/ZBklEQwhPZlkrxRx2NhgFh1X3a5uL7mJ7ZR+8G7Qg==
"@react-native/normalize-color@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.0.0.tgz#da955909432474a9a0fe1cbffc66576a0447f567"
integrity sha512-Wip/xsc5lw8vsBlmY2MO/gFLp3MvuZ2baBZjDeTjjndMgM0h5sxz7AZR62RDPGgstp8Np7JzjvVqVT7tpFZqsw==
"@react-native/polyfills@1.0.0": "@react-native/polyfills@1.0.0":
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-1.0.0.tgz#05bb0031533598f9458cf65a502b8df0eecae780" resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-1.0.0.tgz#05bb0031533598f9458cf65a502b8df0eecae780"
@ -4456,6 +4570,17 @@
"@types/babel__template" "*" "@types/babel__template" "*"
"@types/babel__traverse" "*" "@types/babel__traverse" "*"
"@types/babel__core@^7.1.7":
version "7.1.19"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460"
integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==
dependencies:
"@babel/parser" "^7.1.0"
"@babel/types" "^7.0.0"
"@types/babel__generator" "*"
"@types/babel__template" "*"
"@types/babel__traverse" "*"
"@types/babel__generator@*": "@types/babel__generator@*":
version "7.6.1" version "7.6.1"
resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04"
@ -5394,7 +5519,7 @@ ansi-escapes@^4.2.1:
dependencies: dependencies:
type-fest "^0.11.0" type-fest "^0.11.0"
ansi-escapes@^4.3.0: ansi-escapes@^4.3.0, ansi-escapes@^4.3.1:
version "4.3.2" version "4.3.2"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
@ -5477,6 +5602,11 @@ any-base@^1.1.0:
resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe"
integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg== integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==
anymatch@^2.0.0: anymatch@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@ -5842,6 +5972,20 @@ babel-helper-to-multiple-sequence-expressions@^0.5.0:
resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz#a3f924e3561882d42fcf48907aa98f7979a4588d" resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz#a3f924e3561882d42fcf48907aa98f7979a4588d"
integrity sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA== integrity sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA==
babel-jest@^26.6.3:
version "26.6.3"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056"
integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==
dependencies:
"@jest/transform" "^26.6.2"
"@jest/types" "^26.6.2"
"@types/babel__core" "^7.1.7"
babel-plugin-istanbul "^6.0.0"
babel-preset-jest "^26.6.2"
chalk "^4.0.0"
graceful-fs "^4.2.4"
slash "^3.0.0"
babel-jest@^27.0.6: babel-jest@^27.0.6:
version "27.0.6" version "27.0.6"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.6.tgz#e99c6e0577da2655118e3608b68761a5a69bd0d8" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.6.tgz#e99c6e0577da2655118e3608b68761a5a69bd0d8"
@ -5921,6 +6065,16 @@ babel-plugin-istanbul@^6.0.0:
istanbul-lib-instrument "^4.0.0" istanbul-lib-instrument "^4.0.0"
test-exclude "^6.0.0" test-exclude "^6.0.0"
babel-plugin-jest-hoist@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d"
integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==
dependencies:
"@babel/template" "^7.3.3"
"@babel/types" "^7.3.3"
"@types/babel__core" "^7.0.0"
"@types/babel__traverse" "^7.0.6"
babel-plugin-jest-hoist@^27.0.6: babel-plugin-jest-hoist@^27.0.6:
version "27.0.6" version "27.0.6"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz#f7c6b3d764af21cb4a2a1ab6870117dbde15b456" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz#f7c6b3d764af21cb4a2a1ab6870117dbde15b456"
@ -6170,6 +6324,14 @@ babel-preset-fbjs@^3.3.0:
"@babel/plugin-transform-template-literals" "^7.0.0" "@babel/plugin-transform-template-literals" "^7.0.0"
babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0"
babel-preset-jest@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee"
integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==
dependencies:
babel-plugin-jest-hoist "^26.6.2"
babel-preset-current-node-syntax "^1.0.0"
babel-preset-jest@^27.0.6: babel-preset-jest@^27.0.6:
version "27.0.6" version "27.0.6"
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz#909ef08e9f24a4679768be2f60a3df0856843f9d" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz#909ef08e9f24a4679768be2f60a3df0856843f9d"
@ -6959,6 +7121,11 @@ ci-info@^3.1.1:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6"
integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A== integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==
ci-info@^3.2.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.1.tgz#58331f6f472a25fe3a50a351ae3052936c2c7f32"
integrity sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@ -7243,7 +7410,7 @@ commander@^2.19.0, commander@^2.20.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^4.0.1, commander@^4.1.1: commander@^4.0.0, commander@^4.0.1, commander@^4.1.1:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
@ -9444,7 +9611,7 @@ find-up@3.0.0, find-up@^3.0.0:
dependencies: dependencies:
locate-path "^3.0.0" locate-path "^3.0.0"
find-up@5.0.0, find-up@~5.0.0: find-up@5.0.0, find-up@^5.0.0, find-up@~5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
@ -10022,7 +10189,7 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
graceful-fs@^4.1.3: graceful-fs@^4.1.3, graceful-fs@^4.2.9:
version "4.2.10" version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
@ -11328,6 +11495,21 @@ jest-environment-node@^27.0.6:
jest-mock "^27.0.6" jest-mock "^27.0.6"
jest-util "^27.0.6" jest-util "^27.0.6"
jest-expo@^45.0.1:
version "45.0.1"
resolved "https://registry.yarnpkg.com/jest-expo/-/jest-expo-45.0.1.tgz#59b26f30cb2198d7b5aa17886f08b31b38482ad1"
integrity sha512-45+QiO6FRnYgJKavhUly53NRBtld68SGAsHUGUOgL3XkAcwfDLqnaWyeWwbuqT1BjKp99lisg7Iaw5mUlB/WYw==
dependencies:
"@expo/config" "^6.0.14"
"@jest/create-cache-key-function" "^27.0.1"
babel-jest "^26.6.3"
find-up "^5.0.0"
jest-watch-select-projects "^2.0.0"
jest-watch-typeahead "0.6.4"
json5 "^2.1.0"
lodash "^4.17.19"
react-test-renderer "~17.0.2"
jest-get-type@^24.9.0: jest-get-type@^24.9.0:
version "24.9.0" version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e"
@ -11367,7 +11549,7 @@ jest-haste-map@^24.9.0:
optionalDependencies: optionalDependencies:
fsevents "^1.2.7" fsevents "^1.2.7"
jest-haste-map@^26.5.2: jest-haste-map@^26.5.2, jest-haste-map@^26.6.2:
version "26.6.2" version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa"
integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==
@ -11489,6 +11671,21 @@ jest-message-util@^27.0.6:
slash "^3.0.0" slash "^3.0.0"
stack-utils "^2.0.3" stack-utils "^2.0.3"
jest-message-util@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf"
integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==
dependencies:
"@babel/code-frame" "^7.12.13"
"@jest/types" "^27.5.1"
"@types/stack-utils" "^2.0.0"
chalk "^4.0.0"
graceful-fs "^4.2.9"
micromatch "^4.0.4"
pretty-format "^27.5.1"
slash "^3.0.0"
stack-utils "^2.0.3"
jest-mock@^24.9.0: jest-mock@^24.9.0:
version "24.9.0" version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6"
@ -11524,6 +11721,11 @@ jest-regex-util@^26.0.0:
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28"
integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==
jest-regex-util@^27.0.0:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95"
integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==
jest-regex-util@^27.0.6: jest-regex-util@^27.0.6:
version "27.0.6" version "27.0.6"
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5"
@ -11743,6 +11945,18 @@ jest-util@^27.0.6:
is-ci "^3.0.0" is-ci "^3.0.0"
picomatch "^2.2.3" picomatch "^2.2.3"
jest-util@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9"
integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==
dependencies:
"@jest/types" "^27.5.1"
"@types/node" "*"
chalk "^4.0.0"
ci-info "^3.2.0"
graceful-fs "^4.2.9"
picomatch "^2.2.3"
jest-validate@^26.5.2: jest-validate@^26.5.2:
version "26.6.2" version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec"
@ -11767,6 +11981,41 @@ jest-validate@^27.0.6:
leven "^3.1.0" leven "^3.1.0"
pretty-format "^27.0.6" pretty-format "^27.0.6"
jest-watch-select-projects@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/jest-watch-select-projects/-/jest-watch-select-projects-2.0.0.tgz#4373d7e4de862aae28b46e036b669a4c913ea867"
integrity sha512-j00nW4dXc2NiCW6znXgFLF9g8PJ0zP25cpQ1xRro/HU2GBfZQFZD0SoXnAlaoKkIY4MlfTMkKGbNXFpvCdjl1w==
dependencies:
ansi-escapes "^4.3.0"
chalk "^3.0.0"
prompts "^2.2.1"
jest-watch-typeahead@0.6.4:
version "0.6.4"
resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.6.4.tgz#ea70bf1bec34bd4f55b5b72d471b02d997899c3e"
integrity sha512-tGxriteVJqonyrDj/xZHa0E2glKMiglMLQqISLCjxLUfeueRBh9VoRF2FKQyYO2xOqrWDTg7781zUejx411ZXA==
dependencies:
ansi-escapes "^4.3.1"
chalk "^4.0.0"
jest-regex-util "^27.0.0"
jest-watcher "^27.0.0"
slash "^3.0.0"
string-length "^4.0.1"
strip-ansi "^6.0.0"
jest-watcher@^27.0.0:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2"
integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==
dependencies:
"@jest/test-result" "^27.5.1"
"@jest/types" "^27.5.1"
"@types/node" "*"
ansi-escapes "^4.2.1"
chalk "^4.0.0"
jest-util "^27.5.1"
string-length "^4.0.1"
jest-watcher@^27.0.6: jest-watcher@^27.0.6:
version "27.0.6" version "27.0.6"
resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.6.tgz#89526f7f9edf1eac4e4be989bcb6dec6b8878d9c" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.6.tgz#89526f7f9edf1eac4e4be989bcb6dec6b8878d9c"
@ -12018,6 +12267,11 @@ json5@^1.0.1:
dependencies: dependencies:
minimist "^1.2.0" minimist "^1.2.0"
json5@^2.1.0, json5@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
json5@^2.1.1: json5@^2.1.1:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
@ -12032,11 +12286,6 @@ json5@^2.1.2:
dependencies: dependencies:
minimist "^1.2.5" minimist "^1.2.5"
json5@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
jsonfile@^2.1.0: jsonfile@^2.1.0:
version "2.4.0" version "2.4.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
@ -12398,7 +12647,7 @@ lodash.truncate@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5, lodash@^4.7.0: lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5, lodash@^4.7.0:
version "4.17.21" version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@ -13212,6 +13461,15 @@ mv@~2:
ncp "~2.0.0" ncp "~2.0.0"
rimraf "~2.4.0" rimraf "~2.4.0"
mz@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
nan@^2.12.1: nan@^2.12.1:
version "2.14.1" version "2.14.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
@ -13496,7 +13754,7 @@ ob1@0.64.0:
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.64.0.tgz#f254a55a53ca395c4f9090e28a85483eac5eba19" resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.64.0.tgz#f254a55a53ca395c4f9090e28a85483eac5eba19"
integrity sha512-CO1N+5dhvy+MoAwxz8+fymEUcwsT4a+wHhrHFb02LppcJdHxgcBWviwEhUwKOD2kLMQ7ijrrzybOqpGcqEtvpQ== integrity sha512-CO1N+5dhvy+MoAwxz8+fymEUcwsT4a+wHhrHFb02LppcJdHxgcBWviwEhUwKOD2kLMQ7ijrrzybOqpGcqEtvpQ==
object-assign@^4.1.0, object-assign@^4.1.1: object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@ -14399,7 +14657,7 @@ pretty-format@^27.0.6:
ansi-styles "^5.0.0" ansi-styles "^5.0.0"
react-is "^17.0.1" react-is "^17.0.1"
pretty-format@^27.3.1: pretty-format@^27.3.1, pretty-format@^27.5.1:
version "27.5.1" version "27.5.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e"
integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==
@ -14504,7 +14762,7 @@ prompts@^2.0.1:
kleur "^3.0.3" kleur "^3.0.3"
sisteransi "^1.0.4" sisteransi "^1.0.4"
prompts@^2.4.0: prompts@^2.2.1, prompts@^2.4.0:
version "2.4.2" version "2.4.2"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==
@ -14860,7 +15118,7 @@ react-is@^16.12.0, react-is@^16.13.0, react-is@^16.13.1, react-is@^16.7.0, react
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
"react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1: "react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1, react-is@^17.0.2:
version "17.0.2" version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
@ -15350,6 +15608,16 @@ react-test-renderer@17.0.1:
react-shallow-renderer "^16.13.1" react-shallow-renderer "^16.13.1"
scheduler "^0.20.1" scheduler "^0.20.1"
react-test-renderer@~17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-17.0.2.tgz#4cd4ae5ef1ad5670fc0ef776e8cc7e1231d9866c"
integrity sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==
dependencies:
object-assign "^4.1.1"
react-is "^17.0.2"
react-shallow-renderer "^16.13.1"
scheduler "^0.20.2"
react-textarea-autosize@^7.1.0: react-textarea-autosize@^7.1.0:
version "7.1.2" version "7.1.2"
resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.2.tgz#70fdb333ef86bcca72717e25e623e90c336e2cda" resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.2.tgz#70fdb333ef86bcca72717e25e623e90c336e2cda"
@ -16043,7 +16311,7 @@ scheduler@^0.19.1:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"
scheduler@^0.20.1: scheduler@^0.20.1, scheduler@^0.20.2:
version "0.20.2" version "0.20.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
@ -17005,6 +17273,18 @@ style-loader@^1.0.0:
loader-utils "^2.0.0" loader-utils "^2.0.0"
schema-utils "^2.7.0" schema-utils "^2.7.0"
sucrase@^3.20.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.21.0.tgz#6a5affdbe716b22e4dc99c57d366ad0d216444b9"
integrity sha512-FjAhMJjDcifARI7bZej0Bi1yekjWQHoEvWIXhLPwDhC6O4iZ5PtGb86WV56riW87hzpgB13wwBKO9vKAiWu5VQ==
dependencies:
commander "^4.0.0"
glob "7.1.6"
lines-and-columns "^1.1.6"
mz "^2.7.0"
pirates "^4.0.1"
ts-interface-checker "^0.1.9"
sudo-prompt@^9.0.0: sudo-prompt@^9.0.0:
version "9.2.1" version "9.2.1"
resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.2.1.tgz#77efb84309c9ca489527a4e749f287e6bdd52afd" resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.2.1.tgz#77efb84309c9ca489527a4e749f287e6bdd52afd"
@ -17267,6 +17547,20 @@ text-table@0.2.0, text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.1"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
dependencies:
any-promise "^1.0.0"
thirty-two@^1.0.1: thirty-two@^1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/thirty-two/-/thirty-two-1.0.2.tgz#4ca2fffc02a51290d2744b9e3f557693ca6b627a" resolved "https://registry.yarnpkg.com/thirty-two/-/thirty-two-1.0.2.tgz#4ca2fffc02a51290d2744b9e3f557693ca6b627a"
@ -17436,6 +17730,11 @@ ts-dedent@^1.1.0:
resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-1.1.1.tgz#68fad040d7dbd53a90f545b450702340e17d18f3" resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-1.1.1.tgz#68fad040d7dbd53a90f545b450702340e17d18f3"
integrity sha512-UGTRZu1evMw4uTPyYF66/KFd22XiU+jMaIuHrkIHQ2GivAXVlLV0v/vHrpOuTRf9BmpNHi/SO7Vd0rLu0y57jg== integrity sha512-UGTRZu1evMw4uTPyYF66/KFd22XiU+jMaIuHrkIHQ2GivAXVlLV0v/vHrpOuTRf9BmpNHi/SO7Vd0rLu0y57jg==
ts-interface-checker@^0.1.9:
version "0.1.13"
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
ts-pnp@^1.1.2: ts-pnp@^1.1.2:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
@ -18407,7 +18706,7 @@ xml-parse-from-string@^1.0.0:
resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28"
integrity sha1-qQKekp09vN7RafPG4oI42VpdWig= integrity sha1-qQKekp09vN7RafPG4oI42VpdWig=
xml2js@^0.4.23, xml2js@^0.4.5: xml2js@0.4.23, xml2js@^0.4.23, xml2js@^0.4.5:
version "0.4.23" version "0.4.23"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==