Merge pull request 'ivan/upload-flow-v1' (#87) from ivan/upload-flow-v1 into master
Reviewed-on: railbird/railbird-mobile#87
This commit is contained in:
		| @@ -1,4 +1,4 @@ | ||||
| ((nil | ||||
|   . | ||||
|   ((lsp-pylsp-server-command . ("poetry" "run" "pylsp")) | ||||
|    (apheleia-inhibit . nil)))) | ||||
|   ((apheleia-inhibit . nil) | ||||
|    (imalison:use-lsp t)))) | ||||
|   | ||||
| @@ -1,2 +1,3 @@ | ||||
| # .env.development | ||||
| API_URI=https://api-dev.railbird.ai/graphql | ||||
| API_URI="http://192.168.1.28:8000/graphql" | ||||
| DEV_USER_ID=1 | ||||
|   | ||||
							
								
								
									
										1
									
								
								App.tsx
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								App.tsx
									
									
									
									
									
								
							| @@ -8,6 +8,7 @@ const SetAuthHeaderBasedOnEnv = () => { | ||||
|  | ||||
| 	React.useEffect(() => { | ||||
| 		if (DEV_USER_ID) { | ||||
| 			console.log("Setting fake authorization user to: ", DEV_USER_ID); | ||||
| 			setAuthHeader({ key: "user_id", value: DEV_USER_ID }); | ||||
| 		} | ||||
| 	}, [setAuthHeader]); | ||||
|   | ||||
| @@ -1,6 +1,9 @@ | ||||
| import { ApolloClient, useApolloClient } from "@apollo/client"; | ||||
| import { useIsFocused } from "@react-navigation/native"; | ||||
| import React, { useCallback, useRef, useState } from "react"; | ||||
| import * as gql from "railbird-gql"; | ||||
| import React, { useCallback, useEffect, useRef, useState } from "react"; | ||||
| import { Button, StyleSheet, Text, View } from "react-native"; | ||||
| import * as RNFS from "react-native-fs"; | ||||
| import { | ||||
| 	Camera, | ||||
| 	CameraRuntimeError, | ||||
| @@ -14,16 +17,116 @@ import { | ||||
| import { RecordingButton } from "./capture-button"; | ||||
| import { useIsForeground } from "./is-foreground"; | ||||
|  | ||||
| type Dictionary<KeyType extends string | number | symbol, ValueType> = { | ||||
| 	[key in KeyType]: ValueType; | ||||
| }; | ||||
|  | ||||
| class StreamUploadManager<TCacheShape> { | ||||
| 	client: ApolloClient<TCacheShape>; | ||||
| 	videoId: number; | ||||
| 	nextUploadIdToRequest: number = 0; | ||||
| 	highestUploadLinkObtained: number = -1; | ||||
| 	prefetchedUploadLinks: Dictionary<number, string> = {}; | ||||
| 	uploadQueue: Array<() => Promise<void>> = []; | ||||
| 	isUploading: boolean = false; | ||||
|  | ||||
| 	constructor(client: ApolloClient<TCacheShape>, videoId: number) { | ||||
| 		this.client = client; | ||||
| 		this.videoId = videoId; | ||||
| 	} | ||||
|  | ||||
| 	enqueueUploadTask(task: () => Promise<void>) { | ||||
| 		this.uploadQueue.push(task); | ||||
| 		this.processUploadQueue(); | ||||
| 	} | ||||
|  | ||||
| 	async processUploadQueue() { | ||||
| 		if (this.isUploading || this.uploadQueue.length === 0) { | ||||
| 			return; | ||||
| 		} | ||||
| 		this.isUploading = true; | ||||
| 		const task = this.uploadQueue.shift(); | ||||
| 		try { | ||||
| 			if (task) { | ||||
| 				await task(); | ||||
| 			} | ||||
| 		} catch (error) { | ||||
| 			console.error("Error processing upload task", error); | ||||
| 		} finally { | ||||
| 			this.isUploading = false; | ||||
| 			this.processUploadQueue(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	async uploadChunk({ filepath, index }: { filepath: string; index: number }) { | ||||
| 		this.enqueueUploadTask(async () => { | ||||
| 			const uploadUrl = await this.getUploadLink(index); | ||||
| 			const uploadRequest = RNFS.uploadFiles({ | ||||
| 				toUrl: uploadUrl, | ||||
| 				// @ts-ignore | ||||
| 				files: [{ filepath: filepath }], | ||||
| 				method: "PUT", | ||||
| 				binaryStreamOnly: true, | ||||
| 				headers: { | ||||
| 					"Content-Type": "application/octet-stream", | ||||
| 				}, | ||||
| 				begin: (res) => { | ||||
| 					console.log("Start upload", res); | ||||
| 				}, | ||||
| 				progress: (res) => { | ||||
| 					console.log("Uploading", res); | ||||
| 				}, | ||||
| 			}); | ||||
| 			console.log(JSON.stringify(uploadRequest)); | ||||
| 			const result = await uploadRequest.promise; | ||||
| 			if (result.statusCode === 200) { | ||||
| 				console.log(`${filepath} Uploaded`); | ||||
| 			} else { | ||||
| 				console.error("SERVER ERROR"); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	async getUploadLink(chunkId: number): Promise<string> { | ||||
| 		if (this.prefetchedUploadLinks[chunkId]) { | ||||
| 			return this.prefetchedUploadLinks[chunkId]; | ||||
| 		} | ||||
| 		return this.requestUploadLink(chunkId); | ||||
| 	} | ||||
|  | ||||
| 	async requestUploadLink(chunkId: number): Promise<string> { | ||||
| 		console.log(`Requesting upload link for chunk ${chunkId}`); | ||||
| 		const result = await this.client.mutate({ | ||||
| 			mutation: gql.GetUploadLinkDocument, | ||||
| 			variables: { videoId: this.videoId, chunkIndex: chunkId }, | ||||
| 		}); | ||||
| 		this.prefetchedUploadLinks[chunkId] = result.data.getUploadLink.uploadUrl; | ||||
| 		return result.data.getUploadLink.uploadUrl; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| export default function CameraScreen({ | ||||
| 	route, | ||||
| 	navigation, | ||||
| }): React.ReactElement { | ||||
| 	// TODO: #73 Does this need to be passed to Camera component? | ||||
| 	// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars | ||||
| 	const { gameType, tableSize, tags, location } = route.params; | ||||
| 	// LOG for params -- Remove when no longer needed | ||||
| 	// Note: camelCased value being passed, change on record.tsx if you want a different value format | ||||
| 	console.log(gameType, tableSize, tags, location); | ||||
| 	const apolloClient = useApolloClient(); | ||||
| 	const [createUpload, { data, loading, error }] = | ||||
| 		gql.useCreateUploadStreamMutation(); | ||||
|  | ||||
| 	const [uploadManager, setUploadManager] = useState(null); | ||||
|  | ||||
| 	useEffect(() => { | ||||
| 		if ( | ||||
| 			data && | ||||
| 			data.createUploadStream && | ||||
| 			data.createUploadStream.videoId && | ||||
| 			!uploadManager | ||||
| 		) { | ||||
| 			const newVideoId = data.createUploadStream.videoId; | ||||
| 			console.log(`VideoId: ${newVideoId}`); | ||||
| 			setUploadManager(new StreamUploadManager(apolloClient, newVideoId)); | ||||
| 		} | ||||
| 	}, [data, uploadManager]); | ||||
|  | ||||
| 	const camera = useRef<Camera>(null); | ||||
| 	const { hasPermission, requestPermission } = useCameraPermission(); | ||||
| @@ -41,15 +144,22 @@ export default function CameraScreen({ | ||||
| 	const onInitialized = useCallback(() => { | ||||
| 		console.log("Camera initialized!"); | ||||
| 		setIsCameraInitialized(true); | ||||
| 		createUpload({ variables: { videoName: "Test" } }); | ||||
| 	}, []); | ||||
|  | ||||
| 	const onMediaCaptured = useCallback((media: PhotoFile | VideoFile) => { | ||||
| 		console.log(`Media captured! ${JSON.stringify(media)}`); | ||||
| 	}, []); | ||||
|  | ||||
| 	const onVideoChunkReady = useCallback((event) => { | ||||
| 		console.log(`Chunk ready in react-native`, event.nativeEvent); | ||||
| 	}, []); | ||||
| 	const onVideoChunkReady = useCallback( | ||||
| 		(event) => { | ||||
| 			console.log( | ||||
| 				`Chunk ready in react-native ${JSON.stringify(event.nativeEvent)}`, | ||||
| 			); | ||||
| 			uploadManager.uploadChunk(event.nativeEvent); | ||||
| 		}, | ||||
| 		[uploadManager], | ||||
| 	); | ||||
|  | ||||
| 	if (!hasPermission) { | ||||
| 		requestPermission(); | ||||
| @@ -58,17 +168,16 @@ export default function CameraScreen({ | ||||
|  | ||||
| 	const device = useCameraDevice("back"); | ||||
| 	const format = useCameraFormat(device, [ | ||||
| 		{ videoResolution: { width: 3048, height: 2160 } }, | ||||
| 		{ fps: 60 }, | ||||
| 	]); // this sets as a target | ||||
| 		{ videoResolution: { width: 1920, height: 1080 } }, | ||||
| 		{ fps: 30 }, | ||||
| 	]); | ||||
|  | ||||
| 	//Orientation detection | ||||
| 	// TODO(#60): setOrientation should be called when changes are detected | ||||
| 	const [orientation, setOrientation] = useState<Orientation>("portrait"); | ||||
|  | ||||
| 	const toggleOrientation = () => { | ||||
| 		setOrientation( | ||||
| 			(currentOrientation) => | ||||
| 				currentOrientation === "landscape-left" ? "portrait" : "landscape-left", // Can adjust this and the type to match what we want | ||||
| 		setOrientation((currentOrientation) => | ||||
| 			currentOrientation === "landscape-left" ? "portrait" : "landscape-left", | ||||
| 		); | ||||
| 	}; | ||||
|  | ||||
| @@ -94,7 +203,7 @@ export default function CameraScreen({ | ||||
| 					// @ts-ignore | ||||
| 					onVideoChunkReady={onVideoChunkReady} | ||||
| 					video={true} | ||||
| 					orientation={orientation} // TODO: #60 | ||||
| 					orientation={orientation} | ||||
| 					isActive={isActive} | ||||
| 				/> | ||||
| 				<View | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| import { CameraRoll } from "@react-native-camera-roll/camera-roll"; | ||||
| import React, { useCallback, useRef, useState } from "react"; | ||||
| import { | ||||
| 	StyleProp, | ||||
| @@ -62,10 +61,6 @@ export const RecordingButton: React.FC<RecordingButtonProps> = ({ | ||||
| 				}, | ||||
| 				onRecordingFinished: async (video) => { | ||||
| 					onMediaCaptured(video, "video"); | ||||
| 					const path = video.path; | ||||
| 					await CameraRoll.saveAsset(`file://${path}`, { | ||||
| 						type: "video", | ||||
| 					}); | ||||
| 					onStoppedRecording(); | ||||
| 				}, | ||||
| 			}); | ||||
|   | ||||
| @@ -40,14 +40,15 @@ export const useAuthHeader = () => { | ||||
|  | ||||
| export const ClientProvider: React.FC<Props> = ({ children }) => { | ||||
| 	const [authHeader, setAuthHeader] = useState({ key: "", value: "" }); | ||||
| 	console.log(`The api uri is ${API_URI}`); | ||||
| 	const httpLink = new HttpLink({ | ||||
| 		uri: API_URI || "https://api-dev.railbird.ai/graphql", | ||||
| 		uri: API_URI, | ||||
| 	}); | ||||
| 	const cache = new InMemoryCache({}); | ||||
|  | ||||
| 	const authMiddleware = new ApolloLink((operation, forward) => { | ||||
| 		const { key, value } = authHeader; | ||||
|  | ||||
| 		console.log("Auth Key", key, "Value", value); | ||||
| 		if (key && value) { | ||||
| 			operation.setContext({ | ||||
| 				headers: { | ||||
|   | ||||
| @@ -31,6 +31,7 @@ | ||||
| 		"@typescript-eslint/eslint-plugin": "^6.17.0", | ||||
| 		"@typescript-eslint/parser": "^6.17.0", | ||||
| 		"babel-plugin-inline-dotenv": "^1.7.0", | ||||
| 		"backoff": "^2.5.0", | ||||
| 		"d3-path": "^3.1.0", | ||||
| 		"d3-scale": "^1.0.6", | ||||
| 		"eslint": "^8.56.0", | ||||
| @@ -50,6 +51,7 @@ | ||||
| 		"react-native": "0.72.6", | ||||
| 		"react-native-dotenv": "^3.4.9", | ||||
| 		"react-native-dropdown-picker": "^5.4.6", | ||||
| 		"react-native-fs": "^2.20.0", | ||||
| 		"react-native-reanimated": "^3.6.2", | ||||
| 		"react-native-safe-area-context": "^4.8.2", | ||||
| 		"react-native-screens": "~3.22.0", | ||||
| @@ -76,5 +78,9 @@ | ||||
| 		"plugins": [ | ||||
| 			"prettier-plugin-organize-imports" | ||||
| 		] | ||||
| 	}, | ||||
| 	"resolutions": { | ||||
| 		"@babel/core": "^7.20.2", | ||||
| 		"babel-loader": "^8.3.0" | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										177
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										177
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -108,49 +108,7 @@ | ||||
|   resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" | ||||
|   integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== | ||||
|  | ||||
| "@babel/core@^7.11.6", "@babel/core@^7.12.3": | ||||
|   version "7.23.7" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.7.tgz#4d8016e06a14b5f92530a13ed0561730b5c6483f" | ||||
|   integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== | ||||
|   dependencies: | ||||
|     "@ampproject/remapping" "^2.2.0" | ||||
|     "@babel/code-frame" "^7.23.5" | ||||
|     "@babel/generator" "^7.23.6" | ||||
|     "@babel/helper-compilation-targets" "^7.23.6" | ||||
|     "@babel/helper-module-transforms" "^7.23.3" | ||||
|     "@babel/helpers" "^7.23.7" | ||||
|     "@babel/parser" "^7.23.6" | ||||
|     "@babel/template" "^7.22.15" | ||||
|     "@babel/traverse" "^7.23.7" | ||||
|     "@babel/types" "^7.23.6" | ||||
|     convert-source-map "^2.0.0" | ||||
|     debug "^4.1.0" | ||||
|     gensync "^1.0.0-beta.2" | ||||
|     json5 "^2.2.3" | ||||
|     semver "^6.3.1" | ||||
|  | ||||
| "@babel/core@^7.13.16", "@babel/core@^7.20.0": | ||||
|   version "7.23.6" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.6.tgz#8be77cd77c55baadcc1eae1c33df90ab6d2151d4" | ||||
|   integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== | ||||
|   dependencies: | ||||
|     "@ampproject/remapping" "^2.2.0" | ||||
|     "@babel/code-frame" "^7.23.5" | ||||
|     "@babel/generator" "^7.23.6" | ||||
|     "@babel/helper-compilation-targets" "^7.23.6" | ||||
|     "@babel/helper-module-transforms" "^7.23.3" | ||||
|     "@babel/helpers" "^7.23.6" | ||||
|     "@babel/parser" "^7.23.6" | ||||
|     "@babel/template" "^7.22.15" | ||||
|     "@babel/traverse" "^7.23.6" | ||||
|     "@babel/types" "^7.23.6" | ||||
|     convert-source-map "^2.0.0" | ||||
|     debug "^4.1.0" | ||||
|     gensync "^1.0.0-beta.2" | ||||
|     json5 "^2.2.3" | ||||
|     semver "^6.3.1" | ||||
|  | ||||
| "@babel/core@^7.14.0", "@babel/core@^7.22.9": | ||||
| "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.14.0", "@babel/core@^7.20.0", "@babel/core@^7.20.2", "@babel/core@^7.22.9": | ||||
|   version "7.23.9" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.9.tgz#b028820718000f267870822fec434820e9b1e4d1" | ||||
|   integrity sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw== | ||||
| @@ -361,24 +319,6 @@ | ||||
|     "@babel/template" "^7.22.15" | ||||
|     "@babel/types" "^7.22.19" | ||||
|  | ||||
| "@babel/helpers@^7.23.6": | ||||
|   version "7.23.6" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.6.tgz#d03af2ee5fb34691eec0cda90f5ecbb4d4da145a" | ||||
|   integrity sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA== | ||||
|   dependencies: | ||||
|     "@babel/template" "^7.22.15" | ||||
|     "@babel/traverse" "^7.23.6" | ||||
|     "@babel/types" "^7.23.6" | ||||
|  | ||||
| "@babel/helpers@^7.23.7": | ||||
|   version "7.23.7" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.7.tgz#eb543c36f81da2873e47b76ee032343ac83bba60" | ||||
|   integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== | ||||
|   dependencies: | ||||
|     "@babel/template" "^7.22.15" | ||||
|     "@babel/traverse" "^7.23.7" | ||||
|     "@babel/types" "^7.23.6" | ||||
|  | ||||
| "@babel/helpers@^7.23.9": | ||||
|   version "7.23.9" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.9.tgz#c3e20bbe7f7a7e10cb9b178384b4affdf5995c7d" | ||||
| @@ -1325,7 +1265,7 @@ | ||||
|     debug "^4.3.1" | ||||
|     globals "^11.1.0" | ||||
|  | ||||
| "@babel/traverse@^7.20.0", "@babel/traverse@^7.23.6": | ||||
| "@babel/traverse@^7.20.0": | ||||
|   version "7.23.6" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.6.tgz#b53526a2367a0dd6edc423637f3d2d0f2521abc5" | ||||
|   integrity sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ== | ||||
| @@ -1341,22 +1281,6 @@ | ||||
|     debug "^4.3.1" | ||||
|     globals "^11.1.0" | ||||
|  | ||||
| "@babel/traverse@^7.23.7": | ||||
|   version "7.23.7" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.7.tgz#9a7bf285c928cb99b5ead19c3b1ce5b310c9c305" | ||||
|   integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== | ||||
|   dependencies: | ||||
|     "@babel/code-frame" "^7.23.5" | ||||
|     "@babel/generator" "^7.23.6" | ||||
|     "@babel/helper-environment-visitor" "^7.22.20" | ||||
|     "@babel/helper-function-name" "^7.23.0" | ||||
|     "@babel/helper-hoist-variables" "^7.22.5" | ||||
|     "@babel/helper-split-export-declaration" "^7.22.6" | ||||
|     "@babel/parser" "^7.23.6" | ||||
|     "@babel/types" "^7.23.6" | ||||
|     debug "^4.3.1" | ||||
|     globals "^11.1.0" | ||||
|  | ||||
| "@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.4", "@babel/types@^7.23.6", "@babel/types@^7.3.3", "@babel/types@^7.4.4": | ||||
|   version "7.23.6" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" | ||||
| @@ -3376,7 +3300,7 @@ | ||||
|     "@types/tough-cookie" "*" | ||||
|     parse5 "^7.0.0" | ||||
|  | ||||
| "@types/json-schema@^7.0.12": | ||||
| "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.5": | ||||
|   version "7.0.15" | ||||
|   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" | ||||
|   integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== | ||||
| @@ -3761,6 +3685,11 @@ aggregate-error@^3.0.0: | ||||
|     clean-stack "^2.0.0" | ||||
|     indent-string "^4.0.0" | ||||
|  | ||||
| ajv-keywords@^3.5.2: | ||||
|   version "3.5.2" | ||||
|   resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" | ||||
|   integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== | ||||
|  | ||||
| ajv@^6.12.4: | ||||
|   version "6.12.6" | ||||
|   resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" | ||||
| @@ -4042,6 +3971,16 @@ babel-jest@^29.2.1, babel-jest@^29.7.0: | ||||
|     graceful-fs "^4.2.9" | ||||
|     slash "^3.0.0" | ||||
|  | ||||
| babel-loader@^8.3.0: | ||||
|   version "8.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" | ||||
|   integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== | ||||
|   dependencies: | ||||
|     find-cache-dir "^3.3.1" | ||||
|     loader-utils "^2.0.0" | ||||
|     make-dir "^3.1.0" | ||||
|     schema-utils "^2.6.5" | ||||
|  | ||||
| babel-plugin-inline-dotenv@^1.7.0: | ||||
|   version "1.7.0" | ||||
|   resolved "https://registry.yarnpkg.com/babel-plugin-inline-dotenv/-/babel-plugin-inline-dotenv-1.7.0.tgz#c4b9f9752678be4b49a6b5d3d2b47def741a4d5f" | ||||
| @@ -4195,11 +4134,23 @@ babel-preset-jest@^29.6.3: | ||||
|     babel-plugin-jest-hoist "^29.6.3" | ||||
|     babel-preset-current-node-syntax "^1.0.0" | ||||
|  | ||||
| backoff@^2.5.0: | ||||
|   version "2.5.0" | ||||
|   resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" | ||||
|   integrity sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA== | ||||
|   dependencies: | ||||
|     precond "0.2" | ||||
|  | ||||
| balanced-match@^1.0.0: | ||||
|   version "1.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" | ||||
|   integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== | ||||
|  | ||||
| base-64@^0.1.0: | ||||
|   version "0.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" | ||||
|   integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA== | ||||
|  | ||||
| base64-js@^1.1.2, base64-js@^1.2.3, base64-js@^1.3.1, base64-js@^1.5.1: | ||||
|   version "1.5.1" | ||||
|   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" | ||||
| @@ -4217,6 +4168,11 @@ big-integer@1.6.x: | ||||
|   resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" | ||||
|   integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== | ||||
|  | ||||
| big.js@^5.2.2: | ||||
|   version "5.2.2" | ||||
|   resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" | ||||
|   integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== | ||||
|  | ||||
| bl@^4.1.0: | ||||
|   version "4.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" | ||||
| @@ -5388,6 +5344,11 @@ emoji-regex@^9.2.2: | ||||
|   resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" | ||||
|   integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== | ||||
|  | ||||
| emojis-list@^3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" | ||||
|   integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== | ||||
|  | ||||
| encodeurl@~1.0.2: | ||||
|   version "1.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" | ||||
| @@ -6050,6 +6011,15 @@ find-cache-dir@^2.0.0: | ||||
|     make-dir "^2.0.0" | ||||
|     pkg-dir "^3.0.0" | ||||
|  | ||||
| find-cache-dir@^3.3.1: | ||||
|   version "3.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" | ||||
|   integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== | ||||
|   dependencies: | ||||
|     commondir "^1.0.1" | ||||
|     make-dir "^3.0.2" | ||||
|     pkg-dir "^4.1.0" | ||||
|  | ||||
| find-up@^3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" | ||||
| @@ -7845,7 +7815,7 @@ json-to-pretty-yaml@^1.2.2: | ||||
|     remedial "^1.0.7" | ||||
|     remove-trailing-spaces "^1.0.6" | ||||
|  | ||||
| json5@^2.1.1, json5@^2.2.2, json5@^2.2.3: | ||||
| json5@^2.1.1, json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: | ||||
|   version "2.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" | ||||
|   integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== | ||||
| @@ -7999,6 +7969,15 @@ listr2@^4.0.5: | ||||
|     through "^2.3.8" | ||||
|     wrap-ansi "^7.0.0" | ||||
|  | ||||
| loader-utils@^2.0.0: | ||||
|   version "2.0.4" | ||||
|   resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" | ||||
|   integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== | ||||
|   dependencies: | ||||
|     big.js "^5.2.2" | ||||
|     emojis-list "^3.0.0" | ||||
|     json5 "^2.1.2" | ||||
|  | ||||
| locate-path@^3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" | ||||
| @@ -8123,6 +8102,13 @@ make-dir@^2.0.0, make-dir@^2.1.0: | ||||
|     pify "^4.0.1" | ||||
|     semver "^5.6.0" | ||||
|  | ||||
| make-dir@^3.0.2, make-dir@^3.1.0: | ||||
|   version "3.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" | ||||
|   integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== | ||||
|   dependencies: | ||||
|     semver "^6.0.0" | ||||
|  | ||||
| make-dir@^4.0.0: | ||||
|   version "4.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" | ||||
| @@ -9471,7 +9457,7 @@ pkg-dir@^3.0.0: | ||||
|   dependencies: | ||||
|     find-up "^3.0.0" | ||||
|  | ||||
| pkg-dir@^4.2.0: | ||||
| pkg-dir@^4.1.0, pkg-dir@^4.2.0: | ||||
|   version "4.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" | ||||
|   integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== | ||||
| @@ -9508,6 +9494,11 @@ postcss@~8.4.21: | ||||
|     picocolors "^1.0.0" | ||||
|     source-map-js "^1.0.2" | ||||
|  | ||||
| precond@0.2: | ||||
|   version "0.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" | ||||
|   integrity sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ== | ||||
|  | ||||
| prelude-ls@^1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" | ||||
| @@ -9743,6 +9734,14 @@ react-native-dropdown-picker@^5.4.6: | ||||
|   resolved "https://registry.yarnpkg.com/react-native-dropdown-picker/-/react-native-dropdown-picker-5.4.6.tgz#3736fc468de4a295e4df8d1f65ed2eadaf9b445f" | ||||
|   integrity sha512-T1XBHbE++M6aRU3wFYw3MvcOuabhWZ29RK/Ivdls2r1ZkZ62iEBZknLUPeVLMX3x6iUxj4Zgr3X2DGlEGXeHsA== | ||||
|  | ||||
| react-native-fs@^2.20.0: | ||||
|   version "2.20.0" | ||||
|   resolved "https://registry.yarnpkg.com/react-native-fs/-/react-native-fs-2.20.0.tgz#05a9362b473bfc0910772c0acbb73a78dbc810f6" | ||||
|   integrity sha512-VkTBzs7fIDUiy/XajOSNk0XazFE9l+QlMAce7lGuebZcag5CnjszB+u4BdqzwaQOdcYb5wsJIsqq4kxInIRpJQ== | ||||
|   dependencies: | ||||
|     base-64 "^0.1.0" | ||||
|     utf8 "^3.0.0" | ||||
|  | ||||
| react-native-reanimated@^3.6.2: | ||||
|   version "3.6.2" | ||||
|   resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.6.2.tgz#8a48c37251cbd3b665a659444fa9778f5b510356" | ||||
| @@ -10295,6 +10294,15 @@ scheduler@^0.23.0: | ||||
|   dependencies: | ||||
|     loose-envify "^1.1.0" | ||||
|  | ||||
| schema-utils@^2.6.5: | ||||
|   version "2.7.1" | ||||
|   resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" | ||||
|   integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== | ||||
|   dependencies: | ||||
|     "@types/json-schema" "^7.0.5" | ||||
|     ajv "^6.12.4" | ||||
|     ajv-keywords "^3.5.2" | ||||
|  | ||||
| scuid@^1.1.0: | ||||
|   version "1.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/scuid/-/scuid-1.1.0.tgz#d3f9f920956e737a60f72d0e4ad280bf324d5dab" | ||||
| @@ -10317,7 +10325,7 @@ semver@^5.5.0, semver@^5.6.0: | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" | ||||
|   integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== | ||||
|  | ||||
| semver@^6.3.0, semver@^6.3.1: | ||||
| semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: | ||||
|   version "6.3.1" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" | ||||
|   integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== | ||||
| @@ -11399,6 +11407,11 @@ use-sync-external-store@^1.0.0: | ||||
|   resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" | ||||
|   integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== | ||||
|  | ||||
| utf8@^3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" | ||||
|   integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== | ||||
|  | ||||
| util-deprecate@^1.0.1, util-deprecate@~1.0.1: | ||||
|   version "1.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user