diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 6116f0f..ce005bd 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -234,6 +234,8 @@ PODS: - React-cxxreact (= 0.63.4) - React-jsi (= 0.63.4) - React-jsinspector (0.63.4) + - react-native-blur (0.8.0): + - React - react-native-video (5.1.1): - React-Core - react-native-video/Video (= 5.1.1) @@ -384,6 +386,7 @@ DEPENDENCIES: - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) + - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-video (from `../node_modules/react-native-video`) - react-native-vision-camera (from `../..`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) @@ -448,6 +451,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/jsiexecutor" React-jsinspector: :path: "../node_modules/react-native/ReactCommon/jsinspector" + react-native-blur: + :path: "../node_modules/@react-native-community/blur" react-native-video: :path: "../node_modules/react-native-video" react-native-vision-camera: @@ -510,6 +515,7 @@ SPEC CHECKSUMS: React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31 React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949 React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a + react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-video: 1574074179ecaf6a9dd067116c8f31bf9fec15c8 react-native-vision-camera: bf9c62e2795080a21e9ea134050c01b5d9494b6d React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336 diff --git a/example/package-lock.json b/example/package-lock.json index 55994c0..63a1fe1 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -1007,6 +1007,14 @@ "fastq": "^1.6.0" } }, + "@react-native-community/blur": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@react-native-community/blur/-/blur-3.6.0.tgz", + "integrity": "sha512-GtDBhpX2pQcjl4VopOC8FktrVufrEfYRwVeMQ2WWckqKIv2BdwvlvWvj88L1WmEdBr9UNcm3rtgz+d+YXkmirA==", + "requires": { + "prop-types": "^15.5.10" + } + }, "@react-native-community/cli-debugger-ui": { "version": "4.13.1", "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-4.13.1.tgz", @@ -2855,6 +2863,11 @@ "is-symbol": "^1.0.2" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -4661,6 +4674,53 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash.frompairs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.frompairs/-/lodash.frompairs-4.0.1.tgz", + "integrity": "sha1-vE5SB/onV8E25XNhTpZkUGsrG9I=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, "lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", @@ -6247,6 +6307,101 @@ "resolved": "https://registry.npmjs.org/react-native-static-safe-area-insets/-/react-native-static-safe-area-insets-2.1.1.tgz", "integrity": "sha512-NUSRNZp+0IJOuLeoHoU4kw/cY9g7ozUo2ApCbJAiPyYbkbv49S8gdAcZRkeR0nqwzFDA07sCZCbPI03iEV0RTQ==" }, + "react-native-vector-icons": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-8.0.0.tgz", + "integrity": "sha512-u3NWvO+b7nTCxx7IU4EzukFyiApHdpjbsjKgMFEI2Ma+r1Mq48s0ajvBCIPI7LCgKBGYclOxWmMV9DHV2cJFlw==", + "requires": { + "lodash.frompairs": "^4.0.1", + "lodash.isequal": "^4.5.0", + "lodash.isstring": "^4.0.1", + "lodash.omit": "^4.5.0", + "lodash.pick": "^4.4.0", + "lodash.template": "^4.5.0", + "prop-types": "^15.7.2", + "yargs": "^16.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", + "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==" + } + } + }, "react-native-video": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/react-native-video/-/react-native-video-5.1.1.tgz", diff --git a/example/package.json b/example/package.json index c5cca6f..57a8fcb 100644 --- a/example/package.json +++ b/example/package.json @@ -9,12 +9,14 @@ "start": "react-native start" }, "dependencies": { + "@react-native-community/blur": "^3.6.0", "react": "16.13.1", "react-native": "0.63.4", "react-native-gesture-handler": "^1.10.1", "react-native-navigation": "^7.10.0", "react-native-reanimated": "^2.0.0-rc.3", "react-native-static-safe-area-insets": "^2.1.1", + "react-native-vector-icons": "^8.0.0", "react-native-video": "^5.1.1" }, "devDependencies": { diff --git a/example/src/Splash.tsx b/example/src/Splash.tsx index 396fdef..9295654 100644 --- a/example/src/Splash.tsx +++ b/example/src/Splash.tsx @@ -48,11 +48,21 @@ export const Splash: NavigationFunctionComponent = ({ componentId }) => { useEffect(() => { if (cameraPermissionStatus === 'authorized' && microphonePermissionStatus === 'authorized') { - Navigation.push(componentId, { - component: { name: 'Home' } + Navigation.setRoot({ + root: { + stack: { + children: [ + { + component: { + name: 'Home' + } + } + ] + } + } }) } - }, []); + }, [cameraPermissionStatus, microphonePermissionStatus, componentId]); return ( diff --git a/example/src/hooks/useIsForeground.ts b/example/src/hooks/useIsForeground.ts new file mode 100644 index 0000000..fd91724 --- /dev/null +++ b/example/src/hooks/useIsForeground.ts @@ -0,0 +1,17 @@ +import { useEffect } from "react" +import { AppState, AppStateStatus } from "react-native"; +import { useCachedState } from "./useCachedState"; + +export const useIsForeground = (): boolean => { + const [isForeground, setIsForeground] = useCachedState(true); + + useEffect(() => { + const onChange = (state: AppStateStatus) => { + setIsForeground(state === "active"); + }; + AppState.addEventListener("change", onChange); + return () => AppState.removeEventListener("change", onChange); + }, [setIsForeground]); + + return isForeground; +} diff --git a/example/src/views/CaptureButton.tsx b/example/src/views/CaptureButton.tsx new file mode 100644 index 0000000..e69de29 diff --git a/example/src/views/PressableOpacity.tsx b/example/src/views/PressableOpacity.tsx new file mode 100644 index 0000000..dec093f --- /dev/null +++ b/example/src/views/PressableOpacity.tsx @@ -0,0 +1,61 @@ +import React, { useCallback } from "react"; +import { + PressableProps, + Pressable, + PressableStateCallbackType, + StyleProp, + ViewStyle, +} from "react-native"; + +export interface PressableOpacityProps extends PressableProps { + /** + * The opacity to use when `disabled={true}` + * + * @default 1 + */ + disabledOpacity?: number; + /** + * The opacity to animate to when the user presses the button + * + * @default 0.2 + */ + activeOpacity?: number; +} + +export type StyleType = ( + state: PressableStateCallbackType +) => StyleProp; + +/** + * A Pressable component that lowers opacity when in pressed state. Uses the JS Pressability API. + */ +export const PressableOpacity = ({ + style, + disabled = false, + disabledOpacity = 1, + activeOpacity = 0.2, + ...passThroughProps +}: PressableOpacityProps): React.ReactElement => { + const getOpacity = useCallback( + (pressed: boolean) => { + if (disabled) { + return disabledOpacity; + } else { + if (pressed) return activeOpacity; + else return 1; + } + }, + [activeOpacity, disabled, disabledOpacity] + ); + const _style = useCallback( + ({ pressed }) => [style as ViewStyle, { opacity: getOpacity(pressed) }], + [getOpacity, style] + ); + + return ; +}; + +// Fallback implementation using TouchableOpacity: +// export default function PressableOpacity(props: TouchableOpacityProps & { children?: React.ReactNode }): React.ReactElement { +// return ; +// } diff --git a/example/src/views/StatusBarBlurBackground.tsx b/example/src/views/StatusBarBlurBackground.tsx new file mode 100644 index 0000000..1ebc933 --- /dev/null +++ b/example/src/views/StatusBarBlurBackground.tsx @@ -0,0 +1,35 @@ +import { BlurView, BlurViewProperties } from "@react-native-community/blur"; +import React from "react"; +import { Platform, StyleSheet } from "react-native"; +import StaticSafeAreaInsets from "react-native-static-safe-area-insets"; + +const FALLBACK_COLOR = "rgba(140, 140, 140, 0.3)"; + +const StatusBarBlurBackgroundImpl = ({ + style, + ...props +}: BlurViewProperties) => { + if (Platform.OS !== 'ios') return null; + + return ( + + ); +}; + +export const StatusBarBlurBackground = React.memo(StatusBarBlurBackgroundImpl); + +const styles = StyleSheet.create({ + statusBarBackground: { + position: "absolute", + top: 0, + left: 0, + right: 0, + height: StaticSafeAreaInsets.safeAreaInsetsTop, + }, +});