aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-07-01 17:32:12 -0400
committerGitHub <noreply@github.com>2021-07-01 17:32:12 -0400
commitfa9c527f85d23a38b45c7efc41ec4590597fa7a1 (patch)
tree164852b257ab961fb8d4a067189b85e0aadcc180
parent66c974161b59f1e3570e2a4a42334fabc16c2129 (diff)
parentad2f052c6d2cd1b50cc01200597b5b79cb33082d (diff)
Merge pull request #472 from TaggiD-Inc/poc-video
[POC] PoC Video
-rw-r--r--Makefile2
-rw-r--r--ios/Frontend/Info.plist16
-rw-r--r--ios/Podfile.lock47
-rw-r--r--package.json6
-rw-r--r--patches/react-native-inappbrowser-reborn+3.5.1.patch24
-rw-r--r--src/components/camera/GalleryIcon.tsx12
-rw-r--r--src/components/camera/SaveButton.tsx4
-rw-r--r--src/components/comments/AddComment.tsx23
-rw-r--r--src/components/comments/CommentTextField.tsx45
-rw-r--r--src/components/comments/CommentsCount.tsx15
-rw-r--r--src/components/comments/ZoomInCropper.tsx28
-rw-r--r--src/components/common/MomentTags.tsx14
-rw-r--r--src/components/moments/Moment.tsx52
-rw-r--r--src/components/moments/MomentPost.tsx132
-rw-r--r--src/components/moments/legacy/MomentPostContent.tsx49
-rw-r--r--src/components/profile/MomentMoreInfoDrawer.tsx11
-rw-r--r--src/components/profile/ProfileBody.tsx1
-rw-r--r--src/components/taggs/TaggDraggable.tsx4
-rw-r--r--src/constants/api.ts1
-rw-r--r--src/constants/regex.ts2
-rw-r--r--src/constants/strings.ts2
-rw-r--r--src/routes/main/MainStackNavigator.tsx13
-rw-r--r--src/routes/main/MainStackScreen.tsx21
-rw-r--r--src/screens/chat/ChatListScreen.tsx2
-rw-r--r--src/screens/moments/CameraScreen.tsx55
-rw-r--r--src/screens/moments/TagFriendsScreen.tsx195
-rw-r--r--src/screens/profile/CaptionScreen.tsx113
-rw-r--r--src/screens/profile/IndividualMoment.tsx55
-rw-r--r--src/screens/suggestedPeople/SuggestedPeopleScreen.tsx25
-rw-r--r--src/services/MomentService.ts121
-rw-r--r--src/types/types.ts16
-rw-r--r--src/utils/camera.ts81
-rw-r--r--yarn.lock443
33 files changed, 1005 insertions, 625 deletions
diff --git a/Makefile b/Makefile
index b0022598..44f637e2 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,6 @@ clean:
deep_clean:
-rm *.lock
-rm ios/*.lock
- -rm -rf /Users/ivan/Library/Developer/Xcode/DerivedData
+ -rm -rf ~/Library/Developer/Xcode/DerivedData
-rm -rf node_modules
yarn cache clean
diff --git a/ios/Frontend/Info.plist b/ios/Frontend/Info.plist
index 7dedc043..0b1f27bf 100644
--- a/ios/Frontend/Info.plist
+++ b/ios/Frontend/Info.plist
@@ -54,14 +54,6 @@
<string></string>
<key>NSMainNibFile</key>
<string>LaunchScreen</string>
- <key>NSPhotoLibraryUsageDescription</key>
- <string>This lets you share photos from your library and select profile displays</string>
- <key>NSPhotoLibraryAddUsageDescription</key>
- <string>This lets you save photos captured on Tagg, to your library</string>
- <key>NSCameraUsageDescription</key>
- <string>Enable camera access to capture and share moment with your friends</string>
- <key>NSMicrophoneUsageDescription</key>
- <string>Enable microphone access to record and listen to videos</string>
<key>UIAppFonts</key>
<array>
<string>Feather.ttf</string>
@@ -72,6 +64,8 @@
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
+ <key>NSMicrophoneUsageDescription</key>
+ <string>This lets you share video audio from your camera for a Moment post on your profile!</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
@@ -80,6 +74,12 @@
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
+ <key>NSPhotoLibraryUsageDescription</key>
+ <string>This lets you share photos from your library and select profile displays</string>
+ <key>NSPhotoLibraryAddUsageDescription</key>
+ <string>This lets you save photos captured on Tagg, to your library</string>
+ <key>NSCameraUsageDescription</key>
+ <string>This lets you share photos/videos from your camera for a Moment post on your profile!</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index ae9f5f83..19df8c81 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -134,24 +134,24 @@ PODS:
- GoogleUtilities/Environment (~> 7.2)
- nanopb (~> 2.30907.0)
- PromisesObjC (~> 1.2)
- - GoogleUtilities/AppDelegateSwizzler (7.4.1):
+ - GoogleUtilities/AppDelegateSwizzler (7.4.0):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- - GoogleUtilities/Environment (7.4.1):
+ - GoogleUtilities/Environment (7.4.0):
- PromisesObjC (~> 1.2)
- - GoogleUtilities/Logger (7.4.1):
+ - GoogleUtilities/Logger (7.4.0):
- GoogleUtilities/Environment
- - GoogleUtilities/MethodSwizzler (7.4.1):
+ - GoogleUtilities/MethodSwizzler (7.4.0):
- GoogleUtilities/Logger
- - GoogleUtilities/Network (7.4.1):
+ - GoogleUtilities/Network (7.4.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- - "GoogleUtilities/NSData+zlib (7.4.1)"
- - GoogleUtilities/Reachability (7.4.1):
+ - "GoogleUtilities/NSData+zlib (7.4.0)"
+ - GoogleUtilities/Reachability (7.4.0):
- GoogleUtilities/Logger
- - GoogleUtilities/UserDefaults (7.4.1):
+ - GoogleUtilities/UserDefaults (7.4.0):
- GoogleUtilities/Logger
- libevent (2.1.12)
- nanopb (2.30907.0):
@@ -341,13 +341,13 @@ PODS:
- React-Core
- react-native-contacts (6.0.5):
- React-Core
- - react-native-date-picker (3.3.1):
+ - react-native-date-picker (3.3.2):
- React-Core
- - react-native-document-picker (5.1.0):
+ - react-native-document-picker (5.2.0):
- React-Core
- - react-native-image-picker (4.0.3):
+ - react-native-image-picker (4.0.4):
- React-Core
- - react-native-image-resizer (1.4.4):
+ - react-native-image-resizer (1.4.5):
- React-Core
- react-native-netinfo (6.0.0):
- React-Core
@@ -358,6 +358,11 @@ PODS:
- React-Core
- react-native-splash-screen (3.2.0):
- React
+ - react-native-video (5.1.1):
+ - React-Core
+ - react-native-video/Video (= 5.1.1)
+ - react-native-video/Video (5.1.1):
+ - React-Core
- React-RCTActionSheet (0.63.3):
- React-Core/RCTActionSheetHeaders (= 0.63.3)
- React-RCTAnimation (0.63.3):
@@ -450,7 +455,7 @@ PODS:
- React-Core
- React-RCTImage
- TOCropViewController
- - RNInAppBrowser (3.5.1):
+ - RNInAppBrowser (3.6.1):
- React-Core
- RNReactNativeHapticFeedback (1.11.0):
- React-Core
@@ -548,6 +553,7 @@ DEPENDENCIES:
- react-native-photo-manipulator (from `../node_modules/react-native-photo-manipulator`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
+ - react-native-video (from `../node_modules/react-native-video`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
@@ -663,6 +669,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-safe-area-context"
react-native-splash-screen:
:path: "../node_modules/react-native-splash-screen"
+ react-native-video:
+ :path: "../node_modules/react-native-video"
React-RCTActionSheet:
:path: "../node_modules/react-native/Libraries/ActionSheetIOS"
React-RCTAnimation:
@@ -745,7 +753,7 @@ SPEC CHECKSUMS:
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
GoogleAppMeasurement: c542a2feaac9ab98fd074e8f1a02c3585bbfbd47
GoogleDataTransport: 8b0e733ea77c9218778e5a9e34ba9508b8328939
- GoogleUtilities: f8a43108b38a68eebe8b3540e1f4f2d28843ce20
+ GoogleUtilities: 284cddc7fffc14ae1907efb6f78ab95c1fccaedc
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
nanopb: 59221d7f958fb711001e6a449489542d92ae113e
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
@@ -764,14 +772,15 @@ SPEC CHECKSUMS:
react-native-camera: 7bf59f2728ffb019fa25e60a225d2c57e1a8f0f6
react-native-cameraroll: 88f4e62d9ecd0e1f253abe4f685474f2ea14bfa2
react-native-contacts: 931baebf460125c5a7bbce1c4521a96c69795123
- react-native-date-picker: 2dfef0fcb6c36d078bc62f5de3ca79eff7f42486
- react-native-document-picker: f2f73db94328c84e22144e369fb4a3ede47bc1f5
- react-native-image-picker: 474cf2c33c2b6671da53d293a16c97995f0aec15
- react-native-image-resizer: 13ac4af788f88af36d0353a1324401ebabd04fe4
+ react-native-date-picker: 96a07ca27a6225da8a3935324d85046028456b0f
+ react-native-document-picker: f1b5398801b332c77bc62ae0eae2116f49bdff26
+ react-native-image-picker: c07b072faa83f3480b473a15ea3c19cc39b3d6fa
+ react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
react-native-netinfo: e849fc21ca2f4128a5726c801a82fc6f4a6db50d
react-native-photo-manipulator: e44c14a28bf7c9b7657a0e0ac79327c1a4d8fe2c
react-native-safe-area-context: f0906bf8bc9835ac9a9d3f97e8bde2a997d8da79
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
+ react-native-video: 0bb76b6d6b77da3009611586c7dbf817b947f30e
React-RCTActionSheet: 53ea72699698b0b47a6421cb1c8b4ab215a774aa
React-RCTAnimation: 1befece0b5183c22ae01b966f5583f42e69a83c2
React-RCTBlob: 0b284339cbe4b15705a05e2313a51c6d8b51fa40
@@ -792,7 +801,7 @@ SPEC CHECKSUMS:
RNFS: 3ab21fa6c56d65566d1fb26c2228e2b6132e5e32
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
RNImageCropPicker: 35a3ceb837446fa11547704709bb22b5fac6d584
- RNInAppBrowser: 48b95ba7a4eaff5cc223bca338d3e319561dbd1b
+ RNInAppBrowser: 0523b3c15501fb8b54b4f32905d2e71ca902d914
RNReactNativeHapticFeedback: 653a8c126a0f5e88ce15ffe280b3ff37e1fbb285
RNReanimated: b9c929bfff7dedc9c89ab1875f1c6151023358d9
RNScreens: f7ad633b2e0190b77b6a7aab7f914fad6f198d8d
diff --git a/package.json b/package.json
index eebb8837..63203775 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"@reduxjs/toolkit": "^1.4.0",
"@stream-io/flat-list-mvcp": "^0.10.1",
"@types/react-native-vector-icons": "^6.4.5",
+ "@types/react-native-video": "^5.0.6",
"moment": "^2.29.1",
"patch-package": "^6.4.7",
"postinstall-postinstall": "^2.1.0",
@@ -46,8 +47,8 @@
"react-native-haptic-feedback": "^1.11.0",
"react-native-hyperlink": "^0.0.19",
"react-native-image-crop-picker": "^0.36.0",
+ "react-native-image-picker": "^4.0.4",
"react-native-image-pan-zoom": "^2.1.12",
- "react-native-image-picker": "^4.0.3",
"react-native-image-resizer": "^1.4.4",
"react-native-inappbrowser-reborn": "^3.5.0",
"react-native-linear-gradient": "^2.5.6",
@@ -62,6 +63,7 @@
"react-native-splash-screen": "^3.2.0",
"react-native-svg": "^12.1.0",
"react-native-vector-icons": "^7.0.0",
+ "react-native-video": "^5.1.1",
"react-promise-tracker": "^2.1.0",
"react-redux": "^7.2.2",
"reanimated-bottom-sheet": "^1.0.0-alpha.22",
@@ -109,4 +111,4 @@
"./node_modules/react-native-gesture-handler/jestSetup.js"
]
}
-}
+} \ No newline at end of file
diff --git a/patches/react-native-inappbrowser-reborn+3.5.1.patch b/patches/react-native-inappbrowser-reborn+3.5.1.patch
deleted file mode 100644
index 12a49b85..00000000
--- a/patches/react-native-inappbrowser-reborn+3.5.1.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-diff --git a/node_modules/react-native-inappbrowser-reborn/ios/RNInAppBrowser.m b/node_modules/react-native-inappbrowser-reborn/ios/RNInAppBrowser.m
-index 674e8f1..81f069e 100644
---- a/node_modules/react-native-inappbrowser-reborn/ios/RNInAppBrowser.m
-+++ b/node_modules/react-native-inappbrowser-reborn/ios/RNInAppBrowser.m
-@@ -90,15 +90,17 @@ RCT_EXPORT_METHOD(openAuth:(NSString *)authURL
- }
- };
-
-+ NSString *escapedRedirectURL = [redirectURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
-+
- if (@available(iOS 12.0, *)) {
- webAuthSession = [[ASWebAuthenticationSession alloc]
- initWithURL:url
-- callbackURLScheme:redirectURL
-+ callbackURLScheme:escapedRedirectURL
- completionHandler:completionHandler];
- } else {
- authSession = [[SFAuthenticationSession alloc]
- initWithURL:url
-- callbackURLScheme:redirectURL
-+ callbackURLScheme:escapedRedirectURL
- completionHandler:completionHandler];
- }
-
diff --git a/src/components/camera/GalleryIcon.tsx b/src/components/camera/GalleryIcon.tsx
index c49ace7d..8d396550 100644
--- a/src/components/camera/GalleryIcon.tsx
+++ b/src/components/camera/GalleryIcon.tsx
@@ -1,14 +1,12 @@
-import {useNavigation} from '@react-navigation/native';
import React from 'react';
import {Image, Text, TouchableOpacity, View} from 'react-native';
-import {ScreenType} from '../../types';
import {navigateToImagePicker} from '../../utils/camera';
+import {Image as ImageType} from 'react-native-image-crop-picker';
import {styles} from './styles';
interface GalleryIconProps {
- screenType: ScreenType;
- title: string;
mostRecentPhotoUri: string;
+ callback: (pic: ImageType) => void;
}
/*
@@ -16,14 +14,12 @@ interface GalleryIconProps {
* On click, navigates to the image picker
*/
export const GalleryIcon: React.FC<GalleryIconProps> = ({
- screenType,
- title,
mostRecentPhotoUri,
+ callback,
}) => {
- const navigation = useNavigation();
return (
<TouchableOpacity
- onPress={() => navigateToImagePicker(navigation, screenType, title)}
+ onPress={() => navigateToImagePicker(callback)}
style={styles.saveButton}>
{mostRecentPhotoUri !== '' ? (
<Image
diff --git a/src/components/camera/SaveButton.tsx b/src/components/camera/SaveButton.tsx
index 840cc804..0e220497 100644
--- a/src/components/camera/SaveButton.tsx
+++ b/src/components/camera/SaveButton.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import {Text, TouchableOpacity} from 'react-native';
import SaveIcon from '../../assets/icons/camera/save.svg';
-import {downloadImage} from '../../utils/camera';
+import {saveImageToGallery} from '../../utils/camera';
import {styles} from './styles';
interface SaveButtonProps {
@@ -15,7 +15,7 @@ interface SaveButtonProps {
export const SaveButton: React.FC<SaveButtonProps> = ({capturedImageURI}) => (
<TouchableOpacity
onPress={() => {
- downloadImage(capturedImageURI);
+ saveImageToGallery(capturedImageURI);
}}
style={styles.saveButton}>
<SaveIcon width={40} height={40} />
diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index 8a4ec082..33707d94 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -8,12 +8,11 @@ import {
View,
} from 'react-native';
import {useDispatch} from 'react-redux';
-import {TAGG_LIGHT_BLUE} from '../../constants';
import {CommentContext} from '../../screens/profile/MomentCommentsScreen';
import {postComment} from '../../services';
import {updateReplyPosted} from '../../store/actions';
import {CommentThreadType, CommentType} from '../../types';
-import {SCREEN_HEIGHT, SCREEN_WIDTH, normalize} from '../../utils';
+import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
import {mentionPartTypes} from '../../utils/comments';
import {CommentTextField} from './CommentTextField';
import MentionInputControlled from './MentionInputControlled';
@@ -174,26 +173,6 @@ const styles = StyleSheet.create({
flex: 1,
maxHeight: 100,
},
- avatar: {
- height: 35,
- width: 35,
- borderRadius: 30,
- marginRight: 10,
- marginLeft: '3%',
- marginVertical: '2%',
- alignSelf: 'flex-end',
- },
- submitButton: {
- height: 35,
- width: 35,
- backgroundColor: TAGG_LIGHT_BLUE,
- borderRadius: 999,
- justifyContent: 'center',
- alignItems: 'center',
- marginRight: '3%',
- marginVertical: '2%',
- alignSelf: 'flex-end',
- },
whiteBackround: {
backgroundColor: '#fff',
},
diff --git a/src/components/comments/CommentTextField.tsx b/src/components/comments/CommentTextField.tsx
index 6e92329c..6d86eb3f 100644
--- a/src/components/comments/CommentTextField.tsx
+++ b/src/components/comments/CommentTextField.tsx
@@ -1,8 +1,8 @@
import React, {FC, ReactFragment} from 'react';
import {
NativeSyntheticEvent,
- StyleSheet,
StyleProp,
+ StyleSheet,
Text,
TextInput,
TextInputSelectionChangeEventData,
@@ -10,22 +10,21 @@ import {
View,
ViewStyle,
} from 'react-native';
-import {useSelector} from 'react-redux';
-import {TAGG_LIGHT_BLUE} from '../../constants';
-import {RootState} from '../../store/rootReducer';
import {
+ MentionPartType,
Part,
PartType,
- MentionPartType,
} from 'react-native-controlled-mentions/dist/types';
import {
defaultMentionTextStyle,
isMentionPartType,
} from 'react-native-controlled-mentions/dist/utils';
-import {Avatar} from '../common';
-import {normalize} from '../../utils';
-
+import {useSelector} from 'react-redux';
import UpArrowIcon from '../../assets/icons/up_arrow.svg';
+import {TAGG_LIGHT_BLUE} from '../../constants';
+import {RootState} from '../../store/rootReducer';
+import {normalize} from '../../utils';
+import {Avatar} from '../common';
type CommentTextFieldProps = {
containerStyle: StyleProp<ViewStyle>;
@@ -40,8 +39,6 @@ type CommentTextFieldProps = {
) => null;
parts: Part[];
addComment: () => any;
- theme?: 'dark' | 'white';
- keyboardVisible?: boolean;
comment?: string;
};
@@ -56,8 +53,6 @@ const CommentTextField: FC<CommentTextFieldProps> = ({
handleSelectionChange,
parts,
addComment,
- theme = 'white',
- keyboardVisible = true,
comment = '',
...textInputProps
}) => {
@@ -99,20 +94,18 @@ const CommentTextField: FC<CommentTextFieldProps> = ({
)}
</Text>
</TextInput>
- {(theme === 'white' || (theme === 'dark' && keyboardVisible)) && (
- <View style={styles.submitButton}>
- <TouchableOpacity
- style={
- comment === ''
- ? [styles.submitButton, styles.greyButton]
- : styles.submitButton
- }
- disabled={comment === ''}
- onPress={addComment}>
- <UpArrowIcon width={35} height={35} color={'white'} />
- </TouchableOpacity>
- </View>
- )}
+ <View style={styles.submitButton}>
+ <TouchableOpacity
+ style={
+ comment === ''
+ ? [styles.submitButton, styles.greyButton]
+ : styles.submitButton
+ }
+ disabled={comment === ''}
+ onPress={addComment}>
+ <UpArrowIcon width={35} height={35} color={'white'} />
+ </TouchableOpacity>
+ </View>
</View>
{validateInput(keyboardText) &&
diff --git a/src/components/comments/CommentsCount.tsx b/src/components/comments/CommentsCount.tsx
index 90514193..d4a93bdd 100644
--- a/src/components/comments/CommentsCount.tsx
+++ b/src/components/comments/CommentsCount.tsx
@@ -3,27 +3,32 @@ import React from 'react';
import {StyleSheet, Text} from 'react-native';
import {TouchableOpacity} from 'react-native-gesture-handler';
import CommentsIcon from '../../assets/icons/moment-comment-icon.svg';
-import {MomentPostType, ScreenType} from '../../types';
+import {ScreenType} from '../../types';
import {normalize} from '../../utils';
interface CommentsCountProps {
- moment: MomentPostType;
+ momentId: string;
+ count: number;
screenType: ScreenType;
}
-const CommentsCount: React.FC<CommentsCountProps> = ({moment, screenType}) => {
+const CommentsCount: React.FC<CommentsCountProps> = ({
+ momentId,
+ count,
+ screenType,
+}) => {
const navigation = useNavigation();
return (
<TouchableOpacity
style={styles.countContainer}
onPress={() =>
navigation.navigate('MomentCommentsScreen', {
- moment_id: moment.moment_id,
+ moment_id: momentId,
screenType,
})
}>
<CommentsIcon width={25} height={25} />
- <Text style={styles.count}>{moment.comments_count}</Text>
+ <Text style={styles.count}>{count}</Text>
</TouchableOpacity>
);
};
diff --git a/src/components/comments/ZoomInCropper.tsx b/src/components/comments/ZoomInCropper.tsx
index 94e772b6..7fa88f6e 100644
--- a/src/components/comments/ZoomInCropper.tsx
+++ b/src/components/comments/ZoomInCropper.tsx
@@ -1,7 +1,7 @@
import {RouteProp} from '@react-navigation/core';
import {useFocusEffect} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
-import {default as React, useCallback, useEffect, useState} from 'react';
+import React, {useCallback, useEffect, useState} from 'react';
import {Image, StyleSheet, TouchableOpacity} from 'react-native';
import {normalize} from 'react-native-elements';
import ImageZoom, {IOnMove} from 'react-native-image-pan-zoom';
@@ -25,7 +25,7 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
route,
navigation,
}) => {
- const {screenType, title, image} = route.params;
+ const {screenType, title, media} = route.params;
const [aspectRatio, setAspectRatio] = useState<number>(1);
// Stores the coordinates of the cropped image
@@ -34,7 +34,6 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
const [y0, setY0] = useState<number>();
const [y1, setY1] = useState<number>();
- // Removes bottom navigation bar on current screen and add it back when navigating away
useFocusEffect(
useCallback(() => {
navigation.dangerouslyGetParent()?.setOptions({
@@ -50,9 +49,9 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
// Setting original aspect ratio of image
useEffect(() => {
- if (image.sourceURL) {
+ if (media.uri) {
Image.getSize(
- image.sourceURL,
+ media.uri,
(w, h) => {
setAspectRatio(w / h);
},
@@ -67,10 +66,9 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
x0 !== undefined &&
x1 !== undefined &&
y0 !== undefined &&
- y1 !== undefined &&
- image.sourceURL
+ y1 !== undefined
) {
- PhotoManipulator.crop(image.sourceURL, {
+ PhotoManipulator.crop(media.uri, {
x: x0,
y: y1,
width: Math.abs(x0 - x1),
@@ -80,7 +78,10 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
navigation.navigate('CaptionScreen', {
screenType,
title: title,
- image: {filename: croppedURL, path: croppedURL},
+ media: {
+ uri: croppedURL,
+ isVideo: false,
+ },
});
})
.catch((err) => console.log('err: ', err));
@@ -88,13 +89,12 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
x0 === undefined &&
x1 === undefined &&
y0 === undefined &&
- y1 === undefined &&
- image.sourceURL
+ y1 === undefined
) {
navigation.navigate('CaptionScreen', {
screenType,
title: title,
- image: {filename: image.sourceURL, path: image.sourceURL},
+ media,
});
}
};
@@ -104,7 +104,7 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
*/
const onMove = (position: IOnMove) => {
Image.getSize(
- image.path,
+ media.uri,
(w, h) => {
const x = position.positionX;
const y = position.positionY;
@@ -154,7 +154,7 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
<Image
style={{width: SCREEN_WIDTH, height: SCREEN_WIDTH / aspectRatio}}
source={{
- uri: image.sourceURL,
+ uri: media.uri,
}}
/>
</ImageZoom>
diff --git a/src/components/common/MomentTags.tsx b/src/components/common/MomentTags.tsx
index 4afacddb..d8a70353 100644
--- a/src/components/common/MomentTags.tsx
+++ b/src/components/common/MomentTags.tsx
@@ -1,4 +1,5 @@
-import React, {createRef, MutableRefObject, useEffect, useState} from 'react';
+import React, {createRef, RefObject, useEffect, useState} from 'react';
+import {Image, View} from 'react-native';
import {MomentTagType, ProfilePreviewType} from '../../types';
import TaggDraggable from '../taggs/TaggDraggable';
import Draggable from './Draggable';
@@ -7,7 +8,7 @@ interface MomentTagsProps {
editing: boolean;
tags: MomentTagType[];
setTags: (tag: MomentTagType[]) => void;
- imageRef: MutableRefObject<null>;
+ imageRef: RefObject<Image>;
deleteFromList?: (user: ProfilePreviewType) => void;
}
@@ -21,14 +22,9 @@ const MomentTags: React.FC<MomentTagsProps> = ({
const [offset, setOffset] = useState([0, 0]);
const [imageDimensions, setImageDimensions] = useState([0, 0]);
const [maxZIndex, setMaxZIndex] = useState(1);
- const [draggableRefs, setDraggableRefs] = useState<
- React.MutableRefObject<null>[]
- >([]);
+ const [draggableRefs, setDraggableRefs] = useState<RefObject<View>[]>([]);
- const updateTagPosition = (
- ref: React.MutableRefObject<null>,
- userId: string,
- ) => {
+ const updateTagPosition = (ref: RefObject<Image>, userId: string) => {
if (ref !== null && ref.current !== null) {
ref.current.measure(
(
diff --git a/src/components/moments/Moment.tsx b/src/components/moments/Moment.tsx
index 9449271b..1e1cadce 100644
--- a/src/components/moments/Moment.tsx
+++ b/src/components/moments/Moment.tsx
@@ -1,6 +1,6 @@
import {useNavigation} from '@react-navigation/native';
import React from 'react';
-import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native';
+import {Alert, StyleProp, StyleSheet, View, ViewStyle} from 'react-native';
import {Text} from 'react-native-animatable';
import {ScrollView, TouchableOpacity} from 'react-native-gesture-handler';
import LinearGradient from 'react-native-linear-gradient';
@@ -12,6 +12,8 @@ import UpIcon from '../../assets/icons/up_icon.svg';
import {TAGG_LIGHT_BLUE} from '../../constants';
import {MomentType, ScreenType} from '../../types';
import {normalize, SCREEN_WIDTH} from '../../utils';
+import {navigateToVideoPicker} from '../../utils/camera';
+import ImagePicker from 'react-native-image-crop-picker';
import MomentTile from './MomentTile';
interface MomentProps {
@@ -41,6 +43,17 @@ const Moment: React.FC<MomentProps> = ({
}) => {
const navigation = useNavigation();
+ const navigateToCaptionScreenForVideo = (uri: string) => {
+ navigation.navigate('CaptionScreen', {
+ screenType,
+ title,
+ media: {
+ uri,
+ isVideo: true,
+ },
+ });
+ };
+
const navigateToCameraScreen = () => {
navigation.navigate('CameraScreen', {
title,
@@ -84,7 +97,37 @@ const Moment: React.FC<MomentProps> = ({
<PlusIcon
width={23}
height={23}
- onPress={() => navigateToCameraScreen()}
+ onPress={() =>
+ Alert.alert('Video Upload', 'pick one', [
+ {
+ text: 'gallery',
+ onPress: () =>
+ navigateToVideoPicker((vid) =>
+ navigateToCaptionScreenForVideo(vid.path),
+ ),
+ },
+ {
+ text: 'camera (simulator will not work)',
+ onPress: () =>
+ ImagePicker.openCamera({
+ mediaType: 'video',
+ })
+ .then((vid) => {
+ if (vid.path) {
+ navigateToCaptionScreenForVideo(vid.path);
+ }
+ })
+ .catch((err) => console.error(err)),
+ },
+ ])
+ }
+ color={'black'}
+ style={styles.horizontalMargin}
+ />
+ <PlusIcon
+ width={23}
+ height={23}
+ onPress={navigateToCameraScreen}
color={TAGG_LIGHT_BLUE}
style={styles.horizontalMargin}
/>
@@ -114,7 +157,7 @@ const Moment: React.FC<MomentProps> = ({
/>
))}
{(images === undefined || images.length === 0) && !userXId && (
- <TouchableOpacity onPress={() => navigateToCameraScreen()}>
+ <TouchableOpacity onPress={navigateToCameraScreen}>
<LinearGradient
colors={['rgba(105, 141, 211, 1)', 'rgba(105, 141, 211, 0.3)']}>
<View style={styles.defaultImage}>
@@ -150,9 +193,6 @@ const styles = StyleSheet.create({
color: TAGG_LIGHT_BLUE,
maxWidth: '70%',
},
- flexer: {
- flex: 1,
- },
scrollContainer: {
height: SCREEN_WIDTH / 3.25,
backgroundColor: '#eee',
diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx
index 6eccf5ab..319542f9 100644
--- a/src/components/moments/MomentPost.tsx
+++ b/src/components/moments/MomentPost.tsx
@@ -1,5 +1,5 @@
import {useNavigation} from '@react-navigation/native';
-import React, {useContext, useEffect, useRef, useState} from 'react';
+import React, {useContext, useEffect, useMemo, useRef, useState} from 'react';
import {
Image,
KeyboardAvoidingView,
@@ -12,6 +12,7 @@ import {
View,
} from 'react-native';
import Animated, {EasingNode} from 'react-native-reanimated';
+import Video from 'react-native-video';
import {useDispatch, useSelector, useStore} from 'react-redux';
import {headerBarOptions} from '../../routes';
import {MomentContext} from '../../screens/profile/IndividualMoment';
@@ -71,7 +72,16 @@ const MomentPost: React.FC<MomentPostProps> = ({
const [momentTagId, setMomentTagId] = useState<string>('');
const imageRef = useRef(null);
- const {keyboardVisible} = useContext(MomentContext);
+ const videoRef = useRef<Video>(null);
+ const {keyboardVisible, currentVisibleMomentId} = useContext(MomentContext);
+ const isVideo = !(
+ moment.moment_url.endsWith('jpg') ||
+ moment.moment_url.endsWith('JPG') ||
+ moment.moment_url.endsWith('PNG') ||
+ moment.moment_url.endsWith('png') ||
+ moment.moment_url.endsWith('GIF') ||
+ moment.moment_url.endsWith('gif')
+ );
/*
* Load tags on initial render to pass tags data to moment header and content
@@ -126,13 +136,15 @@ const MomentPost: React.FC<MomentPostProps> = ({
* determine if image must be displayed in full screen or not
*/
useEffect(() => {
- Image.getSize(
- moment.moment_url,
- (w, h) => {
- setAspectRatio(w / h);
- },
- (err) => console.log(err),
- );
+ if (!isVideo) {
+ Image.getSize(
+ moment.moment_url,
+ (w, h) => {
+ setAspectRatio(w / h);
+ },
+ (err) => console.log(err),
+ );
+ }
}, []);
/*
@@ -155,22 +167,31 @@ const MomentPost: React.FC<MomentPostProps> = ({
}
}, [keyboardVisible, hideText]);
- const MomentPosterPreview = () => (
- <View style={styles.momentPosterContainer}>
- <TouchableOpacity
- onPress={() =>
- navigateToProfile(state, dispatch, navigation, screenType, user)
- }
- style={styles.header}>
- <TaggAvatar
- style={styles.avatar}
- userXId={userXId}
- screenType={screenType}
- editable={false}
- />
- <Text style={styles.headerText}>{user.username}</Text>
- </TouchableOpacity>
- </View>
+ useEffect(() => {
+ if (moment.moment_id !== currentVisibleMomentId) {
+ videoRef.current?.seek(0);
+ }
+ }, [currentVisibleMomentId]);
+
+ const momentPosterPreview = useMemo(
+ () => (
+ <View style={styles.momentPosterContainer}>
+ <TouchableOpacity
+ onPress={() =>
+ navigateToProfile(state, dispatch, navigation, screenType, user)
+ }
+ style={styles.header}>
+ <TaggAvatar
+ style={styles.avatar}
+ userXId={userXId}
+ screenType={screenType}
+ editable={false}
+ />
+ <Text style={styles.headerText}>{user.username}</Text>
+ </TouchableOpacity>
+ </View>
+ ),
+ [user.username],
);
return (
@@ -178,17 +199,44 @@ const MomentPost: React.FC<MomentPostProps> = ({
<StatusBar barStyle={'light-content'} />
<View style={styles.mainContainer}>
<View style={styles.imageContainer}>
- <Image
- source={{uri: moment.moment_url}}
- style={[
- styles.image,
- {
- height: SCREEN_WIDTH / aspectRatio,
- },
- ]}
- resizeMode={'contain'}
- ref={imageRef}
- />
+ {isVideo ? (
+ <View
+ ref={imageRef}
+ style={[
+ styles.media,
+ {
+ height: SCREEN_WIDTH / aspectRatio,
+ },
+ ]}>
+ <Video
+ ref={videoRef}
+ source={{
+ uri: moment.moment_url,
+ }}
+ volume={1}
+ style={[
+ styles.media,
+ {
+ height: SCREEN_WIDTH / aspectRatio,
+ },
+ ]}
+ repeat={true}
+ resizeMode={'contain'}
+ onLoad={(response) => {
+ const {width, height} = response.naturalSize;
+ setAspectRatio(width / height);
+ }}
+ paused={moment.moment_id !== currentVisibleMomentId}
+ />
+ </View>
+ ) : (
+ <Image
+ source={{uri: moment.moment_url}}
+ style={styles.media}
+ resizeMode={'contain'}
+ ref={imageRef}
+ />
+ )}
</View>
{visible && (
<Animated.View style={[styles.tagsContainer, {opacity: fadeValue}]}>
@@ -233,9 +281,13 @@ const MomentPost: React.FC<MomentPostProps> = ({
/>
)}
<View style={styles.commentsCountContainer}>
- <CommentsCount moment={moment} screenType={screenType} />
+ <CommentsCount
+ momentId={moment.moment_id}
+ count={commentCount}
+ screenType={screenType}
+ />
</View>
- <MomentPosterPreview />
+ {momentPosterPreview}
{!hideText && (
<>
{moment.caption !== '' &&
@@ -281,8 +333,9 @@ const MomentPost: React.FC<MomentPostProps> = ({
};
const styles = StyleSheet.create({
- image: {
+ media: {
zIndex: 0,
+ flex: 1,
},
imageContainer: {
height: SCREEN_HEIGHT,
@@ -340,6 +393,7 @@ const styles = StyleSheet.create({
},
commentsCountContainer: {
position: 'absolute',
+ zIndex: 3,
right: '2%',
bottom: SCREEN_HEIGHT * 0.12,
},
diff --git a/src/components/moments/legacy/MomentPostContent.tsx b/src/components/moments/legacy/MomentPostContent.tsx
index 6388be27..0e6e5eed 100644
--- a/src/components/moments/legacy/MomentPostContent.tsx
+++ b/src/components/moments/legacy/MomentPostContent.tsx
@@ -3,6 +3,7 @@ import React, {useContext, useEffect, useRef, useState} from 'react';
import {Image, StyleSheet, Text, View, ViewProps} from 'react-native';
import {TouchableWithoutFeedback} from 'react-native-gesture-handler';
import Animated, {EasingNode} from 'react-native-reanimated';
+import Video from 'react-native-video';
import {useDispatch, useStore} from 'react-redux';
import {MomentContext} from '../../../screens/profile/IndividualMoment';
import {RootState} from '../../../store/rootReducer';
@@ -32,14 +33,12 @@ interface MomentPostContentProps extends ViewProps {
screenType: ScreenType;
moment: MomentPostType;
momentTags: MomentTagType[];
- index: number;
}
const MomentPostContent: React.FC<MomentPostContentProps> = ({
screenType,
moment,
style,
momentTags,
- index,
}) => {
const [tags, setTags] = useState<MomentTagType[]>(momentTags);
const state: RootState = useStore().getState();
@@ -55,8 +54,14 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
);
const [commentPreview, setCommentPreview] =
useState<MomentCommentPreviewType | null>(moment.comment_preview);
- const {keyboardVisible, scrollTo} = useContext(MomentContext);
+ const {keyboardVisible} = useContext(MomentContext);
const [hideText, setHideText] = useState(false);
+ const isVideo = !(
+ moment.moment_url.endsWith('jpg') ||
+ moment.moment_url.endsWith('JPG') ||
+ moment.moment_url.endsWith('PNG') ||
+ moment.moment_url.endsWith('png')
+ );
useEffect(() => {
setTags(momentTags);
@@ -78,7 +83,6 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
setHideText(false);
}
}, [keyboardVisible, hideText]);
-
return (
<View style={[styles.container, style]}>
<TouchableWithoutFeedback
@@ -86,12 +90,34 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
setVisible(!visible);
setFadeValue(new Animated.Value(0));
}}>
- <Image
- ref={imageRef}
- style={styles.image}
- source={{uri: moment.moment_url}}
- resizeMode={'cover'}
- />
+ {isVideo ? (
+ <View ref={imageRef}>
+ <Video
+ // ref={imageRef}
+ source={{
+ uri: moment.moment_url,
+ }}
+ // HLS m3u8 version
+ // source={{
+ // uri: 'https://multiplatform-f.akamaihd.net/i/multi/will/bunny/big_buck_bunny_,640x360_400,640x360_700,640x360_1000,950x540_1500,.f4v.csmil/master.m3u8',
+ // }}
+ // mp4 version
+ // source={{
+ // uri: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
+ // }}
+ volume={1}
+ style={styles.image}
+ repeat={true}
+ />
+ </View>
+ ) : (
+ <Image
+ ref={imageRef}
+ style={styles.image}
+ source={{uri: moment.moment_url}}
+ resizeMode={'cover'}
+ />
+ )}
{tags.length > 0 && (
<Image
source={require('../../assets/icons/tag_indicate.png')}
@@ -115,7 +141,7 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
renderTextWithMentions({
value: moment.caption,
styles: styles.captionText,
- partTypes: mentionPartTypes('white'),
+ partTypes: mentionPartTypes('white', 'caption'),
onPress: (user: UserType) =>
navigateToProfile(
state,
@@ -145,7 +171,6 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
}}
onFocus={() => {
setHideText(true);
- scrollTo(index);
}}
isKeyboardAvoiding={false}
theme={'dark'}
diff --git a/src/components/profile/MomentMoreInfoDrawer.tsx b/src/components/profile/MomentMoreInfoDrawer.tsx
index dc4ebe32..910aa095 100644
--- a/src/components/profile/MomentMoreInfoDrawer.tsx
+++ b/src/components/profile/MomentMoreInfoDrawer.tsx
@@ -31,6 +31,13 @@ interface MomentMoreInfoDrawerProps extends ViewProps {
tags: MomentTagType[];
}
+type DrawerButtonType = [
+ string,
+ (event: GestureResponderEvent) => void,
+ JSX.Element?,
+ TextStyle?,
+][];
+
const MomentMoreInfoDrawer: React.FC<MomentMoreInfoDrawerProps> = (props) => {
const {
setIsOpen,
@@ -45,9 +52,7 @@ const MomentMoreInfoDrawer: React.FC<MomentMoreInfoDrawerProps> = (props) => {
const navigation = useNavigation();
- const [drawerButtons, setDrawerButtons] = useState<
- [string, (event: GestureResponderEvent) => void, JSX.Element?, TextStyle?][]
- >([]);
+ const [drawerButtons, setDrawerButtons] = useState<DrawerButtonType>([]);
const handleDeleteMoment = async () => {
setIsOpen(false);
diff --git a/src/components/profile/ProfileBody.tsx b/src/components/profile/ProfileBody.tsx
index c0ee508a..cc001516 100644
--- a/src/components/profile/ProfileBody.tsx
+++ b/src/components/profile/ProfileBody.tsx
@@ -80,7 +80,6 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
);
}}>{`${website}`}</Text>
)}
-
{userXId && isBlocked && (
<View style={styles.toggleButtonContainer}>
<ToggleButton
diff --git a/src/components/taggs/TaggDraggable.tsx b/src/components/taggs/TaggDraggable.tsx
index d458fab6..ea19591d 100644
--- a/src/components/taggs/TaggDraggable.tsx
+++ b/src/components/taggs/TaggDraggable.tsx
@@ -1,5 +1,5 @@
import {useNavigation} from '@react-navigation/native';
-import React from 'react';
+import React, {RefObject} from 'react';
import {
Image,
StyleSheet,
@@ -17,7 +17,7 @@ import {normalize} from '../../utils';
import {navigateToProfile} from '../../utils/users';
interface TaggDraggableProps extends ViewProps {
- draggableRef: React.MutableRefObject<null>;
+ draggableRef: RefObject<View>;
taggedUser: ProfilePreviewType;
editingView: boolean;
deleteFromList: () => void;
diff --git a/src/constants/api.ts b/src/constants/api.ts
index b55489d9..6dab1153 100644
--- a/src/constants/api.ts
+++ b/src/constants/api.ts
@@ -38,6 +38,7 @@ export const VERIFY_INVITATION_CODE_ENDPOUNT: string = API_URL + 'verify-code/';
export const COMMENTS_ENDPOINT: string = API_URL + 'comments/';
export const COMMENT_REACTIONS_ENDPOINT: string = API_URL + 'reaction-comment/';
export const COMMENT_REACTIONS_REPLY_ENDPOINT: string = API_URL + 'reaction-reply/';
+export const PRESIGNED_URL_ENDPOINT: string = API_URL + 'presigned-url/';
export const FRIENDS_ENDPOINT: string = API_URL + 'friends/';
export const ALL_USERS_ENDPOINT: string = API_URL + 'users/';
export const REPORT_ISSUE_ENDPOINT: string = API_URL + 'report/';
diff --git a/src/constants/regex.ts b/src/constants/regex.ts
index f934185d..61523203 100644
--- a/src/constants/regex.ts
+++ b/src/constants/regex.ts
@@ -36,7 +36,7 @@ export const nameRegex: RegExp = /^[A-Za-z'\-,. ]{2,20}$/;
* - match alphanumerics, and special characters used in URLs
*/
export const websiteRegex: RegExp =
- /^$|^(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,50}\.[a-zA-Z0-9()]{2,6}\b([-a-zA-Z0-9()@:%_+.~#?&\/=]{0,35})$/;
+ /^$|^(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,50}\.[a-zA-Z0-9()]{2,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]{0,35})$/;
/**
* The website regex has the following constraints
diff --git a/src/constants/strings.ts b/src/constants/strings.ts
index a1064f49..112bc546 100644
--- a/src/constants/strings.ts
+++ b/src/constants/strings.ts
@@ -77,7 +77,7 @@ You've been tagged by ${invitee}. Follow the instructions below to skip the line
Sign up and use this code to get in: ${inviteCode}\n ${APP_STORE_LINK}`;
export const SUCCESS_LAST_CONTACT_INVITE = 'Done! That was your last invite, hope you used it wisely!';
export const SUCCESS_LINK = (str: string) => `Successfully linked ${str} 🎉`;
-export const SUCCESS_PIC_UPLOAD = 'Beautiful, the picture was uploaded successfully!';
+export const SUCCESS_PIC_UPLOAD = 'Beautiful, the Moment was uploaded successfully!';
export const SUCCESS_PWD_RESET = 'Your password was reset successfully!';
export const SUCCESS_VERIFICATION_CODE_SENT = 'New verification code sent! Check your phone messages for your code';
export const UP_TO_DATE = 'Up-to-Date!';
diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx
index ef3fc7fd..a5d73988 100644
--- a/src/routes/main/MainStackNavigator.tsx
+++ b/src/routes/main/MainStackNavigator.tsx
@@ -2,7 +2,6 @@
* Note the name userXId here, it refers to the id of the user being visited
*/
import {createStackNavigator} from '@react-navigation/stack';
-import {Image} from 'react-native-image-crop-picker';
import {
CommentBaseType,
MomentTagType,
@@ -38,16 +37,16 @@ export type MainStackParams = {
};
CaptionScreen: {
title?: string;
- image?: {
- filename: string;
- path: string;
- };
+ media?: {uri: string; isVideo: boolean};
screenType: ScreenType;
selectedTags?: MomentTagType[];
moment?: MomentType;
};
TagFriendsScreen: {
- imagePath: string;
+ media: {
+ uri: string;
+ isVideo: boolean;
+ };
selectedTags?: MomentTagType[];
};
TagSelectionScreen: {
@@ -111,7 +110,7 @@ export type MainStackParams = {
Chat: undefined;
NewChatModal: undefined;
ZoomInCropper: {
- image: Image;
+ media: {uri: string; isVideo: boolean};
screenType: ScreenType;
title: string;
};
diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx
index f6adeab1..43760b60 100644
--- a/src/routes/main/MainStackScreen.tsx
+++ b/src/routes/main/MainStackScreen.tsx
@@ -332,6 +332,15 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => {
name="ZoomInCropper"
component={ZoomInCropper}
options={{
+ ...modalStyle,
+ gestureEnabled: false,
+ }}
+ />
+ <MainStack.Screen
+ name="CameraScreen"
+ component={CameraScreen}
+ options={{
+ ...modalStyle,
gestureEnabled: false,
}}
/>
@@ -407,18 +416,6 @@ const styles = StyleSheet.create({
letterSpacing: normalize(1.3),
fontWeight: '700',
},
- whiteHeaderTitle: {
- fontSize: normalize(16),
- letterSpacing: normalize(1.3),
- fontWeight: '700',
- color: 'white',
- },
- blackHeaderTitle: {
- fontSize: normalize(16),
- letterSpacing: normalize(1.3),
- fontWeight: '700',
- color: 'black',
- },
});
export default MainStackScreen;
diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx
index 1df5c2da..0f5d8073 100644
--- a/src/screens/chat/ChatListScreen.tsx
+++ b/src/screens/chat/ChatListScreen.tsx
@@ -6,10 +6,10 @@ import {useStore} from 'react-redux';
import {ChannelList, Chat} from 'stream-chat-react-native';
import {ChatContext} from '../../App';
import {TabsGradient} from '../../components';
+import EmptyContentView from '../../components/common/EmptyContentView';
import {ChannelPreview, MessagesHeader} from '../../components/messages';
import {MainStackParams} from '../../routes';
import {RootState} from '../../store/rootReducer';
-import EmptyContentView from '../../components/common/EmptyContentView';
import {
LocalAttachmentType,
LocalChannelType,
diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx
index c6ed1116..37b37264 100644
--- a/src/screens/moments/CameraScreen.tsx
+++ b/src/screens/moments/CameraScreen.tsx
@@ -1,6 +1,7 @@
import CameraRoll from '@react-native-community/cameraroll';
import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs';
-import {RouteProp, useFocusEffect} from '@react-navigation/core';
+import {RouteProp} from '@react-navigation/core';
+import {useFocusEffect} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import React, {createRef, useCallback, useEffect, useState} from 'react';
import {StyleSheet, TouchableOpacity, View} from 'react-native';
@@ -15,7 +16,7 @@ import {
} from '../../components';
import {MainStackParams} from '../../routes';
import {HeaderHeight, normalize, SCREEN_WIDTH} from '../../utils';
-import {takePicture} from '../../utils/camera';
+import {showGIFFailureAlert, takePicture} from '../../utils/camera';
type CameraScreenRouteProps = RouteProp<MainStackParams, 'CameraScreen'>;
export type CameraScreenNavigationProps = StackNavigationProp<
@@ -36,9 +37,6 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
const [mostRecentPhoto, setMostRecentPhoto] = useState<string>('');
const [showSaveButton, setShowSaveButton] = useState<boolean>(false);
- /*
- * Removes bottom navigation bar on current screen and add it back when navigating away
- */
useFocusEffect(
useCallback(() => {
navigation.dangerouslyGetParent()?.setOptions({
@@ -68,16 +66,24 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
);
}, [capturedImage]);
- /*
- * Appears once a picture has been captured to navigate to the caption screen
- */
- const handleNext = () => {
+ const navigateToCropper = (uri: string) => {
+ navigation.navigate('ZoomInCropper', {
+ screenType,
+ title,
+ media: {
+ uri,
+ isVideo: false,
+ },
+ });
+ };
+
+ const navigateToCaptionScreen = () => {
navigation.navigate('CaptionScreen', {
screenType,
title,
- image: {
- filename: capturedImage,
- path: capturedImage,
+ media: {
+ uri: capturedImage,
+ isVideo: false,
},
});
};
@@ -116,7 +122,10 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
)}
<TouchableOpacity
onPress={() =>
- takePicture(cameraRef, setShowSaveButton, setCapturedImage)
+ takePicture(cameraRef, (pic) => {
+ setShowSaveButton(true);
+ setCapturedImage(pic.uri);
+ })
}
style={styles.captureButtonContainer}>
<View style={styles.captureButton} />
@@ -124,7 +133,7 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
<View style={styles.bottomRightContainer}>
{capturedImage ? (
<TaggSquareButton
- onPress={handleNext}
+ onPress={navigateToCaptionScreen}
title={'Next'}
buttonStyle={'large'}
buttonColor={'blue'}
@@ -135,8 +144,17 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
) : (
<GalleryIcon
mostRecentPhotoUri={mostRecentPhoto}
- screenType={screenType}
- title={title}
+ callback={(pic) => {
+ const filename = pic.filename;
+ if (
+ filename &&
+ (filename.endsWith('gif') || filename.endsWith('GIF'))
+ ) {
+ showGIFFailureAlert(() => navigateToCropper(pic.path));
+ } else {
+ navigateToCropper(pic.path);
+ }
+ }}
/>
)}
</View>
@@ -155,11 +173,6 @@ const styles = StyleSheet.create({
flexDirection: 'column',
backgroundColor: 'black',
},
- preview: {
- flex: 1,
- justifyContent: 'flex-end',
- alignItems: 'center',
- },
captureButtonContainer: {
alignSelf: 'center',
backgroundColor: 'transparent',
diff --git a/src/screens/moments/TagFriendsScreen.tsx b/src/screens/moments/TagFriendsScreen.tsx
index 15926b5a..201caf49 100644
--- a/src/screens/moments/TagFriendsScreen.tsx
+++ b/src/screens/moments/TagFriendsScreen.tsx
@@ -1,16 +1,9 @@
import {RouteProp} from '@react-navigation/core';
import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useRef, useState} from 'react';
-import {
- Image,
- Keyboard,
- KeyboardAvoidingView,
- Platform,
- StyleSheet,
- TouchableWithoutFeedback,
- View,
-} from 'react-native';
+import {Image, StyleSheet, TouchableWithoutFeedback, View} from 'react-native';
import {Button} from 'react-native-elements';
+import Video from 'react-native-video';
import {MainStackParams} from 'src/routes';
import {
CaptionScreenHeader,
@@ -30,7 +23,7 @@ interface TagFriendsScreenProps {
route: TagFriendsScreenRouteProps;
}
const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => {
- const {imagePath, selectedTags} = route.params;
+ const {media, selectedTags} = route.params;
const navigation = useNavigation();
const imageRef = useRef(null);
const [tags, setTags] = useState<MomentTagType[]>([]);
@@ -54,26 +47,30 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => {
});
};
+ const setMediaDimensions = (width: number, height: number) => {
+ const imageAspectRatio = width / height;
+
+ // aspectRatio: >= 1 [Landscape] [1:1]
+ if (imageAspectRatio >= 1) {
+ setImageWidth(SCREEN_WIDTH);
+ setImageHeight(SCREEN_WIDTH / imageAspectRatio);
+ }
+ // aspectRatio: < 1 [Portrait]
+ if (imageAspectRatio < 1) {
+ setImageHeight(SCREEN_WIDTH);
+ setImageWidth(SCREEN_WIDTH * imageAspectRatio);
+ }
+ };
+
/*
- * Calculating image width and height with respect to it's enclosing view's dimensions
+ * Calculating image width and height with respect to it's enclosing view's dimensions. Only works for images.
*/
useEffect(() => {
- if (imageRef && imageRef.current) {
+ if (imageRef && imageRef.current && !media.isVideo) {
Image.getSize(
- imagePath,
+ media.uri,
(w, h) => {
- const imageAspectRatio = w / h;
-
- // aspectRatio: >= 1 [Landscape] [1:1]
- if (imageAspectRatio >= 1) {
- setImageWidth(SCREEN_WIDTH);
- setImageHeight(SCREEN_WIDTH / imageAspectRatio);
- }
- // aspectRatio: < 1 [Portrait]
- else if (imageAspectRatio < 1) {
- setImageHeight(SCREEN_WIDTH);
- setImageWidth(SCREEN_WIDTH * imageAspectRatio);
- }
+ setMediaDimensions(w, h);
},
(err) => console.log(err),
);
@@ -82,65 +79,85 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => {
return (
<SearchBackground>
- <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
- <KeyboardAvoidingView
- behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
- style={styles.flex}>
- <View style={styles.contentContainer}>
- <View style={styles.buttonsContainer}>
- <Button
- title="Cancel"
- buttonStyle={styles.button}
- onPress={() => navigation.goBack()}
- />
- <Button
- title="Done"
- titleStyle={styles.shareButtonTitle}
- buttonStyle={styles.button}
- onPress={handleDone}
+ <View style={styles.contentContainer}>
+ <View style={styles.buttonsContainer}>
+ <Button
+ title="Cancel"
+ buttonStyle={styles.button}
+ onPress={() => navigation.goBack()}
+ />
+ <Button
+ title="Done"
+ titleStyle={styles.shareButtonTitle}
+ buttonStyle={styles.button}
+ onPress={handleDone}
+ />
+ </View>
+ <CaptionScreenHeader
+ style={styles.header}
+ title={'Tap on photo to tag friends!'}
+ />
+ <TouchableWithoutFeedback
+ onPress={() =>
+ navigation.navigate('TagSelectionScreen', {
+ selectedTags: tags,
+ })
+ }>
+ {media.isVideo ? (
+ <View
+ style={{
+ width: imageWidth,
+ height: imageHeight,
+ marginVertical: (SCREEN_WIDTH - imageHeight) / 2,
+ marginHorizontal: (SCREEN_WIDTH - imageWidth) / 2,
+ }}
+ ref={imageRef}>
+ <Video
+ style={{
+ width: imageWidth,
+ height: imageHeight,
+ }}
+ source={{uri: media.uri}}
+ repeat={true}
+ onLoad={(response) => {
+ const {width, height, orientation} = response.naturalSize;
+ // portrait will flip width and height
+ if (orientation === 'portrait') {
+ setMediaDimensions(height, width);
+ } else {
+ setMediaDimensions(width, height);
+ }
+ }}
/>
</View>
- <CaptionScreenHeader
- style={styles.header}
- title={'Tap on photo to tag friends!'}
+ ) : (
+ <Image
+ ref={imageRef}
+ style={{
+ width: imageWidth,
+ height: imageHeight,
+ marginVertical: (SCREEN_WIDTH - imageHeight) / 2,
+ marginHorizontal: (SCREEN_WIDTH - imageWidth) / 2,
+ }}
+ source={{uri: media.uri}}
/>
- <TouchableWithoutFeedback
- onPress={() =>
- navigation.navigate('TagSelectionScreen', {
- selectedTags: tags,
- })
- }>
- <Image
- ref={imageRef}
- style={[
- {
- width: imageWidth,
- height: imageHeight,
- marginVertical: (SCREEN_WIDTH - imageHeight) / 2,
- marginHorizontal: (SCREEN_WIDTH - imageWidth) / 2,
- },
- styles.image,
- ]}
- source={{uri: imagePath}}
- />
- </TouchableWithoutFeedback>
- {tags.length !== 0 && (
- <MomentTags
- tags={tags}
- setTags={setTags}
- editing={true}
- imageRef={imageRef}
- deleteFromList={(user) =>
- setTags(tags.filter((tag) => tag.user.id !== user.id))
- }
- />
- )}
- <View style={styles.footerContainer}>
- <TagFriendsFooter tags={tags} setTags={setTags} />
- </View>
- </View>
- </KeyboardAvoidingView>
- </TouchableWithoutFeedback>
+ )}
+ </TouchableWithoutFeedback>
+ {tags.length !== 0 && (
+ <MomentTags
+ tags={tags}
+ setTags={setTags}
+ editing={true}
+ imageRef={imageRef}
+ deleteFromList={(user) =>
+ setTags(tags.filter((tag) => tag.user.id !== user.id))
+ }
+ />
+ )}
+ <View style={styles.footerContainer}>
+ <TagFriendsFooter tags={tags} setTags={setTags} />
+ </View>
+ </View>
</SearchBackground>
);
};
@@ -148,7 +165,6 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => {
const styles = StyleSheet.create({
contentContainer: {
paddingTop: StatusBarHeight,
- justifyContent: 'flex-end',
},
buttonsContainer: {
flexDirection: 'row',
@@ -166,19 +182,10 @@ const styles = StyleSheet.create({
header: {
marginVertical: 20,
},
- image: {zIndex: 0, justifyContent: 'center', alignSelf: 'center'},
- text: {
- position: 'relative',
- backgroundColor: 'white',
- width: '100%',
- paddingHorizontal: '2%',
- paddingVertical: '1%',
- height: 60,
- },
- flex: {
- flex: 1,
+ footerContainer: {
+ marginHorizontal: '5%',
+ marginTop: '3%',
},
- footerContainer: {marginHorizontal: '5%', marginTop: '3%'},
});
export default TagFriendsScreen;
diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx
index 75533a9b..05db8ed7 100644
--- a/src/screens/profile/CaptionScreen.tsx
+++ b/src/screens/profile/CaptionScreen.tsx
@@ -15,6 +15,7 @@ import {
} from 'react-native';
import {MentionInputControlled} from '../../components';
import {Button, normalize} from 'react-native-elements';
+import Video from 'react-native-video';
import {useDispatch, useSelector} from 'react-redux';
import FrontArrow from '../../assets/icons/front-arrow.svg';
import {SearchBackground} from '../../components';
@@ -27,7 +28,13 @@ import {
SUCCESS_PIC_UPLOAD,
} from '../../constants/strings';
import {MainStackParams} from '../../routes';
-import {patchMoment, postMoment, postMomentTags} from '../../services';
+import {
+ handlePresignedURL,
+ handleVideoUpload,
+ patchMoment,
+ postMoment,
+ postMomentTags,
+} from '../../services';
import {
loadUserMoments,
updateProfileCompletionStage,
@@ -51,7 +58,7 @@ interface CaptionScreenProps {
}
const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
- const {title, image, screenType, selectedTags, moment} = route.params;
+ const {title, screenType, selectedTags, moment} = route.params;
const {
user: {userId},
} = useSelector((state: RootState) => state.user);
@@ -62,6 +69,16 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
selectedTags ? selectedTags : [],
);
const [taggedList, setTaggedList] = useState<string>('');
+ const mediaUri = moment ? moment.moment_url : route.params.media!.uri;
+ // TODO: change this once moment refactor is done
+ const isMediaAVideo = moment
+ ? !(
+ moment.moment_url.endsWith('.jpg') ||
+ moment.moment_url.endsWith('.JPG') ||
+ moment.moment_url.endsWith('.png') ||
+ moment.moment_url.endsWith('.PNG')
+ )
+ : route.params.media?.isVideo ?? false;
useEffect(() => {
setTags(selectedTags ? selectedTags : []);
@@ -120,36 +137,50 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
const handleShare = async () => {
setLoading(true);
- if (!image?.filename || !title) {
- return;
- }
- const momentResponse = await postMoment(
- image.filename,
- image.path,
- caption,
- title,
- userId,
- );
- if (!momentResponse) {
+ if (moment || !title) {
handleFailed();
return;
}
- const momentTagResponse = await postMomentTags(
- momentResponse.moment_id,
- formattedTags(),
- );
- if (!momentTagResponse) {
- handleFailed();
- return;
+ let profileCompletionStage;
+ let momentId;
+ // separate upload logic for image/video
+ if (isMediaAVideo) {
+ const presignedURLResponse = await handlePresignedURL(title);
+ if (!presignedURLResponse) {
+ handleFailed();
+ return;
+ }
+ momentId = presignedURLResponse.moment_id;
+ const fileHash = presignedURLResponse.response_url.fields.key;
+ if (fileHash !== null && fileHash !== '' && fileHash !== undefined) {
+ await handleVideoUpload(mediaUri, presignedURLResponse);
+ } else {
+ handleFailed();
+ }
+ } else {
+ const momentResponse = await postMoment(mediaUri, caption, title, userId);
+ if (!momentResponse) {
+ handleFailed();
+ return;
+ }
+ profileCompletionStage = momentResponse.profile_completion_stage;
+ momentId = momentResponse.moment_id;
+ }
+ if (momentId) {
+ const momentTagResponse = await postMomentTags(momentId, formattedTags());
+ if (!momentTagResponse) {
+ handleFailed();
+ return;
+ }
}
dispatch(loadUserMoments(userId));
- dispatch(
- updateProfileCompletionStage(momentResponse.profile_completion_stage),
- );
+ if (profileCompletionStage) {
+ dispatch(updateProfileCompletionStage(profileCompletionStage));
+ }
handleSuccess();
};
- const handleDone = async () => {
+ const handleDoneEditing = async () => {
setLoading(true);
if (moment?.moment_id) {
const success = await patchMoment(
@@ -186,19 +217,26 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
title={moment ? 'Done' : 'Share'}
titleStyle={styles.shareButtonTitle}
buttonStyle={styles.button}
- onPress={moment ? handleDone : handleShare}
+ onPress={moment ? handleDoneEditing : handleShare}
/>
</View>
<CaptionScreenHeader
style={styles.header}
- {...{title: moment ? moment.moment_category : title}}
- />
- {/* this is the image we want to center our tags' initial location within */}
- <Image
- style={styles.image}
- source={{uri: moment ? moment.moment_url : image?.path}}
- resizeMode={'contain'}
+ {...{title: moment ? moment.moment_category : title ?? ''}}
/>
+ {isMediaAVideo ? (
+ <Video
+ style={styles.media}
+ source={{uri: mediaUri}}
+ repeat={true}
+ />
+ ) : (
+ <Image
+ style={styles.media}
+ source={{uri: mediaUri}}
+ resizeMode={'contain'}
+ />
+ )}
<MentionInputControlled
containerStyle={styles.text}
placeholder="Write something....."
@@ -210,11 +248,10 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
<TouchableOpacity
onPress={() =>
navigation.navigate('TagFriendsScreen', {
- imagePath: moment
- ? moment.moment_url
- : image
- ? image.path
- : '',
+ media: {
+ uri: mediaUri,
+ isVideo: isMediaAVideo,
+ },
selectedTags: tags,
})
}
@@ -257,7 +294,7 @@ const styles = StyleSheet.create({
header: {
marginVertical: 20,
},
- image: {
+ media: {
position: 'relative',
width: SCREEN_WIDTH,
aspectRatio: 1,
diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx
index ca31ad5b..7d231312 100644
--- a/src/screens/profile/IndividualMoment.tsx
+++ b/src/screens/profile/IndividualMoment.tsx
@@ -1,22 +1,17 @@
import {RouteProp} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import React, {useEffect, useRef, useState} from 'react';
-import {FlatList, Keyboard} from 'react-native';
+import {FlatList, Keyboard, ViewToken} from 'react-native';
import {useSelector} from 'react-redux';
import {MomentPost, TabsGradient} from '../../components';
-import {AVATAR_DIM} from '../../constants';
import {MainStackParams} from '../../routes';
import {RootState} from '../../store/rootreducer';
import {MomentPostType} from '../../types';
-import {isIPhoneX} from '../../utils';
-
-/**
- * Individual moment view opened when user clicks on a moment tile
- */
+import {SCREEN_HEIGHT} from '../../utils';
type MomentContextType = {
keyboardVisible: boolean;
- scrollTo: (index: number) => void;
+ currentVisibleMomentId: string | undefined;
};
export const MomentContext = React.createContext({} as MomentContextType);
@@ -48,6 +43,26 @@ const IndividualMoment: React.FC<IndividualMomentProps> = ({route}) => {
);
const initialIndex = momentData.findIndex((m) => m.moment_id === moment_id);
const [keyboardVisible, setKeyboardVisible] = useState(false);
+ const [currentVisibleMomentId, setCurrentVisibleMomentId] = useState<
+ string | undefined
+ >();
+ const [viewableItems, setViewableItems] = useState<ViewToken[]>([]);
+
+ // https://stackoverflow.com/a/57502343
+ const viewabilityConfigCallback = useRef(
+ (info: {viewableItems: ViewToken[]}) => {
+ setViewableItems(info.viewableItems);
+ },
+ );
+
+ useEffect(() => {
+ if (viewableItems.length > 0) {
+ const index = viewableItems[0].index;
+ if (index !== null && momentData.length > 0) {
+ setCurrentVisibleMomentId(momentData[index].moment_id);
+ }
+ }
+ }, [viewableItems]);
useEffect(() => {
const showKeyboard = () => setKeyboardVisible(true);
@@ -60,20 +75,11 @@ const IndividualMoment: React.FC<IndividualMomentProps> = ({route}) => {
};
}, []);
- const scrollTo = (index: number) => {
- // TODO: make this dynamic
- const offset = isIPhoneX() ? -(AVATAR_DIM + 100) : -(AVATAR_DIM + 160);
- scrollRef.current?.scrollToIndex({
- index: index,
- viewOffset: offset,
- });
- };
-
return (
<MomentContext.Provider
value={{
keyboardVisible,
- scrollTo,
+ currentVisibleMomentId,
}}>
<FlatList
ref={scrollRef}
@@ -89,13 +95,12 @@ const IndividualMoment: React.FC<IndividualMomentProps> = ({route}) => {
keyExtractor={(item, _) => item.moment_id}
showsVerticalScrollIndicator={false}
initialScrollIndex={initialIndex}
- onScrollToIndexFailed={(info) => {
- setTimeout(() => {
- scrollRef.current?.scrollToIndex({
- index: info.index,
- });
- }, 500);
- }}
+ onViewableItemsChanged={viewabilityConfigCallback.current}
+ getItemLayout={(data, index) => ({
+ length: SCREEN_HEIGHT,
+ offset: SCREEN_HEIGHT * index,
+ index,
+ })}
pagingEnabled
/>
<TabsGradient />
diff --git a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
index 39d98bcc..6156e950 100644
--- a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
+++ b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
@@ -44,6 +44,7 @@ const SuggestedPeopleScreen: React.FC = () => {
const [hideStatusBar, setHideStatusBar] = useState(false);
// boolean for showing/hiding loading indicator
const [loading, setLoading] = useState(true);
+ const [viewableItems, setViewableItems] = useState<ViewToken[]>([]);
// set loading to false once there are people to display
useEffect(() => {
@@ -59,6 +60,20 @@ const SuggestedPeopleScreen: React.FC = () => {
const stausBarRef = useRef(hideStatusBar);
+ // https://stackoverflow.com/a/57502343
+ const viewabilityConfigCallback = useRef(
+ (info: {viewableItems: ViewToken[]}) => {
+ setViewableItems(info.viewableItems);
+ },
+ );
+
+ useEffect(() => {
+ if (viewableItems.length > 0) {
+ setHideStatusBar(viewableItems[0].index !== 0);
+ stausBarRef.current = viewableItems[0].index !== 0;
+ }
+ }, [viewableItems]);
+
useEffect(() => {
const handlePageChange = async () => {
const checkAsync = await AsyncStorage.getItem(
@@ -208,14 +223,6 @@ const SuggestedPeopleScreen: React.FC = () => {
updateDisplayedUser(user, 'no_record', '');
};
- const onViewableItemsChanged = useCallback(
- ({viewableItems}: {viewableItems: ViewToken[]}) => {
- setHideStatusBar(viewableItems[0].index !== 0);
- stausBarRef.current = viewableItems[0].index !== 0;
- },
- [],
- );
-
useFocusEffect(() => {
if (suggested_people_linked === 0) {
navigation.navigate('SPWelcomeScreen');
@@ -244,7 +251,7 @@ const SuggestedPeopleScreen: React.FC = () => {
}}
keyExtractor={(_, index) => index.toString()}
showsVerticalScrollIndicator={false}
- onViewableItemsChanged={onViewableItemsChanged}
+ onViewableItemsChanged={viewabilityConfigCallback.current}
onEndReached={() => setPage(page + 1)}
onEndReachedThreshold={3}
refreshControl={
diff --git a/src/services/MomentService.ts b/src/services/MomentService.ts
index b837585a..0c93876a 100644
--- a/src/services/MomentService.ts
+++ b/src/services/MomentService.ts
@@ -5,12 +5,17 @@ import {
MOMENTTAG_ENDPOINT,
MOMENT_TAGS_ENDPOINT,
MOMENT_THUMBNAIL_ENDPOINT,
+ PRESIGNED_URL_ENDPOINT,
+ TAGG_CUSTOMER_SUPPORT,
} from '../constants';
-import {MomentPostType, MomentTagType} from '../types';
+import {
+ ERROR_SOMETHING_WENT_WRONG,
+ ERROR_SOMETHING_WENT_WRONG_REFRESH,
+} from '../constants/strings';
+import {MomentPostType, MomentTagType, PresignedURLResponse} from '../types';
import {checkImageUploadStatus} from '../utils';
export const postMoment = async (
- fileName: string,
uri: string,
caption: string,
category: string,
@@ -18,13 +23,10 @@ export const postMoment = async (
) => {
try {
const request = new FormData();
- //Manipulating filename to end with .jpg instead of .heic
- if (fileName.endsWith('.heic') || fileName.endsWith('.HEIC')) {
- fileName = fileName.split('.')[0] + '.jpg';
- }
+
request.append('image', {
uri: uri,
- name: fileName,
+ name: 'moment.jpg',
type: 'image/jpg',
});
request.append('moment', category);
@@ -208,3 +210,108 @@ export const deleteMomentTag = async (moment_tag_id: string) => {
return false;
}
};
+/**
+ * This function makes a request to the server in order to provide the client with a presigned URL.
+ * This is called first, in order for the client to directly upload a file to S3
+ * @param value: string | undefined
+ * @returns a PresignedURLResponse object
+ */
+export const handlePresignedURL = async (momentCategory: string) => {
+ try {
+ // TODO: just a random filename for video poc, we should not need to once complete
+ const randHash = Math.random().toString(36).substring(7);
+ const filename = `pc_${randHash}.mov`;
+ const token = await AsyncStorage.getItem('token');
+ const response = await fetch(PRESIGNED_URL_ENDPOINT, {
+ method: 'POST',
+ headers: {
+ Authorization: 'Token ' + token,
+ },
+ body: JSON.stringify({
+ filename,
+ category: momentCategory,
+ }),
+ });
+ const status = response.status;
+ let data: PresignedURLResponse = await response.json();
+ if (status === 200) {
+ return data;
+ } else {
+ if (status === 404) {
+ console.log(
+ `Please make sure that the email / username entered is registered with us. You may contact our customer support at ${TAGG_CUSTOMER_SUPPORT}`,
+ );
+ } else {
+ console.log(ERROR_SOMETHING_WENT_WRONG_REFRESH);
+ }
+ console.log(response);
+ }
+ } catch (error) {
+ console.log(error);
+ console.log(ERROR_SOMETHING_WENT_WRONG);
+ }
+};
+/**
+ * This util function takes in the file object and the PresignedURLResponse object, creates form data from the latter,
+ * and makes a post request to the presigned URL, sending the file object inside of the form data.
+ * @param filePath: the path to the file, including filename
+ * @param urlObj PresignedURLResponse | undefined
+ * @returns responseURL or boolean
+ */
+export const handleVideoUpload = async (
+ filePath: string,
+ urlObj: PresignedURLResponse | undefined,
+) => {
+ try {
+ if (urlObj === null || urlObj === undefined) {
+ console.log('Invalid urlObj');
+ return false;
+ }
+ const form = new FormData();
+ form.append('key', urlObj.response_url.fields.key);
+ form.append(
+ 'x-amz-algorithm',
+ urlObj.response_url.fields['x-amz-algorithm'],
+ );
+ form.append(
+ 'x-amz-credential',
+ urlObj.response_url.fields['x-amz-credential'],
+ );
+ form.append('x-amz-date', urlObj.response_url.fields['x-amz-date']);
+ form.append('policy', urlObj.response_url.fields.policy);
+ form.append(
+ 'x-amz-signature',
+ urlObj.response_url.fields['x-amz-signature'],
+ );
+ form.append('file', {
+ uri: filePath,
+ // other types such as 'quicktime' 'image' etc exist, and we can programmatically type this, but for now sticking with simple 'video'
+ type: 'video',
+ name: urlObj.response_url.fields.key,
+ });
+ const response = await fetch(urlObj.response_url.url, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ },
+ body: form,
+ });
+ const status = response.status;
+ if (status === 200 || status === 204) {
+ console.log('complete');
+ return true;
+ } else {
+ if (status === 404) {
+ console.log(
+ `Please make sure that the email / username entered is registered with us. You may contact our customer support at ${TAGG_CUSTOMER_SUPPORT}`,
+ );
+ } else {
+ console.log(ERROR_SOMETHING_WENT_WRONG_REFRESH);
+ }
+ }
+ } catch (error) {
+ console.log(error);
+ console.log(ERROR_SOMETHING_WENT_WRONG);
+ }
+ return false;
+};
diff --git a/src/types/types.ts b/src/types/types.ts
index 171a9ff3..416d9146 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -365,3 +365,19 @@ export type ReactionType = {
id: string;
type: ReactionOptionsType;
};
+// used to handle direct S3 uploads by packaging presigned_url info into one object
+export type PresignedURLResponse = {
+ response_msg: string;
+ response_url: {
+ url: string;
+ fields: {
+ key: string | undefined;
+ 'x-amz-algorithm': string;
+ 'x-amz-credential': string;
+ 'x-amz-date': string;
+ policy: string;
+ 'x-amz-signature': string;
+ };
+ };
+ moment_id: string;
+};
diff --git a/src/utils/camera.ts b/src/utils/camera.ts
index 73461ad7..3937129a 100644
--- a/src/utils/camera.ts
+++ b/src/utils/camera.ts
@@ -1,43 +1,41 @@
import CameraRoll from '@react-native-community/cameraroll';
-import {Dispatch, RefObject, SetStateAction} from 'react';
+import {RefObject} from 'react';
import {Alert} from 'react-native';
-import {RNCamera} from 'react-native-camera';
-import ImagePicker from 'react-native-image-crop-picker';
-import {ScreenType} from 'src/types';
+import {
+ RNCamera,
+ TakePictureOptions,
+ TakePictureResponse,
+} from 'react-native-camera';
+import ImagePicker, {Image, Video} from 'react-native-image-crop-picker';
import {ERROR_UPLOAD} from '../constants/strings';
/*
- * Captures a photo and pauses to shoe the preview of the picture taken
+ * Captures a photo and pauses to show the preview of the picture taken
*/
export const takePicture = (
cameraRef: RefObject<RNCamera>,
- setShowSaveButton: Dispatch<SetStateAction<boolean>>,
- setCapturedImage: Dispatch<SetStateAction<string>>,
+ callback: (pic: TakePictureResponse) => void,
) => {
if (cameraRef !== null) {
cameraRef.current?.pausePreview();
- const options = {
+ const options: TakePictureOptions = {
forceUpOrientation: true,
+ orientation: 'portrait',
writeExif: false,
};
- cameraRef.current?.takePictureAsync(options).then((response) => {
- setShowSaveButton(true);
- setCapturedImage(response.uri);
+ cameraRef.current?.takePictureAsync(options).then((pic) => {
+ callback(pic);
});
}
};
-export const downloadImage = (capturedImageURI: string) => {
+export const saveImageToGallery = (capturedImageURI: string) => {
CameraRoll.save(capturedImageURI, {album: 'Recents', type: 'photo'})
.then((_res) => Alert.alert('Saved to device!'))
.catch((_err) => Alert.alert('Failed to save to device!'));
};
-export const navigateToImagePicker = (
- navigation: any,
- screenType: ScreenType,
- title: string,
-) => {
+export const navigateToImagePicker = (callback: (pic: Image) => void) => {
ImagePicker.openPicker({
smartAlbums: [
'Favorites',
@@ -48,13 +46,23 @@ export const navigateToImagePicker = (
],
mediaType: 'photo',
})
- .then((picture) => {
- if ('path' in picture) {
- navigation.navigate('ZoomInCropper', {
- screenType,
- title,
- image: picture,
- });
+ .then((pic) => {
+ callback(pic);
+ })
+ .catch((err) => {
+ if (err.code && err.code !== 'E_PICKER_CANCELLED') {
+ Alert.alert(ERROR_UPLOAD);
+ }
+ });
+};
+
+export const navigateToVideoPicker = (callback: (vid: Video) => void) => {
+ ImagePicker.openPicker({
+ mediaType: 'video',
+ })
+ .then(async (vid) => {
+ if (vid.path) {
+ callback(vid);
}
})
.catch((err) => {
@@ -63,3 +71,28 @@ export const navigateToImagePicker = (
}
});
};
+
+export const showGIFFailureAlert = (onSuccess: () => void) =>
+ Alert.alert(
+ 'Warning',
+ 'The app currently cannot handle GIFs, and will only save a static image.',
+ [
+ {
+ text: 'Cancel',
+ onPress: () => {},
+ style: 'cancel',
+ },
+ {
+ text: 'Post',
+ onPress: onSuccess,
+ style: 'default',
+ },
+ ],
+ {
+ cancelable: true,
+ onDismiss: () =>
+ Alert.alert(
+ 'This alert was dismissed by tapping outside of the alert dialog.',
+ ),
+ },
+ );
diff --git a/yarn.lock b/yarn.lock
index a0ac5baf..8dff89cf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9,22 +9,22 @@
dependencies:
"@babel/highlight" "^7.14.5"
-"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.5.tgz#8ef4c18e58e801c5c95d3c1c0f2874a2680fadea"
- integrity sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w==
+"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7":
+ version "7.14.7"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08"
+ integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==
"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.6.2":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.5.tgz#d281f46a9905f07d1b3bf71ead54d9c7d89cb1e3"
- integrity sha512-RN/AwP2DJmQTZSfiDaD+JQQ/J99KsIpOCfBE5pL+5jJSt7nI3nYGoAXZu+ffYSQ029NLs2DstZb+eR81uuARgg==
+ version "7.14.6"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab"
+ integrity sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==
dependencies:
"@babel/code-frame" "^7.14.5"
"@babel/generator" "^7.14.5"
"@babel/helper-compilation-targets" "^7.14.5"
"@babel/helper-module-transforms" "^7.14.5"
- "@babel/helpers" "^7.14.5"
- "@babel/parser" "^7.14.5"
+ "@babel/helpers" "^7.14.6"
+ "@babel/parser" "^7.14.6"
"@babel/template" "^7.14.5"
"@babel/traverse" "^7.14.5"
"@babel/types" "^7.14.5"
@@ -69,10 +69,10 @@
browserslist "^4.16.6"
semver "^6.3.0"
-"@babel/helper-create-class-features-plugin@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.5.tgz#8842ec495516dd1ed8f6c572be92ba78b1e9beef"
- integrity sha512-Uq9z2e7ZtcnDMirRqAGLRaLwJn+Lrh388v5ETrR3pALJnElVh2zqQmdbz4W2RUJYohAPh2mtyPUgyMHMzXMncQ==
+"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.14.6":
+ version "7.14.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz#f114469b6c06f8b5c59c6c4e74621f5085362542"
+ integrity sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==
dependencies:
"@babel/helper-annotate-as-pure" "^7.14.5"
"@babel/helper-function-name" "^7.14.5"
@@ -134,9 +134,9 @@
"@babel/types" "^7.14.5"
"@babel/helper-member-expression-to-functions@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.5.tgz#d5c70e4ad13b402c95156c7a53568f504e2fb7b8"
- integrity sha512-UxUeEYPrqH1Q/k0yRku1JE7dyfyehNwT6SVkMHvYvPDv4+uu627VXBckVj891BO8ruKBkiDoGnZf4qPDD8abDQ==
+ version "7.14.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz#97e56244beb94211fe277bd818e3a329c66f7970"
+ integrity sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==
dependencies:
"@babel/types" "^7.14.5"
@@ -173,6 +173,15 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
+"@babel/helper-remap-async-to-generator@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz#51439c913612958f54a987a4ffc9ee587a2045d6"
+ integrity sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.14.5"
+ "@babel/helper-wrap-function" "^7.14.5"
+ "@babel/types" "^7.14.5"
+
"@babel/helper-replace-supers@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz#0ecc0b03c41cd567b4024ea016134c28414abb94"
@@ -214,10 +223,20 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==
-"@babel/helpers@^7.14.5":
+"@babel/helper-wrap-function@^7.14.5":
version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.5.tgz#4870f8d9a6fdbbd65e5674a3558b4ff7fef0d9b2"
- integrity sha512-xtcWOuN9VL6nApgVHtq3PPcQv5qFBJzoSZzJ/2c0QK/IP/gxVcoWSNQwFEGvmbQsuS9rhYqjILDGGXcTkA705Q==
+ resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz#5919d115bf0fe328b8a5d63bcb610f51601f2bff"
+ integrity sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ==
+ dependencies:
+ "@babel/helper-function-name" "^7.14.5"
+ "@babel/template" "^7.14.5"
+ "@babel/traverse" "^7.14.5"
+ "@babel/types" "^7.14.5"
+
+"@babel/helpers@^7.14.6":
+ version "7.14.6"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.6.tgz#5b58306b95f1b47e2a0199434fa8658fa6c21635"
+ integrity sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==
dependencies:
"@babel/template" "^7.14.5"
"@babel/traverse" "^7.14.5"
@@ -232,10 +251,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.5.tgz#4cd2f346261061b2518873ffecdf1612cb032829"
- integrity sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==
+"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0":
+ version "7.14.7"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595"
+ integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==
"@babel/plugin-external-helpers@^7.0.0":
version "7.14.5"
@@ -269,11 +288,11 @@
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
"@babel/plugin-proposal-object-rest-spread@^7.0.0":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.5.tgz#e581d5ccdfa187ea6ed73f56c6a21c1580b90fbf"
- integrity sha512-VzMyY6PWNPPT3pxc5hi9LloKNr4SSrVCg7Yr6aZpW4Ym07r7KqSU/QXYwjXLVxqwSv0t/XSXkFoKBPUkZ8vb2A==
+ version "7.14.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363"
+ integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g==
dependencies:
- "@babel/compat-data" "^7.14.5"
+ "@babel/compat-data" "^7.14.7"
"@babel/helper-compilation-targets" "^7.14.5"
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-syntax-object-rest-spread" "^7.8.3"
@@ -373,6 +392,15 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
+"@babel/plugin-transform-async-to-generator@^7.0.0":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz#72c789084d8f2094acb945633943ef8443d39e67"
+ integrity sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==
+ dependencies:
+ "@babel/helper-module-imports" "^7.14.5"
+ "@babel/helper-plugin-utils" "^7.14.5"
+ "@babel/helper-remap-async-to-generator" "^7.14.5"
+
"@babel/plugin-transform-block-scoped-functions@^7.0.0":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz#e48641d999d4bc157a67ef336aeb54bc44fd3ad4"
@@ -408,9 +436,9 @@
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-transform-destructuring@^7.0.0":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.5.tgz#d32ad19ff1a6da1e861dc62720d80d9776e3bf35"
- integrity sha512-wU9tYisEbRMxqDezKUqC9GleLycCRoUsai9ddlsq54r8QRLaeEhc+d+9DqCG+kV9W2GgQjTZESPTpn5bAFMDww==
+ version "7.14.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz#0ad58ed37e23e22084d109f185260835e5557576"
+ integrity sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
@@ -557,9 +585,9 @@
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-transform-spread@^7.0.0":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.5.tgz#bd269fb4119754d2ce7f4cc39a96b4f71baae356"
- integrity sha512-/3iqoQdiWergnShZYl0xACb4ADeYCJ7X/RgmwtXshn6cIvautRPAFzhd58frQlokLO6Jb4/3JXvmm6WNTPtiTw==
+ version "7.14.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz#6bd40e57fe7de94aa904851963b5616652f73144"
+ integrity sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/helper-skip-transparent-expression-wrappers" "^7.14.5"
@@ -579,11 +607,11 @@
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-transform-typescript@^7.5.0":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.5.tgz#5b41b59072f765bd1ec1d0b694e08c7df0f6f8a0"
- integrity sha512-cFD5PKp4b8/KkwQ7h71FdPXFvz1RgwTFF9akRZwFldb9G0AHf7CgoPx96c4Q/ZVjh6V81tqQwW5YiHws16OzPg==
+ version "7.14.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz#6e9c2d98da2507ebe0a883b100cde3c7279df36c"
+ integrity sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA==
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.14.5"
+ "@babel/helper-create-class-features-plugin" "^7.14.6"
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-syntax-typescript" "^7.14.5"
@@ -607,24 +635,24 @@
source-map-support "^0.5.16"
"@babel/runtime-corejs3@^7.12.1":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.14.5.tgz#0d9bf00d59c0b73185c462c323efffd0f4c37283"
- integrity sha512-cBbwXj3F2xjnQJ0ERaFRLjxhUSBYsQPXJ7CERz/ecx6q6hzQ99eTflAPFC3ks4q/IG4CWupNVdflc4jlFBJVsg==
+ version "7.14.7"
+ resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.14.7.tgz#0ef292bbce40ca00f874c9724ef175a12476465c"
+ integrity sha512-Wvzcw4mBYbTagyBVZpAJWI06auSIj033T/yNE0Zn1xcup83MieCddZA7ls3kme17L4NOGBrQ09Q+nKB41RLWBA==
dependencies:
- core-js-pure "^3.14.0"
+ core-js-pure "^3.15.0"
regenerator-runtime "^0.13.4"
-"@babel/runtime@7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d"
- integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw==
+"@babel/runtime@7.13.10":
+ version "7.13.10"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
+ integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.13.10", "@babel/runtime@^7.6.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.5.tgz#665450911c6031af38f81db530f387ec04cd9a98"
- integrity sha512-121rumjddw9c3NCQ55KGkyE1h/nzWhU/owjhw0l4mQrkzz4x9SGS1X8gFLraHwX7td3Yo4QTL+qj0NcIzN87BA==
+ version "7.14.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d"
+ integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==
dependencies:
regenerator-runtime "^0.13.4"
@@ -638,16 +666,16 @@
"@babel/types" "^7.14.5"
"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.4":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.5.tgz#c111b0f58afab4fea3d3385a406f692748c59870"
- integrity sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==
+ version "7.14.7"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753"
+ integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==
dependencies:
"@babel/code-frame" "^7.14.5"
"@babel/generator" "^7.14.5"
"@babel/helper-function-name" "^7.14.5"
"@babel/helper-hoist-variables" "^7.14.5"
"@babel/helper-split-export-declaration" "^7.14.5"
- "@babel/parser" "^7.14.5"
+ "@babel/parser" "^7.14.7"
"@babel/types" "^7.14.5"
debug "^4.1.0"
globals "^11.1.0"
@@ -675,14 +703,23 @@
dependencies:
"@types/hammerjs" "^2.0.36"
-"@gorhom/bottom-sheet@3.0.0-alpha.0":
- version "3.0.0-alpha.0"
- resolved "https://registry.yarnpkg.com/@gorhom/bottom-sheet/-/bottom-sheet-3.0.0-alpha.0.tgz#deb165324335b331b8bb1d22db9ada03bc475b7c"
- integrity sha512-1509wJEPShPhAFCY2Bcrdt9O0oLFrDk3Rs6XNcSzY4M+JDQTbEvzsL3NehZOMK++ObebaIyOzq+ViossG3jWnw==
+"@gorhom/bottom-sheet@3.6.4":
+ version "3.6.4"
+ resolved "https://registry.yarnpkg.com/@gorhom/bottom-sheet/-/bottom-sheet-3.6.4.tgz#9f8c590493e1067dd638b69d7d7f1e86089844fc"
+ integrity sha512-jWZH64tur/PdwCdv6Ojt3Q85f/Q2LuyHV7gYjrN/30INnQw8ArRTOLUmLoLnwWFxeh561JdQ+XTvE53Hjo9wOw==
dependencies:
+ "@gorhom/portal" "^1.0.4"
invariant "^2.2.4"
- lodash.isequal "^4.5.0"
- react-native-redash "^15.11.1"
+ nanoid "^3.1.20"
+ react-native-redash "^16.0.10"
+
+"@gorhom/portal@^1.0.4":
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/@gorhom/portal/-/portal-1.0.7.tgz#e27cd40f8e2b6cb742050bcaa00fdcf94f3dfca8"
+ integrity sha512-lDZZ5/cjvg1GHrK6Swljv1EssndiVz0iXsIOpsI8FS6IDyxIDDnzbHQ6ZhLp95jDhDyE0UTUsAjL2PeI2yVKMQ==
+ dependencies:
+ immer "^9.0.3"
+ nanoid "^3.1.23"
"@hapi/address@2.x.x":
version "2.1.4"
@@ -1241,9 +1278,9 @@
"@babel/types" "^7.0.0"
"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6":
- version "7.11.1"
- resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639"
- integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==
+ version "7.14.0"
+ resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.0.tgz#a34277cf8acbd3185ea74129e1f100491eb1da7f"
+ integrity sha512-IilJZ1hJBUZwMOVDNTdflOOLzJB/ZtljYVa7k3gEZN/jqIJIPkWHC6dvbX+DD2CwZDHB9wAKzZPzzqMIkW37/w==
dependencies:
"@babel/types" "^7.3.0"
@@ -1298,16 +1335,16 @@
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
"@types/jsonwebtoken@^8.5.0":
- version "8.5.1"
- resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#56958cb2d80f6d74352bd2e501a018e2506a8a84"
- integrity sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw==
+ version "8.5.2"
+ resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.2.tgz#eb71c717b3b8681bb85fbd2950c9c4c5d4506748"
+ integrity sha512-X8BOCkp+WJVNYCYIBugREtVZa4Y09Or9HDx6xqRZem5F8jJV8FuJgNessXyMuv9+U8pjnvdezASwU28uw+1scw==
dependencies:
"@types/node" "*"
"@types/node@*":
- version "15.12.2"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d"
- integrity sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==
+ version "15.12.5"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.5.tgz#9a78318a45d75c9523d2396131bd3cca54b2d185"
+ integrity sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg==
"@types/prop-types@*":
version "15.7.3"
@@ -1328,9 +1365,17 @@
"@types/react-native" "*"
"@types/react-native-vector-icons@^6.4.5":
- version "6.4.6"
- resolved "https://registry.yarnpkg.com/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.6.tgz#848e3b14572def56212cafbf5cb1254b445bfb41"
- integrity sha512-lAyxNfMd5L1xZvXWsGcJmNegDf61TAp40uL6ashNNWj9W3IrDJO59L9+9inh0Y2MsEZpLTdxzVU8Unb4/0FQng==
+ version "6.4.7"
+ resolved "https://registry.yarnpkg.com/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.7.tgz#862039d668afcff42690b179b2a61dc762b84f73"
+ integrity sha512-srU4IWO5ghzm96dwyiKRYJCGD+Q0Lcu8NsWOXLi4pRPH24mb68XhrqW5Gb63AeiXlAOFsaOl2Irlsg79BNYt4A==
+ dependencies:
+ "@types/react" "*"
+ "@types/react-native" "*"
+
+"@types/react-native-video@^5.0.6":
+ version "5.0.7"
+ resolved "https://registry.yarnpkg.com/@types/react-native-video/-/react-native-video-5.0.7.tgz#f1d05698c62f2c9b54cff6cf7050bca2052bac99"
+ integrity sha512-ITJ9K3jEaP1hX58JhLvXJHGdNAkIKAYDxGZMiYys+5h3AOjFmdg7B3lqmoOc5+dGL41op3h1dNDoqstDD+H8eg==
dependencies:
"@types/react" "*"
"@types/react-native" "*"
@@ -1386,9 +1431,9 @@
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
"@types/ws@^7.4.0":
- version "7.4.4"
- resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.4.tgz#93e1e00824c1de2608c30e6de4303ab3b4c0c9bc"
- integrity sha512-d/7W23JAXPodQNbOZNXvl2K+bqAQrCMwlh/nuQsPSQk6Fq0opHoPrUw43aHsvSbIiQPr8Of2hkFbnz1XBFVyZQ==
+ version "7.4.5"
+ resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.5.tgz#8ff0f7efcd8fea19f51f9dd66cb8b498d172a752"
+ integrity sha512-8mbDgtc8xpxDDem5Gwj76stBDJX35KQ3YBoayxlqUQcL5BZUthiqP/VQ4PQnLHqM4PmlbyO74t98eJpURO+gPA==
dependencies:
"@types/node" "*"
@@ -1854,12 +1899,12 @@ babel-plugin-polyfill-corejs2@^0.2.2:
semver "^6.1.1"
babel-plugin-polyfill-corejs3@^0.2.2:
- version "0.2.2"
- resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz#7424a1682ee44baec817327710b1b094e5f8f7f5"
- integrity sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A==
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz#72add68cf08a8bf139ba6e6dfc0b1d504098e57b"
+ integrity sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.2.2"
- core-js-compat "^3.9.1"
+ core-js-compat "^3.14.0"
babel-plugin-polyfill-regenerator@^0.2.2:
version "0.2.2"
@@ -2119,9 +2164,9 @@ camelcase@^5.0.0, camelcase@^5.3.1:
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
caniuse-lite@^1.0.30001219:
- version "1.0.30001236"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001236.tgz#0a80de4cdf62e1770bb46a30d884fc8d633e3958"
- integrity sha512-o0PRQSrSCGJKCPZcgMzl5fUaj5xHe8qA2m4QRvnyY4e1lITqoNkr7q/Oh1NcpGSy0Th97UZ35yoKcINPoq7YOQ==
+ version "1.0.30001241"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001241.tgz#cd3fae47eb3d7691692b406568d7a3e5b23c7598"
+ integrity sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ==
capture-exit@^2.0.0:
version "2.0.0"
@@ -2422,9 +2467,9 @@ connect@^3.6.5:
utils-merge "1.0.1"
convert-source-map@^1.4.0, convert-source-map@^1.7.0:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
- integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
+ integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
dependencies:
safe-buffer "~5.1.1"
@@ -2433,18 +2478,18 @@ copy-descriptor@^0.1.0:
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
-core-js-compat@^3.9.1:
- version "3.14.0"
- resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.14.0.tgz#b574dabf29184681d5b16357bd33d104df3d29a5"
- integrity sha512-R4NS2eupxtiJU+VwgkF9WTpnSfZW4pogwKHd8bclWU2sp93Pr5S1uYJI84cMOubJRou7bcfL0vmwtLslWN5p3A==
+core-js-compat@^3.14.0:
+ version "3.15.2"
+ resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.15.2.tgz#47272fbb479880de14b4e6081f71f3492f5bd3cb"
+ integrity sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==
dependencies:
browserslist "^4.16.6"
semver "7.0.0"
-core-js-pure@^3.14.0:
- version "3.14.0"
- resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.14.0.tgz#72bcfacba74a65ffce04bf94ae91d966e80ee553"
- integrity sha512-YVh+LN2FgNU0odThzm61BsdkwrbrchumFq3oztnE9vTKC4KS2fvnPmcx8t6jnqAyOTCTF4ZSiuK8Qhh7SNcL4g==
+core-js-pure@^3.15.0:
+ version "3.15.2"
+ resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.15.2.tgz#c8e0874822705f3385d3197af9348f7c9ae2e3ce"
+ integrity sha512-D42L7RYh1J2grW8ttxoY1+17Y4wXZeKe7uyplAI3FkNQyI5OgBIAjUfFiTPfL1rs0qLpxaabITNbjKl1Sp82tA==
core-js@^1.0.0:
version "1.2.7"
@@ -2785,9 +2830,14 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.723:
- version "1.3.752"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz#0728587f1b9b970ec9ffad932496429aef750d09"
- integrity sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==
+ version "1.3.762"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.762.tgz#3fa4e3bcbda539b50e3aa23041627063a5cffe61"
+ integrity sha512-LehWjRpfPcK8F1Lf/NZoAwWLWnjJVo0SZeQ9j/tvnBWYcT99qDqgo4raAfS2oTKZjPrR/jxruh85DGgDUmywEA==
+
+eme-encryption-scheme-polyfill@^2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/eme-encryption-scheme-polyfill/-/eme-encryption-scheme-polyfill-2.0.3.tgz#2ca6e06480e06cceb5e50efd27943ac46c959878"
+ integrity sha512-44CNFMsqzHdKHrzWxlS7xZ8KUHn5XutBqpmCuWzNIynmAyFInHrrD3ozv/RvK9ZhgV6QY6Easx8EWAmxteNodg==
emoji-regex@^7.0.1:
version "7.0.3"
@@ -3857,10 +3907,10 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
-i18next@19.8.7:
- version "19.8.7"
- resolved "https://registry.yarnpkg.com/i18next/-/i18next-19.8.7.tgz#ef023e353974d1b1453e8b6331bd9fb7cba427df"
- integrity sha512-ezo1gb7QO4OQ5gQCdZMUxopwQSoqpRp6whdEjm1grxMSmkGj1NJ+kYS0UQd4NnpPIVqsgqTQ2L2eqSQYQ+U3Fw==
+i18next@20.2.4:
+ version "20.2.4"
+ resolved "https://registry.yarnpkg.com/i18next/-/i18next-20.2.4.tgz#972220f19dfef0075a70890d3e8b1f7cf64c5bd6"
+ integrity sha512-goE1LCA/IZOGG26PkkqoOl2KWR7YP606SvokVQZ29J6QwE02KycrzNetoMUJeqYrTxs4rmiiZgZp+q8qofQL6Q==
dependencies:
"@babel/runtime" "^7.12.0"
@@ -3900,7 +3950,7 @@ image-size@^0.6.0:
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.3.tgz#e7e5c65bb534bd7cdcedd6cb5166272a85f75fb2"
integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==
-immer@^9.0.1:
+immer@^9.0.1, immer@^9.0.3:
version "9.0.3"
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.3.tgz#146e2ba8b84d4b1b15378143c2345559915097f4"
integrity sha512-mONgeNSMuyjIe0lkQPa9YhdmTv8P19IeHV0biYhcXhbd5dhdB9HSK93zBpyKjp6wersSUgT5QyU0skmejUVP2A==
@@ -4865,6 +4915,11 @@ jws@^3.2.2:
jwa "^1.4.1"
safe-buffer "^5.0.1"
+keymirror@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/keymirror/-/keymirror-0.1.1.tgz#918889ea13f8d0a42e7c557250eee713adc95c35"
+ integrity sha1-kYiJ6hP40KQufFVyUO7nE63JXDU=
+
kind-of@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44"
@@ -4989,10 +5044,10 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
-lodash-es@4.17.20:
- version "4.17.20"
- resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.20.tgz#29f6332eefc60e849f869c264bc71126ad61e8f7"
- integrity sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA==
+lodash-es@4.17.21:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
+ integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
lodash._reinterpolate@^3.0.0:
version "3.0.0"
@@ -5304,10 +5359,10 @@ metro-react-native-babel-preset@0.59.0:
"@babel/template" "^7.0.0"
react-refresh "^0.4.0"
-metro-react-native-babel-preset@0.65.0:
- version "0.65.0"
- resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.65.0.tgz#1b9a1b3932bb80670f2319be2f9cca7770bd2411"
- integrity sha512-mgs+Z5atqlxm4/+k7KZo38smLThUzcUm6fRMzwtBQBJFr757tw2gEykjXKMOP1gKjoDVd8KDoU6EAgNtX9l05w==
+metro-react-native-babel-preset@0.66.0:
+ version "0.66.0"
+ resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.66.0.tgz#a4495df4b24a2eb9f82705e0a53f4cbbd36d983e"
+ integrity sha512-rO3yayxplLNxFDc7HyMShN+psgEb2mbw15EMreNvgV8QnXNYHmgU6e15tLbtEvC8LuftOLuSufEdSmR/ykm+aA==
dependencies:
"@babel/core" "^7.0.0"
"@babel/plugin-proposal-class-properties" "^7.0.0"
@@ -5322,6 +5377,7 @@ metro-react-native-babel-preset@0.65.0:
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0"
"@babel/plugin-syntax-optional-chaining" "^7.0.0"
"@babel/plugin-transform-arrow-functions" "^7.0.0"
+ "@babel/plugin-transform-async-to-generator" "^7.0.0"
"@babel/plugin-transform-block-scoping" "^7.0.0"
"@babel/plugin-transform-classes" "^7.0.0"
"@babel/plugin-transform-computed-properties" "^7.0.0"
@@ -5521,10 +5577,10 @@ micromatch@^4.0.2:
braces "^3.0.1"
picomatch "^2.2.3"
-mime-db@1.45.0:
- version "1.45.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea"
- integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==
+mime-db@1.47.0:
+ version "1.47.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
+ integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
mime-db@1.48.0, "mime-db@>= 1.43.0 < 2":
version "1.48.0"
@@ -5543,12 +5599,12 @@ mime-types@2.1.11:
dependencies:
mime-db "~1.23.0"
-mime-types@2.1.28:
- version "2.1.28"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd"
- integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==
+mime-types@2.1.30:
+ version "2.1.30"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
+ integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==
dependencies:
- mime-db "1.45.0"
+ mime-db "1.47.0"
mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24:
version "2.1.31"
@@ -5652,7 +5708,7 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
-nanoid@^3.1.15:
+nanoid@^3.1.15, nanoid@^3.1.20, nanoid@^3.1.23:
version "3.1.23"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
@@ -5739,9 +5795,9 @@ node-releases@^1.1.71:
integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==
node-stream-zip@^1.9.1:
- version "1.13.5"
- resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.13.5.tgz#90c28b1b8fe8f7c40a72bd30a7c1a8cfae61b715"
- integrity sha512-Lfi9xhSNvnJU35+4ZFlECXKJ70etAgJYWAVCdcEpksPnMrgwNqwkCJqdunoViVoFFV38C7AIodYE+2apuoK9Gw==
+ version "1.13.6"
+ resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.13.6.tgz#8abdfdbc4bc96ee11e9438d94cc8c93c7df28959"
+ integrity sha512-c7tRSVkLNOHvasWgmZ2d86cDgTWEygnkuuHNOY9c0mR3yLZtQTTrGvMaJ/fPs6+LOJn3240y30l5sjLaXFtcvw==
normalize-package-data@^2.3.2:
version "2.5.0"
@@ -6209,9 +6265,9 @@ prettier-linter-helpers@^1.0.0:
fast-diff "^1.1.2"
prettier@^2.0.2, prettier@^2.0.4:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6"
- integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
+ integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==
pretty-format@^24.9.0:
version "24.9.0"
@@ -6335,17 +6391,16 @@ react-addons-shallow-compare@15.6.2:
fbjs "^0.8.4"
object-assign "^4.1.0"
-react-art@^16.8.6:
- version "16.13.1"
- resolved "https://registry.yarnpkg.com/react-art/-/react-art-16.13.1.tgz#79bf4d83c6032467bef1f12272adf0904ee49f81"
- integrity sha512-IDXRZCUlyl3AkQ6Xf3qg0C6MSDxKhOhf7amYzWNMaelH5K2W9KqUOUHL8mGwC0k/1BXFhhusSgsE1Bekz3aHEQ==
+react-art@^17.0.2:
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/react-art/-/react-art-17.0.2.tgz#ea1b972e0ee19c08f15e2d2cec522f0d992351cc"
+ integrity sha512-x+AhS0ex8B8kWh2GNyRK/IdX9V+xPax22WphtML8RBdu8CYd9dDOgP3ejQlPthpmwILJUaVf/+5a/qQ8X4I+yA==
dependencies:
art "^0.10.1"
create-react-class "^15.6.2"
loose-envify "^1.1.0"
object-assign "^4.1.1"
- prop-types "^15.6.2"
- scheduler "^0.19.1"
+ scheduler "^0.20.2"
react-devtools-core@^4.6.0:
version "4.13.5"
@@ -6398,9 +6453,9 @@ react-native-controlled-mentions@^2.2.5:
string.prototype.matchall "4.0.3"
react-native-date-picker@^3.2.5:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/react-native-date-picker/-/react-native-date-picker-3.3.1.tgz#1f8b0712967c1e01257d32bab759aa64d6ffb601"
- integrity sha512-9784eFZtxGooIitLSpDRrjWuJzc6vSmQzubZTzLRxMDHIHt2wlAep3QxVMFKj1SSPXNBjM4vY8CbkJXFlYgSNQ==
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/react-native-date-picker/-/react-native-date-picker-3.3.2.tgz#1e08ae1793112510cd19eaca900b3be3b21c7339"
+ integrity sha512-iLlze62sBPwHXaBz69eXPy8cA5vXWV21UaDflQ6TECDhOOQ5HTeDXqSHrQFNPqsYwfmHADGiQdKRnzRy5st2VA==
react-native-device-info@^7.3.1:
version "7.4.0"
@@ -6408,9 +6463,9 @@ react-native-device-info@^7.3.1:
integrity sha512-n5mrUuwUcPXAspLZcAOE+Q087yq+Gfvo8+soZIg1l7rUZUrLNWlFxFgOo/DMPNZA5vcBSv1TSGFFdiAZVHalLw==
react-native-document-picker@^5.0.3:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/react-native-document-picker/-/react-native-document-picker-5.1.0.tgz#37272c49b8b4d59174024c2605a85c11ebb26d3d"
- integrity sha512-XMSDibp1GX0UMlVdsmAgjmf4/FJ+TCvVLWdKjV4QkTIO3TbDKsWSAS1+9jgUYcqIwQpO87SFBkvJ5cjOwx9vNA==
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/react-native-document-picker/-/react-native-document-picker-5.2.0.tgz#1fb2185a56ba6b2509acdc418a8a75906c31e58e"
+ integrity sha512-zXK34hW6fM0gXoo6v7edZZxKvLT7DyjOdBXi7WrxbKqZchDokTEQ/tNTeZxky+7oI8sVz8T3uXBBEW0sp+VfXQ==
react-native-elements@^2.3.2:
version "2.3.2"
@@ -6469,20 +6524,20 @@ react-native-image-pan-zoom@^2.1.12:
resolved "https://registry.yarnpkg.com/react-native-image-pan-zoom/-/react-native-image-pan-zoom-2.1.12.tgz#eb98bf56fb5610379bdbfdb63219cc1baca98fd2"
integrity sha512-BF66XeP6dzuANsPmmFsJshM2Jyh/Mo1t8FsGc1L9Q9/sVP8MJULDabB1hms+eAoqgtyhMr5BuXV3E1hJ5U5H6Q==
-react-native-image-picker@^4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/react-native-image-picker/-/react-native-image-picker-4.0.3.tgz#dd8d393e0c57321688885c74b52244ad36e532d6"
- integrity sha512-S4a1jE4fAPDzmah/7OVTEAXGz1/wlGyClU+spygmek5rVLERR5BgwnkX3tLP/UvMQbfdPZNUbnH0hEe7su2AZg==
+react-native-image-picker@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/react-native-image-picker/-/react-native-image-picker-4.0.4.tgz#4b09d644d9ad7afaedc82db650522dca6bbefc5c"
+ integrity sha512-MR1okWbIQg38ZtD9QT2kCu6kZez9h92JKhGi0VLT/f5fXhwk+piBKxVbLhKdFx6+ofS0d4+gT4GaYauHSkG4Lw==
react-native-image-resizer@^1.4.4:
- version "1.4.4"
- resolved "https://registry.yarnpkg.com/react-native-image-resizer/-/react-native-image-resizer-1.4.4.tgz#75eee65580de509ada674669d13e4d236caea2d5"
- integrity sha512-cPb2R3ZF/9+gBVYx2QyubqILICJpxElIxgRwLSnBSNRFl8eeaAxzWPHa6QNjtki55dkGsgoq5l5EjEu6XjlUng==
+ version "1.4.5"
+ resolved "https://registry.yarnpkg.com/react-native-image-resizer/-/react-native-image-resizer-1.4.5.tgz#5a520aa8baa07638b1894a1d87d4d9a0945c8d58"
+ integrity sha512-33EgL3C9pyvjKpullAB6fWyD5QhoYEpNNB9rxNvUsrpAnL2mHBW7PTrUCCZudJeB6Weg7nbweKrSw1nnto5aqg==
react-native-inappbrowser-reborn@^3.5.0:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/react-native-inappbrowser-reborn/-/react-native-inappbrowser-reborn-3.5.1.tgz#a17e6548ac7864f074f5df6171781601d179d638"
- integrity sha512-pEM9DSvW3LYoI7x1sfr4GtTA1/BSzSoQvHeNRtbJwOpujgRBqnEQrapBwC/24l2pIRhKDWmXGfqc12478IXY3Q==
+ version "3.6.1"
+ resolved "https://registry.yarnpkg.com/react-native-inappbrowser-reborn/-/react-native-inappbrowser-reborn-3.6.1.tgz#9f2bfab73901f1e6c6ef6958e994749b008fa19b"
+ integrity sha512-4hoBh15ppCl1XxHbrZfvwq86s3Q+65jdUZwKZX3dCALWrSN1Rj47gxPEqlT6dSUltsgGBgWJ4Raq2JyIW2ZiYw==
dependencies:
invariant "^2.2.4"
opencollective-postinstall "^2.0.2"
@@ -6550,10 +6605,10 @@ react-native-reanimated@2.0.0-rc.0:
fbjs "^3.0.0"
string-hash-64 "^1.0.3"
-react-native-redash@^15.11.1:
- version "15.11.1"
- resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-15.11.1.tgz#c9a21b20157fb6e0d35337d0dc159371248d78b5"
- integrity sha512-chQkd9t4gecqEz5Gr7D+bl3q5eG2hhHyadO7QT5l893abLFkRHDGY9YtEGwkR/j050TQl5A1KdxuCJEzxhogQw==
+react-native-redash@^16.0.10:
+ version "16.0.11"
+ resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-16.0.11.tgz#973c3050a0645e3b9873790a8e68694770a32f27"
+ integrity sha512-9yTpeabkAoWASzmhEkynNh1wDTrLVtbE+x9dOV1DI23vRa7k1HI+Y1jOUNOPyRG2ddgHampNq9iHtsLnkK4mtw==
dependencies:
abs-svg-path "^0.1.1"
normalize-svg-path "^1.0.1"
@@ -6624,6 +6679,15 @@ react-native-vector-icons@^7.0.0:
prop-types "^15.7.2"
yargs "^15.0.2"
+react-native-video@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/react-native-video/-/react-native-video-5.1.1.tgz#89a7989efeb8d404611c06154d1da227a745d7d8"
+ integrity sha512-zee8gRUrjPWRoZSEBiMebClqu1iAuCQNLjzqpmXFrRWEoJj7azM3BPqLQWJgsnfLiYUYGySeApC/G60THM5+tw==
+ dependencies:
+ keymirror "^0.1.1"
+ prop-types "^15.7.2"
+ shaka-player "^2.5.9"
+
react-native@0.63.3:
version "0.63.3"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.63.3.tgz#4a7f6540e049ff41810887bbd1125abc4672f3bf"
@@ -6798,9 +6862,9 @@ regexpp@^2.0.1:
integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
regexpp@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
- integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
+ integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
regexpu-core@^4.7.1:
version "4.7.1"
@@ -7060,7 +7124,7 @@ sax@^1.2.1, sax@^1.2.4, sax@~1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
-scheduler@0.19.1, scheduler@^0.19.1:
+scheduler@0.19.1:
version "0.19.1"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==
@@ -7076,6 +7140,14 @@ scheduler@^0.17.0:
loose-envify "^1.1.0"
object-assign "^4.1.1"
+scheduler@^0.20.2:
+ version "0.20.2"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
+ integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
schema-utils@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef"
@@ -7166,6 +7238,13 @@ setprototypeof@1.1.1:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
+shaka-player@^2.5.9:
+ version "2.5.23"
+ resolved "https://registry.yarnpkg.com/shaka-player/-/shaka-player-2.5.23.tgz#db92d1c6cf2314f0180a2cec11b0e2f2560336f5"
+ integrity sha512-3MC9k0OXJGw8AZ4n/ZNCZS2yDxx+3as5KgH6Tx4Q5TRboTBBCu6dYPI5vp1DxKeyU12MBN1Zcbs7AKzXv2EnCg==
+ dependencies:
+ eme-encryption-scheme-polyfill "^2.0.1"
+
shallow-clone@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060"
@@ -7459,37 +7538,37 @@ stream-buffers@~2.2.0:
resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4"
integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=
-stream-chat-react-native-core@^3.3.3, stream-chat-react-native-core@v3.5.0:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-3.5.0.tgz#87f3c586de3acff7c7aea8f01d6fe433669baafe"
- integrity sha512-UVzWqblHOgFlAqA+O5K7BgyOHx/zQ7aIlGeZI7D0Immu/CzNvAKyxJrZaulQF9dKZ42GZ5h34Y7zU53UvnoVMQ==
+stream-chat-react-native-core@^3.3.3, stream-chat-react-native-core@v3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/stream-chat-react-native-core/-/stream-chat-react-native-core-3.6.0.tgz#f14dc837d9eb9b0a04bb3492e0d03ca43ac0ead9"
+ integrity sha512-9XnKSloJIc2+SoGaePIAHpFh0K7PTEN78tjiQGOf4ChGCjTWamLVcKGe9uhXR93DI7mvCl4aVjGf3ZUvjfOiuA==
dependencies:
- "@babel/runtime" "7.12.13"
- "@gorhom/bottom-sheet" "3.0.0-alpha.0"
+ "@babel/runtime" "7.13.10"
+ "@gorhom/bottom-sheet" "3.6.4"
anchorme "^1.1.2"
dayjs "1.10.4"
file-loader "6.2.0"
- i18next "19.8.7"
- lodash-es "4.17.20"
- metro-react-native-babel-preset "0.65.0"
- mime-types "2.1.28"
+ i18next "20.2.4"
+ lodash-es "4.17.21"
+ metro-react-native-babel-preset "0.66.0"
+ mime-types "2.1.30"
path "0.12.7"
- react-art "^16.8.6"
+ react-art "^17.0.2"
react-native-markdown-package "1.8.1"
- stream-chat "3.6.2"
+ stream-chat "3.9.0"
stream-chat-react-native@^3.3.3:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/stream-chat-react-native/-/stream-chat-react-native-3.5.0.tgz#0a2cede3e6b66252554b1755389c4e0772c2eeea"
- integrity sha512-PF6eu5UaL82aFOb472XlzKmoA2JKKlx2JUb8JxiTgjS5+cDPf6lgTcMPgwnp3R9UsQKcoECUW7l2j8dz5DyMoQ==
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/stream-chat-react-native/-/stream-chat-react-native-3.6.0.tgz#cad2dea6ed23c86a86ed37175e18caa30195d775"
+ integrity sha512-C2+0ILevALe3LtoNd9Bi0iPlPQIlMtbVO3SIGmNl++rFaW9rDqeqqg64qtjkR8WwAHXQBVUEswrleUuuqHJlIw==
dependencies:
es6-symbol "^3.1.3"
- stream-chat-react-native-core v3.5.0
+ stream-chat-react-native-core v3.6.0
-stream-chat@3.6.2:
- version "3.6.2"
- resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-3.6.2.tgz#4f3ab28f3c02519daea26bcb8578bddd5f414c4a"
- integrity sha512-hhe7gW86GfaoYdZoauh9FQf2bwhi5LApwLZAjsm9qZ0Qx31z409XVPvkMfiDewgjBjodzGWq7p7ZTyW7mczeDg==
+stream-chat@3.9.0:
+ version "3.9.0"
+ resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-3.9.0.tgz#64019fa4f4a6c5551f623e687b46bfb0ef89b9c3"
+ integrity sha512-WeRQQUwFXM6f+V6CE34Ryp9ePcOaRHdpZ+X/ONcT5a45xvFERmeqcG2j28TZXD4+UI63iJ1+0KBVipFvsIrSKw==
dependencies:
"@babel/runtime" "^7.13.10"
"@types/jsonwebtoken" "^8.5.0"
@@ -7886,9 +7965,9 @@ typedarray@^0.0.6:
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
typescript@^3.8.3:
- version "3.9.9"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.9.tgz#e69905c54bc0681d0518bd4d587cc6f2d0b1a674"
- integrity sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==
+ version "3.9.10"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"
+ integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==
ua-parser-js@^0.7.18:
version "0.7.28"
@@ -8232,9 +8311,9 @@ ws@^5.2.0:
async-limiter "~1.0.0"
ws@^7, ws@^7.4.4:
- version "7.4.6"
- resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
- integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
+ version "7.5.1"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.1.tgz#44fc000d87edb1d9c53e51fbc69a0ac1f6871d66"
+ integrity sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow==
xcode@^2.0.0:
version "2.1.0"
@@ -8307,9 +8386,9 @@ yargs-parser@^13.1.2:
decamelize "^1.2.0"
yargs-parser@^15.0.1:
- version "15.0.1"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.1.tgz#54786af40b820dcb2fb8025b11b4d659d76323b3"
- integrity sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==
+ version "15.0.3"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.3.tgz#316e263d5febe8b38eef61ac092b33dfcc9b1115"
+ integrity sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"