From 198a671d12fcbdc63e9c2f40e154fb3dd854b3d4 Mon Sep 17 00:00:00 2001 From: Tjikal Jedy Date: Sun, 29 May 2022 05:33:47 +0700 Subject: [PATCH] add camera mode prompt --- App.tsx | 4 +- .../elements/SnapCamera/SnapCamera.tsx | 29 ++- src/redux/rootReducers.ts | 5 +- src/redux/slices/cameraSlice.ts | 41 +++++ src/screens/Acquire/Acquire.tsx | 19 +- src/screens/AcquireAR/AcquireAR.tsx | 165 ++++++++++-------- src/screens/Home/Stories/Stories.tsx | 35 +++- .../Home/Stories/StoriesCameraModal.tsx | 45 +++++ src/screens/Settings/ChangeCameraModal.tsx | 50 ++++++ src/screens/Settings/ChangeLanguageModal.tsx | 10 +- src/screens/Settings/Settings.tsx | 26 +++ src/screens/Settings/styles.ts | 3 + 12 files changed, 318 insertions(+), 114 deletions(-) create mode 100644 src/redux/slices/cameraSlice.ts create mode 100644 src/screens/Home/Stories/StoriesCameraModal.tsx create mode 100644 src/screens/Settings/ChangeCameraModal.tsx diff --git a/App.tsx b/App.tsx index 79be933..d5d338a 100644 --- a/App.tsx +++ b/App.tsx @@ -39,16 +39,14 @@ const App = () => { React.useEffect(() => { const subscription = AppState.addEventListener('change', (nextAppState) => { console.log('>> 0' + appStateVisible); - console.log('>> 1' + nextAppState); }); return () => { - console.log('>> 2' + appStateVisible); + console.log('>> 1' + appStateVisible); subscription.remove(); }; }, []); React.useEffect(() => { - console.log('>> 3' + appStateVisible); if (appStateVisible !== 'active') { return; } diff --git a/src/components/elements/SnapCamera/SnapCamera.tsx b/src/components/elements/SnapCamera/SnapCamera.tsx index e61d5a2..cfaea7a 100644 --- a/src/components/elements/SnapCamera/SnapCamera.tsx +++ b/src/components/elements/SnapCamera/SnapCamera.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import {StyleSheet, StatusBar} from 'react-native'; +import {StyleSheet} from 'react-native'; import { PinchGestureHandler, PinchGestureHandlerGestureEvent, @@ -38,16 +38,12 @@ import { SCALE_FULL_ZOOM, BUTTON_SIZE, } from '../../../constants'; -import PermissionContext from '../../../context/permission-context'; -import {PermissionCamera} from './PermissionCamera'; -import changeNavigationBarColor from 'react-native-navigation-bar-color-fix-behavior-status-bar'; + import Icon from '../Icon'; -import {useAppDispatch} from '@src/redux/useRedux'; -import {resetSelectionArts} from '@src/redux/slices/artSlice'; type SnapCameraProps = { children?: React.ReactNode; - onSwitchToAR: () => void; + onSwitchToAR?: () => void; }; const ReanimatedCamera = Reanimated.createAnimatedComponent(Camera); @@ -56,9 +52,11 @@ Reanimated.addWhitelistedNativeProps({ }); //Construct Component -const SnapCamera: React.FC = ({children, ...rest}) => { - const dispatch = useAppDispatch(); - const {isPass} = React.useContext(PermissionContext); +const SnapCamera: React.FC = ({ + children, + onSwitchToAR, + ...rest +}) => { const navigation = useNavigation(); const camera = React.useRef(null); const [isCameraInitialized, setIsCameraInitialized] = React.useState(false); @@ -283,11 +281,6 @@ const SnapCamera: React.FC = ({children, ...rest}) => { // ImagePicker.launchImageLibrary({mediaType: 'mixed'}, setResponse); }, []); - const _onSwitchToAR = React.useCallback((type?: any, options?: any) => { - dispatch(resetSelectionArts()); - navigation.navigate('AcquireARScreen' as any); - }, []); - React.useEffect(() => { navigation.addListener('beforeRemove', (e) => { setIsCameraInitialized(false); @@ -299,7 +292,7 @@ const SnapCamera: React.FC = ({children, ...rest}) => { return ( <> - {device != null && isPass ? ( + {device != null && ( = ({children, ...rest}) => { @@ -438,8 +431,6 @@ const SnapCamera: React.FC = ({children, ...rest}) => { - ) : ( - )} ); diff --git a/src/redux/rootReducers.ts b/src/redux/rootReducers.ts index 94d7c1c..e4d2932 100644 --- a/src/redux/rootReducers.ts +++ b/src/redux/rootReducers.ts @@ -3,17 +3,18 @@ import {persistCombineReducers} from 'redux-persist'; import AsyncStorage from '@react-native-async-storage/async-storage'; import theme from './slices/themeSlice'; import artSlice from './slices/artSlice'; - +import camera from './slices/cameraSlice'; //Reducer const reducers = { theme, + camera, artSlice, }; const persistConfig = { key: 'root', storage: AsyncStorage, - whitelist: ['theme'], + whitelist: ['theme', 'camera'], }; export const persistedRootReducer = persistCombineReducers( diff --git a/src/redux/slices/cameraSlice.ts b/src/redux/slices/cameraSlice.ts new file mode 100644 index 0000000..669647a --- /dev/null +++ b/src/redux/slices/cameraSlice.ts @@ -0,0 +1,41 @@ +import {createSlice} from '@reduxjs/toolkit'; +import {RootState} from '../useRedux'; + +const sliceName = 'camera'; + +const slice = createSlice({ + name: sliceName, + initialState: { + label: 'Prompt', + value: 'prompt', + } as CameraState, + reducers: { + changeDefault: (state: CameraState, action: CameraLoad) => { + state.label = + typeof action.payload.label !== 'undefined' + ? action.payload.label + : 'Prompt'; + state.value = + typeof action.payload.value !== 'undefined' + ? action.payload.value + : 'prompt'; + }, + }, +}); + +export const {changeDefault} = slice.actions; +export const fetchDefault = (state: RootState) => state.camera; + +export default slice.reducer; + +export type CameraState = { + label: 'Device' | 'AR' | 'Prompt'; + value: 'device' | 'ar' | 'prompt'; +}; + +type CameraLoad = { + payload: { + label: 'Device' | 'AR' | 'Prompt'; + value: 'device' | 'ar' | 'prompt'; + }; +}; diff --git a/src/screens/Acquire/Acquire.tsx b/src/screens/Acquire/Acquire.tsx index 76184bf..b25cfd5 100644 --- a/src/screens/Acquire/Acquire.tsx +++ b/src/screens/Acquire/Acquire.tsx @@ -1,7 +1,12 @@ import * as React from 'react'; -import {useTheme, useNavigation} from '@react-navigation/native'; +import {useNavigation} from '@react-navigation/native'; + +import {useAppDispatch} from '@src/redux/useRedux'; +import {resetSelectionArts} from '@src/redux/slices/artSlice'; import {Container, SnapCamera} from '@src/components/elements'; import NavProvider from '@src/components/common/NavProvider/NavProvider'; +import PermissionContext from '@src/context/permission-context'; +import {PermissionCamera} from '@src/components/elements/SnapCamera/PermissionCamera'; import AuthContext from '@src/context/auth-context'; import {profile} from '@src/data/mock-profile'; import styles from './styles'; @@ -9,9 +14,15 @@ import styles from './styles'; type AcquireProps = {}; const Acquire: React.FC = () => { + const dispatch = useAppDispatch(); + const {isPass} = React.useContext(PermissionContext); const navigation = useNavigation(); const {userToken} = React.useContext(AuthContext); + const _onSwitchToAR = React.useCallback((type?: any, options?: any) => { + dispatch(resetSelectionArts()); + navigation.navigate('AcquireARScreen' as any); + }, []); return ( <> = () => { }} /> - + {isPass ? ( + + ) : ( + + )} ); diff --git a/src/screens/AcquireAR/AcquireAR.tsx b/src/screens/AcquireAR/AcquireAR.tsx index 0e9ba2f..e65a4f8 100644 --- a/src/screens/AcquireAR/AcquireAR.tsx +++ b/src/screens/AcquireAR/AcquireAR.tsx @@ -3,8 +3,10 @@ import {useNavigation} from '@react-navigation/core'; import {Image, Animated} from 'react-native'; import LottieView from 'lottie-react-native'; import {PressableOpacity} from 'react-native-pressable-opacity'; -import {ViroARSceneNavigator, ViroConstants} from '@viro-community/react-viro'; +import {ViroConstants} from '@viro-community/react-viro'; //Default +import PermissionContext from '@src/context/permission-context'; +import {PermissionCamera} from '@src/components/elements/SnapCamera/PermissionCamera'; import NavProvider from '@src/components/common/NavProvider/NavProvider'; import { Container, @@ -25,13 +27,12 @@ import { } from '@src/redux/slices/artSlice'; import {selectSortedArts} from '@src/redux/combinedSelector'; import {useAppDispatch, useAppSelector} from '@src/redux/useRedux'; -import {mockItemArt} from '@src/data/mock-arts'; type AcquireARProps = {}; const AcquireAR: React.FC = () => { const dispatch = useAppDispatch(); - + const {isPass} = React.useContext(PermissionContext); const {userToken} = React.useContext(AuthContext); const allArts = useAppSelector(selectSortedArts); const planReady = useAppSelector(fetchPlanStatus); @@ -108,81 +109,91 @@ const AcquireAR: React.FC = () => { }} /> - - - - {!planReady ? ( - - {}} - /> - - - ) : ( - - - + + + {!planReady ? ( + + {}} + /> + + + ) : ( + + + + + )} + + + + + + + + - - )} - - - - - - - - - + + + ) : ( + + )} ); diff --git a/src/screens/Home/Stories/Stories.tsx b/src/screens/Home/Stories/Stories.tsx index b5bd97a..c55856d 100644 --- a/src/screens/Home/Stories/Stories.tsx +++ b/src/screens/Home/Stories/Stories.tsx @@ -10,28 +10,46 @@ import { Icon, Dialog, } from '@src/components/elements'; +import {fetchDefault} from '@store/slices/cameraSlice'; +import {useAppSelector} from '@src/redux/useRedux'; import {mockStories, Story} from '@src/data/mock-stories'; import {profile} from '@src/data/mock-profile'; import styles from './styles'; +import StoriesCameraModal from './StoriesCameraModal'; //Default type StoriesProps = {}; const Stories: React.FC = () => { - //Default const navigation = useNavigation(); + const defaultValue = useAppSelector(fetchDefault); const [isModalVisible, setIsModalVisible] = React.useState(false); const { colors: {primary}, } = useTheme(); - const _onAddItemPressed = (name?: string) => { - return () => { - navigation.navigate('AcquireScreen' as any); - }; + const _hideModal = () => { + setIsModalVisible(false); }; + const _onCameraSelectMode = React.useCallback((item: any) => { + setIsModalVisible(false); + return item.value === 'ar' + ? navigation.navigate('AcquireARScreen' as any) + : navigation.navigate('AcquireScreen' as any); + }, []); + + const _onAddItemPressed = React.useCallback( + (name?: string) => { + return () => + defaultValue.value === 'prompt' + ? setIsModalVisible(true) + : _onCameraSelectMode(defaultValue); + }, + [defaultValue], + ); + const _renderProfileStory = () => { return ( @@ -76,7 +94,7 @@ const Stories: React.FC = () => { {`Add story`} + numberOfLines={1}>{`Add Stories`} = () => { hasPagination={false} /> + ); }; diff --git a/src/screens/Home/Stories/StoriesCameraModal.tsx b/src/screens/Home/Stories/StoriesCameraModal.tsx new file mode 100644 index 0000000..c88d508 --- /dev/null +++ b/src/screens/Home/Stories/StoriesCameraModal.tsx @@ -0,0 +1,45 @@ +import * as React from 'react'; +import {Dialog, RadioButton} from '@src/components/elements'; +import {RadioOption} from '@src/components/elements/RadioButton/RadioButton'; +import {fetchDefault} from '@store/slices/cameraSlice'; +import {useAppSelector} from '@src/redux/useRedux'; + +type StoriesCameraModalProps = { + isVisible: boolean; + hideModal: () => void; + onItemPressed: (item: any) => void; +}; + +const cameraOptions: RadioOption[] = [ + { + label: 'Device', + value: 'device', + }, + { + label: 'AR', + value: 'ar', + }, +]; + +const StoriesCameraMoodal: React.FC = ({ + isVisible, + hideModal, + onItemPressed, +}) => { + const defaultValue = useAppSelector(fetchDefault); + + React.useEffect(() => { + isVisible = defaultValue.value === 'prompt'; + }, [isVisible]); + + return ( + + + + ); +}; + +export default StoriesCameraMoodal; diff --git a/src/screens/Settings/ChangeCameraModal.tsx b/src/screens/Settings/ChangeCameraModal.tsx new file mode 100644 index 0000000..c4cf667 --- /dev/null +++ b/src/screens/Settings/ChangeCameraModal.tsx @@ -0,0 +1,50 @@ +import * as React from 'react'; +import {Dialog, RadioButton} from '@src/components/elements'; +import {RadioOption} from '@src/components/elements/RadioButton/RadioButton'; +import {changeDefault, fetchDefault} from '@store/slices/cameraSlice'; +import {useAppDispatch, useAppSelector} from '@src/redux/useRedux'; +type ChangeCameraModalProps = { + isVisible: boolean; + hideModal: () => void; +}; + +const cameraOptions: RadioOption[] = [ + { + label: 'Device', + value: 'device', + }, + { + label: 'AR', + value: 'ar', + }, + { + label: 'Prompt', + value: 'prompt', + }, +]; + +const ChangeCameraModal: React.FC = ({ + isVisible, + hideModal, +}) => { + const dispatch = useAppDispatch(); + let defaultValue = useAppSelector(fetchDefault); + const _onItemPressed = (item: RadioOption) => { + dispatch(changeDefault(item as any)); + }; + + return ( + + + + ); +}; + +export default ChangeCameraModal; diff --git a/src/screens/Settings/ChangeLanguageModal.tsx b/src/screens/Settings/ChangeLanguageModal.tsx index 149c182..aa5aa50 100644 --- a/src/screens/Settings/ChangeLanguageModal.tsx +++ b/src/screens/Settings/ChangeLanguageModal.tsx @@ -10,15 +10,15 @@ type ChangeLanguageModalProps = { const languageOptions: RadioOption[] = [ { label: 'English', - value: 'english', + value: 'en', }, { - label: 'Vietnamese', - value: 'vietnamese', + label: 'Indonesian', + value: 'id', }, { - label: 'French', - value: 'French', + label: 'Hindi', + value: 'hi-in', }, ]; diff --git a/src/screens/Settings/Settings.tsx b/src/screens/Settings/Settings.tsx index 54f3fca..7fbff7c 100644 --- a/src/screens/Settings/Settings.tsx +++ b/src/screens/Settings/Settings.tsx @@ -12,7 +12,10 @@ import ListRowItem from '@src/components/elements/List/ListRowItem'; import styles from './styles'; import ChangeAppearanceModal from './ChangeAppearanceModal'; import ChangeLanguageModal from './ChangeLanguageModal'; +import ChangeCameraModal from './ChangeCameraModal'; import {useTheme} from '@src/hooks'; +import {fetchDefault} from '@store/slices/cameraSlice'; +import {useAppSelector} from '@src/redux/useRedux'; import {getStoreURL} from '@src/utils/store-info'; type SettingsProps = {}; @@ -24,6 +27,8 @@ const Settings: React.FC = () => { React.useState(false); const [isLanguageModalVisible, setIsLanguageModalVisible] = React.useState(false); + const [isCameraModalVisible, setIsCameraModalVisible] = React.useState(false); + const defaultCamera = useAppSelector(fetchDefault); React.useEffect(() => { setEnableRTL(I18nManager.isRTL); @@ -36,6 +41,9 @@ const Settings: React.FC = () => { const _hideLanguageModal = () => { setIsLanguageModalVisible(false); }; + const _hideCameraModal = () => { + setIsCameraModalVisible(false); + }; const chevronIconName = I18nManager.isRTL ? 'chevron-left' : 'chevron-right'; @@ -85,6 +93,20 @@ const Settings: React.FC = () => { } /> + + setIsCameraModalVisible(true)} + rightIcon={ + + + {defaultCamera.label} + + + + } + /> ); }; @@ -175,6 +197,10 @@ const Settings: React.FC = () => { isVisible={isLanguageModalVisible} hideModal={_hideLanguageModal} /> + ); }; diff --git a/src/screens/Settings/styles.ts b/src/screens/Settings/styles.ts index 2e7bd1e..6933696 100644 --- a/src/screens/Settings/styles.ts +++ b/src/screens/Settings/styles.ts @@ -12,4 +12,7 @@ export default StyleSheet.create({ marginRight: 5, textTransform: 'capitalize', }, + settingOptionTextUpper: { + marginRight: 5, + }, });