Merge branch 'develop' into feat.troubleshooting-notification-push-quota

This commit is contained in:
GleidsonDaniel 2024-02-20 13:44:23 -03:00
commit 80d4f34c99
73 changed files with 12007 additions and 770 deletions

View File

@ -6,7 +6,7 @@ orbs:
macos: &macos
macos:
xcode: "14.2.0"
xcode: "15.2.0"
resource_class: macos.m1.medium.gen1
bash-env: &bash-env
@ -54,7 +54,6 @@ save-gems-cache: &save-gems-cache
update-fastlane-ios: &update-fastlane-ios
name: Update Fastlane
command: |
echo "ruby-2.7.7" > ~/.ruby-version
bundle install
working_directory: ios
@ -78,6 +77,27 @@ restore_cache: &restore-gradle-cache
# COMMANDS
commands:
manage-ruby:
description: "Manage ruby version"
steps:
- restore_cache:
name: Restore ruby
key: ruby-v2-{{ checksum ".ruby-version" }}
- run:
name: Install ruby
command: |
echo "ruby-2.7.7" > ~/.ruby-version
if [ -d ~/.rbenv/versions/2.7.7 ]; then
echo "Ruby already installed"
else
rbenv install 2.7.7
fi
- save_cache:
name: Save ruby cache
key: ruby-v2-{{ checksum ".ruby-version" }}
paths:
- ~/.rbenv/versions/2.7.7
manage-pods:
description: "Restore/Get/Save cache of pods libs"
steps:
@ -204,6 +224,7 @@ commands:
- checkout
- restore_cache: *restore-gems-cache
- restore_cache: *restore-npm-cache-mac
- manage-ruby
- run: *install-npm-modules
- run: *update-fastlane-ios
- manage-pods
@ -328,6 +349,7 @@ commands:
at: ios
- restore_cache: *restore-gems-cache
- restore_cache: *restore-npm-cache-mac
- manage-ruby
- run: *install-npm-modules
- run: *update-fastlane-ios
- manage-pods
@ -575,6 +597,7 @@ jobs:
- checkout
- restore_cache: *restore-gems-cache
- restore_cache: *restore-npm-cache-mac
- manage-ruby
- run: *install-npm-modules
- run: *update-fastlane-ios
- save_cache: *save-npm-cache-mac

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,6 @@
import React from 'react';
import { act, fireEvent, render, screen } from '@testing-library/react-native';
import { act, fireEvent, render, screen, userEvent } from '@testing-library/react-native';
import { Provider } from 'react-redux';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { MessageComposerContainer } from './MessageComposerContainer';
import { setPermissions } from '../../actions/permissions';
@ -27,7 +25,7 @@ const initialStoreState = () => {
initialStoreState();
const initialContext = {
rid: '',
rid: 'rid',
tmid: undefined,
sharing: false,
action: null,
@ -38,33 +36,15 @@ const initialContext = {
onRemoveQuoteMessage: jest.fn()
};
const Stack = createStackNavigator();
// const Navigation = ({ children }: { children: any }) => (
// <NavigationContainer>
// <Stack.Navigator>
// <Stack.Screen name='A' component={children} />
// </Stack.Navigator>
// </NavigationContainer>
// );
// const Content = () => (
// <MessageComposerContainer />
// )
const Render = ({ context }: { context?: Partial<IRoomContext> }) => (
<Provider store={mockedStore}>
<RoomContext.Provider value={{ ...initialContext, ...context }}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name='MessageComposer' component={MessageComposerContainer} />
</Stack.Navigator>
</NavigationContainer>
<MessageComposerContainer />
</RoomContext.Provider>
</Provider>
);
describe.skip('MessageComposer', () => {
describe('MessageComposer', () => {
test('renders correctly', () => {
render(<Render />);
expect(screen.getByTestId('message-composer-input')).toBeOnTheScreen();
@ -76,14 +56,14 @@ describe.skip('MessageComposer', () => {
test('renders correctly with audio recorder disabled', () => {
mockedStore.dispatch(addSettings({ Message_AudioRecorderEnabled: false }));
render(<Render />);
expect(screen.queryByTestId('message-composer-send-audio')).toBeNull();
expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});
test('renders correctly without audio upload permissions', () => {
mockedStore.dispatch(setPermissions({}));
render(<Render />);
expect(screen.queryByTestId('message-composer-send-audio')).toBeNull();
expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});
@ -91,7 +71,7 @@ describe.skip('MessageComposer', () => {
mockedStore.dispatch(addSettings({ Message_AudioRecorderEnabled: false }));
mockedStore.dispatch(setPermissions({}));
render(<Render />);
expect(screen.queryByTestId('message-composer-send-audio')).toBeNull();
expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});
@ -100,9 +80,9 @@ describe.skip('MessageComposer', () => {
render(<Render />);
expect(screen.getByTestId('message-composer-actions')).toBeOnTheScreen();
expect(screen.getByTestId('message-composer-send-audio')).toBeOnTheScreen();
expect(screen.queryByTestId('message-composer-open-emoji')).toBeNull();
expect(screen.queryByTestId('message-composer-open-markdown')).toBeNull();
expect(screen.queryByTestId('message-composer-mention')).toBeNull();
expect(screen.queryByTestId('message-composer-open-emoji')).not.toBeOnTheScreen();
expect(screen.queryByTestId('message-composer-open-markdown')).not.toBeOnTheScreen();
expect(screen.queryByTestId('message-composer-mention')).not.toBeOnTheScreen();
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
@ -116,238 +96,247 @@ describe.skip('MessageComposer', () => {
});
test('send message', async () => {
const user = userEvent.setup();
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
expect(screen.getByTestId('message-composer-send-audio')).toBeOnTheScreen();
await user.type(screen.getByTestId('message-composer-input'), 'test');
expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen();
expect(screen.getByTestId('message-composer-send')).toBeOnTheScreen();
await act(async () => {
await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
expect(screen.queryByTestId('message-composer-send-audio')).toBeNull();
expect(screen.getByTestId('message-composer-send')).toBeOnTheScreen();
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('test', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
test('tap actions from toolbar', async () => {
render(<Render />);
describe('Toolbar', () => {
test('tap actions', async () => {
render(<Render />);
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-actions'));
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-actions'));
});
expect(screen.toJSON()).toMatchSnapshot();
});
expect(screen.toJSON()).toMatchSnapshot();
});
test('tap emoji', async () => {
render(<Render />);
test('tap emoji', async () => {
render(<Render />);
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-open-emoji'));
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-open-emoji'));
});
expect(screen.getByTestId('message-composer-close-emoji')).toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});
expect(screen.getByTestId('message-composer-close-emoji')).toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});
// describe('Markdown', () => {
// test('tap markdown', async () => {
// render(<Render />);
describe('Markdown', () => {
test('tap markdown', async () => {
render(<Render />);
// await act(async () => {
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// });
// expect(screen.getByTestId('message-composer-close-markdown')).toBeOnTheScreen();
// expect(screen.getByTestId('message-composer-bold')).toBeOnTheScreen();
// expect(screen.getByTestId('message-composer-italic')).toBeOnTheScreen();
// expect(screen.getByTestId('message-composer-strike')).toBeOnTheScreen();
// expect(screen.getByTestId('message-composer-code')).toBeOnTheScreen();
// expect(screen.getByTestId('message-composer-code-block')).toBeOnTheScreen();
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
});
expect(screen.getByTestId('message-composer-close-markdown')).toBeOnTheScreen();
expect(screen.getByTestId('message-composer-bold')).toBeOnTheScreen();
expect(screen.getByTestId('message-composer-italic')).toBeOnTheScreen();
expect(screen.getByTestId('message-composer-strike')).toBeOnTheScreen();
expect(screen.getByTestId('message-composer-code')).toBeOnTheScreen();
expect(screen.getByTestId('message-composer-code-block')).toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});
// test('tap bold', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('tap bold', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// // await waitFor(() => fireEvent.press(screen.getByTestId('message-composer-open-markdown')), { timeout: 1000 });
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-bold'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('**', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-bold'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('**', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
// test('type test and tap bold', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('type test and tap bold', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
// nativeEvent: { selection: { start: 0, end: 4 } }
// });
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-bold'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('*test*', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
nativeEvent: { selection: { start: 0, end: 4 } }
});
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-bold'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('*test*', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
// test('tap italic', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('tap italic', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-italic'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('__', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-italic'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('__', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
// test('type test and tap italic', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('type test and tap italic', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
// nativeEvent: { selection: { start: 0, end: 4 } }
// });
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-italic'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('_test_', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
nativeEvent: { selection: { start: 0, end: 4 } }
});
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-italic'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('_test_', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
// test('tap strike', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('tap strike', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-strike'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('~~', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-strike'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('~~', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
// test('type test and tap strike', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('type test and tap strike', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
// nativeEvent: { selection: { start: 0, end: 4 } }
// });
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-strike'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('~test~', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
nativeEvent: { selection: { start: 0, end: 4 } }
});
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-strike'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('~test~', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
// test('tap code', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('tap code', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-code'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('``', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-code'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('``', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
// test('type test and tap code', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('type test and tap code', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
// nativeEvent: { selection: { start: 0, end: 4 } }
// });
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-code'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('`test`', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
nativeEvent: { selection: { start: 0, end: 4 } }
});
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-code'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('`test`', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
// test('tap code-block', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('tap code-block', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-code-block'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('``````', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-code-block'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('``````', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
// test('type test and tap code-block', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
test('type test and tap code-block', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
// await act(async () => {
// await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
// await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
// nativeEvent: { selection: { start: 0, end: 4 } }
// });
// await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
// await fireEvent.press(screen.getByTestId('message-composer-code-block'));
// await fireEvent.press(screen.getByTestId('message-composer-send'));
// });
// expect(onSendMessage).toHaveBeenCalledTimes(1);
// expect(onSendMessage).toHaveBeenCalledWith('```test```', undefined);
// expect(screen.toJSON()).toMatchSnapshot();
// });
// });
test('tap mention', async () => {
render(<Render />);
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
// await fireEvent.press(screen.getByTestId('message-composer-mention'));
await act(async () => {
await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', {
nativeEvent: { selection: { start: 0, end: 4 } }
});
await fireEvent.press(screen.getByTestId('message-composer-open-markdown'));
await fireEvent.press(screen.getByTestId('message-composer-code-block'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('```test```', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
});
test('tap mention', async () => {
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
await act(async () => {
await fireEvent(screen.getByTestId('message-composer-input'), 'focus');
await fireEvent.press(screen.getByTestId('message-composer-mention'));
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(onSendMessage).toHaveBeenCalledTimes(1);
expect(onSendMessage).toHaveBeenCalledWith('@', undefined);
expect(screen.toJSON()).toMatchSnapshot();
});
expect(screen.toJSON()).toMatchSnapshot();
});
describe('edit message', () => {
@ -362,19 +351,26 @@ describe.skip('MessageComposer', () => {
await screen.findByTestId('message-composer');
expect(screen.getByTestId('message-composer')).toHaveStyle({ backgroundColor: colors.light.statusBackgroundWarning2 });
expect(screen.getByTestId('message-composer-actions')).toBeOnTheScreen();
expect(screen.queryByTestId('message-composer-send-audio')).toBeNull();
expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen();
expect(screen.getByTestId('message-composer-cancel-edit')).toBeOnTheScreen();
});
test('cancel', async () => {
await screen.findByTestId('message-composer');
expect(screen.getByTestId('message-composer')).toHaveStyle({ backgroundColor: colors.light.statusBackgroundWarning2 });
fireEvent.press(screen.getByTestId('message-composer-cancel-edit'));
await act(async () => {
await fireEvent.press(screen.getByTestId('message-composer-cancel-edit'));
});
expect(editCancel).toHaveBeenCalledTimes(1);
expect(screen.getByTestId('message-composer-actions')).toBeOnTheScreen();
expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen();
expect(screen.getByTestId('message-composer-cancel-edit')).toBeOnTheScreen();
});
test('send', async () => {
await screen.findByTestId('message-composer');
expect(screen.getByTestId('message-composer')).toHaveStyle({ backgroundColor: colors.light.statusBackgroundWarning2 });
fireEvent.press(screen.getByTestId('message-composer-send'));
await act(async () => {
await fireEvent.press(screen.getByTestId('message-composer-send'));
});
expect(editRequest).toHaveBeenCalledTimes(1);
expect(editRequest).toHaveBeenCalledWith({ id, msg: `Message ${id}`, rid: 'rid' });
});
@ -404,34 +400,46 @@ describe.skip('MessageComposer', () => {
}));
describe('Quote', () => {
test('Adding/removing quotes', () => {
const onRemoveQuoteMessage = jest.fn();
// Render without quotes
const { rerender } = render(<Render context={{ selectedMessages: [], onRemoveQuoteMessage }} />);
expect(screen.queryByTestId('composer-quote-abc')).toBeNull();
expect(screen.queryByTestId('composer-quote-def')).toBeNull();
expect(screen.toJSON()).toMatchSnapshot();
// Add a quote
rerender(<Render context={{ action: 'quote', selectedMessages: ['abc'], onRemoveQuoteMessage }} />);
expect(screen.getByTestId('composer-quote-abc')).toBeOnTheScreen();
expect(screen.queryByTestId('composer-quote-def')).toBeNull();
expect(screen.toJSON()).toMatchSnapshot();
// Add another quote
rerender(<Render context={{ action: 'quote', selectedMessages: ['abc', 'def'], onRemoveQuoteMessage }} />);
expect(screen.getByTestId('composer-quote-abc')).toBeOnTheScreen();
expect(screen.getByTestId('composer-quote-def')).toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
// Remove a quote
fireEvent.press(screen.getByTestId('composer-quote-remove-def'));
expect(onRemoveQuoteMessage).toHaveBeenCalledTimes(1);
expect(onRemoveQuoteMessage).toHaveBeenCalledWith('def');
test('Add quote `abc`', async () => {
render(<Render context={{ action: 'quote', selectedMessages: ['abc'] }} />);
await act(async () => {
await screen.findByTestId('composer-quote-abc');
expect(screen.queryByTestId('composer-quote-abc')).toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});
});
// TODO: need to create proper mocks for getMessageById and getPermalinkMessage
// test('Send message with a quote', async () => {});
test('Add quote `def`', async () => {
render(<Render context={{ action: 'quote', selectedMessages: ['abc', 'def'] }} />);
await act(async () => {
await screen.findByTestId('composer-quote-abc');
expect(screen.queryByTestId('composer-quote-abc')).toBeOnTheScreen();
expect(screen.queryByTestId('composer-quote-def')).toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});
});
test('Remove a quote', async () => {
const onRemoveQuoteMessage = jest.fn();
render(<Render context={{ action: 'quote', selectedMessages: ['abc', 'def'], onRemoveQuoteMessage }} />);
await act(async () => {
await screen.findByTestId('composer-quote-def');
await fireEvent.press(screen.getByTestId('composer-quote-remove-def'));
});
expect(onRemoveQuoteMessage).toHaveBeenCalledTimes(1);
expect(onRemoveQuoteMessage).toHaveBeenCalledWith('def');
expect(screen.toJSON()).toMatchSnapshot();
});
});
describe('Audio', () => {
test('tap record', async () => {
render(<Render />);
expect(screen.getByTestId('message-composer-send-audio')).toBeOnTheScreen();
await act(async () => {
await fireEvent.press(screen.getByTestId('message-composer-send-audio'));
});
expect(screen.toJSON()).toMatchSnapshot();
});
});
});

View File

@ -30,6 +30,7 @@ import log from '../../lib/methods/helpers/log';
import { prepareQuoteMessage } from './helpers';
import { RecordAudio } from './components/RecordAudio';
import { useKeyboardListener } from './hooks';
import { emitter } from '../../lib/methods/helpers/emitter';
const styles = StyleSheet.create({
container: {
@ -65,8 +66,13 @@ export const MessageComposer = ({
const showEmojiKeyboard = useShowEmojiKeyboard();
const showEmojiSearchbar = useShowEmojiSearchbar();
const alsoSendThreadToChannel = useAlsoSendThreadToChannel();
const { openSearchEmojiKeyboard, closeEmojiKeyboard, closeSearchEmojiKeyboard, setTrackingViewHeight } =
useMessageComposerApi();
const {
openSearchEmojiKeyboard,
closeEmojiKeyboard,
closeSearchEmojiKeyboard,
setTrackingViewHeight,
setAlsoSendThreadToChannel
} = useMessageComposerApi();
const recordingAudio = useRecordingAudio();
useKeyboardListener(trackingViewRef);
@ -100,6 +106,10 @@ export const MessageComposer = ({
const handleSendMessage = async () => {
if (!rid) return;
if (alsoSendThreadToChannel) {
setAlsoSendThreadToChannel(false);
}
if (sharing) {
onSendMessage?.();
return;
@ -193,12 +203,12 @@ export const MessageComposer = ({
const onHeightChanged = (height: number) => {
setTrackingViewHeight(height);
emitter.emit(`setComposerHeight${tmid ? 'Thread' : ''}`, height);
};
const backgroundColor = action === 'edit' ? colors.statusBackgroundWarning2 : colors.surfaceLight;
const renderContent = () => {
console.count('[MessageComposer] renderContent');
if (recordingAudio) {
return <RecordAudio />;
}

File diff suppressed because it is too large Load Diff

View File

@ -7,16 +7,16 @@ import { RouteProp, useFocusEffect, useRoute } from '@react-navigation/native';
import I18n from '../../../i18n';
import { IAutocompleteItemProps, IComposerInput, IComposerInputProps, IInputSelection, TSetInput } from '../interfaces';
import { useAutocompleteParams, useFocused, useMessageComposerApi } from '../context';
import { loadDraftMessage, saveDraftMessage, fetchIsAllOrHere, getMentionRegexp } from '../helpers';
import { useSubscription } from '../hooks';
import { loadDraftMessage, fetchIsAllOrHere, getMentionRegexp } from '../helpers';
import { useSubscription, useAutoSaveDraft } from '../hooks';
import sharedStyles from '../../../views/Styles';
import { useTheme } from '../../../theme';
import { userTyping } from '../../../actions/room';
import { getRoomTitle } from '../../../lib/methods/helpers';
import { getRoomTitle, parseJson } from '../../../lib/methods/helpers';
import { MAX_HEIGHT, MIN_HEIGHT, NO_CANNED_RESPONSES, MARKDOWN_STYLES } from '../constants';
import database from '../../../lib/database';
import Navigation from '../../../lib/navigation/appNavigation';
import { emitter } from '../emitter';
import { emitter } from '../../../lib/methods/helpers/emitter';
import { useRoomContext } from '../../../views/RoomView/context';
import { getMessageById } from '../../../lib/database/services/Message';
import { generateTriggerId } from '../../../lib/methods';
@ -30,11 +30,12 @@ const defaultSelection: IInputSelection = { start: 0, end: 0 };
export const ComposerInput = memo(
forwardRef<IComposerInput, IComposerInputProps>(({ inputRef }, ref) => {
const { colors, theme } = useTheme();
const { rid, tmid, sharing, action, selectedMessages } = useRoomContext();
const { rid, tmid, sharing, action, selectedMessages, setQuotesAndText } = useRoomContext();
const focused = useFocused();
const { setFocused, setMicOrSend, setAutocompleteParams } = useMessageComposerApi();
const autocompleteType = useAutocompleteParams()?.type;
const textRef = React.useRef('');
const firstRender = React.useRef(false);
const selectionRef = React.useRef<IInputSelection>(defaultSelection);
const dispatch = useDispatch();
const subscription = useSubscription(rid);
@ -47,29 +48,29 @@ export const ComposerInput = memo(
const usedCannedResponse = route.params?.usedCannedResponse;
const prevAction = usePrevious(action);
useAutoSaveDraft(textRef.current);
// Draft/Canned Responses
useEffect(() => {
const setDraftMessage = async () => {
const draftMessage = await loadDraftMessage({ rid, tmid });
if (draftMessage) {
setInput(draftMessage);
const parsedDraft = parseJson(draftMessage);
if (parsedDraft?.msg || parsedDraft?.quotes) {
setQuotesAndText?.(parsedDraft.msg, parsedDraft.quotes);
} else {
setInput(draftMessage);
}
}
};
if (sharing) return;
if (usedCannedResponse) {
setInput(usedCannedResponse);
} else if (action !== 'edit') {
if (usedCannedResponse) setInput(usedCannedResponse);
if (action !== 'edit' && !firstRender.current) {
firstRender.current = true;
setDraftMessage();
}
return () => {
if (action !== 'edit') {
saveDraftMessage({ rid, tmid, draftMessage: textRef.current });
}
};
}, [action, rid, tmid, usedCannedResponse]);
}, [action, rid, tmid, usedCannedResponse, firstRender.current]);
// Edit/quote
useEffect(() => {
@ -91,7 +92,7 @@ export const ComposerInput = memo(
fetchMessageAndSetInput();
return;
}
if (action === 'quote' && selectedMessages.length === 1) {
if (action === 'quote' && selectedMessages.length) {
focus();
}
}, [action, selectedMessages]);
@ -339,7 +340,8 @@ export const ComposerInput = memo(
defaultValue=''
multiline
keyboardAppearance={theme === 'light' ? 'light' : 'dark'}
testID={`message-composer-input${tmid ? '-thread' : ''}`}
// eslint-disable-next-line no-nested-ternary
testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`}
/>
);
})

View File

@ -51,8 +51,7 @@ export const SendThreadToChannel = (): React.ReactElement | null => {
* */
if (alsoSendThreadToChannelUserPref === 'default') {
const db = database.active;
const observable = db.get('threads').query(Q.where('tmid', tmid)).observe();
const observable = db.get('threads').query(Q.where('id', tmid)).observe();
subscription.current = observable.subscribe(result => {
setAlsoSendThreadToChannel(!result.length);
});

View File

@ -3,7 +3,7 @@ import React, { ReactElement } from 'react';
import { ActionsButton, BaseButton } from '..';
import { useMessageComposerApi } from '../../context';
import { Gap } from '../Gap';
import { emitter } from '../../emitter';
import { emitter } from '../../../../lib/methods/helpers/emitter';
import { useRoomContext } from '../../../../views/RoomView/context';
export const Default = (): ReactElement | null => {

View File

@ -4,7 +4,7 @@ import { BaseButton } from '..';
import { useMessageComposerApi } from '../../context';
import { Gap } from '../Gap';
import { TMarkdownStyle } from '../../interfaces';
import { emitter } from '../../emitter';
import { emitter } from '../../../../lib/methods/helpers/emitter';
export const Markdown = (): ReactElement => {
const { setMarkdownToolbar } = useMessageComposerApi();

View File

@ -1,14 +0,0 @@
import mitt from 'mitt';
import { TMarkdownStyle } from './interfaces';
type Events = {
toolbarMention: undefined;
addMarkdown: {
style: TMarkdownStyle;
};
};
export const emitter = mitt<Events>();
emitter.on('*', (type, e) => console.log(type, e));

View File

@ -1,4 +1,5 @@
export * from './useAutocomplete';
export * from './useAutoSaveDraft';
export * from './useCanUploadFile';
export * from './useChooseMedia';
export * from './useKeyboardListener';

View File

@ -0,0 +1,35 @@
import { useCallback, useEffect, useRef } from 'react';
import { saveDraftMessage } from '../helpers';
import { useRoomContext } from '../../../views/RoomView/context';
import { useFocused } from '../context';
export const useAutoSaveDraft = (text = '') => {
const { rid, tmid, action, selectedMessages } = useRoomContext();
const focused = useFocused();
const oldText = useRef('');
const intervalRef = useRef();
const saveMessageDraft = useCallback(() => {
if (action === 'edit') return;
const draftMessage = selectedMessages?.length ? JSON.stringify({ quotes: selectedMessages, msg: text }) : text;
if (oldText.current !== draftMessage) {
oldText.current = draftMessage;
saveDraftMessage({ rid, tmid, draftMessage });
}
}, [action, rid, tmid, text, selectedMessages?.length]);
useEffect(() => {
if (focused) {
intervalRef.current = setInterval(saveMessageDraft, 3000) as any;
} else {
clearInterval(intervalRef.current);
}
return () => {
clearInterval(intervalRef.current);
saveMessageDraft();
};
}, [focused, saveMessageDraft]);
};

View File

@ -1,6 +1,5 @@
import { Alert } from 'react-native';
import DocumentPicker from 'react-native-document-picker';
import ImagePicker, { ImageOrVideo } from 'react-native-image-crop-picker';
import { IMAGE_PICKER_CONFIG, LIBRARY_PICKER_CONFIG, VIDEO_PICKER_CONFIG } from '../constants';
import { forceJpgExtension } from '../helpers';
@ -12,6 +11,7 @@ import { getThreadById } from '../../../lib/database/services/Thread';
import Navigation from '../../../lib/navigation/appNavigation';
import { useAppSelector } from '../../../lib/hooks';
import { useRoomContext } from '../../../views/RoomView/context';
import ImagePicker, { ImageOrVideo } from '../../../lib/methods/helpers/ImagePicker/ImagePicker';
export const useChooseMedia = ({
rid,
@ -23,7 +23,7 @@ export const useChooseMedia = ({
permissionToUpload: boolean;
}) => {
const { FileUpload_MediaTypeWhiteList, FileUpload_MaxFileSize } = useAppSelector(state => state.settings);
const { action, selectedMessages } = useRoomContext();
const { action, setQuotesAndText, selectedMessages, getText } = useRoomContext();
const allowList = FileUpload_MediaTypeWhiteList as string;
const maxFileSize = FileUpload_MaxFileSize as number;
const libPickerLabels = {
@ -115,6 +115,16 @@ export const useChooseMedia = ({
}
};
const startShareView = () => {
const text = getText?.() || '';
return {
selectedMessages,
text
};
};
const finishShareView = (text = '', quotes = []) => setQuotesAndText?.(text, quotes);
const openShareView = async (attachments: any) => {
if (!rid) return;
const room = await getSubscriptionByRoomId(rid);
@ -129,7 +139,8 @@ export const useChooseMedia = ({
thread,
attachments,
action,
selectedMessages
finishShareView,
startShareView
});
}
};

View File

@ -1,26 +1,37 @@
import { MutableRefObject, useEffect } from 'react';
import { Keyboard } from 'react-native';
import { useIsFocused } from '@react-navigation/native';
import { useMessageComposerApi } from '../context';
import { ITrackingView } from '../interfaces';
import { TKeyEmitterEvent, emitter } from '../../../lib/methods/helpers/emitter';
import { useRoomContext } from '../../../views/RoomView/context';
export const useKeyboardListener = (ref: MutableRefObject<ITrackingView>) => {
const { setKeyboardHeight } = useMessageComposerApi();
const { tmid } = useRoomContext();
const isFocused = useIsFocused();
useEffect(() => {
if (!isFocused) {
return;
}
const keyboardEvent: TKeyEmitterEvent = `setKeyboardHeight${tmid ? 'Thread' : ''}`;
const showListener = Keyboard.addListener('keyboardWillShow', async () => {
if (ref?.current) {
const props = await ref.current.getNativeProps();
setKeyboardHeight(props.keyboardHeight);
emitter.emit(keyboardEvent, props.keyboardHeight);
}
});
const hideListener = Keyboard.addListener('keyboardWillHide', () => {
setKeyboardHeight(0);
emitter.emit(keyboardEvent, 0);
});
return () => {
showListener.remove();
hideListener.remove();
};
}, [ref, setKeyboardHeight]);
}, [ref, setKeyboardHeight, tmid, isFocused]);
};

View File

@ -44,7 +44,7 @@ const methods: IMethods = {
keyboardType: 'numeric'
},
email: {
text: 'Verify_your_email_for_the_code_we_sent',
text: 'Enter_the_code',
keyboardType: 'numeric'
},
password: {
@ -129,7 +129,7 @@ const TwoFactor = React.memo(({ isMasterDetail }: { isMasterDetail: boolean }) =
/>
{isEmail ? (
<Text style={[styles.sendEmail, { color }]} onPress={sendEmail}>
{I18n.t('Send_me_the_code_again')}
{I18n.t('Resend_email')}
</Text>
) : null}
<View style={styles.buttonContainer}>
@ -140,7 +140,7 @@ const TwoFactor = React.memo(({ isMasterDetail }: { isMasterDetail: boolean }) =
style={styles.button}
onPress={onCancel}
/>
<Button title={I18n.t('Send')} type='primary' style={styles.button} onPress={onSubmit} testID='two-factor-send' />
<Button title={I18n.t('Verify')} type='primary' style={styles.button} onPress={onSubmit} testID='two-factor-send' />
</View>
</View>
</View>

View File

@ -1,9 +1,11 @@
import React from 'react';
import { KaTeX as KaTeXProps } from '@rocket.chat/message-parser';
import React from 'react';
import { StyleProp, ViewStyle } from 'react-native';
import Katex from 'react-native-katex';
// eslint-disable-next-line import/no-unresolved
import MathView, { MathText } from 'react-native-math-view';
import Katex from 'react-native-katex';
import { isAndroid } from '../../../lib/methods/helpers';
import { useTheme } from '../../../theme';
import { DEFAULT_MESSAGE_HEIGHT } from '../../message/utils';
@ -13,11 +15,14 @@ interface IKaTeXProps {
export const KaTeX = ({ value }: IKaTeXProps): React.ReactElement | null => {
const { colors } = useTheme();
const fixAndroidWebviewCrashStyle: StyleProp<ViewStyle> = isAndroid ? { opacity: 0.99, overflow: 'hidden' } : {};
return (
<MathView
math={value}
style={{ color: colors.bodyText }}
renderError={() => <Katex expression={value} style={{ flex: 1, height: DEFAULT_MESSAGE_HEIGHT }} />}
renderError={() => (
<Katex expression={value} style={[{ flex: 1, height: DEFAULT_MESSAGE_HEIGHT }, fixAndroidWebviewCrashStyle]} />
)}
/>
);
};

View File

@ -5,6 +5,7 @@ import { Tasks as TasksProps } from '@rocket.chat/message-parser';
import Inline from './Inline';
import styles from '../styles';
import { useTheme } from '../../../theme';
import { CustomIcon } from '../../CustomIcon';
interface ITasksProps {
value: TasksProps['value'];
@ -16,7 +17,14 @@ const TaskList = ({ value = [] }: ITasksProps) => {
<View>
{value.map(item => (
<View style={styles.row}>
<Text style={[styles.text, { color: colors.bodyText }]}>{item.status ? '- [x] ' : '- [ ] '}</Text>
<Text style={[styles.text, { color: colors.bodyText }]}>
<CustomIcon
testID={item.status ? 'task-list-checked' : 'task-list-unchecked'}
name={item.status ? 'checkbox-checked' : 'checkbox-unchecked'}
size={24}
color={colors.taskBoxColor}
/>
</Text>
<Text style={[styles.inline, { color: colors.bodyText }]}>
<Inline value={item.value} />
</Text>

View File

@ -17,8 +17,8 @@ const UnorderedList = ({ value }: IUnorderedListProps) => {
<View>
{value.map(item => (
<View style={styles.row}>
<Text style={[styles.text, styles.listPrefix, { color: themes[theme].bodyText }]}>- </Text>
<Text style={[styles.text, styles.inline, { color: themes[theme].bodyText }]}>
<Text style={[styles.text, { color: themes[theme].bodyText }]}>{'\u2022'}</Text>
<Text style={[styles.inline, { color: themes[theme].bodyText }]}>
<Inline value={item.value} />
</Text>
</View>

View File

@ -98,7 +98,7 @@ const User = React.memo(
return (
<View style={styles.container}>
<TouchableOpacity style={styles.titleContainer} onPress={onUserPress}>
<TouchableOpacity testID={`username-header-${username}`} style={styles.titleContainer} onPress={onUserPress}>
<Text style={[styles.username, { color: colors.titleText }]} numberOfLines={1}>
{textContent}
</Text>

View File

@ -331,7 +331,6 @@
"Send_audio_message": "إرسال رسالة صوتية",
"Send_crash_report": "إرسال تقرير الأعطال",
"Send_message": "إرسال الرسالة",
"Send_me_the_code_again": "أرسل الرمز مرة أخرى",
"Send_to": "إرسال إلى...",
"Sending_to": "يتم الإرسال إلى",
"Server": "سرفر",
@ -391,7 +390,6 @@
"Uses_server_configuration": "يستخدم إعداد الخادم",
"Registration_Succeeded": "تم التسجيل بنجاح",
"Verify_email_desc": "لقد أرسلنا إليك بريداً إلكترونياً لتأكيد تسجيلك. إذا لم تتلق البريد الإلكتروني قريباً، فيرجى العودة والمحاولة مرة أخرى",
"Verify_your_email_for_the_code_we_sent": "يرجى تأكيد البريد الإلكتروني عبر الرمز المرسل",
"View_Original": "عرض المحتوى الأصلي",
"Waiting_for_network": "بانتظار توفر شبكة...",
"Websocket_disabled": "تم تعطيل Websocket لهذا الخادم.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "অডিও মেসেজ পাঠান",
"Send_crash_report": "ক্র্যাশ রিপোর্ট পাঠান",
"Send_message": "মেসেজ পাঠান",
"Send_me_the_code_again": "আবার কোড পাঠান",
"Send_to": "পাঠান...",
"Sending_to": "পাঠাচ্ছি",
"Server": "ওয়ার্কস্পেস",
@ -433,7 +432,6 @@
"Uses_server_configuration": "ওয়ার্কস্পেস কনফিগারেশন ব্যবহার করে",
"Registration_Succeeded": "নিবন্ধন সফল!",
"Verify_email_desc": "আমরা আপনার নিবন্ধন নিশ্চিত করতে একটি ইমেল পাঠিয়েছি। যদি আপনি শীঘ্রই একটি ইমেল পাননি, তবে দয়া করে ফিরে এসে আবার চেষ্টা করুন।",
"Verify_your_email_for_the_code_we_sent": "আমরা পাঠায় কোডের জন্য আপনার ইমেল যাচাই করুন",
"View_Original": "মৌলিক দেখুন",
"Waiting_for_network": "নেটওয়ার্কের জন্য অপেক্ষা করছে...",
"Websocket_disabled": "এই ওয়ার্কস্পেসের জন্য ওয়েবসকেট অক্ষম রয়েছে।\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Audio-Nachricht senden",
"Send_crash_report": "Absturzbericht senden",
"Send_message": "Nachricht senden",
"Send_me_the_code_again": "Den Code neu versenden",
"Send_to": "Senden an …",
"Sending_to": "Sende an",
"Server": "Server",
@ -434,7 +433,6 @@
"Uses_server_configuration": "Nutzt Servereinstellungen",
"Registration_Succeeded": "Registrierung erfolgreich!",
"Verify_email_desc": "Wir haben Ihnen eine Email geschickt um Ihre Anmeldung zu bestätigen. Wenn Sie keine Email erhalten, versuchen Sie es später noch einmal.",
"Verify_your_email_for_the_code_we_sent": "Prüfen Sie Ihre Mails auf den Code, den wir Ihnen eben geschickt haben.",
"View_Original": "Original anzeigen",
"Waiting_for_network": "Warte auf das Netzwerk …",
"Websocket_disabled": "Websockets sind auf diesem Server nicht aktiviert.\n{{contact}}",

View File

@ -367,7 +367,6 @@
"Send_audio_message": "Send audio message",
"Send_crash_report": "Send crash report",
"Send_message": "Send message",
"Send_me_the_code_again": "Send me the code again",
"Send_to": "Send to...",
"Sending_to": "Sending to",
"Server": "Workspace",
@ -437,7 +436,6 @@
"Uses_server_configuration": "Uses workspace configuration",
"Registration_Succeeded": "Registration succeeded!",
"Verify_email_desc": "We have sent you an email to confirm your registration. If you do not receive an email shortly, please come back and try again.",
"Verify_your_email_for_the_code_we_sent": "Verify your email for the code we sent",
"View_Original": "View original",
"Waiting_for_network": "Waiting for network...",
"Websocket_disabled": "Websocket is disabled for this workspace.\n{{contact}}",
@ -829,5 +827,8 @@
"Microphone_access_needed_to_record_audio": "Microphone access needed to record audio",
"Go_to_your_device_settings_and_allow_microphone": "Go to your device settings and allow microphone access for Rocket.Chat",
"Check_again": "Check again",
"error-no-tokens-for-this-user": "There are no tokens for this user"
"error-no-tokens-for-this-user": "There are no tokens for this user",
"Enter_the_code": "Enter the code we just emailed you.",
"Resend_email": "Resend email",
"Verify": "Verify"
}

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Lähetä ääniviesti",
"Send_crash_report": "Lähetä kaatumisraportti",
"Send_message": "Lähetä viesti",
"Send_me_the_code_again": "Lähetä koodi uudelleen",
"Send_to": "Lähetä kohteeseen...",
"Sending_to": "Lähetetään kohteeseen",
"Server": "Palvelin",
@ -434,7 +433,6 @@
"Uses_server_configuration": "Käyttää palvelimen määrityksiä",
"Registration_Succeeded": "Rekisteröinti onnistui!",
"Verify_email_desc": "Lähetimme rekisteröitymisvahvistuksen sähköpostiisi. Jos et saa sähköpostia pian, yritä uudelleen.",
"Verify_your_email_for_the_code_we_sent": "Vahvista sähköpostiosoitteesi lähettämällämme koodilla",
"View_Original": "Näytä alkuperäinen",
"Waiting_for_network": "Odotetaan verkkoa...",
"Websocket_disabled": "Websocket ei ole käytössä tässä palvelimessa.\n{{contact}}",

View File

@ -340,7 +340,6 @@
"Send_audio_message": "Envoyer un message audio",
"Send_crash_report": "Envoyer un rapport de plantage",
"Send_message": "Envoyer un message",
"Send_me_the_code_again": "Envoyez-moi à nouveau le code",
"Send_to": "Envoyer à...",
"Sending_to": "Envoi à",
"Server": "Serveur",
@ -401,7 +400,6 @@
"Uses_server_configuration": "Utilise la configuration du serveur",
"Registration_Succeeded": "Inscription réussie !",
"Verify_email_desc": "Nous vous avons envoyé un e-mail pour confirmer votre inscription. Si vous ne recevez pas d'e-mail sous peu, veuillez revenir et réessayer.",
"Verify_your_email_for_the_code_we_sent": "Vérifiez votre e-mail pour le code que nous avons envoyé",
"View_Original": "Voir l'original",
"Waiting_for_network": "En attente du réseau...",
"Websocket_disabled": "Le Websocket est désactivé pour ce serveur.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "ऑडियो संदेश भेजें",
"Send_crash_report": "क्रैश रिपोर्ट भेजें",
"Send_message": "संदेश भेजें",
"Send_me_the_code_again": "मुझे कोड फिर से भेजें",
"Send_to": "भेजें को...",
"Sending_to": "भेजा जा रहा है",
"Server": "कार्यस्थान",
@ -433,7 +432,6 @@
"Uses_server_configuration": "कार्यस्थान समरूपण का उपयोग करता है",
"Registration_Succeeded": "पंजीकरण सफल हुआ!",
"Verify_email_desc": "हमने आपको आपके पंजीकरण की पुष्टि के लिए एक ईमेल भेजा है। यदि आपको शीघ्र एक ईमेल प्राप्त नहीं होता है, तो कृपया वापस आकर पुनः प्रयास करें।",
"Verify_your_email_for_the_code_we_sent": "हमने आपको भेजे गए कोड के लिए अपनी ईमेल की पुष्टि करें",
"View_Original": "मूल देखें",
"Waiting_for_network": "नेटवर्क के लिए प्रतीक्षा कर रहा है...",
"Websocket_disabled": "इस कार्यस्थान के लिए वेबसॉकेट निष्क्रिय है।\n{{संपर्क}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Hangüzenet küldése",
"Send_crash_report": "Összeomlás jelentés küldése",
"Send_message": "Üzenet küldése",
"Send_me_the_code_again": "Küldje el nekem a kódot újra",
"Send_to": "Küldje el...",
"Sending_to": "Küldés a",
"Server": "Munkaterület",
@ -434,7 +433,6 @@
"Uses_server_configuration": "Használja a munkaterület konfigurációját",
"Registration_Succeeded": "A regisztráció sikeres",
"Verify_email_desc": "Küldtünk Önnek egy e-mailt a regisztrációja megerősítéséhez. Ha nem kap rövidesen e-mailt, akkor térjen vissza, és próbálja meg újra.",
"Verify_your_email_for_the_code_we_sent": "Ellenőrizze az e-mail-címét azzal a kóddal, amit küldtünk",
"View_Original": "Eredeti megtekintése",
"Waiting_for_network": "Hálózatra várva...",
"Websocket_disabled": "A websocket ki van kapcsolva ehhez a munkaterülethez. {{contact}}",

View File

@ -345,7 +345,6 @@
"Send_audio_message": "Invia messaggio audio",
"Send_crash_report": "Invia report sui crash",
"Send_message": "Invia messaggio",
"Send_me_the_code_again": "Inviami nuovamente il codice",
"Send_to": "Invia a...",
"Sending_to": "Invio a",
"Server": "Server",
@ -405,7 +404,6 @@
"Uses_server_configuration": "Usa la configurazione del server",
"Registration_Succeeded": "Registrazione completata!",
"Verify_email_desc": "Ti abbiamo inviato una e-mail per confermare la tua registrazione. Se non la ricevi, ritorna qui e riprova",
"Verify_your_email_for_the_code_we_sent": "Controlla l'e-mail con il codice che ti abbiamo inviato",
"View_Original": "Mostra originale",
"Waiting_for_network": "In attesa di connessione ...",
"Websocket_disabled": "Websocket disabilitata per questo server.\n{{contact}}",

View File

@ -340,7 +340,6 @@
"Send_audio_message": "Audiobericht verzenden",
"Send_crash_report": "Crashrapport verzenden",
"Send_message": "Bericht verzenden",
"Send_me_the_code_again": "Stuur me de code opnieuw",
"Send_to": "Verzenden naar...",
"Sending_to": "Verzenden naar",
"Server": "Server",
@ -401,7 +400,6 @@
"Uses_server_configuration": "Gebruikt serverconfiguratie",
"Registration_Succeeded": "Registratie geslaagd!",
"Verify_email_desc": "We hebben je een e-mail gestuurd om je inschrijving te bevestigen. Als je binnenkort geen e-mail ontvangt, gelieve terug te komen en het opnieuw te proberen.",
"Verify_your_email_for_the_code_we_sent": "Verifieer je e-mail voor de code die we hebben gestuurd",
"View_Original": "Bekijk origineel",
"Waiting_for_network": "Wachten op netwerk...",
"Websocket_disabled": "Websocket is uitgeschakeld voor deze server.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Enviar mensagem de áudio",
"Send_crash_report": "Enviar relatório de erros",
"Send_message": "Enviar mensagem",
"Send_me_the_code_again": "Envie-me o código novamente",
"Send_to": "Enviar para...",
"Sending_to": "Envio para",
"Server": "Workspace",
@ -435,7 +434,6 @@
"Uses_server_configuration": "Usar configuração da workspace",
"Registration_Succeeded": "Registrado com sucesso!",
"Verify_email_desc": "Nós lhe enviamos um e-mail para confirmar o seu registro. Se você não receber um e-mail em breve, por favor retorne e tente novamente.",
"Verify_your_email_for_the_code_we_sent": "Verifique em seu e-mail o código que enviamos",
"View_Original": "Visualizar original",
"Waiting_for_network": "Aguardando rede...",
"Websocket_disabled": "Websocket está desativado para essa workspace.\n{{contact}}",
@ -790,10 +788,6 @@
"Jitsi_authentication_before_making_calls": "Jitsi pode exigir autenticação antes de fazer chamadas. Para saber mais sobre suas políticas, visite o site do Jitsi.",
"Jitsi_authentication_before_making_calls_ask_admin": "Se você acredita que há problemas com o Jitsi e sua autenticação, peça ajuda a um administrador do espaço de trabalho.",
"Continue": "Continuar",
"decline": "Recusar",
"accept": "Aceitar",
"Incoming_call_from": "Chamada recebida de",
"Call_started": "Chamada Iniciada",
"Your_push_was_sent_to_s_devices": "A sua notificação foi enviada para {{s}} dispositivos",
"Message_has_been_shared": "Menssagem foi compartilhada",
"No_channels_in_team": "Nenhum canal nesta equipe",
@ -821,5 +815,8 @@
"In_app_message_notifications": "Notificações de mensagens in-app",
"Vibrate": "Vibrar",
"Check_again": "Verificar novamente",
"error-no-tokens-for-this-user": "Não existem tokens para este usuário"
"error-no-tokens-for-this-user": "Não existem tokens para este usuário",
"Enter_the_code": "Insira o código que acabamos de enviar por e-mail.",
"Resend_email": "Reenviar e-mail",
"Verify": "Verificar"
}

View File

@ -351,7 +351,6 @@
"Send_audio_message": "Отправить аудиосообщение",
"Send_crash_report": "Отправить отчет об ошибке",
"Send_message": "Отправить сообщение",
"Send_me_the_code_again": "Отправить мне код снова",
"Send_to": "Отправить...",
"Sending_to": "Отправляется",
"Server": "Сервер",
@ -412,7 +411,6 @@
"Uses_server_configuration": "Используется конфигурация сервера",
"Registration_Succeeded": "Регистрация Успешна!",
"Verify_email_desc": "Вам был отправлен email для подтверждения регистрации. Если вы не получили этого сообщения, пожалуйста, попробуйте еще раз.",
"Verify_your_email_for_the_code_we_sent": "Проверка вашего email с помощью отправленного нами кода",
"View_Original": "Посмотреть оригинал",
"Waiting_for_network": "Ожидание сети...",
"Websocket_disabled": "Websocket отключен для этого сервера.\n{{contact}}",

View File

@ -348,7 +348,6 @@
"Send_audio_message": "Pošljite zvočno sporočilo",
"Send_crash_report": "Pošlji poročilo o sesutju",
"Send_message": "Pošlji sporočilo",
"Send_me_the_code_again": "Pošljite mi kodo še enkrat",
"Send_to": "Pošlji...",
"Sending_to": "Pošiljanje na",
"Server": "Strežnik",
@ -409,7 +408,6 @@
"Uses_server_configuration": "Uporablja konfiguracijo strežnika",
"Registration_Succeeded": "Registracija je bila uspešna",
"Verify_email_desc": "Poslali smo vam e -poštno sporočilo za potrditev vaše registracije. Če v kratkem ne prejmete e -pošte, se vrnite in poskusite znova.",
"Verify_your_email_for_the_code_we_sent": "Preverite svoj e -poštni naslov za kodo, ki smo jo poslali",
"View_Original": "Pogled original",
"Waiting_for_network": "Čakanje na omrežje ...",
"Websocket_disabled": "WebSocket je onemogočen za ta strežnik.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Skicka ljudmeddelande",
"Send_crash_report": "Skicka kraschrapport",
"Send_message": "Skicka meddelande",
"Send_me_the_code_again": "Skicka mig koden igen",
"Send_to": "Skicka till...",
"Sending_to": "Skickar till",
"Server": "Server",
@ -432,7 +431,6 @@
"Uses_server_configuration": "Använder serverkonfiguration",
"Registration_Succeeded": "Registreringen är klar.",
"Verify_email_desc": "Vi har skickat ett e-postmeddelande för att bekräfta din registrering. Om du inte får e-postmeddelandet försöker du igen.",
"Verify_your_email_for_the_code_we_sent": "Titta efter koden i din e-post",
"View_Original": "Visa original",
"Waiting_for_network": "Väntar på nätverket...",
"Websocket_disabled": "Websocket är inaktiverad för servern.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "ஒரு ஒலி செய்தியை அனுப்பு",
"Send_crash_report": "குழப்பத்தின் அறிகையை அனுப்பு",
"Send_message": "செய்தியை அனுப்பு",
"Send_me_the_code_again": "எனக்கு குறியீடுக்கு மீண்டும் அனுப்பு",
"Send_to": "அனுப்பு...",
"Sending_to": "அனுப்பினது",
"Server": "பணி இடம்",
@ -433,7 +432,6 @@
"Uses_server_configuration": "பணியில் உள்ளேயே உபயோகிக்குகின்றது",
"Registration_Succeeded": "பதிவு செய்தது வெற்றிகரமாகின்றது!",
"Verify_email_desc": "உங்களுக்கு உங்கள் பதிவுக்கு உறுதிப்படுத்த ஒரு மின்னஞ்சல் அனுப்பினோம். உங்களுக்கு விரைவில் ஒரு மின்னஞ்சல் பெறாதிருக்கின்றார்கள், தயவுசெய்து மீண்டும் வாருங்கள் மற்றும் முயற்சிக்கவும்.",
"Verify_your_email_for_the_code_we_sent": "நாங்கள் அனுப்பிய குறியீடுக்கு உங்கள் மின்னஞ்சலை சரிபார்க்கவும்",
"View_Original": "மூலத்தைக் காண்",
"Waiting_for_network": "பிணையத்தைக் காத்திருக்கின்றது...",
"Websocket_disabled": "இந்த பணியில் Websocket முடக்கப்பட்டுள்ளது.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "ఆడియో సందేశాన్ని పంపండి",
"Send_crash_report": "క్రాష్ నివేదించండి",
"Send_message": "సందేశాన్ని పంపండి",
"Send_me_the_code_again": "మళ్ళీ కోడ్‌ను పంపండి",
"Send_to": "పంపండి...",
"Sending_to": "పంపిస్తోంది",
"Server": "పనితనం",
@ -433,7 +432,6 @@
"Uses_server_configuration": "పనితనం ఆకృతి ఉపయోగిస్తుంది",
"Registration_Succeeded": "నమోదు విజయవంతంగా చేయబడింది!",
"Verify_email_desc": "మేము మీ నమోదుని ధ్యానంలోకి పెంపొందాం. మీరు తక్షణం ఒక ఇమెయిల్ పొందరాక, దయచేసి మళ్ళీ ప్రయత్నించండి.",
"Verify_your_email_for_the_code_we_sent": "మేము పంపిన కోడ్ కోసం మీ ఇమెయిల్‌ని ధ్యానంలోకి పెంచండి",
"View_Original": "అసలు చూడండి",
"Waiting_for_network": "నెట్వర్క్ కోసం వేచి ఉండి...",
"Websocket_disabled": "ఈ పనితనంలో వెబ్‌సాకెట్ నిషేధించబడింది.\n{{contact}}",

View File

@ -328,7 +328,6 @@
"Send_audio_message": "Sesli ileti gönder",
"Send_crash_report": "Çökme raporu gönder",
"Send_message": "İleti gönder",
"Send_me_the_code_again": "Kodu tekrar gönder",
"Send_to": "Gönderiliyor...",
"Sending_to": "Gönderiliyor:",
"Server": "Sunucu",
@ -388,7 +387,6 @@
"Uses_server_configuration": "Sunucu yapılandırmasını kullanır",
"Registration_Succeeded": "Kayıt Başarılı!",
"Verify_email_desc": "Kaydınızı onaylamak için size bir e-posta gönderdik. Kısa süre içinde bir e-posta almazsanız, lütfen geri gelin ve tekrar deneyin.",
"Verify_your_email_for_the_code_we_sent": "Gönderdiğimiz kod için e-postanızı doğrulayın",
"View_Original": "Orijinali Görüntüle",
"Waiting_for_network": "Ağ bağlantısı bekleniyor ...",
"Websocket_disabled": "Bu sunucu için Websocket devre dışı bırakıldı.\n{{contact}}",

View File

@ -324,7 +324,6 @@
"Send_audio_message": "发送音频信息",
"Send_crash_report": "送出当机报告",
"Send_message": "发送信息",
"Send_me_the_code_again": "再次发送代码给我",
"Send_to": "发送到",
"Sending_to": "正发送到",
"Server": "服务器",
@ -384,7 +383,6 @@
"Uses_server_configuration": "使用服务器设置",
"Registration_Succeeded": "注册成功",
"Verify_email_desc": "我们已经送出一封电子邮件,以确认您的注册。如果您没有很快收到,请再试一次。",
"Verify_your_email_for_the_code_we_sent": "检查您的电子邮件以取得我们发送的代码",
"View_Original": "检视原文",
"Waiting_for_network": "等待网路连接",
"Websocket_disabled": "Websocket 已于此伺服器上禁用。 \\n{{contact}}",

View File

@ -330,7 +330,6 @@
"Send_audio_message": "發送語音訊息",
"Send_crash_report": "送出當機報告",
"Send_message": "發送訊息",
"Send_me_the_code_again": "再次發送代碼給我",
"Send_to": "發送到",
"Sending_to": "正發送到",
"Server": "伺服器",
@ -390,7 +389,6 @@
"Uses_server_configuration": "使用伺服器設定",
"Registration_Succeeded": "註冊成功",
"Verify_email_desc": "我們已經送出一封電子郵件,以確認您的註冊。如果您沒有很快收到,請再試一次。",
"Verify_your_email_for_the_code_we_sent": "檢查您的電子郵件以取得我們發送的代碼",
"View_Original": "檢視原文",
"Waiting_for_network": "等待網路連線",
"Websocket_disabled": "Websocket 已於此伺服器上禁用。\\n{{contact}}",

View File

@ -305,6 +305,7 @@ export const colors = {
surfaceTint: '#F7F8FA',
fontDisabled: '#CBCED1',
overlayColor: '#1F2329CC',
taskBoxColor: '#9297a2',
...mentions,
...callButtons
},
@ -402,6 +403,7 @@ export const colors = {
surfaceTint: '#1F2329',
fontDisabled: '#60646C',
overlayColor: '#1F2329CC',
taskBoxColor: '#9297a2',
...mentions,
...callButtons
},
@ -499,6 +501,7 @@ export const colors = {
surfaceTint: '#1F2329',
fontDisabled: '#60646C',
overlayColor: '#1F2329CC',
taskBoxColor: '#9297a2',
...mentions,
...callButtons
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
import ImagePicker, { Image as ImageInterface, ImageOrVideo as ImageOrVideoType } from 'react-native-image-crop-picker';
export type Image = ImageInterface;
export type ImageOrVideo = ImageOrVideoType;
export default ImagePicker;

View File

@ -0,0 +1,20 @@
import mitt from 'mitt';
import { TMarkdownStyle } from '../../../containers/MessageComposer/interfaces';
export type TEmitterEvents = {
toolbarMention: undefined;
addMarkdown: {
style: TMarkdownStyle;
};
setKeyboardHeight: number;
setKeyboardHeightThread: number;
setComposerHeight: number;
setComposerHeightThread: number;
};
export type TKeyEmitterEvent = keyof TEmitterEvents;
export const emitter = mitt<TEmitterEvents>();
emitter.on('*', (type, e) => console.log(type, e));

View File

@ -42,6 +42,9 @@ class EventEmitter {
}
}
/**
* @deprecated use lib/methods/helpers/emitter.ts
*/
emit(event: string, ...args: TEventEmitterEmmitArgs[]) {
if (typeof this.events[event] === 'object') {
this.events[event].forEach((listener: Function) => {

View File

@ -16,3 +16,5 @@ export * from './isValidEmail';
export * from './random';
export * from './image';
export * from './askAndroidMediaPermissions';
export * from './emitter';
export * from './parseJson';

View File

@ -0,0 +1,7 @@
export const parseJson = (json: string) => {
try {
return JSON.parse(json);
} catch (ex) {
return json;
}
};

View File

@ -7,7 +7,7 @@ export interface IInAppFeedbackState {
export const initialState: IInAppFeedbackState = {};
export default function activeUsers(state = initialState, action: TApplicationActions): IInAppFeedbackState {
export default function inAppFeedback(state = initialState, action: TApplicationActions): IInAppFeedbackState {
switch (action.type) {
case IN_APP_FEEDBACK.SET:
const { msgId } = action;

View File

@ -277,7 +277,8 @@ export type InsideStackParamList = {
room: TSubscriptionModel;
thread: TThreadModel;
action: TMessageAction;
selectedMessages: string[];
finishShareView: (text?: string, selectedMessages?: string[]) => void | undefined;
startShareView: () => { text: string; selectedMessages: string[] };
};
ModalBlockView: {
data: any; // TODO: Change;

View File

@ -25,7 +25,7 @@ import { IAvatar } from '../../definitions';
import AvatarSuggestion from './AvatarSuggestion';
import log from '../../lib/methods/helpers/log';
import { changeRoomsAvatar, changeUserAvatar, resetUserAvatar } from './submitServices';
import ImagePicker, { Image } from './ImagePicker';
import ImagePicker, { Image } from '../../lib/methods/helpers/ImagePicker/ImagePicker';
enum AvatarStateActions {
CHANGE_AVATAR = 'CHANGE_AVATAR',

View File

@ -159,7 +159,7 @@ const RoomInfoView = (): React.ReactElement => {
const loadUser = async () => {
if (isEmpty(roomUser)) {
try {
const roomUserId = getUidDirectMessage(room || { rid, t, itsMe });
const roomUserId = getUidDirectMessage({ ...(room || { rid, t }), itsMe });
const result = await Services.getUserInfo(roomUserId);
if (result.success) {
const { user } = result;

View File

@ -1,14 +1,16 @@
import React from 'react';
import { StyleSheet, View, Platform } from 'react-native';
import React, { memo } from 'react';
import { StyleSheet, View } from 'react-native';
import { CustomIcon } from '../../../../containers/CustomIcon';
import { useTheme } from '../../../../theme';
import Touch from '../../../../containers/Touch';
import { useNavBottomStyle } from '../hooks';
import { EDGE_DISTANCE } from '../constants';
const styles = StyleSheet.create({
container: {
position: 'absolute',
right: 15
right: EDGE_DISTANCE
},
button: {
borderRadius: 25
@ -23,46 +25,25 @@ const styles = StyleSheet.create({
}
});
const NavBottomFAB = ({
visible,
onPress,
isThread
}: {
visible: boolean;
onPress: Function;
isThread: boolean;
}): React.ReactElement | null => {
const { colors } = useTheme();
const NavBottomFAB = memo(
({ visible, onPress, isThread }: { visible: boolean; onPress: Function; isThread: boolean }): React.ReactElement | null => {
const { colors } = useTheme();
const positionStyle = useNavBottomStyle(isThread);
if (!visible) {
return null;
if (!visible) {
return null;
}
return (
<View style={[styles.container, positionStyle]} testID='nav-jump-to-bottom'>
<Touch onPress={() => onPress()} style={[styles.button, { backgroundColor: colors.backgroundColor }]}>
<View style={[styles.content, { borderColor: colors.borderColor }]}>
<CustomIcon name='chevron-down' color={colors.auxiliaryTintColor} size={36} />
</View>
</Touch>
</View>
);
}
return (
<View
style={[
styles.container,
{
...Platform.select({
ios: {
bottom: 100 + (isThread ? 40 : 0)
},
android: {
top: 15,
scaleY: -1
}
})
}
]}
testID='nav-jump-to-bottom'
>
<Touch onPress={() => onPress()} style={[styles.button, { backgroundColor: colors.backgroundColor }]}>
<View style={[styles.content, { borderColor: colors.borderColor }]}>
<CustomIcon name='chevron-down' color={colors.auxiliaryTintColor} size={36} />
</View>
</Touch>
</View>
);
};
);
export default NavBottomFAB;

View File

@ -5,3 +5,5 @@ export const VIEWABILITY_CONFIG = {
};
export const SCROLL_LIMIT = 200;
export const EDGE_DISTANCE = 15;

View File

@ -1,2 +1,3 @@
export * from './useNavBottomStyle';
export * from './useMessages';
export * from './useScroll';

View File

@ -0,0 +1 @@
export * from './useNavBottomStyle';

View File

@ -0,0 +1,8 @@
import { ViewStyle } from 'react-native';
import { EDGE_DISTANCE } from '../../constants';
export const useNavBottomStyle = (): ViewStyle => ({
top: EDGE_DISTANCE,
scaleY: -1
});

View File

@ -0,0 +1,36 @@
import { useEffect, useState } from 'react';
import { ViewStyle } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { TKeyEmitterEvent, emitter } from '../../../../../lib/methods/helpers';
import { EDGE_DISTANCE } from '../../constants';
export const useNavBottomStyle = (isThread: boolean): ViewStyle => {
const [keyboardHeight, setKeyboardHeight] = useState(0);
const [composerHeight, setComposerHeight] = useState(0);
const { bottom } = useSafeAreaInsets();
useEffect(() => {
const keyboardEvent: TKeyEmitterEvent = `setKeyboardHeight${isThread ? 'Thread' : ''}`;
const composerEvent: TKeyEmitterEvent = `setComposerHeight${isThread ? 'Thread' : ''}`;
emitter.on(keyboardEvent, height => {
if (height !== keyboardHeight) {
setKeyboardHeight(height);
}
});
emitter.on(composerEvent, height => {
if (height !== composerHeight) {
setComposerHeight(height);
}
});
return () => {
emitter.off(keyboardEvent);
emitter.off(composerEvent);
};
}, [isThread, keyboardHeight, composerHeight]);
return {
bottom: keyboardHeight + composerHeight + (keyboardHeight ? 0 : bottom) + EDGE_DISTANCE
};
};

View File

@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { ViewToken, ViewabilityConfigCallbackPairs } from 'react-native';
import { IListContainerRef, IListProps, TListRef, TMessagesIdsRef } from '../definitions';
@ -20,9 +20,9 @@ export const useScroll = ({ listRef, messagesIds }: { listRef: TListRef; message
[]
);
const jumpToBottom = () => {
const jumpToBottom = useCallback(() => {
listRef.current?.scrollToOffset({ offset: -100 });
};
}, [listRef]);
const onViewableItemsChanged: IListProps['onViewableItemsChanged'] = ({ viewableItems: vi }) => {
viewableItems.current = vi;

View File

@ -9,11 +9,12 @@ export interface IRoomContext {
sharing?: boolean;
action?: TMessageAction;
selectedMessages: string[];
editCancel?: () => void;
editRequest?: (message: any) => void;
onRemoveQuoteMessage?: (messageId: string) => void;
onSendMessage?: Function;
setQuotesAndText?: (text: string, quotes: string[]) => void;
getText?: () => string | undefined;
}
export const RoomContext = createContext<IRoomContext>({} as IRoomContext);

View File

@ -687,7 +687,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
onEditInit = (messageId: string) => {
const { action } = this.state;
// TODO: implement multiple actions running. Quoting, then edit. Edit then quote.
if (action) {
return;
}
@ -736,7 +735,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}
return;
}
// TODO: implement multiple actions running. Quoting, then edit. Edit then quote.
if (action) {
return;
}
@ -773,7 +771,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
};
onReactionInit = (messageId: string) => {
// TODO: implement multiple actions running. Quoting, then edit. Edit then quote.
if (this.state.action) {
return;
}
@ -790,7 +787,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
onMessageLongPress = (message: TAnyMessageModel) => {
const { action } = this.state;
// TODO: implement multiple actions running. Quoting, then edit. Edit then quote.
if (action && action !== 'quote') {
return;
}
@ -1250,6 +1246,17 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}
};
setQuotesAndText = (text: string, quotes: string[]) => {
if (quotes.length) {
this.setState({ selectedMessages: quotes, action: 'quote' });
} else {
this.setState({ action: null, selectedMessages: [] });
}
this.messageComposerRef.current?.setInput(text || '');
};
getText = () => this.messageComposerRef.current?.getText();
renderItem = (item: TAnyMessageModel, previousItem: TAnyMessageModel, highlightedMessage?: string) => {
const { room, lastOpen, canAutoTranslate } = this.state;
const {
@ -1454,7 +1461,9 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
onRemoveQuoteMessage: this.onRemoveQuoteMessage,
editCancel: this.onEditCancel,
editRequest: this.onEditRequest,
onSendMessage: this.handleSendMessage
onSendMessage: this.handleSendMessage,
setQuotesAndText: this.setQuotesAndText,
getText: this.getText
}}
>
<SafeAreaView style={{ backgroundColor: themes[theme].backgroundColor }} testID='room-view'>

View File

@ -23,7 +23,15 @@ import Thumbs from './Thumbs';
import Preview from './Preview';
import Header from './Header';
import styles from './styles';
import { IApplicationState, IServer, IShareAttachment, IUser, TSubscriptionModel, TThreadModel } from '../../definitions';
import {
IApplicationState,
IServer,
IShareAttachment,
IUser,
TMessageAction,
TSubscriptionModel,
TThreadModel
} from '../../definitions';
import { sendFileMessage, sendMessage } from '../../lib/methods';
import { hasPermission, isAndroid, canUploadFile, isReadOnly, isBlocked } from '../../lib/methods/helpers';
import { RoomContext } from '../RoomView/context';
@ -38,6 +46,8 @@ interface IShareViewState {
thread: TThreadModel;
maxFileSize?: number;
mediaAllowList?: string;
selectedMessages: string[];
action: TMessageAction;
}
interface IShareViewProps {
@ -59,7 +69,8 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
private files: any[];
private isShareExtension: boolean;
private serverInfo: IServer;
private closeReply?: Function;
private finishShareView: (text?: string, selectedMessages?: string[]) => void;
private sentMessage: boolean;
constructor(props: IShareViewProps) {
super(props);
@ -67,6 +78,8 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
this.files = props.route.params?.attachments ?? [];
this.isShareExtension = props.route.params?.isShareExtension;
this.serverInfo = props.route.params?.serverInfo ?? {};
this.finishShareView = props.route.params?.finishShareView;
this.sentMessage = false;
this.state = {
selected: {} as IShareAttachment,
@ -77,7 +90,11 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
room: props.route.params?.room ?? {},
thread: props.route.params?.thread ?? {},
maxFileSize: this.isShareExtension ? this.serverInfo?.FileUpload_MaxFileSize : props.FileUpload_MaxFileSize,
mediaAllowList: this.isShareExtension ? this.serverInfo?.FileUpload_MediaTypeWhiteList : props.FileUpload_MediaTypeWhiteList
mediaAllowList: this.isShareExtension
? this.serverInfo?.FileUpload_MediaTypeWhiteList
: props.FileUpload_MediaTypeWhiteList,
selectedMessages: [],
action: props.route.params?.action
};
this.getServerInfo();
}
@ -86,16 +103,15 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
const readOnly = await this.getReadOnly();
const { attachments, selected } = await this.getAttachments();
this.setState({ readOnly, attachments, selected }, () => this.setHeader());
this.startShareView();
};
componentWillUnmount = () => {
console.countReset(`${this.constructor.name}.render calls`);
// close reply from the RoomView
setTimeout(() => {
if (this.closeReply) {
this.closeReply();
}
}, 300);
if (this.finishShareView && !this.sentMessage) {
const text = this.messageComposerRef.current?.getText();
this.finishShareView(text, this.state.selectedMessages);
}
};
setHeader = () => {
@ -110,7 +126,7 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
// if is share extension show default back button
if (!this.isShareExtension) {
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} color={themes[theme].previewTintColor} />;
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} color={themes[theme].previewTintColor} testID='share-view-close' />;
}
if (!attachments.length && !readOnly) {
@ -196,21 +212,23 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
};
};
send = async () => {
const { loading, selected } = this.state;
if (loading) {
return;
startShareView = () => {
const startShareView = this.props.route.params?.startShareView;
if (startShareView) {
const { selectedMessages, text } = startShareView();
this.messageComposerRef.current?.setInput(text);
this.setState({ selectedMessages });
}
};
send = async () => {
if (this.state.loading) return;
const { attachments, room, text, thread, action, selected, selectedMessages } = this.state;
const { navigation, server, user } = this.props;
// update state
await this.selectFile(selected);
const { attachments, room, text, thread } = this.state;
const { navigation, server, user, route } = this.props;
const action = route.params?.action;
const selectedMessages = route.params?.selectedMessages ?? [];
// if it's share extension this should show loading
if (this.isShareExtension) {
this.setState({ loading: true });
@ -218,6 +236,8 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
// if it's not share extension this can close
} else {
this.sentMessage = true;
this.finishShareView('', []);
navigation.pop();
}
@ -257,7 +277,10 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
await sendMessage(room.rid, text, thread?.id, { id: user.id, token: user.token } as IUser);
}
} catch {
// Do nothing
if (!this.isShareExtension) {
const text = this.messageComposerRef.current?.getText();
this.finishShareView(text, this.state.selectedMessages);
}
}
// if it's share extension this should close
@ -303,8 +326,14 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
this.setState({ text });
};
onRemoveQuoteMessage = (messageId: string) => {
const { selectedMessages } = this.state;
const newSelectedMessages = selectedMessages.filter(item => item !== messageId);
this.setState({ selectedMessages: newSelectedMessages, action: newSelectedMessages.length ? 'quote' : null });
};
renderContent = () => {
const { attachments, selected, text, room, thread } = this.state;
const { attachments, selected, text, room, thread, selectedMessages } = this.state;
const { theme, route } = this.props;
if (attachments.length) {
@ -316,8 +345,9 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
tmid: thread.id,
sharing: true,
action: route.params?.action,
selectedMessages: route.params?.selectedMessages,
onSendMessage: this.send
selectedMessages,
onSendMessage: this.send,
onRemoveQuoteMessage: this.onRemoveQuoteMessage
}}
>
<View style={styles.container}>

View File

@ -7,7 +7,8 @@ const defaultTextStyle: TextStyle = {
backgroundColor: 'transparent',
...Platform.select({
android: {
includeFontPadding: false
includeFontPadding: false,
alignSelf: 'stretch'
}
})
};

View File

@ -143,6 +143,20 @@ async function navigateToRoom(room: string) {
await checkRoomTitle(room);
}
async function navigateToRecentRoom(room: string) {
await waitFor(element(by.id('rooms-list-view')))
.toExist()
.withTimeout(10000);
await tapAndWaitFor(element(by.id('rooms-list-view-search')), element(by.id('rooms-list-view-search-input')), 5000);
await waitFor(element(by.id(`rooms-list-view-item-${room}`)))
.toBeVisible()
.withTimeout(10000);
await element(by.id(`rooms-list-view-item-${room}`)).tap();
await waitFor(element(by.id(`room-view-title-${room}`)))
.toBeVisible()
.withTimeout(10000);
}
async function tryTapping(
theElement: Detox.IndexableNativeElement | Detox.NativeElement,
timeout: number,
@ -261,5 +275,6 @@ export {
checkServer,
platformTypes,
expectValidRegisterOrRetry,
jumpToQuotedMessage
jumpToQuotedMessage,
navigateToRecentRoom
};

View File

@ -22,7 +22,7 @@ import random from '../../helpers/random';
const DEEPLINK_METHODS = { AUTH: 'auth', ROOM: 'room' };
let amp = '&';
const amp = '&';
const getDeepLink = (method: string, server: string, params?: string) => {
const deeplink = `rocketchat://${method}?host=${server.replace(/^(http:\/\/|https:\/\/)/, '')}${amp}${params}`;
@ -47,7 +47,6 @@ describe('Deep linking', () => {
const loginResult = await login(user.username, user.password);
({ userId, authToken } = loginResult);
const deviceType = device.getPlatform();
amp = deviceType === 'android' ? '\\&' : '&';
({ textMatcher } = platformTypes[deviceType]);
// create a thread with api
const result = await sendMessage(user, room, threadMessage);

View File

@ -5,21 +5,15 @@ import {
login,
tapBack,
sleep,
searchRoom,
tryTapping,
platformTypes,
TTextMatcher,
mockMessage
mockMessage,
navigateToRoom,
navigateToRecentRoom
} from '../../helpers/app';
import { createRandomRoom, createRandomUser, ITestUser, sendMessage } from '../../helpers/data_setup';
async function navigateToRoom(roomName: string) {
await searchRoom(`${roomName}`);
await element(by.id(`rooms-list-view-item-${roomName}`)).tap();
await waitFor(element(by.id('room-view')))
.toBeVisible()
.withTimeout(5000);
}
import { createRandomRoom, createRandomUser, deleteCreatedUsers, ITestUser, sendMessage } from '../../helpers/data_setup';
import data from '../../data';
describe('Room screen', () => {
let room: string;
@ -244,6 +238,39 @@ describe('Room screen', () => {
await element(by.id('action-sheet-handle')).swipe('down', 'fast', 0.5);
});
it('should open the profile view tapping on his username', async () => {
const { username } = user;
await waitFor(element(by.id(`username-header-${username}`)))
.toExist()
.withTimeout(2000);
await element(by.id(`username-header-${username}`)).tap();
await waitFor(element(by.id('room-info-view-username')))
.toExist()
.withTimeout(2000);
await waitFor(element(by[textMatcher](`@${username}`)))
.toExist()
.withTimeout(2000);
await tapBack();
});
it('should open the profile view tapping on other username', async () => {
const otherUser = await createRandomUser();
const { username } = otherUser;
await sendMessage(otherUser, room, 'new message');
await waitFor(element(by.id(`username-header-${username}`)))
.toExist()
.withTimeout(2000);
await element(by.id(`username-header-${username}`)).tap();
await waitFor(element(by.id('room-info-view-username')))
.toExist()
.withTimeout(2000);
await waitFor(element(by[textMatcher](`@${username}`)))
.toExist()
.withTimeout(2000);
await tapBack();
await deleteCreatedUsers([{ server: data.server, username }]);
});
it('should edit message', async () => {
const editMessage = await mockMessage('edit');
const editedMessage = `${editMessage}ed`;
@ -371,6 +398,103 @@ describe('Room screen', () => {
.toExist()
.withTimeout(60000);
await element(by[textMatcher](replyMessage)).atIndex(0).tap();
await tapBack();
});
it('should save message and quote draft correctly', async () => {
const newUser = await createRandomUser();
const { name: draftRoom } = await createRandomRoom(newUser, 'c');
const draftMessage = 'draft';
const originalMessage = '123';
const quoteMessage = '123456';
await sendMessage(newUser, draftRoom, originalMessage);
await waitFor(element(by.id('rooms-list-view')))
.toBeVisible()
.withTimeout(5000);
await navigateToRoom(draftRoom);
await waitFor(element(by[textMatcher](originalMessage)).atIndex(0))
.toBeVisible()
.withTimeout(10000);
await element(by.id('room-view-join-button')).tap();
await waitFor(element(by.id('room-view-join-button')))
.not.toBeVisible()
.withTimeout(10000);
// add draft
await element(by.id('message-composer-input')).typeText(draftMessage);
await tapBack();
await navigateToRecentRoom(draftRoom);
await sleep(500); // wait for animation
await expect(element(by.id('message-composer-input'))).toHaveText(draftMessage);
// add quote to draft
await tryTapping(element(by[textMatcher](originalMessage)).atIndex(0), 2000, true);
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(5000);
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
await element(by[textMatcher]('Quote')).atIndex(0).tap();
await waitFor(element(by.id(`markdown-preview-${originalMessage}`)))
.toBeVisible()
.withTimeout(10000);
await tapBack();
await navigateToRecentRoom(draftRoom);
await sleep(500); // wait for animation
await waitFor(element(by.id(`markdown-preview-${originalMessage}`)))
.toBeVisible()
.withTimeout(10000);
// edit draft with quote
await element(by.id('message-composer-input')).replaceText(quoteMessage);
await tapBack();
await navigateToRecentRoom(draftRoom);
await sleep(500); // wait for animation
await expect(element(by.id('message-composer-input'))).toHaveText(quoteMessage);
// send message
await waitFor(element(by.id('message-composer-send')))
.toExist()
.withTimeout(5000);
await element(by.id('message-composer-send')).tap();
await waitFor(element(by.id(`reply-${newUser.name}-${originalMessage}`).withDescendant(by[textMatcher](originalMessage))))
.toBeVisible()
.withTimeout(5000);
await expect(element(by.id('message-composer-input'))).toHaveText('');
});
it('should edit message on shareview and after close the text needs to be changed on roomView', async () => {
const draftShareMessage = 'draftShare';
const originalMessage = '123';
await element(by.id('message-composer-input')).typeText(draftShareMessage);
await element(by.id('message-composer-actions')).tap();
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(2000);
await element(by[textMatcher]('Choose from library')).atIndex(0).tap();
await sleep(300); // wait for animation
await waitFor(element(by.id('message-composer-input-share')))
.toHaveText(draftShareMessage)
.withTimeout(2000);
await element(by.id('message-composer-input-share')).replaceText(draftShareMessage + originalMessage);
await element(by.id('share-view-close')).tap();
await sleep(500); // wait for animation
await waitFor(element(by.id('message-composer-input')))
.toHaveText(draftShareMessage + originalMessage)
.withTimeout(2000);
// add quote to draft
await tryTapping(element(by[textMatcher](originalMessage)).atIndex(0), 2000, true);
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(2000);
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
await element(by[textMatcher]('Quote')).atIndex(0).tap();
await element(by.id('message-composer-actions')).tap();
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(2000);
await element(by[textMatcher]('Choose from library')).atIndex(0).tap();
await sleep(500); // wait for animation
await waitFor(element(by.id(`markdown-preview-${originalMessage}`)).atIndex(0))
.toExist()
.withTimeout(20000);
});
});
});

View File

@ -1,5 +1,6 @@
source "https://rubygems.org"
gem 'fastlane'
gem "cocoapods"
gem "cocoapods-patch"
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)

View File

@ -64,6 +64,8 @@ GEM
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.5)
cocoapods-downloader (1.6.3)
cocoapods-patch (1.0.2)
cocoapods (~> 1.11.0)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.1)
@ -280,6 +282,7 @@ PLATFORMS
DEPENDENCIES
cocoapods
cocoapods-patch
fastlane
fastlane-plugin-bugsnag

View File

@ -2,6 +2,8 @@ require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
plugin 'cocoapods-patch'
platform :ios, '12.0'
install! 'cocoapods', :deterministic_uuids => false

View File

@ -993,6 +993,6 @@ SPEC CHECKSUMS:
WatermelonDB: 577c61fceff16e9f9103b59d14aee4850c0307b6
Yoga: 0bc4b37c3b8a345336ff601e2cf7d9704bab7e93
PODFILE CHECKSUM: 0dc489a0c4bec783a132693070c2d02e2ca6b0db
PODFILE CHECKSUM: 64d42395bfd44083a3a28acf1ade8637a43b275e
COCOAPODS: 1.11.3

View File

@ -0,0 +1,13 @@
diff --git a/cocoapods-patch-20240202-23940-12mtcm3/boost/boost/container_hash/hash.hpp b/Pods/boost/boost/container_hash/hash.hpp
index 6059fee19..b665976de 100644
--- a/cocoapods-patch-20240202-23940-12mtcm3/boost/boost/container_hash/hash.hpp
+++ b/Pods/boost/boost/container_hash/hash.hpp
@@ -128,7 +128,7 @@ namespace boost
};
#else
template <typename T>
- struct hash_base : std::unary_function<T, std::size_t> {};
+ struct hash_base : std::__unary_function<T, std::size_t> {};
#endif
struct enable_hash_value { typedef std::size_t type; };

View File

@ -1,6 +1,5 @@
import React from 'react';
import '@testing-library/react-native/extend-expect';
import '@testing-library/jest-native/legacy-extend-expect';
import mockClipboard from '@react-native-clipboard/clipboard/jest/clipboard-mock.js';
import mockAsyncStorage from '@react-native-async-storage/async-storage/jest/async-storage-mock';
@ -17,6 +16,10 @@ jest.mock('react-native-safe-area-context', () => {
};
});
jest.mock('./node_modules/react-native/Libraries/Interaction/InteractionManager', () => ({
runAfterInteractions: callback => callback()
}));
// @ts-ignore
global.__reanimatedWorkletInit = () => {};
jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));
@ -41,6 +44,24 @@ jest.mock('react-native-file-viewer', () => ({
jest.mock('expo-haptics', () => jest.fn(() => null));
jest.mock('expo-av', () => ({
...jest.requireActual('expo-av'),
Audio: {
...jest.requireActual('expo-av').Audio,
getPermissionsAsync: jest.fn(() => ({ status: 'granted', granted: true, canAskAgain: true })),
Recording: jest.fn(() => ({
prepareToRecordAsync: jest.fn(),
startAsync: jest.fn(),
stopAndUnloadAsync: jest.fn(),
setOnRecordingStatusUpdate: jest.fn()
}))
}
}));
jest.mock('./app/lib/methods/search', () => ({
search: () => []
}));
jest.mock('./app/lib/database', () => jest.fn(() => null));
jest.mock('./app/containers/MessageComposer/components/EmojiKeyboard', () => jest.fn(() => null));
@ -60,20 +81,24 @@ jest.mock('./app/lib/database/services/Message', () => ({
})
}));
const mockedNavigate = jest.fn();
jest.mock('@react-navigation/native', () => ({
...jest.requireActual('@react-navigation/native'),
useNavigation: () => ({
jest.mock('@react-navigation/native', () => {
const actualNav = jest.requireActual('@react-navigation/native');
const { useEffect } = require('react');
return {
...actualNav,
useFocusEffect: useEffect,
isFocused: () => true,
useIsFocused: () => true,
useRoute: () => jest.fn(),
useNavigation: () => ({
navigate: jest.fn(),
addListener: () => jest.fn()
}),
createNavigationContainerRef: jest.fn(),
navigate: jest.fn(),
addListener: jest.fn().mockImplementation((event, callback) => {
callback();
return {
remove: jest.fn()
};
})
})
}));
addListener: jest.fn(() => jest.fn())
};
});
jest.mock('react-native-notifications', () => ({
Notifications: {

View File

@ -84,7 +84,7 @@
"prop-types": "15.7.2",
"react": "17.0.2",
"react-hook-form": "^7.34.2",
"react-native": "RocketChat/react-native#6cf729c196f0f043ac6e7444e73f5a560d7a8a8a",
"react-native": "RocketChat/react-native#1b987e4ae3d5e912fda77da5215912ec15f14327",
"react-native-animatable": "^1.3.3",
"react-native-background-timer": "2.4.1",
"react-native-bootsplash": "^4.3.3",
@ -165,9 +165,8 @@
"@storybook/addon-storyshots": "6.3",
"@storybook/react": "6.3",
"@storybook/react-native": "^6.0.1-beta.7",
"@testing-library/jest-native": "^5.4.2",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/react-native": "^12.4.1",
"@testing-library/react-native": "^12.4.3",
"@types/bytebuffer": "^5.0.44",
"@types/ejson": "^2.1.3",
"@types/i18n-js": "^3.8.3",
@ -192,7 +191,7 @@
"babel-loader": "8.3.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"codecov": "^3.8.3",
"detox": "20.11.0",
"detox": "20.17.1",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "2.26.0",
@ -224,7 +223,7 @@
"node_modules"
],
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?@?react-native|@react-native-community|@react-navigation|expo)"
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)"
],
"preset": "./jest.preset.js",
"coverageDirectory": "./coverage/",

557
yarn.lock
View File

@ -59,12 +59,12 @@
dependencies:
"@babel/highlight" "^7.18.6"
"@babel/code-frame@^7.22.13":
version "7.22.13"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e"
integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
"@babel/code-frame@^7.23.5":
version "7.23.5"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244"
integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==
dependencies:
"@babel/highlight" "^7.22.13"
"@babel/highlight" "^7.23.4"
chalk "^2.4.2"
"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5":
@ -87,10 +87,10 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec"
integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==
"@babel/compat-data@^7.22.9":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.20.tgz#8df6e96661209623f1975d66c35ffca66f3306d0"
integrity sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==
"@babel/compat-data@^7.23.5":
version "7.23.5"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98"
integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==
"@babel/core@7.12.9":
version "7.12.9"
@ -158,21 +158,21 @@
semver "^6.3.0"
"@babel/core@^7.13.16":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.20.tgz#e3d0eed84c049e2a2ae0a64d27b6a37edec385b7"
integrity sha512-Y6jd1ahLubuYweD/zJH+vvOY141v4f9igNQAQ+MBgq9JlHS2iTsZKn1aMsb3vGccZsXI16VzTBw52Xx0DWmtnA==
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.9.tgz#b028820718000f267870822fec434820e9b1e4d1"
integrity sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==
dependencies:
"@ampproject/remapping" "^2.2.0"
"@babel/code-frame" "^7.22.13"
"@babel/generator" "^7.22.15"
"@babel/helper-compilation-targets" "^7.22.15"
"@babel/helper-module-transforms" "^7.22.20"
"@babel/helpers" "^7.22.15"
"@babel/parser" "^7.22.16"
"@babel/template" "^7.22.15"
"@babel/traverse" "^7.22.20"
"@babel/types" "^7.22.19"
convert-source-map "^1.7.0"
"@babel/code-frame" "^7.23.5"
"@babel/generator" "^7.23.6"
"@babel/helper-compilation-targets" "^7.23.6"
"@babel/helper-module-transforms" "^7.23.3"
"@babel/helpers" "^7.23.9"
"@babel/parser" "^7.23.9"
"@babel/template" "^7.23.9"
"@babel/traverse" "^7.23.9"
"@babel/types" "^7.23.9"
convert-source-map "^2.0.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
json5 "^2.2.3"
@ -277,12 +277,12 @@
"@jridgewell/gen-mapping" "^0.3.2"
jsesc "^2.5.1"
"@babel/generator@^7.14.0", "@babel/generator@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.15.tgz#1564189c7ec94cb8f77b5e8a90c4d200d21b2339"
integrity sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==
"@babel/generator@^7.14.0", "@babel/generator@^7.23.6":
version "7.23.6"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e"
integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==
dependencies:
"@babel/types" "^7.22.15"
"@babel/types" "^7.23.6"
"@jridgewell/gen-mapping" "^0.3.2"
"@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1"
@ -469,14 +469,14 @@
lru-cache "^5.1.1"
semver "^6.3.0"
"@babel/helper-compilation-targets@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52"
integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==
"@babel/helper-compilation-targets@^7.23.6":
version "7.23.6"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991"
integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==
dependencies:
"@babel/compat-data" "^7.22.9"
"@babel/helper-validator-option" "^7.22.15"
browserslist "^4.21.9"
"@babel/compat-data" "^7.23.5"
"@babel/helper-validator-option" "^7.23.5"
browserslist "^4.22.2"
lru-cache "^5.1.1"
semver "^6.3.1"
@ -531,17 +531,17 @@
"@babel/helper-replace-supers" "^7.18.9"
"@babel/helper-split-export-declaration" "^7.18.6"
"@babel/helper-create-class-features-plugin@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4"
integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==
"@babel/helper-create-class-features-plugin@^7.23.6":
version "7.23.10"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz#25d55fafbaea31fd0e723820bb6cc3df72edf7ea"
integrity sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==
dependencies:
"@babel/helper-annotate-as-pure" "^7.22.5"
"@babel/helper-environment-visitor" "^7.22.5"
"@babel/helper-function-name" "^7.22.5"
"@babel/helper-member-expression-to-functions" "^7.22.15"
"@babel/helper-environment-visitor" "^7.22.20"
"@babel/helper-function-name" "^7.23.0"
"@babel/helper-member-expression-to-functions" "^7.23.0"
"@babel/helper-optimise-call-expression" "^7.22.5"
"@babel/helper-replace-supers" "^7.22.9"
"@babel/helper-replace-supers" "^7.22.20"
"@babel/helper-skip-transparent-expression-wrappers" "^7.22.5"
"@babel/helper-split-export-declaration" "^7.22.6"
semver "^6.3.1"
@ -654,7 +654,7 @@
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
"@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5":
"@babel/helper-environment-visitor@^7.22.20":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167"
integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==
@ -731,13 +731,13 @@
"@babel/template" "^7.20.7"
"@babel/types" "^7.21.0"
"@babel/helper-function-name@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be"
integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==
"@babel/helper-function-name@^7.23.0":
version "7.23.0"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759"
integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
dependencies:
"@babel/template" "^7.22.5"
"@babel/types" "^7.22.5"
"@babel/template" "^7.22.15"
"@babel/types" "^7.23.0"
"@babel/helper-function-name@^7.8.3", "@babel/helper-function-name@^7.9.5":
version "7.9.5"
@ -832,12 +832,12 @@
dependencies:
"@babel/types" "^7.18.9"
"@babel/helper-member-expression-to-functions@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz#b95a144896f6d491ca7863576f820f3628818621"
integrity sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==
"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0":
version "7.23.0"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366"
integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==
dependencies:
"@babel/types" "^7.22.15"
"@babel/types" "^7.23.0"
"@babel/helper-member-expression-to-functions@^7.8.3":
version "7.8.3"
@ -943,10 +943,10 @@
"@babel/traverse" "^7.21.2"
"@babel/types" "^7.21.2"
"@babel/helper-module-transforms@^7.22.15", "@babel/helper-module-transforms@^7.22.20":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.20.tgz#da9edc14794babbe7386df438f3768067132f59e"
integrity sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A==
"@babel/helper-module-transforms@^7.23.3":
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1"
integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==
dependencies:
"@babel/helper-environment-visitor" "^7.22.20"
"@babel/helper-module-imports" "^7.22.15"
@ -1139,7 +1139,7 @@
"@babel/traverse" "^7.18.9"
"@babel/types" "^7.18.9"
"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9":
"@babel/helper-replace-supers@^7.22.20":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793"
integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==
@ -1282,10 +1282,10 @@
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63"
integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==
"@babel/helper-string-parser@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f"
integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
"@babel/helper-string-parser@^7.23.4":
version "7.23.4"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83"
integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==
"@babel/helper-validator-identifier@^7.10.4":
version "7.10.4"
@ -1312,7 +1312,7 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
"@babel/helper-validator-identifier@^7.22.19", "@babel/helper-validator-identifier@^7.22.20":
"@babel/helper-validator-identifier@^7.22.20":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0"
integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
@ -1337,10 +1337,10 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
"@babel/helper-validator-option@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040"
integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==
"@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5":
version "7.23.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307"
integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==
"@babel/helper-wrap-function@^7.16.8":
version "7.16.8"
@ -1398,14 +1398,14 @@
"@babel/traverse" "^7.21.0"
"@babel/types" "^7.21.0"
"@babel/helpers@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.15.tgz#f09c3df31e86e3ea0b7ff7556d85cdebd47ea6f1"
integrity sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==
"@babel/helpers@^7.23.9":
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.9.tgz#c3e20bbe7f7a7e10cb9b178384b4affdf5995c7d"
integrity sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==
dependencies:
"@babel/template" "^7.22.15"
"@babel/traverse" "^7.22.15"
"@babel/types" "^7.22.15"
"@babel/template" "^7.23.9"
"@babel/traverse" "^7.23.9"
"@babel/types" "^7.23.9"
"@babel/helpers@^7.9.6":
version "7.9.6"
@ -1452,10 +1452,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/highlight@^7.22.13":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54"
integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==
"@babel/highlight@^7.23.4":
version "7.23.4"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b"
integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==
dependencies:
"@babel/helper-validator-identifier" "^7.22.20"
chalk "^2.4.2"
@ -1485,10 +1485,10 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9"
integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==
"@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.22.15", "@babel/parser@^7.22.16":
version "7.22.16"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.16.tgz#180aead7f247305cce6551bea2720934e2fa2c95"
integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==
"@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.23.9":
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.9.tgz#7b903b6149b0f8fa7ad564af646c4c38a77fc44b"
integrity sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==
"@babel/parser@^7.14.5":
version "7.14.5"
@ -2018,10 +2018,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.3"
"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859"
integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==
"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.23.3":
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz#084564e0f3cc21ea6c70c44cff984a1c0509729a"
integrity sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@ -2074,10 +2074,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.10.4"
"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918"
integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==
"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.23.3":
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473"
integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@ -2186,10 +2186,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-syntax-typescript@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272"
integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==
"@babel/plugin-syntax-typescript@^7.23.3":
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f"
integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@ -2247,9 +2247,9 @@
"@babel/helper-remap-async-to-generator" "^7.18.6"
"@babel/plugin-transform-block-scoped-functions@^7.0.0":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024"
integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77"
integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@ -2451,13 +2451,13 @@
"@babel/helper-plugin-utils" "^7.18.9"
"@babel/plugin-syntax-flow" "^7.18.6"
"@babel/plugin-transform-flow-strip-types@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2"
integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==
"@babel/plugin-transform-flow-strip-types@^7.23.3":
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz#cfa7ca159cc3306fab526fc67091556b51af26ff"
integrity sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-flow" "^7.22.5"
"@babel/plugin-syntax-flow" "^7.23.3"
"@babel/plugin-transform-for-of@^7.0.0":
version "7.9.0"
@ -2528,9 +2528,9 @@
"@babel/helper-plugin-utils" "^7.18.9"
"@babel/plugin-transform-member-expression-literals@^7.0.0":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def"
integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc"
integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@ -2576,12 +2576,12 @@
"@babel/helper-simple-access" "^7.8.3"
babel-plugin-dynamic-import-node "^2.3.3"
"@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.15.tgz#b11810117ed4ee7691b29bd29fd9f3f98276034f"
integrity sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==
"@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.23.3":
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4"
integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==
dependencies:
"@babel/helper-module-transforms" "^7.22.15"
"@babel/helper-module-transforms" "^7.23.3"
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/helper-simple-access" "^7.22.5"
@ -2688,12 +2688,12 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-transform-object-super@^7.0.0":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c"
integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd"
integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/helper-replace-supers" "^7.22.5"
"@babel/helper-replace-supers" "^7.22.20"
"@babel/plugin-transform-object-super@^7.16.7":
version "7.16.7"
@ -2734,9 +2734,9 @@
"@babel/helper-plugin-utils" "^7.17.12"
"@babel/plugin-transform-property-literals@^7.0.0":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766"
integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875"
integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@ -2998,15 +2998,15 @@
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-syntax-typescript" "^7.18.6"
"@babel/plugin-transform-typescript@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz#15adef906451d86349eb4b8764865c960eb54127"
integrity sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==
"@babel/plugin-transform-typescript@^7.23.3":
version "7.23.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz#aa36a94e5da8d94339ae3a4e22d40ed287feb34c"
integrity sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==
dependencies:
"@babel/helper-annotate-as-pure" "^7.22.5"
"@babel/helper-create-class-features-plugin" "^7.22.15"
"@babel/helper-create-class-features-plugin" "^7.23.6"
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-typescript" "^7.22.5"
"@babel/plugin-syntax-typescript" "^7.23.3"
"@babel/plugin-transform-typescript@^7.5.0":
version "7.9.6"
@ -3227,13 +3227,13 @@
"@babel/plugin-transform-flow-strip-types" "^7.18.6"
"@babel/preset-flow@^7.13.13":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.22.15.tgz#30318deb9b3ebd9f5738e96da03a531e0cd3165d"
integrity sha512-dB5aIMqpkgbTfN5vDdTRPzjqtWiZcRESNR88QYnoPR+bmdYoluOzMX9tQerTv0XzSgZYctPfO1oc0N5zdog1ew==
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.23.3.tgz#8084e08b9ccec287bd077ab288b286fab96ffab1"
integrity sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/helper-validator-option" "^7.22.15"
"@babel/plugin-transform-flow-strip-types" "^7.22.5"
"@babel/plugin-transform-flow-strip-types" "^7.23.3"
"@babel/preset-modules@^0.1.5":
version "0.1.5"
@ -3268,15 +3268,15 @@
"@babel/plugin-transform-typescript" "^7.18.6"
"@babel/preset-typescript@^7.13.0":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.22.15.tgz#43db30516fae1d417d748105a0bc95f637239d48"
integrity sha512-HblhNmh6yM+cU4VwbBRpxFhxsTdfS1zsvH9W+gEjD0ARV9+8B4sNfpI6GuhePti84nuvhiwKS539jKPFHskA9A==
version "7.23.3"
resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913"
integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/helper-validator-option" "^7.22.15"
"@babel/plugin-syntax-jsx" "^7.22.5"
"@babel/plugin-transform-modules-commonjs" "^7.22.15"
"@babel/plugin-transform-typescript" "^7.22.15"
"@babel/plugin-syntax-jsx" "^7.23.3"
"@babel/plugin-transform-modules-commonjs" "^7.23.3"
"@babel/plugin-transform-typescript" "^7.23.3"
"@babel/preset-typescript@^7.16.7":
version "7.17.12"
@ -3299,14 +3299,14 @@
source-map-support "^0.5.16"
"@babel/register@^7.13.16":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.15.tgz#c2c294a361d59f5fa7bcc8b97ef7319c32ecaec7"
integrity sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==
version "7.23.7"
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.23.7.tgz#485a5e7951939d21304cae4af1719fdb887bc038"
integrity sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ==
dependencies:
clone-deep "^4.0.1"
find-cache-dir "^2.0.0"
make-dir "^2.1.0"
pirates "^4.0.5"
pirates "^4.0.6"
source-map-support "^0.5.16"
"@babel/runtime-corejs3@^7.10.2":
@ -3444,14 +3444,14 @@
"@babel/parser" "^7.20.7"
"@babel/types" "^7.20.7"
"@babel/template@^7.22.15", "@babel/template@^7.22.5":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38"
integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==
"@babel/template@^7.22.15", "@babel/template@^7.23.9":
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a"
integrity sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==
dependencies:
"@babel/code-frame" "^7.22.13"
"@babel/parser" "^7.22.15"
"@babel/types" "^7.22.15"
"@babel/code-frame" "^7.23.5"
"@babel/parser" "^7.23.9"
"@babel/types" "^7.23.9"
"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.18.10", "@babel/traverse@^7.18.11":
version "7.18.11"
@ -3499,20 +3499,20 @@
debug "^4.1.0"
globals "^11.1.0"
"@babel/traverse@^7.14.0", "@babel/traverse@^7.22.15", "@babel/traverse@^7.22.20":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.20.tgz#db572d9cb5c79e02d83e5618b82f6991c07584c9"
integrity sha512-eU260mPZbU7mZ0N+X10pxXhQFMGTeLb9eFS0mxehS8HZp9o1uSnFeWQuG1UPrlxgA7QoUzFhOnilHDp0AXCyHw==
"@babel/traverse@^7.14.0", "@babel/traverse@^7.23.9":
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.9.tgz#2f9d6aead6b564669394c5ce0f9302bb65b9d950"
integrity sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==
dependencies:
"@babel/code-frame" "^7.22.13"
"@babel/generator" "^7.22.15"
"@babel/code-frame" "^7.23.5"
"@babel/generator" "^7.23.6"
"@babel/helper-environment-visitor" "^7.22.20"
"@babel/helper-function-name" "^7.22.5"
"@babel/helper-function-name" "^7.23.0"
"@babel/helper-hoist-variables" "^7.22.5"
"@babel/helper-split-export-declaration" "^7.22.6"
"@babel/parser" "^7.22.16"
"@babel/types" "^7.22.19"
debug "^4.1.0"
"@babel/parser" "^7.23.9"
"@babel/types" "^7.23.9"
debug "^4.3.1"
globals "^11.1.0"
"@babel/traverse@^7.16.7":
@ -3710,13 +3710,13 @@
"@babel/helper-validator-identifier" "^7.19.1"
to-fast-properties "^2.0.0"
"@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5":
version "7.22.19"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.19.tgz#7425343253556916e440e662bb221a93ddb75684"
integrity sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==
"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.23.9":
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002"
integrity sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==
dependencies:
"@babel/helper-string-parser" "^7.22.5"
"@babel/helper-validator-identifier" "^7.22.19"
"@babel/helper-string-parser" "^7.23.4"
"@babel/helper-validator-identifier" "^7.22.20"
to-fast-properties "^2.0.0"
"@bcoe/v8-coverage@^0.2.3":
@ -4335,6 +4335,11 @@
find-up "^5.0.0"
js-yaml "^4.1.0"
"@flatten-js/interval-tree@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@flatten-js/interval-tree/-/interval-tree-1.1.2.tgz#fcc891da48bc230392884be01c26fe8c625702e8"
integrity sha512-OwLoV9E/XM6b7bes2rSFnGNjyRy7vcoIHFTnmBR2WAaZTf0Fe4EX4GdA65vU1KgFAasti7iRSg2dZfYd1Zt00Q==
"@gar/promisify@^1.0.1":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
@ -4362,12 +4367,12 @@
resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.1.tgz#076d78ce99822258cf813ecc1e7fa460fa74d052"
integrity sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==
"@hapi/hoek@^9.0.0":
"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0":
version "9.3.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb"
integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==
"@hapi/topo@^5.0.0":
"@hapi/topo@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012"
integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==
@ -5660,10 +5665,10 @@
component-type "^1.2.1"
join-component "^1.1.0"
"@sideway/address@^4.1.3":
version "4.1.4"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==
"@sideway/address@^4.1.5":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5"
integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==
dependencies:
"@hapi/hoek" "^9.0.0"
@ -6292,17 +6297,6 @@
resolve-from "^5.0.0"
store2 "^2.12.0"
"@testing-library/jest-native@^5.4.2":
version "5.4.3"
resolved "https://registry.yarnpkg.com/@testing-library/jest-native/-/jest-native-5.4.3.tgz#9334c68eaf45db9eb20d0876728cc5d7fc2c3ea2"
integrity sha512-/sSDGaOuE+PJ1Z9Kp4u7PQScSVVXGud59I/qsBFFJvIbcn4P6yYw6cBnBmbPF+X9aRIsTJRDl6gzw5ZkJNm66w==
dependencies:
chalk "^4.1.2"
jest-diff "^29.0.1"
jest-matcher-utils "^29.0.1"
pretty-format "^29.0.3"
redent "^3.0.0"
"@testing-library/react-hooks@^8.0.1":
version "8.0.1"
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12"
@ -6311,10 +6305,10 @@
"@babel/runtime" "^7.12.5"
react-error-boundary "^3.1.0"
"@testing-library/react-native@^12.4.1":
version "12.4.1"
resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-12.4.1.tgz#f15d0b6727e5e1af8bc35049aa95ce24b4420fe7"
integrity sha512-HDHwGTJwBB9//Flv0HhApghFsUYZvaKTemXOs9PCMk6P8mUl4IJby8zAud8rq7bT/ZMnehgIak8QK+mJCH6+5Q==
"@testing-library/react-native@^12.4.3":
version "12.4.3"
resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-12.4.3.tgz#57cd6a88b289f19144558b5e97336b57101af3ec"
integrity sha512-WLE7VbbR5jZJQl3vfNK7Wt+IHnzhOxyu95Mr56EHmzH3XhC8DkrPVAnUq9asq/QWj4aGnymbinFx6zZys/WZmA==
dependencies:
jest-matcher-utils "^29.7.0"
pretty-format "^29.7.0"
@ -8540,15 +8534,15 @@ browserslist@^4.21.3:
node-releases "^2.0.6"
update-browserslist-db "^1.0.5"
browserslist@^4.21.9:
version "4.21.10"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0"
integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==
browserslist@^4.22.2:
version "4.22.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.3.tgz#299d11b7e947a6b843981392721169e27d60c5a6"
integrity sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==
dependencies:
caniuse-lite "^1.0.30001517"
electron-to-chromium "^1.4.477"
node-releases "^2.0.13"
update-browserslist-db "^1.0.11"
caniuse-lite "^1.0.30001580"
electron-to-chromium "^1.4.648"
node-releases "^2.0.14"
update-browserslist-db "^1.0.13"
bser@2.1.1:
version "2.1.1"
@ -8625,6 +8619,17 @@ builtins@^1.0.3:
resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==
bunyamin@^1.5.0:
version "1.5.2"
resolved "https://registry.yarnpkg.com/bunyamin/-/bunyamin-1.5.2.tgz#681db204c0b16531369d5c1f6c89dc8d760b7558"
integrity sha512-Xp2nfqk33zt3nX90OSTkLVOc5N+1zdR3MWvfLHoIrm3cGRkdxPTPYB9CCgrDV8oum5rbghJjAbmXFXOrRXvMtg==
dependencies:
"@flatten-js/interval-tree" "^1.1.2"
multi-sort-stream "^1.0.4"
stream-json "^1.7.5"
trace-event-lib "^1.3.1"
bunyan-debug-stream@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-3.1.0.tgz#78309c67ad85cfb8f011155334152c49209dcda8"
@ -8642,6 +8647,18 @@ bunyan@^1.8.12:
mv "~2"
safe-json-stringify "~1"
bunyan@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-2.0.5.tgz#9dd056755220dddd8b5bb9cf76f3d0d766e96e71"
integrity sha512-Jvl74TdxCN6rSP9W1I6+UOUtwslTDqsSFkDqZlFb/ilaSvQ+bZAnXT/GT97IZ5L+Vph0joPZPhxUyn6FLNmFAA==
dependencies:
exeunt "1.1.0"
optionalDependencies:
dtrace-provider "~0.8"
moment "^2.19.3"
mv "~2"
safe-json-stringify "~1"
bytebuffer@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd"
@ -8837,10 +8854,10 @@ caniuse-lite@^1.0.30001349:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001349.tgz#90740086a2eb2e825084944169d313c9793aeba4"
integrity sha512-VFaWW3jeo6DLU5rwdiasosxhYSduJgSGil4cSyX3/85fbctlE58pXAkWyuRmVA0r2RxsOSVYUTZcySJ8WpbTxw==
caniuse-lite@^1.0.30001517:
version "1.0.30001538"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001538.tgz#9dbc6b9af1ff06b5eb12350c2012b3af56744f3f"
integrity sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw==
caniuse-lite@^1.0.30001580:
version "1.0.30001584"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001584.tgz#5e3ea0625d048d5467670051687655b1f7bf7dfd"
integrity sha512-LOz7CCQ9M1G7OjJOF9/mzmqmj3jE/7VOmrfw6Mgs0E8cjOsbRXQJHsPBfmBOXDskXKrHLyyW3n7kpDW/4BsfpQ==
capture-exit@^2.0.0:
version "2.0.0"
@ -9072,9 +9089,9 @@ cli-spinners@^2.0.0:
integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==
cli-spinners@^2.5.0:
version "2.9.1"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.1.tgz#9c0b9dad69a6d47cbb4333c14319b060ed395a35"
integrity sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==
version "2.9.2"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41"
integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==
cli-table3@^0.6.1:
version "0.6.2"
@ -9511,6 +9528,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0,
dependencies:
safe-buffer "~5.1.1"
convert-source-map@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
@ -10140,10 +10162,10 @@ detect-port@^1.3.0:
address "^1.0.1"
debug "^2.6.0"
detox@20.11.0:
version "20.11.0"
resolved "https://registry.yarnpkg.com/detox/-/detox-20.11.0.tgz#f240e01db12334e0706b7f3477e59b8a5e4358c8"
integrity sha512-01LpETlZwfo2V7Awo+5ccUbee7E1lvH3ldLlmXxsx3mQ0pEA65f9CaO+FWhtUGYh7vQRMOQ9SnzYdej/ydQ7iQ==
detox@20.17.1:
version "20.17.1"
resolved "https://registry.yarnpkg.com/detox/-/detox-20.17.1.tgz#55b9615cf5937819e1257fbf03fb2d2d58cf2acc"
integrity sha512-10pey6CR9D5GSloRkH60ObBGZ8VS11H7iuBNY7qq6jO2swiqqckHhPLRXfH9+WGR7l3vDnfU+G/gQs7JxQkJwA==
dependencies:
ajv "^8.6.3"
bunyan "^1.8.12"
@ -10157,6 +10179,7 @@ detox@20.11.0:
funpermaproxy "^1.1.0"
glob "^8.0.3"
ini "^1.3.4"
jest-environment-emit "^1.0.5"
json-cycle "^1.3.0"
lodash "^4.17.11"
multi-sort-stream "^1.0.3"
@ -10447,10 +10470,10 @@ electron-to-chromium@^1.4.147:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.147.tgz#1ecf318737b21ba1e5b53319eb1edf8143892270"
integrity sha512-czclPqxLMPqPMkahKcske4TaS5lcznsc26ByBlEFDU8grTBVK9C5W6K9I6oEEhm4Ai4jTihGnys90xY1yjXcRg==
electron-to-chromium@^1.4.477:
version "1.4.526"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.526.tgz#1bcda5f2b8238e497c20fcdb41af5da907a770e2"
integrity sha512-tjjTMjmZAx1g6COrintLTa2/jcafYKxKoiEkdQOrVdbLaHh2wCt2nsAF8ZHweezkrP+dl/VG9T5nabcYoo0U5Q==
electron-to-chromium@^1.4.648:
version "1.4.657"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.657.tgz#8a07ee3faa552976970843a80a1c94088ea59c9a"
integrity sha512-On2ymeleg6QbRuDk7wNgDdXtNqlJLM2w4Agx1D/RiTmItiL+a9oq5p7HUa2ZtkAtGBe/kil2dq/7rPfkbe0r5w==
element-resize-detector@^1.2.2:
version "1.2.4"
@ -10580,9 +10603,9 @@ env-editor@^0.4.1:
integrity sha512-ObFo8v4rQJAE59M69QzwloxPZtd33TpYEIjtKD1rrFDcM1Gd7IkDxEBU+HriziN6HSHQnBJi8Dmy+JWkav5HKA==
envinfo@^7.7.2:
version "7.10.0"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13"
integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==
version "7.11.1"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.1.tgz#2ffef77591057081b0129a8fd8cf6118da1b94e1"
integrity sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==
eol@^0.9.1:
version "0.9.1"
@ -11133,6 +11156,11 @@ execa@^5.0.0, execa@^5.1.1:
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
exeunt@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/exeunt/-/exeunt-1.1.0.tgz#af72db6f94b3cb75e921aee375d513049843d284"
integrity sha512-dd++Yn/0Fp+gtJ04YHov7MeAii+LFivJc6KqnJNfplzLVUkUDrfKoQDTLlCgzcW15vY5hKlHasWeIsQJ8agHsw==
exif-parser@^0.1.12:
version "0.1.12"
resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922"
@ -11740,9 +11768,9 @@ flatted@^3.1.0:
integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==
flow-parser@0.*:
version "0.217.0"
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.217.0.tgz#0e6bed214151fa3240dc9fd83ac8a9e050e523c5"
integrity sha512-hEa5n0dta1RcaDwJDWbnyelw07PK7+Vx0f9kDht28JOt2hXgKdKGaT3wM45euWV2DxOXtzDSTaUgGSD/FPvC2Q==
version "0.228.0"
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.228.0.tgz#0b801507c8cf44257338596b49bd0904caea2026"
integrity sha512-xPWkzCO07AnS8X+fQFpWm+tJ+C7aeaiVzJ+rSepbkCXUvUJ6l6squEl63axoMcixyH4wLjmypOzq/+zTD0O93w==
flow-parser@^0.121.0:
version "0.121.0"
@ -13726,16 +13754,6 @@ jest-diff@^28.1.3:
jest-get-type "^28.0.2"
pretty-format "^28.1.3"
jest-diff@^29.0.1, jest-diff@^29.6.4:
version "29.6.4"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.4.tgz#85aaa6c92a79ae8cd9a54ebae8d5b6d9a513314a"
integrity sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==
dependencies:
chalk "^4.0.0"
diff-sequences "^29.6.3"
jest-get-type "^29.6.3"
pretty-format "^29.6.3"
jest-diff@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a"
@ -13764,6 +13782,20 @@ jest-each@^28.1.3:
jest-util "^28.1.3"
pretty-format "^28.1.3"
jest-environment-emit@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/jest-environment-emit/-/jest-environment-emit-1.0.5.tgz#e6f33451f98b88ccd48e9e1188bb535880f03c1b"
integrity sha512-OsQ08AhYxkkyDBTIow+9ogNmJheQIGWQKp0Nku+1ToLWjAj2Pd6LmypN8HgUIqYHs4HFcqkQ25kaf1qExmoZpg==
dependencies:
bunyamin "^1.5.0"
bunyan "^2.0.5"
bunyan-debug-stream "^3.1.0"
funpermaproxy "^1.1.0"
lodash.merge "^4.6.2"
node-ipc "9.2.1"
strip-ansi "^6.0.0"
tslib "^2.5.3"
jest-environment-node@^28.1.3:
version "28.1.3"
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5"
@ -13909,16 +13941,6 @@ jest-matcher-utils@^28.1.3:
jest-get-type "^28.0.2"
pretty-format "^28.1.3"
jest-matcher-utils@^29.0.1:
version "29.6.4"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz#327db7ababea49455df3b23e5d6109fe0c709d24"
integrity sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==
dependencies:
chalk "^4.0.0"
jest-diff "^29.6.4"
jest-get-type "^29.6.3"
pretty-format "^29.6.3"
jest-matcher-utils@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12"
@ -14336,13 +14358,13 @@ jimp@^0.16.2:
regenerator-runtime "^0.13.3"
joi@^17.2.1:
version "17.10.2"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.10.2.tgz#4ecc348aa89ede0b48335aad172e0f5591e55b29"
integrity sha512-hcVhjBxRNW/is3nNLdGLIjkgXetkeGc2wyhydhz8KumG23Aerk4HPjU5zaPAMRqXQFc0xNqXTC7+zQjxr0GlKA==
version "17.12.1"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.12.1.tgz#3347ecf4cd3301962d42191c021b165eef1f395b"
integrity sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==
dependencies:
"@hapi/hoek" "^9.0.0"
"@hapi/topo" "^5.0.0"
"@sideway/address" "^4.1.3"
"@hapi/hoek" "^9.3.0"
"@hapi/topo" "^5.1.0"
"@sideway/address" "^4.1.5"
"@sideway/formula" "^3.0.1"
"@sideway/pinpoint" "^2.0.0"
@ -15782,7 +15804,7 @@ ms@2.1.3:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
multi-sort-stream@^1.0.3:
multi-sort-stream@^1.0.3, multi-sort-stream@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/multi-sort-stream/-/multi-sort-stream-1.0.4.tgz#e4348edc9edc36e16333e531a90c0f166235cc99"
integrity sha512-hAZ8JOEQFbgdLe8HWZbb7gdZg0/yAIHF00Qfo3kd0rXFv96nXe+/bPTrKHZ2QMHugGX4FiAyET1Lt+jiB+7Qlg==
@ -16007,10 +16029,10 @@ node-releases@^1.1.71:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20"
integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==
node-releases@^2.0.13:
version "2.0.13"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d"
integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==
node-releases@^2.0.14:
version "2.0.14"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==
node-releases@^2.0.5:
version "2.0.5"
@ -16853,6 +16875,11 @@ pirates@^4.0.4, pirates@^4.0.5:
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b"
integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==
pirates@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9"
integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
pixelmatch@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854"
@ -17130,15 +17157,6 @@ pretty-format@^28.1.3:
ansi-styles "^5.0.0"
react-is "^18.0.0"
pretty-format@^29.0.3, pretty-format@^29.6.3:
version "29.6.3"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.3.tgz#d432bb4f1ca6f9463410c3fb25a0ba88e594ace7"
integrity sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==
dependencies:
"@jest/schemas" "^29.6.3"
ansi-styles "^5.0.0"
react-is "^18.0.0"
pretty-format@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812"
@ -17568,9 +17586,9 @@ react-dev-utils@^11.0.3:
text-table "0.2.0"
react-devtools-core@^4.23.0:
version "4.28.0"
resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.28.0.tgz#3fa18709b24414adddadac33b6b9cea96db60f2f"
integrity sha512-E3C3X1skWBdBzwpOUbmXG8SgH6BtsluSMe+s6rRcujNKG1DGi8uIfhdhszkgDpAsMoE55hwqRUzeXCmETDBpTg==
version "4.28.5"
resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.28.5.tgz#c8442b91f068cdf0c899c543907f7f27d79c2508"
integrity sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA==
dependencies:
shell-quote "^1.6.1"
ws "^7"
@ -18025,9 +18043,9 @@ react-native-webview@11.26.1, react-native-webview@^11.18.2:
escape-string-regexp "2.0.0"
invariant "2.2.4"
react-native@RocketChat/react-native#6cf729c196f0f043ac6e7444e73f5a560d7a8a8a:
react-native@RocketChat/react-native#1b987e4ae3d5e912fda77da5215912ec15f14327:
version "0.68.7"
resolved "https://codeload.github.com/RocketChat/react-native/tar.gz/6cf729c196f0f043ac6e7444e73f5a560d7a8a8a"
resolved "https://codeload.github.com/RocketChat/react-native/tar.gz/1b987e4ae3d5e912fda77da5215912ec15f14327"
dependencies:
"@jest/create-cache-key-function" "^27.0.1"
"@react-native-community/cli" "^7.0.3"
@ -18877,11 +18895,16 @@ sanitize-filename@^1.6.1:
dependencies:
truncate-utf8-bytes "^1.0.0"
sax@>=0.6.0, sax@^1.2.4:
sax@>=0.6.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
sax@^1.2.4:
version "1.3.0"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==
scheduler@^0.20.1, scheduler@^0.20.2:
version "0.20.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
@ -19571,6 +19594,13 @@ stream-json@^1.7.4:
dependencies:
stream-chain "^2.2.5"
stream-json@^1.7.5:
version "1.8.0"
resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.8.0.tgz#53f486b2e3b4496c506131f8d7260ba42def151c"
integrity sha512-HZfXngYHUAr1exT4fxlbc1IOce1RYxp2ldeaf97LYCOPSoOqY/1Psp7iGvpb+6JIOgkra9zDYnPX01hGAHzEPw==
dependencies:
stream-chain "^2.2.5"
stream-shift@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
@ -20461,6 +20491,11 @@ tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
tslib@^2.5.3:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
@ -20869,7 +20904,7 @@ upath@^1.1.1:
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
update-browserslist-db@^1.0.11:
update-browserslist-db@^1.0.13:
version "1.0.13"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4"
integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==
@ -21297,9 +21332,9 @@ whatwg-fetch@>=0.10.0:
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
whatwg-fetch@^3.0.0:
version "3.6.19"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz#caefd92ae630b91c07345537e67f8354db470973"
integrity sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==
version "3.6.20"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70"
integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==
whatwg-url-without-unicode@8.0.0-3:
version "8.0.0-3"